@Override
  public void onUpdate() {
    super.onUpdate();

    if (worldObj.isRemote && updateDelay > 0) {
      updateDelay--;

      if (updateDelay == 0 && clientActive != isActive) {
        isActive = clientActive;
        MekanismUtils.updateBlock(worldObj, xCoord, yCoord, zCoord);
      }
    }

    if (!worldObj.isRemote) {
      if (updateDelay > 0) {
        updateDelay--;

        if (updateDelay == 0 && clientActive != isActive) {
          Mekanism.packetHandler.sendToReceivers(
              new TileEntityMessage(Coord4D.get(this), getNetworkedData(new ArrayList())),
              new Range4D(Coord4D.get(this)));
        }
      }
    }
  }
  @Override
  public void writeToNBT(NBTTagCompound nbtTags) {
    super.writeToNBT(nbtTags);

    nbtTags.setInteger("operatingTicks", operatingTicks);
    nbtTags.setBoolean("isActive", isActive);
    nbtTags.setInteger("controlType", controlType.ordinal());
  }
  @Override
  public void readFromNBT(NBTTagCompound nbtTags) {
    super.readFromNBT(nbtTags);

    operatingTicks = nbtTags.getInteger("operatingTicks");
    clientActive = isActive = nbtTags.getBoolean("isActive");
    controlType = RedstoneControl.values()[nbtTags.getInteger("controlType")];
  }
  @Override
  public ArrayList getNetworkedData(ArrayList data) {
    super.getNetworkedData(data);

    data.add(operatingTicks);
    data.add(isActive);
    data.add(ticksRequired);
    data.add(controlType.ordinal());

    return data;
  }
  @Override
  public void handlePacketData(ByteBuf dataStream) {
    super.handlePacketData(dataStream);

    operatingTicks = dataStream.readInt();
    clientActive = dataStream.readBoolean();
    ticksRequired = dataStream.readInt();
    controlType = RedstoneControl.values()[dataStream.readInt()];

    if (updateDelay == 0 && clientActive != isActive) {
      updateDelay = general.UPDATE_DELAY;
      isActive = clientActive;
      MekanismUtils.updateBlock(worldObj, xCoord, yCoord, zCoord);
    }
  }
  @Override
  public void recalculateUpgradables(Upgrade upgrade) {
    super.recalculateUpgradables(upgrade);

    switch (upgrade) {
      case SPEED:
        ticksRequired = MekanismUtils.getTicks(this, BASE_TICKS_REQUIRED);
        energyPerTick = MekanismUtils.getEnergyPerTick(this, BASE_ENERGY_PER_TICK);
        break;
      case ENERGY:
        energyPerTick = MekanismUtils.getEnergyPerTick(this, BASE_ENERGY_PER_TICK);
        maxEnergy = MekanismUtils.getMaxEnergy(this, BASE_MAX_ENERGY);
        break;
      default:
        break;
    }
  }