Multiblock Lib 1174

Multiblock Lib 1174

自定义多方块模组

1174 的多方块库(MultiblockLib)

这是一个用于自定义多方块结构的模组。 如何使用?

00 配置项目

将本模组的 cursedmaven 添加到你的 build.gradle 中。

01 注册控制器与端口

public class Register {
    public static final DeferredRegister.Blocks BLOCKS = DeferredRegister.createBlocks(MultiblockLib.MOD_ID);
    public static final DeferredRegister.Items ITEMS = DeferredRegister.createItems(MultiblockLib.MOD_ID);

    // 1.端口
    public static final DeferredBlock<Block> TEST_ITEM_PORT_IN_B = BLOCKS.register(
            "test_item_port_in",
            //                         ↓你可以使用 ItemPortBlock、FluidPortBlock、FEPortBlock 来注册不同类型的端口
            registryName -> new ItemPortBlock(BlockBehaviour.Properties.of()
                    .setId(ResourceKey.create(Registries.BLOCK, registryName)),
                    //  ↓端口的 IO 模式,可为 INPUT、OUTPUT 或 BOTH
                    4, IOMode.INPUT
                 // ↑端口的大小
            ));

    public static final DeferredItem<Item> TEST_ITEM_PORT_IN =
            ITEMS.register("test_item_port_in",
                    registryName -> new PortBlockItem(TEST_ITEM_PORT_IN_B.get(), new Item.Properties()
                            .setId(ResourceKey.create(Registries.ITEM, registryName)),
                            IOMode.INPUT
                    ));

    // 如果你的端口没有方向性,请像这样注册
    public static final DeferredBlock<Block> TEST_WASTE_B = BLOCKS.register(
            "test_waste",
            registryName -> new ItemPortBlock(BlockBehaviour.Properties.of()
                    .setId(ResourceKey.create(Registries.BLOCK, registryName)),
                    1, IOMode.OUTPUT
            ) {
                @Override
                public boolean isDirectional() {
                    return false;
                }
            });

    // 2.探测器,可以让玩家知道在哪里放置方块
    public static final DeferredItem<Item> TEST_DETECTOR =
            ITEMS.register("test_detector",
                    registryName -> new MultiblockDetector(new Item.Properties()
                            .setId(ResourceKey.create(Registries.ITEM, registryName))
                    ));

    // 3.建造器,可以自动建造结构
    public static final DeferredItem<Item> TEST_BUILDER =
            ITEMS.register("test_builder",
                    registryName -> new MultiblockBuilder(new Item.Properties()
                            .setId(ResourceKey.create(Registries.ITEM, registryName))
                    ));
}

最困难的部分是控制器。 首先,编写控制器的 BlockEntity 代码。

public class TestControllerBlockEntity extends ControllerBlockEntity {
    public TestControllerBlockEntity(BlockPos worldPosition, BlockState blockState) {
        super(Register.TEST_CONTROLLER_BE.get(), worldPosition, blockState);
        //    ↑这是它的方块实体类型,我们稍后会编写它们
    }

    // 这两个值都可以动态修改
    // 机器同时能处理的配方数量
    @Override
    public int getParallels() {
        return 1;
    }

    // 速度。越大越快
    @Override
    public int getParseSpeed() {
        return 1;
    }
}

接着,编写其方块类。

public class TestControllerBlock extends ControllerBlock {
    public TestControllerBlock(Properties properties) {
        super(properties);
    }

    @Override
    public @Nullable <T extends BlockEntity> BlockEntityTicker<T> getTicker(Level level, BlockState blockState, BlockEntityType<T> type) {
        return createTickerHelper(type, Register.TEST_CONTROLLER_BE.get(), TestControllerBlockEntity::tick);
        //                              ↑这是它的方块注册,我们稍后会编写它们
    }

    @Override
    protected MapCodec<? extends BaseEntityBlock> codec() {
        return simpleCodec(TestControllerBlock::new);
    }

    @Override
    public @Nullable BlockEntity newBlockEntity(BlockPos blockPos, BlockState blockState) {
        return new TestControllerBlockEntity(blockPos, blockState);
    }
}

最后,回到你的注册类中。

public static final DeferredRegister<BlockEntityType<?>> BLOCK_ENTITY_TYPES =
        DeferredRegister.create(Registries.BLOCK_ENTITY_TYPE, MultiblockLib.MOD_ID);

public static final DeferredBlock<Block> TEST_CONTROLLER_B = BLOCKS.register(
        "test_controller",
        registryName -> new TestControllerBlock(BlockBehaviour.Properties.of()
                .setId(ResourceKey.create(Registries.BLOCK, registryName))
        ));

public static final DeferredItem<Item> TEST_CONTROLLER =
        ITEMS.register("test_controller",
                registryName -> new BlockItem(TEST_CONTROLLER_B.get(), new Item.Properties()
                        .setId(ResourceKey.create(Registries.ITEM, registryName))
                ));

public static final Supplier<BlockEntityType<TestControllerBlockEntity>> TEST_CONTROLLER_BE = BLOCK_ENTITY_TYPES.register(
        "test_controller",
        () -> new BlockEntityType<>(
                TestControllerBlockEntity::new,
                false,
                TEST_CONTROLLER_B.get()
        )
);

02 结构

在你的世界中建造你的结构。 使用这个命令:

/multiblocklibes structure -104 56 -61 -109 59 -64 -99 56 -61 TestExport

第一个 BlockPos 是控制器坐标。 第二个和第三个是两个角落的方块坐标。 字符串部分是文件名。 在 /GameFile/multiblockes/xxx.json 路径下找到你的文件。 这是一个配方 JSON 文件:

{
    "type": "multiblocklibes:structure",
    // 结构的 ID
    "structure_id": "blast",
    // 控制器的方块 ID
    "controller_id": "multiblocklibes:test_controller",
    "pattern": [
        // 方块可以出现在某些位置,这是一个 JSON 数组
        [1, 0, 0, ["minecraft:oxidized_cut_copper", "multiblocklibes:test_item_port_in", "multiblocklibes:test_item_port_ou", "multiblocklibes:test_fluid_port_in", "multiblocklibes:test_fluid_port_ou", "multiblocklibes:test_fe_port"]],
        [-1, 0, 0, ["minecraft:oxidized_cut_copper", "multiblocklibes:test_item_port_in", "multiblocklibes:test_item_port_ou", "multiblocklibes:test_fluid_port_in", "multiblocklibes:test_fluid_port_ou", "multiblocklibes:test_fe_port"]],
        [1, 0, 1, ["minecraft:oxidized_cut_copper", "multiblocklibes:test_item_port_in", "multiblocklibes:test_item_port_ou", "multiblocklibes:test_fluid_port_in", "multiblocklibes:test_fluid_port_ou", "multiblocklibes:test_fe_port"]],
        [-1, 0, 1, ["minecraft:oxidized_cut_copper", "multiblocklibes:test_item_port_in", "multiblocklibes:test_item_port_ou", "multiblocklibes:test_fluid_port_in", "multiblocklibes:test_fluid_port_ou", "multiblocklibes:test_fe_port"]],
        [1, 0, 2, ["minecraft:oxidized_cut_copper", "multiblocklibes:test_item_port_in", "multiblocklibes:test_item_port_ou", "multiblocklibes:test_fluid_port_in", "multiblocklibes:test_fluid_port_ou", "multiblocklibes:test_fe_port"]],
        [0, 0, 2, ["minecraft:oxidized_cut_copper", "multiblocklibes:test_item_port_in", "multiblocklibes:test_item_port_ou", "multiblocklibes:test_fluid_port_in", "multiblocklibes:test_fluid_port_ou", "multiblocklibes:test_fe_port"]],
        [-1, 0, 2, ["minecraft:oxidized_cut_copper", "multiblocklibes:test_item_port_in", "multiblocklibes:test_item_port_ou", "multiblocklibes:test_fluid_port_in", "multiblocklibes:test_fluid_port_ou", "multiblocklibes:test_fe_port"]],
        [0, 0, 1, ["minecraft:oxidized_cut_copper", "multiblocklibes:test_item_port_in", "multiblocklibes:test_item_port_ou", "multiblocklibes:test_fluid_port_in", "multiblocklibes:test_fluid_port_ou", "multiblocklibes:test_fe_port"]],

        [1, 3, 0, ["minecraft:oxidized_cut_copper", "multiblocklibes:test_item_port_in", "multiblocklibes:test_item_port_ou", "multiblocklibes:test_fluid_port_in", "multiblocklibes:test_fluid_port_ou", "multiblocklibes:test_fe_port"]],
        [0, 3, 0, ["minecraft:oxidized_cut_copper", "multiblocklibes:test_item_port_in", "multiblocklibes:test_item_port_ou", "multiblocklibes:test_fluid_port_in", "multiblocklibes:test_fluid_port_ou", "multiblocklibes:test_fe_port"]],
        [-1, 3, 0, ["minecraft:oxidized_cut_copper", "multiblocklibes:test_item_port_in", "multiblocklibes:test_item_port_ou", "multiblocklibes:test_fluid_port_in", "multiblocklibes:test_fluid_port_ou", "multiblocklibes:test_fe_port"]],
        [1, 3, 1, ["minecraft:oxidized_cut_copper", "multiblocklibes:test_item_port_in", "multiblocklibes:test_item_port_ou", "multiblocklibes:test_fluid_port_in", "multiblocklibes:test_fluid_port_ou", "multiblocklibes:test_fe_port"]],
        [-1, 3, 1, ["minecraft:oxidized_cut_copper", "multiblocklibes:test_item_port_in", "multiblocklibes:test_item_port_ou", "multiblocklibes:test_fluid_port_in", "multiblocklibes:test_fluid_port_ou", "multiblocklibes:test_fe_port"]],
        [1, 3, 2, ["minecraft:oxidized_cut_copper", "multiblocklibes:test_item_port_in", "multiblocklibes:test_item_port_ou", "multiblocklibes:test_fluid_port_in", "multiblocklibes:test_fluid_port_ou", "multiblocklibes:test_fe_port"]],
        [0, 3, 2, ["minecraft:oxidized_cut_copper", "multiblocklibes:test_item_port_in", "multiblocklibes:test_item_port_ou", "multiblocklibes:test_fluid_port_in", "multiblocklibes:test_fluid_port_ou", "multiblocklibes:test_fe_port"]],
        [-1, 3, 2, ["minecraft:oxidized_cut_copper", "multiblocklibes:test_item_port_in", "multiblocklibes:test_item_port_ou", "multiblocklibes:test_fluid_port_in", "multiblocklibes:test_fluid_port_ou", "multiblocklibes:test_fe_port"]],

        [0, 1, 0, ["minecraft:diamond_block", "minecraft:emerald_block"]],
        [1, 1, 0, ["minecraft:diamond_block", "minecraft:emerald_block"]],
        [-1, 1, 0, ["minecraft:diamond_block", "minecraft:emerald_block"]],
        [1, 1, 1, ["minecraft:diamond_block", "minecraft:emerald_block"]],
        [-1, 1, 1, ["minecraft:diamond_block", "minecraft:emerald_block"]],
        [1, 1, 2, ["minecraft:diamond_block", "minecraft:emerald_block"]],
        [0, 1, 2, ["minecraft:diamond_block", "minecraft:emerald_block"]],
        [-1, 1, 2, ["minecraft:diamond_block", "minecraft:emerald_block"]],

        [0, 2, 0, ["minecraft:diamond_block", "minecraft:emerald_block"]],
        [1, 2, 0, ["minecraft:diamond_block", "minecraft:emerald_block"]],
        [-1, 2, 0, ["minecraft:diamond_block", "minecraft:emerald_block"]],
        [1, 2, 1, ["minecraft:diamond_block", "minecraft:emerald_block"]],
        [-1, 2, 1, ["minecraft:diamond_block", "minecraft:emerald_block"]],
        [1, 2, 2, ["minecraft:diamond_block", "minecraft:emerald_block"]],
        [0, 2, 2, ["minecraft:diamond_block", "minecraft:emerald_block"]],
        [-1, 2, 2, ["minecraft:diamond_block", "minecraft:emerald_block"]],

        [0, 3, 1, ["multiblocklibes:test_waste"]]
    ],
    "requirements": [
        // 结构要求
    ]
}

你也可以在“结构要求”中添加内容。

{
    // 结构中方块的数量
    "id": "right_count_blocks_structure_requirement",
    "property": [
        ["multiblocklibes:test_fe_port"],
        1
    ]
}
{
    "id": "max_blocks_structure_requirement",
    "property": [
        ["multiblocklibes:test_fe_port"],
        1
    ]
}
{
    "id": "min_blocks_structure_requirement",
    "property": [
        ["multiblocklibes:test_fe_port"],
        1
    ]
}
// 为结构添加描述
// 可翻译文本
{
    "id": "desc_structure_requirement",
    "property": [
        "tran",
        "key.modid.sth"
    ]
},
// 字面文本
{
    "id": "desc_structure_requirement",
    "property": [
        "lite",
        "Also Trys War Thunder !!"
    ]
}
// 某些方块需要相同
{
    "id": "same_block_structure_requirement",
    "property": [
        [0, 1, 0],
        [1, 1, 0],
        [-1, 1, 0],
        [1, 1, 1],
        [-1, 1, 1],
        [1, 1, 2],
        [0, 1, 2],
        [-1, 1, 2],

        [0, 2, 0],
        [1, 2, 0],
        [-1, 2, 0],
        [1, 2, 1],
        [-1, 2, 1],
        [1, 2, 2],
        [0, 2, 2],
        [-1, 2, 2]
    ]
}

03 配方

这是一个示例配方。

{
    "type": "multiblocklibes:recipe",
    // 配方所需时间
    "time": 100,
    // 配方 ID
    "recipe_id": "blast_revipe_test",
    // 绑定的结构
    "structure_id": "blast",
    "requirements": [
        // 配方的资源要求
    ]
}

配方资源要求:

// 物品要求
{
    "id": "item_recipe_requirement",
    "property": [
        "input",
        "minecraft:iron_ingot",
        3
    ]
},
{
    "id": "item_recipe_requirement",
    "property": [
        "output",
        "minecraft:netherite_ingot",
        1,
        // 如果你希望物品只能通过指定类型的端口输出
        // 也可用于流体和 FE 的要求
        ["multiblocklibes:test_item_port_ou"]
    ]
}
{
    "id": "fluid_recipe_requirement",
    "property": [
        "output",
        "mod_id:some_fluid",
        2
    ]
}
{
    "id": "fe_recipe_requirement",
    "property": [
        "input",
        5000
    ]
}
{
    "id": "block_recipe_requirement",
    "property": [
        // 输入时不会破坏方块
        "input",
        ["modid:blovkkkkk"],
        0,3,0
    ]
}
{
    "id": "command_recipe_requirement",
    "property": [
        // 执行时,是输入还是输出!
        "input",
        "summon modid:sth_mob",
        0,3,0
    ]
}
{
    "id": "desc_recipe_requirement",
    "property": [
        // 执行时,是输入还是输出!
        "input",
        "tran",
        "key.modid.eeeeeee"
    ]
}
{
    // 结构中方块的数量
    "id": "right_count_blocks_structure_requirement",
    "property": [
        ["modid:sth_block"],
        10
    ]
}
{
    "id": "min_count_blocks_structure_requirement",
    "property": [
        ["modid:sth_block"],
        10
    ]
}
{
    "id": "max_count_blocks_structure_requirement",
    "property": [
        ["modid:sth_block"],
        10
    ]
}