Minecraft 1.14.4 Forge Modの作成 その8 【鉱石の追加と生成】

# はじめに
鉱石を追加し、ワールド生成時に鉱石が生成されるようにしてみます。

今回、参考サイトを通りに手順を進め、鉱石を生成させることに成功しましたが、
自分の理解が追い付きませんでした。

ソースコードを眺め、ある程度調べてみましたが、推測を多く含みます。
分かり次第、記事を更新していく予定です。

![2019-11-04_20.51.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/336583/99045d4d-e71b-76c4-c73f-087b7e11e7a0.png)
![2019-11-04_21.14.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/336583/8e7b84a1-7a93-eae4-6323-c307d6dcba66.png)

参考
[Ore Generation - Minecraft Modding Tutorial for MC 1.14/1.14.3 (Old)](https://www.youtube.com/watch?v=IZslaPN1UaM)
[Ore Generation - Minecraft Modding Tutorial for MC 1.14/1.14.4](https://www.youtube.com/watch?v=t_zr2onGhmQ)


# 💻開発環境
ここでは環境は以下のようにします。

- Windows 10
- JDK 8u211
- Minecraft 1.14.4
- Minecraft Forge 1.14.4 (28.1.0)
- IntelliJ IDEA 2019.2.3

# 鉱石ブロックの追加
[Minecraft 1.14.4 Forge Modの作成 その4 【ブロックの追加】](https://qiita.com/Hiroya_W/items/5b14f397bc52ce87255f)
を参考にブロックを追加します。

## 琵琶鉱石
![biwako_ore.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/336583/d3a99ed2-fefe-6516-498a-f3228f43cd2a.png)
![2019-11-03_23.26.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/336583/55d72352-2695-cc81-f6b2-7fbf698e762e.png)

## 琵琶湖ォーツ
![biwako_quartz_ore.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/336583/c106ebb4-7c84-092d-41c6-4b9791c9b91e.png)
![2019-11-04_20.27.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/336583/22644c4d-9f37-9265-6dc6-8ce2e547a2a5.png)

# パッケージ、クラスファイルの作成
`jp/yuyu/biwako_mod/config`フォルダを作成し、
フォルダ内に、`Config.java`、`OregenConfig.java`ファイルを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/336583/adcc1004-7211-1d84-f7dc-3c3f3a5fc9ba.png)

`jp/yuyu/biwako_mod/world`フォルダを作成し、
フォルダ内に、`OreGeneration.java`ファイルを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/336583/0824be7d-8820-a877-873f-dd5752694ec0.png)

# Loggerをpublicに修正する

```BiwakoMod.java
public static final Logger LOGGER = LogManager.getLogger(MOD_ID);
```

# Config.java
## ソースコード
ソースコード内の`BiwakoMod`の部分を各自変更してください。

```Config.java
package jp.yuyu.biwako_mod.config;

import java.io.File;

import com.electronwill.nightconfig.core.file.CommentedFileConfig;
import com.electronwill.nightconfig.core.io.WritingMode;

import jp.yuyu.biwako_mod.BiwakoMod;
import net.minecraftforge.common.ForgeConfigSpec;
import net.minecraftforge.fml.common.Mod;

@Mod.EventBusSubscriber
public class Config
{
    private static final ForgeConfigSpec.Builder SERVER_BUILDER = new ForgeConfigSpec.Builder();
    public static final ForgeConfigSpec SERVER;

    private static final ForgeConfigSpec.Builder CLIENT_BUILDER = new ForgeConfigSpec.Builder();
    public static final ForgeConfigSpec CLIENT;

    static
    {
        OregenConfig.init(SERVER_BUILDER, CLIENT_BUILDER);

        SERVER = SERVER_BUILDER.build();
        CLIENT = CLIENT_BUILDER.build();
    }

    public static void loadConfig(ForgeConfigSpec config, String path)
    {
        BiwakoMod.LOGGER.info("Loading config: " + path);
        final CommentedFileConfig file = CommentedFileConfig.builder(new File(path)).sync().autosave().writingMode(WritingMode.REPLACE).build();
        BiwakoMod.LOGGER.info("Built config: " + path);
        file.load();
        BiwakoMod.LOGGER.info("Loaded config: " + path);
        config.setConfig(file);
    }
}
```

## 役割

`runClient`実行時に生成される`run`フォルダ内に`config`フォルダがあり、
その中に、`forge-client.toml`ファイルがあります。

中身はこんな感じ。

```toml:forge-client.toml

#Client only settings, mostly things related to rendering
[client]
	#Disable culling of hidden faces next to stairs and slabs. Causes extra rendering, but may fix some resource packs that exploit this vanilla mechanic.
	disableStairSlabCulling = false
	#Allow item rendering to detect emissive quads and draw them properly. This allows glowing blocks to look the same in item form, but incurs a very slight performance hit.
	allowEmissiveItems = true
	#Toggle off to make missing model text in the gui fit inside the slot.
	zoomInMissingModelTextInGui = false
	#Enable forge to queue all chunk updates to the Chunk Update thread.
	#May increase FPS significantly, but may also cause weird rendering lag.
	#Not recommended for computers without a significant number of cores available.
	alwaysSetupTerrainOffThread = false
	#Enable the forge block rendering pipeline - fixes the lighting of custom models.
	forgeLightPipelineEnabled = true
	#When enabled, forge will show any warnings that occurred during loading
	showLoadWarnings = true
	#Enable uploading cloud geometry to the GPU for faster rendering.
	forgeCloudsEnabled = true
	#When enabled, makes specific reload tasks such as language changing quicker to run.
	selectiveResourceReloadEnabled = true
```

おそらく、`Config.java`はこのコンフィグファイルを扱うために用意する必要があるのだと思います。
`Server`のコンフィグはこの時は生成されない（？）みたいです

# OregenConfig
## ソースコード
各自変更しておく部分は、

- ForgeConfigSpec.IntValueの変数名
- ForgeConfigSpec.Builder.commentメソッドの引数
- ForgeConfigSpec.Builder.defineInRangeメソッドの引数

です。解説はこの下に記載しています。

```OregenConfig.java
package jp.yuyu.biwako_mod.config;

import jp.yuyu.biwako_mod.BiwakoMod;
import net.minecraftforge.common.ForgeConfigSpec;

public class OregenConfig
{
    public static ForgeConfigSpec.IntValue biwako_ore_chance;
    public static ForgeConfigSpec.BooleanValue generate_overworld;

    public static void init(ForgeConfigSpec.Builder server, ForgeConfigSpec.Builder client)
    {
        BiwakoMod.LOGGER.info("OregenConfig init");
        server.comment("Oregen Config");

        biwako_ore_chance = server
                .comment("Maximum number of ore veins of the biwako ore that can spawn in one chunk.")
                .defineInRange("oregen.biwako_ore_chance", 20, 1, 1000000);

        generate_overworld = server
                .comment("Decide if you want Biwako Mod ores to spawn in the overworld")
                .define("oregen.generate_overworld", true);
    }
}
```

## 解説
鉱石生成時のパラメータを設定するために用意するものと思われます。
先ほど作成した`Config.java`により、サーバー向けコンフィグを追加しています。

`comment`メソッドにて、コンフィグファイルに記述される`コメント`を設定します。
`define`メソッドでコンフィグの`Path`と`値`、
`defineInRange`ではコンフィグの`Path`と`デフォルト値`、`値の取りうる最小値・最大値`を設定します。

このコンフィグは`forge-client.toml`のようにファイル等の形で記憶され、ユーザが後から変更する
ことができるようになっているのだと思います。

Minecraft起動後、Mod一覧でModを選択した際にある設定がおそらく、これに当たると思うけど、
ソースコードを用意しないことには変更できないみたいです。

### biwako_ore_chance
琵琶鉱石が生成されたときその周りに何個の鉱石を生成させるか、設定します。

バニラ鉱石を例に挙げると、

- 石炭 17
- 鉄鉱石 金 9
- ダイヤモンド レッドストーン 8
- ラピスラズリ 7

です。今回はデフォルト値に20を設定したので、石炭のように大きな鉱脈が生成されるはずです。
また、取りうる値の範囲は1~1000000と設定しましたが、現状、デフォルト値以外に変更されないので、
常に20が`biwako_ore_chance`変数に格納されています。

実際のワールドには、この値を最大値としたランダムな個数の鉱脈が生成されるようになっています。

### generate_overworld
オーバーワールドに鉱石を生成するか、設定します。

# OreGeneration
## ソースコード

```java:OreGeneration.java
package jp.yuyu.biwako_mod.world;

import jp.yuyu.biwako_mod.BiwakoMod;
import jp.yuyu.biwako_mod.config.OregenConfig;
import jp.yuyu.biwako_mod.lists.BlockList;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.gen.GenerationStage;
import net.minecraft.world.gen.feature.Feature;
import net.minecraft.world.gen.feature.OreFeatureConfig;
import net.minecraft.world.gen.placement.CountRangeConfig;
import net.minecraft.world.gen.placement.Placement;
import net.minecraftforge.registries.ForgeRegistries;

public class OreGeneration {
    public static void setupOreGeneration() {
        if (OregenConfig.generate_overworld.get()) {
            for (Biome biome : ForgeRegistries.BIOMES) {
                biome.addFeature(
                        GenerationStage.Decoration.UNDERGROUND_ORES,
                        Biome.createDecoratedFeature(
                                Feature.ORE,
                                new OreFeatureConfig(
                                        OreFeatureConfig.FillerBlockType.NATURAL_STONE,
                                        BlockList.BiwakoOre.getDefaultState(),
                                        OregenConfig.biwako_ore_chance.get()),
                                Placement.COUNT_RANGE,
                                new CountRangeConfig(10, 20, 0, 100)));
                biome.addFeature(
                        GenerationStage.Decoration.UNDERGROUND_ORES,
                        Biome.createDecoratedFeature(
                                Feature.ORE,
                                new OreFeatureConfig(
                                        OreFeatureConfig.FillerBlockType.NETHERRACK,
                                        BlockList.BiwakoQuartzOre.getDefaultState(),
                                        OregenConfig.biwako_ore_chance.get()),
                                Placement.COUNT_RANGE,
                                new CountRangeConfig(10, 20, 0, 100)));
            }
        }
    }
}
```

## 解説
全部のバイオーム(Forest,River,Nezer,The End,...)を取得し、それぞれのバイオームに鉱石を生成させるようにします。

addFeatureメソッドの解説をします。

- **第1引数 Decoration decorationStage**

バイオームに追加する特徴のタイプ。地下の鉱石以外にも地上の建造物、地下の建造物などがある。

今回は、`GenerationStage.Decoration.UNDERGROUND_ORES`で地下の鉱石を追加する。

- **第2引数 ConfiguredFeature<?> featureIn**

具体的な鉱石の特徴を設定する。

`OreFeatureConfig.FillerBlockType.NATURAL_STONE`で鉱石の周りには、
自然のブロック(石・安山岩,...)で埋め尽くされて生成されます。
その後に洞窟が生成されるから、問題ないのかな？

`BlockList.BiwakoOre.getDefaultState()`で生成されたときのブロックの状態を設定します。
今回はデフォルトの状態を取得し、設定しています。

`OregenConfig.biwako_ore_chance.get()`で、1鉱脈に生成される鉱石の個数を設定します。

`Placement.COUNT_RANGE`は**調査中です、よくわかっていません**

`CountRangeConfig(10, 20, 0, 100))`で、生成される高さ、鉱脈の個数を設定している**気がします**。
第1引数:count,第2引数:bottomOffset,第3引数:topOffset,第4引数:maximumです。
第4引数生成されるy座標の最大値を表していることだけ分かりましたが、
それ以外の値がどう影響してくるのかは現在調査中です。

# 鉱石生成メソッドの呼び出し
最後に、`BiwakoMod.java`の`setup()`で鉱石を生成するセットアップメソッドを呼び出します。

```BiwakoMod.java
    private void setup(final FMLCommonSetupEvent event) {
        OreGeneration.setupOreGeneration();
        LOGGER.info("HELLO FROM PREINIT");
    }
```

# Minecraftの起動
ちゃんと生成されていました！
![2019-11-04_20.51.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/336583/99045d4d-e71b-76c4-c73f-087b7e11e7a0.png)
![2019-11-04_21.14.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/336583/8e7b84a1-7a93-eae4-6323-c307d6dcba66.png)

---
[Github](https://github.com/Hiroya-W/biwakoMC/tree/1.14.4)にてプロジェクトを公開しています。