/**
   * Checks to see if the situation for firing the laser exists... and changes the state accordingly
   */
  public void checkCanRun() {
    // Laser requires lense, redstone power, not be jammed, and be in orbit and energy to function
    if (!worldObj.isBlockIndirectlyGettingPowered(xCoord, yCoord, zCoord)
        || glassPanel == null
        || storage.getEnergyStored()
            == 0 /*|| !(this.worldObj.provider instanceof IOrbitDimension)*/) {
      if (laserSat.isAlive()) {
        laserSat.deactivateLaser();
      }

      isRunning = false;
    } else if (!laserSat.isAlive()
        && !finished
        && !laserSat.getJammed()
        && worldObj.isBlockIndirectlyGettingPowered(xCoord, yCoord, zCoord)
        && canMachineSeeEarth()) {

      // Laser will be on at this point
      int orbitDimId =
          0; // =
             // WorldUtil.getProviderForName(((IOrbitDimension)this.worldObj.provider).getPlanetToOrbit()).dimensionId;
      WorldServer orbitWorld = DimensionManager.getWorld(orbitDimId);

      if (ticket == null) {
        ticket =
            ForgeChunkManager.requestTicket(AdvancedRocketry.instance, this.worldObj, Type.NORMAL);
        if (ticket != null)
          ForgeChunkManager.forceChunk(
              ticket,
              new ChunkCoordIntPair(
                  this.xCoord / 16 - (this.xCoord < 0 ? 1 : 0),
                  this.zCoord / 16 - (this.zCoord < 0 ? 1 : 0)));
      }

      isRunning = laserSat.activateLaser(orbitWorld, laserX, laserZ);
    }

    if (!this.worldObj.isRemote)
      PacketHandler.sendToNearby(
          new PacketMachine(this, (byte) 2),
          this.xCoord,
          this.yCoord,
          this.zCoord,
          128,
          this.worldObj.provider.dimensionId);
  }
  @Override
  public void updateEntity() {
    // TODO: drain energy
    if (!this.worldObj.isRemote) {
      tickSinceLastOperation++;
    }

    if (hasPowerForOperation()
        && isReadyForOperation()
        && laserSat.isAlive()
        && !laserSat.getJammed()) {
      laserSat.performOperation();

      storage.setEnergyStored(storage.getEnergyStored() - POWER_PER_OPERATION);
      tickSinceLastOperation = 0;
    }

    if (laserSat.isFinished()) {
      this.isRunning = false;
      laserSat.deactivateLaser();

      if (!laserSat.getJammed()) {
        if (mode == MODE.SINGLE) finished = true;

        if (this.worldObj.getBlockPowerInput(this.xCoord, this.yCoord, this.zCoord) != 0) {
          if (mode == MODE.LINE_X) {
            this.laserX += 3;
          } else if (mode == MODE.LINE_Z) {
            this.laserZ += 3;
          } else if (mode == MODE.SPIRAL) {
            numSteps++;
            if (radius < numSteps) {
              numSteps = 0;
              if (prevDir == ForgeDirection.NORTH) prevDir = ForgeDirection.EAST;
              else if (prevDir == ForgeDirection.EAST) {
                prevDir = ForgeDirection.SOUTH;
                radius++;
              } else if (prevDir == ForgeDirection.SOUTH) prevDir = ForgeDirection.WEST;
              else {
                prevDir = ForgeDirection.NORTH;
                radius++;
              }
            }

            this.laserX += 3 * prevDir.offsetX;
            this.laserZ += 3 * prevDir.offsetZ;
          }
        }
        // TODO: unneeded?
        checkCanRun();
      }
    }
  }