MOD製作チュートリアル > 鉱石の追加

概要

ドロップアイテムがそのブロック自身ではなく、さらに経験値をドロップするブロックを追加し、地下に生成させる。

ソースコード

  • AluminiumMod.java
package tutorial.aluminiummod;
 
import net.minecraft.block.Block;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.item.Item;
import cpw.mods.fml.common.Mod;
import cpw.mods.fml.common.Mod.EventHandler;
import cpw.mods.fml.common.event.FMLInitializationEvent;
import cpw.mods.fml.common.event.FMLPreInitializationEvent;
import cpw.mods.fml.common.registry.GameRegistry;
 
@Mod(modid = AluminiumMod.MODID, name = AluminiumMod.MODNAME, version = AluminiumMod.VERSION)
public class AluminiumMod {
 
	public static final String MODID = "AluminiumMod";
	public static final String MODNAME = "Aluminium Mod";
	public static final String VERSION = "1.0.0";
 
	public static Item aluminium;
 
	public static Block oreAluminium;
 
	@EventHandler
	public void perInit(FMLPreInitializationEvent event) {
		aluminium = new Item()
		.setCreativeTab(CreativeTabs.tabMaterials)
		.setUnlocalizedName("aluminium")
		.setTextureName("aluminiummod:aluminium");
		GameRegistry.registerItem(aluminium, "aluminium");
 
		oreAluminium = new AluminiumOre()
		.setBlockName("oreAluminium")
		.setBlockTextureName("aluminiummod:aluminium_ore");
		GameRegistry.registerBlock(oreAluminium, "oreAluminium");
	}
 
	@EventHandler
	public void init(FMLInitializationEvent event) {
		GameRegistry.registerWorldGenerator(new AluminiumOreGenerator(), 0);
	}
 
}
 

  • AluminiumOre.java
package tutorial.aluminiummod;
 
import java.util.Random;
 
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.item.Item;
import net.minecraft.util.MathHelper;
import net.minecraft.world.IBlockAccess;
 
public class AluminiumOre extends Block {
 
	private Random random = new Random();
 
	public AluminiumOre() {
		super(Material.rock);
		this.setCreativeTab(CreativeTabs.tabBlock);
		this.setHardness(3.0F);
		this.setResistance(5.0F);
		this.setStepSound(Block.soundTypeStone);
		this.setHarvestLevel("pickaxe", 2);
	}
 
	@Override
	public Item getItemDropped(int meta, Random random, int fortune) {
		return AluminiumMod.aluminium;
	}
 
	@Override
	public int quantityDroppedWithBonus(int fortune, Random random) {
		if (fortune > 0 && Item.getItemFromBlock(this) != this.getItemDropped(0, random, fortune)) {
			int i = random.nextInt(fortune + 2) - 1;
			if (i < 0) {
				i = 0;
			}
			return this.quantityDropped(random) * (i + 1);
		} else {
			return this.quantityDropped(random);
		}
	}
 
	@Override
	public int getExpDrop(IBlockAccess iBlockAccess, int meta, int fortune) {
		return MathHelper.getRandomIntegerInRange(random, 3, 7);
	}
 
}
 

  • AluminiumOreGenerator.java
package tutorial.aluminiummod;
 
import java.util.Random;
 
import net.minecraft.init.Blocks;
import net.minecraft.world.World;
import net.minecraft.world.WorldProviderSurface;
import net.minecraft.world.chunk.IChunkProvider;
import net.minecraft.world.gen.feature.WorldGenMinable;
import cpw.mods.fml.common.IWorldGenerator;
 
public class AluminiumOreGenerator implements IWorldGenerator {
 
	@Override
	public void generate(Random random, int chunkX, int chunkZ, World world, IChunkProvider chunkGenerator, IChunkProvider chunkProvider) {
		if (world.provider instanceof WorldProviderSurface) {
			generateOre(world, random, chunkX << 4, chunkZ << 4);
		}
	}
 
	private void generateOre(World world, Random random, int x, int z) {
		for(int i = 0; i < 10; i++) {
			int genX = x + random.nextInt(16);
			int genY = 1 + random.nextInt(15);
			int genZ = z + random.nextInt(16);
			new WorldGenMinable(AluminiumMod.oreAluminium, 0, 20, Blocks.stone).generate(world, random, genX, genY, genZ);
		}
	}
 
}
 

解説

Block

Item getItemDropped(int meta, Random random, int fortune)

そのブロックを破壊したときにドロップするアイテムを返す。

int quantityDroppedWithBonus(int fortune, Random random)

破壊するのに使用したツールの幸運レベルをもとに、ドロップ数を変更する。

int getExpDrop(IBlockAccess iBlockAccess, int meta, int fortune)

経験値のドロップ量を返す。

GameRegistry

void registerWorldGenerator(IWorldGenerator generator, int modGenerationWeight)

GameRegistryにチャンク生成時にブロックを自然生成させるためのクラスを登録するメソッド。
第二引数は生成の優先度(?)。

IWorldGenerator

チャンク生成時にブロックを自然生成させるためのインターフェース。

generate(Random random, int chunkX, int chunkZ, World world, IChunkProvider chunkGenerator, IChunkProvider chunkProvider)

world.providerはそのワールド(ディメンション)のプロバイダ。
これを使って判定することで鉱石を生成するディメンションを制御できる。

WorldGenMinable

ブロックを生成させるクラスの一つ。
コンストラクタで指定したパラメータをもとにgenerateで鉱脈を生成する。

コンストラクタ(Block block, int meta, int number, Block target)

引数は、生成するブロック、生成するブロックのメタデータ、生成する鉱脈の大きさ、置き換えるブロック。
第二引数はなくてもよい。

boolean generate(World world, Random random, int x, int y, int z)

鉱脈を生成する処理。
戻り値は生成が成功したかどうか。

使用例

オファレン鉱石を追加している部分。
+ オファレンMOD

コメント

この項目に関する質問などをどうぞ。
  • 鉱石から鉱石ブロックをドロップする方法くぉおあいえていただけないでsy - World_of_the_Takumi 2016-03-11 07:40:22
    • AluminiumOreクラスで、getItemDropped・quantityDroppedWithBonus・getExpDropの部分を削除すればできます。 - 赤砂蛇凪浜 2016-03-13 07:44:13
      • 返信ありがとうございました、わかりにくいコメントですいません。今後から気を付けます。あともう一つお願いします" new WorldGenMinable(AluminiumMod.oreAluminium, 0, 20, Blocks.stone).generate(world,”以降はどうなっていますか。wikiにものってなかったのでお願いします。 - World_of_the_Takumi 2016-03-13 19:18:57
        • ソースコードの表示が見切れてしまっていたでしょうか。このようになっています。
          new WorldGenMinable(AluminiumMod.oreAluminium, 0, 20, Blocks.stone).generate(world, random, genX, genY, genZ); - 赤砂蛇凪浜 2016-03-14 06:40:37
          • ありがとうございました。感謝します - World_of_the_Takumi 2016-03-14 17:38:44
  • はじめまして このような素晴らしいwikiをありがとうございます 一つ気になることがあるのですが  AluminiumOreGenerator.javaの22行目 「for(int i = 0; i < 64; i++) {」 26行目 「new WorldGenMinable(decorationMOD.oreDecoration, 0, 64, Blocks.stone).generate(world, random, genX, genY, genZ);」 としているのですが 地下に鉱石が生成された気配が全くありません どこか間違えている・その他に設定が必要 などありましたら教えていただけないでしょうか 長文失礼しました - さくら 2016-04-01 00:10:45
    • こちらの環境でそのように変更すると、チャンクを読み込もうとしたときにクラッシュしました。
      鉱石はクリエイティブタブなどから利用できますか?GameRegistry.registerBlockをpreInitで呼び出しているか、GameRegistry.registerWorldGeneratorをinitで呼び出しているかなどを確認してください。
      WorldGenMinable.generateの次の行に「FMLLog.info("Generated ore. (" + genX + ", " + genY + ", " + genZ + ")");」と入れてログを確認するのも有効かと思います。 - 赤砂蛇凪浜 2016-04-01 06:58:20
      • 返信ありがとうございます。まず報告からなんですが、行けました! 無事に生成されてました。ありがとうございます。で、原因なんですが「GameRegistry.registerWorldGeneratorをinitで呼び出しているかなどを確認してください。」というのが気になったので 上をよく見るとそのような文章があり、「げ」と思ってEclipseを見なおしたところ追加し忘れていました。お騒がせして申し訳ありません。 (int i = 0; i < 16; i++) WorldGenMinable(decorationMOD.oreDecoration, 0, 8, Blocks.stone) として無事生成できました。本当にありがとうございました!長文、大変失礼いたしました - さくら 2016-04-02 05:55:25
        • 解決できたようでよかったです。 - 赤砂蛇凪浜 2016-04-02 06:10:29
  • わかりやすい解説ありがとうございます。アイテムをドロップさせる際にメタデータを指定する為にはどのようにすればよいのでしょうか。よろしくお願いします。 - asajyra 2016-04-02 02:14:53
  • WorldGenMinableのコンストラクタの第三引数をバニラの鉱石を参考にしたいのですが、バニラの鉱石のWorldGenMinableってどこにあるんですかね? - 名無しさん 2017-02-08 21:38:00
    • net.minecraft.world.biome.BiomeDecoratorのコンストラクタにおいて、通常世界の鉱石類のためにWorldGenMinableインスタンスの生成が行われています。
      (以下、補足。今後のModdingをより便利に行うためにご活用ください。)
      このような情報はIDEの機能を使うと簡単に調べることができます。
      今回の場合、コード内の「WorldGenMinable」にカーソルを合わせて「定義へ移動」(EclipseではF3)をすると、Forgeコード内のコンストラクタ記述部に移動でき、WorldGenMinableがコンストラクタを三種類持っていることがわかります。
      それぞれのコンストラクタ記述部にカーソルを合わせて「呼び出し階層を開く」(EclipseではCtrl+Alt+H)をすると、それぞれがどこから呼び出されているかがわかります。
      WorldGenMinable(Block p_i45459_1_, int p_i45459_2_)がBiomeDecoratorから呼び出されていることはこうして調べました。 - 赤砂蛇凪浜 2017-02-10 18:39:31
      • 丁寧な回答ありがとうございます。どうにか丁度よい生成量にできました! - 名無しさん 2017-02-10 22:55:50
名前: