package net.minecraft.item; import com.google.common.collect.Multimap; import java.util.Set; import net.minecraft.block.Block; import net.minecraft.block.state.IBlockState; import net.minecraft.creativetab.CreativeTabs; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.SharedMonsterAttributes; import net.minecraft.entity.ai.attributes.AttributeModifier; import net.minecraft.inventory.EntityEquipmentSlot; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; public class ItemTool extends Item { private final Set effectiveBlocks; protected float efficiency; /** Damage versus entities. */ protected float attackDamage; protected float attackSpeed; /** The material this tool is made from. */ protected Item.ToolMaterial toolMaterial; protected ItemTool(float attackDamageIn, float attackSpeedIn, Item.ToolMaterial materialIn, Set effectiveBlocksIn) { this.efficiency = 4.0F; this.toolMaterial = materialIn; this.effectiveBlocks = effectiveBlocksIn; this.maxStackSize = 1; this.setMaxDamage(materialIn.getMaxUses()); this.efficiency = materialIn.getEfficiency(); this.attackDamage = attackDamageIn + materialIn.getAttackDamage(); this.attackSpeed = attackSpeedIn; this.setCreativeTab(CreativeTabs.TOOLS); if (this instanceof ItemPickaxe) { toolClass = "pickaxe"; } else if (this instanceof ItemAxe) { toolClass = "axe"; } else if (this instanceof ItemSpade) { toolClass = "shovel"; } } protected ItemTool(Item.ToolMaterial materialIn, Set effectiveBlocksIn) { this(0.0F, 0.0F, materialIn, effectiveBlocksIn); } public float getDestroySpeed(ItemStack stack, IBlockState state) { for (String type : getToolClasses(stack)) { if (state.getBlock().isToolEffective(type, state)) return efficiency; } return this.effectiveBlocks.contains(state.getBlock()) ? this.efficiency : 1.0F; } /** * Current implementations of this method in child classes do not use the entry argument beside ev. They just raise * the damage on the stack. */ public boolean hitEntity(ItemStack stack, EntityLivingBase target, EntityLivingBase attacker) { stack.damageItem(2, attacker); return true; } /** * Called when a Block is destroyed using this Item. Return true to trigger the "Use Item" statistic. */ public boolean onBlockDestroyed(ItemStack stack, World worldIn, IBlockState state, BlockPos pos, EntityLivingBase entityLiving) { if (!worldIn.isRemote && (double)state.getBlockHardness(worldIn, pos) != 0.0D) { stack.damageItem(1, entityLiving); } return true; } /** * Returns True is the item is renderer in full 3D when hold. */ @SideOnly(Side.CLIENT) public boolean isFull3D() { return true; } /** * Return the enchantability factor of the item, most of the time is based on material. */ public int getItemEnchantability() { return this.toolMaterial.getEnchantability(); } /** * Return the name for this tool's material. */ public String getToolMaterialName() { return this.toolMaterial.toString(); } /** * Return whether this item is repairable in an anvil. * * @param toRepair the {@code ItemStack} being repaired * @param repair the {@code ItemStack} being used to perform the repair */ public boolean getIsRepairable(ItemStack toRepair, ItemStack repair) { ItemStack mat = this.toolMaterial.getRepairItemStack(); if (!mat.isEmpty() && net.minecraftforge.oredict.OreDictionary.itemMatches(mat, repair, false)) return true; return super.getIsRepairable(toRepair, repair); } /** * Gets a map of item attribute modifiers, used by ItemSword to increase hit damage. */ public Multimap getItemAttributeModifiers(EntityEquipmentSlot equipmentSlot) { Multimap multimap = super.getItemAttributeModifiers(equipmentSlot); if (equipmentSlot == EntityEquipmentSlot.MAINHAND) { multimap.put(SharedMonsterAttributes.ATTACK_DAMAGE.getName(), new AttributeModifier(ATTACK_DAMAGE_MODIFIER, "Tool modifier", (double)this.attackDamage, 0)); multimap.put(SharedMonsterAttributes.ATTACK_SPEED.getName(), new AttributeModifier(ATTACK_SPEED_MODIFIER, "Tool modifier", (double)this.attackSpeed, 0)); } return multimap; } /*===================================== FORGE START =================================*/ @javax.annotation.Nullable private String toolClass; @Override public int getHarvestLevel(ItemStack stack, String toolClass, @javax.annotation.Nullable net.minecraft.entity.player.EntityPlayer player, @javax.annotation.Nullable IBlockState blockState) { int level = super.getHarvestLevel(stack, toolClass, player, blockState); if (level == -1 && toolClass.equals(this.toolClass)) { return this.toolMaterial.getHarvestLevel(); } else { return level; } } @Override public Set getToolClasses(ItemStack stack) { return toolClass != null ? com.google.common.collect.ImmutableSet.of(toolClass) : super.getToolClasses(stack); } /*===================================== FORGE END =================================*/ }