From 0aed2a58876ec5daee727dc5dbcc01700fdd14c3 Mon Sep 17 00:00:00 2001 From: Vasco Lavos Date: Sun, 16 Feb 2014 21:25:38 +0000 Subject: [PATCH] Helpers for XP and inventories. --- .../common/core/helper/ExperienceHelper.java | 54 ++++ .../common/core/helper/InventoryHelper.java | 302 ++++++++++++++++++ 2 files changed, 356 insertions(+) create mode 100644 MODSRC/vazkii/botania/common/core/helper/ExperienceHelper.java create mode 100644 MODSRC/vazkii/botania/common/core/helper/InventoryHelper.java diff --git a/MODSRC/vazkii/botania/common/core/helper/ExperienceHelper.java b/MODSRC/vazkii/botania/common/core/helper/ExperienceHelper.java new file mode 100644 index 000000000..31600258a --- /dev/null +++ b/MODSRC/vazkii/botania/common/core/helper/ExperienceHelper.java @@ -0,0 +1,54 @@ +/** + * This class was created by . It's distributed as + * part of the Botania Mod. Get the Source Code in github: + * https://github.com/Vazkii/Botania + * + * Botania is Open Source and distributed under a + * Creative Commons Attribution-NonCommercial-ShareAlike 3.0 License + * (http://creativecommons.org/licenses/by-nc-sa/3.0/deed.en_GB) + * + * File Created @ [? (GMT)] + */ +package vazkii.botania.common.core.helper; + +import net.minecraft.entity.player.EntityPlayer; + +// From OpenBlocksLib: https://github.com/OpenMods/OpenModsLib +public class ExperienceHelper { + + public static int getPlayerXP(EntityPlayer player) { + return (int)(getExperienceForLevel(player.experienceLevel) + player.experience * player.xpBarCap()); + } + + public static void drainPlayerXP(EntityPlayer player, int amount) { + addPlayerXP(player, -amount); + } + + public static void addPlayerXP(EntityPlayer player, int amount) { + int experience = getPlayerXP(player) + amount; + player.experienceTotal = experience; + player.experienceLevel = getLevelForExperience(experience); + int expForLevel = getExperienceForLevel(player.experienceLevel); + player.experience = (float)(experience - expForLevel) / (float)player.xpBarCap(); + } + + public static int getExperienceForLevel(int level) { + if (level == 0) { return 0; } + if (level > 0 && level < 16) { + return level * 17; + } else if (level > 15 && level < 31) { + return (int)(1.5 * Math.pow(level, 2) - 29.5 * level + 360); + } else { + return (int)(3.5 * Math.pow(level, 2) - 151.5 * level + 2220); + } + } + + public static int getLevelForExperience(int experience) { + int i = 0; + while (getExperienceForLevel(i) <= experience) { + i++; + } + return i - 1; + } + +} diff --git a/MODSRC/vazkii/botania/common/core/helper/InventoryHelper.java b/MODSRC/vazkii/botania/common/core/helper/InventoryHelper.java new file mode 100644 index 000000000..134856bb3 --- /dev/null +++ b/MODSRC/vazkii/botania/common/core/helper/InventoryHelper.java @@ -0,0 +1,302 @@ +/** + * This class was created by . It's distributed as + * part of the Botania Mod. Get the Source Code in github: + * https://github.com/Vazkii/Botania + * + * Botania is Open Source and distributed under a + * Creative Commons Attribution-NonCommercial-ShareAlike 3.0 License + * (http://creativecommons.org/licenses/by-nc-sa/3.0/deed.en_GB) + * + * File Created @ [? (GMT)] + */ +package vazkii.botania.common.core.helper; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.IInventory; +import net.minecraft.inventory.ISidedInventory; +import net.minecraft.inventory.InventoryLargeChest; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.tileentity.TileEntityChest; +import net.minecraft.world.World; +import net.minecraftforge.common.ForgeDirection; + +//From OpenBlocksLib: https://github.com/OpenMods/OpenModsLib +public class InventoryHelper { + + public static void tryInsertStack(IInventory targetInventory, int slot, ItemStack stack, boolean canMerge) { + if(targetInventory.isItemValidForSlot(slot, stack)) { + ItemStack targetStack = targetInventory.getStackInSlot(slot); + if(targetStack == null) { + targetInventory.setInventorySlotContents(slot, stack.copy()); + stack.stackSize = 0; + } else if(canMerge) { + if(targetInventory.isItemValidForSlot(slot, stack) && areMergeCandidates(stack, targetStack)) { + int space = targetStack.getMaxStackSize() - targetStack.stackSize; + int mergeAmount = Math.min(space, stack.stackSize); + ItemStack copy = targetStack.copy(); + copy.stackSize += mergeAmount; + targetInventory.setInventorySlotContents(slot, copy); + stack.stackSize -= mergeAmount; + } + } + } + } + + protected static boolean areMergeCandidates(ItemStack source, ItemStack target) { + return source.isItemEqual(target) && ItemStack.areItemStackTagsEqual(source, target) && target.stackSize < target.getMaxStackSize(); + } + + public static void insertItemIntoInventory(IInventory inventory, ItemStack stack) { + insertItemIntoInventory(inventory, stack, ForgeDirection.UNKNOWN, -1); + } + + public static void insertItemIntoInventory(IInventory inventory, ItemStack stack, ForgeDirection side, int intoSlot) { + insertItemIntoInventory(inventory, stack, side, intoSlot, true); + } + + public static void insertItemIntoInventory(IInventory inventory, ItemStack stack, ForgeDirection side, int intoSlot, boolean doMove) { + insertItemIntoInventory(inventory, stack, side, intoSlot, doMove, true); + } + + public static void insertItemIntoInventory(IInventory inventory, ItemStack stack, ForgeDirection side, int intoSlot, boolean doMove, boolean canStack) { + if(stack == null) return; + + IInventory targetInventory = inventory; + + if(!doMove) { + targetInventory = new GenericInventory("temporary.inventory", false, targetInventory.getSizeInventory()); + ((GenericInventory)targetInventory).copyFrom(inventory); + } + + int i = 0; + int[] attemptSlots = new int[0]; + + if(inventory instanceof ISidedInventory && side != ForgeDirection.UNKNOWN) { + attemptSlots = ((ISidedInventory)inventory).getAccessibleSlotsFromSide(side.ordinal()); + if(attemptSlots == null) + attemptSlots = new int[0]; + } else { + attemptSlots = new int[inventory.getSizeInventory()]; + for(int a = 0; a < inventory.getSizeInventory(); a++) + attemptSlots[a] = a; + } + if(intoSlot > -1) { + Set x = new HashSet(); + for(int attemptedSlot : attemptSlots) + x.add(attemptedSlot); + + if(x.contains(intoSlot)) + attemptSlots = new int[] { intoSlot }; + else attemptSlots = new int[0]; + } + while(stack.stackSize > 0 && i < attemptSlots.length) { + if(side != ForgeDirection.UNKNOWN && inventory instanceof ISidedInventory) + if(!((ISidedInventory)inventory).canInsertItem(intoSlot, stack, side.ordinal())) { + i++; + continue; + } + + tryInsertStack(targetInventory, attemptSlots[i], stack, canStack); + i++; + } + } + + public static IInventory getInventory(World world, int x, int y, int z) { + TileEntity tileEntity = world.getBlockTileEntity(x, y, z); + if(tileEntity instanceof TileEntityChest) { + int chestId = world.getBlockId(x, y, z); + if(world.getBlockId(x - 1, y, z) == chestId) + return new InventoryLargeChest("Large chest", (IInventory)world.getBlockTileEntity(x - 1, y, z), (IInventory)tileEntity); + if(world.getBlockId(x + 1, y, z) == chestId) + return new InventoryLargeChest("Large chest", (IInventory)tileEntity, (IInventory)world.getBlockTileEntity(x + 1, y, z)); + if(world.getBlockId(x, y, z - 1) == chestId) + return new InventoryLargeChest("Large chest", (IInventory)world.getBlockTileEntity(x, y, z - 1), (IInventory)tileEntity); + if(world.getBlockId(x, y, z + 1) == chestId) + return new InventoryLargeChest("Large chest", (IInventory)tileEntity, (IInventory)world.getBlockTileEntity(x, y, z + 1)); + } + return (tileEntity instanceof IInventory)? (IInventory)tileEntity : null; + } + + public static IInventory getInventory(World world, int x, int y, int z, ForgeDirection direction) { + if(direction != null && direction != ForgeDirection.UNKNOWN) { + x += direction.offsetX; + y += direction.offsetY; + z += direction.offsetZ; + } + return getInventory(world, x, y, z); + + } + + public static IInventory getInventory(IInventory inventory) { + if(inventory instanceof TileEntityChest) { + TileEntity te = (TileEntity)inventory; + return getInventory(te.worldObj, te.xCoord, te.yCoord, te.zCoord); + } + return inventory; + } + + public static class GenericInventory implements IInventory { + + protected String inventoryTitle; + protected int slotsCount; + protected ItemStack[] inventoryContents; + protected boolean isInvNameLocalized; + + public GenericInventory(String name, boolean isInvNameLocalized, int size) { + this.isInvNameLocalized = isInvNameLocalized; + this.slotsCount = size; + this.inventoryTitle = name; + inventoryContents = new ItemStack[size]; + } + + @Override + public void closeChest() { } + + @Override + public ItemStack decrStackSize(int par1, int par2) { + if(inventoryContents[par1] != null) { + ItemStack itemstack; + + if(inventoryContents[par1].stackSize <= par2) { + itemstack = inventoryContents[par1]; + inventoryContents[par1] = null; + return itemstack; + } + + itemstack = inventoryContents[par1].splitStack(par2); + if(inventoryContents[par1].stackSize == 0) + inventoryContents[par1] = null; + + return itemstack; + } + return null; + } + + @Override + public int getInventoryStackLimit() { + return 64; + } + + @Override + public String getInvName() { + return inventoryTitle; + } + + @Override + public int getSizeInventory() { + return slotsCount; + } + + @Override + public ItemStack getStackInSlot(int i) { + return inventoryContents[i]; + } + + public ItemStack getStackInSlot(Enum i) { + return getStackInSlot(i.ordinal()); + } + + @Override + public ItemStack getStackInSlotOnClosing(int i) { + if(i >= inventoryContents.length) + return null; + + if(inventoryContents[i] != null) { + ItemStack itemstack = inventoryContents[i]; + inventoryContents[i] = null; + return itemstack; + } + + return null; + } + + @Override + public boolean isInvNameLocalized() { + return isInvNameLocalized; + } + + public boolean isItem(int slot, Item item) { + return inventoryContents[slot] != null && inventoryContents[slot].getItem() == item; + } + + @Override + public boolean isItemValidForSlot(int i, ItemStack itemstack) { + return true; + } + + @Override + public boolean isUseableByPlayer(EntityPlayer entityplayer) { + return true; + } + + @Override + public void openChest() { } + + public void clearAndSetSlotCount(int amount) { + slotsCount = amount; + inventoryContents = new ItemStack[amount]; + } + + public void readFromNBT(NBTTagCompound tag) { + if(tag.hasKey("size")) + slotsCount = tag.getInteger("size"); + + NBTTagList nbttaglist = tag.getTagList("Items"); + inventoryContents = new ItemStack[slotsCount]; + for(int i = 0; i < nbttaglist.tagCount(); i++) { + NBTTagCompound stacktag = (NBTTagCompound)nbttaglist.tagAt(i); + int j = stacktag.getByte("Slot"); + if(j >= 0 && j < inventoryContents.length) + inventoryContents[j] = ItemStack.loadItemStackFromNBT(stacktag); + } + } + + @Override + public void setInventorySlotContents(int i, ItemStack itemstack) { + inventoryContents[i] = itemstack; + + if(itemstack != null && itemstack.stackSize > getInventoryStackLimit()) + itemstack.stackSize = getInventoryStackLimit(); + } + + public void writeToNBT(NBTTagCompound tag) { + tag.setInteger("size", getSizeInventory()); + NBTTagList nbttaglist = new NBTTagList(); + for(int i = 0; i < inventoryContents.length; i++) { + if(inventoryContents[i] != null) { + NBTTagCompound stacktag = new NBTTagCompound(); + stacktag.setByte("Slot", (byte)i); + inventoryContents[i].writeToNBT(stacktag); + nbttaglist.appendTag(stacktag); + } + } + tag.setTag("Items", nbttaglist); + } + + @Override + public void onInventoryChanged() { } + + public void copyFrom(IInventory inventory) { + for(int i = 0; i < inventory.getSizeInventory(); i++) + if(i < getSizeInventory()) { + ItemStack stack = inventory.getStackInSlot(i); + if(stack != null) + setInventorySlotContents(i, stack.copy()); + else setInventorySlotContents(i, null); + } + } + + public List contents() { + return Arrays.asList(inventoryContents); + } + } +}