@Override
  public void onUsingTick(ItemStack is, EntityPlayer ep, int count) {
    if (is.getItemDamage() > 0 && this.getWater(is) > 0) {
      double r = 1;
      double d = ReikaRandomHelper.getRandomPlusMinus(2.5, 2);
      Vec3 vec = ep.getLookVec();
      double dx = ep.posX + vec.xCoord * d;
      double dy = ep.posY + ep.getEyeHeight() + vec.yCoord * d;
      double dz = ep.posZ + vec.zCoord * d;
      if (count % TICK_PER_KJ == 0) {
        AxisAlignedBB box = AxisAlignedBB.getBoundingBox(dx, dy, dz, dx, dy, dz).expand(r, r, r);
        List<EntityRadiation> li = ep.worldObj.getEntitiesWithinAABB(EntityRadiation.class, box);
        for (EntityRadiation e : li) {
          e.clean();
        }
      }
      int n = ReikaRandomHelper.getRandomPlusMinus(8, 4);
      for (int i = 0; i < n; i++) {
        double v = ReikaRandomHelper.getRandomPlusMinus(0.1875, 0.0625);
        double vx = vec.xCoord * v;
        double vy = vec.yCoord * v;
        double vz = vec.zCoord * v;

        vx = ReikaRandomHelper.getRandomPlusMinus(vx, 0.001);
        vz = ReikaRandomHelper.getRandomPlusMinus(vz, 0.001);

        ReikaParticleHelper.RAIN.spawnAt(ep.worldObj, dx, dy, dz, vx, vy, vz);
      }
    }
  }
  @SideOnly(Side.CLIENT)
  private void spawnParticle(World world, int x, int y, int z) {
    int p = Minecraft.getMinecraft().gameSettings.particleSetting;
    if (rand.nextInt(1 + p / 2) == 0) {
      double d = 1.25;
      double rx = ReikaRandomHelper.getRandomPlusMinus(x + 0.5, d);
      double ry = ReikaRandomHelper.getRandomPlusMinus(y + 0.5, d);
      double rz = ReikaRandomHelper.getRandomPlusMinus(z + 0.5, d);
      EntityFlareFX fx = new EntityFlareFX(color, world, rx, ry, rz);
      Minecraft.getMinecraft().effectRenderer.addEffect(fx);
    }

    if (this.isEnhanced()) {
      int n = 2 + (int) Math.sin(Math.toRadians(this.getTicksExisted()));
      for (int i = 0; i < n; i++) {
        float s = (float) ReikaRandomHelper.getRandomPlusMinus(2D, 1);
        int l = 10 + rand.nextInt(50);
        EntityFloatingSeedsFX fx =
            new EntityFloatingSeedsFX(
                world,
                x + 0.5,
                y + 0.5,
                z + 0.5,
                rand.nextInt(360),
                ReikaRandomHelper.getRandomPlusMinus(0, 90));
        fx.fadeColors(ReikaColorAPI.mixColors(color.getColor(), 0xffffff, 0.375F), color.getColor())
            .setScale(s)
            .setLife(l)
            .setRapidExpand();
        fx.freedom *= 3;
        fx.velocity *= 3;
        Minecraft.getMinecraft().effectRenderer.addEffect(fx);
      }
    }
  }
Ejemplo n.º 3
0
 private void fightDecay(World world, int x, int y, int z) {
   if (MystObjects.decay != null) {
     int rx = ReikaRandomHelper.getRandomPlusMinus(x, 64);
     int rz = ReikaRandomHelper.getRandomPlusMinus(z, 64);
     ReikaChunkHelper.removeBlocksFromChunk(world, rx, rz, MystObjects.decay.blockID, -1);
   }
 }
 private void denyEntity(Entity e) {
   e.motionY = 1.5;
   e.fallDistance = Math.max(e.fallDistance, 500);
   e.addVelocity(
       ReikaRandomHelper.getRandomPlusMinus(0, 0.25),
       0,
       ReikaRandomHelper.getRandomPlusMinus(0, 0.25));
   ChromaSounds.POWERDOWN.playSound(e);
 }
 @SideOnly(Side.CLIENT)
 private void doFXClient() {
   for (int i = 0; i < 32; i++) {
     double x = ReikaRandomHelper.getRandomPlusMinus(xCoord + 0.5, 0.75);
     double y = ReikaRandomHelper.getRandomPlusMinus(yCoord + 0.5, 0.5);
     double z = ReikaRandomHelper.getRandomPlusMinus(zCoord + 0.5, 0.75);
     int l = ReikaRandomHelper.getRandomBetween(8, 30);
     EntityFX fx =
         new EntityBlurFX(worldObj, x, y, z).setColor(this.getRenderColor()).setLife(l);
     Minecraft.getMinecraft().effectRenderer.addEffect(fx);
   }
 }
    @SideOnly(Side.CLIENT)
    private void activeParticles() {
      CrystalElement e = CrystalElement.elements[ticks / 8 % 16];
      double vx = ReikaRandomHelper.getRandomPlusMinus(0, 0.03125);
      double vz = ReikaRandomHelper.getRandomPlusMinus(0, 0.03125);
      float g = -(float) ReikaRandomHelper.getRandomPlusMinus(0.125, 0.0625);
      EntityBlurFX fx =
          new EntityBlurFX(worldObj, xCoord + 0.5, yCoord + 8.25, zCoord + 0.5, vx, 0, vz)
              .setGravity(g);
      Minecraft.getMinecraft().effectRenderer.addEffect(fx);

      // ---------------------------
      int dx = worldObj.rand.nextBoolean() ? 3 : -3;
      int dz = worldObj.rand.nextBoolean() ? 3 : -3;
      double x = xCoord + dx + worldObj.rand.nextDouble();
      double y = yCoord + 5 + worldObj.rand.nextDouble();
      double z = zCoord + dz + worldObj.rand.nextDouble();
      double v = 0.0625;
      vx = x < xCoord ? v : -v;
      vz = z < zCoord ? v : -v;
      if (worldObj.rand.nextBoolean()) vx = 0;
      else vz = 0;

      EntityFX fx2 =
          new EntityCenterBlurFX(e, worldObj, x, y, z, vx, 0, vz).setScale(2).setNoSlowdown();
      fx2.noClip = true;
      Minecraft.getMinecraft().effectRenderer.addEffect(fx2);

      // ----------------------------------
      dx = worldObj.rand.nextBoolean() ? 7 : -7;
      dz = worldObj.rand.nextBoolean() ? 7 : -7;
      if (worldObj.rand.nextBoolean()) dx += Math.signum(dx) * -4;
      else dz += Math.signum(dz) * -4;
      x = xCoord + dx + worldObj.rand.nextDouble();
      y = yCoord + 5 + worldObj.rand.nextDouble();
      z = zCoord + dz + worldObj.rand.nextDouble();
      v = 0.0625;
      vx = x < xCoord ? v : -v;
      vz = z < zCoord ? v : -v;
      if (worldObj.rand.nextBoolean()) vx = 0;
      else vz = 0;

      boolean longAxis = (Math.abs(dx) == 7 && vx != 0) || (Math.abs(dz) == 7 && vz != 0);
      int l = !longAxis ? 100 : 60;

      EntityRuneFX fx3 = new EntityRuneFX(worldObj, x, y, z, vx, 0, vz, e).setScale(2).setLife(l);
      fx3.noClip = true;
      Minecraft.getMinecraft().effectRenderer.addEffect(fx3);
    }
 @SideOnly(Side.CLIENT)
 private void invalidatationParticles() {
   double d = 1.25;
   int n = 64 + rand.nextInt(64);
   for (int i = 0; i < n; i++) {
     double rx = ReikaRandomHelper.getRandomPlusMinus(xCoord + 0.5, d);
     double ry = ReikaRandomHelper.getRandomPlusMinus(yCoord + 0.5, d);
     double rz = ReikaRandomHelper.getRandomPlusMinus(zCoord + 0.5, d);
     double vx = rand.nextDouble() - 0.5;
     double vy = rand.nextDouble() - 0.5;
     double vz = rand.nextDouble() - 0.5;
     EntityRuneFX fx = new EntityRuneFX(worldObj, rx, ry, rz, vx, vy, vz, color);
     Minecraft.getMinecraft().effectRenderer.addEffect(fx);
   }
 }
 @SideOnly(Side.CLIENT)
 private void idleParticles() {
   double px = ReikaRandomHelper.getRandomPlusMinus(xCoord + 0.5, 1.5);
   double pz = ReikaRandomHelper.getRandomPlusMinus(zCoord + 0.5, 1.5);
   float g = -(float) ReikaRandomHelper.getRandomPlusMinus(0.125, 0.0625);
   int color = CrystalElement.getBlendedColor(ticks, 40);
   int l = ReikaRandomHelper.getRandomPlusMinus(80, 40);
   EntityBlurFX fx =
       new EntityBlurFX(worldObj, px, yCoord + 1.25, pz, 0, 0, 0)
           .setGravity(g)
           .setLife(l)
           .setColor(color);
   fx.noClip = true;
   Minecraft.getMinecraft().effectRenderer.addEffect(fx);
 }
Ejemplo n.º 9
0
 private void pickNewTarget() {
   targetRadius =
       ReikaRandomHelper.getRandomPlusMinus(
           maxSize, maxSize / 16D); // rand.nextDouble()*maxSize;
   targetTheta = rand.nextDouble() * 360;
   targetPhi = rand.nextDouble() * 360;
 }
Ejemplo n.º 10
0
 @SideOnly(Side.CLIENT)
 private static void doDeathParticles(World world, double dx, double dy, double dz, int color) {
   int n = 32;
   for (int i = 0; i < n; i++) {
     EntityCenterBlurFX fx =
         new EntityCenterBlurFX(world, dx, dy, dz).setColor(color).setScale(1.5F);
     fx.motionX = ReikaRandomHelper.getRandomPlusMinus(0, 0.2);
     fx.motionY = ReikaRandomHelper.getRandomPlusMinus(0, 0.2);
     fx.motionZ = ReikaRandomHelper.getRandomPlusMinus(0, 0.2);
     EntityCenterBlurFX fx2 =
         new EntityCenterBlurFX(world, dx, dy, dz).setColor(0xffffff).setScale(0.5F);
     fx2.motionX = fx.motionX;
     fx2.motionY = fx.motionY;
     fx2.motionZ = fx.motionZ;
     Minecraft.getMinecraft().effectRenderer.addEffect(fx);
     Minecraft.getMinecraft().effectRenderer.addEffect(fx2);
   }
 }
Ejemplo n.º 11
0
  private void convertToRainbowForest(World world, int x, int y, int z) {
    int rx = ReikaRandomHelper.getRandomPlusMinus(x, 32);
    int rz = ReikaRandomHelper.getRandomPlusMinus(z, 32);

    if (world.checkChunksExist(rx, 0, rz, rx, 255, rz)) {
      int r = 3;
      for (int i = -r; i <= r; i++) {
        for (int k = -r; k <= r; k++) {
          int dx = rx + i;
          int dz = rz + k;
          BiomeGenBase biome = world.getBiomeGenForCoords(dx, dz);
          int id = biome.biomeID;
          if (id != DyeTrees.forest.biomeID) {
            ReikaWorldHelper.setBiomeForXZ(world, dx, dz, DyeTrees.forest);
          }
        }
      }
    }
  }
 private Coordinate getRandomPosition(World world, int x, int y, int z) {
   ForgeDirection dir = this.getFacing();
   ForgeDirection left = ReikaDirectionHelper.getLeftBy90(dir);
   int r = rand.nextInt(16);
   int sp = ReikaRandomHelper.getRandomPlusMinus(0, r); // r/2
   int dx = x + r * dir.offsetX + sp * left.offsetX; // ReikaRandomHelper.getRandomPlusMinus(x, r);
   int dz = z + r * dir.offsetZ + sp * left.offsetZ; // ReikaRandomHelper.getRandomPlusMinus(z, r);
   int dy =
       ReikaWorldHelper.findTopBlockBelowY(
           world, dx, y, dz); // Math.min(y, world.getTopSolidOrLiquidBlock(x, z));
   return new Coordinate(dx, dy, dz);
 }
Ejemplo n.º 13
0
  private void fightEerie(World world, int x, int y, int z) {
    int rx = ReikaRandomHelper.getRandomPlusMinus(x, 32);
    int rz = ReikaRandomHelper.getRandomPlusMinus(z, 32);

    if (world.checkChunksExist(rx, 0, rz, rx, 255, rz)) {
      int r = 3;
      for (int i = -r; i <= r; i++) {
        for (int k = -r; k <= r; k++) {
          int dx = rx + i;
          int dz = rz + k;
          BiomeGenBase biome = world.getBiomeGenForCoords(dx, dz);
          int id = biome.biomeID;
          if (id == ThaumBlockHandler.getInstance().eerieBiomeID) {
            BiomeGenBase natural = ReikaWorldHelper.getNaturalGennedBiomeAt(world, dx, dz);
            if (natural != null) {
              ReikaWorldHelper.setBiomeForXZ(world, dx, dz, natural);
            }
          }
        }
      }
    }
  }
Ejemplo n.º 14
0
 @SideOnly(Side.CLIENT)
 public void doWarningParticles(World world, int x, int y, int z) {
   int n = 2 + rand.nextInt(6);
   for (int i = 0; i < n; i++) {
     double rx = x + rand.nextDouble();
     double ry = y + rand.nextDouble();
     double rz = z + rand.nextDouble();
     int l = 10 + rand.nextInt(20);
     float g = -(float) ReikaRandomHelper.getRandomPlusMinus(0.0625, 0.03125);
     EntityFX fx = new EntityCenterBlurFX(world, rx, ry, rz).setGravity(g).setLife(l);
     Minecraft.getMinecraft().effectRenderer.addEffect(fx);
   }
 }
Ejemplo n.º 15
0
  private void convertPureNodeMagic(World world, int x, int y, int z) {
    int rx = ReikaRandomHelper.getRandomPlusMinus(x, 64);
    int rz = ReikaRandomHelper.getRandomPlusMinus(z, 64);

    if (world.checkChunksExist(rx, 0, rz, rx, 255, rz)) {
      int r = 3;
      for (int i = -r; i <= r; i++) {
        for (int k = -r; k <= r; k++) {
          int dx = rx + i;
          int dz = rz + k;
          BiomeGenBase biome = world.getBiomeGenForCoords(dx, dz);
          int id = biome.biomeID;
          if (id == ThaumBlockHandler.getInstance().magicBiomeID) {
            BiomeGenBase natural = ReikaWorldHelper.getNaturalGennedBiomeAt(world, dx, dz);
            if (natural != null && DyeTrees.isRainbowForest(natural)) {
              ReikaWorldHelper.setBiomeForXZ(world, dx, dz, natural);
            }
          }
        }
      }
    }
  }
Ejemplo n.º 16
0
 @SideOnly(Side.CLIENT)
 private void lifeParticles() {
   int p = Minecraft.getMinecraft().gameSettings.particleSetting;
   if (rand.nextInt(1 + p * 2) == 0) {
     double d = 0.25;
     double px = ReikaRandomHelper.getRandomPlusMinus(posX, d);
     double py = ReikaRandomHelper.getRandomPlusMinus(posY, d);
     double pz = ReikaRandomHelper.getRandomPlusMinus(posZ, d);
     float g = (float) ReikaRandomHelper.getRandomPlusMinus(0.05, 0.025);
     if (rand.nextInt(4) == 0) g = -g;
     EntityLaserFX fx =
         new EntityLaserFX(color, worldObj, px, py, pz)
             .setColor(this.getRenderColor())
             .setGravity(g);
     EntityLaserFX fx2 =
         new EntityLaserFX(color, worldObj, px, py, pz)
             .setColor(0xffffff)
             .setScale(0.42F)
             .setGravity(g);
     Minecraft.getMinecraft().effectRenderer.addEffect(fx);
     Minecraft.getMinecraft().effectRenderer.addEffect(fx2);
   }
 }
Ejemplo n.º 17
0
  public TieredOreRenderer() {
    for (int a = 0; a < 16; a++) {
      for (int i = 0; i < numSections + 1; i++) {
        for (int k = 0; k < numSections + 1; k++) {
          double dy = 1;
          double dr = 0.25;
          double di = Math.min(i, numSections - i) / (double) numSections;
          double dk = Math.min(k, numSections - k) / (double) numSections;
          double dp = 0.25;
          dy = 1 - dr * Math.pow(di, dp) * Math.pow(dk, dp);
          if (di > 0 && dk > 0) dy = ReikaRandomHelper.getRandomPlusMinus(dy, dr * 0.125);
          stoneOffsets[a][i * numSections + k] = dy;
        }
      }

      for (int i = 0; i < numSections + 1; i++) {
        for (int k = 0; k < numSections + 1; k++) {
          double dy = 1;
          double dr = 0.25;
          double di = Math.min(i, numSections - i) / (double) numSections;
          double dk = Math.min(k, numSections - k) / (double) numSections;
          double dp = 0.25;
          dy = 1 + dr * Math.pow(di, dp) * Math.pow(dk, dp) - 0.25;
          if (di > 0 && dk > 0) dy = ReikaRandomHelper.getRandomPlusMinus(dy, dr * 0.5);
          oreOffsets[a][i * numSections + k] = dy;
        }
      }
    }

    for (int a = 0; a < 16; a++) {
      for (int b = 0; b < 16; b++) {
        for (int c = 0; c < 16; c++) {
          offsetArray[a][b][c] = ReikaRandomHelper.getSafeRandomInt(16);
        }
      }
    }
  }
Ejemplo n.º 18
0
  @Override
  public void onUpdate() {
    super.onUpdate();
    if (ReikaMathLibrary.approxr(velocity.inclination, targetTheta, 2)) {
      targetTheta = rand.nextInt(360);
    } else {
      if (targetTheta > velocity.inclination) velocity.inclination++;
      else velocity.inclination--;
    }

    if (ReikaMathLibrary.approxr(velocity.rotation, targetPhi, 2)) {
      targetPhi = rand.nextInt(360);
    } else {
      if (targetPhi > velocity.rotation) velocity.rotation++;
      else velocity.rotation--;
    }

    if (ReikaMathLibrary.approxr(velocity.rotation, targetPhi, 0.05)) {
      targetVelocity = ReikaRandomHelper.getRandomPlusMinus(0.1, 0.1);
    } else {
      if (targetVelocity > velocity.magnitude) velocity.magnitude += 0.01D;
      else velocity.magnitude -= 0.01D;
    }

    velocityChanged = true;
    // ReikaJavaLibrary.pConsole(velocity.inclination+"/"+targetTheta+";
    // "+velocity.rotation+"/"+targetPhi, Side.SERVER);

    double[] v = velocity.getCartesian();
    motionX = v[0];
    motionY = v[1];
    motionZ = v[2];

    if (targetColor != null) {
      colorTransitionFraction += 0.1F;
      if (colorTransitionFraction >= 1) {
        color = targetColor;
        targetColor = null;
        colorTransitionFraction = 0;
      }
    }
    dataWatcher.updateObject(30, this.calcRenderColor());

    if (worldObj.isRemote) {
      this.lifeParticles();
    }

    fallDistance = 0;
  }
Ejemplo n.º 19
0
public class EntityBallLightning extends EntityLiving implements IEntityAdditionalSpawnData {

  private SphericalVector velocity;
  private double targetTheta = rand.nextInt(360);
  private double targetPhi = rand.nextInt(360);
  private double targetVelocity = ReikaRandomHelper.getRandomPlusMinus(0.1, 0.1);

  private CrystalElement color;

  private CrystalElement targetColor = null;
  private float colorTransitionFraction = 0;

  private boolean isPylonSpawn = false;
  private boolean doDrops = true;

  // private static int spawnedEntities;

  public EntityBallLightning(World world, CrystalElement color, double x, double y, double z) {
    super(world);
    this.color = color;
    this.setPosition(x, y, z);
    height = 0.25F;
    width = 0.25F;
  }

  public EntityBallLightning(World world) {
    super(world);
  }

  public EntityBallLightning setNoDrops() {
    doDrops = false;
    return this;
  }

  public EntityBallLightning setPylon() {
    isPylonSpawn = true;
    return this;
  }

  @Override
  protected boolean canTriggerWalking() {
    return false;
  }

  @Override
  public boolean canRenderOnFire() {
    return false;
  }

  @Override
  protected String func_146067_o(int p_146067_1_) {
    return "";
  }

  @Override
  protected void fall(float p_70069_1_) {}

  @Override
  public boolean handleWaterMovement() {
    return false;
  }

  @Override
  protected void entityInit() {
    super.entityInit();
    velocity = new SphericalVector(0.15, rand.nextInt(360), rand.nextInt(360));

    if (color == null) color = CrystalElement.randomElement();

    dataWatcher.addObject(30, 0);

    if (worldObj != null) ; // spawnedEntities++;
  }

  @Override
  public void onUpdate() {
    super.onUpdate();
    if (ReikaMathLibrary.approxr(velocity.inclination, targetTheta, 2)) {
      targetTheta = rand.nextInt(360);
    } else {
      if (targetTheta > velocity.inclination) velocity.inclination++;
      else velocity.inclination--;
    }

    if (ReikaMathLibrary.approxr(velocity.rotation, targetPhi, 2)) {
      targetPhi = rand.nextInt(360);
    } else {
      if (targetPhi > velocity.rotation) velocity.rotation++;
      else velocity.rotation--;
    }

    if (ReikaMathLibrary.approxr(velocity.rotation, targetPhi, 0.05)) {
      targetVelocity = ReikaRandomHelper.getRandomPlusMinus(0.1, 0.1);
    } else {
      if (targetVelocity > velocity.magnitude) velocity.magnitude += 0.01D;
      else velocity.magnitude -= 0.01D;
    }

    velocityChanged = true;
    // ReikaJavaLibrary.pConsole(velocity.inclination+"/"+targetTheta+";
    // "+velocity.rotation+"/"+targetPhi, Side.SERVER);

    double[] v = velocity.getCartesian();
    motionX = v[0];
    motionY = v[1];
    motionZ = v[2];

    if (targetColor != null) {
      colorTransitionFraction += 0.1F;
      if (colorTransitionFraction >= 1) {
        color = targetColor;
        targetColor = null;
        colorTransitionFraction = 0;
      }
    }
    dataWatcher.updateObject(30, this.calcRenderColor());

    if (worldObj.isRemote) {
      this.lifeParticles();
    }

    fallDistance = 0;
  }

  @SideOnly(Side.CLIENT)
  private void lifeParticles() {
    int p = Minecraft.getMinecraft().gameSettings.particleSetting;
    if (rand.nextInt(1 + p * 2) == 0) {
      double d = 0.25;
      double px = ReikaRandomHelper.getRandomPlusMinus(posX, d);
      double py = ReikaRandomHelper.getRandomPlusMinus(posY, d);
      double pz = ReikaRandomHelper.getRandomPlusMinus(posZ, d);
      float g = (float) ReikaRandomHelper.getRandomPlusMinus(0.05, 0.025);
      if (rand.nextInt(4) == 0) g = -g;
      EntityLaserFX fx =
          new EntityLaserFX(color, worldObj, px, py, pz)
              .setColor(this.getRenderColor())
              .setGravity(g);
      EntityLaserFX fx2 =
          new EntityLaserFX(color, worldObj, px, py, pz)
              .setColor(0xffffff)
              .setScale(0.42F)
              .setGravity(g);
      Minecraft.getMinecraft().effectRenderer.addEffect(fx);
      Minecraft.getMinecraft().effectRenderer.addEffect(fx2);
    }
  }

  @Override
  public void readEntityFromNBT(NBTTagCompound nbt) {
    super.readEntityFromNBT(nbt);

    int c = nbt.getInteger("color");
    color = c >= 0 ? CrystalElement.elements[c] : CrystalElement.randomElement();

    isPylonSpawn = nbt.getBoolean("pylon");
    doDrops = nbt.getBoolean("dodrops");

    if (nbt.getBoolean("isdead")) this.setDead();
  }

  @Override
  public void writeEntityToNBT(NBTTagCompound nbt) {
    super.writeEntityToNBT(nbt);

    if (color != null) nbt.setInteger("color", color.ordinal());

    nbt.setBoolean("dodrops", doDrops);
    nbt.setBoolean("pylon", isPylonSpawn);

    nbt.setBoolean("isdead", isDead);
  }

  private void die() {
    // particle effect
    if (worldObj.isRemote) {
      this.doDeathParticles(worldObj, posX, posY, posZ, this.getRenderColor());
    } else {
      ReikaPacketHelper.sendDataPacket(
          ChromatiCraft.packetChannel,
          ChromaPackets.LIGHTNINGDIE.ordinal(),
          new PacketTarget.RadiusTarget(this, 32),
          this.calcRenderColor());
    }
    this.setDead();
  }

  @Override
  public void setDead() {
    super.setDead();
    if (worldObj != null) ; // spawnedEntities--;
  }

  private void doBolt(EntityBallLightning other) {
    Vec3 vec = ReikaVectorHelper.getVec2Pt(posX, posY, posZ, other.posX, other.posY, other.posZ);
    // EntityGluon g = new EntityGluon(this, other);
    // worldObj.spawnEntityInWorld(g);
    targetColor = other.color;

    ReikaPacketHelper.sendDataPacket(
        ChromatiCraft.packetChannel,
        ChromaPackets.GLUON.ordinal(),
        new DimensionTarget(worldObj),
        this.getEntityId(),
        other.getEntityId());

    double len = vec.lengthVector();
    for (double i = 0; i < len; i += 0.0625) {
      double dx = posX - i * vec.xCoord / len;
      double dy = posY - i * vec.yCoord / len;
      double dz = posZ - i * vec.zCoord / len;
      if (worldObj.isRemote) this.gluonParticles(other, dx, dy, dz, (float) (i / len));

      if (ChromaOptions.HOSTILEFOREST.getState()) {
        AxisAlignedBB box =
            AxisAlignedBB.getBoundingBox(dx, dy, dz, dx, dy, dz).expand(0.5, 0.5, 0.5);
        List<EntityLivingBase> elb = worldObj.getEntitiesWithinAABB(EntityLivingBase.class, box);
        for (EntityLivingBase e : elb) {
          e.attackEntityFrom(DamageSource.generic, isPylonSpawn ? 4 : 1);
        }
      }
    }
  }

  @SideOnly(Side.CLIENT)
  public void doBoltClient(EntityBallLightning other) {
    targetColor = other.color;
  }

  @SideOnly(Side.CLIENT)
  private void gluonParticles(
      EntityBallLightning other, double dx, double dy, double dz, float frac) {
    int c = ReikaColorAPI.mixColors(other.getRenderColor(), this.getRenderColor(), frac);
    EntityBlurFX fx = new EntityBlurFX(worldObj, dx, dy, dz);
    fx.setLife(5).setColor(c);
    Minecraft.getMinecraft().effectRenderer.addEffect(fx);
  }

  private void onReceiveBolt(EntityBallLightning src) {
    targetColor = src.color;
  }

  @Override
  public AxisAlignedBB getCollisionBox(Entity entity) {
    if (entity instanceof EntityLivingBase
        && !(entity instanceof EntityBallLightning)
        && !worldObj.isRemote) {
      boolean flag =
          (entity instanceof EntityPlayer && ((EntityPlayer) entity).capabilities.isCreativeMode);
      if (!flag) {
        if (ChromaOptions.HOSTILEFOREST.getState()) {
          entity.attackEntityFrom(DamageSource.generic, 5);
        }
        if (entity instanceof EntityPlayer)
          ProgressStage.BALLLIGHTNING.stepPlayerTo((EntityPlayer) entity);
        this.die();
      }
    }
    return null; // AxisAlignedBB.getBoundingBox(posX, posY, posZ, posX, posY, posZ).expand(3, 3,
    // 3);
  }

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

    if (!worldObj.isRemote && colorTransitionFraction == 0 && rand.nextInt(400) == 0) {
      EntityBallLightning e = ReikaEntityHelper.getNearestEntityOfSameType(this, 24);
      if (e != null && e.colorTransitionFraction == 0) {
        this.doBolt(e);
        e.onReceiveBolt(this);
      }
    }

    // if (ticksExisted%36 == 0) {
    //	ChromaSounds.POWER.playSound(this, 0.1F, 2F);
    // }

    if (!worldObj.isRemote && rand.nextInt(1600) == 0) {
      if (!CrystalNetworker.instance
          .getNearbyPylons(worldObj, posX, posY, posZ, color, 24, false)
          .isEmpty()) {
        this.heal(this.getMaxHealth());
      }
    }

    if (!worldObj.isRemote) {

      EntityPlayer ep = worldObj.getClosestPlayerToEntity(this, -1);
      if (posY >= 128) {
        this.die();
      } else if (ep == null || worldObj.playerEntities.isEmpty()) {
        this.die();
      } else if (ticksExisted >= 12000 || rand.nextInt(12000 - ticksExisted) == 0) {
        this.die();
      } else if (worldObj.isRaining() && rand.nextInt(80) == 0) {
        this.die();
      } else if (this.getDistanceSqToEntity(ep) >= 65536) {
        this.die();
      } else if (this.getDistanceSqToEntity(ep) >= 1024 && rand.nextInt(200) == 0) {
        this.die();
      }
      // else if (spawnedEntities > 200 && rand.nextInt(spawnedEntities-200) > 0) {
      //	this.die();
      // }
      else if (rand.nextInt(20) == 0) {
        AxisAlignedBB box =
            AxisAlignedBB.getBoundingBox(posX, 0, posZ, posX, 1024, posZ).expand(24, 0, 24);
        List<EntityBallLightning> li = worldObj.getEntitiesWithinAABB(this.getClass(), box);
        if (rand.nextInt(1 + li.size() / 16) > 0) this.die();
      }
    }
  }

  @Override
  public boolean getCanSpawnHere() {
    return rand.nextInt(5) == 0
        && worldObj.canBlockSeeTheSky(
            MathHelper.floor_double(posX),
            MathHelper.floor_double(posY) + 1,
            MathHelper.floor_double(posZ));
  }

  @Override
  public int getMaxSpawnedInChunk() {
    return 4;
  }

  @Override
  public void playLivingSound() {
    ; // ChromaSounds.POWER.playSound(this, 1F, 2F);

    float p = CrystalMusicManager.instance.getRandomScaledDing(color);
    ChromaSounds.BALLLIGHTNING.playSound(this, 1, p);
  }

  @Override
  public final int getTalkInterval() {
    return 20;
  }

  @Override
  protected final void func_145780_a(int par1, int par2, int par3, Block par4) // play step sound
      {}

  @Override
  protected String getHurtSound() {
    return "";
  }

  @Override
  protected String getDeathSound() {
    return "";
  }

  @Override
  public void onDeath(DamageSource src) {
    ChromaSounds.DISCHARGE.playSound(this, 1F, 2F);
    if (!worldObj.isRemote) {
      Entity e = src.getEntity();
      if (e instanceof EntityPlayer) {
        EntityPlayer ep = (EntityPlayer) e;
        if (doDrops && !ReikaPlayerAPI.isFakeOrNotInteractable(ep, posX, posY, posZ, 8)) {
          int looting = EnchantmentHelper.getLootingModifier((EntityPlayer) src.getEntity());
          ReikaItemHelper.dropItem(
              this,
              ReikaItemHelper.getSizedItemStack(
                  ChromaStacks.beaconDust, rand.nextInt(1 + looting * 2)));
          if (looting > 1) {
            if (color.isPrimary()) ReikaItemHelper.dropItem(this, ChromaStacks.purityDust);
            else ReikaItemHelper.dropItem(this, ChromaStacks.auraDust);
          }
        }
        ProgressStage.BALLLIGHTNING.stepPlayerTo(ep);
      }

      this.sendDeathParticles();
    }
  }

  private void sendDeathParticles() {
    ReikaPacketHelper.sendPositionPacket(
        ChromatiCraft.packetChannel,
        ChromaPackets.LIGHTNINGDIE.ordinal(),
        this,
        this.calcRenderColor(),
        new DimensionTarget(worldObj));
  }

  @SideOnly(Side.CLIENT)
  public static void receiveDeathParticles(
      World world, double dx, double dy, double dz, int color) {
    doDeathParticles(world, dx, dy, dz, color);
  }

  @SideOnly(Side.CLIENT)
  private static void doDeathParticles(World world, double dx, double dy, double dz, int color) {
    int n = 32;
    for (int i = 0; i < n; i++) {
      EntityCenterBlurFX fx =
          new EntityCenterBlurFX(world, dx, dy, dz).setColor(color).setScale(1.5F);
      fx.motionX = ReikaRandomHelper.getRandomPlusMinus(0, 0.2);
      fx.motionY = ReikaRandomHelper.getRandomPlusMinus(0, 0.2);
      fx.motionZ = ReikaRandomHelper.getRandomPlusMinus(0, 0.2);
      EntityCenterBlurFX fx2 =
          new EntityCenterBlurFX(world, dx, dy, dz).setColor(0xffffff).setScale(0.5F);
      fx2.motionX = fx.motionX;
      fx2.motionY = fx.motionY;
      fx2.motionZ = fx.motionZ;
      Minecraft.getMinecraft().effectRenderer.addEffect(fx);
      Minecraft.getMinecraft().effectRenderer.addEffect(fx2);
    }
  }

  @Override
  public void writeSpawnData(ByteBuf buf) {
    buf.writeInt(color != null ? color.ordinal() : -1);
  }

  @Override
  public void readSpawnData(ByteBuf buf) {
    int c = buf.readInt();
    color = c >= 0 && c < 16 ? CrystalElement.elements[c] : CrystalElement.randomElement();
  }

  /*
  public int getRenderColor() {
  	return targetColor != null ? ReikaColorAPI.mixColors(targetColor.getColor(), color.getColor(), colorTransitionFraction) : color.getColor();
  }
   */

  private int calcRenderColor() {
    return targetColor != null
        ? ReikaColorAPI.mixColors(targetColor.getColor(), color.getColor(), colorTransitionFraction)
        : color.getColor();
  }

  @SideOnly(Side.CLIENT)
  public int getRenderColor() {
    return dataWatcher.getWatchableObjectInt(30);
  }

  /*
  public int getRenderColor() {
  	float frac = dataWatcher.getWatchableObjectFloat(31);
  	int tgi = dataWatcher.getWatchableObjectInt(30);
  	CrystalElement tg = tgi >= 0 ? CrystalElement.elements[tgi] : null;
  	CrystalElement c = CrystalElement.elements[dataWatcher.getWatchableObjectInt(29)];
  	return tg != null ? ReikaColorAPI.mixColors(tg.getColor(), c.getColor(), frac) : c.getColor();
  }
   */

  @Override
  public boolean attackEntityFrom(DamageSource src, float dmg) {
    Entity e = src.getEntity();
    if (e instanceof EntityPlayer) {
      if (!ReikaPlayerAPI.isFake((EntityPlayer) e)) {
        boolean flag = super.attackEntityFrom(src, dmg);
        if (flag && this.getHealth() <= 0) {
          this.die();
        }
        return flag;
      }
    }
    return false;
  }

  public CrystalElement getElement() {
    return color;
  }

  @Override
  public boolean shouldRenderInPass(int pass) {
    return pass == 1;
  }

  @Override
  protected void dropFewItems(boolean recentHit, int looting) {
    if (recentHit) {}
  }
}
 static {
   for (int i = 0; i < CrystalElement.elements.length; i++) {
     map[i] = 5 + ReikaRandomHelper.getRandomPlusMinus(i * 22.5, 5);
   }
   ReikaArrayHelper.shuffleArray(map);
 }