Minecraft 1.16.5模组开发(三十一) 自定义建筑生成(structure) (新)

本文详细指导了如何在Minecraft 1.16.5中自动生成建筑,包括创建.nbt文件、配置结构模板、编写结构类,并在世界生成中应用。通过实例介绍了如何使用模组和JSON配置,确保建筑在指定地形上自然出现。

如果你学习过我们之前在1.12.2的建筑生成教程,那么对本次的教程的理解可能会相对轻松。

往期回顾

Minecraft 1.12.2模组开发(十四) 建筑生成 (structure generation)
Minecraft 1.12.2模组开发(二十二) 多种建筑生成

我们本次将在1.16.5版本中实现建筑的自动生成。

1.首先我们需要生成一个建筑的.nbt文件

创建一个新世界

通过命令让我们获得一个建筑方块:

/give @s minecraft:structure_block

cr0.png

之后我们建造一个建筑

cr1.png

通过对建筑操作的坐标变换,将我们这个建筑完全包裹在区域内:

cr2.png

点击’Save’,建筑成功保存下来

cr3.png

保存的建筑会生成一个.nbt文件,我们需要将这个文件找到,路径为
开发包\run\saves\1_8version_test(你的存档名称)\generated\minecraft\structures

2.在data包中新建structures文件夹,将生成的.nbt文件放入其中。

cr4.png

3.在worldgen文件夹中新建template_pool(建筑模板库)文件夹 -> 新建一个与我们建筑名称对应的文件夹(以tank1为例) -> 在tank1中新建一个start_pool.json文件

在start_pool.json中编写:
{
  "name": "re8joymod:tank1/start_pool", //格式:模组名:建筑名称/start_pool的文件路径
  "fallback": "minecraft:empty",
  "elements": [
    {
      "weight": 1,
      "element": {
        "location": "re8joymod:tank1",  //格式:模组名:建筑名称
        "processors": "minecraft:empty",
        "projection": "rigid",
        "element_type": "minecraft:single_pool_element"
      }
    }
  ]
}

4.在common文件夹下新建 world文件夹 -> world文件夹中新建structure文件夹 -> structure文件夹中新建 structures文件夹 -> structures中新建一个建筑物类(以Tank1Structure.java为例)

cr5.png

在Tank1Structure.java中编写:
package com.joy187.re8joymod.common.world.structure.structures;

import com.google.common.collect.ImmutableList;
import com.mojang.serialization.Codec;
import net.minecraft.entity.EntityType;
import net.minecraft.util.SharedSeedRandom;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.ChunkPos;
import net.minecraft.util.math.MutableBoundingBox;
import net.minecraft.util.math.vector.Vector3i;
import net.minecraft.util.registry.Registry;
import net.minecraft.world.IBlockReader;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.biome.MobSpawnInfo;
import net.minecraft.world.biome.provider.BiomeProvider;
import net.minecraft.world.gen.ChunkGenerator;
import net.minecraft.world.gen.GenerationStage;
import net.minecraft.world.gen.Heightmap;
import net.minecraft.world.gen.feature.NoFeatureConfig;
import net.minecraft.world.gen.feature.jigsaw.JigsawManager;
import net.minecraft.world.gen.feature.structure.*;
import net.minecraft.util.registry.DynamicRegistries;
import net.minecraft.world.gen.feature.template.TemplateManager;
import net.minecraft.block.BlockState;
import net.minecraft.util.ResourceLocation;
import com.joy187.re8joymod.Utils;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;

import java.util.List;

public class Tank1Structure extends Structure<NoFeatureConfig> {

    public Tank1Structure(Codec<NoFeatureConfig> codec) {
        super(codec);
    }

    @Override
    public IStartFactory<NoFeatureConfig> getStartFactory() {
        return Tank1Structure.Start::new;
    }

    @Override
    public GenerationStage.Decoration step() {
        return GenerationStage.Decoration.SURFACE_STRUCTURES;
    }

    private static final List<MobSpawnInfo.Spawners> STRUCTURE_MONSTERS = ImmutableList.of(
            new MobSpawnInfo.Spawners(EntityType.ILLUSIONER, 10, 1, 4),
            new MobSpawnInfo.Spawners(EntityType.VINDICATOR, 10, 1, 4)
    );

    private static final List<MobSpawnInfo.Spawners> STRUCTURE_CREATURES = ImmutableList.of(
            new MobSpawnInfo.Spawners(EntityType.SHEEP, 10, 1, 5),
            new MobSpawnInfo.Spawners(EntityType.RABBIT, 10, 1, 4)
    );

    @Override
    public List<MobSpawnInfo.Spawners> getDefaultSpawnList() {
        return STRUCTURE_MONSTERS;
    }

    @Override
    public List<MobSpawnInfo.Spawners> getDefaultCreatureSpawnList() {
        return STRUCTURE_CREATURES;
    }


    @Override
    protected boolean isFeatureChunk(ChunkGenerator chunkGenerator, BiomeProvider biomeSource,
                                     long seed, SharedSeedRandom chunkRandom, int chunkX, int chunkZ,
                                     Biome biome, ChunkPos chunkPos, NoFeatureConfig featureConfig) {
        BlockPos centerOfChunk = new BlockPos((chunkX << 4) + 7, 0, (chunkZ << 4) + 7);
        int landHeight = chunkGenerator.getBaseHeight(centerOfChunk.getX(), centerOfChunk.getZ(), Heightmap.Type.WORLD_SURFACE_WG);

        IBlockReader columnOfBlocks = chunkGenerator.getBaseColumn(centerOfChunk.getX(), centerOfChunk.getZ());
        BlockState topBlock = columnOfBlocks.getBlockState(centerOfChunk.above(landHeight));

        return topBlock.getFluidState().isEmpty();
    }


    @Override
    public boolean getDefaultRestrictsSpawnsToInside() {
        return 
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jay_fearless

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值