# 簡單礦物生成
如有問題請及時指出,謝謝閱讀!
*****
## 序
游戲里的世界地殼蘊藏著大量礦物,如煤礦石,1.17前礦脈還并未加入,但有**團簇**,他們是以團簇的形式生成的,一個團簇聚合著幾個礦石。那么模組中的礦物應該如何加入到世界中去呢?本教程將以羊毛為例子教你添加礦物**地形特征**,以及簡單的生成參數。
## 地形特征
地形特征會在世界中生成,上述的團簇便是一種地形特征,在源碼中類路徑為`net.minecraft.world.gen.feature.Feature`,這個類中聲明了大量的地形特征,其中`ORE`便是生成礦物的特征了,其聲明如下:`public static final Feature ORE = register("ore", newOreFeature(OreFeatureConfig::deserialize));`如果你善于看源碼,通過查找用法不難發現它的創建方法,在`net.minecraft.world.biome.DefaultBiomeFeatures`類中提供了大量方便的默認方法,可以看出這些地形特征都是指定生物群系加入的,其中`addDefaultOres`方法為某群系添加默認的礦物,代碼如下:
```
public static void?addDefaultOres(Biome?biome) {?
biome.addFeature(GenerationStep.Feature.UNDERGROUND_ORES,?Feature.ORE
.configure(new?OreFeatureConfig(OreFeatureConfig.Target.NATURAL_STONE,?COAL_ORE,?17))
.createDecoratedFeature(Decorator.COUNT_RANGE.configure(new?RangeDecoratorConfig(20,?0,?0,?128))));?
//...
}
```
源碼通過調用`biome`對象的`addFeature`方法,將地形特征加入其中,第一個參數是類型,地下礦物傳入`GenerationStep.Feature.UNDERGROUND_ORES`即可;第二個是欲添加的地形特征,需要一個**已配置的地形特征(ConfiguredFeature)**,這便是我們所關注的了,源碼通過調用`Feature`類的`configure`方法創建已配置的地形特征,需要一個對應的特征配置,這里是`OreFeatureConfig`,下面是它的構造器方法參數列表:
| 參數 | 解釋 |
| --- | --- |
| `OreFeatureConfig.Target target` | 生成該礦物可替換掉的方塊,只有兩種值可用:<br>`NATURAL_STONE`:主世界地殼方塊;<br>`NETHERRACK`:下界地殼方塊。 |
| `BlockState state` | 礦物方塊,調用`block.getDefaultState()`獲取。 |
| `int size` | 每個礦簇最大的方塊數量。 |
接下來連續調用createDecoratedFeature來為之添加裝飾器,以設置礦簇在地殼中的發布狀況,需要傳入一個**已配置的裝飾器(ConfiguredDecorator)**,和地形特征一樣,為選好的裝飾器調用configure方法傳入對應配置創建即可。下面是常見的礦物裝飾器及其配置:
| 裝飾器類型 | 配置及構造器 |
| --- | --- |
| `COUNT_RANGE`<br>每個區塊最大數量和范圍 | `RangeDecoratorConfig`<br>構造器:<br>`int count`:每個區塊生成的最大數量<br>`int bottomOffset`:最低生成高度<br>`int topOffset`:最高高度偏移<br>`int maximum`:最高生成高度(實際最高高度為`maximum - topOffset`,可能是為結構預留的高度) |
| `COUNT_DEPTH_AVERAGE`<br>每個區塊最大數量和平均位置 | `CountDepthDecoratorConfig`<br>構造器:<br>`int count`<br>`int baseline`:平均高度<br>`int spread`:蔓延范圍 |
| `EMERALD_ORE`<br>綠寶石礦石專用 | 固定為?`DecoratorConfig.DEFAULT` |
這便是地形特征的創建方式,以下是我們的羊毛礦代碼:
```
private static final ConfiguredFeature WOOL_ORE = Feature.ORE.configure(new OreFeatureConfig(OreFeatureConfig.Target.NATURAL_STONE, Blocks.WOOL.getDefaultState(), 6)).createDecoratedFeature(Decorator.COUNT_RANGE.configure(new RangeDecoratorConfig(20, 0, 0, 64)));
```
## 添加到世界
上述源碼中使用biome.addFeature方法將地形特征加入到某群系中,我們可用通過 Fabric 提供的注冊表方法遍歷現有群系,然后注冊一個偵聽器,以供將來添加。
```
@Override
public void onInitialize() {
?? ?? ? Registry.BIOME.forEach(this::handleBiome);
?? ?? ? RegistryEntryAddedCallback.event(Registry.BIOME).register((i, identifier, biome) -> handleBiome(biome));
?? ?? ? //...
}
```
```
private static void handleBiome(Biome biome) {
?? ?? ? if(biome.getCategory() != Biome.Category.NETHER && biome.getCategory() != Biome.Category.THEEND) {
? ?? ?? ?? ?? ? biome.addFeature(GenerationStep.Feature.UNDERGROUND_ORES, WOOL\_ORE);
?? ?? ? }
}
```
遍歷代碼中使用`biome.getCategory() != Biome.Category.NETHER && biome.getCategory() != Biome.Category.THEEND`判斷是否為主世界的生物群系,還可以增加判斷以在不同的生物群系生成不同規模的礦簇。快創建世界看下成果吧!使用右側指令清除石頭:`/fill ~-8 0 ~-8 ~8 ~ ~8 minecraft:air replace minecraft:stone`
*Fabric Wiki 效果圖*
*****
感謝閱讀,編寫不易,您的支持是我最大的動力!