BloodMagic/src/main/java/WayofTime/bloodmagic/item/ItemExperienceBook.java

187 lines
6.7 KiB
Java
Raw Normal View History

2016-04-02 16:02:01 -04:00
package WayofTime.bloodmagic.item;
2017-08-15 21:30:48 -07:00
import WayofTime.bloodmagic.BloodMagic;
import WayofTime.bloodmagic.util.helper.NBTHelper;
2017-08-15 21:30:48 -07:00
import WayofTime.bloodmagic.client.IVariantProvider;
import WayofTime.bloodmagic.util.helper.TextHelper;
2017-08-15 20:21:54 -07:00
import net.minecraft.client.util.ITooltipFlag;
2016-04-02 16:02:01 -04:00
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.SoundEvents;
2016-04-02 16:02:01 -04:00
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
2016-04-02 20:09:23 -04:00
import net.minecraft.util.ActionResult;
2016-04-02 16:02:01 -04:00
import net.minecraft.util.EnumActionResult;
import net.minecraft.util.EnumHand;
import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.Pair;
2017-08-15 21:30:48 -07:00
import java.util.ArrayList;
import java.util.List;
2016-04-02 16:02:01 -04:00
2017-08-15 21:30:48 -07:00
public class ItemExperienceBook extends Item implements IVariantProvider {
public ItemExperienceBook() {
setUnlocalizedName(BloodMagic.MODID + ".experienceTome");
2016-04-02 16:02:01 -04:00
setMaxStackSize(1);
setCreativeTab(BloodMagic.TAB_BM);
2016-04-02 16:02:01 -04:00
}
@Override
@SideOnly(Side.CLIENT)
2017-08-15 21:30:48 -07:00
public boolean hasEffect(ItemStack stack) {
return true;
}
2016-04-02 16:02:01 -04:00
@Override
@SideOnly(Side.CLIENT)
2017-08-15 21:30:48 -07:00
public void addInformation(ItemStack stack, World world, List<String> tooltip, ITooltipFlag flag) {
2017-01-02 01:18:29 -08:00
tooltip.add(TextHelper.localizeEffect("tooltip.bloodmagic.experienceTome"));
if (!stack.hasTagCompound())
return;
double storedExp = getStoredExperience(stack);
2017-01-02 01:18:29 -08:00
tooltip.add(TextHelper.localizeEffect("tooltip.bloodmagic.experienceTome.exp", (int) storedExp));
tooltip.add(TextHelper.localizeEffect("tooltip.bloodmagic.experienceTome.expLevel", (int) getLevelForExperience(storedExp)));
2016-04-02 16:02:01 -04:00
}
@Override
2017-08-15 21:30:48 -07:00
public ActionResult<ItemStack> onItemRightClick(World world, EntityPlayer player, EnumHand hand) {
2017-01-01 22:26:42 -08:00
ItemStack stack = player.getHeldItem(hand);
2017-08-15 21:30:48 -07:00
if (!world.isRemote) {
2016-04-02 20:09:23 -04:00
if (player.isSneaking())
absorbOneLevelExpFromPlayer(stack, player);
else
giveOneLevelExpToPlayer(stack, player);
2016-04-02 20:09:23 -04:00
}
2016-04-02 16:02:01 -04:00
2016-04-02 20:09:23 -04:00
return new ActionResult<ItemStack>(EnumActionResult.SUCCESS, stack);
2016-04-02 16:02:01 -04:00
}
@Override
2017-08-15 21:30:48 -07:00
public List<Pair<Integer, String>> getVariants() {
2016-04-02 16:02:01 -04:00
List<Pair<Integer, String>> ret = new ArrayList<Pair<Integer, String>>();
ret.add(new ImmutablePair<Integer, String>(0, "type=experiencetome"));
return ret;
}
2017-08-15 21:30:48 -07:00
public void giveOneLevelExpToPlayer(ItemStack stack, EntityPlayer player) {
float progress = player.experience;
int expToNext = getExperienceForNextLevel(player.experienceLevel);
int neededExp = (int) Math.ceil((1 - progress) * expToNext);
float containedExp = (float) getStoredExperience(stack);
System.out.println("Needed: " + neededExp + ", contained: " + containedExp + ", exp to next: " + expToNext);
2017-08-15 21:30:48 -07:00
if (containedExp >= neededExp) {
setStoredExperience(stack, containedExp - neededExp);
addPlayerXP(player, neededExp);
2017-08-15 21:30:48 -07:00
if (player.experienceLevel % 5 == 0) {
float f = player.experienceLevel > 30 ? 1.0F : (float) player.experienceLevel / 30.0F;
2017-01-01 22:26:42 -08:00
player.getEntityWorld().playSound(null, player.posX, player.posY, player.posZ, SoundEvents.ENTITY_PLAYER_LEVELUP, player.getSoundCategory(), f * 0.75F, 1.0F);
}
2017-08-15 21:30:48 -07:00
} else {
setStoredExperience(stack, 0);
addPlayerXP(player, (int) containedExp);
}
}
2017-08-15 21:30:48 -07:00
public void absorbOneLevelExpFromPlayer(ItemStack stack, EntityPlayer player) {
float progress = player.experience;
2017-08-15 21:30:48 -07:00
if (progress > 0) {
int expDeduction = (int) getExperienceAcquiredToNext(player);
2017-08-15 21:30:48 -07:00
if (expDeduction > 0) {
addPlayerXP(player, -expDeduction);
addExperience(stack, expDeduction);
}
2017-08-15 21:30:48 -07:00
} else if (progress == 0 && player.experienceLevel > 0) {
int expDeduction = getExperienceForNextLevel(player.experienceLevel - 1);
addPlayerXP(player, -expDeduction);
addExperience(stack, expDeduction);
}
}
// Credits to Ender IO for some of the experience code, although now modified slightly for my convenience.
2017-08-15 21:30:48 -07:00
public static int getPlayerXP(EntityPlayer player) {
return (int) (getExperienceForLevel(player.experienceLevel) + (player.experience * player.xpBarCap()));
}
2017-08-15 21:30:48 -07:00
public static void addPlayerXP(EntityPlayer player, int amount) {
int experience = Math.max(0, getPlayerXP(player) + amount);
player.experienceTotal = experience;
player.experienceLevel = getLevelForExperience(experience);
int expForLevel = getExperienceForLevel(player.experienceLevel);
player.experience = (float) (experience - expForLevel) / (float) player.xpBarCap();
}
2017-08-15 21:30:48 -07:00
public static void setStoredExperience(ItemStack stack, double exp) {
NBTHelper.checkNBT(stack);
NBTTagCompound tag = stack.getTagCompound();
tag.setDouble("experience", exp);
}
2017-08-15 21:30:48 -07:00
public static double getStoredExperience(ItemStack stack) {
NBTHelper.checkNBT(stack);
NBTTagCompound tag = stack.getTagCompound();
return tag.getDouble("experience");
}
2017-08-15 21:30:48 -07:00
public static void addExperience(ItemStack stack, double exp) {
setStoredExperience(stack, getStoredExperience(stack) + exp);
}
2017-08-15 21:30:48 -07:00
public static int getExperienceForNextLevel(int currentLevel) {
if (currentLevel < 16) {
return 2 * currentLevel + 7;
2017-08-15 21:30:48 -07:00
} else if (currentLevel < 31) {
return 5 * currentLevel - 38;
2017-08-15 21:30:48 -07:00
} else {
return 9 * currentLevel - 158;
}
}
//TODO: Change to calculation form.
2017-08-15 21:30:48 -07:00
public static int getExperienceForLevel(int level) {
if (level >= 21863) {
return Integer.MAX_VALUE;
}
2017-08-15 21:30:48 -07:00
if (level == 0) {
return 0;
}
int res = 0;
2017-08-15 21:30:48 -07:00
for (int i = 0; i < level; i++) {
res += getExperienceForNextLevel(i);
}
return res;
}
2017-08-15 21:30:48 -07:00
public static double getExperienceAcquiredToNext(EntityPlayer player) {
return player.experience * player.xpBarCap();
}
2017-08-15 21:30:48 -07:00
public static int getLevelForExperience(double exp) {
if (exp <= 352) {
return (int) Math.floor(solveParabola(1, 6, -exp));
2017-08-15 21:30:48 -07:00
} else if (exp <= 1507) {
return (int) Math.floor(solveParabola(2.5, -40.5, 360 - exp));
2017-08-15 21:30:48 -07:00
} else {
return (int) Math.floor(solveParabola(4.5, -162.5, 2220 - exp));
}
}
2017-08-15 21:30:48 -07:00
public static double solveParabola(double a, double b, double c) {
return (-b + Math.sqrt(b * b - 4 * a * c)) / (2 * a);
}
2016-04-02 16:02:01 -04:00
}