@Override
  protected void setNoPowerRequests() {
    currentConsumedPower = 0;
    currentMainPowerTypes = PowerTypes.NONE;

    super.setNoPowerRequests();
  }
  @Override
  public void readFromNBT(NBTTagCompound nbttagcompound) {
    super.readFromNBT(nbttagcompound);

    if (!nbttagcompound.hasKey("altarData")) return;

    NBTTagCompound altarCompound = nbttagcompound.getCompoundTag("altarData");

    NBTTagList allAddedItems =
        altarCompound.getTagList("allAddedItems", Constants.NBT.TAG_COMPOUND);
    NBTTagList currentAddedItems =
        altarCompound.getTagList("currentAddedItems", Constants.NBT.TAG_COMPOUND);

    this.isCrafting = altarCompound.getBoolean("isCrafting");
    this.currentKey = altarCompound.getInteger("currentKey");
    this.currentSpellName = altarCompound.getString("currentSpellName");

    if (altarCompound.hasKey("phylactery")) {
      NBTTagCompound phylactery = altarCompound.getCompoundTag("phylactery");
      if (phylactery != null) this.addedPhylactery = ItemStack.loadItemStackFromNBT(phylactery);
    }

    if (altarCompound.hasKey("catalyst")) {
      NBTTagCompound catalyst = altarCompound.getCompoundTag("catalyst");
      if (catalyst != null) this.addedBindingCatalyst = ItemStack.loadItemStackFromNBT(catalyst);
    }

    this.allAddedItems.clear();
    for (int i = 0; i < allAddedItems.tagCount(); ++i) {
      NBTTagCompound addedItem = (NBTTagCompound) allAddedItems.getCompoundTagAt(i);
      if (addedItem == null) continue;
      ItemStack stack = ItemStack.loadItemStackFromNBT(addedItem);
      if (stack == null) continue;
      this.allAddedItems.add(stack);
    }

    this.currentAddedItems.clear();
    for (int i = 0; i < currentAddedItems.tagCount(); ++i) {
      NBTTagCompound addedItem = (NBTTagCompound) currentAddedItems.getCompoundTagAt(i);
      if (addedItem == null) continue;
      ItemStack stack = ItemStack.loadItemStackFromNBT(addedItem);
      if (stack == null) continue;
      this.currentAddedItems.add(stack);
    }

    this.spellDef.clear();
    for (ArrayList<KeyValuePair<ISpellPart, byte[]>> groups : shapeGroups) groups.clear();

    NBTTagCompound currentSpellDef = altarCompound.getCompoundTag("spellDef");
    this.spellDef.addAll(NBTToISpellPartList(currentSpellDef));

    NBTTagList currentShapeGroups =
        altarCompound.getTagList("shapeGroups", Constants.NBT.TAG_COMPOUND);

    for (int i = 0; i < currentShapeGroups.tagCount(); ++i) {
      NBTTagCompound compound = (NBTTagCompound) currentShapeGroups.getCompoundTagAt(i);
      shapeGroups.get(i).addAll(NBTToISpellPartList(compound));
    }
  }
  @Override
  public void updateEntity() {
    super.updateEntity();

    if (worldObj.isRemote) {
      if (particleCounter == 0 || particleCounter++ > 1000) {
        particleCounter = 1;
        radiant =
            (AMParticle)
                AMCore.proxy.particleManager.spawn(
                    worldObj, "radiant", xCoord + 0.5f, yCoord + 0.5f, zCoord + 0.5f);
        if (radiant != null) {
          radiant.setMaxAge(1000);
          radiant.setRGBColorF(0.1f, 0.1f, 0.1f);
          radiant.setParticleScale(0.1f);
          radiant.AddParticleController(new ParticleHoldPosition(radiant, 1000, 1, false));
        }
      }
    } else {
      if (!isActive()) {
        if (inventory[0] != null) {
          current_deconstruction_time = 1;
        }
      } else {
        if (inventory[0] == null) {
          current_deconstruction_time = 0;
          deconstructionRecipe = null;
          worldObj.markBlockForUpdate(xCoord, yCoord, zCoord);
        } else {
          if (PowerNodeRegistry.For(worldObj)
              .checkPower(this, PowerTypes.DARK, DECONSTRUCTION_POWER_COST)) {
            if (deconstructionRecipe == null) {
              if (!getDeconstructionRecipe()) {
                transferOrEjectItem(inventory[0]);
                setInventorySlotContents(0, null);
              }
            } else {
              if (current_deconstruction_time++ >= DECONSTRUCTION_TIME) {
                for (ItemStack stack : deconstructionRecipe) {
                  transferOrEjectItem(stack);
                }
                deconstructionRecipe = null;
                decrStackSize(0, 1);
                current_deconstruction_time = 0;
              }
              if (current_deconstruction_time % 10 == 0)
                worldObj.markBlockForUpdate(xCoord, yCoord, zCoord);
            }
            PowerNodeRegistry.For(worldObj)
                .consumePower(this, PowerTypes.DARK, DECONSTRUCTION_POWER_COST);
          }
        }
      }
    }
  }
  @Override
  public void onDeath(World world) {
    AMCore.instance.proxy.blocks.removeKeystonePortal(
        xCoord, yCoord, zCoord, worldObj.provider.dimensionId);

    if (!world.isRemote) {
      AMChunkLoader.INSTANCE.releaseStaticChunkLoad(
          this.getClass(), this.xCoord, this.yCoord, this.zCoord, this.worldObj);
    }

    super.onDeath(world);
  }
  @Override
  public void writeToNBT(NBTTagCompound nbttagcompound) {
    super.writeToNBT(nbttagcompound);

    NBTTagCompound altarCompound = new NBTTagCompound();
    altarCompound.setBoolean("isCrafting", this.isCrafting);
    altarCompound.setInteger("currentKey", this.currentKey);
    altarCompound.setString("currentSpellName", currentSpellName);

    NBTTagList allAddedItemsList = new NBTTagList();
    for (ItemStack stack : allAddedItems) {
      NBTTagCompound addedItem = new NBTTagCompound();
      stack.writeToNBT(addedItem);
      allAddedItemsList.appendTag(addedItem);
    }

    altarCompound.setTag("allAddedItems", allAddedItemsList);

    NBTTagList currentAddedItemsList = new NBTTagList();
    for (ItemStack stack : currentAddedItems) {
      NBTTagCompound addedItem = new NBTTagCompound();
      stack.writeToNBT(addedItem);
      currentAddedItemsList.appendTag(addedItem);
    }

    altarCompound.setTag("currentAddedItems", currentAddedItemsList);

    if (addedPhylactery != null) {
      NBTTagCompound phylactery = new NBTTagCompound();
      addedPhylactery.writeToNBT(phylactery);
      altarCompound.setTag("phylactery", phylactery);
    }

    if (addedBindingCatalyst != null) {
      NBTTagCompound catalyst = new NBTTagCompound();
      addedBindingCatalyst.writeToNBT(catalyst);
      altarCompound.setTag("catalyst", catalyst);
    }

    NBTTagList shapeGroupData = new NBTTagList();
    for (ArrayList<KeyValuePair<ISpellPart, byte[]>> list : shapeGroups) {
      shapeGroupData.appendTag(ISpellPartListToNBT(list));
    }
    altarCompound.setTag("shapeGroups", shapeGroupData);

    NBTTagCompound spellDefSave = ISpellPartListToNBT(this.spellDef);
    altarCompound.setTag("spellDef", spellDefSave);

    nbttagcompound.setTag("altarData", altarCompound);
  }
 @Override
 public void readFromNBT(NBTTagCompound nbttagcompound) {
   super.readFromNBT(nbttagcompound);
   NBTTagList nbttaglist =
       nbttagcompound.getTagList("AstralBarrierInventory", Constants.NBT.TAG_COMPOUND);
   inventory = new ItemStack[getSizeInventory()];
   for (int i = 0; i < nbttaglist.tagCount(); i++) {
     String tag = String.format("ArrayIndex", i);
     NBTTagCompound nbttagcompound1 = (NBTTagCompound) nbttaglist.getCompoundTagAt(i);
     byte byte0 = nbttagcompound1.getByte(tag);
     if (byte0 >= 0 && byte0 < inventory.length) {
       inventory[byte0] = ItemStack.loadItemStackFromNBT(nbttagcompound1);
     }
   }
 }
  @Override
  public void writeToNBT(NBTTagCompound nbttagcompound) {
    super.writeToNBT(nbttagcompound);
    NBTTagList nbttaglist = new NBTTagList();
    for (int i = 0; i < inventory.length; i++) {
      if (inventory[i] != null) {
        String tag = String.format("ArrayIndex", i);
        NBTTagCompound nbttagcompound1 = new NBTTagCompound();
        nbttagcompound1.setByte(tag, (byte) i);
        inventory[i].writeToNBT(nbttagcompound1);
        nbttaglist.appendTag(nbttagcompound1);
      }
    }

    nbttagcompound.setTag("AstralBarrierInventory", nbttaglist);
  }
  @Override
  public void writeToNBT(NBTTagCompound nbttagcompound) {
    super.writeToNBT(nbttagcompound);
    NBTTagList nbttaglist = new NBTTagList();
    for (int i = 0; i < inventory.length; i++) {
      if (inventory[i] != null) {
        String tag = String.format("ArrayIndex", i);
        NBTTagCompound nbttagcompound1 = new NBTTagCompound();
        nbttagcompound1.setByte(tag, (byte) i);
        inventory[i].writeToNBT(nbttagcompound1);
        nbttaglist.appendTag(nbttagcompound1);
      }
    }

    nbttagcompound.setTag("DeconstructorInventory", nbttaglist);

    nbttagcompound.setInteger("DeconstructionTime", current_deconstruction_time);
  }
  @Override
  public void writeToNBT(NBTTagCompound nbttagcompound) {
    super.writeToNBT(nbttagcompound);
    NBTTagList nbttaglist = new NBTTagList();
    for (int i = 0; i < inventory.length; i++) {
      if (inventory[i] != null) {
        String tag = String.format("ArrayIndex", i);
        NBTTagCompound nbttagcompound1 = new NBTTagCompound();
        nbttagcompound1.setByte(tag, (byte) i);
        inventory[i].writeToNBT(nbttagcompound1);
        nbttaglist.appendTag(nbttagcompound1);
      }
    }

    nbttagcompound.setInteger("keystone_receptacle_dimension_id", worldObj.provider.dimensionId);
    nbttagcompound.setTag("KeystoneRecepticleInventory", nbttaglist);
    nbttagcompound.setBoolean("isActive", this.isActive);
  }
  @Override
  public void readFromNBT(NBTTagCompound nbttagcompound) {
    super.readFromNBT(nbttagcompound);
    NBTTagList nbttaglist =
        nbttagcompound.getTagList("DeconstructorInventory", Constants.NBT.TAG_COMPOUND);
    inventory = new ItemStack[getSizeInventory()];
    for (int i = 0; i < nbttaglist.tagCount(); i++) {
      String tag = String.format("ArrayIndex", i);
      NBTTagCompound nbttagcompound1 = (NBTTagCompound) nbttaglist.getCompoundTagAt(i);
      byte byte0 = nbttagcompound1.getByte(tag);
      if (byte0 >= 0 && byte0 < inventory.length) {
        inventory[byte0] = ItemStack.loadItemStackFromNBT(nbttagcompound1);
      }
    }

    this.current_deconstruction_time = nbttagcompound.getInteger("DeconstructionTime");

    if (current_deconstruction_time > 0) getDeconstructionRecipe();
  }
  @Override
  public void readFromNBT(NBTTagCompound nbttagcompound) {
    super.readFromNBT(nbttagcompound);
    NBTTagList nbttaglist =
        nbttagcompound.getTagList("KeystoneRecepticleInventory", Constants.NBT.TAG_COMPOUND);
    inventory = new ItemStack[getSizeInventory()];
    for (int i = 0; i < nbttaglist.tagCount(); i++) {
      String tag = String.format("ArrayIndex", i);
      NBTTagCompound nbttagcompound1 = (NBTTagCompound) nbttaglist.getCompoundTagAt(i);
      byte byte0 = nbttagcompound1.getByte(tag);
      if (byte0 >= 0 && byte0 < inventory.length) {
        inventory[byte0] = ItemStack.loadItemStackFromNBT(nbttagcompound1);
      }
    }
    AMCore.instance.proxy.blocks.registerKeystonePortal(
        xCoord, yCoord, zCoord, nbttagcompound.getInteger("keystone_receptacle_dimension_id"));

    this.isActive = nbttagcompound.getBoolean("isActive");
  }
  @Override
  public void updateEntity() {
    super.updateEntity();

    AxisAlignedBB bb =
        AxisAlignedBB.getBoundingBox(
            xCoord + 0.3, yCoord - 3, zCoord + 0.3, xCoord + 0.7, yCoord, zCoord + 0.7);
    ArrayList<Entity> entities =
        (ArrayList<Entity>) worldObj.getEntitiesWithinAABB(EntityLivingBase.class, bb);

    if (this.isActive) {
      surroundingCheckTicks--;
      if (surroundingCheckTicks <= 0) {
        surroundingCheckTicks = 20;
        checkSurroundings();
      }
      if (entities.size() == 1) {
        doTeleport(entities.get(0));
      }
    } else {
      if (entities.size() == 1 && worldObj.canBlockSeeTheSky(xCoord, yCoord, zCoord)) {
        Entity entity = entities.get(0);
        if (entity instanceof EntityPlayer) {
          EntityPlayer player = (EntityPlayer) entity;
          if (player.isPotionActive(BuffList.haste)
              && player.isPotionActive(Potion.moveSpeed.id)
              && player.isSprinting()) {
            // if (worldObj.isRemote)
            // player.addStat(AMCore.achievements.EightyEightMilesPerHour, 1);
            this.key = 0;
            if (!worldObj.isRemote) {
              EntityLightningBolt elb = new EntityLightningBolt(worldObj, xCoord, yCoord, zCoord);
              worldObj.spawnEntityInWorld(elb);
            }
            doTeleport(player);
          }
        }
      }
    }
  }
  @Override
  public void updateEntity() {
    super.updateEntity();

    int radius = getRadius();

    if (IsActive()) {
      PowerNodeRegistry.For(this.worldObj)
          .consumePower(
              this, PowerNodeRegistry.For(worldObj).getHighestPowerType(this), 0.35f * radius);
    }

    if (worldObj.isRemote) {
      if (IsActive()) {
        if (displayAura) {
          AMParticle effect =
              (AMParticle)
                  AMCore.instance.proxy.particleManager.spawn(
                      worldObj, "symbols", xCoord, yCoord + 0.5, zCoord);
          if (effect != null) {
            effect.setIgnoreMaxAge(false);
            effect.setMaxAge(100);
            effect.setParticleScale(0.5f);
            effect.AddParticleController(
                new ParticleOrbitPoint(effect, xCoord + 0.5, yCoord + 0.5, zCoord + 0.5, 1, false)
                    .SetOrbitSpeed(0.03)
                    .SetTargetDistance(radius));
          }
        }

        particleTickCounter++;

        if (particleTickCounter >= 15) {

          particleTickCounter = 0;

          String particleName = "";
          AMParticle effect =
              (AMParticle)
                  AMCore.instance.proxy.particleManager.spawn(
                      worldObj,
                      "sparkle",
                      xCoord + 0.5,
                      yCoord + 0.1 + rand.nextDouble() * 0.5,
                      zCoord + 0.5);
          if (effect != null) {
            effect.setIgnoreMaxAge(false);
            effect.setMaxAge(100);
            effect.setParticleScale(0.5f);
            float color = rand.nextFloat() * 0.2f + 0.8f;
            effect.AddParticleController(
                new ParticleOrbitPoint(effect, xCoord + 0.5, yCoord + 0.5, zCoord + 0.5, 1, false)
                    .SetOrbitSpeed(0.005)
                    .SetTargetDistance(rand.nextDouble() * 0.6 - 0.3));
            effect.AddParticleController(new ParticleHoldPosition(effect, 80, 2, true));
            effect.AddParticleController(new ParticleFadeOut(effect, 3, false).setFadeSpeed(0.05f));
          }
        }
      }
    }
  }
  @Override
  public void updateEntity() {
    super.updateEntity();
    this.ticksExisted++;

    checkStructure();
    checkForStartCondition();
    updateLecternInformation();
    if (isCrafting) {
      checkForEndCondition();
      updatePowerRequestData();
      if (!worldObj.isRemote
          && !currentDefinitionIsWithinStructurePower()
          && this.ticksExisted > 100) {
        worldObj.newExplosion(null, xCoord + 0.5, yCoord - 1.5, zCoord + 0.5, 5, false, true);
        setCrafting(false);
        return;
      }
      if (worldObj.isRemote && checkCounter == 1) {
        AMCore.proxy.particleManager.RibbonFromPointToPoint(
            worldObj,
            xCoord + 0.5,
            yCoord - 2,
            zCoord + 0.5,
            xCoord + 0.5,
            yCoord - 3,
            zCoord + 0.5);
      }
      List<EntityItem> components = lookForValidItems();
      ItemStack stack = getNextPlannedItem();
      for (EntityItem item : components) {
        if (item.isDead) continue;
        ItemStack entityItemStack = item.getEntityItem();
        if (stack != null && compareItemStacks(stack, entityItemStack)) {
          if (!worldObj.isRemote) {
            updateCurrentRecipe(item);
            item.setDead();
          } else {
            worldObj.playSound(
                xCoord,
                yCoord,
                zCoord,
                "arsmagica2:misc.craftingaltar.component_added",
                1.0f,
                0.4f + worldObj.rand.nextFloat() * 0.6f,
                false);
            for (int i = 0; i < 5 * AMCore.config.getGFXLevel(); ++i) {
              AMParticle particle =
                  (AMParticle)
                      AMCore.proxy.particleManager.spawn(
                          worldObj, "radiant", item.posX, item.posY, item.posZ);
              if (particle != null) {
                particle.setMaxAge(40);
                particle.AddParticleController(
                    new ParticleMoveOnHeading(
                        particle,
                        worldObj.rand.nextFloat() * 360,
                        worldObj.rand.nextFloat() * 360,
                        0.01f,
                        1,
                        false));
                particle.AddParticleController(
                    new ParticleFadeOut(particle, 1, false)
                        .setFadeSpeed(0.05f)
                        .setKillParticleOnFinish(true));
                particle.setParticleScale(0.02f);
                particle.setRGBColorF(
                    worldObj.rand.nextFloat(),
                    worldObj.rand.nextFloat(),
                    worldObj.rand.nextFloat());
              }
            }
          }
        }
      }
    }
  }