MOD製作チュートリアル > ツール類の追加

概要

新しい剣・シャベル・斧・ツルハシ・クワや、適正ブロックを自由に設定できるツールを追加する。

ソースコード

  • AluminiumMod.java
package tutorial.aluminiummod;
 
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.item.Item;
import net.minecraft.item.Item.ToolMaterial;
import net.minecraft.item.ItemHoe;
import net.minecraft.item.ItemSpade;
import net.minecraft.item.ItemStack;
import net.minecraft.item.ItemSword;
import net.minecraftforge.common.util.EnumHelper;
import cpw.mods.fml.common.Mod;
import cpw.mods.fml.common.Mod.EventHandler;
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 Item swordAluminium;
	public static Item shovelAluminium;
	public static Item pickaxeAluminium;
	public static Item axeAluminium;
	public static Item hoeAluminium;
	public static Item toolAluminium;
 
	public static ToolMaterial ALUMINIUM;
 
	@EventHandler
	public void perInit(FMLPreInitializationEvent event) {
		aluminium = new Item()
				.setCreativeTab(CreativeTabs.tabMaterials)
				.setUnlocalizedName("aluminium")
				.setTextureName("aluminiummod:aluminium");
		GameRegistry.registerItem(aluminium, "aluminium");
 
		ALUMINIUM = EnumHelper.addToolMaterial("ALUMINIUM", 3, 1000, 7.5F, 2.5F, 10)
				.setRepairItem(new ItemStack(AluminiumMod.aluminium));
 
		swordAluminium = new ItemSword(ALUMINIUM)
				.setCreativeTab(CreativeTabs.tabCombat)
				.setUnlocalizedName("swordAluminium")
				.setTextureName("aluminiummod:aluminium_sword");
		GameRegistry.registerItem(swordAluminium, "swordAluminium");
 
		shovelAluminium = new ItemSpade(ALUMINIUM)
				.setCreativeTab(CreativeTabs.tabTools)
				.setUnlocalizedName("shovelAluminium")
				.setTextureName("aluminiummod:aluminium_shovel");
		GameRegistry.registerItem(shovelAluminium, "shovelAluminium");
 
		pickaxeAluminium = new AluminiumPickaxe(ALUMINIUM)
				.setCreativeTab(CreativeTabs.tabTools)
				.setUnlocalizedName("pickaxeAluminium")
				.setTextureName("aluminiummod:aluminium_pickaxe");
		GameRegistry.registerItem(pickaxeAluminium, "pickaxeAluminium");
 
		axeAluminium = new AluminiumAxe(ALUMINIUM)
				.setCreativeTab(CreativeTabs.tabTools)
				.setUnlocalizedName("axeAluminium")
				.setTextureName("aluminiummod:aluminium_axe");
		GameRegistry.registerItem(axeAluminium, "axeAluminium");
 
		hoeAluminium = new ItemHoe(ALUMINIUM)
				.setCreativeTab(CreativeTabs.tabTools)
				.setUnlocalizedName("hoeAluminium")
				.setTextureName("aluminiummod:aluminium_hoe");
		GameRegistry.registerItem(hoeAluminium, "hoeAluminium");
 
		toolAluminium = new AluminiumTool(ALUMINIUM)
				.setCreativeTab(CreativeTabs.tabTools)
				.setUnlocalizedName("toolAluminium")
				.setTextureName("aluminiummod:aluminium_tool");
		GameRegistry.registerItem(toolAluminium, "toolAluminium");
	}
 
}
 

  • AluminiumPickaxe.java
package tutorial.aluminiummod;
 
import net.minecraft.item.ItemPickaxe;
 
public class AluminiumPickaxe extends ItemPickaxe {
 
	public AluminiumPickaxe(ToolMaterial toolMaterial) {
		super(toolMaterial);
	}
 
}
 

  • AluminiumAxe.java
package tutorial.aluminiummod;
 
import net.minecraft.item.ItemAxe;
 
public class AluminiumAxe extends ItemAxe {
 
	public AluminiumAxe(ToolMaterial toolMaterial) {
		super(toolMaterial);
	}
 
}
 

  • AluminiumTool.java
package tutorial.aluminiummod;
 
import java.util.Set;
 
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.init.Blocks;
import net.minecraft.item.ItemStack;
import net.minecraft.item.ItemTool;
 
import com.google.common.collect.Sets;
 
public class AluminiumTool extends ItemTool {
 
	private static final Set canHarvestBlock = Sets.newHashSet(new Block[] { Blocks.diamond_block });
 
	public AluminiumTool(ToolMaterial toolMaterial) {
		super(0.0F, toolMaterial, canHarvestBlock);
	}
 
	@Override
	public boolean func_150897_b(Block block) {
		return true;
	}
 
	@Override
	public float func_150893_a(ItemStack itemStack, Block block) {
		if (block.getMaterial() == Material.rock) {
			return this.efficiencyOnProperMaterial;
		}
		return super.func_150893_a(itemStack, block);
	}
 
	// ここにItemHoeのプログラムを張り付ければ、クワの効果も得られる。
 
}
 

解説

ToolMaterial

ツールの性質を保持するためのenum。

ToolMaterial setRepairItem(ItemStack stack)

金床で修繕するための素材を設定するメソッド。

EnumHelper

ToolMaterial addToolMaterial(String name, int harvestLevel, int maxUses, float efficiency, float damage, int enchantability)

新しくツールマテリアルを追加するためのメソッド。
引数は順に、ツールマテリアルの名前・回収レベル・最大耐久値・採掘速度・攻撃に使用したときのダメージ倍率・エンチャントの付きやすさ。
ダイヤモンドは、3, 1561, 8.0F, 3.0F, 10

Item

public boolean func_150897_b(Block block)

引数のブロックを回収できるかを返す。

public float func_150893_a(ItemStack itemStack, Block block)

採掘速度を返す。
ItemToolでは、コンストラクタの第3引数のSetに登録されているブロックのときに適性時採掘速度を返している。

使用例

オファレンの万能ツールを追加している部分
+オファレンMOD
  • OfalenModCore.java
package nahama.ofalenmod;
 
/*略*/
 
/** @author Akasata Nahama */
@Mod(modid = OfalenModCore.MODID, name = OfalenModCore.MODNAME, version = OfalenModCore.VERSION)
public class OfalenModCore {
 
	public static final String MODID = "OfalenMod";
	public static final String MODNAME = "Ofalen Mod";
	public static final String VERSION = "[1.7.10]1.0.0";
 
/*略*/
 
	/** 最初に行われる処理。アイテム・ブロックの追加などを行う */
	@EventHandler
	public void preInit(FMLPreInitializationEvent event) {
/*略*/
 
		// アイテムを設定するメソッドを実行
		OfalenModItemCore.registerItem();
 
/*略*/
	}
 
/*略*/
 
}
 

  • OfalenModItemCore.java
package nahama.ofalenmod.core;
 
/*略*/
 
public class OfalenModItemCore {
 
/*略*/
 
	public static Item toolPerfectOfalen;
/*略*/
 
	/**アイテムを設定する*/
	public static void registerItem () {
/*略*/
 
		toolPerfectOfalen = new OfalenPerfectTool(OfalenModMaterialCore.PERFECTT)
		.setUnlocalizedName("toolPerfectOfalen")
		.setTextureName("ofalenmod:ofalen_perfect_tool");
		GameRegistry.registerItem(toolPerfectOfalen, "toolPerfectOfalen");
 
/*略*/
	}
 
}
 

  • OfalenPerfectTool.java
package nahama.ofalenmod.item.tool;
 
import nahama.ofalenmod.OfalenModCore;
import net.minecraft.block.Block;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Blocks;
import net.minecraft.item.EnumAction;
import net.minecraft.item.ItemStack;
import net.minecraft.item.ItemTool;
import net.minecraft.world.World;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.entity.player.UseHoeEvent;
import cpw.mods.fml.common.eventhandler.Event.Result;
 
public class OfalenPerfectTool extends ItemTool {
 
	public OfalenPerfectTool(ToolMaterial material) {
		super(0.0F, material, null);
		this.setCreativeTab(OfalenModCore.tabOfalen);
	}
 
	@Override
	public boolean func_150897_b(Block block) {
		return true;
	 }
 
	/**採掘速度の設定*/
	@Override
	public float func_150893_a(ItemStack itemStack, Block block) {
		//他のツールでは適正ブロックの判定をするが、ここではすべてに適正採掘速度を適用する
		return this.efficiencyOnProperMaterial;
	}
 
	//クワの処理
	/**アイテムが使われた(右クリック)時の処理*/
	@Override
	public boolean onItemUse(ItemStack itemStack, EntityPlayer entityPlayer, World world, int x, int y, int z, int side, float hitX, float hitY, float hitZ) {
		//プレイヤーが編集不可ならば
		if (!entityPlayer.canPlayerEdit(x, y, z, side, itemStack)) {
			//falseを返す
			return false;
		} else {
			//eventの登録
			UseHoeEvent event = new UseHoeEvent(entityPlayer, itemStack, world, x, y, z);
			if (MinecraftForge.EVENT_BUS.post(event)) {
				return false;
			}
 
			if (event.getResult() == Result.ALLOW) {
				//ダメージを与える
				itemStack.damageItem(1, entityPlayer);
				return true;
			}
 
			//右クリックされたブロックを取得する
			Block block = world.getBlock(x, y, z);
 
			//右クリックされたブロックの上が空気ブロックで、右クリックされたブロックが草ブロックか土ブロックならば
			if (side != 0 && world.getBlock(x, y + 1, z).isAir(world, x, y + 1, z) && (block == Blocks.grass || block == Blocks.dirt)) {
				Block block1 = Blocks.farmland;
				//音を鳴らす
				world.playSoundEffect((double)((float)x + 0.5F), (double)((float)y + 0.5F), (double)((float)z + 0.5F), block1.stepSound.getStepResourcePath(), (block1.stepSound.getVolume() + 1.0F) / 2.0F, block1.stepSound.getPitch() * 0.8F);
 
				//クライアント側では何もせず
				if (world.isRemote) {
					return true;
				//サーバー側では
				} else {
					//ブロックを置き換えて
					world.setBlock(x, y, z, block1);
					//ダメージを与える
					itemStack.damageItem(1, entityPlayer);
					return true;
				}
			} else {
				return false;
			}
		}
	}
 
	//剣の処理
	/**Entityを叩いたときの処理。ItemToolでは2のダメージをアイテムに与えるが、剣と同じように1与えるようにする。*/
	@Override
	public boolean hitEntity(ItemStack itemStack, EntityLivingBase target, EntityLivingBase player) {
		itemStack.damageItem(1, player);
		return true;
	}
 
	@Override
	public EnumAction getItemUseAction(ItemStack itemStack) {
		return EnumAction.block;
	}
 
	@Override
	public int getMaxItemUseDuration(ItemStack itemStack) {
		return 72000;
	}
 
	@Override
	public ItemStack onItemRightClick(ItemStack itemStack, World world, EntityPlayer player) {
		player.setItemInUse(itemStack, this.getMaxItemUseDuration(itemStack));
		return itemStack;
	}
 
}
 

Tips

ここで、実装したツールに常時エンチャントを追加する方法を紹介する。
コードは、匠Craftの匠式ツールや対地雷ツールを参考にしていただきたい。
Itemをオーバーライドしたクラスに、以下のメソッドを追加する。
//アイテムに対して毎ティック呼ばれるメソッド。
    //引数は、itemStack(アイテムと個数、メタデータ等をまとめたもの),world(ワールド),entity(持っているEntity),slot(現在あるスロット番号),isHeld(手持ちかどうか)
    public void onUpdate(ItemStack itemStack, World world, Entity entity, int slot, boolean isHeld) {
        //エンチャントされていないかどうかを確認する。
        if (itemStack.isItemEnchanted() == false) {
            //エンチャントを付与する。引数はエンチャント,レベルの順に追加する。
            itemStack.addEnchantment(TEnchantment.enchantmentMS, 1);
        }
    }
 
これにより、常時効果を発揮するエンチャントや手に持ってるときに効果を発揮するものなどを実装できる。

コメント

この項目に関する質問などをどうぞ。
  • アルミニウムツールが耐久値を保持しないのですが、、 - 名無しさん 2015-08-22 17:58:35
    • まだ編集が終わっていません。原因を調べ、テンプレートを使用して修正します。報告ありがとうございます - 赤砂蛇凪浜 2015-08-23 08:51:21
    • 編集完了しましたが、こちらの環境では特に問題はありませんでした。解決できていない場合はもう一度コメントしてくださるとありがたいです。 - 赤砂蛇凪浜 2015-09-04 09:17:25
  • 質問です。黄昏の森のstealeafでできるツールのようにもともとエンチャントがつくツールはどのようなコードにすればいいのでしょうか? - 名無しさん 2017-01-07 16:19:06
    • 解決しました。 - 名無しさん 2017-01-22 10:08:12
      • 方法を教えていただけませんか? - あるふぁ 2017-05-20 16:26:48
      • 匠craftの「地雷除去」のように、新しいエンチャントをつける方法を解説していただけると助かります。 - あるふぁ 2017-05-20 18:53:49
        • 追加いたしました、ご確認ください。 - Tom Kate 2017-05-22 19:34:58
          • すみません、伝わりにくかったと思います…匠craftの「地雷除去」のように、新しいエンチャントの”種類”を作る方法でした。 - あるふぁ 2017-05-23 20:15:17
            • エンチャント「追加」ですか。申し訳ありません。追加予定はありますがすぐにはできないと思いますのでご了承ください。 - Tom Kate 2017-05-23 20:26:53
  • どんなブロックでもクリエイティブの時のように即時破壊し、ドロップさせるツールは作れますか? - あるふぁ 2017-05-31 19:29:48
    • 通常破壊可能なブロックを採掘したいのであれば、比較的容易に作れます。
      AluminiumTool.javaでの実装を応用し、func_150893_aで常にefficiencyOnProperMaterialを返せば、通常破壊可能なすべてのブロックを、適正採掘速度で破壊できます。
      さらに、EnumHelper.addToolMaterialの第四引数に大きな値を渡すことで、クリエイティブ以上の採掘速度を出すことが可能です。
      (1500以上であれば、通常時は黒曜石を最大速度で破壊できます。)
      岩盤のような破壊不可ブロックは、干渉できるイベントが見当たらないため、左クリック時に破壊することは簡単ではないと思います。
      アイテム使用時に呼ばれるonItemUseメソッドをオーバーライドすれば、右クリック時に岩盤を破壊し、ドロップさせるといった処理は可能です。 - 赤砂蛇凪浜 2017-06-01 17:50:09
      • ありがとうございます!実は返信が来る前に試行錯誤して解決してしまったのですが、参考になりました。 - あるふぁ 2017-06-01 18:38:38
  • こちらも「防具の追加」同様に、金床で修理することが出来ません。 - mod初心者 2017-06-17 12:48:38
    • ご指摘ありがとうございます。原因は「防具の追加」と同様です。修正しておきました。 - 赤砂蛇凪浜 2017-06-17 16:52:20
      • 解決しました!ありがとうございました! - mod初心者 2017-06-19 17:19:34
  • 参考になりました、ありがとうございます - 名無しさん 2017-08-04 19:14:19
名前: