@Override
  public void outputEnergy(int amount, ForgeDirection side) {
    int xo = xCoord + side.offsetX;
    int yo = yCoord + side.offsetY;
    int zo = zCoord + side.offsetZ;

    TileEntity t = worldObj.getBlockTileEntity(xo, yo, zo);

    if (t != null && t instanceof IEnergyHandler) {
      IEnergyHandler ieh = (IEnergyHandler) t;
      int amnt = ieh.receiveEnergy(side.getOpposite(), capacitor.extractEnergy(1000, true), false);
      capacitor.extractEnergy(amnt, false);
    }
  }
 @Override
 public int extractEnergy(EnumFacing from, int maxExtract, boolean simulate) {
   if (!m_ProvidesEnergy) {
     return 0;
   }
   return energyStorage.extractEnergy(maxExtract, simulate);
 }
  public void onStepped(Entity stepper) {
    if (worldObj.isRemote || link == null) return;

    if (here == null) here = Vector3.getNewVector().set(this);
    if (linkPos == null) {
      linkPos = Vector3.getNewVector().set(link.x, link.y, link.z);
    }

    double distSq = 0;
    long time = worldObj.getTotalWorldTime();
    long lastStepped = stepper.getEntityData().getLong("lastWarpPadUse");
    boolean tele =
        link != null
            && !link.isEmpty()
            && lastStepped + COOLDOWN <= time
            && (MAXRANGE < 0 || (distSq = here.distToSq(linkPos)) < MAXRANGE * MAXRANGE);
    if (tele && Config.instance.warpPadEnergy && !noEnergy) {
      int energy = (int) (distSq);
      tele = storage.extractEnergy(energy, false) == energy;

      if (!tele) {
        worldObj.playSoundEffect(
            getPos().getX(), getPos().getY(), getPos().getZ(), "note.bd", 1.0F, 1.0F);
        stepper.getEntityData().setLong("lastWarpPadUse", time);
      }
    }

    if (tele) {
      worldObj.playSoundEffect(
          getPos().getX(), getPos().getY(), getPos().getZ(), "mob.endermen.portal", 1.0F, 1.0F);
      PacketBuffer buff = new PacketBuffer(Unpooled.buffer());
      buff.writeByte(9);
      here.writeToBuff(buff);
      MessageClient packet = new MessageClient(buff);
      PokecubePacketHandler.sendToAllNear(packet, here, stepper.dimension, 20);
      stepper.getEntityData().setLong("lastWarpPadUse", time);
      TeleDest d = new TeleDest(link);
      Vector3 loc = d.getLoc();
      int dim = d.getDim();
      if (stepper instanceof EntityPlayer) {
        Transporter.teleportEntity(stepper, loc, dim, false);
      } else if (dim == d.getDim()) {
        stepper.setPositionAndUpdate(loc.x, loc.y, loc.z);
      } else {
        return;
      }
      worldObj.playSoundEffect(loc.x, loc.y, loc.z, "mob.endermen.portal", 1.0F, 1.0F);
      buff = new PacketBuffer(Unpooled.buffer());
      buff.writeByte(9);
      linkPos.writeToBuff(buff);
      packet = new MessageClient(buff);
      PokecubePacketHandler.sendToAllNear(packet, linkPos, stepper.dimension, 20);
    }
  }
  @Override
  public void updateEntity() {
    super.updateEntity();
    getHandler().updateEntity();

    // PUSH pressure
    // This had me busy for two days.
    TileEntity receiver =
        worldObj.getBlockTileEntity(
            xCoord + facing.offsetX, yCoord + facing.offsetY, zCoord + facing.offsetZ);
    if (receiver != null && receiver instanceof IEnergyHandler) {
      IEnergyHandler recv = (IEnergyHandler) receiver;
      int energyPushed =
          recv.receiveEnergy(
              facing.getOpposite(), storage.extractEnergy(Constants.MAX_TRANSFER_RF, true), true);

      if (energyPushed > 0) {
        recv.receiveEnergy(facing.getOpposite(), storage.extractEnergy(energyPushed, false), false);
      }
    }
  }
  @Override
  public void updateEntity() {
    if (!formed || pos != 17) return;

    if (!worldObj.isRemote) {
      boolean update = false;
      int prevAmount = tank2.getFluidAmount();
      boolean enabled;
      if (computerControlled) enabled = computerOn;
      else
        enabled =
            !worldObj.isBlockIndirectlyGettingPowered(
                xCoord + (facing == 4 ? -1 : facing == 5 ? 1 : facing == 2 ? -2 : 2),
                yCoord + 1,
                zCoord + (facing == 2 ? -1 : facing == 3 ? 1 : facing == 4 ? 2 : -2));
      if (enabled) {
        RefineryRecipe recipe = getRecipe(true);
        if (recipe != null) {
          int consumed = Config.getInt("refinery_consumption");
          if (energyStorage.extractEnergy(consumed, true) == consumed
              && tank2.fill(recipe.output.copy(), false) == recipe.output.amount) {
            int drain0 =
                tank0.getFluid().isFluidEqual(recipe.input0)
                    ? recipe.input0.amount
                    : recipe.input1.amount;
            int drain1 =
                tank0.getFluid().isFluidEqual(recipe.input0)
                    ? recipe.input1.amount
                    : recipe.input0.amount;
            if (tank0.getFluidAmount() >= drain0 && tank1.getFluidAmount() >= drain1) {
              energyStorage.extractEnergy(consumed, false);
              tank0.drain(drain0, true);
              tank1.drain(drain1, true);
              tank2.fill(recipe.output.copy(), true);
              update = true;
            }
          }
        }
      }
      if (tank2.getFluidAmount() > 0) {
        ItemStack filledContainer = Utils.fillFluidContainer(tank2, inventory[4], inventory[5]);
        if (filledContainer != null) {
          if (inventory[5] != null
              && OreDictionary.itemMatches(inventory[5], filledContainer, true))
            inventory[5].stackSize += filledContainer.stackSize;
          else if (inventory[5] == null) inventory[5] = filledContainer.copy();
          this.decrStackSize(4, filledContainer.stackSize);
          update = true;
        }
        if (tank2.getFluidAmount() > 0) {
          ForgeDirection f = ForgeDirection.getOrientation(facing);
          int out = Math.min(144, tank2.getFluidAmount());
          TileEntity te =
              Utils.getExistingTileEntity(
                  worldObj, xCoord + f.offsetX * 2, yCoord, zCoord + f.offsetZ * 2);
          if (te instanceof IFluidHandler
              && ((IFluidHandler) te).canFill(f.getOpposite(), tank2.getFluid().getFluid())) {
            int accepted =
                ((IFluidHandler) te)
                    .fill(f.getOpposite(), new FluidStack(tank2.getFluid().getFluid(), out), false);
            FluidStack drained = this.tank2.drain(accepted, true);
            ((IFluidHandler) te).fill(f.getOpposite(), drained, true);
          }
        }
      }
      if (tank2.getFluidAmount() != prevAmount) update = true;

      ItemStack emptyContainer = Utils.drainFluidContainer(tank0, inventory[0]);
      if (emptyContainer != null) {
        if (inventory[1] != null && OreDictionary.itemMatches(inventory[1], emptyContainer, true))
          inventory[1].stackSize += emptyContainer.stackSize;
        else if (inventory[1] == null) inventory[1] = emptyContainer.copy();
        this.decrStackSize(0, emptyContainer.stackSize);
        update = true;
      }
      emptyContainer = Utils.drainFluidContainer(tank1, inventory[2]);
      if (emptyContainer != null) {
        if (inventory[3] != null && OreDictionary.itemMatches(inventory[3], emptyContainer, true))
          inventory[3].stackSize += emptyContainer.stackSize;
        else if (inventory[3] == null) inventory[3] = emptyContainer.copy();
        this.decrStackSize(2, emptyContainer.stackSize);
        update = true;
      }

      if (update) {
        this.markDirty();
        worldObj.markBlockForUpdate(xCoord, yCoord, zCoord);
      }
    }
  }
 @Override
 public int useEnergy(int toUse, boolean simulate) {
   return capacitor.extractEnergy(toUse, simulate);
 }
 @Method(modid = "CoFHCore")
 @Override
 public int extractEnergy(ForgeDirection direction, int maxExtract, boolean simulate) {
   return storage.extractEnergy(storage.getMaxExtract(), simulate);
 }