package minefantasy.mf2.mechanics; import minefantasy.mf2.api.archery.AmmoMechanicsMF; import minefantasy.mf2.api.rpg.RPGElements; import minefantasy.mf2.api.rpg.SkillList; import minefantasy.mf2.api.stamina.StaminaBar; import minefantasy.mf2.config.ConfigStamina; import net.minecraft.enchantment.Enchantment; import net.minecraft.enchantment.EnchantmentHelper; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Items; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.world.World; import net.minecraftforge.event.entity.player.ArrowLooseEvent; import net.minecraftforge.event.entity.player.ArrowNockEvent; import cpw.mods.fml.common.eventhandler.EventPriority; import cpw.mods.fml.common.eventhandler.SubscribeEvent; import cpw.mods.fml.common.gameevent.PlayerEvent.ItemPickupEvent; public class ArrowHandlerMF { /** * When the arrow is pulled back it initiates */ @SubscribeEvent public void readyBow(ArrowNockEvent event) { if(AmmoMechanicsMF.arrows == null || AmmoMechanicsMF.arrows.size() <= 0) { return; } EntityPlayer user = event.entityPlayer; ItemStack bow = event.result; /*Checks over registered arrows and finds one to load * The Quiver can be used to determine this */ ItemStack arrowToFire = AmmoMechanicsMF.reloadBow(bow); if(arrowToFire != null) { user.setItemInUse(bow, bow.getMaxItemUseDuration());//Starts pullback loadArrow(user, bow, arrowToFire);//adds the arrow to NBT for rendering and later use event.setCanceled(true); return; } /* for(int a = 0; a < AmmoMechanicsMF.arrows.size(); a ++) { ItemStack arrow = AmmoMechanicsMF.arrows.get(a); if(user.inventory.hasItemStack(arrow)) { user.setItemInUse(bow, bow.getMaxItemUseDuration());//Starts pullback loadArrow(user, bow, arrow);//adds the arrow to NBT for rendering and later use event.setCanceled(true); return; } } */ } /** * This method adds arrows to the bow */ public static void loadArrow(EntityPlayer player, ItemStack bow, ItemStack arrow) { if(player.worldObj.isRemote) { return; } NBTTagCompound nbt = getOrApplyNBT(bow); if(arrow == null) { nbt.removeTag("loadedArrow"); } else { NBTTagCompound loaded = new NBTTagCompound(); arrow.writeToNBT(loaded); nbt.setTag("loadedArrow", loaded); } } /** * Gets the NBT, if there is none, it creates it */ private static NBTTagCompound getOrApplyNBT(ItemStack bow) { if(!bow.hasTagCompound()) { bow.setTagCompound(new NBTTagCompound()); } return bow.getTagCompound(); } @SubscribeEvent (priority=EventPriority.HIGHEST) public void applyExhaustArrow(ArrowLooseEvent event) { if(StaminaBar.isSystemActive && !StaminaBar.isAnyStamina(event.entityPlayer, false)) { if(ConfigStamina.weaponDrain < 1.0F) event.charge *= ConfigStamina.weaponDrain; } } /** * This initates when firing a bow * @param event */ @SubscribeEvent public void fireArrow(ArrowLooseEvent event) { float power = event.charge; EntityPlayer user = event.entityPlayer; ItemStack bow = event.bow; World world = event.entity.worldObj; boolean infinite = getIsInfinite(user, bow); float charge = power / 20.0F; charge = (charge * charge + charge * 2.0F) / 3.0F; if (charge < 0.1D) { return; } if (charge > 1.0F) { charge = 1.0F; } //Default is flint arrow ItemStack arrow = new ItemStack(Items.arrow); if(AmmoMechanicsMF.getArrowOnBow(bow) != null) { //if an arrow is on the bow, it uses that arrow = AmmoMechanicsMF.getArrowOnBow(bow); } if(AmmoMechanicsMF.handlers != null && AmmoMechanicsMF.handlers.size() > 0) { for(int a = 0; a < AmmoMechanicsMF.handlers.size(); a ++) { //If the Arrow handler succeeds at firing an arrow if(AmmoMechanicsMF.handlers.get(a).onFireArrow(world, arrow, bow, user, charge, infinite)) { if(!user.capabilities.isCreativeMode) { bow.damageItem(1, user); } if(!infinite) { consumePlayerItem(user, arrow); } world.playSoundAtEntity(user, "minefantasy2:weapon.bowFire", 0.5F, 1.0F / (world.rand.nextFloat() * 0.4F + 1.2F) + charge * 0.5F); loadArrow(user, bow, null); event.setCanceled(true); AmmoMechanicsMF.consumeAmmo(user, bow); break; } } } } private boolean getIsInfinite(EntityPlayer user, ItemStack bow) { return user.capabilities.isCreativeMode || EnchantmentHelper.getEnchantmentLevel(Enchantment.infinity.effectId, bow) > 0; } //Used to take an item/subId from the inventory private boolean consumePlayerItem(EntityPlayer player, ItemStack item) { for(int a = 0; a < player.inventory.getSizeInventory(); a ++) { ItemStack i = player.inventory.getStackInSlot(a); if(i != null && i.isItemEqual(item)) { player.inventory.decrStackSize(a, 1); return true; } } return false; } }