package minefantasy.item.weapon;
import java.text.DecimalFormat;
import java.util.List;
import minefantasy.api.aesthetic.IWeaponrackHangable;
import minefantasy.api.arrow.Arrows;
import minefantasy.api.arrow.ISpecialBow;
import minefantasy.entity.EntityArrowMF;
import minefantasy.item.ArrowType;
import minefantasy.item.ItemListMF;
import minefantasy.item.ToolMaterialMedieval;
import minefantasy.system.data_minefantasy;
import minefantasy.system.network.PacketManagerMF;
import net.minecraft.client.renderer.texture.IconRegister;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.enchantment.Enchantment;
import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.projectile.EntityArrow;
import net.minecraft.item.EnumAction;
import net.minecraft.item.EnumRarity;
import net.minecraft.item.EnumToolMaterial;
import net.minecraft.item.Item;
import net.minecraft.item.ItemBow;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.packet.Packet;
import net.minecraft.util.EnumChatFormatting;
import net.minecraft.util.Icon;
import net.minecraft.util.StatCollector;
import net.minecraft.world.World;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.entity.player.ArrowLooseEvent;
import net.minecraftforge.event.entity.player.ArrowNockEvent;
import cpw.mods.fml.common.network.PacketDispatcher;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
public class ItemBowMF extends ItemBow implements ISpecialBow, IWeaponrackHangable
{
public static final DecimalFormat decimal_format = new DecimalFormat("#.##");
public Icon[] iconArray = new Icon[3];
private final EnumBowType model;
private EnumToolMaterial material = EnumToolMaterial.WOOD;
public ItemBowMF(int id, EnumToolMaterial mat, EnumBowType type)
{
this(id, (int)((float)mat.getMaxUses()*type.durability), type);
material = mat;
}
public ItemBowMF(int id, int dura, EnumBowType type)
{
super(id);
model = type;
this.maxStackSize = 1;
this.setMaxDamage(dura);
setCreativeTab(ItemListMF.tabArcher);
}
@SideOnly(Side.CLIENT)
/**
* Returns True is the item is renderer in full 3D when hold.
*/
public boolean isFull3D()
{
return true;
}
public int getId()
{
if(this == ItemListMF.bowIronbark)
return 1;
if(this == ItemListMF.bowEbony)
return 2;
if(this == ItemListMF.longbow)
return 3;
return 0;
}
/**
* called when the player releases the use item button. Args: itemstack, world, entityplayer, itemInUseCount
*/
public void onPlayerStoppedUsing(ItemStack item, World world, EntityPlayer player, int time)
{
int power = (this.getMaxItemUseDuration(item) - time);
power *= model.speed; // Speeds up the power in relation to ticks used
power = (int)((float)power / 20F * getMaxPower());//scales the power down from full
if(power > getMaxPower())power = (int)getMaxPower();//limits the power to max
ArrowLooseEvent event = new ArrowLooseEvent(player, item, power);
MinecraftForge.EVENT_BUS.post(event);
if (event.isCanceled())
{
return;
}
power = event.charge;
boolean var5 = player.capabilities.isCreativeMode || EnchantmentHelper.getEnchantmentLevel(Enchantment.infinity.effectId, item) > 0;
if (var5 || player.inventory.hasItem(Item.arrow.itemID))
{
float var7 = (float)power / 20.0F;
var7 = (var7 * var7 + var7 * 2.0F) / 3.0F;
if ((double)var7 < 0.1D)
{
return;
}
if (var7 > 1.0F)
{
var7 = 1.0F;
}
EntityArrow var8 = new EntityArrow(world, player, var7 * 2.0F);
if (var7 == 1.0F)
{
var8.setIsCritical(true);
}
int var9 = EnchantmentHelper.getEnchantmentLevel(Enchantment.power.effectId, item);
if (var9 > 0)
{
var8.setDamage(var8.getDamage() + (double)var9 * 0.5D + 0.5D);
}
int var10 = EnchantmentHelper.getEnchantmentLevel(Enchantment.punch.effectId, item);
if (var10 > 0)
{
var8.setKnockbackStrength(var10);
}
if (EnchantmentHelper.getEnchantmentLevel(Enchantment.flame.effectId, item) > 0)
{
var8.setFire(100);
}
item.damageItem(1, player);
world.playSoundAtEntity(player, "random.bow", 1.0F, 1.0F / (itemRand.nextFloat() * 0.4F + 1.2F) + var7 * 0.5F);
if (var5)
{
var8.canBePickedUp = 2;
}
else
{
player.inventory.consumeInventoryItem(Item.arrow.itemID);
}
if (!world.isRemote)
{
world.spawnEntityInWorld(var8);
}
}
}
/**
* Gets the power of the bow
* 20 is the power of V bows(max)
*/
private float getMaxPower()
{
return 20F * model.power;
}
public ItemStack onFoodEaten(ItemStack item, World world, EntityPlayer player)
{
return item;
}
/**
* How long it takes to use or consume an item
*/
public int getMaxItemUseDuration(ItemStack item)
{
return 72000;
}
/**
* returns the action that specifies what animation to play when the items is being used
*/
public EnumAction getItemUseAction(ItemStack item)
{
return EnumAction.bow;
}
public void addInformation(ItemStack item, EntityPlayer player, List desc, boolean flag)
{
super.addInformation(item, player, desc, flag);
float power = this.model.power;
desc.add(EnumChatFormatting.BLUE+
StatCollector.translateToLocalFormatted("attribute.modifier.plus."+ 0,
new Object[] {decimal_format.format(power),
StatCollector.translateToLocal("attribute.arrow.force")}));;
}
/**
* Called whenever this item is equipped and the right mouse button is pressed. Args: itemStack, world, entityPlayer
*/
public ItemStack onItemRightClick(ItemStack item, World world, EntityPlayer player)
{
ArrowNockEvent event = new ArrowNockEvent(player, item);
MinecraftForge.EVENT_BUS.post(event);
if (event.isCanceled())
{
return event.result;
}
if (player.capabilities.isCreativeMode || player.inventory.hasItem(Item.arrow.itemID))
{
player.setItemInUse(item, this.getMaxItemUseDuration(item));
}
return item;
}
/**
* Return the enchantability factor of the item, most of the time is based on material.
*/
public int getItemEnchantability()
{
return 1;
}
public Icon getIconIndex(ItemStack stack, int useRemaining)
{
float multiplier = 1.0F / model.speed; //Reverses the decimal (eg. 0.5 becomes 2.0)
if (stack != null)
{
if (useRemaining >= 18*multiplier) return iconArray[2];//The return values are
if (useRemaining > 13*multiplier) return iconArray[1];//the icon indexes (in the /Tutorial/Items.png file)
if (useRemaining > 0) return iconArray[0];
}
return this.getIconFromDamage(0);
}
@Override
public void onUpdate(ItemStack item, World world, Entity entity, int i, boolean b)
{
super.onUpdate(item, world, entity, i, b);
if(!item.hasTagCompound())
item.setTagCompound(new NBTTagCompound());
item.stackTagCompound.setInteger("Use", i);
}
@SideOnly(Side.CLIENT)
@Override
public void registerIcons(IconRegister reg)
{
this.itemIcon = reg.registerIcon(this.getIconString());
for (int i = 0; i < 3; ++i)
{
this.iconArray[i] = reg.registerIcon(this.getIconString() + "_" + (i+1));
}
}
@SideOnly(Side.CLIENT)
/**
* used to cycle through icons based on their used duration, i.e. for the bow
*/
public Icon getItemIconForUseDuration(int use)
{
return this.iconArray[use];
}
@Override
public Item setUnlocalizedName(String name)
{
this.setTextureName("minefantasy:Archery/"+name);
return super.setUnlocalizedName(name);
}
public int getDrawAmount(int timer)
{
float multiplier = 1.0F / model.speed; //Reverses the decimal (eg. 0.5 becomes 2.0)
if (timer >= 18 * multiplier)
return 2;
else if (timer > 13 * multiplier)
return 1;
else if (timer > 0)
return 0;
return -2;
}
public ItemStack getArrow(ItemStack item)
{
ItemStack arrow = Arrows.getLoadedArrow(item);
if(arrow == null)
{
return new ItemStack(Item.arrow);
}
return arrow;
}
/**
* Adds an arrow to an item for rendering arrow = null when taking it off
* @param bow the bow used
* @param arrow the arrow applied
*/
public static void loadArrow(EntityPlayer player, ItemStack bow, ItemStack arrow, boolean sendPacket)
{
NBTTagCompound nbt = getOrApplyNBT(bow);
if(arrow == null)
{
nbt.removeTag("arrowID");
nbt.removeTag("arrowSub");
}
else
{
nbt.setInteger("arrowID", arrow.itemID);
nbt.setInteger("arrowSub", arrow.getItemDamage());
if(sendPacket)
{
try
{
Packet packet = PacketManagerMF.getArrowItemPacket(player, arrow.itemID, arrow.getItemDamage());
PacketDispatcher.sendPacketToAllAround(player.posX, player.posY, player.posZ, 16D, player.dimension, packet);
}
catch(Exception e)
{
System.err.println("MineFantasy: Failed to send arrow render packet to bow");
}
}
}
}
private static NBTTagCompound getOrApplyNBT(ItemStack item)
{
if(!item.hasTagCompound())
{
item.setTagCompound(new NBTTagCompound());
}
return item.getTagCompound();
}
@Override
public void getSubItems(int id, CreativeTabs tabs, List list)
{
if(tabs != ItemListMF.tabArcher)
{
super.getSubItems(id, tabs, list);
return;
}
if(id != ItemListMF.shortbow.itemID)
return;
add(list, ItemListMF.shortbow);
add(list, ItemListMF.bowBronze);
add(list, ItemListMF.bowIron);
add(list, ItemListMF.bowOrnate);
add(list, ItemListMF.bowSteel);
add(list, ItemListMF.bowDragon);
add(list, ItemListMF.bowDeepIron);
add(list, ItemListMF.bowMithril);
add(list, ItemListMF.bowComposite);
add(list, ItemListMF.bowIronbark);
add(list, ItemListMF.bowEbony);
add(list, ItemListMF.longbow);
ItemListMF.arrowMF.getSubItems(ItemListMF.arrowMF.itemID, tabs, list);
ItemListMF.boltMF.getSubItems(ItemListMF.arrowMF.itemID, tabs, list);
}
private void add(List list, Item item) {
list.add(new ItemStack(item));
}
@Override
public EnumRarity getRarity(ItemStack itemStack)
{
if (getMaterial() == ToolMaterialMedieval.EBONY)
{
return rarity(itemStack, 1);
}
if (getMaterial() == ToolMaterialMedieval.DRAGONFORGE)
{
return rarity(itemStack, 1);
}
if (getMaterial() == ToolMaterialMedieval.IGNOTUMITE)
{
return rarity(itemStack, 2);
}
return super.getRarity(itemStack);
}
private EnumToolMaterial getMaterial() {
return material;
}
private EnumRarity rarity(ItemStack item, int lvl)
{
EnumRarity[] rarity = new EnumRarity[]{EnumRarity.common, EnumRarity.uncommon, EnumRarity.rare, EnumRarity.epic};
if(item.isItemEnchanted())
{
if(lvl == 0)
{
lvl++;
}
lvl ++;
}
if(lvl >= rarity.length)
{
lvl = rarity.length-1;
}
return rarity[lvl];
}
@Override
public Entity modifyArrow(Entity arrow)
{
if (getMaterial() == ToolMaterialMedieval.DRAGONFORGE)
{
arrow.setFire(60);
}
return arrow;
}
@Override
public boolean canUseRenderer(ItemStack item)
{
return true;
}
}