概要
前回 独自の鉱石を作成しました
これまではインベントリから取得できましたが今回は自然の世界にランダムで発生させてみたいと思います
環境
- macOS X 10.13.2
- Minecraft 1.12.2
- Forge 1.12.2 - 14.23.1.2555
- Forge MDK 1.12.2 - 14.23.1.2555
- Java 1.8.0_151
- eclipse Oxygen.1a Release (4.7.1a)
各種 Java ファイルの作成
コードを書いていきます
com.sample.mod.gen パッケージの作成
- SampleOreGen.java
package com.sample.mod.gen;
import java.util.Random;
import com.sample.mod.init.BlockInit;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraft.world.chunk.IChunkProvider;
import net.minecraft.world.gen.IChunkGenerator;
import net.minecraft.world.gen.feature.WorldGenMinable;
import net.minecraft.world.gen.feature.WorldGenerator;
import net.minecraftforge.fml.common.IWorldGenerator;
public class SampleOreGen implements IWorldGenerator {
private WorldGenerator sample_ore;
public SampleOreGen() {
sample_ore = new WorldGenMinable(BlockInit.sample_ore.getDefaultState(), 9);
}
@Override
public void generate(Random random, int chunkX, int chunkZ, World world, IChunkGenerator chunkGenerator,
IChunkProvider chunkProvider) {
switch(world.provider.getDimension()) {
case 0:
runGenerator(sample_ore, world, random, chunkX, chunkZ, 50, 0, 50);
break;
case 1:
break;
case -1:
break;
}
}
private void runGenerator(WorldGenerator gen, World world, Random rand, int chunkX, int chunkZ, int chance, int minHeight, int maxHeight) {
if (minHeight > maxHeight || minHeight < 0 || maxHeight > 256) throw new IllegalArgumentException("Ore generated out of bounds");
int heightDiff = maxHeight - minHeight + 1;
for (int i = 0; i < chance; i++) {
int x = chunkX * 16 + rand.nextInt(16);
int y = minHeight + rand.nextInt(heightDiff);
int z = chunkZ * 16 + rand.nextInt(16);
gen.generate(world, rand, new BlockPos(x, y, z));
}
}
}
WorldGenMinable でワールドを作成します
第二引数の 9 は鉱石が見つかった際に塊としていくつ周りに生成させるか指定できます
Override している generate でどのワールドに生成するかハンドリングします
world.provider.getDimension()
で現在どのワールドタイプにいるのか取得することができます
-1 がネザーで 0 が通常世界で 1 がエンドポータルになります
今回は通常世界での鉱石は発生させるようにします
runGenerator で鉱石を配置する座標をランダムに決定し独自の鉱石が発生するワールドを作成します
まず高さのチェックをします
0 から 256 の範囲外は指定できないのでそれ以外が指定された場合はエラーとします
チャンクごとに chance で指定された回数分ワールドを作成します
chance が小さいほど 1 チャンク内に出現する鉱石の数は少なくなります
x, y, z の座標を生成しワールドを作成します
鉱石を発生させる高さを minHeight と maxHeight で指定できます
今回は 0 - 50 の高さで発生するようにしました
com.sample.mod.handlers パッケージの作成
- RegistryHandler.java
package com.sample.mod.handlers;
import com.sample.mod.gen.SampleOreGen;
import com.sample.mod.init.BlockInit;
import com.sample.mod.init.ItemInit;
import net.minecraftforge.fml.common.registry.GameRegistry;
public class RegistyHandler {
public static void Client() {
RecipeHandler.registerCrafting();
RecipeHandler.registerSmelting();
}
public static void Common() {
ItemInit.init();
ItemInit.register();
BlockInit.init();
BlockInit.register();
BlockInit.registerRenders();
GameRegistry.registerWorldGenerator(new SampleOreGen(), 0);
}
}
GameRegistry.registerWorldGenerator(new SampleOreGen(), 0);
で鉱石を発生させるワールドを登録します
第二引数はワールドの重みを指定することができます
大きければ大きいほど生成が後ろ回しになるため鉱石をあまり発生させたくない場合は値を大きくします
動作確認
クリエイティブモードでワールドを作成しましょう
今回の設定値であればそのまま下に掘っていけば簡単に見つかると思います
指定した高さの座標内で見つかると思います
またその周辺にも鉱石が発生しているのが確認できると思います
最後に
独自で作成した鉱石をゲームワールド内に発生させる方法を紹介しました
新規で作成した鉱石の重みが軽いとたくさん作成されてしまうので、既存の鉱石の発生確率が下がってしまう点は注意してください
鉱石側のチューニング (壊せる回数や壊せるピッケルレベルなど) は鉱石側の設定で行ってください
ネザーに鉱石を生成したいのですが、
返信削除上記のプログラムのcase 0; とcase -1; を
入れ替えて書き出しても、
ネザーに生成されません。
試しに、case 0; に同様のプログラムを
書き出した場合は、
オーバーワールドに生成されます。
(エンドも生成されません)
原因は何か教えていただけますでしょうか。
開発環境は
Minecraft 1.12.2
Forge 1.12.2-14.23.5.2855
Intelij IDEA です。
//AncientDebrisGen.java
package katyo.usefulplus.gen;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraft.world.chunk.IChunkProvider;
import net.minecraft.world.gen.IChunkGenerator;
import net.minecraft.world.gen.feature.WorldGenMinable;
import net.minecraft.world.gen.feature.WorldGenerator;
import net.minecraftforge.fml.common.IWorldGenerator;
import java.util.Random;
import katyo.usefulplus.init.BlockInit;
public class AncientDebrisGen implements IWorldGenerator {
private WorldGenerator ancient_debris;
public AncientDebrisGen() {
ancient_debris = new WorldGenMinable(BlockInit.ancient_debris.getDefaultState(), 3);
}
@Override
public void generate(Random random, int chunkX, int chunkZ, World world, IChunkGenerator chunkGenerator, IChunkProvider chunkProvider) {
switch(world.provider.getDimension()) {
case 0:
break;
case 1:
break;
case -1:
runGenerator(ancient_debris, world, random, chunkX, chunkZ, 50, 13, 17);
break;
}
}
private void runGenerator(WorldGenerator gen, World world, Random rand, int chunkX, int chunkZ, int chance, int minHeight, int maxHeight) {
if (minHeight > maxHeight || minHeight < 0 || maxHeight > 256) throw new IllegalArgumentException("Ore generated out of bounds");
int heightDiff = maxHeight - minHeight + 1;
for (int i = 0; i < chance; i++) {
int x = chunkX * 16 + rand.nextInt(16);
int y = minHeight + rand.nextInt(heightDiff);
int z = chunkZ * 16 + rand.nextInt(16);
gen.generate(world, rand, new BlockPos(x, y, z));
}
}
}
(すいません、スパムが多くコメントは承認制になっており投稿にラグがあります、、)
削除最近全く触っていないので試せる環境がなく不確かではありますがおそらく原因は以下かなと思います。
https://forums.minecraftforge.net/topic/63264-generate-ore-in-nether/
自然鉱石はネザーに生成することができないようなので WorldGenMinable(IBlockState, int) ではなく WorldGenMinable(IBlockState, int, Predicate) コンストラクタを使えとのことです
実際に動作しているコードもあり自分の記事と同じような書き方なのでそれを見ながら修正すれば動作するかなと思います
試してみてください
わかりました。試してみます!
返信削除ancient_debris = new WorldGenMinable(BlockInit.ancient_debris.getDefaultState(), 3); を、
返信削除ancient_debris = new WorldGenMinable(BlockInit.ancient_debris.getDefaultState(), 3, BlockMatcher.forBlock(Blocks.NETHERRACK));
にすると、できました。ありがとうございます!!