/** * This class was created by <Vazkii>. It's distributed as * part of the Botania Mod. Get the Source Code in github: * https://github.com/Vazkii/Botania * * Botania is Open Source and distributed under the * Botania License: http://botaniamod.net/license.php * * File Created @ [Feb 21, 2015, 4:58:45 PM (GMT)] */ package vazkii.botania.common.item.equipment.tool.bow; import java.util.function.Predicate; import javax.annotation.Nonnull; import net.minecraft.client.renderer.block.model.ModelResourceLocation; import net.minecraft.enchantment.EnchantmentHelper; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.entity.projectile.EntityArrow; import net.minecraft.init.Enchantments; import net.minecraft.init.Items; import net.minecraft.init.SoundEvents; import net.minecraft.item.ItemArrow; import net.minecraft.item.ItemBow; import net.minecraft.item.ItemStack; import net.minecraft.stats.StatList; import net.minecraft.util.ActionResult; import net.minecraft.util.EnumActionResult; import net.minecraft.util.EnumHand; import net.minecraft.util.ResourceLocation; import net.minecraft.util.SoundCategory; import net.minecraft.world.World; import net.minecraftforge.client.model.ModelLoader; import net.minecraftforge.event.ForgeEventFactory; import net.minecraftforge.fml.common.registry.GameRegistry; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; import vazkii.botania.api.mana.IManaUsingItem; import vazkii.botania.api.mana.ManaItemHandler; import vazkii.botania.client.lib.LibResources; import vazkii.botania.client.render.IModelRegister; import vazkii.botania.common.core.BotaniaCreativeTab; import vazkii.botania.common.core.helper.PlayerHelper; import vazkii.botania.common.item.ModItems; import vazkii.botania.common.item.equipment.tool.ToolCommons; import vazkii.botania.common.lib.LibItemNames; import vazkii.botania.common.lib.LibMisc; public class ItemLivingwoodBow extends ItemBow implements IManaUsingItem, IModelRegister { private static final Predicate<ItemStack> AMMO_FUNC = s -> s != null && s.getItem() instanceof ItemArrow; public static final int MANA_PER_DAMAGE = 40; public ItemLivingwoodBow() { this(LibItemNames.LIVINGWOOD_BOW); } public ItemLivingwoodBow(String name) { setCreativeTab(BotaniaCreativeTab.INSTANCE); GameRegistry.register(this, new ResourceLocation(LibMisc.MOD_ID, name)); setUnlocalizedName(name); setMaxDamage(500); addPropertyOverride(new ResourceLocation("minecraft:pull"), (stack, worldIn, entityIn) -> { if (entityIn == null) { return 0.0F; } else { ItemStack itemstack = entityIn.getActiveItemStack(); return !itemstack.isEmpty() && itemstack.getItem() instanceof ItemLivingwoodBow ? (stack.getMaxItemUseDuration() - entityIn.getItemInUseCount()) * chargeVelocityMultiplier() / 20.0F : 0.0F; } }); } @Nonnull @Override public String getUnlocalizedNameInefficiently(@Nonnull ItemStack par1ItemStack) { return super.getUnlocalizedNameInefficiently(par1ItemStack).replaceAll("item.", "item." + LibResources.PREFIX_MOD); } @Nonnull @Override public ActionResult<ItemStack> onItemRightClick(@Nonnull World world, EntityPlayer player, @Nonnull EnumHand hand) { ItemStack stack = player.getHeldItem(hand); // Copy from superclass with our own check boolean flag = canFire(stack, player); ActionResult<ItemStack> ret = ForgeEventFactory.onArrowNock(stack, world, player, hand, flag); if (ret != null) return ret; if (!player.capabilities.isCreativeMode && !flag) { return new ActionResult<>(EnumActionResult.FAIL, stack); } else { player.setActiveHand(hand); return new ActionResult<>(EnumActionResult.SUCCESS, stack); } } @Override public void onPlayerStoppedUsing(@Nonnull ItemStack stack, @Nonnull World world, EntityLivingBase shooter, int useTicks) { EntityPlayer player = (EntityPlayer) shooter; // Begin copy modified ItemBow.onPlayerStoppedUsing boolean flag = canFire(stack, player); // Botania - Custom canFire check ItemStack itemstack = getAmmo(player); int i = (int) ((getMaxItemUseDuration(stack) - useTicks) * chargeVelocityMultiplier()); // Botania - velocity multiplier i = net.minecraftforge.event.ForgeEventFactory.onArrowLoose(stack, world, player, i, !itemstack.isEmpty() || flag); if (i < 0) return; if (!itemstack.isEmpty() || flag) { if (itemstack.isEmpty()) { itemstack = new ItemStack(Items.ARROW); } float f = getArrowVelocity(i); if (f >= 0.1D) { boolean infinite = player.capabilities.isCreativeMode || (itemstack.getItem() instanceof ItemArrow ? ((ItemArrow)itemstack.getItem()).isInfinite(itemstack, stack, player) : false); if (!world.isRemote) { ItemArrow itemarrow = (ItemArrow) (itemstack.getItem() instanceof ItemArrow ? itemstack.getItem() : Items.ARROW); EntityArrow entityarrow = itemarrow.createArrow(world, itemstack, shooter); entityarrow.setAim(shooter, shooter.rotationPitch, shooter.rotationYaw, 0.0F, f * 3.0F, 1.0F); if (f == 1.0F) { entityarrow.setIsCritical(true); } int j = EnchantmentHelper.getEnchantmentLevel(Enchantments.POWER, stack); if (j > 0) { entityarrow.setDamage(entityarrow.getDamage() + j * 0.5D + 0.5D); } int k = EnchantmentHelper.getEnchantmentLevel(Enchantments.PUNCH, stack); if (k > 0) { entityarrow.setKnockbackStrength(k); } if (EnchantmentHelper.getEnchantmentLevel(Enchantments.FLAME, stack) > 0) { entityarrow.setFire(100); } // Botania - move bow damage into onFire (below) if (infinite) { entityarrow.pickupStatus = EntityArrow.PickupStatus.CREATIVE_ONLY; } world.spawnEntity(entityarrow); onFire(stack, shooter, infinite, entityarrow); } world.playSound(null, shooter.posX, shooter.posY, shooter.posZ, SoundEvents.ENTITY_ARROW_SHOOT, SoundCategory.NEUTRAL, 1.0F, 1.0F / (itemRand.nextFloat() * 0.4F + 1.2F) + f * 0.5F); player.addStat(StatList.getObjectUseStats(this)); } } // End modified ItemBow.onPlayerStoppedUsing } float chargeVelocityMultiplier() { return 1F; } boolean canFire(ItemStack stack, EntityPlayer player) { return player.capabilities.isCreativeMode || EnchantmentHelper.getEnchantmentLevel(Enchantments.INFINITY, stack) > 0 || PlayerHelper.hasAmmo(player, AMMO_FUNC); } void onFire(ItemStack bow, EntityLivingBase living, boolean infinity, EntityArrow arrow) { if(living instanceof EntityPlayerMP) { ToolCommons.damageItem(bow, 1, living, MANA_PER_DAMAGE); if(((EntityPlayerMP) living).interactionManager.getGameType().isSurvivalOrAdventure() && !infinity) PlayerHelper.consumeAmmo((EntityPlayerMP) living, AMMO_FUNC); } } @Override public void onUpdate(ItemStack stack, World world, Entity player, int par4, boolean par5) { if(!world.isRemote && player instanceof EntityPlayer && stack.getItemDamage() > 0 && ManaItemHandler.requestManaExactForTool(stack, (EntityPlayer) player, MANA_PER_DAMAGE * 2, true)) stack.setItemDamage(stack.getItemDamage() - 1); } @Override public boolean getIsRepairable(ItemStack par1ItemStack, ItemStack par2ItemStack) { return par2ItemStack.getItem() == ModItems.manaResource && par2ItemStack.getItemDamage() == 3 || super.getIsRepairable(par1ItemStack, par2ItemStack); } @Override public boolean usesMana(ItemStack stack) { return true; } private ItemStack getAmmo(EntityPlayer player) { if(isArrow(player.getHeldItem(EnumHand.OFF_HAND))) return player.getHeldItem(EnumHand.OFF_HAND); else if(isArrow(player.getHeldItem(EnumHand.MAIN_HAND))) return player.getHeldItem(EnumHand.MAIN_HAND); else for(int i = 0; i < player.inventory.getSizeInventory(); ++i) { ItemStack itemstack = player.inventory.getStackInSlot(i); if (isArrow(itemstack)) return itemstack; } return ItemStack.EMPTY; } @SideOnly(Side.CLIENT) @Override public void registerModels() { ModelLoader.setCustomModelResourceLocation(this, 0, new ModelResourceLocation(getRegistryName(), "inventory")); } }