dynamicswordskills.api.ItemSkillProvider.java Source code

Java tutorial

Introduction

Here is the source code for dynamicswordskills.api.ItemSkillProvider.java

Source

/**
Copyright (C) <2015> <coolAlias>
    
This file is part of coolAlias' Dynamic Sword Skills Minecraft Mod; as such,
you can redistribute it and/or modify it under the terms of the GNU
General Public License as published by the Free Software Foundation,
either version 3 of the License, or (at your option) any later version.
    
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
    
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

package dynamicswordskills.api;

import java.util.List;

import net.minecraft.block.Block;
import net.minecraft.client.renderer.ItemModelMesher;
import net.minecraft.client.resources.model.ModelBakery;
import net.minecraft.client.resources.model.ModelResourceLocation;
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.item.EnumAction;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.BlockPos;
import net.minecraft.util.EnumChatFormatting;
import net.minecraft.util.StatCollector;
import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;

import com.google.common.collect.Multimap;

import dynamicswordskills.item.IModItem;
import dynamicswordskills.skills.SkillBase;

/**
 * 
 * Base class providing all the functionality needed for ISkillItem as well as
 * acting almost exactly like a regular sword (aside from the web-cutting ability),
 * without actually being a sword.
 * 
 * If the item cannot for some reason extend {@link #ItemSword} but should still be
 * considered a sword, {@link ISword} should also be implemented. This will allow
 * the item to be used with skills that require swords, such as Mortal Draw.
 * 
 * Note that an ISkillProvider item will always be able to use the skill it provides,
 * even if the item is not a sword and the skill would otherwise require such.
 * 
 * It is a simple class, having a set skill and level per item rather than using NBT.
 * 
 * Easily create a new skill-providing weapon simply by extending this class.
 *
 */
public class ItemSkillProvider extends Item implements IModItem, ISkillProvider {
    /** The weapon's tool material determines damage and durability */
    private final ToolMaterial material;

    /** Weapon damage is based on tool material, just like swords */
    private float weaponDamage;

    /** The skill id and level of the SkillBase.{skill} granted by this Item */
    private final byte skillId, level;

    /** This is used mainly for the tooltip display */
    private SkillBase skill;

    /** Whether the player should be granted basic sword skill should they not have it */
    private final boolean grantsBasicSkill;

    /**
     * Shortcut method sets ISkillItem to always grant Basic Sword skill if needed to use
     * the main skill designated by the skill id below.
     * Standard sword-like weapon with max stack size of 1; be sure to set the unlocalized
     * name, texture, and creative tab using chained methods if using the class as is.
     * @param material   the tool material determines both durability and damage
     * @param skill      use SkillBase.{skill} during construction to ensure a valid skill
     * @param level      should be at least 1, and will be capped automatically at the skill's max level
     */
    public ItemSkillProvider(ToolMaterial material, SkillBase skill, byte level) {
        this(material, skill, level, true);
    }

    /**
     * Standard sword-like weapon with max stack size of 1; be sure to set the unlocalized
     * name, texture, and creative tab using chained methods if using the class as is.
     * @param material         the tool material determines both durability and damage
     * @param skill            use SkillBase.{skill} during construction to ensure a valid skill
     * @param level            should be at least 1, and will be capped automatically at the skill's max level
     * @param grantsBasicSkill   if true, the player will be temporarily granted Basic Sword skill in
     *                      order to use the ISkillItem's main skill, if other than Basic Sword
     */
    public ItemSkillProvider(ToolMaterial material, SkillBase skill, byte level, boolean grantsBasicSkill) {
        super();
        this.material = material;
        this.weaponDamage = 4.0F + this.material.getDamageVsEntity();
        this.skillId = skill.getId();
        this.level = level;
        this.grantsBasicSkill = grantsBasicSkill;
        setMaxDamage(this.material.getMaxUses());
        setMaxStackSize(1);
    }

    /**
     * A convenience / optimizer for displaying item tooltips; never used by the rest of the API
     * Store the leveled SkillBase locally in the Item class the first time the method is
     * called to improve efficiency (since the level will never change) using the method
     * {@link SkillBase#getSkillFromItem(ItemStack, ISkillProvider) SkillBase.getSkillFromItem}
     * @param stack not used in this implementation, but required for the SkillBase method above
     * @return   DO NOT use the returned skill as a player's active instance - it is not unique!
     */
    protected SkillBase getSkill(ItemStack stack) {
        if (skill == null) {
            skill = SkillBase.getSkillFromItem(stack, this);
        }
        return skill;
    }

    @Override
    public int getSkillId(ItemStack stack) {
        return skillId;
    }

    @Override
    public byte getSkillLevel(ItemStack stack) {
        return level;
    }

    @Override
    public boolean grantsBasicSwordSkill(ItemStack stack) {
        return grantsBasicSkill;
    }

    @Override
    public boolean hitEntity(ItemStack stack, EntityLivingBase target, EntityLivingBase attacker) {
        stack.damageItem(1, attacker);
        return true;
    }

    @SideOnly(Side.CLIENT)
    public boolean isFull3D() {
        return true;
    }

    @Override
    public EnumAction getItemUseAction(ItemStack stack) {
        return EnumAction.BLOCK;
    }

    @Override
    public int getItemEnchantability() {
        return material.getEnchantability();
    }

    @Override
    public boolean getIsRepairable(ItemStack toRepair, ItemStack stack) {
        return ItemStack.areItemsEqual(stack, material.getRepairItemStack())
                || super.getIsRepairable(toRepair, stack);
    }

    @Override
    public int getMaxItemUseDuration(ItemStack stack) {
        return 72000;
    }

    @Override
    public boolean onBlockDestroyed(ItemStack stack, World world, Block block, BlockPos pos,
            EntityLivingBase entity) {
        if (block.getBlockHardness(world, pos) != 0.0D) {
            stack.damageItem(2, entity);
        }
        return true;
    }

    @Override
    public ItemStack onItemRightClick(ItemStack stack, World world, EntityPlayer player) {
        player.setItemInUse(stack, getMaxItemUseDuration(stack));
        return stack;
    }

    @Override
    public String getItemStackDisplayName(ItemStack stack) {
        SkillBase skill = getSkill(stack);
        return StatCollector.translateToLocal("item.dss.skillitem.name")
                + (skill != null ? (" " + skill.getDisplayName()) : "");
    }

    @Override
    @SideOnly(Side.CLIENT)
    public void addInformation(ItemStack stack, EntityPlayer player, List list, boolean par4) {
        SkillBase skill = getSkill(stack);
        if (skill != null) {
            list.add(StatCollector.translateToLocalFormatted("tooltip.dss.skillprovider.desc.skill",
                    EnumChatFormatting.GOLD + skill.getDisplayName()));
            list.add(StatCollector.translateToLocalFormatted("tooltip.dss.skillprovider.desc.level",
                    skill.getLevel(), skill.getMaxLevel()));
            if (grantsBasicSwordSkill(stack)) {
                list.add(StatCollector.translateToLocalFormatted("tooltip.dss.skillprovider.desc.provider",
                        EnumChatFormatting.DARK_GREEN + SkillBase.swordBasic.getDisplayName()));
            }
            list.addAll(skill.getDescription(player));
        }
    }

    @Override
    @SideOnly(Side.CLIENT)
    public void registerVariants() {
        ModelBakery.addVariantName(this, "iron_sword");
    }

    @Override
    @SideOnly(Side.CLIENT)
    public void registerRenderer(ItemModelMesher mesher) {
        mesher.register(this, 0, new ModelResourceLocation("iron_sword", "inventory"));
    }

    @Override
    public Multimap getAttributeModifiers(ItemStack stack) {
        Multimap multimap = super.getAttributeModifiers(stack);
        multimap.put(SharedMonsterAttributes.attackDamage.getAttributeUnlocalizedName(),
                new AttributeModifier(itemModifierUUID, "Weapon modifier", weaponDamage, 0));
        return multimap;
    }
}