package game.item; import java.util.List; import java.util.Map; import java.util.Set; import game.collect.Maps; import game.collect.Sets; import game.block.Block; import game.color.TextColor; import game.entity.attributes.Attribute; import game.entity.attributes.AttributeModifier; import game.entity.npc.EntityNPC; import game.entity.types.EntityLiving; import game.nbt.NBTTagCompound; import game.renderer.ItemMeshDefinition; import game.renderer.blockmodel.ModelBlock; import game.renderer.blockmodel.Transforms; import game.rng.Random; import game.util.ExtMath; import game.world.BlockPos; import game.world.Facing; import game.world.HitPosition; import game.world.Vec3; import game.world.World; public class Item { protected static final Random itemRand = new Random(); protected int maxStackSize = 64; private int maxDamage; protected boolean hasSubtypes; private Item containerItem; private String potionEffect; private String display; private CheatTab tabToDisplayOn; private TextColor color = null; public Item setMaxStackSize(int maxStackSize) { this.maxStackSize = maxStackSize; return this; } public Item setHasSubtypes(boolean hasSubtypes) { this.hasSubtypes = hasSubtypes; return this; } /** * set max damage of an Item */ public Item setMaxDamage(int maxDamageIn) { this.maxDamage = maxDamageIn; return this; } public Item setDisplay(String name) { this.display = name; return this; } public Item setContainerItem(Item containerItem) { this.containerItem = containerItem; return this; } /** * Sets the string representing this item's effect on a potion when used as an ingredient. */ public Item setPotionEffect(String potionEffect) { this.potionEffect = potionEffect; return this; } /** * returns this; */ public Item setTab(CheatTab tab) { this.tabToDisplayOn = tab; return this; } public Item setColor(TextColor color) { this.color = color; return this; } public Block getBlock() { return null; } /** * Called when an ItemStack with NBT data is read to potentially that ItemStack's NBT data */ public boolean updateItemStackNBT(NBTTagCompound nbt) { return false; } /** * Called when a Block is right-clicked with this Item */ public boolean onItemUse(ItemStack stack, EntityNPC playerIn, World worldIn, BlockPos pos, Facing side, float hitX, float hitY, float hitZ) { return false; } public boolean onAction(ItemStack stack, EntityNPC player, World world, ItemControl control, BlockPos block) { return false; } public float getStrVsBlock(ItemStack stack, Block state) { return 1.0F; } /** * Called whenever this item is equipped and the right mouse button is pressed. Args: itemStack, world, entityPlayer */ public ItemStack onItemRightClick(ItemStack itemStackIn, World worldIn, EntityNPC playerIn) { return itemStackIn; } /** * Called when the player finishes using this Item (E.g. finishes eating.). Not called when the player stops using * the Item before the action is complete. */ public ItemStack onItemUseFinish(ItemStack stack, World worldIn, EntityNPC playerIn) { return stack; } /** * Returns the maximum size of the stack for a specific item. *Isn't this more a Set than a Get?* */ public int getItemStackLimit() { return this.maxStackSize; } /** * Converts the given ItemStack damage value into a metadata value to be placed in the world when this Item is * placed as a Block (mostly used with ItemBlocks). */ public int getMetadata(int damage) { return 0; } public boolean getHasSubtypes() { return this.hasSubtypes; } /** * Returns the maximum damage an item can take. */ public int getMaxDamage() { return this.maxDamage; } public boolean isDamageable() { return this.maxDamage > 0 && !this.hasSubtypes; } /** * 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, EntityLiving target, EntityLiving attacker) { return false; } /** * Called when a Block is destroyed using this Item. Return true to trigger the "Use Item" statistic. */ public boolean onBlockDestroyed(ItemStack stack, World worldIn, Block blockIn, BlockPos pos, EntityLiving playerIn) { return false; } /** * Check whether this Item can harvest the given Block */ public boolean canHarvestBlock(Block blockIn) { return false; } /** * Returns true if the item can be used on the given entity, e.g. shears on sheep. */ public boolean itemInteractionForEntity(ItemStack stack, EntityNPC playerIn, EntityLiving target) { return false; } // public String getUnlocalizedNameInefficiently(ItemStack stack) // { // String s = this.getUnlocalizedName(stack); // return s == null ? "" : s; // I18n.translate(s); // } // /** // * Returns the unlocalized name of this item. // */ // public String getUnlocalizedName() // { // return "item." + this.unlocalizedName; // } public String getDisplay(ItemStack stack) { return this.display; } /** * If this function returns true (or the item is damageable), the ItemStack's NBT tag will be sent to the client. */ public boolean getShareTag() { return true; } public Item getContainerItem() { return this.containerItem; } /** * True if this Item has a container item (a.k.a. crafting result) */ public boolean hasContainerItem() { return this.containerItem != null; } public int getColorFromItemStack(ItemStack stack, int renderPass) { return 16777215; } // /** // * Called each tick as long the item is on a player inventory. Uses by maps to check if is on a player hand and // * update it's contents. // */ // public void onUpdate(ItemStack stack, World worldIn, Entity entityIn, int itemSlot, boolean isSelected) // { // } // // /** // * Called when item is crafted/smelted. Used only by maps so far. // */ // public void onCreated(ItemStack stack, World worldIn, EntityNPC playerIn) // { // } /** * returns the action that specifies what animation to play when the items is being used */ public ItemAction getItemUseAction(ItemStack stack) { return ItemAction.NONE; } public ItemAction getItemPosition(ItemStack stack) { return ItemAction.NONE; } /** * How long it takes to use or consume an item */ public int getMaxItemUseDuration(ItemStack stack) { return 0; } /** * Called when the player stops using an Item (stops holding the right mouse button). */ public void onPlayerStoppedUsing(ItemStack stack, World worldIn, EntityNPC playerIn, int timeLeft) { } public String getPotionEffect(ItemStack stack) { return this.potionEffect; } public boolean isPotionIngredient(ItemStack stack) { return this.getPotionEffect(stack) != null; } /** * allows items to add custom lines of information to the mouseover description */ public void addInformation(ItemStack stack, EntityNPC playerIn, List tooltip) { } // public String getItemStackDisplayName(ItemStack stack) // { // return this.getUnlocalizedName(stack); // } public boolean hasEffect(ItemStack stack) { return stack.isItemEnchanted(); } public TextColor getColor(ItemStack stack) { return this.color != null ? this.color : (stack.isItemEnchanted() ? TextColor.NEON : TextColor.WHITE); } /** * Checks isDamagable and if it cannot be stacked */ public boolean isItemTool(ItemStack stack) { return this.getItemStackLimit() == 1 && this.isDamageable(); } protected HitPosition getMovingObjectPositionFromPlayer(World worldIn, EntityNPC playerIn, boolean useLiquids) { float f = playerIn.rotPitch; float f1 = playerIn.rotYaw; double d0 = playerIn.posX; double d1 = playerIn.posY + (double)playerIn.getEyeHeight(); double d2 = playerIn.posZ; Vec3 vec3 = new Vec3(d0, d1, d2); float f2 = ExtMath.cos(-f1 * 0.017453292F - (float)Math.PI); float f3 = ExtMath.sin(-f1 * 0.017453292F - (float)Math.PI); float f4 = -ExtMath.cos(-f * 0.017453292F); float f5 = ExtMath.sin(-f * 0.017453292F); float f6 = f3 * f4; float f7 = f2 * f4; double d3 = 5.0D; Vec3 vec31 = vec3.addVector((double)f6 * d3, (double)f5 * d3, (double)f7 * d3); return worldIn.rayTraceBlocks(vec3, vec31, useLiquids, !useLiquids, false); } /** * Return the enchantability factor of the item, most of the time is based on material. */ public int getItemEnchantability() { return 0; } /** * returns a list of items with the same ID, but different meta (eg: dye returns 16 items) */ public void getSubItems(Item itemIn, CheatTab tab, List subItems) { subItems.add(new ItemStack(itemIn, 1, 0)); } /** * gets the tab this item is displayed on */ public CheatTab getTab() { return this.tabToDisplayOn; } // public boolean canItemEditBlocks() // { // return false; // } /** * Return whether this item is repairable in an anvil. */ public boolean getIsRepairable(ItemStack toRepair, ItemStack repair) { return false; } public Map> getItemAttributeModifiers() { return Maps.newHashMap(); } public Map> getItemInventoryModifiers() { return Maps.newHashMap(); } // public boolean canBeDyed() { // return false; // } public boolean isFragile() { return false; } // public boolean isValidMeta(int meta) { // return true; // meta == 0; // } // // public int getDefaultMeta() { // return 0; // } public final Set getValidTags() { return Sets.newHashSet(); } // private static final Set VALID_TAGS = Sets.newHashSet("Name", "ench", "RepairCost"); protected final boolean validateNbt(NBTTagCompound tag) { return true; } // private final boolean isValidNbt(ItemStack stack) { // if(!stack.hasTagCompound()) { // return true; // } // NBTTagCompound tag = stack.getTagCompound(); // if(tag.hasNoTags()) { // return false; // } // Set keys = tag.getKeySet(); // int z = keys.size(); // boolean validate = false; // if(z > 0) { // for(String v : VALID_TAGS) { // if(keys.contains(v)) { // z--; // if(z == 0) { // break; // } // } // } // } //// if(adv && z > 0) { ////// for(String v : ADV_TAGS) { //// if(keys.contains("Unbreakable")) { //// z--; ////// if(z == 0) { ////// break; ////// } //// } ////// } //// } // if(z > 0) { // for(String v : this.getValidTags()) { // if(keys.contains(v)) { // validate = true; // z--; // if(z == 0) { // break; // } // } // } // } // if(z > 0) { // return false; // } //// if(tag.hasKey("display")) { //// if(!tag.hasKey("display", 10)) { //// return false; //// } //// NBTTagCompound display = tag.getCompoundTag("display"); //// keys = display.getKeySet(); //// z = keys.size(); // if(tag.hasKey("Name")) { // if(!tag.hasKey("Name", 8)) { // return false; // } // if(tag.getString("Name").length() > 64) { // return false; // } //// z--; // } //// if(display.hasKey("Lore")) { //// if(!adv) { //// display.removeTag("Lore"); //// if(display.hasNoTags()) { //// tag.removeTag("display"); //// if(tag.hasNoTags()) { //// stack.setTagCompound(null); //// return true; //// } //// } //// } //// else { //// if(!display.hasKey("Lore", 9)) { //// return false; //// } //// NBTTagList lore = display.getTagList("Lore", 8); //// if(lore.hasNoTags()) { //// return false; //// } //// } //// z--; //// } //// if(display.hasKey("color")) { //// if(!display.hasKey("color", 3)) { //// return false; //// } //// if(!this.canBeDyed()) { //// return false; //// } //// z--; //// } //// if(z > 0) { //// return false; //// } //// } // if(tag.hasKey("RepairCost")) { // if(!tag.hasKey("RepairCost", 3)) { // return false; // } // if(tag.getInteger("RepairCost") < 1) { // return false; // } // } // if(tag.hasKey("ench")) { // if(!tag.hasKey("ench", 9)) { // return false; // } // NBTTagList ench = tag.getTagList("ench", 10); // if(ench.hasNoTags()) { // return false; // } // if(ench.tagCount() > Enchantment.getNames().size()) { // return false; // } // Enchantment[] ecn = new Enchantment[ench.tagCount()]; // for(int e = 0; e < ench.tagCount(); e++) { // NBTTagCompound ec = ench.getCompoundTagAt(e); // if(ec.getKeySet().size() != 2 || !ec.hasKey("id", 2) || !ec.hasKey("lvl", 2)) { // return false; // } // int id = ec.getShort("id"); // int lvl = ec.getShort("lvl"); // Enchantment en = Enchantment.getEnchantmentById(id); // if(en == null) { // return false; // } //// if(!adv && (lvl < en.getMinLevel() || lvl > en.getMaxLevel())) { //// return false; //// } //// if(!adv && !en.canApply(stack)) { //// return false; //// } // ecn[e] = en; // } // for(int e = 0; e < ecn.length; e++) { // for(int f = 0; f < ecn.length; f++) { // if(f != e && ecn[e] == ecn[f]) { // return false; // } // } // } // } //// if(adv) { //// if(tag.hasKey("Unbreakable")) { //// if(!tag.hasKey("Unbreakable", 1)) { //// return false; //// } //// } //// if(tag.hasKey("HideFlags")) { //// if(!tag.hasKey("HideFlags", 3)) { //// return false; //// } //// } //// } // if(validate) { // if(this.validateNbt(stack.getTagCompound())) { // if(tag.hasNoTags()) { // stack.setTagCompound(null); // } // } // else { // return false; // } // } // return true; // } // boolean validate(ItemStack stack) { //// if(!bypass && this.isSpecialItem()) { //// return false; //// } // boolean flag = true; // if(this.isDamageable() && (stack.getItemDamage() < 0 || (stack.getItemDamage() > this.getMaxDamage()))) { // stack.setItemDamage(0); // flag = false; // } // if(stack.stackSize > stack.getMaxStackSize()) { // stack.stackSize = stack.getMaxStackSize(); // flag = false; // } // else if(stack.stackSize < 1) { // stack.stackSize = 1; // flag = false; // } // if(!this.isValidNbt(stack)) { // stack.setTagCompound(null); // flag = false; // } // return flag; // } // public boolean canBreakBlocks() { // return true; // } // // public boolean canUseInAir() { // return false; // } // // public boolean ignoresBlocks() { // return false; // } public float getRadiation(ItemStack stack) { return 0.0f; } public boolean isMagnetic() { return false; } public boolean isFirstPerson() { return true; } public String getHotbarText(EntityNPC player, ItemStack stack) { return stack.getColoredName(); } public Transforms getTransform() { return Transforms.ITEM; } public ModelBlock getModel(String name, int meta) { return new ModelBlock(this.getTransform(), name); } public ItemMeshDefinition getMesher() { return null; } public void getRenderItems(Item itemIn, List subItems) { this.getSubItems(itemIn, null, subItems); } }