tcr/java/src/game/enchantment/EnchantmentHelper.java
2025-05-04 20:27:55 +02:00

572 lines
18 KiB
Java
Executable file

package game.enchantment;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import game.collect.Lists;
import game.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<Integer, Integer> getEnchantments(ItemStack stack)
{
Map<Integer, Integer> map = Maps.<Integer, Integer>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<Integer, Integer> 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<RngEnchantment> 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<RngEnchantment> 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<RngEnchantment> list = null;
Map<Integer, RngEnchantment> map = mapEnchantmentData(k, itemStackIn);
if (map != null && !map.isEmpty())
{
RngEnchantment enchantmentdata = (RngEnchantment)new WeightedList(map.values()).pick(randomIn);
if (enchantmentdata != null)
{
list = Lists.<RngEnchantment>newArrayList();
list.add(enchantmentdata);
for (int l = k; randomIn.zrange(50) <= l; l >>= 1)
{
Iterator<Integer> 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<Integer, RngEnchantment> mapEnchantmentData(int p_77505_0_, ItemStack p_77505_1_)
{
Item item = p_77505_1_.getItem();
Map<Integer, RngEnchantment> 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.<Integer, RngEnchantment>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);
}
}
}