今天我们在模组中实现一个自定义盾牌
1.新建一个接口类IHasModel:
IHasModel.java
public interface IHasModel {
public void registerModels();
}
之后我们新建一个物品基类ItemBase来实现接口类:
ItemBase.java
package com.joy187.rejoymod.item;
import com.joy187.rejoymod.IdlFramework;
import com.joy187.rejoymod.init.ModCreativeTab;
import com.joy187.rejoymod.util.IHasModel;
import net.minecraft.client.resources.I18n;
import net.minecraft.client.util.ITooltipFlag;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.EnumRarity;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ActionResult;
import net.minecraft.util.EnumActionResult;
import net.minecraft.util.EnumHand;
import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import javax.annotation.Nonnull;
import java.util.List;
import java.util.UUID;
import static com.joy187.rejoymod.util.IDLSkillNBT.GetGuaEnhance;
public class ItemBase extends Item implements IHasModel {
private boolean overrideRarity = false;
private EnumRarity enumRarity = EnumRarity.COMMON;
protected boolean showGuaSocketDesc = false;
protected boolean shiftToShowDesc = false;
protected boolean use_flavor = false;
protected boolean useable = false;
private boolean isRangedWeapon = false;
protected boolean logNBT = false;
protected boolean glitters = false;
protected static final UUID OFF_HAND_MODIFIER = UUID.fromString("9271eeea-5f74-4e12-97b6-7cf3c60ef7a0");
protected static final UUID MAIN_HAND_MODIFIER = UUID.fromString("7d766720-0695-46c6-b320-44529f3da63f");
protected static final UUID POWER_UP_MODIFIER = UUID.fromString("dc8a0a25-24c4-43a9-bfc3-e31e431f4ebf");
protected static final UUID POWER_UP_MODIFIER_PERCENT = UUID.fromString("9236a0fe-8f9b-4ede-80a3-05386216d06f");
public ItemBase(String name, CreativeTabs tab)
{
setUnlocalizedName(name);
setRegistryName(name);
setCreativeTab(tab);
ModItems.ITEMS.add(this);
InitItem();
}
public ItemBase(String name)
{
setUnlocalizedName(name);
setRegistryName(name);
setCreativeTab(CreativeTabs.MISC);
ModItems.ITEMS.add(this);
InitItem();
}
protected ItemBase setGlitter()
{
glitters = true;
return this;
}
@SideOnly(Side.CLIENT)
public boolean hasEffect(ItemStack stack)
{
return stack.isItemEnchanted() || glitters;
}
public ItemBase setRangedWeapon()
{
isRangedWeapon = true;
return this;
}
public ItemBase setRarity(EnumRarity enumRarity)
{
overrideRarity = true;
this.enumRarity = enumRarity;
return this;
}
public EnumRarity getRarity(ItemStack stack)
{
if (overrideRarity)
{
return enumRarity;
}else {
return super.getRarity(stack);
}
}
public void InitItem()
{
if (this instanceof IGuaEnhance)
{
showGuaSocketDesc = true;
}
}
public boolean isRangedWeaponItem()
{
return isRangedWeapon;
}
@Override
public void onUsingTick(ItemStack stack, EntityLivingBase living, int count) {
//Particle;
super.onUsingTick(stack, living, count);
//IdlFramework.LogWarning(String.format("base onUsingTick %s",count));
if (living.world.isRemote)
{
clientUseTick(stack, living, getMaxItemUseDuration(stack) - count);
}
else
{
serverUseTick(stack, living, getMaxItemUseDuration(stack) - count);
}
}
//右键效果
@Nonnull
@Override
public ActionResult<ItemStack> onItemRightClick(World world, EntityPlayer player, @Nonnull EnumHand hand) {
if (useable)
{
player.setActiveHand(hand);
ItemStack stack = player.getHeldItem(hand);
boolean result = onUseSimple(player, stack);
if (result)
{
return ActionResult.newResult(EnumActionResult.SUCCESS, stack);
}
else {
return ActionResult.newResult(EnumActionResult.FAIL, stack);
}
}
else {
return super.onItemRightClick(world, player, hand);
}
}
public boolean onUseSimple(EntityPlayer player, ItemStack stack)
{
return true;
}
public void clientUseTick(ItemStack stack, EntityLivingBase living, int count)
{
}
public void serverUseTick(ItemStack stack, EntityLivingBase living, int count)
{
}
@Override
public void registerModels()
{
IdlFramework.proxy.registerItemRenderer(this, 0, "inventory");
}
public void onMouseFire(EntityPlayer player)
{
}
}
2.新建一个ItemAdaptingBase类作为盾牌基类:
ItemAdaptingBase.java
package com.joy187.rejoymod.item;
import net.minecraft.enchantment.Enchantment;
import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Enchantments;
import net.minecraft.item.EnumAction;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumHand;
import net.minecraft.world.World;
public class ItemAdaptingBase extends ItemBase {
public ItemAdaptingBase(String name) {
super(name);
}
public float base_power = 6f;
public float base_range = 3f;
public float base_cd = 10f;
public float getPower(ItemStack stack)
{
float result = base_power;
int powerEnchant = EnchantmentHelper.getEnchantmentLevel(Enchantments.POWER, stack);
if (powerEnchant > 0)
{
result += powerEnchant ;
}
return result;
}
public float getRange(ItemStack stack)
{
float result = base_power;
int powerEnchant = EnchantmentHelper.getEnchantmentLevel(Enchantments.POWER, stack);
if (powerEnchant > 0)
{
result += powerEnchant ;
}
return result;
}
public int getCoolDownTicks(ItemStack stack)
{
return (int) (base_cd * 20);
}
@Override
public int getMaxDamage(ItemStack stack) {
return 256;
}
/**
* How long it takes to use or consume an item
*/
public int getMaxItemUseDuration(ItemStack stack)
{
return 72000;
}
/**
* returns the action that specifies what animation to play when the items is being used
*/
public EnumAction getItemUseAction(ItemStack stack)
{
return EnumAction.BOW;
}
@Override
public boolean canApplyAtEnchantingTable(ItemStack stack, Enchantment enchantment) {
if (enchantment == Enchantments.PUNCH || enchantment == Enchantments.INFINITY)
{
return false;
}
if (enchantment == Enchantments.POWER || enchantment == Enchantments.UNBREAKING)
{
return true;
}
return super.canApplyAtEnchantingTable(stack, enchantment);
}
/**
* Called when the player stops using an Item (stops holding the right mouse button).
*/
public void onPlayerStoppedUsing(ItemStack stack, World worldIn, EntityLivingBase entityLiving, int timeLeft)
{
if (!useable)
{
return;
}
onCreatureStoppedUsing(stack, worldIn, entityLiving, timeLeft);
entityLiving.swingArm(entityLiving.getHeldItemMainhand() == stack ? EnumHand.MAIN_HAND : EnumHand.OFF_HAND);
if (!worldIn.isRemote)
{
if (entityLiving instanceof EntityPlayer)
{
EntityPlayer entityplayer = (EntityPlayer)entityLiving;
{
entityplayer.getCooldownTracker().setCooldown(this, getCoolDownTicks(stack));
}
}
}
}
public void onCreatureStoppedUsing(ItemStack stack, World worldIn, EntityLivingBase entityLiving, int timeLeft)
{
}
}
3.新建一个我们的盾牌类继承第2步中的基类:
ItemREShield.java
package com.joy187.rejoymod.item.weapon;
import com.joy187.rejoymod.item.ItemAdaptingBase;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.enchantment.Enchantment;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.SharedMonsterAttributes;
import net.minecraft.entity.ai.attributes.AttributeModifier;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Enchantments;
import net.minecraft.inventory.EntityEquipmentSlot;
import net.minecraft.item.EnumAction;
import net.minecraft.item.IItemPropertyGetter;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ActionResult;
import net.minecraft.util.EnumActionResult;
import net.minecraft.util.EnumHand;
import net.minecraft.util.ResourceLocation;
import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import javax.annotation.Nullable;
public class ItemREShield extends ItemAdaptingBase {
public ItemREShield(String name) {
super(name);
setRangedWeapon();
useable = true;
this.addPropertyOverride(new ResourceLocation("blocking"), new IItemPropertyGetter()
{
@SideOnly(Side.CLIENT)
public float apply(ItemStack stack, @Nullable World worldIn, @Nullable EntityLivingBase entityIn)
{
return entityIn != null && entityIn.isHandActive() && entityIn.getActiveItemStack() == stack ? 1.0F : 0.0F;
}
});
}
//物品名称 放在哪个物品栏
public ItemREShield(String name, CreativeTabs tab) {
super(name);
setRangedWeapon();
setCreativeTab(tab);
useable = true;
this.addPropertyOverride(new ResourceLocation("blocking"), new IItemPropertyGetter()
{
@SideOnly(Side.CLIENT)
public float apply(ItemStack stack, @Nullable World worldIn, @Nullable EntityLivingBase entityIn)
{
return entityIn != null && entityIn.isHandActive() && entityIn.getActiveItemStack() == stack ? 1.0F : 0.0F;
}
});
}
public boolean isShield(ItemStack stack, @Nullable EntityLivingBase entity)
{
return true;
}
/**
* returns the action that specifies what animation to play when the items is being used
*/
public EnumAction getItemUseAction(ItemStack stack)
{
return EnumAction.BLOCK;
}
/**
* How long it takes to use or consume an item
*/
public int getMaxItemUseDuration(ItemStack stack)
{
return 72000;
}
/**
* Called when the equipped item is right clicked.
*/
public ActionResult<ItemStack> onItemRightClick(World worldIn, EntityPlayer playerIn, EnumHand handIn)
{
ItemStack itemstack = playerIn.getHeldItem(handIn);
playerIn.setActiveHand(handIn);
return new ActionResult<>(EnumActionResult.SUCCESS, itemstack);
}
@Override
public void onPlayerStoppedUsing(ItemStack stack, World worldIn, EntityLivingBase entityLiving, int timeLeft) {
}
@Override
public int getMaxDamage(ItemStack stack) {
return 768;
}
@Override
public boolean canApplyAtEnchantingTable(ItemStack stack, Enchantment enchantment) {
if (enchantment == Enchantments.PUNCH || enchantment == Enchantments.INFINITY)
{
return false;
}
if (enchantment == Enchantments.POWER || enchantment == Enchantments.UNBREAKING)
{
return true;
}
return super.canApplyAtEnchantingTable(stack, enchantment);
}
public Multimap<String, AttributeModifier> getAttributeModifiers(EntityEquipmentSlot equipmentSlot, ItemStack stack)
{
Multimap<String, AttributeModifier> multimap = HashMultimap.<String, AttributeModifier>create();
//盾牌在主手,身上的护甲受到攻击的话就把伤害设置为0(即盾牌抵挡了一次攻击)
if (equipmentSlot == EntityEquipmentSlot.OFFHAND )
{
multimap.put(SharedMonsterAttributes.ARMOR.getName(), new AttributeModifier(OFF_HAND_MODIFIER, "Weapon modifier", (double)getPower(stack), 0));
}
if (equipmentSlot == EntityEquipmentSlot.MAINHAND)
{
multimap.put(SharedMonsterAttributes.ARMOR.getName(), new AttributeModifier(MAIN_HAND_MODIFIER, "Weapon modifier", (double)getPower(stack), 0));
multimap.put(SharedMonsterAttributes.ATTACK_DAMAGE.getName(), new AttributeModifier(MAIN_HAND_MODIFIER, "Weapon modifier", (double)getPower(stack) / 2f, 0));
}
return multimap;
}
}
把我们的盾牌在ModItems中注册一下:
public static final Item RE_SHIELD = new ItemREShield("reshield", IdlFramework.ITEM_TAB);
4.Java代码部分结束,在resources\assets\rejoymod\models\item 中新建我们的盾牌的模型.json文件:
reshield.json
{
"parent": "item/generated",
"textures": {
"layer0": "rejoymod:items/record_yfds"
}
}
在textures\items 中添加我们的盾牌贴图:
在en_us.lang中添加我们的盾牌的游戏名称
item.reshield.name=RE8 Shield
保存所有文件 -> 进入游戏测试:
把我们的盾牌放在副手,当怪物攻击时按右键盾牌会抵挡一次攻击:
注:如果你想制作3D盾牌,只需要通过blockbench制作一个盾牌模型导出为.json文件,替换第4步中的models\item中的物品模型文件就可以了:
导出3D物品.json模型:
3D盾牌游戏内测试效果
|