From 3e50dd4117fc05b99ea72dc3bb86e8cb3c251205 Mon Sep 17 00:00:00 2001
From: Arcaratus <byou64@gmail.com>
Date: Mon, 11 Apr 2016 19:57:23 -0400
Subject: [PATCH] Improved the API and internal workings

Update things

Fix some more things

Update once more

Refactoring and removing unnecessary null checks

Woops

Fix

Nother fix

Moar fix

Fix imports

Update ItemBindable.java
---
 .../api/iface/IItemLPContainer.java           |  15 ++
 .../bloodmagic/api/iface/IMultiWillTool.java  |   2 +-
 .../iface/ISentientSwordEffectProvider.java   |   4 +-
 .../api/impl/ItemSigilToggleable.java         |  23 ++-
 .../api/util/helper/BindableHelper.java       |   6 +-
 .../api/util/helper/ItemHelper.java           | 152 ++++++++++++++++++
 .../api/util/helper/NetworkHelper.java        |  14 +-
 .../api/util/helper/PlayerHelper.java         |  12 +-
 .../util/helper/PlayerSacrificeHelper.java    |  42 ++++-
 .../compat/jei/BloodMagicPlugin.java          |   6 +-
 .../bloodmagic/item/ItemBindableBase.java     |   3 +-
 .../bloodmagic/item/ItemBloodOrb.java         |   8 +-
 .../bloodmagic/item/ItemBoundAxe.java         |   1 -
 .../bloodmagic/item/ItemBoundPickaxe.java     |   3 +-
 .../bloodmagic/item/ItemBoundShovel.java      |   1 -
 .../bloodmagic/item/ItemBoundSword.java       |  36 +++--
 .../bloodmagic/item/ItemBoundTool.java        |  13 +-
 .../item/ItemDaggerOfSacrifice.java           |  46 +-----
 .../item/ItemSacrificialDagger.java           |  46 +-----
 .../bloodmagic/item/ItemUpgradeTome.java      |  53 +-----
 .../bloodmagic/item/ItemUpgradeTrainer.java   |  35 +---
 .../item/gear/ItemPackSacrifice.java          |  57 +++----
 .../item/gear/ItemPackSelfSacrifice.java      |  78 +++++----
 .../bloodmagic/item/sigil/ItemSigilBase.java  |   2 +-
 .../item/sigil/ItemSigilToggleableBase.java   |  37 +++--
 .../ritual/RitualUpgradeRemove.java           |   6 +-
 .../WayofTime/bloodmagic/util/ChatUtil.java   |   2 -
 .../bloodmagic/util/handler/EventHandler.java |  26 ++-
 28 files changed, 389 insertions(+), 340 deletions(-)
 create mode 100644 src/main/java/WayofTime/bloodmagic/api/iface/IItemLPContainer.java
 create mode 100644 src/main/java/WayofTime/bloodmagic/api/util/helper/ItemHelper.java

diff --git a/src/main/java/WayofTime/bloodmagic/api/iface/IItemLPContainer.java b/src/main/java/WayofTime/bloodmagic/api/iface/IItemLPContainer.java
new file mode 100644
index 00000000..0dedec7d
--- /dev/null
+++ b/src/main/java/WayofTime/bloodmagic/api/iface/IItemLPContainer.java
@@ -0,0 +1,15 @@
+package WayofTime.bloodmagic.api.iface;
+
+import net.minecraft.item.ItemStack;
+
+/**
+ * Interface used for any item that can store LP in itself
+ */
+public interface IItemLPContainer
+{
+    int getCapacity();
+
+    void setStoredLP(ItemStack stack, int lp);
+
+    int getStoredLP(ItemStack stack);
+}
diff --git a/src/main/java/WayofTime/bloodmagic/api/iface/IMultiWillTool.java b/src/main/java/WayofTime/bloodmagic/api/iface/IMultiWillTool.java
index fc4f4cb5..dfb2afa0 100644
--- a/src/main/java/WayofTime/bloodmagic/api/iface/IMultiWillTool.java
+++ b/src/main/java/WayofTime/bloodmagic/api/iface/IMultiWillTool.java
@@ -5,5 +5,5 @@ import WayofTime.bloodmagic.api.soul.EnumDemonWillType;
 
 public interface IMultiWillTool
 {
-    public EnumDemonWillType getCurrentType(ItemStack stack);
+    EnumDemonWillType getCurrentType(ItemStack stack);
 }
diff --git a/src/main/java/WayofTime/bloodmagic/api/iface/ISentientSwordEffectProvider.java b/src/main/java/WayofTime/bloodmagic/api/iface/ISentientSwordEffectProvider.java
index 1c884ed1..cedfce53 100644
--- a/src/main/java/WayofTime/bloodmagic/api/iface/ISentientSwordEffectProvider.java
+++ b/src/main/java/WayofTime/bloodmagic/api/iface/ISentientSwordEffectProvider.java
@@ -6,7 +6,7 @@ import WayofTime.bloodmagic.api.soul.EnumDemonWillType;
 
 public interface ISentientSwordEffectProvider
 {
-    public boolean applyOnHitEffect(EnumDemonWillType type, ItemStack swordStack, ItemStack providerStack, EntityLivingBase attacker, EntityLivingBase target);
+    boolean applyOnHitEffect(EnumDemonWillType type, ItemStack swordStack, ItemStack providerStack, EntityLivingBase attacker, EntityLivingBase target);
 
-    public boolean providesEffectForWill(EnumDemonWillType type);
+    boolean providesEffectForWill(EnumDemonWillType type);
 }
diff --git a/src/main/java/WayofTime/bloodmagic/api/impl/ItemSigilToggleable.java b/src/main/java/WayofTime/bloodmagic/api/impl/ItemSigilToggleable.java
index f39d7e20..1bef8555 100644
--- a/src/main/java/WayofTime/bloodmagic/api/impl/ItemSigilToggleable.java
+++ b/src/main/java/WayofTime/bloodmagic/api/impl/ItemSigilToggleable.java
@@ -1,6 +1,8 @@
 package WayofTime.bloodmagic.api.impl;
 
+import WayofTime.bloodmagic.api.Constants;
 import WayofTime.bloodmagic.api.iface.IActivatable;
+import WayofTime.bloodmagic.api.util.helper.NBTHelper;
 import WayofTime.bloodmagic.api.util.helper.NetworkHelper;
 import net.minecraft.entity.Entity;
 import net.minecraft.entity.player.EntityPlayer;
@@ -18,30 +20,27 @@ import net.minecraft.world.World;
  */
 public class ItemSigilToggleable extends ItemSigil implements IActivatable
 {
-    private boolean toggleable;
-
     public ItemSigilToggleable(int lpUsed)
     {
         super(lpUsed);
-        setToggleable();
-    }
-
-    public void setToggleable()
-    {
-        this.toggleable = true;
     }
 
+    @Override
     public boolean getActivated(ItemStack stack)
     {
-        return stack.getItemDamage() > 0;
+        return stack != null && NBTHelper.checkNBT(stack).getTagCompound().getBoolean(Constants.NBT.ACTIVATED);
     }
 
+    @Override
     public ItemStack setActivatedState(ItemStack stack, boolean activated)
     {
-        if (this.toggleable)
-            stack.setItemDamage(activated ? 1 : 0);
+        if (stack != null)
+        {
+            NBTHelper.checkNBT(stack).getTagCompound().setBoolean(Constants.NBT.ACTIVATED, activated);
+            return stack;
+        }
 
-        return stack;
+        return null;
     }
 
     @Override
diff --git a/src/main/java/WayofTime/bloodmagic/api/util/helper/BindableHelper.java b/src/main/java/WayofTime/bloodmagic/api/util/helper/BindableHelper.java
index 4d3a5c2c..28ec6844 100644
--- a/src/main/java/WayofTime/bloodmagic/api/util/helper/BindableHelper.java
+++ b/src/main/java/WayofTime/bloodmagic/api/util/helper/BindableHelper.java
@@ -86,7 +86,7 @@ public class BindableHelper
      * Deprecated.
      * 
      * Now handled automatically with
-     * {@link WayofTime.bloodmagic.util.handler.EventHandler#interactEvent(PlayerInteractEvent)}
+     * {@link WayofTime.bloodmagic.util.handler.EventHandler#onInteract(PlayerInteractEvent.RightClickItem)}}
      * 
      * @param stack
      *        - The ItemStack to bind
@@ -105,7 +105,7 @@ public class BindableHelper
      * Deprecated.
      * 
      * Now handled automatically with
-     * {@link WayofTime.bloodmagic.util.handler.EventHandler#interactEvent(PlayerInteractEvent)}
+     * {@link WayofTime.bloodmagic.util.handler.EventHandler#onInteract(PlayerInteractEvent.RightClickItem)}}
      * 
      * @param stack
      *        - The ItemStack to bind
@@ -145,7 +145,7 @@ public class BindableHelper
      * Deprecated.
      * 
      * Now handled automatically with
-     * {@link WayofTime.bloodmagic.util.handler.EventHandler#interactEvent(PlayerInteractEvent)}
+     * {@link WayofTime.bloodmagic.util.handler.EventHandler#onInteract(PlayerInteractEvent.RightClickItem)}}
      * 
      * @param stack
      *        - ItemStack to check
diff --git a/src/main/java/WayofTime/bloodmagic/api/util/helper/ItemHelper.java b/src/main/java/WayofTime/bloodmagic/api/util/helper/ItemHelper.java
new file mode 100644
index 00000000..eabb74b4
--- /dev/null
+++ b/src/main/java/WayofTime/bloodmagic/api/util/helper/ItemHelper.java
@@ -0,0 +1,152 @@
+package WayofTime.bloodmagic.api.util.helper;
+
+import WayofTime.bloodmagic.api.altar.IBloodAltar;
+import WayofTime.bloodmagic.api.iface.IItemLPContainer;
+import WayofTime.bloodmagic.api.iface.IUpgradeTrainer;
+import WayofTime.bloodmagic.api.livingArmour.LivingArmourHandler;
+import WayofTime.bloodmagic.api.livingArmour.LivingArmourUpgrade;
+import WayofTime.bloodmagic.item.ItemUpgradeTome;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.world.World;
+
+public class ItemHelper
+{
+    // IItemLPContainer
+    public static class LPContainer
+    {
+        /**
+         * Attempts to fill an altar with the contained LP
+         *
+         * @param altar
+         *        - The altar in question
+         * @param itemStack
+         *        - The {@link IItemLPContainer} ItemStack filling the altar
+         * @param world
+         *        - The world
+         * @param altarPos
+         *        - The position of the altar
+         *
+         * @return Whether or not the altar was filled (or at least attempted)
+         */
+        public static boolean tryAndFillAltar(IBloodAltar altar, ItemStack itemStack, World world, BlockPos altarPos)
+        {
+            if (itemStack.getItem() instanceof IItemLPContainer)
+            {
+                if (!altar.isActive())
+                {
+                    IItemLPContainer fillable = (IItemLPContainer) itemStack.getItem();
+                    int amount = fillable.getStoredLP(itemStack);
+
+                    if (amount > 0)
+                    {
+                        int filledAmount = altar.fillMainTank(amount);
+                        amount -= filledAmount;
+                        fillable.setStoredLP(itemStack, amount);
+                        world.notifyBlockUpdate(altarPos, world.getBlockState(altarPos), world.getBlockState(altarPos), 3);
+                        return true;
+                    }
+                }
+            }
+
+            return false;
+        }
+
+        /**
+         * Adds the given LP into the {@link IItemLPContainer}'s storage
+         *
+         * @param stack
+         *        - The item in question
+         * @param toAdd
+         *        - How much LP should be added to the item
+         * @param maxCapacity
+         *        - The item's maximum holding capacity
+         *
+         * @return Whether or not LP was added to the item
+         */
+        public static boolean addLPToItem(ItemStack stack, int toAdd, int maxCapacity)
+        {
+            if (stack.getItem() instanceof IItemLPContainer)
+            {
+                IItemLPContainer fillable = (IItemLPContainer) stack.getItem();
+                stack = NBTHelper.checkNBT(stack);
+
+                if (toAdd < 0)
+                    toAdd = 0;
+
+                if (toAdd > maxCapacity)
+                    toAdd = maxCapacity;
+
+                fillable.setStoredLP(stack, Math.min(fillable.getStoredLP(stack) + toAdd, maxCapacity));
+                return true;
+            }
+
+            return false;
+        }
+    }
+
+    public static class LivingUpgrades
+    {
+        public static LivingArmourUpgrade getUpgrade(ItemStack stack)
+        {
+            if (stack.getItem() instanceof ItemUpgradeTome || stack.getItem() instanceof IUpgradeTrainer)
+            {
+                String key = getKey(stack);
+                int level = getLevel(stack);
+
+                return LivingArmourHandler.generateUpgradeFromKey(key, level);
+            }
+
+            return null;
+        }
+
+        public static void setKey(ItemStack stack, String key)
+        {
+            if (stack.getItem() instanceof ItemUpgradeTome || stack.getItem() instanceof IUpgradeTrainer)
+            {
+                NBTHelper.checkNBT(stack);
+                NBTTagCompound tag = stack.getTagCompound();
+
+                tag.setString("key", key);
+            }
+        }
+
+        public static String getKey(ItemStack stack)
+        {
+            if (stack.getItem() instanceof ItemUpgradeTome || stack.getItem() instanceof IUpgradeTrainer)
+            {
+                NBTHelper.checkNBT(stack);
+                NBTTagCompound tag = stack.getTagCompound();
+
+                return tag.getString("key");
+            }
+
+            return "";
+        }
+
+        public static void setLevel(ItemStack stack, int level)
+        {
+            if (stack.getItem() instanceof ItemUpgradeTome || stack.getItem() instanceof IUpgradeTrainer)
+            {
+                NBTHelper.checkNBT(stack);
+                NBTTagCompound tag = stack.getTagCompound();
+
+                tag.setInteger("level", level);
+            }
+        }
+
+        public static int getLevel(ItemStack stack)
+        {
+            if (stack.getItem() instanceof ItemUpgradeTome || stack.getItem() instanceof IUpgradeTrainer)
+            {
+                NBTHelper.checkNBT(stack);
+                NBTTagCompound tag = stack.getTagCompound();
+
+                return tag.getInteger("level");
+            }
+
+            return 0;
+        }
+    }
+}
diff --git a/src/main/java/WayofTime/bloodmagic/api/util/helper/NetworkHelper.java b/src/main/java/WayofTime/bloodmagic/api/util/helper/NetworkHelper.java
index 5aa573cc..da525baa 100644
--- a/src/main/java/WayofTime/bloodmagic/api/util/helper/NetworkHelper.java
+++ b/src/main/java/WayofTime/bloodmagic/api/util/helper/NetworkHelper.java
@@ -25,25 +25,25 @@ public class NetworkHelper
     /**
      * Gets the SoulNetwork for the player.
      * 
-     * @param name
-     *        - The name of the SoulNetwork owner - this is UUID.toString().
+     * @param uuid
+     *        - The UUID of the SoulNetwork owner - this is UUID.toString().
      * 
      * @return - The SoulNetwork for the given name.
      */
-    public static SoulNetwork getSoulNetwork(String name)
+    public static SoulNetwork getSoulNetwork(String uuid)
     {
         World world = DimensionManager.getWorld(0);
         if (world == null || world.getMapStorage() == null) //Hack-ish way to fix the lava crystal. 
         {
-            return new SoulNetwork(name);
+            return new SoulNetwork(uuid);
         }
 
-        SoulNetwork network = (SoulNetwork) world.getMapStorage().loadData(SoulNetwork.class, name);
+        SoulNetwork network = (SoulNetwork) world.getMapStorage().loadData(SoulNetwork.class, uuid);
 
         if (network == null)
         {
-            network = new SoulNetwork(name);
-            world.getMapStorage().setData(name, network);
+            network = new SoulNetwork(uuid);
+            world.getMapStorage().setData(uuid, network);
         }
 
         return network;
diff --git a/src/main/java/WayofTime/bloodmagic/api/util/helper/PlayerHelper.java b/src/main/java/WayofTime/bloodmagic/api/util/helper/PlayerHelper.java
index a0972f9b..6d625aec 100644
--- a/src/main/java/WayofTime/bloodmagic/api/util/helper/PlayerHelper.java
+++ b/src/main/java/WayofTime/bloodmagic/api/util/helper/PlayerHelper.java
@@ -1,16 +1,12 @@
 package WayofTime.bloodmagic.api.util.helper;
 
 import WayofTime.bloodmagic.api.Constants;
-
 import com.google.common.base.Strings;
 import com.google.common.collect.Lists;
-
 import net.minecraft.entity.player.EntityPlayer;
 import net.minecraft.init.MobEffects;
 import net.minecraft.item.ItemStack;
-import net.minecraft.potion.Potion;
 import net.minecraft.potion.PotionEffect;
-import net.minecraft.server.MinecraftServer;
 import net.minecraftforge.common.UsernameCache;
 import net.minecraftforge.common.util.FakePlayer;
 import net.minecraftforge.fml.common.FMLCommonHandler;
@@ -73,6 +69,14 @@ public class PlayerHelper
         return stack.getTagCompound().getString(Constants.NBT.OWNER_NAME);
     }
 
+    /**
+     * Checks whether or not the given player is an "actual" player
+     *
+     * @param player
+     *        - The player in question
+     *
+     * @return If the player is fake or not
+     */
     public static boolean isFakePlayer(EntityPlayer player)
     {
         return player != null && (player instanceof FakePlayer || knownFakePlayers.contains(player.getClass().getCanonicalName()));
diff --git a/src/main/java/WayofTime/bloodmagic/api/util/helper/PlayerSacrificeHelper.java b/src/main/java/WayofTime/bloodmagic/api/util/helper/PlayerSacrificeHelper.java
index 32b7c3ff..3dd89ae0 100644
--- a/src/main/java/WayofTime/bloodmagic/api/util/helper/PlayerSacrificeHelper.java
+++ b/src/main/java/WayofTime/bloodmagic/api/util/helper/PlayerSacrificeHelper.java
@@ -2,6 +2,7 @@ package WayofTime.bloodmagic.api.util.helper;
 
 import WayofTime.bloodmagic.api.altar.IBloodAltar;
 import WayofTime.bloodmagic.registry.ModPotions;
+import net.minecraft.entity.EntityLivingBase;
 import net.minecraft.entity.player.EntityPlayer;
 import net.minecraft.potion.Potion;
 import net.minecraft.potion.PotionEffect;
@@ -42,6 +43,14 @@ public class PlayerSacrificeHelper
         return true;
     }
 
+    /**
+     * Sacrifices a player's health while the player is under the influence of incense
+     *
+     * @param player
+     *        - The player sacrificing
+     *
+     * @return Whether or not the health sacrificing succeeded
+     */
     public static boolean sacrificePlayerHealth(EntityPlayer player)
     {
         if (player.isPotionActive(soulFrayId))
@@ -79,17 +88,24 @@ public class PlayerSacrificeHelper
         return 1 + amount * scalingOfSacrifice;
     }
 
-    public static boolean findAndFillAltar(World world, EntityPlayer player, int amount)
+    /**
+     * Finds the nearest {@link IBloodAltar} and attempts to fill it
+     *
+     * @param world
+     *        - The world
+     * @param sacrificingEntity
+     *        - The entity having the sacrifice done on (can be {@link EntityPlayer} for self-sacrifice)
+     * @param amount
+     *        - The amount of which the altar should be filled
+     *
+     * @return Whether the altar is found and (attempted) filled
+     */
+    public static boolean findAndFillAltar(World world, EntityLivingBase sacrificingEntity, int amount)
     {
-        int posX = (int) Math.round(player.posX - 0.5f);
-        int posY = (int) player.posY;
-        int posZ = (int) Math.round(player.posZ - 0.5f);
-        IBloodAltar altarEntity = getAltar(world, new BlockPos(posX, posY, posZ));
+        IBloodAltar altarEntity = getAltar(world, sacrificingEntity.getPosition());
 
         if (altarEntity == null)
-        {
             return false;
-        }
 
         altarEntity.sacrificialDaggerCall(amount, false);
         altarEntity.startCycle();
@@ -97,6 +113,16 @@ public class PlayerSacrificeHelper
         return true;
     }
 
+    /**
+     * Gets the nearest {@link IBloodAltar}
+     *
+     * @param world
+     *        - The world
+     * @param blockPos
+     *        - The position of where the check should be in (in a 2 block radius from this)
+     *
+     * @return The nearest altar, if no altar is found, then this will return null
+     */
     public static IBloodAltar getAltar(World world, BlockPos blockPos)
     {
         TileEntity tileEntity;
@@ -107,7 +133,7 @@ public class PlayerSacrificeHelper
             {
                 for (int k = -2; k <= 1; k++)
                 {
-                    tileEntity = world.getTileEntity(new BlockPos(i + blockPos.getX(), k + blockPos.getY(), j + blockPos.getZ()));
+                    tileEntity = world.getTileEntity(blockPos.add(i, j, k));
 
                     if (tileEntity instanceof IBloodAltar)
                     {
diff --git a/src/main/java/WayofTime/bloodmagic/compat/jei/BloodMagicPlugin.java b/src/main/java/WayofTime/bloodmagic/compat/jei/BloodMagicPlugin.java
index 51d7cc12..32930db0 100644
--- a/src/main/java/WayofTime/bloodmagic/compat/jei/BloodMagicPlugin.java
+++ b/src/main/java/WayofTime/bloodmagic/compat/jei/BloodMagicPlugin.java
@@ -12,6 +12,7 @@ import net.minecraft.item.ItemStack;
 import net.minecraftforge.oredict.OreDictionary;
 import WayofTime.bloodmagic.api.Constants;
 import WayofTime.bloodmagic.api.livingArmour.LivingArmourHandler;
+import WayofTime.bloodmagic.api.util.helper.ItemHelper.LivingUpgrades;
 import WayofTime.bloodmagic.compat.jei.alchemyArray.AlchemyArrayCraftingCategory;
 import WayofTime.bloodmagic.compat.jei.alchemyArray.AlchemyArrayCraftingRecipeHandler;
 import WayofTime.bloodmagic.compat.jei.alchemyArray.AlchemyArrayCraftingRecipeMaker;
@@ -26,7 +27,6 @@ import WayofTime.bloodmagic.compat.jei.forge.TartaricForgeRecipeHandler;
 import WayofTime.bloodmagic.compat.jei.forge.TartaricForgeRecipeMaker;
 import WayofTime.bloodmagic.compat.jei.orb.ShapedOrbRecipeHandler;
 import WayofTime.bloodmagic.compat.jei.orb.ShapelessOrbRecipeHandler;
-import WayofTime.bloodmagic.item.ItemUpgradeTome;
 import WayofTime.bloodmagic.registry.ModBlocks;
 import WayofTime.bloodmagic.registry.ModItems;
 
@@ -65,8 +65,8 @@ public class BloodMagicPlugin extends BlankModPlugin
             for (int i = 0; i < maxLevel - 1; i++)
             {
                 ItemStack stack = new ItemStack(ModItems.upgradeTome);
-                ItemUpgradeTome.setKey(stack, key);
-                ItemUpgradeTome.setLevel(stack, i);
+                LivingUpgrades.setKey(stack, key);
+                LivingUpgrades.setLevel(stack, i);
                 jeiHelper.getItemBlacklist().addItemToBlacklist(stack);
             }
         }
diff --git a/src/main/java/WayofTime/bloodmagic/item/ItemBindableBase.java b/src/main/java/WayofTime/bloodmagic/item/ItemBindableBase.java
index d1c3657f..df9508e9 100644
--- a/src/main/java/WayofTime/bloodmagic/item/ItemBindableBase.java
+++ b/src/main/java/WayofTime/bloodmagic/item/ItemBindableBase.java
@@ -1,7 +1,6 @@
 package WayofTime.bloodmagic.item;
 
 import WayofTime.bloodmagic.BloodMagic;
-import WayofTime.bloodmagic.api.Constants;
 import WayofTime.bloodmagic.api.impl.ItemBindable;
 import WayofTime.bloodmagic.api.util.helper.NBTHelper;
 import WayofTime.bloodmagic.api.util.helper.PlayerHelper;
@@ -29,7 +28,7 @@ public class ItemBindableBase extends ItemBindable
     {
         NBTHelper.checkNBT(stack);
 
-        if (!Strings.isNullOrEmpty(stack.getTagCompound().getString(Constants.NBT.OWNER_UUID)))
+        if (!Strings.isNullOrEmpty(getOwnerUUID(stack)))
             tooltip.add(TextHelper.localizeEffect("tooltip.BloodMagic.currentOwner", PlayerHelper.getUsernameFromStack(stack)));
     }
 }
diff --git a/src/main/java/WayofTime/bloodmagic/item/ItemBloodOrb.java b/src/main/java/WayofTime/bloodmagic/item/ItemBloodOrb.java
index 3703fb5d..4f1a0433 100644
--- a/src/main/java/WayofTime/bloodmagic/item/ItemBloodOrb.java
+++ b/src/main/java/WayofTime/bloodmagic/item/ItemBloodOrb.java
@@ -65,16 +65,16 @@ public class ItemBloodOrb extends ItemBindableBase implements IBloodOrb, IBindab
             return super.onItemRightClick(stack, world, player, hand);
         }
 
-        if (Strings.isNullOrEmpty(stack.getTagCompound().getString(Constants.NBT.OWNER_UUID)))
+        if (Strings.isNullOrEmpty(getOwnerUUID(stack)))
             return super.onItemRightClick(stack, world, player, hand);
 
         if (world.isRemote)
             return super.onItemRightClick(stack, world, player, hand);
 
-        if (stack.getTagCompound().getString(Constants.NBT.OWNER_UUID).equals(PlayerHelper.getUsernameFromPlayer(player)))
-            NetworkHelper.setMaxOrb(NetworkHelper.getSoulNetwork(stack.getTagCompound().getString(Constants.NBT.OWNER_UUID)), getOrbLevel(stack.getItemDamage()));
+        if (getOwnerUUID(stack).equals(PlayerHelper.getUsernameFromPlayer(player)))
+            NetworkHelper.setMaxOrb(NetworkHelper.getSoulNetwork(getOwnerUUID(stack)), getOrbLevel(stack.getItemDamage()));
 
-        NetworkHelper.getSoulNetwork(stack.getTagCompound().getString(Constants.NBT.OWNER_UUID)).addLifeEssence(200, getMaxEssence(stack.getItemDamage()));
+        NetworkHelper.getSoulNetwork(getOwnerUUID(stack)).addLifeEssence(200, getMaxEssence(stack.getItemDamage()));
         NetworkHelper.getSoulNetwork(player).hurtPlayer(player, 200);
         return super.onItemRightClick(stack, world, player, hand);
     }
diff --git a/src/main/java/WayofTime/bloodmagic/item/ItemBoundAxe.java b/src/main/java/WayofTime/bloodmagic/item/ItemBoundAxe.java
index cdcc31fd..944e94bd 100644
--- a/src/main/java/WayofTime/bloodmagic/item/ItemBoundAxe.java
+++ b/src/main/java/WayofTime/bloodmagic/item/ItemBoundAxe.java
@@ -26,7 +26,6 @@ import net.minecraftforge.fml.common.eventhandler.Event;
 import net.minecraftforge.fml.relauncher.Side;
 import net.minecraftforge.fml.relauncher.SideOnly;
 import WayofTime.bloodmagic.api.BlockStack;
-import WayofTime.bloodmagic.api.Constants;
 import WayofTime.bloodmagic.api.ItemStackWrapper;
 import WayofTime.bloodmagic.api.util.helper.NetworkHelper;
 import WayofTime.bloodmagic.client.IMeshProvider;
diff --git a/src/main/java/WayofTime/bloodmagic/item/ItemBoundPickaxe.java b/src/main/java/WayofTime/bloodmagic/item/ItemBoundPickaxe.java
index b8c0bfb9..711529c1 100644
--- a/src/main/java/WayofTime/bloodmagic/item/ItemBoundPickaxe.java
+++ b/src/main/java/WayofTime/bloodmagic/item/ItemBoundPickaxe.java
@@ -26,7 +26,6 @@ import net.minecraftforge.fml.common.eventhandler.Event;
 import net.minecraftforge.fml.relauncher.Side;
 import net.minecraftforge.fml.relauncher.SideOnly;
 import WayofTime.bloodmagic.api.BlockStack;
-import WayofTime.bloodmagic.api.Constants;
 import WayofTime.bloodmagic.api.ItemStackWrapper;
 import WayofTime.bloodmagic.api.util.helper.NetworkHelper;
 import WayofTime.bloodmagic.client.IMeshProvider;
@@ -84,7 +83,7 @@ public class ItemBoundPickaxe extends ItemBoundTool implements IMeshProvider
 
         boolean silkTouch = EnchantmentHelper.getEnchantmentLevel(Enchantments.silkTouch, stack) > 0;
         int fortuneLvl = EnchantmentHelper.getEnchantmentLevel(Enchantments.fortune, stack);
-        int range = (int) (charge / 6); //Charge is a max of 30 - want 5 to be the max
+        int range = (charge / 6); //Charge is a max of 30 - want 5 to be the max
 
         HashMultiset<ItemStackWrapper> drops = HashMultiset.create();
 
diff --git a/src/main/java/WayofTime/bloodmagic/item/ItemBoundShovel.java b/src/main/java/WayofTime/bloodmagic/item/ItemBoundShovel.java
index ac40bf6f..870699ab 100644
--- a/src/main/java/WayofTime/bloodmagic/item/ItemBoundShovel.java
+++ b/src/main/java/WayofTime/bloodmagic/item/ItemBoundShovel.java
@@ -25,7 +25,6 @@ import net.minecraftforge.fml.common.eventhandler.Event;
 import net.minecraftforge.fml.relauncher.Side;
 import net.minecraftforge.fml.relauncher.SideOnly;
 import WayofTime.bloodmagic.api.BlockStack;
-import WayofTime.bloodmagic.api.Constants;
 import WayofTime.bloodmagic.api.ItemStackWrapper;
 import WayofTime.bloodmagic.api.util.helper.NetworkHelper;
 import WayofTime.bloodmagic.client.IMeshProvider;
diff --git a/src/main/java/WayofTime/bloodmagic/item/ItemBoundSword.java b/src/main/java/WayofTime/bloodmagic/item/ItemBoundSword.java
index 4e43864f..6df766aa 100644
--- a/src/main/java/WayofTime/bloodmagic/item/ItemBoundSword.java
+++ b/src/main/java/WayofTime/bloodmagic/item/ItemBoundSword.java
@@ -97,7 +97,7 @@ public class ItemBoundSword extends ItemSword implements IBindable, IActivatable
 
         tooltip.add(TextHelper.localize("tooltip.BloodMagic." + (getActivated(stack) ? "activated" : "deactivated")));
 
-        if (!Strings.isNullOrEmpty(stack.getTagCompound().getString(Constants.NBT.OWNER_UUID)))
+        if (!Strings.isNullOrEmpty(getOwnerUUID(stack)))
             tooltip.add(TextHelper.localizeEffect("tooltip.BloodMagic.currentOwner", PlayerHelper.getUsernameFromStack(stack)));
     }
 
@@ -113,20 +113,6 @@ public class ItemBoundSword extends ItemSword implements IBindable, IActivatable
         return multimap;
     }
 
-    public boolean getActivated(ItemStack stack)
-    {
-        NBTHelper.checkNBT(stack);
-        return stack.getTagCompound().getBoolean(Constants.NBT.ACTIVATED);
-    }
-
-    public ItemStack setActivatedState(ItemStack stack, boolean activated)
-    {
-        NBTHelper.checkNBT(stack);
-        stack.getTagCompound().setBoolean(Constants.NBT.ACTIVATED, activated);
-
-        return stack;
-    }
-
     @Override
     @SideOnly(Side.CLIENT)
     public ItemMeshDefinition getMeshDefinition()
@@ -169,4 +155,24 @@ public class ItemBoundSword extends ItemSword implements IBindable, IActivatable
     {
         return stack != null ? NBTHelper.checkNBT(stack).getTagCompound().getString(Constants.NBT.OWNER_UUID) : null;
     }
+
+    // IActivatable
+
+    @Override
+    public boolean getActivated(ItemStack stack)
+    {
+        return stack != null && NBTHelper.checkNBT(stack).getTagCompound().getBoolean(Constants.NBT.ACTIVATED);
+    }
+
+    @Override
+    public ItemStack setActivatedState(ItemStack stack, boolean activated)
+    {
+        if (stack != null)
+        {
+            NBTHelper.checkNBT(stack).getTagCompound().setBoolean(Constants.NBT.ACTIVATED, activated);
+            return stack;
+        }
+
+        return null;
+    }
 }
diff --git a/src/main/java/WayofTime/bloodmagic/item/ItemBoundTool.java b/src/main/java/WayofTime/bloodmagic/item/ItemBoundTool.java
index 2dbe793c..678cc373 100644
--- a/src/main/java/WayofTime/bloodmagic/item/ItemBoundTool.java
+++ b/src/main/java/WayofTime/bloodmagic/item/ItemBoundTool.java
@@ -190,7 +190,7 @@ public class ItemBoundTool extends ItemTool implements IBindable, IActivatable
 
         NBTHelper.checkNBT(stack);
 
-        if (!Strings.isNullOrEmpty(stack.getTagCompound().getString(Constants.NBT.OWNER_UUID)))
+        if (!Strings.isNullOrEmpty(getOwnerUUID(stack)))
             tooltip.add(TextHelper.localizeEffect("tooltip.BloodMagic.currentOwner", PlayerHelper.getUsernameFromStack(stack)));
 
         super.addInformation(stack, player, tooltip, advanced);
@@ -258,13 +258,18 @@ public class ItemBoundTool extends ItemTool implements IBindable, IActivatable
     @Override
     public boolean getActivated(ItemStack stack)
     {
-        return NBTHelper.checkNBT(stack).getTagCompound().getBoolean(Constants.NBT.ACTIVATED);
+        return stack != null && NBTHelper.checkNBT(stack).getTagCompound().getBoolean(Constants.NBT.ACTIVATED);
     }
 
     @Override
     public ItemStack setActivatedState(ItemStack stack, boolean activated)
     {
-        NBTHelper.checkNBT(stack).getTagCompound().setBoolean(Constants.NBT.ACTIVATED, activated);
-        return stack;
+        if (stack != null)
+        {
+            NBTHelper.checkNBT(stack).getTagCompound().setBoolean(Constants.NBT.ACTIVATED, activated);
+            return stack;
+        }
+
+        return null;
     }
 }
diff --git a/src/main/java/WayofTime/bloodmagic/item/ItemDaggerOfSacrifice.java b/src/main/java/WayofTime/bloodmagic/item/ItemDaggerOfSacrifice.java
index ad36fe03..07c1e8cc 100644
--- a/src/main/java/WayofTime/bloodmagic/item/ItemDaggerOfSacrifice.java
+++ b/src/main/java/WayofTime/bloodmagic/item/ItemDaggerOfSacrifice.java
@@ -9,11 +9,7 @@ import net.minecraft.entity.player.EntityPlayerMP;
 import net.minecraft.init.SoundEvents;
 import net.minecraft.item.Item;
 import net.minecraft.item.ItemStack;
-import net.minecraft.tileentity.TileEntity;
 import net.minecraft.util.SoundCategory;
-import net.minecraft.util.math.BlockPos;
-import net.minecraft.world.World;
-
 import org.apache.commons.lang3.tuple.ImmutablePair;
 import org.apache.commons.lang3.tuple.Pair;
 
@@ -21,9 +17,8 @@ import WayofTime.bloodmagic.BloodMagic;
 import WayofTime.bloodmagic.ConfigHandler;
 import WayofTime.bloodmagic.api.BloodMagicAPI;
 import WayofTime.bloodmagic.api.Constants;
-import WayofTime.bloodmagic.api.DamageSourceBloodMagic;
-import WayofTime.bloodmagic.api.altar.IBloodAltar;
 import WayofTime.bloodmagic.client.IVariantProvider;
+import WayofTime.bloodmagic.api.util.helper.PlayerSacrificeHelper;
 
 public class ItemDaggerOfSacrifice extends Item implements IVariantProvider
 {
@@ -57,11 +52,11 @@ public class ItemDaggerOfSacrifice extends Item implements IVariantProvider
         if (BloodMagicAPI.getEntitySacrificeValues().containsKey(entityName))
             lifeEssence = BloodMagicAPI.getEntitySacrificeValues().get(entityName);
 
-        if (findAndFillAltar(attacker.worldObj, target, lifeEssence))
+        if (PlayerSacrificeHelper.findAndFillAltar(attacker.worldObj, target, lifeEssence))
         {
             target.worldObj.playSound(null, target.posX, target.posY, target.posZ, SoundEvents.block_fire_extinguish, SoundCategory.BLOCKS, 0.5F, 2.6F + (target.worldObj.rand.nextFloat() - target.worldObj.rand.nextFloat()) * 0.8F);
             target.setHealth(-1);
-            target.onDeath(new DamageSourceBloodMagic());
+            target.onDeath(BloodMagicAPI.getDamageSource());
         }
 
         return false;
@@ -74,39 +69,4 @@ public class ItemDaggerOfSacrifice extends Item implements IVariantProvider
         ret.add(new ImmutablePair<Integer, String>(0, "type=normal"));
         return ret;
     }
-
-    public boolean findAndFillAltar(World world, EntityLivingBase sacrifice, int amount)
-    {
-        IBloodAltar bloodAltar = findBloodAltar(world, sacrifice.getPosition());
-
-        if (bloodAltar != null)
-        {
-            bloodAltar.sacrificialDaggerCall(amount, true);
-            bloodAltar.startCycle();
-            return true;
-        }
-
-        return false;
-    }
-
-    public IBloodAltar findBloodAltar(World world, BlockPos blockPos)
-    {
-        TileEntity tileEntity;
-
-        for (int i = -2; i <= 2; i++)
-        {
-            for (int j = -2; j <= 2; j++)
-            {
-                for (int k = -2; k <= 1; k++)
-                {
-                    tileEntity = world.getTileEntity(blockPos.add(i, k, j));
-
-                    if ((tileEntity instanceof IBloodAltar))
-                        return (IBloodAltar) tileEntity;
-                }
-            }
-        }
-
-        return null;
-    }
 }
diff --git a/src/main/java/WayofTime/bloodmagic/item/ItemSacrificialDagger.java b/src/main/java/WayofTime/bloodmagic/item/ItemSacrificialDagger.java
index 0c01a5ae..d0bcd18d 100644
--- a/src/main/java/WayofTime/bloodmagic/item/ItemSacrificialDagger.java
+++ b/src/main/java/WayofTime/bloodmagic/item/ItemSacrificialDagger.java
@@ -13,12 +13,7 @@ import net.minecraft.item.EnumAction;
 import net.minecraft.item.Item;
 import net.minecraft.item.ItemStack;
 import net.minecraft.tileentity.TileEntity;
-import net.minecraft.util.ActionResult;
-import net.minecraft.util.EnumActionResult;
-import net.minecraft.util.EnumHand;
-import net.minecraft.util.EnumParticleTypes;
-import net.minecraft.util.SoundCategory;
-import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.*;
 import net.minecraft.util.math.RayTraceResult;
 import net.minecraft.world.World;
 import net.minecraftforge.common.MinecraftForge;
@@ -31,7 +26,6 @@ import org.apache.commons.lang3.tuple.Pair;
 import WayofTime.bloodmagic.BloodMagic;
 import WayofTime.bloodmagic.api.BloodMagicAPI;
 import WayofTime.bloodmagic.api.Constants;
-import WayofTime.bloodmagic.api.altar.IBloodAltar;
 import WayofTime.bloodmagic.api.event.SacrificeKnifeUsedEvent;
 import WayofTime.bloodmagic.api.util.helper.NBTHelper;
 import WayofTime.bloodmagic.api.util.helper.PlayerHelper;
@@ -154,7 +148,7 @@ public class ItemSacrificialDagger extends Item implements IVariantProvider
             return super.onItemRightClick(stack, world, player, hand);
 
         // TODO - Check if SoulFray is active
-        findAndFillAltar(world, player, lpAdded);
+        PlayerSacrificeHelper.findAndFillAltar(world, player, lpAdded);
 
         return super.onItemRightClick(stack, world, player, hand);
     }
@@ -168,42 +162,6 @@ public class ItemSacrificialDagger extends Item implements IVariantProvider
         return ret;
     }
 
-    protected void findAndFillAltar(World world, EntityPlayer player, int amount)
-    {
-        BlockPos pos = player.getPosition();
-        IBloodAltar altarEntity = getAltar(world, pos);
-
-        if (altarEntity == null)
-            return;
-
-        altarEntity.sacrificialDaggerCall(amount, false);
-        altarEntity.startCycle();
-    }
-
-    public IBloodAltar getAltar(World world, BlockPos pos)
-    {
-        TileEntity tileEntity;
-
-        for (int i = -2; i <= 2; i++)
-        {
-            for (int j = -2; j <= 2; j++)
-            {
-                for (int k = -2; k <= 1; k++)
-                {
-                    BlockPos newPos = pos.add(i, j, k);
-                    tileEntity = world.getTileEntity(newPos);
-
-                    if (tileEntity instanceof IBloodAltar)
-                    {
-                        return (IBloodAltar) tileEntity;
-                    }
-                }
-            }
-        }
-
-        return null;
-    }
-
     @Override
     public void onUpdate(ItemStack stack, World world, Entity entity, int par4, boolean par5)
     {
diff --git a/src/main/java/WayofTime/bloodmagic/item/ItemUpgradeTome.java b/src/main/java/WayofTime/bloodmagic/item/ItemUpgradeTome.java
index 1adcc237..2daa1538 100644
--- a/src/main/java/WayofTime/bloodmagic/item/ItemUpgradeTome.java
+++ b/src/main/java/WayofTime/bloodmagic/item/ItemUpgradeTome.java
@@ -4,7 +4,7 @@ import WayofTime.bloodmagic.BloodMagic;
 import WayofTime.bloodmagic.api.Constants;
 import WayofTime.bloodmagic.api.livingArmour.LivingArmourHandler;
 import WayofTime.bloodmagic.api.livingArmour.LivingArmourUpgrade;
-import WayofTime.bloodmagic.api.util.helper.NBTHelper;
+import WayofTime.bloodmagic.api.util.helper.ItemHelper.LivingUpgrades;
 import WayofTime.bloodmagic.client.IVariantProvider;
 import WayofTime.bloodmagic.item.armour.ItemLivingArmour;
 import WayofTime.bloodmagic.livingArmour.LivingArmour;
@@ -14,13 +14,11 @@ import net.minecraft.entity.player.EntityPlayer;
 import net.minecraft.inventory.EntityEquipmentSlot;
 import net.minecraft.item.Item;
 import net.minecraft.item.ItemStack;
-import net.minecraft.nbt.NBTTagCompound;
 import net.minecraft.util.ActionResult;
 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;
 
@@ -47,7 +45,8 @@ public class ItemUpgradeTome extends Item implements IVariantProvider
         {
             return super.onItemRightClick(stack, world, player, hand);
         }
-        LivingArmourUpgrade upgrade = ItemUpgradeTome.getUpgrade(stack);
+
+        LivingArmourUpgrade upgrade = LivingUpgrades.getUpgrade(stack);
         if (upgrade == null)
         {
             return super.onItemRightClick(stack, world, player, hand);
@@ -83,8 +82,8 @@ public class ItemUpgradeTome extends Item implements IVariantProvider
             for (int i = 0; i < maxLevel; i++)
             {
                 ItemStack stack = new ItemStack(this);
-                setKey(stack, key);
-                setLevel(stack, i);
+                LivingUpgrades.setKey(stack, key);
+                LivingUpgrades.setLevel(stack, i);
                 list.add(stack);
             }
         }
@@ -98,52 +97,12 @@ public class ItemUpgradeTome extends Item implements IVariantProvider
         return ret;
     }
 
-    public static LivingArmourUpgrade getUpgrade(ItemStack stack)
-    {
-        String key = getKey(stack);
-        int level = getLevel(stack);
-
-        return LivingArmourHandler.generateUpgradeFromKey(key, level);
-    }
-
-    public static void setKey(ItemStack stack, String key)
-    {
-        NBTHelper.checkNBT(stack);
-        NBTTagCompound tag = stack.getTagCompound();
-
-        tag.setString("key", key);
-    }
-
-    public static String getKey(ItemStack stack)
-    {
-        NBTHelper.checkNBT(stack);
-        NBTTagCompound tag = stack.getTagCompound();
-
-        return tag.getString("key");
-    }
-
-    public static void setLevel(ItemStack stack, int level)
-    {
-        NBTHelper.checkNBT(stack);
-        NBTTagCompound tag = stack.getTagCompound();
-
-        tag.setInteger("level", level);
-    }
-
-    public static int getLevel(ItemStack stack)
-    {
-        NBTHelper.checkNBT(stack);
-        NBTTagCompound tag = stack.getTagCompound();
-
-        return tag.getInteger("level");
-    }
-
     @Override
     @SideOnly(Side.CLIENT)
     public void addInformation(ItemStack stack, EntityPlayer player, List<String> tooltip, boolean advanced)
     {
 //        tooltip.addAll(Arrays.asList(TextHelper.cutLongString(TextHelper.localizeEffect("tooltip.BloodMagic.livingArmour"))));
-        LivingArmourUpgrade upgrade = ItemUpgradeTome.getUpgrade(stack);
+        LivingArmourUpgrade upgrade = LivingUpgrades.getUpgrade(stack);
         if (upgrade != null)
         {
             tooltip.add(TextHelper.localizeEffect("tooltip.BloodMagic.livingArmour.upgrade.level", TextHelper.localize(upgrade.getUnlocalizedName()), upgrade.getUpgradeLevel() + 1));
diff --git a/src/main/java/WayofTime/bloodmagic/item/ItemUpgradeTrainer.java b/src/main/java/WayofTime/bloodmagic/item/ItemUpgradeTrainer.java
index b064a996..bb3f5d5d 100644
--- a/src/main/java/WayofTime/bloodmagic/item/ItemUpgradeTrainer.java
+++ b/src/main/java/WayofTime/bloodmagic/item/ItemUpgradeTrainer.java
@@ -5,14 +5,13 @@ import WayofTime.bloodmagic.api.Constants;
 import WayofTime.bloodmagic.api.iface.IUpgradeTrainer;
 import WayofTime.bloodmagic.api.livingArmour.LivingArmourHandler;
 import WayofTime.bloodmagic.api.livingArmour.LivingArmourUpgrade;
-import WayofTime.bloodmagic.api.util.helper.NBTHelper;
+import WayofTime.bloodmagic.api.util.helper.ItemHelper.LivingUpgrades;
 import WayofTime.bloodmagic.client.IVariantProvider;
 import WayofTime.bloodmagic.util.helper.TextHelper;
 import net.minecraft.creativetab.CreativeTabs;
 import net.minecraft.entity.player.EntityPlayer;
 import net.minecraft.item.Item;
 import net.minecraft.item.ItemStack;
-import net.minecraft.nbt.NBTTagCompound;
 import net.minecraftforge.fml.relauncher.Side;
 import net.minecraftforge.fml.relauncher.SideOnly;
 import org.apache.commons.lang3.tuple.ImmutablePair;
@@ -43,41 +42,17 @@ public class ItemUpgradeTrainer extends Item implements IUpgradeTrainer, IVarian
         {
             String key = entry.getKey();
             ItemStack stack = new ItemStack(this);
-            setKey(stack, key);
+            LivingUpgrades.setKey(stack, key);
             list.add(stack);
         }
     }
 
-    public static LivingArmourUpgrade getUpgrade(ItemStack stack)
-    {
-        String key = getKey(stack);
-        int level = 0;
-
-        return LivingArmourHandler.generateUpgradeFromKey(key, level);
-    }
-
-    public static void setKey(ItemStack stack, String key)
-    {
-        NBTHelper.checkNBT(stack);
-        NBTTagCompound tag = stack.getTagCompound();
-
-        tag.setString("key", key);
-    }
-
-    public static String getKey(ItemStack stack)
-    {
-        NBTHelper.checkNBT(stack);
-        NBTTagCompound tag = stack.getTagCompound();
-
-        return tag.getString("key");
-    }
-
     @Override
     @SideOnly(Side.CLIENT)
     public void addInformation(ItemStack stack, EntityPlayer player, List<String> tooltip, boolean advanced)
     {
 //        tooltip.addAll(Arrays.asList(TextHelper.cutLongString(TextHelper.localizeEffect("tooltip.BloodMagic.livingArmour"))));
-        LivingArmourUpgrade upgrade = ItemUpgradeTrainer.getUpgrade(stack);
+        LivingArmourUpgrade upgrade = LivingUpgrades.getUpgrade(stack);
         if (upgrade != null)
         {
             tooltip.add(TextHelper.localize(upgrade.getUnlocalizedName()));
@@ -88,7 +63,7 @@ public class ItemUpgradeTrainer extends Item implements IUpgradeTrainer, IVarian
     public List<String> getTrainedUpgrades(ItemStack stack)
     {
         List<String> keyList = new ArrayList<String>();
-        String key = getKey(stack);
+        String key = LivingUpgrades.getKey(stack);
 
         if (!key.isEmpty())
         {
@@ -106,7 +81,7 @@ public class ItemUpgradeTrainer extends Item implements IUpgradeTrainer, IVarian
             return false;
         }
 
-        setKey(stack, keys.get(0));
+        LivingUpgrades.setKey(stack, keys.get(0));
         return true;
     }
 
diff --git a/src/main/java/WayofTime/bloodmagic/item/gear/ItemPackSacrifice.java b/src/main/java/WayofTime/bloodmagic/item/gear/ItemPackSacrifice.java
index acb1f7e3..0da7e164 100644
--- a/src/main/java/WayofTime/bloodmagic/item/gear/ItemPackSacrifice.java
+++ b/src/main/java/WayofTime/bloodmagic/item/gear/ItemPackSacrifice.java
@@ -3,9 +3,11 @@ package WayofTime.bloodmagic.item.gear;
 import WayofTime.bloodmagic.BloodMagic;
 import WayofTime.bloodmagic.api.Constants;
 import WayofTime.bloodmagic.api.altar.IAltarManipulator;
+import WayofTime.bloodmagic.api.altar.IBloodAltar;
+import WayofTime.bloodmagic.api.iface.IItemLPContainer;
+import WayofTime.bloodmagic.api.util.helper.ItemHelper.LPContainer;
 import WayofTime.bloodmagic.api.util.helper.NBTHelper;
 import WayofTime.bloodmagic.client.IVariantProvider;
-import WayofTime.bloodmagic.tile.TileAltar;
 import WayofTime.bloodmagic.util.helper.TextHelper;
 import net.minecraft.entity.player.EntityPlayer;
 import net.minecraft.inventory.EntityEquipmentSlot;
@@ -23,7 +25,7 @@ import org.apache.commons.lang3.tuple.Pair;
 import java.util.ArrayList;
 import java.util.List;
 
-public class ItemPackSacrifice extends ItemArmor implements IAltarManipulator, IVariantProvider
+public class ItemPackSacrifice extends ItemArmor implements IAltarManipulator, IItemLPContainer, IVariantProvider
 {
     public final int CAPACITY = 10000; // Max LP storage
 
@@ -52,23 +54,10 @@ public class ItemPackSacrifice extends ItemArmor implements IAltarManipulator, I
             {
                 TileEntity tile = world.getTileEntity(position.getBlockPos());
 
-                if (!(tile instanceof TileAltar))
+                if (!(tile instanceof IBloodAltar))
                     return super.onItemRightClick(stack, world, player, EnumHand.MAIN_HAND);
 
-                TileAltar altar = (TileAltar) tile;
-
-                if (!altar.isActive())
-                {
-                    int amount = this.getStoredLP(stack);
-
-                    if (amount > 0)
-                    {
-                        int filledAmount = altar.fillMainTank(amount);
-                        amount -= filledAmount;
-                        setStoredLP(stack, amount);
-                        world.notifyBlockUpdate(position.getBlockPos(), world.getBlockState(position.getBlockPos()), world.getBlockState(position.getBlockPos()), 3);
-                    }
-                }
+                LPContainer.tryAndFillAltar((IBloodAltar) tile, stack, world, position.getBlockPos());
             }
         }
 
@@ -98,28 +87,26 @@ public class ItemPackSacrifice extends ItemArmor implements IAltarManipulator, I
         return ret;
     }
 
-    public void addLP(ItemStack stack, int toAdd)
+    // IFillable
+
+    @Override
+    public int getCapacity()
     {
-        stack = NBTHelper.checkNBT(stack);
-
-        if (toAdd < 0)
-            toAdd = 0;
-
-        if (toAdd > CAPACITY)
-            toAdd = CAPACITY;
-
-        setStoredLP(stack, Math.min(getStoredLP(stack) + toAdd, CAPACITY));
-    }
-
-    public void setStoredLP(ItemStack stack, int lp)
-    {
-        stack = NBTHelper.checkNBT(stack);
-        stack.getTagCompound().setInteger(Constants.NBT.STORED_LP, lp);
+        return this.CAPACITY;
     }
 
+    @Override
     public int getStoredLP(ItemStack stack)
     {
-        stack = NBTHelper.checkNBT(stack);
-        return stack.getTagCompound().getInteger(Constants.NBT.STORED_LP);
+        return stack != null ? NBTHelper.checkNBT(stack).getTagCompound().getInteger(Constants.NBT.STORED_LP) : 0;
+    }
+
+    @Override
+    public void setStoredLP(ItemStack stack, int lp)
+    {
+        if (stack != null)
+        {
+            NBTHelper.checkNBT(stack).getTagCompound().setInteger(Constants.NBT.STORED_LP, lp);
+        }
     }
 }
diff --git a/src/main/java/WayofTime/bloodmagic/item/gear/ItemPackSelfSacrifice.java b/src/main/java/WayofTime/bloodmagic/item/gear/ItemPackSelfSacrifice.java
index 178ea0b6..2c9d6733 100644
--- a/src/main/java/WayofTime/bloodmagic/item/gear/ItemPackSelfSacrifice.java
+++ b/src/main/java/WayofTime/bloodmagic/item/gear/ItemPackSelfSacrifice.java
@@ -3,10 +3,12 @@ package WayofTime.bloodmagic.item.gear;
 import WayofTime.bloodmagic.BloodMagic;
 import WayofTime.bloodmagic.api.Constants;
 import WayofTime.bloodmagic.api.altar.IAltarManipulator;
+import WayofTime.bloodmagic.api.altar.IBloodAltar;
+import WayofTime.bloodmagic.api.iface.IItemLPContainer;
+import WayofTime.bloodmagic.api.util.helper.ItemHelper.LPContainer;
 import WayofTime.bloodmagic.api.util.helper.NBTHelper;
 import WayofTime.bloodmagic.api.util.helper.NetworkHelper;
 import WayofTime.bloodmagic.client.IVariantProvider;
-import WayofTime.bloodmagic.tile.TileAltar;
 import WayofTime.bloodmagic.util.helper.TextHelper;
 import net.minecraft.entity.player.EntityPlayer;
 import net.minecraft.inventory.EntityEquipmentSlot;
@@ -24,15 +26,23 @@ import org.apache.commons.lang3.tuple.Pair;
 import java.util.ArrayList;
 import java.util.List;
 
-public class ItemPackSelfSacrifice extends ItemArmor implements IAltarManipulator, IVariantProvider
+public class ItemPackSelfSacrifice extends ItemArmor implements IAltarManipulator, IItemLPContainer, IVariantProvider
 {
-    /** How much LP per half heart */
+    /**
+     * How much LP per half heart
+     */
     public final int CONVERSION = 100;
-    /** Max LP storage */
+    /**
+     * Max LP storage
+     */
     public final int CAPACITY = 10000;
-    /** How often the pack syphons */
+    /**
+     * How often the pack syphons
+     */
     public final int INTERVAL = 20;
-    /** How much health is required for the pack to syphon (0 - 1) */
+    /**
+     * How much health is required for the pack to syphon (0 - 1)
+     */
     public final float HEALTHREQ = 0.5f;
 
     public ItemPackSelfSacrifice()
@@ -54,29 +64,17 @@ public class ItemPackSelfSacrifice extends ItemArmor implements IAltarManipulato
         if (position == null)
         {
             return super.onItemRightClick(stack, world, player, EnumHand.MAIN_HAND);
-        } else
+        }
+        else
         {
             if (position.typeOfHit == RayTraceResult.Type.BLOCK)
             {
                 TileEntity tile = world.getTileEntity(position.getBlockPos());
 
-                if (!(tile instanceof TileAltar))
+                if (!(tile instanceof IBloodAltar))
                     return super.onItemRightClick(stack, world, player, EnumHand.MAIN_HAND);
 
-                TileAltar altar = (TileAltar) tile;
-
-                if (!altar.isActive())
-                {
-                    int amount = this.getStoredLP(stack);
-
-                    if (amount > 0)
-                    {
-                        int filledAmount = altar.fillMainTank(amount);
-                        amount -= filledAmount;
-                        setStoredLP(stack, amount);
-                        world.notifyBlockUpdate(position.getBlockPos(), world.getBlockState(position.getBlockPos()), world.getBlockState(position.getBlockPos()), 3);
-                    }
-                }
+                LPContainer.tryAndFillAltar((IBloodAltar) tile, stack, world, position.getBlockPos());
             }
         }
 
@@ -94,7 +92,7 @@ public class ItemPackSelfSacrifice extends ItemArmor implements IAltarManipulato
         if (shouldSyphon & world.getTotalWorldTime() % INTERVAL == 0)
         {
             NetworkHelper.getSoulNetwork(player).hurtPlayer(player, 1.0F);
-            addLP(stack, CONVERSION);
+            LPContainer.addLPToItem(stack, CONVERSION, CAPACITY);
         }
 
         if (getStoredLP(stack) > CAPACITY)
@@ -117,28 +115,26 @@ public class ItemPackSelfSacrifice extends ItemArmor implements IAltarManipulato
         return ret;
     }
 
-    public void addLP(ItemStack stack, int toAdd)
+    // IFillable
+
+    @Override
+    public int getCapacity()
     {
-        stack = NBTHelper.checkNBT(stack);
-
-        if (toAdd < 0)
-            toAdd = 0;
-
-        if (toAdd > CAPACITY)
-            toAdd = CAPACITY;
-
-        setStoredLP(stack, Math.min(getStoredLP(stack) + toAdd, CAPACITY));
-    }
-
-    public void setStoredLP(ItemStack stack, int lp)
-    {
-        stack = NBTHelper.checkNBT(stack);
-        stack.getTagCompound().setInteger(Constants.NBT.STORED_LP, lp);
+        return this.CAPACITY;
     }
 
+    @Override
     public int getStoredLP(ItemStack stack)
     {
-        stack = NBTHelper.checkNBT(stack);
-        return stack.getTagCompound().getInteger(Constants.NBT.STORED_LP);
+        return stack != null ? NBTHelper.checkNBT(stack).getTagCompound().getInteger(Constants.NBT.STORED_LP) : 0;
+    }
+
+    @Override
+    public void setStoredLP(ItemStack stack, int lp)
+    {
+        if (stack != null)
+        {
+            NBTHelper.checkNBT(stack).getTagCompound().setInteger(Constants.NBT.STORED_LP, lp);
+        }
     }
 }
diff --git a/src/main/java/WayofTime/bloodmagic/item/sigil/ItemSigilBase.java b/src/main/java/WayofTime/bloodmagic/item/sigil/ItemSigilBase.java
index 53d06b4d..b737a693 100644
--- a/src/main/java/WayofTime/bloodmagic/item/sigil/ItemSigilBase.java
+++ b/src/main/java/WayofTime/bloodmagic/item/sigil/ItemSigilBase.java
@@ -53,7 +53,7 @@ public class ItemSigilBase extends ItemSigil implements IVariantProvider
 
         NBTHelper.checkNBT(stack);
 
-        if (!Strings.isNullOrEmpty(stack.getTagCompound().getString(Constants.NBT.OWNER_UUID)))
+        if (!Strings.isNullOrEmpty(getOwnerName(stack)))
             tooltip.add(TextHelper.localizeEffect("tooltip.BloodMagic.currentOwner", PlayerHelper.getUsernameFromStack(stack)));
 
         super.addInformation(stack, player, tooltip, advanced);
diff --git a/src/main/java/WayofTime/bloodmagic/item/sigil/ItemSigilToggleableBase.java b/src/main/java/WayofTime/bloodmagic/item/sigil/ItemSigilToggleableBase.java
index a0190411..d2afc11c 100644
--- a/src/main/java/WayofTime/bloodmagic/item/sigil/ItemSigilToggleableBase.java
+++ b/src/main/java/WayofTime/bloodmagic/item/sigil/ItemSigilToggleableBase.java
@@ -8,19 +8,22 @@ import WayofTime.bloodmagic.api.Constants;
 import WayofTime.bloodmagic.api.impl.ItemSigilToggleable;
 import WayofTime.bloodmagic.api.util.helper.NBTHelper;
 import WayofTime.bloodmagic.api.util.helper.PlayerHelper;
-import WayofTime.bloodmagic.client.IVariantProvider;
+import WayofTime.bloodmagic.client.IMeshProvider;
+import WayofTime.bloodmagic.client.mesh.CustomMeshDefinitionActivatable;
 import com.google.common.base.Strings;
+import net.minecraft.client.renderer.ItemMeshDefinition;
 import net.minecraft.entity.player.EntityPlayer;
 import net.minecraft.item.ItemStack;
+import net.minecraft.util.ResourceLocation;
 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;
+import org.apache.commons.lang3.text.WordUtils;
 
+import javax.annotation.Nullable;
 import WayofTime.bloodmagic.util.helper.TextHelper;
 
-public class ItemSigilToggleableBase extends ItemSigilToggleable implements IVariantProvider
+public class ItemSigilToggleableBase extends ItemSigilToggleable implements IMeshProvider
 {
     protected final String tooltipBase;
     private final String name;
@@ -28,7 +31,6 @@ public class ItemSigilToggleableBase extends ItemSigilToggleable implements IVar
     public ItemSigilToggleableBase(String name, int lpUsed)
     {
         super(lpUsed);
-        setToggleable();
 
         setUnlocalizedName(Constants.Mod.MODID + ".sigil." + name);
         setCreativeTab(BloodMagic.tabBloodMagic);
@@ -45,16 +47,31 @@ public class ItemSigilToggleableBase extends ItemSigilToggleable implements IVar
         super.addInformation(stack, player, tooltip, advanced);
         tooltip.add(TextHelper.localizeEffect("tooltip.BloodMagic." + (getActivated(stack) ? "activated" : "deactivated")));
 
-        if (!Strings.isNullOrEmpty(stack.getTagCompound().getString(Constants.NBT.OWNER_UUID)))
+        if (!Strings.isNullOrEmpty(getOwnerName(stack)))
             tooltip.add(TextHelper.localizeEffect("tooltip.BloodMagic.currentOwner", PlayerHelper.getUsernameFromStack(stack)));
     }
 
     @Override
-    public List<Pair<Integer, String>> getVariants()
+    @SideOnly(Side.CLIENT)
+    public ItemMeshDefinition getMeshDefinition()
     {
-        List<Pair<Integer, String>> ret = new ArrayList<Pair<Integer, String>>();
-        ret.add(new ImmutablePair<Integer, String>(0, "active=false"));
-        ret.add(new ImmutablePair<Integer, String>(1, "active=true"));
+        return new CustomMeshDefinitionActivatable("ItemSigil" + WordUtils.capitalize(name));
+    }
+
+    @Nullable
+    @Override
+    public ResourceLocation getCustomLocation()
+    {
+        return null;
+    }
+
+    @Override
+    public List<String> getVariants()
+    {
+        List<String> ret = new ArrayList<String>();
+        ret.add("active=false");
+        ret.add("active=true");
+
         return ret;
     }
 }
diff --git a/src/main/java/WayofTime/bloodmagic/ritual/RitualUpgradeRemove.java b/src/main/java/WayofTime/bloodmagic/ritual/RitualUpgradeRemove.java
index ab525d4e..88b1754b 100644
--- a/src/main/java/WayofTime/bloodmagic/ritual/RitualUpgradeRemove.java
+++ b/src/main/java/WayofTime/bloodmagic/ritual/RitualUpgradeRemove.java
@@ -4,7 +4,7 @@ import WayofTime.bloodmagic.api.Constants;
 import WayofTime.bloodmagic.api.livingArmour.LivingArmourUpgrade;
 import WayofTime.bloodmagic.api.livingArmour.StatTracker;
 import WayofTime.bloodmagic.api.ritual.*;
-import WayofTime.bloodmagic.item.ItemUpgradeTome;
+import WayofTime.bloodmagic.api.util.helper.ItemHelper.LivingUpgrades;
 import WayofTime.bloodmagic.item.armour.ItemLivingArmour;
 import WayofTime.bloodmagic.livingArmour.LivingArmour;
 import WayofTime.bloodmagic.registry.ModItems;
@@ -66,8 +66,8 @@ public class RitualUpgradeRemove extends Ritual
                         String upgradeKey = entry.getKey();
 
                         ItemStack upgradeStack = new ItemStack(ModItems.upgradeTome);
-                        ItemUpgradeTome.setKey(upgradeStack, upgradeKey);
-                        ItemUpgradeTome.setLevel(upgradeStack, upgrade.getUpgradeLevel());
+                        LivingUpgrades.setKey(upgradeStack, upgradeKey);
+                        LivingUpgrades.setLevel(upgradeStack, upgrade.getUpgradeLevel());
 
                         boolean successful = armour.removeUpgrade(player, upgrade);
 
diff --git a/src/main/java/WayofTime/bloodmagic/util/ChatUtil.java b/src/main/java/WayofTime/bloodmagic/util/ChatUtil.java
index 2eab3d95..d3b022e4 100644
--- a/src/main/java/WayofTime/bloodmagic/util/ChatUtil.java
+++ b/src/main/java/WayofTime/bloodmagic/util/ChatUtil.java
@@ -224,7 +224,6 @@ public class ChatUtil
      */
     public static class PacketNoSpamChat implements IMessage
     {
-
         private ITextComponent[] chatLines;
 
         public PacketNoSpamChat()
@@ -260,7 +259,6 @@ public class ChatUtil
 
         public static class Handler implements IMessageHandler<PacketNoSpamChat, IMessage>
         {
-
             @Override
             public IMessage onMessage(PacketNoSpamChat message, MessageContext ctx)
             {
diff --git a/src/main/java/WayofTime/bloodmagic/util/handler/EventHandler.java b/src/main/java/WayofTime/bloodmagic/util/handler/EventHandler.java
index f13c1bc6..b794ebc2 100644
--- a/src/main/java/WayofTime/bloodmagic/util/handler/EventHandler.java
+++ b/src/main/java/WayofTime/bloodmagic/util/handler/EventHandler.java
@@ -71,10 +71,7 @@ import WayofTime.bloodmagic.api.soul.EnumDemonWillType;
 import WayofTime.bloodmagic.api.soul.IDemonWill;
 import WayofTime.bloodmagic.api.soul.IDemonWillWeapon;
 import WayofTime.bloodmagic.api.soul.PlayerDemonWillHandler;
-import WayofTime.bloodmagic.api.util.helper.BindableHelper;
-import WayofTime.bloodmagic.api.util.helper.NBTHelper;
-import WayofTime.bloodmagic.api.util.helper.NetworkHelper;
-import WayofTime.bloodmagic.api.util.helper.PlayerHelper;
+import WayofTime.bloodmagic.api.util.helper.*;
 import WayofTime.bloodmagic.block.BlockAltar;
 import WayofTime.bloodmagic.demonAura.PosXY;
 import WayofTime.bloodmagic.demonAura.WillChunk;
@@ -83,7 +80,6 @@ import WayofTime.bloodmagic.entity.projectile.EntitySentientArrow;
 import WayofTime.bloodmagic.item.ItemAltarMaker;
 import WayofTime.bloodmagic.item.ItemExperienceBook;
 import WayofTime.bloodmagic.item.ItemInscriptionTool;
-import WayofTime.bloodmagic.item.ItemUpgradeTome;
 import WayofTime.bloodmagic.item.armour.ItemLivingArmour;
 import WayofTime.bloodmagic.item.armour.ItemSentientArmour;
 import WayofTime.bloodmagic.item.gear.ItemPackSacrifice;
@@ -356,7 +352,7 @@ public class EventHandler
                 int totalLP = Math.round(damageDone * ConfigHandler.sacrificialPackConversion);
 
                 if (shouldSyphon)
-                    pack.addLP(player.getItemStackFromSlot(EntityEquipmentSlot.CHEST), totalLP);
+                    ItemHelper.LPContainer.addLPToItem(player.getItemStackFromSlot(EntityEquipmentSlot.CHEST), totalLP, pack.CAPACITY);
             }
         }
     }
@@ -370,8 +366,8 @@ public class EventHandler
             {
                 ItemStack output = new ItemStack(ModItems.upgradeTome);
                 output = NBTHelper.checkNBT(output);
-                ItemUpgradeTome.setKey(output, Constants.Mod.MODID + ".upgrade.revealing");
-                ItemUpgradeTome.setLevel(output, 1);
+                ItemHelper.LivingUpgrades.setKey(output, Constants.Mod.MODID + ".upgrade.revealing");
+                ItemHelper.LivingUpgrades.setLevel(output, 1);
                 event.setCost(1);
 
                 event.setOutput(output);
@@ -382,16 +378,16 @@ public class EventHandler
 
         if (event.getLeft().getItem() == ModItems.upgradeTome && event.getRight().getItem() == ModItems.upgradeTome)
         {
-            LivingArmourUpgrade leftUpgrade = ItemUpgradeTome.getUpgrade(event.getLeft());
-            if (leftUpgrade != null && ItemUpgradeTome.getKey(event.getLeft()).equals(ItemUpgradeTome.getKey(event.getRight())))
+            LivingArmourUpgrade leftUpgrade = ItemHelper.LivingUpgrades.getUpgrade(event.getLeft());
+            if (leftUpgrade != null && ItemHelper.LivingUpgrades.getKey(event.getLeft()).equals(ItemHelper.LivingUpgrades.getKey(event.getRight())))
             {
-                int leftLevel = ItemUpgradeTome.getLevel(event.getLeft());
-                int rightLevel = ItemUpgradeTome.getLevel(event.getRight());
+                int leftLevel = ItemHelper.LivingUpgrades.getLevel(event.getLeft());
+                int rightLevel = ItemHelper.LivingUpgrades.getLevel(event.getRight());
 
                 if (leftLevel == rightLevel && leftLevel < leftUpgrade.getMaxTier() - 1)
                 {
                     ItemStack outputStack = event.getLeft().copy();
-                    ItemUpgradeTome.setLevel(outputStack, leftLevel + 1);
+                    ItemHelper.LivingUpgrades.setLevel(outputStack, leftLevel + 1);
                     event.setCost(leftLevel + 2);
 
                     event.setOutput(outputStack);
@@ -403,10 +399,10 @@ public class EventHandler
 
         if (event.getLeft().getItem() instanceof IUpgradeTrainer && event.getRight().getItem() == ModItems.upgradeTome)
         {
-            LivingArmourUpgrade rightUpgrade = ItemUpgradeTome.getUpgrade(event.getRight());
+            LivingArmourUpgrade rightUpgrade = ItemHelper.LivingUpgrades.getUpgrade(event.getRight());
             if (rightUpgrade != null)
             {
-                String key = ItemUpgradeTome.getKey(event.getRight());
+                String key = ItemHelper.LivingUpgrades.getKey(event.getRight());
                 ItemStack outputStack = event.getLeft().copy();
                 List<String> keyList = new ArrayList<String>();
                 keyList.add(key);