package openblocks.enchantments;
import com.google.common.base.Supplier;
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
import java.util.Map;
import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import openblocks.Config;
import openblocks.OpenBlocks.Enchantments;
import openmods.calc.Environment;
import openmods.calc.ExprType;
import openmods.calc.SingleExprEvaluator;
import openmods.calc.SingleExprEvaluator.EnvironmentConfigurator;
import openmods.calc.types.fp.DoubleCalculatorFactory;
import openmods.config.properties.ConfigurationChange;
import openmods.entity.PlayerDamageEvent;
import openmods.utils.EnchantmentUtils;
public class LastStandEnchantmentsHandler {
private static final String VAR_ENCH_LEVEL = "ench";
private static final String VAR_PLAYER_XP = "xp";
private static final String VAR_PLAYER_HP = "hp";
private static final String VAR_DAMAGE = "dmg";
private final SingleExprEvaluator<Double, ExprType> reductionCalculator = SingleExprEvaluator.create(DoubleCalculatorFactory.createDefault());
{
updateReductionFormula();
}
@SubscribeEvent
public void onConfigChange(ConfigurationChange.Post evt) {
if (evt.check("features", "lastStandFormula"))
updateReductionFormula();
}
private void updateReductionFormula() {
reductionCalculator.setExpr(ExprType.INFIX, Config.lastStandEnchantmentFormula);
}
@SubscribeEvent
public void onHurt(final PlayerDamageEvent e) {
final int enchantmentLevels = countLastStandEnchantmentLevels(e.player);
if (enchantmentLevels > 0) {
final float playerHealth = e.player.getHealth();
final float healthAvailable = playerHealth - e.amount;
if (healthAvailable < 1f) {
final int xpAvailable = EnchantmentUtils.getPlayerXP(e.player);
float xpRequired = reductionCalculator.evaluate(
new EnvironmentConfigurator<Double>() {
@Override
public void accept(Environment<Double> env) {
env.setGlobalSymbol(VAR_ENCH_LEVEL, Double.valueOf(enchantmentLevels));
env.setGlobalSymbol(VAR_PLAYER_XP, Double.valueOf(xpAvailable));
env.setGlobalSymbol(VAR_PLAYER_HP, Double.valueOf(playerHealth));
env.setGlobalSymbol(VAR_DAMAGE, Double.valueOf(e.amount));
}
},
new Supplier<Double>() {
@Override
public Double get() {
float xpRequired = 1f - healthAvailable;
xpRequired *= 50;
xpRequired /= enchantmentLevels;
xpRequired = Math.max(1, xpRequired);
return Double.valueOf(xpRequired);
}
}).floatValue();
if (xpAvailable >= xpRequired) {
e.player.setHealth(1f);
EnchantmentUtils.addPlayerXP(e.player, -(int)xpRequired);
e.amount = 0;
e.setCanceled(true);
}
}
}
}
@SuppressWarnings("unchecked")
public static int countLastStandEnchantmentLevels(EntityPlayer player) {
if (player != null) {
int count = 0;
for (ItemStack stack : player.inventory.armorInventory) {
if (stack != null) {
Map<Integer, Integer> enchantments = EnchantmentHelper.getEnchantments(stack);
Integer ench = enchantments.get(Enchantments.lastStand.effectId);
if (ench != null) {
count += ench;
}
}
}
return count;
}
return 0;
}
}