- 其物品類別為 "戰鬥 (Combat)" 物品。
- 其有自己的名字 (英文叫 Super Sword,中文叫超級劍)。
- 其為"劍 (Sword)"這個物品的客制版本,有自己的攻擊傷害等數值。
- 其有自己的2D圖示,並拿此圖示做為 3D 時的樣子 (例如玩家拿在手上的樣子)。
- 其被玩家拿在手上時,有自己效果,此例為玩家不會受到攻擊及效果傷害,並且攻擊者會受到最大生命值一半的傷害。
package com.my.mode.item; import net.minecraft.entity.LivingEntity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.IItemTier; import net.minecraft.item.Item; import net.minecraft.item.ItemGroup; import net.minecraft.item.Rarity; import net.minecraft.item.SwordItem; import net.minecraft.item.crafting.Ingredient; import net.minecraft.util.DamageSource; import net.minecraft.world.World; import net.minecraftforge.event.entity.living.LivingAttackEvent; import net.minecraftforge.event.entity.living.LivingHurtEvent; import net.minecraftforge.eventbus.api.SubscribeEvent; public class SuperSword extends SwordItem{ public final static String ITEM_ID = "super_sword"; public SuperSword() { super(new IItemTier() { @Override public int getMaxUses() { // TODO Auto-generated method stub return 100; } @Override public float getEfficiency() { // TODO Auto-generated method stub return 0; } @Override public float getAttackDamage() { // TODO Auto-generated method stub return 100; } @Override public int getHarvestLevel() { // TODO Auto-generated method stub return 0; } @Override public int getEnchantability() { // TODO Auto-generated method stub return 0; } @Override public Ingredient getRepairMaterial() { // TODO Auto-generated method stub return null; } }, 100, 1, (new Item.Properties()).group(ItemGroup.COMBAT)); } @SubscribeEvent public void onLivingAttackEvent(LivingAttackEvent event) { LivingEntity livingEntity = event.getEntityLiving(); World world = livingEntity.getEntityWorld(); if(!world.isRemote && livingEntity instanceof PlayerEntity) { PlayerEntity playerEntity = (PlayerEntity) livingEntity; if (playerEntity.getHeldItemMainhand().getItem() instanceof SuperSword || playerEntity.getHeldItemOffhand().getItem() instanceof SuperSword) { //把事件取消,效果為攻擊無效,不會愛傷 event.setCanceled(true); //增加效果,效果為對攻擊玩家 (player) 的生物造成傷害 if (event.getSource().getTrueSource() instanceof LivingEntity) { LivingEntity attacker = (LivingEntity) event.getSource().getTrueSource(); attacker.attackEntityFrom(DamageSource.GENERIC, attacker.getMaxHealth() / 2); } } } } @SubscribeEvent public void onLivingAttackEvent(LivingHurtEvent event) { LivingEntity livingEntity = event.getEntityLiving(); World world = livingEntity.getEntityWorld(); if(!world.isRemote && livingEntity instanceof PlayerEntity) { PlayerEntity playerEntity = (PlayerEntity) livingEntity; if (playerEntity.getHeldItemMainhand().getItem() instanceof SuperSword || playerEntity.getHeldItemOffhand().getItem() instanceof SuperSword) { //把事件取消,效果為傷害無效,不會愛傷 event.setCanceled(true); } } } }
在 SuperSword.java 的建構子 (constructor) 中,SuperSword 繼承了 SwordItem,
net.minecraft.item.SwordItem.SwordItem(IItemTier tier, int attackDamageIn, float attackSpeedIn, Properties builderIn)
LivingEntity livingEntity = event.getEntityLiving();
if (playerEntity.getHeldItemMainhand().getItem() instanceof SuperSword || playerEntity.getHeldItemOffhand().getItem() instanceof SuperSword)
if (event.getSource().getTrueSource() instanceof LivingEntity) { LivingEntity attacker = (LivingEntity) event.getSource().getTrueSource(); attacker.attackEntityFrom(DamageSource.GENERIC, attacker.getMaxHealth() / 2); }
package com.my.mode.item; import com.my.mode.MyMod; import net.minecraft.item.Item; import net.minecraftforge.fml.RegistryObject; import net.minecraftforge.registries.DeferredRegister; import net.minecraftforge.registries.ForgeRegistries; public class Items { private static DeferredRegister<Item> REGISTER = null; public static DeferredRegister<Item> getRegister(){ if (REGISTER == null) { REGISTER = DeferredRegister.create(ForgeRegistries.ITEMS, MyMod.MOD_ID); } //注冊自製物品 REGISTER.register(SuperSword.ITEM_ID, () -> new SuperSword()); return REGISTER; } }
package com.my.mode; import com.my.mode.item.Items; import net.minecraftforge.eventbus.api.IEventBus; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent; import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; public class ModEventBusHandler { public static void register() { IEventBus modEventBus = FMLJavaModLoadingContext.get().getModEventBus(); modEventBus.register(ModEventBusHandler.class); modEventBus.register(new ModEventBusHandler()); //註冊自製物品,並將其註冊到 ModEventBus 中 Items.getRegister().register(modEventBus); } @SubscribeEvent public void onCommonSetupEvent(FMLCommonSetupEvent event) { ForgeEventBusHandler.register(); } }
Items.getRegister().register(modEventBus);
package com.my.mode; import com.my.mode.item.SuperSword; import net.minecraft.client.Minecraft; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityType; import net.minecraft.entity.LivingEntity; import net.minecraft.entity.item.ItemEntity; import net.minecraft.entity.monster.MonsterEntity; import net.minecraft.entity.passive.FoxEntity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.Item; import net.minecraft.util.DamageSource; import net.minecraft.world.World; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.event.entity.item.ItemTossEvent; import net.minecraftforge.event.entity.living.LivingAttackEvent; import net.minecraftforge.event.entity.living.LivingEvent; import net.minecraftforge.event.entity.living.LivingHurtEvent; import net.minecraftforge.eventbus.api.IEventBus; import net.minecraftforge.eventbus.api.SubscribeEvent; public class ForgeEventBusHandler { public static void register() { IEventBus forgeEventBus = MinecraftForge.EVENT_BUS; forgeEventBus.register(ForgeEventBusHandler.class); forgeEventBus.register(new ForgeEventBusHandler()); //註冊超級劍 (super sword) 的事件效果 forgeEventBus.register(new SuperSword()); forgeEventBus.register(SuperSword.class); } // Event 有分成在 ModEventUs 上的,或在 ForgeEventBus 上的, // 此例的 ItemTossEvent 為在 ForgeEventBus 上的 Event @SubscribeEvent public void onItemTossEvent(ItemTossEvent event) { //ItemTossEvent: 物品丟棄時觸發的 Event, //在遊戲中可用按鍵 q 來丟棄物品 ItemEntity item = event.getEntityItem(); World world = item.getEntityWorld(); if (!world.isRemote) { // 判斷是否為 logical server 端,即處理邏輯的那端 // 如果此例的 isRemote 為 true,即為 logical client 端 // 可參考 // https://hackmd.io/@immortalmice/Hkj9s-CvU/https%3A%2F%2Fhackmd.io%2F%40immortalmice%2FrJKayrf9U //建立一個狐狸物件 FoxEntity fox = new FoxEntity(EntityType.FOX, world); fox.setPosition(item.getPosX(), item.getPosY(), item.getPosZ()); //將物件放到世界中 world.addEntity(fox); } } }
forgeEventBus.register(new SuperSword()); forgeEventBus.register(SuperSword.class);
Note:
forgeEventBus.register(new SuperSword()); 用來註冊 SuperSword 裡的 non-static method,forgeEventBus.register(SuperSword.class); 用來註冊 SuperSwrod 裡的 static method。
{ "item.mymod.super_sword": "Super Sword" }
{ "item.mymod.super_sword": "超級劍" }
{ "parent": "item/generated", "textures": { "layer0": "mymod:item/super_sword" }, "display": { "thirdperson_righthand": { "rotation": [0, 90, 0], "translation" : [0, 3, 0], "scale" : [1, 1, 1] } } }
Note:
此時如果把 SuperSword 拿在左手,會發現一樣如拿在右手上一樣有吃到調整的設定,應該是因為當有設定右手時,如果左手沒設定的話會自動以右手設定為準。
{ "type": "minecraft:crafting_shaped", "pattern": [ " x ", "xxx", " x " ], "key": { "x": { "item": "minecraft:dirt" } }, "result": { "item": "mymod:super_sword", "count": 1 } }