package game.enchantment; import java.util.Iterator; import java.util.List; import java.util.Map; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import game.entity.DamageSource; import game.entity.Entity; import game.entity.types.EntityLiving; import game.init.Items; import game.item.Item; import game.item.ItemStack; import game.nbt.NBTTagCompound; import game.nbt.NBTTagList; import game.rng.Random; import game.rng.WeightedList; public class EnchantmentHelper { /** Is the random seed of enchantment effects. */ private static final Random enchantmentRand = new Random(); /** * Used to calculate the extra armor of enchantments on armors equipped on player. */ private static final EnchantmentHelper.ModifierDamage enchantmentModifierDamage = new EnchantmentHelper.ModifierDamage(); /** * Used to calculate the (magic) extra damage done by enchantments on current equipped item of player. */ private static final EnchantmentHelper.ModifierLiving enchantmentModifierLiving = new EnchantmentHelper.ModifierLiving(); private static final EnchantmentHelper.HurtIterator ENCHANTMENT_ITERATOR_HURT = new EnchantmentHelper.HurtIterator(); private static final EnchantmentHelper.DamageIterator ENCHANTMENT_ITERATOR_DAMAGE = new EnchantmentHelper.DamageIterator(); /** * Returns the level of enchantment on the ItemStack passed. */ public static int getEnchantmentLevel(int enchID, ItemStack stack) { if (stack == null) { return 0; } else { NBTTagList nbttaglist = stack.getEnchantmentTagList(); if (nbttaglist == null) { return 0; } else { for (int i = 0; i < nbttaglist.tagCount(); ++i) { int j = nbttaglist.getCompoundTagAt(i).getShort("id"); int k = nbttaglist.getCompoundTagAt(i).getShort("lvl"); if (j == enchID) { return k; } } return 0; } } } public static Map getEnchantments(ItemStack stack) { Map map = Maps.newLinkedHashMap(); NBTTagList nbttaglist = stack.getItem() == Items.enchanted_book ? Items.enchanted_book.getEnchantments(stack) : stack.getEnchantmentTagList(); if (nbttaglist != null) { for (int i = 0; i < nbttaglist.tagCount(); ++i) { int j = nbttaglist.getCompoundTagAt(i).getShort("id"); int k = nbttaglist.getCompoundTagAt(i).getShort("lvl"); map.put(j, k); } } return map; } /** * Set the enchantments for the specified stack. */ public static void setEnchantments(Map enchMap, ItemStack stack) { NBTTagList nbttaglist = new NBTTagList(); Iterator iterator = enchMap.keySet().iterator(); while (iterator.hasNext()) { int i = ((Integer)iterator.next()).intValue(); Enchantment enchantment = Enchantment.getEnchantmentById(i); if (enchantment != null) { NBTTagCompound nbttagcompound = new NBTTagCompound(); nbttagcompound.setShort("id", (short)i); nbttagcompound.setShort("lvl", (short)enchMap.get(i).intValue()); nbttaglist.appendTag(nbttagcompound); if (stack.getItem() == Items.enchanted_book) { Items.enchanted_book.addEnchantment(stack, new RngEnchantment(enchantment, enchMap.get(i).intValue())); } } } if (nbttaglist.tagCount() > 0) { if (stack.getItem() != Items.enchanted_book) { stack.setTagInfo("ench", nbttaglist); } } else if (stack.hasTagCompound()) { stack.getTagCompound().removeTag("ench"); } } /** * Returns the biggest level of the enchantment on the array of ItemStack passed. */ public static int getMaxEnchantmentLevel(int enchID, ItemStack[] stacks) { if (stacks == null) { return 0; } else { int i = 0; for (ItemStack itemstack : stacks) { int j = getEnchantmentLevel(enchID, itemstack); if (j > i) { i = j; } } return i; } } /** * Executes the enchantment modifier on the ItemStack passed. */ private static void applyEnchantmentModifier(EnchantmentHelper.IModifier modifier, ItemStack stack) { if (stack != null) { NBTTagList nbttaglist = stack.getEnchantmentTagList(); if (nbttaglist != null) { for (int i = 0; i < nbttaglist.tagCount(); ++i) { int j = nbttaglist.getCompoundTagAt(i).getShort("id"); int k = nbttaglist.getCompoundTagAt(i).getShort("lvl"); if (Enchantment.getEnchantmentById(j) != null) { modifier.calculateModifier(Enchantment.getEnchantmentById(j), k); } } } } } /** * Executes the enchantment modifier on the array of ItemStack passed. */ private static void applyEnchantmentModifierArray(EnchantmentHelper.IModifier modifier, ItemStack[] stacks) { for (ItemStack itemstack : stacks) { applyEnchantmentModifier(modifier, itemstack); } } /** * Returns the modifier of protection enchantments on armors equipped on player. */ public static int getEnchantmentModifierDamage(ItemStack[] stacks, DamageSource source) { enchantmentModifierDamage.damageModifier = 0; enchantmentModifierDamage.source = source; applyEnchantmentModifierArray(enchantmentModifierDamage, stacks); if (enchantmentModifierDamage.damageModifier > 25) { enchantmentModifierDamage.damageModifier = 25; } else if (enchantmentModifierDamage.damageModifier < 0) { enchantmentModifierDamage.damageModifier = 0; } return (enchantmentModifierDamage.damageModifier + 1 >> 1) + enchantmentRand.zrange((enchantmentModifierDamage.damageModifier >> 1) + 1); } public static int getDamageModifier(ItemStack p_152377_0_) { enchantmentModifierLiving.livingModifier = 0; applyEnchantmentModifier(enchantmentModifierLiving, p_152377_0_); return enchantmentModifierLiving.livingModifier; } public static void applyThornEnchantments(EntityLiving user, Entity attacker) { ENCHANTMENT_ITERATOR_HURT.attacker = attacker; ENCHANTMENT_ITERATOR_HURT.user = user; if (user != null) { applyEnchantmentModifierArray(ENCHANTMENT_ITERATOR_HURT, user.getInventory()); } if (user != null && attacker != null) // && attacker.isPlayer()) { applyEnchantmentModifier(ENCHANTMENT_ITERATOR_HURT, user.getHeldItem()); } } public static void applyArthropodEnchantments(EntityLiving user, Entity target) { ENCHANTMENT_ITERATOR_DAMAGE.user = user; ENCHANTMENT_ITERATOR_DAMAGE.target = target; if (user != null) { applyEnchantmentModifierArray(ENCHANTMENT_ITERATOR_DAMAGE, user.getInventory()); } if (user != null) // && user.isPlayer()) { applyEnchantmentModifier(ENCHANTMENT_ITERATOR_DAMAGE, user.getHeldItem()); } } /** * Returns the Knockback modifier of the enchantment on the players held item. */ public static int getKnockbackModifier(EntityLiving player) { return getEnchantmentLevel(Enchantment.knockback.effectId, player.getHeldItem()); } /** * Returns the fire aspect modifier of the players held item. */ public static int getFireAspectModifier(EntityLiving player) { return getEnchantmentLevel(Enchantment.fireAspect.effectId, player.getHeldItem()); } // /** // * Returns the 'Water Breathing' modifier of enchantments on player equipped armors. // */ // public static int getRespiration(Entity player) // { // return getMaxEnchantmentLevel(Enchantment.respiration.effectId, player.getInventory()); // } // /** // * Returns the level of the Depth Strider enchantment. // */ // public static int getDepthStriderModifier(Entity player) // { // return getMaxEnchantmentLevel(Enchantment.depthStrider.effectId, player.getInventory()); // } /** * Return the extra efficiency of tools based on enchantments on equipped player item. */ public static int getEfficiencyModifier(EntityLiving player) { return getEnchantmentLevel(Enchantment.efficiency.effectId, player.getHeldItem()); } /** * Returns the silk touch status of enchantments on current equipped item of player. */ public static boolean getSilkTouchModifier(EntityLiving player) { return getEnchantmentLevel(Enchantment.silkTouch.effectId, player.getHeldItem()) > 0; } /** * Returns the fortune enchantment modifier of the current equipped item of player. */ public static int getFortuneModifier(EntityLiving player) { return getEnchantmentLevel(Enchantment.fortune.effectId, player.getHeldItem()); } /** * Returns the level of the 'Luck Of The Sea' enchantment. */ public static int getLuckOfSeaModifier(EntityLiving player) { return getEnchantmentLevel(Enchantment.luckOfTheSea.effectId, player.getHeldItem()); } /** * Returns the level of the 'Lure' enchantment on the players held item. */ public static int getLureModifier(EntityLiving player) { return getEnchantmentLevel(Enchantment.lure.effectId, player.getHeldItem()); } /** * Returns the looting enchantment modifier of the current equipped item of player. */ public static int getLootingModifier(EntityLiving player) { return getEnchantmentLevel(Enchantment.looting.effectId, player.getHeldItem()); } // /** // * Returns the aqua affinity status of enchantments on current equipped item of player. // */ // public static boolean getAquaAffinityModifier(EntityLivingBase player) // { // return getMaxEnchantmentLevel(Enchantment.aquaAffinity.effectId, player.getInventory()) > 0; // } public static ItemStack getEnchantedItem(Enchantment p_92099_0_, EntityLiving p_92099_1_) { for (ItemStack itemstack : p_92099_1_.getInventory()) { if (itemstack != null && getEnchantmentLevel(p_92099_0_.effectId, itemstack) > 0) { return itemstack; } } return null; } /** * Returns the enchantability of itemstack, using a separate calculation for each enchantNum (0, 1 or 2), cutting to * the max enchantability power of the table, which is locked to a max of 15. */ public static int calcItemStackEnchantability(Random rand, int enchantNum, int power, ItemStack stack) { Item item = stack.getItem(); int i = item.getItemEnchantability(); if (i <= 0) { return 0; } else { if (power > 15) { power = 15; } int j = rand.roll(8) + (power >> 1) + rand.zrange(power + 1); return enchantNum == 0 ? Math.max(j / 3, 1) : (enchantNum == 1 ? j * 2 / 3 + 1 : Math.max(j, power * 2)); } } /** * Adds a random enchantment to the specified item. Args: random, itemStack, enchantabilityLevel */ public static ItemStack addRandomEnchantment(Random p_77504_0_, ItemStack p_77504_1_, int p_77504_2_) { List list = buildEnchantmentList(p_77504_0_, p_77504_1_, p_77504_2_); boolean flag = p_77504_1_.getItem() == Items.book; if (flag) { p_77504_1_.setItem(Items.enchanted_book); } if (list != null) { for (RngEnchantment enchantmentdata : list) { if (flag) { Items.enchanted_book.addEnchantment(p_77504_1_, enchantmentdata); } else { p_77504_1_.addEnchantment(enchantmentdata.enchantmentobj, enchantmentdata.enchantmentLevel); } } } return p_77504_1_; } public static List buildEnchantmentList(Random randomIn, ItemStack itemStackIn, int level) { Item item = itemStackIn.getItem(); int i = item.getItemEnchantability(); if (i <= 0) { return null; } else { i = i / 2; i = randomIn.roll((i >> 1) + 1) + randomIn.zrange((i >> 1) + 1); int j = i + level; float f = (randomIn.floatv() + randomIn.floatv() - 1.0F) * 0.15F; int k = (int)((float)j * (1.0F + f) + 0.5F); if (k < 1) { k = 1; } List list = null; Map map = mapEnchantmentData(k, itemStackIn); if (map != null && !map.isEmpty()) { RngEnchantment enchantmentdata = (RngEnchantment)new WeightedList(map.values()).pick(randomIn); if (enchantmentdata != null) { list = Lists.newArrayList(); list.add(enchantmentdata); for (int l = k; randomIn.zrange(50) <= l; l >>= 1) { Iterator iterator = map.keySet().iterator(); while (iterator.hasNext()) { Integer integer = (Integer)iterator.next(); boolean flag = true; for (RngEnchantment enchantmentdata1 : list) { if (!enchantmentdata1.enchantmentobj.canApplyTogether(Enchantment.getEnchantmentById(integer.intValue()))) { flag = false; break; } } if (!flag) { iterator.remove(); } } if (!map.isEmpty()) { RngEnchantment enchantmentdata2 = (RngEnchantment)new WeightedList(map.values()).pick(randomIn); list.add(enchantmentdata2); } } } } return list; } } public static Map mapEnchantmentData(int p_77505_0_, ItemStack p_77505_1_) { Item item = p_77505_1_.getItem(); Map map = null; boolean flag = p_77505_1_.getItem() == Items.book; for (Enchantment enchantment : Enchantment.enchantmentsBookList) { if (enchantment != null && (enchantment.type.canEnchantItem(item) || flag)) { for (int i = enchantment.getMinLevel(); i <= enchantment.getMaxLevel(); ++i) { if (p_77505_0_ >= enchantment.getMinEnchantability(i) && p_77505_0_ <= enchantment.getMaxEnchantability(i)) { if (map == null) { map = Maps.newHashMap(); } map.put(enchantment.effectId, new RngEnchantment(enchantment, i)); } } } } return map; } static final class DamageIterator implements EnchantmentHelper.IModifier { public EntityLiving user; public Entity target; private DamageIterator() { } public void calculateModifier(Enchantment enchantmentIn, int enchantmentLevel) { enchantmentIn.onEntityDamaged(this.user, this.target, enchantmentLevel); } } static final class HurtIterator implements EnchantmentHelper.IModifier { public EntityLiving user; public Entity attacker; private HurtIterator() { } public void calculateModifier(Enchantment enchantmentIn, int enchantmentLevel) { enchantmentIn.onUserHurt(this.user, this.attacker, enchantmentLevel); } } interface IModifier { void calculateModifier(Enchantment enchantmentIn, int enchantmentLevel); } static final class ModifierDamage implements EnchantmentHelper.IModifier { public int damageModifier; public DamageSource source; private ModifierDamage() { } public void calculateModifier(Enchantment enchantmentIn, int enchantmentLevel) { this.damageModifier += enchantmentIn.calcDamageReduction(enchantmentLevel, this.source); } } static final class ModifierLiving implements EnchantmentHelper.IModifier { public int livingModifier; private ModifierLiving() { } public void calculateModifier(Enchantment enchantmentIn, int enchantmentLevel) { this.livingModifier += enchantmentIn.calcAdditionalDamage(enchantmentLevel); } } }