Minecraft 1.19.2 Forge模组开发 05.矿石生成

我们本次尝试在主世界生成模组中自定义的矿石

1.由于1.19的版本出现了深板岩层的矿石,我们要在BlockInit类中声明一个矿石的两种岩层形态:

BlockInit.java

package com.joy187.re8joymod.init;

import com.joy187.re8joymod.Main;
import net.minecraft.core.BlockPos;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.item.BlockItem;
import net.minecraft.world.item.CreativeModeTab;
import net.minecraft.world.item.DyeColor;
import net.minecraft.world.item.Item;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.SoundType;
import net.minecraft.world.level.block.StainedGlassBlock;
import net.minecraft.world.level.block.state.BlockBehaviour;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Material;
import net.minecraft.world.level.material.MaterialColor;
import net.minecraftforge.registries.DeferredRegister;
import net.minecraftforge.registries.ForgeRegistries;
import net.minecraftforge.registries.RegistryObject;

import java.util.function.Function;
import java.util.function.Supplier;

public class BlockInit {
    public static DeferredRegister<Block> BLOCKS = DeferredRegister.create(ForgeRegistries.BLOCKS, Main.MOD_ID);
    public static final DeferredRegister<Item> ITEMS = ItemInit.ITEMS;

    //普通矿石,UniformInt.of(a,b)意思是该矿石挖掘后奖励多少经验,范围在[a,b]
    public static final RegistryObject<Block> FANTOM_ORE = registerBlock("fantom_ore",
            () -> new DropExperienceBlock(BlockBehaviour.Properties.of(Material.STONE)
                    .strength(5f).requiresCorrectToolForDrops(), UniformInt.of(3, 10)), Main.TUTORIAL_TAB);
    
    //深板岩矿石
    public static final RegistryObject<Block> DEEPSLATE_FANTOM_ORE = registerBlock("deepslate_fantom_ore",
            () -> new Block(BlockBehaviour.Properties.of(Material.STONE)
                    .strength(7f).requiresCorrectToolForDrops()), Main.TUTORIAL_TAB);


    private static <T extends Block> RegistryObject<T> registerBlock(final String name,
                                                                     final Supplier<? extends T> block) {
        return BLOCKS.register(name, block);
    }

    private static <T extends Block> RegistryObject<T> register(final String name, final Supplier<? extends T> block,
                                                                Function<RegistryObject<T>, Supplier<? extends Item>> item) {
        RegistryObject<T> obj = registerBlock(name, block);
        ITEMS.register(name, item.apply(obj));
        return obj;
    }

    private static <T extends Block> RegistryObject<T> registerBlock(String name, Supplier<T> block, CreativeModeTab tab) {
        RegistryObject<T> toReturn = BLOCKS.register(name, block);
        registerBlockItem(name, toReturn, tab);
        return toReturn;
    }

    private static <T extends Block> RegistryObject<Item> registerBlockItem(String name, RegistryObject<T> block,
                                                                            CreativeModeTab tab) {
        return ItemInit.ITEMS.register(name, () -> new BlockItem(block.get(),
                new Item.Properties().tab(tab)));
    }

    private static <T extends Block> RegistryObject<T> registerBlockWithoutBlockItem(String name, Supplier<T> block) {
        return BLOCKS.register(name, block);
    }

    public static Supplier<Block> createStainedGlassFromColor(DyeColor color) {
        return () -> new StainedGlassBlock(color, BlockBehaviour.Properties.of(Material.GLASS, color).strength(0.3F)
                .sound(SoundType.GLASS).noOcclusion().isValidSpawn(BlockInit::never).isRedstoneConductor(BlockInit::never).isSuffocating(BlockInit::never).isViewBlocking(BlockInit::never));
    }

    public static boolean always(BlockState state, BlockGetter reader, BlockPos pos) {
        return true;
    }

    public static boolean never(BlockState state, BlockGetter reader, BlockPos pos) {
        return false;
    }

    public static boolean always(BlockState state, BlockGetter reader, BlockPos pos, EntityType<?> entityType) {
        return true;
    }

    public static boolean never(BlockState state, BlockGetter reader, BlockPos pos, EntityType<?> entityType) {
        return false;
    }
}

之后参考Minecraft 1.19.2 Forge模组开发 02.物品栏+方块+物品将两个方块制作出来。

2.准备好了方块,下一步就是定义其生成的内容了。在Java包中新建一个world包->world包中新建一个feature包->feature包中分别新建三个类ModConfiguredFeaturesModOrePlacementModPlacedFeatures

Minecraft 1.19.2 Forge模组开发 05.矿石生成_第1张图片

首先是我们的矿石摆放类:

ModOrePlacement.java

package com.joy187.re8joymod.world.feature;

import net.minecraft.world.level.levelgen.placement.*;

import java.util.List;

public class ModOrePlacement {
    //默认矿石摆放
    public static List<PlacementModifier> orePlacement(PlacementModifier p_195347_, PlacementModifier p_195348_) {
        return List.of(p_195347_, InSquarePlacement.spread(), p_195348_, BiomeFilter.biome());
    }
    
    //普通矿石摆放
    public static List<PlacementModifier> commonOrePlacement(int p_195344_, PlacementModifier p_195345_) {
        return orePlacement(CountPlacement.of(p_195344_), p_195345_);
    }
    
    //稀有矿石摆放
    public static List<PlacementModifier> rareOrePlacement(int p_195350_, PlacementModifier p_195351_) {
        return orePlacement(RarityFilter.onAverageOnceEvery(p_195350_), p_195351_);
    }

}

其次是我们的矿石生成定义类ModPlacedFeatures

ModPlacedFeatures.java

package com.joy187.re8joymod.world.feature;

import com.joy187.re8joymod.Main;
import net.minecraft.core.Registry;
import net.minecraft.world.level.levelgen.VerticalAnchor;
import net.minecraft.world.level.levelgen.placement.*;
import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.registries.DeferredRegister;
import net.minecraftforge.registries.RegistryObject;

import static com.joy187.re8joymod.world.feature.ModOrePlacement.commonOrePlacement;

public class ModPlacedFeatures {
    public static final DeferredRegister<PlacedFeature> PLACED_FEATURES =
            DeferredRegister.create(Registry.PLACED_FEATURE_REGISTRY, Main.MOD_ID);

    //矿石摆放
    public static final RegistryObject<PlacedFeature> FANTOM_ORE_PLACED = PLACED_FEATURES.register("fantom_ore_placed",
            () -> new PlacedFeature(ModConfiguredFeatures.FANTOM_ORES.getHolder().get(),
                    commonOrePlacement(7, //每个区块生成多少矿石
                            HeightRangePlacement.triangle(VerticalAnchor.aboveBottom(-60), VerticalAnchor.aboveBottom(60))))); //-60,60分别指矿石生成高度范围介于[-60,60]



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

}

最后是矿石生成配置类ModConfiguredFeatures

ModConfiguredFeatures.java

package com.joy187.re8joymod.world.feature;

import com.google.common.base.Suppliers;
import com.joy187.re8joymod.Main;
import com.joy187.re8joymod.init.BlockInit;
import net.minecraft.core.Registry;
import net.minecraft.data.worldgen.features.OreFeatures;
import net.minecraft.world.level.levelgen.feature.ConfiguredFeature;
import net.minecraft.world.level.levelgen.feature.Feature;
import net.minecraft.world.level.levelgen.feature.configurations.*;
import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.registries.DeferredRegister;
import net.minecraftforge.registries.RegistryObject;

import java.util.List;
import java.util.function.Supplier;


public class ModConfiguredFeatures {

    public static final DeferredRegister<ConfiguredFeature<?, ?>> CONFIGURED_FEATURES =
            DeferredRegister.create(Registry.CONFIGURED_FEATURE_REGISTRY, Main.MOD_ID);

    //将我们第一步的两种矿石分别填入其中
    public static final Supplier<List<OreConfiguration.TargetBlockState>> OVERWORLD_FANTOM_ORES = Suppliers.memoize(() -> List.of(
            OreConfiguration.target(OreFeatures.STONE_ORE_REPLACEABLES, BlockInit.FANTOM_ORE.get().defaultBlockState()), //普通岩层
            OreConfiguration.target(OreFeatures.DEEPSLATE_ORE_REPLACEABLES, BlockInit.DEEPSLATE_FANTOM_ORE.get().defaultBlockState()))); //深板岩层

    //将这种矿石生成类型进行注册
    public static final RegistryObject<ConfiguredFeature<?, ?>> FANTOM_ORES = CONFIGURED_FEATURES.register("fantom_ore",
            () -> new ConfiguredFeature<>(Feature.ORE, new OreConfiguration(OVERWORLD_FANTOM_ORES.get(),7)));

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

}

3.在项目主类中添加我们矿石生成配置类和矿石生成定义类的注册事件:

    public Main()
    {
        IEventBus bus = FMLJavaModLoadingContext.get().getModEventBus();
        bus.addListener(this::commonSetup);
        bus.addListener(this::setup);
        bus.addListener(this::clientSetup);
        ItemInit.ITEMS.register(bus);
        BlockInit.BLOCKS.register(bus);
        EntityInit.ENTITY_TYPES.register(bus);
        
        //添加这两个
        ModConfiguredFeatures.register(bus);
        ModPlacedFeatures.register(bus);

        MinecraftForge.EVENT_BUS.register(this);
    }

4.代码部分结束,之后需要在数据包中添加矿石生成的内容

Minecraft 1.19.2 Forge模组开发 05.矿石生成_第2张图片

在数据包中新建forge包,forge包中新建biome_modifier包-> biome_modifier包中新建矿石生成文件add_fantom_ore,在features中填入我们在ModPlacedFeatures类中定义的名称:

add_fantom_ore.json

{
  "type": "forge:add_features",
  "biomes": "#minecraft:is_overworld",
  "features": "re8joymod:fantom_ore_placed",
  "step": "underground_ores"
}

5.保存所有设置,进入游戏:

我们新建一个存档,之后查看是否能找到模组中的矿石:

成功在深板岩层发现了矿石!

你可能感兴趣的:(我的世界,java,spring,minecraft)