/*
 *  Copyright 2025-2026 R3944Realms
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

package top.r3944realms.eroticdungeongame.core.register;

import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.state.BlockBehaviour;
import net.minecraft.world.level.block.state.properties.WoodType;
import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.registries.DeferredRegister;
import net.minecraftforge.registries.ForgeRegistries;
import net.minecraftforge.registries.RegistryObject;
import org.jetbrains.annotations.NotNull;
import top.r3944realms.eroticdungeongame.EroticDungeon;
import top.r3944realms.eroticdungeongame.content.block.type.*;
import top.r3944realms.eroticdungeongame.util.ColorContent;
import top.r3944realms.lib39.util.block.BlockRegistryBuilder;
import top.r3944realms.lib39.util.lang.Pair;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

public class EDGBlocks {
    public static final DeferredRegister<Block> BLOCKS = DeferredRegister.create(ForgeRegistries.BLOCKS, EroticDungeon.MOD_ID);
    public static final Set<RegistryObject<Block>> SEAT_BLOCKS = new HashSet<>();
    public static final Map<ColorContent,RegistryObject<Block>> CUFF_BED_BLOCKS = new HashMap<>();
    public static final Map<WoodType, RegistryObject<Block>> RACK_BLOCKS = new HashMap<>();
    public static final Map<WoodType, RegistryObject<Block>> X_CROSS_BLOCKS = new HashMap<>();
    public static final Map<WoodType, RegistryObject<Block>> PETRINE_CROSS_BLOCKS = new HashMap<>();
    public static final Map<WoodType, RegistryObject<Block>> CRUX_BLOCKS = new HashMap<>();
    public static final Map<WoodType, RegistryObject<Block>> SPANISH_DONKEY_BLOCKS = new HashMap<>();
    public static final Map<WoodType, RegistryObject<Block>> PILLORY_BLOCKS = new HashMap<>();
    public static final Map<WoodType, RegistryObject<Block>> WALL_RACK_BLOCKS = new HashMap<>();
    public static final Map<WoodType, RegistryObject<Block>> CUFF_POLE_BLOCKS = new HashMap<>();
    public static final Map<Pair<ColorContent, WoodType>, RegistryObject<Block>> PRONE_BENCH_BLOCKS = new HashMap<>();
    public static final Map<WoodType, RegistryObject<Block>> HANGING_POST_BLOCKS = new HashMap<>();

    public static final RegistryObject<Block> DUNGEON_CRAFTING_TABLE = BlockRegistryBuilder.create()
            .withName("dungeon_crafting_table")
            .registerBlock(BLOCKS, () -> new DungeonCraftingTableBlock(BlockBehaviour.Properties.copy(Blocks.CRAFTING_TABLE)))
            .build();
    public static final RegistryObject<Block> END_ROD_LOVE_MACHINE = BlockRegistryBuilder.create()
            .withName("end_rod_love_machine")
            .registerBlock(BLOCKS, () -> new LoveMachineBlock(BlockBehaviour.Properties.copy(Blocks.PISTON), "end_rod"))
            .build();
    public static final RegistryObject<Block> LIGHTNING_ROD_LOVE_MACHINE = BlockRegistryBuilder.create()
            .withName("lightning_rod_love_machine")
            .registerBlock(BLOCKS, () -> new LoveMachineBlock(BlockBehaviour.Properties.copy(Blocks.PISTON), "lightning_rod"))
            .build();

    public static final RegistryObject<Block> WHITE_CUFF_BED = registerCuffBed(ColorContent.WHITE);
    public static final RegistryObject<Block> ORANGE_CUFF_BED = registerCuffBed(ColorContent.ORANGE);
    public static final RegistryObject<Block> MAGENTA_CUFF_BED = registerCuffBed(ColorContent.MAGENTA);
    public static final RegistryObject<Block> LIGHT_BLUE_CUFF_BED = registerCuffBed(ColorContent.LIGHT_BLUE);
    public static final RegistryObject<Block> YELLOW_CUFF_BED = registerCuffBed(ColorContent.YELLOW);
    public static final RegistryObject<Block> LIME_CUFF_BED = registerCuffBed(ColorContent.LIME);
    public static final RegistryObject<Block> PINK_CUFF_BED = registerCuffBed(ColorContent.PINK);
    public static final RegistryObject<Block> GRAY_CUFF_BED = registerCuffBed(ColorContent.GRAY);
    public static final RegistryObject<Block> LIGHT_GRAY_CUFF_BED = registerCuffBed(ColorContent.LIGHT_GRAY);
    public static final RegistryObject<Block> CYAN_CUFF_BED = registerCuffBed(ColorContent.CYAN);
    public static final RegistryObject<Block> PURPLE_CUFF_BED = registerCuffBed(ColorContent.PURPLE);
    public static final RegistryObject<Block> BLUE_CUFF_BED = registerCuffBed(ColorContent.BLUE);
    public static final RegistryObject<Block> BROWN_CUFF_BED = registerCuffBed(ColorContent.BROWN);
    public static final RegistryObject<Block> GREEN_CUFF_BED = registerCuffBed(ColorContent.GREEN);
    public static final RegistryObject<Block> RED_CUFF_BED = registerCuffBed(ColorContent.RED);
    public static final RegistryObject<Block> BLACK_CUFF_BED = registerCuffBed(ColorContent.BLACK);

    public static final RegistryObject<Block> OAK_RACK =  registerRack(WoodType.OAK);
    public static final RegistryObject<Block> SPRUCE_RACK =  registerRack(WoodType.SPRUCE);
    public static final RegistryObject<Block> BIRCH_RACK =  registerRack(WoodType.BIRCH);
    public static final RegistryObject<Block> ACACIA_RACK =  registerRack(WoodType.ACACIA);
    public static final RegistryObject<Block> CHERRY_RACK =  registerRack(WoodType.CHERRY);
    public static final RegistryObject<Block> JUNGLE_RACK =  registerRack(WoodType.JUNGLE);
    public static final RegistryObject<Block> DARK_OAK_RACK =  registerRack(WoodType.DARK_OAK);
    public static final RegistryObject<Block> CRIMSON_RACK =  registerRack(WoodType.CRIMSON);
    public static final RegistryObject<Block> WARPED_RACK =  registerRack(WoodType.WARPED);
    public static final RegistryObject<Block> MANGROVE_RACK =  registerRack(WoodType.MANGROVE);
    public static final RegistryObject<Block> BAMBOO_RACK =  registerRack(WoodType.BAMBOO);

    public static final RegistryObject<Block> OAK_X_CROSS =  registerXCross(WoodType.OAK);
    public static final RegistryObject<Block> SPRUCE_X_CROSS =  registerXCross(WoodType.SPRUCE);
    public static final RegistryObject<Block> BIRCH_X_CROSS =  registerXCross(WoodType.BIRCH);
    public static final RegistryObject<Block> ACACIA_X_CROSS =  registerXCross(WoodType.ACACIA);
    public static final RegistryObject<Block> CHERRY_X_CROSS =  registerXCross(WoodType.CHERRY);
    public static final RegistryObject<Block> JUNGLE_X_CROSS =  registerXCross(WoodType.JUNGLE);
    public static final RegistryObject<Block> DARK_OAK_X_CROSS =  registerXCross(WoodType.DARK_OAK);
    public static final RegistryObject<Block> CRIMSON_X_CROSS =  registerXCross(WoodType.CRIMSON);
    public static final RegistryObject<Block> WARPED_X_CROSS =  registerXCross(WoodType.WARPED);
    public static final RegistryObject<Block> MANGROVE_X_CROSS =  registerXCross(WoodType.MANGROVE);
    public static final RegistryObject<Block> BAMBOO_X_CROSS =  registerXCross(WoodType.BAMBOO);

    public static final RegistryObject<Block> OAK_PETRINE_CROSS =  registerPetrineCross(WoodType.OAK);
    public static final RegistryObject<Block> SPRUCE_PETRINE_CROSS =  registerPetrineCross(WoodType.SPRUCE);
    public static final RegistryObject<Block> BIRCH_PETRINE_CROSS =  registerPetrineCross(WoodType.BIRCH);
    public static final RegistryObject<Block> ACACIA_PETRINE_CROSS =  registerPetrineCross(WoodType.ACACIA);
    public static final RegistryObject<Block> CHERRY_PETRINE_CROSS =  registerPetrineCross(WoodType.CHERRY);
    public static final RegistryObject<Block> JUNGLE_PETRINE_CROSS =  registerPetrineCross(WoodType.JUNGLE);
    public static final RegistryObject<Block> DARK_OAK_PETRINE_CROSS =  registerPetrineCross(WoodType.DARK_OAK);
    public static final RegistryObject<Block> CRIMSON_PETRINE_CROSS =  registerPetrineCross(WoodType.CRIMSON);
    public static final RegistryObject<Block> WARPED_PETRINE_CROSS =  registerPetrineCross(WoodType.WARPED);
    public static final RegistryObject<Block> MANGROVE_PETRINE_CROSS =  registerPetrineCross(WoodType.MANGROVE);
    public static final RegistryObject<Block> BAMBOO_PETRINE_CROSS =  registerPetrineCross(WoodType.BAMBOO);

    public static final RegistryObject<Block> OAK_CRUX =  registerCrux(WoodType.OAK);
    public static final RegistryObject<Block> SPRUCE_CRUX =  registerCrux(WoodType.SPRUCE);
    public static final RegistryObject<Block> BIRCH_CRUX =  registerCrux(WoodType.BIRCH);
    public static final RegistryObject<Block> ACACIA_CRUX =  registerCrux(WoodType.ACACIA);
    public static final RegistryObject<Block> CHERRY_CRUX =  registerCrux(WoodType.CHERRY);
    public static final RegistryObject<Block> JUNGLE_CRUX =  registerCrux(WoodType.JUNGLE);
    public static final RegistryObject<Block> DARK_OAK_CRUX =  registerCrux(WoodType.DARK_OAK);
    public static final RegistryObject<Block> CRIMSON_CRUX =  registerCrux(WoodType.CRIMSON);
    public static final RegistryObject<Block> WARPED_CRUX =  registerCrux(WoodType.WARPED);
    public static final RegistryObject<Block> MANGROVE_CRUX =  registerCrux(WoodType.MANGROVE);
    public static final RegistryObject<Block> BAMBOO_CRUX =  registerCrux(WoodType.BAMBOO);

    public static final RegistryObject<Block> IRON_CAGE = BlockRegistryBuilder
            .create()
            .withName("iron_cage")
            .registerBlock(BLOCKS, IronCageBlock::new)
            .build();

    public static final RegistryObject<Block> OAK_SPANISH_DONKEY =  registerSpanishDonkey(WoodType.OAK);
    public static final RegistryObject<Block> SPRUCE_SPANISH_DONKEY =  registerSpanishDonkey(WoodType.SPRUCE);
    public static final RegistryObject<Block> BIRCH_SPANISH_DONKEY =  registerSpanishDonkey(WoodType.BIRCH);
    public static final RegistryObject<Block> ACACIA_SPANISH_DONKEY =  registerSpanishDonkey(WoodType.ACACIA);
    public static final RegistryObject<Block> CHERRY_SPANISH_DONKEY =  registerSpanishDonkey(WoodType.CHERRY);
    public static final RegistryObject<Block> JUNGLE_SPANISH_DONKEY =  registerSpanishDonkey(WoodType.JUNGLE);
    public static final RegistryObject<Block> DARK_OAK_SPANISH_DONKEY =  registerSpanishDonkey(WoodType.DARK_OAK);
    public static final RegistryObject<Block> CRIMSON_SPANISH_DONKEY =  registerSpanishDonkey(WoodType.CRIMSON);
    public static final RegistryObject<Block> WARPED_SPANISH_DONKEY =  registerSpanishDonkey(WoodType.WARPED);
    public static final RegistryObject<Block> MANGROVE_SPANISH_DONKEY =  registerSpanishDonkey(WoodType.MANGROVE);
    public static final RegistryObject<Block> BAMBOO_SPANISH_DONKEY =  registerSpanishDonkey(WoodType.BAMBOO);


    public static final RegistryObject<Block> OAK_PILLORY =  registerPillory(WoodType.OAK);
    public static final RegistryObject<Block> SPRUCE_PILLORY =  registerPillory(WoodType.SPRUCE);
    public static final RegistryObject<Block> BIRCH_PILLORY =  registerPillory(WoodType.BIRCH);
    public static final RegistryObject<Block> ACACIA_PILLORY =  registerPillory(WoodType.ACACIA);
    public static final RegistryObject<Block> CHERRY_PILLORY =  registerPillory(WoodType.CHERRY);
    public static final RegistryObject<Block> JUNGLE_PILLORY =  registerPillory(WoodType.JUNGLE);
    public static final RegistryObject<Block> DARK_OAK_PILLORY =  registerPillory(WoodType.DARK_OAK);
    public static final RegistryObject<Block> CRIMSON_PILLORY =  registerPillory(WoodType.CRIMSON);
    public static final RegistryObject<Block> WARPED_PILLORY =  registerPillory(WoodType.WARPED);
    public static final RegistryObject<Block> MANGROVE_PILLORY =  registerPillory(WoodType.MANGROVE);
    public static final RegistryObject<Block> BAMBOO_PILLORY =  registerPillory(WoodType.BAMBOO);

    public static final RegistryObject<Block> OAK_WALL_RACK =  registerWallRack(WoodType.OAK);
    public static final RegistryObject<Block> SPRUCE_WALL_RACK =  registerWallRack(WoodType.SPRUCE);
    public static final RegistryObject<Block> BIRCH_WALL_RACK =  registerWallRack(WoodType.BIRCH);
    public static final RegistryObject<Block> ACACIA_WALL_RACK =  registerWallRack(WoodType.ACACIA);
    public static final RegistryObject<Block> CHERRY_WALL_RACK =  registerWallRack(WoodType.CHERRY);
    public static final RegistryObject<Block> JUNGLE_WALL_RACK =  registerWallRack(WoodType.JUNGLE);
    public static final RegistryObject<Block> DARK_OAK_WALL_RACK =  registerWallRack(WoodType.DARK_OAK);
    public static final RegistryObject<Block> CRIMSON_WALL_RACK =  registerWallRack(WoodType.CRIMSON);
    public static final RegistryObject<Block> WARPED_WALL_RACK =  registerWallRack(WoodType.WARPED);
    public static final RegistryObject<Block> MANGROVE_WALL_RACK =  registerWallRack(WoodType.MANGROVE);
    public static final RegistryObject<Block> BAMBOO_WALL_RACK =  registerWallRack(WoodType.BAMBOO);

    public static final RegistryObject<Block> OAK_CUFF_POLE =  registerCuffPole(WoodType.OAK);
    public static final RegistryObject<Block> SPRUCE_CUFF_POLE =  registerCuffPole(WoodType.SPRUCE);
    public static final RegistryObject<Block> BIRCH_CUFF_POLE =  registerCuffPole(WoodType.BIRCH);
    public static final RegistryObject<Block> ACACIA_CUFF_POLE =  registerCuffPole(WoodType.ACACIA);
    public static final RegistryObject<Block> CHERRY_CUFF_POLE =  registerCuffPole(WoodType.CHERRY);
    public static final RegistryObject<Block> JUNGLE_CUFF_POLE =  registerCuffPole(WoodType.JUNGLE);
    public static final RegistryObject<Block> DARK_OAK_CUFF_POLE =  registerCuffPole(WoodType.DARK_OAK);
    public static final RegistryObject<Block> CRIMSON_CUFF_POLE =  registerCuffPole(WoodType.CRIMSON);
    public static final RegistryObject<Block> WARPED_CUFF_POLE =  registerCuffPole(WoodType.WARPED);
    public static final RegistryObject<Block> MANGROVE_CUFF_POLE =  registerCuffPole(WoodType.MANGROVE);
    public static final RegistryObject<Block> BAMBOO_CUFF_POLE =  registerCuffPole(WoodType.BAMBOO);

    public static final RegistryObject<Block> OAK_HANGING_POST =  registerHangingPost(WoodType.OAK);
    public static final RegistryObject<Block> SPRUCE_HANGING_POST =  registerHangingPost(WoodType.SPRUCE);
    public static final RegistryObject<Block> BIRCH_HANGING_POST =  registerHangingPost(WoodType.BIRCH);
    public static final RegistryObject<Block> ACACIA_HANGING_POST =  registerHangingPost(WoodType.ACACIA);
    public static final RegistryObject<Block> CHERRY_HANGING_POST =  registerHangingPost(WoodType.CHERRY);
    public static final RegistryObject<Block> JUNGLE_HANGING_POST =  registerHangingPost(WoodType.JUNGLE);
    public static final RegistryObject<Block> DARK_OAK_HANGING_POST =  registerHangingPost(WoodType.DARK_OAK);
    public static final RegistryObject<Block> CRIMSON_HANGING_POST =  registerHangingPost(WoodType.CRIMSON);
    public static final RegistryObject<Block> WARPED_HANGING_POST =  registerHangingPost(WoodType.WARPED);
    public static final RegistryObject<Block> MANGROVE_HANGING_POST =  registerHangingPost(WoodType.MANGROVE);
    public static final RegistryObject<Block> BAMBOO_HANGING_POST =  registerHangingPost(WoodType.BAMBOO);

    public static final RegistryObject<Block> WHITE_OAK_PRONE_BENCH =  registerProneBench(ColorContent.WHITE, WoodType.OAK);
    public static final RegistryObject<Block> WHITE_SPRUCE_PRONE_BENCH =  registerProneBench(ColorContent.WHITE, WoodType.SPRUCE);
    public static final RegistryObject<Block> WHITE_BIRCH_PRONE_BENCH =  registerProneBench(ColorContent.WHITE, WoodType.BIRCH);
    public static final RegistryObject<Block> WHITE_ACACIA_PRONE_BENCH =  registerProneBench(ColorContent.WHITE, WoodType.ACACIA);
    public static final RegistryObject<Block> WHITE_CHERRY_PRONE_BENCH =  registerProneBench(ColorContent.WHITE, WoodType.CHERRY);
    public static final RegistryObject<Block> WHITE_JUNGLE_PRONE_BENCH =  registerProneBench(ColorContent.WHITE, WoodType.JUNGLE);
    public static final RegistryObject<Block> WHITE_DARK_OAK_PRONE_BENCH =  registerProneBench(ColorContent.WHITE, WoodType.DARK_OAK);
    public static final RegistryObject<Block> WHITE_CRIMSON_PRONE_BENCH =  registerProneBench(ColorContent.WHITE, WoodType.CRIMSON);
    public static final RegistryObject<Block> WHITE_WARPED_PRONE_BENCH =  registerProneBench(ColorContent.WHITE, WoodType.WARPED);
    public static final RegistryObject<Block> WHITE_MANGROVE_PRONE_BENCH =  registerProneBench(ColorContent.WHITE, WoodType.MANGROVE);
    public static final RegistryObject<Block> WHITE_BAMBOO_PRONE_BENCH =  registerProneBench(ColorContent.WHITE, WoodType.BAMBOO);

    public static final RegistryObject<Block> ORANGE_OAK_PRONE_BENCH =  registerProneBench(ColorContent.ORANGE, WoodType.OAK);
    public static final RegistryObject<Block> ORANGE_SPRUCE_PRONE_BENCH =  registerProneBench(ColorContent.ORANGE, WoodType.SPRUCE);
    public static final RegistryObject<Block> ORANGE_BIRCH_PRONE_BENCH =  registerProneBench(ColorContent.ORANGE, WoodType.BIRCH);
    public static final RegistryObject<Block> ORANGE_ACACIA_PRONE_BENCH =  registerProneBench(ColorContent.ORANGE, WoodType.ACACIA);
    public static final RegistryObject<Block> ORANGE_CHERRY_PRONE_BENCH =  registerProneBench(ColorContent.ORANGE, WoodType.CHERRY);
    public static final RegistryObject<Block> ORANGE_JUNGLE_PRONE_BENCH =  registerProneBench(ColorContent.ORANGE, WoodType.JUNGLE);
    public static final RegistryObject<Block> ORANGE_DARK_OAK_PRONE_BENCH =  registerProneBench(ColorContent.ORANGE, WoodType.DARK_OAK);
    public static final RegistryObject<Block> ORANGE_CRIMSON_PRONE_BENCH =  registerProneBench(ColorContent.ORANGE, WoodType.CRIMSON);
    public static final RegistryObject<Block> ORANGE_WARPED_PRONE_BENCH =  registerProneBench(ColorContent.ORANGE, WoodType.WARPED);
    public static final RegistryObject<Block> ORANGE_MANGROVE_PRONE_BENCH =  registerProneBench(ColorContent.ORANGE, WoodType.MANGROVE);
    public static final RegistryObject<Block> ORANGE_BAMBOO_PRONE_BENCH =  registerProneBench(ColorContent.ORANGE, WoodType.BAMBOO);

    public static final RegistryObject<Block> MAGENTA_OAK_PRONE_BENCH =  registerProneBench(ColorContent.MAGENTA, WoodType.OAK);
    public static final RegistryObject<Block> MAGENTA_SPRUCE_PRONE_BENCH =  registerProneBench(ColorContent.MAGENTA, WoodType.SPRUCE);
    public static final RegistryObject<Block> MAGENTA_BIRCH_PRONE_BENCH =  registerProneBench(ColorContent.MAGENTA, WoodType.BIRCH);
    public static final RegistryObject<Block> MAGENTA_ACACIA_PRONE_BENCH =  registerProneBench(ColorContent.MAGENTA, WoodType.ACACIA);
    public static final RegistryObject<Block> MAGENTA_CHERRY_PRONE_BENCH =  registerProneBench(ColorContent.MAGENTA, WoodType.CHERRY);
    public static final RegistryObject<Block> MAGENTA_JUNGLE_PRONE_BENCH =  registerProneBench(ColorContent.MAGENTA, WoodType.JUNGLE);
    public static final RegistryObject<Block> MAGENTA_DARK_OAK_PRONE_BENCH =  registerProneBench(ColorContent.MAGENTA, WoodType.DARK_OAK);
    public static final RegistryObject<Block> MAGENTA_CRIMSON_PRONE_BENCH =  registerProneBench(ColorContent.MAGENTA, WoodType.CRIMSON);
    public static final RegistryObject<Block> MAGENTA_WARPED_PRONE_BENCH =  registerProneBench(ColorContent.MAGENTA, WoodType.WARPED);
    public static final RegistryObject<Block> MAGENTA_MANGROVE_PRONE_BENCH =  registerProneBench(ColorContent.MAGENTA, WoodType.MANGROVE);
    public static final RegistryObject<Block> MAGENTA_BAMBOO_PRONE_BENCH =  registerProneBench(ColorContent.MAGENTA, WoodType.BAMBOO);

    public static final RegistryObject<Block> LIGHT_BLUE_OAK_PRONE_BENCH =  registerProneBench(ColorContent.LIGHT_BLUE, WoodType.OAK);
    public static final RegistryObject<Block> LIGHT_BLUE_SPRUCE_PRONE_BENCH =  registerProneBench(ColorContent.LIGHT_BLUE, WoodType.SPRUCE);
    public static final RegistryObject<Block> LIGHT_BLUE_BIRCH_PRONE_BENCH =  registerProneBench(ColorContent.LIGHT_BLUE, WoodType.BIRCH);
    public static final RegistryObject<Block> LIGHT_BLUE_ACACIA_PRONE_BENCH =  registerProneBench(ColorContent.LIGHT_BLUE, WoodType.ACACIA);
    public static final RegistryObject<Block> LIGHT_BLUE_CHERRY_PRONE_BENCH =  registerProneBench(ColorContent.LIGHT_BLUE, WoodType.CHERRY);
    public static final RegistryObject<Block> LIGHT_BLUE_JUNGLE_PRONE_BENCH =  registerProneBench(ColorContent.LIGHT_BLUE, WoodType.JUNGLE);
    public static final RegistryObject<Block> LIGHT_BLUE_DARK_OAK_PRONE_BENCH =  registerProneBench(ColorContent.LIGHT_BLUE, WoodType.DARK_OAK);
    public static final RegistryObject<Block> LIGHT_BLUE_CRIMSON_PRONE_BENCH =  registerProneBench(ColorContent.LIGHT_BLUE, WoodType.CRIMSON);
    public static final RegistryObject<Block> LIGHT_BLUE_WARPED_PRONE_BENCH =  registerProneBench(ColorContent.LIGHT_BLUE, WoodType.WARPED);
    public static final RegistryObject<Block> LIGHT_BLUE_MANGROVE_PRONE_BENCH =  registerProneBench(ColorContent.LIGHT_BLUE, WoodType.MANGROVE);
    public static final RegistryObject<Block> LIGHT_BLUE_BAMBOO_PRONE_BENCH =  registerProneBench(ColorContent.LIGHT_BLUE, WoodType.BAMBOO);

    public static final RegistryObject<Block> YELLOW_OAK_PRONE_BENCH =  registerProneBench(ColorContent.YELLOW, WoodType.OAK);
    public static final RegistryObject<Block> YELLOW_SPRUCE_PRONE_BENCH =  registerProneBench(ColorContent.YELLOW, WoodType.SPRUCE);
    public static final RegistryObject<Block> YELLOW_BIRCH_PRONE_BENCH =  registerProneBench(ColorContent.YELLOW, WoodType.BIRCH);
    public static final RegistryObject<Block> YELLOW_ACACIA_PRONE_BENCH =  registerProneBench(ColorContent.YELLOW, WoodType.ACACIA);
    public static final RegistryObject<Block> YELLOW_CHERRY_PRONE_BENCH =  registerProneBench(ColorContent.YELLOW, WoodType.CHERRY);
    public static final RegistryObject<Block> YELLOW_JUNGLE_PRONE_BENCH =  registerProneBench(ColorContent.YELLOW, WoodType.JUNGLE);
    public static final RegistryObject<Block> YELLOW_DARK_OAK_PRONE_BENCH =  registerProneBench(ColorContent.YELLOW, WoodType.DARK_OAK);
    public static final RegistryObject<Block> YELLOW_CRIMSON_PRONE_BENCH =  registerProneBench(ColorContent.YELLOW, WoodType.CRIMSON);
    public static final RegistryObject<Block> YELLOW_WARPED_PRONE_BENCH =  registerProneBench(ColorContent.YELLOW, WoodType.WARPED);
    public static final RegistryObject<Block> YELLOW_MANGROVE_PRONE_BENCH =  registerProneBench(ColorContent.YELLOW, WoodType.MANGROVE);
    public static final RegistryObject<Block> YELLOW_BAMBOO_PRONE_BENCH =  registerProneBench(ColorContent.YELLOW, WoodType.BAMBOO);

    public static final RegistryObject<Block> LIME_OAK_PRONE_BENCH =  registerProneBench(ColorContent.LIME, WoodType.OAK);
    public static final RegistryObject<Block> LIME_SPRUCE_PRONE_BENCH =  registerProneBench(ColorContent.LIME, WoodType.SPRUCE);
    public static final RegistryObject<Block> LIME_BIRCH_PRONE_BENCH =  registerProneBench(ColorContent.LIME, WoodType.BIRCH);
    public static final RegistryObject<Block> LIME_ACACIA_PRONE_BENCH =  registerProneBench(ColorContent.LIME, WoodType.ACACIA);
    public static final RegistryObject<Block> LIME_CHERRY_PRONE_BENCH =  registerProneBench(ColorContent.LIME, WoodType.CHERRY);
    public static final RegistryObject<Block> LIME_JUNGLE_PRONE_BENCH =  registerProneBench(ColorContent.LIME, WoodType.JUNGLE);
    public static final RegistryObject<Block> LIME_DARK_OAK_PRONE_BENCH =  registerProneBench(ColorContent.LIME, WoodType.DARK_OAK);
    public static final RegistryObject<Block> LIME_CRIMSON_PRONE_BENCH =  registerProneBench(ColorContent.LIME, WoodType.CRIMSON);
    public static final RegistryObject<Block> LIME_WARPED_PRONE_BENCH =  registerProneBench(ColorContent.LIME, WoodType.WARPED);
    public static final RegistryObject<Block> LIME_MANGROVE_PRONE_BENCH =  registerProneBench(ColorContent.LIME, WoodType.MANGROVE);
    public static final RegistryObject<Block> LIME_BAMBOO_PRONE_BENCH =  registerProneBench(ColorContent.LIME, WoodType.BAMBOO);

    public static final RegistryObject<Block> PINK_OAK_PRONE_BENCH =  registerProneBench(ColorContent.PINK, WoodType.OAK);
    public static final RegistryObject<Block> PINK_SPRUCE_PRONE_BENCH =  registerProneBench(ColorContent.PINK, WoodType.SPRUCE);
    public static final RegistryObject<Block> PINK_BIRCH_PRONE_BENCH =  registerProneBench(ColorContent.PINK, WoodType.BIRCH);
    public static final RegistryObject<Block> PINK_ACACIA_PRONE_BENCH =  registerProneBench(ColorContent.PINK, WoodType.ACACIA);
    public static final RegistryObject<Block> PINK_CHERRY_PRONE_BENCH =  registerProneBench(ColorContent.PINK, WoodType.CHERRY);
    public static final RegistryObject<Block> PINK_JUNGLE_PRONE_BENCH =  registerProneBench(ColorContent.PINK, WoodType.JUNGLE);
    public static final RegistryObject<Block> PINK_DARK_OAK_PRONE_BENCH =  registerProneBench(ColorContent.PINK, WoodType.DARK_OAK);
    public static final RegistryObject<Block> PINK_CRIMSON_PRONE_BENCH =  registerProneBench(ColorContent.PINK, WoodType.CRIMSON);
    public static final RegistryObject<Block> PINK_WARPED_PRONE_BENCH =  registerProneBench(ColorContent.PINK, WoodType.WARPED);
    public static final RegistryObject<Block> PINK_MANGROVE_PRONE_BENCH =  registerProneBench(ColorContent.PINK, WoodType.MANGROVE);
    public static final RegistryObject<Block> PINK_BAMBOO_PRONE_BENCH =  registerProneBench(ColorContent.PINK, WoodType.BAMBOO);

    public static final RegistryObject<Block> GRAY_OAK_PRONE_BENCH =  registerProneBench(ColorContent.GRAY, WoodType.OAK);
    public static final RegistryObject<Block> GRAY_SPRUCE_PRONE_BENCH =  registerProneBench(ColorContent.GRAY, WoodType.SPRUCE);
    public static final RegistryObject<Block> GRAY_BIRCH_PRONE_BENCH =  registerProneBench(ColorContent.GRAY, WoodType.BIRCH);
    public static final RegistryObject<Block> GRAY_ACACIA_PRONE_BENCH =  registerProneBench(ColorContent.GRAY, WoodType.ACACIA);
    public static final RegistryObject<Block> GRAY_CHERRY_PRONE_BENCH =  registerProneBench(ColorContent.GRAY, WoodType.CHERRY);
    public static final RegistryObject<Block> GRAY_JUNGLE_PRONE_BENCH =  registerProneBench(ColorContent.GRAY, WoodType.JUNGLE);
    public static final RegistryObject<Block> GRAY_DARK_OAK_PRONE_BENCH =  registerProneBench(ColorContent.GRAY, WoodType.DARK_OAK);
    public static final RegistryObject<Block> GRAY_CRIMSON_PRONE_BENCH =  registerProneBench(ColorContent.GRAY, WoodType.CRIMSON);
    public static final RegistryObject<Block> GRAY_WARPED_PRONE_BENCH =  registerProneBench(ColorContent.GRAY, WoodType.WARPED);
    public static final RegistryObject<Block> GRAY_MANGROVE_PRONE_BENCH =  registerProneBench(ColorContent.GRAY, WoodType.MANGROVE);
    public static final RegistryObject<Block> GRAY_BAMBOO_PRONE_BENCH =  registerProneBench(ColorContent.GRAY, WoodType.BAMBOO);

    public static final RegistryObject<Block> LIGHT_GRAY_OAK_PRONE_BENCH =  registerProneBench(ColorContent.LIGHT_GRAY, WoodType.OAK);
    public static final RegistryObject<Block> LIGHT_GRAY_SPRUCE_PRONE_BENCH =  registerProneBench(ColorContent.LIGHT_GRAY, WoodType.SPRUCE);
    public static final RegistryObject<Block> LIGHT_GRAY_BIRCH_PRONE_BENCH =  registerProneBench(ColorContent.LIGHT_GRAY, WoodType.BIRCH);
    public static final RegistryObject<Block> LIGHT_GRAY_ACACIA_PRONE_BENCH =  registerProneBench(ColorContent.LIGHT_GRAY, WoodType.ACACIA);
    public static final RegistryObject<Block> LIGHT_GRAY_CHERRY_PRONE_BENCH =  registerProneBench(ColorContent.LIGHT_GRAY, WoodType.CHERRY);
    public static final RegistryObject<Block> LIGHT_GRAY_JUNGLE_PRONE_BENCH =  registerProneBench(ColorContent.LIGHT_GRAY, WoodType.JUNGLE);
    public static final RegistryObject<Block> LIGHT_GRAY_DARK_OAK_PRONE_BENCH =  registerProneBench(ColorContent.LIGHT_GRAY, WoodType.DARK_OAK);
    public static final RegistryObject<Block> LIGHT_GRAY_CRIMSON_PRONE_BENCH =  registerProneBench(ColorContent.LIGHT_GRAY, WoodType.CRIMSON);
    public static final RegistryObject<Block> LIGHT_GRAY_WARPED_PRONE_BENCH =  registerProneBench(ColorContent.LIGHT_GRAY, WoodType.WARPED);
    public static final RegistryObject<Block> LIGHT_GRAY_MANGROVE_PRONE_BENCH =  registerProneBench(ColorContent.LIGHT_GRAY, WoodType.MANGROVE);
    public static final RegistryObject<Block> LIGHT_GRAY_BAMBOO_PRONE_BENCH =  registerProneBench(ColorContent.LIGHT_GRAY, WoodType.BAMBOO);

    public static final RegistryObject<Block> CYAN_OAK_PRONE_BENCH =  registerProneBench(ColorContent.CYAN, WoodType.OAK);
    public static final RegistryObject<Block> CYAN_SPRUCE_PRONE_BENCH =  registerProneBench(ColorContent.CYAN, WoodType.SPRUCE);
    public static final RegistryObject<Block> CYAN_BIRCH_PRONE_BENCH =  registerProneBench(ColorContent.CYAN, WoodType.BIRCH);
    public static final RegistryObject<Block> CYAN_ACACIA_PRONE_BENCH =  registerProneBench(ColorContent.CYAN, WoodType.ACACIA);
    public static final RegistryObject<Block> CYAN_CHERRY_PRONE_BENCH =  registerProneBench(ColorContent.CYAN, WoodType.CHERRY);
    public static final RegistryObject<Block> CYAN_JUNGLE_PRONE_BENCH =  registerProneBench(ColorContent.CYAN, WoodType.JUNGLE);
    public static final RegistryObject<Block> CYAN_DARK_OAK_PRONE_BENCH =  registerProneBench(ColorContent.CYAN, WoodType.DARK_OAK);
    public static final RegistryObject<Block> CYAN_CRIMSON_PRONE_BENCH =  registerProneBench(ColorContent.CYAN, WoodType.CRIMSON);
    public static final RegistryObject<Block> CYAN_WARPED_PRONE_BENCH =  registerProneBench(ColorContent.CYAN, WoodType.WARPED);
    public static final RegistryObject<Block> CYAN_MANGROVE_PRONE_BENCH =  registerProneBench(ColorContent.CYAN, WoodType.MANGROVE);
    public static final RegistryObject<Block> CYAN_BAMBOO_PRONE_BENCH =  registerProneBench(ColorContent.CYAN, WoodType.BAMBOO);

    public static final RegistryObject<Block> PURPLE_OAK_PRONE_BENCH =  registerProneBench(ColorContent.PURPLE, WoodType.OAK);
    public static final RegistryObject<Block> PURPLE_SPRUCE_PRONE_BENCH =  registerProneBench(ColorContent.PURPLE, WoodType.SPRUCE);
    public static final RegistryObject<Block> PURPLE_BIRCH_PRONE_BENCH =  registerProneBench(ColorContent.PURPLE, WoodType.BIRCH);
    public static final RegistryObject<Block> PURPLE_ACACIA_PRONE_BENCH =  registerProneBench(ColorContent.PURPLE, WoodType.ACACIA);
    public static final RegistryObject<Block> PURPLE_CHERRY_PRONE_BENCH =  registerProneBench(ColorContent.PURPLE, WoodType.CHERRY);
    public static final RegistryObject<Block> PURPLE_JUNGLE_PRONE_BENCH =  registerProneBench(ColorContent.PURPLE, WoodType.JUNGLE);
    public static final RegistryObject<Block> PURPLE_DARK_OAK_PRONE_BENCH =  registerProneBench(ColorContent.PURPLE, WoodType.DARK_OAK);
    public static final RegistryObject<Block> PURPLE_CRIMSON_PRONE_BENCH =  registerProneBench(ColorContent.PURPLE, WoodType.CRIMSON);
    public static final RegistryObject<Block> PURPLE_WARPED_PRONE_BENCH =  registerProneBench(ColorContent.PURPLE, WoodType.WARPED);
    public static final RegistryObject<Block> PURPLE_MANGROVE_PRONE_BENCH =  registerProneBench(ColorContent.PURPLE, WoodType.MANGROVE);
    public static final RegistryObject<Block> PURPLE_BAMBOO_PRONE_BENCH =  registerProneBench(ColorContent.PURPLE, WoodType.BAMBOO);

    public static final RegistryObject<Block> BLUE_OAK_PRONE_BENCH =  registerProneBench(ColorContent.BLUE, WoodType.OAK);
    public static final RegistryObject<Block> BLUE_SPRUCE_PRONE_BENCH =  registerProneBench(ColorContent.BLUE, WoodType.SPRUCE);
    public static final RegistryObject<Block> BLUE_BIRCH_PRONE_BENCH =  registerProneBench(ColorContent.BLUE, WoodType.BIRCH);
    public static final RegistryObject<Block> BLUE_ACACIA_PRONE_BENCH =  registerProneBench(ColorContent.BLUE, WoodType.ACACIA);
    public static final RegistryObject<Block> BLUE_CHERRY_PRONE_BENCH =  registerProneBench(ColorContent.BLUE, WoodType.CHERRY);
    public static final RegistryObject<Block> BLUE_JUNGLE_PRONE_BENCH =  registerProneBench(ColorContent.BLUE, WoodType.JUNGLE);
    public static final RegistryObject<Block> BLUE_DARK_OAK_PRONE_BENCH =  registerProneBench(ColorContent.BLUE, WoodType.DARK_OAK);
    public static final RegistryObject<Block> BLUE_CRIMSON_PRONE_BENCH =  registerProneBench(ColorContent.BLUE, WoodType.CRIMSON);
    public static final RegistryObject<Block> BLUE_WARPED_PRONE_BENCH =  registerProneBench(ColorContent.BLUE, WoodType.WARPED);
    public static final RegistryObject<Block> BLUE_MANGROVE_PRONE_BENCH =  registerProneBench(ColorContent.BLUE, WoodType.MANGROVE);
    public static final RegistryObject<Block> BLUE_BAMBOO_PRONE_BENCH =  registerProneBench(ColorContent.BLUE, WoodType.BAMBOO);

    public static final RegistryObject<Block> BROWN_OAK_PRONE_BENCH =  registerProneBench(ColorContent.BROWN, WoodType.OAK);
    public static final RegistryObject<Block> BROWN_SPRUCE_PRONE_BENCH =  registerProneBench(ColorContent.BROWN, WoodType.SPRUCE);
    public static final RegistryObject<Block> BROWN_BIRCH_PRONE_BENCH =  registerProneBench(ColorContent.BROWN, WoodType.BIRCH);
    public static final RegistryObject<Block> BROWN_ACACIA_PRONE_BENCH =  registerProneBench(ColorContent.BROWN, WoodType.ACACIA);
    public static final RegistryObject<Block> BROWN_CHERRY_PRONE_BENCH =  registerProneBench(ColorContent.BROWN, WoodType.CHERRY);
    public static final RegistryObject<Block> BROWN_JUNGLE_PRONE_BENCH =  registerProneBench(ColorContent.BROWN, WoodType.JUNGLE);
    public static final RegistryObject<Block> BROWN_DARK_OAK_PRONE_BENCH =  registerProneBench(ColorContent.BROWN, WoodType.DARK_OAK);
    public static final RegistryObject<Block> BROWN_CRIMSON_PRONE_BENCH =  registerProneBench(ColorContent.BROWN, WoodType.CRIMSON);
    public static final RegistryObject<Block> BROWN_WARPED_PRONE_BENCH =  registerProneBench(ColorContent.BROWN, WoodType.WARPED);
    public static final RegistryObject<Block> BROWN_MANGROVE_PRONE_BENCH =  registerProneBench(ColorContent.BROWN, WoodType.MANGROVE);
    public static final RegistryObject<Block> BROWN_BAMBOO_PRONE_BENCH =  registerProneBench(ColorContent.BROWN, WoodType.BAMBOO);

    public static final RegistryObject<Block> GREEN_OAK_PRONE_BENCH =  registerProneBench(ColorContent.GREEN, WoodType.OAK);
    public static final RegistryObject<Block> GREEN_SPRUCE_PRONE_BENCH =  registerProneBench(ColorContent.GREEN, WoodType.SPRUCE);
    public static final RegistryObject<Block> GREEN_BIRCH_PRONE_BENCH =  registerProneBench(ColorContent.GREEN, WoodType.BIRCH);
    public static final RegistryObject<Block> GREEN_ACACIA_PRONE_BENCH =  registerProneBench(ColorContent.GREEN, WoodType.ACACIA);
    public static final RegistryObject<Block> GREEN_CHERRY_PRONE_BENCH =  registerProneBench(ColorContent.GREEN, WoodType.CHERRY);
    public static final RegistryObject<Block> GREEN_JUNGLE_PRONE_BENCH =  registerProneBench(ColorContent.GREEN, WoodType.JUNGLE);
    public static final RegistryObject<Block> GREEN_DARK_OAK_PRONE_BENCH =  registerProneBench(ColorContent.GREEN, WoodType.DARK_OAK);
    public static final RegistryObject<Block> GREEN_CRIMSON_PRONE_BENCH =  registerProneBench(ColorContent.GREEN, WoodType.CRIMSON);
    public static final RegistryObject<Block> GREEN_WARPED_PRONE_BENCH =  registerProneBench(ColorContent.GREEN, WoodType.WARPED);
    public static final RegistryObject<Block> GREEN_MANGROVE_PRONE_BENCH =  registerProneBench(ColorContent.GREEN, WoodType.MANGROVE);
    public static final RegistryObject<Block> GREEN_BAMBOO_PRONE_BENCH =  registerProneBench(ColorContent.GREEN, WoodType.BAMBOO);

    public static final RegistryObject<Block> RED_OAK_PRONE_BENCH =  registerProneBench(ColorContent.RED, WoodType.OAK);
    public static final RegistryObject<Block> RED_SPRUCE_PRONE_BENCH =  registerProneBench(ColorContent.RED, WoodType.SPRUCE);
    public static final RegistryObject<Block> RED_BIRCH_PRONE_BENCH =  registerProneBench(ColorContent.RED, WoodType.BIRCH);
    public static final RegistryObject<Block> RED_ACACIA_PRONE_BENCH =  registerProneBench(ColorContent.RED, WoodType.ACACIA);
    public static final RegistryObject<Block> RED_CHERRY_PRONE_BENCH =  registerProneBench(ColorContent.RED, WoodType.CHERRY);
    public static final RegistryObject<Block> RED_JUNGLE_PRONE_BENCH =  registerProneBench(ColorContent.RED, WoodType.JUNGLE);
    public static final RegistryObject<Block> RED_DARK_OAK_PRONE_BENCH =  registerProneBench(ColorContent.RED, WoodType.DARK_OAK);
    public static final RegistryObject<Block> RED_CRIMSON_PRONE_BENCH =  registerProneBench(ColorContent.RED, WoodType.CRIMSON);
    public static final RegistryObject<Block> RED_WARPED_PRONE_BENCH =  registerProneBench(ColorContent.RED, WoodType.WARPED);
    public static final RegistryObject<Block> RED_MANGROVE_PRONE_BENCH =  registerProneBench(ColorContent.RED, WoodType.MANGROVE);
    public static final RegistryObject<Block> RED_BAMBOO_PRONE_BENCH =  registerProneBench(ColorContent.RED, WoodType.BAMBOO);

    public static final RegistryObject<Block> BLACK_OAK_PRONE_BENCH =  registerProneBench(ColorContent.BLACK, WoodType.OAK);
    public static final RegistryObject<Block> BLACK_SPRUCE_PRONE_BENCH =  registerProneBench(ColorContent.BLACK, WoodType.SPRUCE);
    public static final RegistryObject<Block> BLACK_BIRCH_PRONE_BENCH =  registerProneBench(ColorContent.BLACK, WoodType.BIRCH);
    public static final RegistryObject<Block> BLACK_ACACIA_PRONE_BENCH =  registerProneBench(ColorContent.BLACK, WoodType.ACACIA);
    public static final RegistryObject<Block> BLACK_CHERRY_PRONE_BENCH =  registerProneBench(ColorContent.BLACK, WoodType.CHERRY);
    public static final RegistryObject<Block> BLACK_JUNGLE_PRONE_BENCH =  registerProneBench(ColorContent.BLACK, WoodType.JUNGLE);
    public static final RegistryObject<Block> BLACK_DARK_OAK_PRONE_BENCH =  registerProneBench(ColorContent.BLACK, WoodType.DARK_OAK);
    public static final RegistryObject<Block> BLACK_CRIMSON_PRONE_BENCH =  registerProneBench(ColorContent.BLACK, WoodType.CRIMSON);
    public static final RegistryObject<Block> BLACK_WARPED_PRONE_BENCH =  registerProneBench(ColorContent.BLACK, WoodType.WARPED);
    public static final RegistryObject<Block> BLACK_MANGROVE_PRONE_BENCH =  registerProneBench(ColorContent.BLACK, WoodType.MANGROVE);
    public static final RegistryObject<Block> BLACK_BAMBOO_PRONE_BENCH =  registerProneBench(ColorContent.BLACK, WoodType.BAMBOO);

    private static RegistryObject<Block> registerProneBench (@NotNull ColorContent color, @NotNull WoodType woodType) {
        String name =  color.getName() + "_" +  woodType.name() + "_prone_bench";
        RegistryObject<Block> block = BlockRegistryBuilder
                .create()
                .withName(name)
                .registerBlock(BLOCKS, () -> new ProneBenchBlock(woodType, color))
                .build();
        PRONE_BENCH_BLOCKS.put(Pair.of(color, woodType), block);
        SEAT_BLOCKS.add(block);
        return block;
    }

    public static @NotNull ProneBenchBlock getProneBenchBlock(ColorContent color, WoodType woodType) {
        return (ProneBenchBlock) PRONE_BENCH_BLOCKS.get(Pair.of(color, woodType)).get();
    }

    public static @NotNull ProneBenchBlock @NotNull [] getProneBenchBlocks() {
        return PRONE_BENCH_BLOCKS.values().stream().map(RegistryObject::get).map(ProneBenchBlock.class::cast).toArray(ProneBenchBlock[]::new);
    }

    private static RegistryObject<Block> registerCuffPole(@NotNull WoodType woodType) {
        String name = woodType.name() + "_cuff_pole";
        RegistryObject<Block> block = BlockRegistryBuilder
                .create()
                .withName(name)
                .registerBlock(BLOCKS, () -> new CuffPoleBlock(woodType))
                .build();
        CUFF_POLE_BLOCKS.put(woodType, block);
        SEAT_BLOCKS.add(block);
        return block;
    }

    public static @NotNull CuffPoleBlock getCuffPoleBlock(WoodType content) {
        return (CuffPoleBlock) CUFF_POLE_BLOCKS.get(content).get();
    }

    public static @NotNull CuffPoleBlock @NotNull [] getCuffPoleBlocks() {
        return CUFF_POLE_BLOCKS.values().stream().map(RegistryObject::get).map(CuffPoleBlock.class::cast).toArray(CuffPoleBlock[]::new);
    }
    
    private static RegistryObject<Block> registerWallRack(@NotNull WoodType woodType) {
        String name = woodType.name() + "_wall_rack";
        RegistryObject<Block> block = BlockRegistryBuilder
                .create()
                .withName(name)
                .registerBlock(BLOCKS, () -> new WallRackBlock(woodType))
                .build();
        WALL_RACK_BLOCKS.put(woodType, block);
        SEAT_BLOCKS.add(block);
        return block;
    }

    public static @NotNull WallRackBlock getWallRackBlock(WoodType content) {
        return (WallRackBlock) WALL_RACK_BLOCKS.get(content).get();
    }

    public static @NotNull WallRackBlock @NotNull [] getWallRackBlocks() {
        return WALL_RACK_BLOCKS.values().stream().map(RegistryObject::get).map(WallRackBlock.class::cast).toArray(WallRackBlock[]::new);
    }

    private static RegistryObject<Block> registerPillory(@NotNull WoodType woodType) {
        String name = woodType.name() + "_pillory";
        RegistryObject<Block> block = BlockRegistryBuilder
                .create()
                .withName(name)
                .registerBlock(BLOCKS, () -> new PilloryBlock(woodType))
                .build();
        PILLORY_BLOCKS.put(woodType, block);
        SEAT_BLOCKS.add(block);
        return block;
    }

    public static @NotNull PilloryBlock getPilloryBlock(WoodType content) {
        return (PilloryBlock) PILLORY_BLOCKS.get(content).get();
    }

    public static @NotNull PilloryBlock @NotNull [] getPilloryBlocks() {
        return PILLORY_BLOCKS.values().stream().map(RegistryObject::get).map(PilloryBlock.class::cast).toArray(PilloryBlock[]::new);
    }

    private static RegistryObject<Block> registerSpanishDonkey(@NotNull WoodType woodType) {
        String name = woodType.name() + "_spanish_donkey";
        RegistryObject<Block> block = BlockRegistryBuilder
                .create()
                .withName(name)
                .registerBlock(BLOCKS, () -> new SpanishDonkeyBlock(woodType))
                .build();
        SPANISH_DONKEY_BLOCKS.put(woodType, block);
        SEAT_BLOCKS.add(block);
        return block;
    }

    public static @NotNull SpanishDonkeyBlock getSpanishDonkeyBlock(WoodType content) {
        return (SpanishDonkeyBlock) SPANISH_DONKEY_BLOCKS.get(content).get();
    }

    public static @NotNull SpanishDonkeyBlock @NotNull [] getSpanishDonkeyBlocks() {
        return SPANISH_DONKEY_BLOCKS.values().stream().map(RegistryObject::get).map(SpanishDonkeyBlock.class::cast).toArray(SpanishDonkeyBlock[]::new);
    }

    public static @NotNull CuffBedBlock getCuffedBlock(ColorContent content) {
        return (CuffBedBlock) CUFF_BED_BLOCKS.get(content).get();
    }

    public static @NotNull CuffBedBlock @NotNull [] getCuffedBlocks() {
        return  CUFF_BED_BLOCKS.values().stream().map(RegistryObject::get).map(CuffBedBlock.class::cast).toArray(CuffBedBlock[]::new);
    }

    private static RegistryObject<Block> registerRack(@NotNull WoodType woodType) {
        String name = woodType.name() + "_rack";
        RegistryObject<Block> block = BlockRegistryBuilder
                .create()
                .withName(name)
                .registerBlock(BLOCKS, () -> new RackBlock(woodType))
                .build();
        RACK_BLOCKS.put(woodType, block);
        SEAT_BLOCKS.add(block);
        return block;
    }

    public static @NotNull RackBlock getRackBlock(WoodType content) {
        return (RackBlock) RACK_BLOCKS.get(content).get();
    }

    public static @NotNull RackBlock @NotNull [] getRackBlocks() {
        return RACK_BLOCKS.values().stream().map(RegistryObject::get).map(RackBlock.class::cast).toArray(RackBlock[]::new);
    }

    private static RegistryObject<Block> registerCuffBed(@NotNull ColorContent color) {
        String name = color.getName() + "_cuff_bed";
        RegistryObject<Block> block = BlockRegistryBuilder
                .create()
                .withName(name)
                .registerBlock(BLOCKS, () -> new CuffBedBlock(color))
                .build();
        CUFF_BED_BLOCKS.put(color, block);
        SEAT_BLOCKS.add(block);
        return block;
    }

    private static RegistryObject<Block> registerXCross(@NotNull WoodType woodType) {
        String name = woodType.name() + "_x_cross";
        RegistryObject<Block> block = BlockRegistryBuilder
                .create()
                .withName(name)
                .registerBlock(BLOCKS, () -> new XCrossBlock(woodType))
                .build();
        X_CROSS_BLOCKS.put(woodType, block);
        SEAT_BLOCKS.add(block);
        return block;
    }

    public static @NotNull XCrossBlock getXCrossBlock(WoodType content) {
        return (XCrossBlock) X_CROSS_BLOCKS.get(content).get();
    }

    private static RegistryObject<Block> registerPetrineCross(@NotNull WoodType woodType) {
        String name = woodType.name() + "_petrine_cross";
        RegistryObject<Block> block = BlockRegistryBuilder
                .create()
                .withName(name)
                .registerBlock(BLOCKS, () -> new PetrineCrossBlock(woodType))
                .build();
        PETRINE_CROSS_BLOCKS.put(woodType, block);
        SEAT_BLOCKS.add(block);
        return block;
    }

    public static @NotNull XCrossBlock @NotNull [] getXCrossBlocks() {
        return X_CROSS_BLOCKS.values().stream().map(RegistryObject::get).map(XCrossBlock.class::cast).toArray(XCrossBlock[]::new);
    }

    public static @NotNull CruxBlock @NotNull [] getCruxBlocks() {
        return CRUX_BLOCKS.values().stream().map(RegistryObject::get).map(CruxBlock.class::cast).toArray(CruxBlock[]::new);
    }

    public static @NotNull PetrineCrossBlock @NotNull [] getPetrineCrossBlocks() {
        return PETRINE_CROSS_BLOCKS.values().stream().map(RegistryObject::get).map(PetrineCrossBlock.class::cast).toArray(PetrineCrossBlock[]::new);
    }

    public static @NotNull PetrineCrossBlock getPetrineCrossBlock(WoodType content) {
        return (PetrineCrossBlock) PETRINE_CROSS_BLOCKS.get(content).get();
    }

    private static RegistryObject<Block> registerCrux(@NotNull WoodType woodType) {
        String name = woodType.name() + "_crux";
        RegistryObject<Block> block = BlockRegistryBuilder
                .create()
                .withName(name)
                .registerBlock(BLOCKS, () -> new CruxBlock(woodType))
                .build();
        CRUX_BLOCKS.put(woodType, block);
        SEAT_BLOCKS.add(block);
        return block;
    }

    public static @NotNull CruxBlock getCruxBlock(WoodType content) {
        return (CruxBlock) CRUX_BLOCKS.get(content).get();
    }

    private static RegistryObject<Block> registerHangingPost(@NotNull WoodType woodType) {
        String name = woodType.name() + "_hanging_post";
        RegistryObject<Block> block = BlockRegistryBuilder
                .create()
                .withName(name)
                .registerBlock(BLOCKS, () -> new HangingPostBlock(woodType))
                .build();
        HANGING_POST_BLOCKS.put(woodType, block);
        SEAT_BLOCKS.add(block);
        return block;
    }

    public static @NotNull HangingPostBlock getHangingPostBlock(WoodType content) {
        return (HangingPostBlock) HANGING_POST_BLOCKS.get(content).get();
    }

    public static @NotNull HangingPostBlock @NotNull [] getHangingPostBlocks() {
        return HANGING_POST_BLOCKS.values().stream().map(RegistryObject::get).map(HangingPostBlock.class::cast).toArray(HangingPostBlock[]::new);
    }

    public static void register(IEventBus eventBus) {
        BLOCKS.register(eventBus);
    }
}
