/**
   * Will render the specified entity at the specified partial tick time. Args: entity,
   * partialTickTime
   */
  public void renderEntity(Entity par1Entity, float par2) {
    if (par1Entity.ticksExisted == 0) {
      par1Entity.lastTickPosX = par1Entity.posX;
      par1Entity.lastTickPosY = par1Entity.posY;
      par1Entity.lastTickPosZ = par1Entity.posZ;
    }

    double d0 =
        par1Entity.lastTickPosX + (par1Entity.posX - par1Entity.lastTickPosX) * (double) par2;
    double d1 =
        par1Entity.lastTickPosY + (par1Entity.posY - par1Entity.lastTickPosY) * (double) par2;
    double d2 =
        par1Entity.lastTickPosZ + (par1Entity.posZ - par1Entity.lastTickPosZ) * (double) par2;
    float f1 =
        par1Entity.prevRotationYaw + (par1Entity.rotationYaw - par1Entity.prevRotationYaw) * par2;
    int i = par1Entity.getBrightnessForRender(par2);

    if (par1Entity.isBurning()) {
      i = 15728880;
    }

    int j = i % 65536;
    int k = i / 65536;
    OpenGlHelper.setLightmapTextureCoords(
        OpenGlHelper.lightmapTexUnit, (float) j / 1.0F, (float) k / 1.0F);
    GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
    this.renderEntityWithPosYaw(
        par1Entity, d0 - renderPosX, d1 - renderPosY, d2 - renderPosZ, f1, par2);
  }
  @Override
  public void updateWeather() {
    super.updateWeather();

    if (!this.worldObj.isRemote) {
      if (this.dataNotLoaded) {
        this.savefile = OrbitSpinSaveData.initWorldData(this.worldObj);
        this.readFromNBT(this.savefile.datacompound);
        if (ConfigManagerCore.enableDebug)
          System.out.println(
              "Loading data from save: " + this.savefile.datacompound.getFloat("omegaSky"));
        this.dataNotLoaded = false;
      }

      if (this.doSpinning) {
        boolean updateNeeded = true;
        if (this.angularVelocityTarget < this.angularVelocityRadians) {
          float newAngle = this.angularVelocityRadians - this.angularVelocityAccel;
          if (newAngle < this.angularVelocityTarget) {
            newAngle = this.angularVelocityTarget;
          }
          this.setSpinRate(newAngle);
          this.thrustersFiring = true;
        } else if (this.angularVelocityTarget > this.angularVelocityRadians) {
          float newAngle = this.angularVelocityRadians + this.angularVelocityAccel;
          if (newAngle > this.angularVelocityTarget) {
            newAngle = this.angularVelocityTarget;
          }
          this.setSpinRate(newAngle);
          this.thrustersFiring = true;
        } else if (this.thrustersFiring) {
          this.thrustersFiring = false;
        } else {
          updateNeeded = false;
        }

        if (updateNeeded) {
          this.writeToNBT(this.savefile.datacompound);
          this.savefile.markDirty();

          List<Object> objList = new ArrayList<Object>();
          objList.add(Float.valueOf(this.angularVelocityRadians));
          objList.add(Boolean.valueOf(this.thrustersFiring));
          GalacticraftCore.packetPipeline.sendToDimension(
              new PacketSimple(EnumSimplePacket.C_UPDATE_STATION_SPIN, objList),
              this.spaceStationDimensionID);
        }

        // Update entity positions if in freefall
        this.loadedEntities.clear();
        this.loadedEntities.addAll(this.worldObj.loadedEntityList);
        for (Entity e : this.loadedEntities) {
          if ((e instanceof EntityItem
                  || e instanceof EntityLivingBase && !(e instanceof EntityPlayer)
                  || e instanceof EntityTNTPrimed
                  || e instanceof EntityFallingBlock)
              && !e.onGround) {
            boolean freefall = true;
            if (e.boundingBox.maxX >= this.ssBoundsMinX
                && e.boundingBox.minX <= this.ssBoundsMaxX
                && e.boundingBox.maxY >= this.ssBoundsMinY
                && e.boundingBox.minY <= this.ssBoundsMaxY
                && e.boundingBox.maxZ >= this.ssBoundsMinZ
                && e.boundingBox.minZ <= this.ssBoundsMaxZ) {
              // Entity is somewhere within the space station boundaries

              // Check if the entity's bounding box is in the same block coordinates as any
              // non-vacuum block (including torches etc)
              // If so, it's assumed the entity has something close enough to catch onto, so is not
              // in freefall
              // Note: breatheable air here means the entity is definitely not in freefall
              int xmx = MathHelper.floor_double(e.boundingBox.maxX + 0.2D);
              int ym = MathHelper.floor_double(e.boundingBox.minY - 0.1D);
              int yy = MathHelper.floor_double(e.boundingBox.maxY + 0.1D);
              int zm = MathHelper.floor_double(e.boundingBox.minZ - 0.2D);
              int zz = MathHelper.floor_double(e.boundingBox.maxZ + 0.2D);
              BLOCKCHECK:
              for (int x = MathHelper.floor_double(e.boundingBox.minX - 0.2D); x <= xmx; x++) {
                for (int y = ym; y <= yy; y++) {
                  for (int z = zm; z <= zz; z++) {
                    if (this.worldObj.blockExists(x, y, z)
                        && this.worldObj.getBlock(x, y, z) != Blocks.air) {
                      freefall = false;
                      break BLOCKCHECK;
                    }
                  }
                }
              }
            }

            if (freefall) {
              // Do the rotation
              if (this.angularVelocityRadians != 0F) {
                float angle;
                final double xx = e.posX - this.spinCentreX;
                final double zz = e.posZ - this.spinCentreZ;
                double arc = Math.sqrt(xx * xx + zz * zz);
                if (xx == 0D) {
                  angle = zz > 0 ? 3.141592536F / 2 : -3.141592536F / 2;
                } else {
                  angle = (float) Math.atan(zz / xx);
                }
                if (xx < 0D) {
                  angle += 3.141592536F;
                }
                angle += this.angularVelocityRadians / 3F;
                arc = arc * this.angularVelocityRadians;
                final double offsetX = -arc * MathHelper.sin(angle);
                final double offsetZ = arc * MathHelper.cos(angle);
                e.posX += offsetX;
                e.posZ += offsetZ;
                e.lastTickPosX += offsetX;
                e.lastTickPosZ += offsetZ;

                // Rotated into an unloaded chunk (probably also drifted out to there): byebye
                if (!this.worldObj.blockExists(
                    MathHelper.floor_double(e.posX), 64, MathHelper.floor_double(e.posZ))) {
                  e.setDead();
                }

                e.boundingBox.offset(offsetX, 0.0D, offsetZ);
                // TODO check for block collisions here - if so move the entity appropriately and
                // apply fall damage
                // Moving the entity = slide along / down
                e.rotationYaw += this.skyAngularVelocity;
                while (e.rotationYaw > 360F) {
                  e.rotationYaw -= 360F;
                }
              }

              // Undo deceleration
              if (e instanceof EntityLivingBase) {
                e.motionX /= 0.91F;
                e.motionZ /= 0.91F;
                if (e instanceof EntityFlying) {
                  e.motionY /= 0.91F;
                } else if (e instanceof EntityFallingBlock) {
                  e.motionY /= 0.9800000190734863D;
                  // e.motionY += 0.03999999910593033D;
                  // e.posY += 0.03999999910593033D;
                  // e.lastTickPosY += 0.03999999910593033D;
                } else {
                  e.motionY /= 0.9800000190734863D;
                }
              } else {
                e.motionX /= 0.9800000190734863D;
                e.motionY /= 0.9800000190734863D;
                e.motionZ /= 0.9800000190734863D;
              }
            }
          }
        }
      }
    }
  }