Package cofh.lib.world

Source Code of cofh.lib.world.WorldGenMinableCluster

package cofh.lib.world;

import cofh.lib.util.WeightedRandomBlock;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import net.minecraft.block.Block;
import net.minecraft.init.Blocks;
import net.minecraft.item.ItemStack;
import net.minecraft.util.MathHelper;
import net.minecraft.util.WeightedRandom;
import net.minecraft.world.World;
import net.minecraft.world.gen.feature.WorldGenerator;

public class WorldGenMinableCluster extends WorldGenerator {

  public static final List<WeightedRandomBlock> fabricateList(WeightedRandomBlock resource) {

    List<WeightedRandomBlock> list = new ArrayList<WeightedRandomBlock>();
    list.add(resource);
    return list;
  }

  public static final List<WeightedRandomBlock> fabricateList(Block resource) {

    List<WeightedRandomBlock> list = new ArrayList<WeightedRandomBlock>();
    list.add(new WeightedRandomBlock(new ItemStack(resource, 1, 0)));
    return list;
  }

  private final List<WeightedRandomBlock> cluster;
  private final int genClusterSize;
  private final WeightedRandomBlock[] genBlock;

  public WorldGenMinableCluster(ItemStack ore, int clusterSize) {

    this(new WeightedRandomBlock(ore), clusterSize);
  }

  public WorldGenMinableCluster(WeightedRandomBlock resource, int clusterSize) {

    this(fabricateList(resource), clusterSize);
  }

  public WorldGenMinableCluster(List<WeightedRandomBlock> resource, int clusterSize) {

    this(resource, clusterSize, Blocks.stone);
  }

  public WorldGenMinableCluster(ItemStack ore, int clusterSize, Block block) {

    this(new WeightedRandomBlock(ore, 1), clusterSize, block);
  }

  public WorldGenMinableCluster(WeightedRandomBlock resource, int clusterSize, Block block) {

    this(fabricateList(resource), clusterSize, block);
  }

  public WorldGenMinableCluster(List<WeightedRandomBlock> resource, int clusterSize, Block block) {

    this(resource, clusterSize, fabricateList(block));
  }

  public WorldGenMinableCluster(List<WeightedRandomBlock> resource, int clusterSize, List<WeightedRandomBlock> block) {

    cluster = resource;
    genClusterSize = clusterSize > 32 ? 32 : clusterSize;
    genBlock = block.toArray(new WeightedRandomBlock[block.size()]);
  }

  @Override
  public boolean generate(World world, Random rand, int x, int y, int z) {

    int blocks = genClusterSize;
    if (blocks < 4) { // HACK: at 1 and 2 no ores are ever generated. at 3 only 1/3 veins generate
      return generateTiny(world, rand, x, y, z);
    }
    float f = rand.nextFloat() * (float) Math.PI;
    // despite naming, these are not exactly min/max. more like direction
    float xMin = x + 8 + (MathHelper.sin(f) * blocks) / 8F;
    float xMax = x + 8 - (MathHelper.sin(f) * blocks) / 8F;
    float zMin = z + 8 + (MathHelper.cos(f) * blocks) / 8F;
    float zMax = z + 8 - (MathHelper.cos(f) * blocks) / 8F;
    float yMin = (y + rand.nextInt(3)) - 2;
    float yMax = (y + rand.nextInt(3)) - 2;

    // optimization so this subtraction doesn't occur every time in the loop
    xMax -= xMin;
    yMax -= yMin;
    zMax -= zMin;

    boolean r = false;
    for (int i = 0; i <= blocks; i++) {

      float xCenter = xMin + (xMax * i) / blocks;
      float yCenter = yMin + (yMax * i) / blocks;
      float zCenter = zMin + (zMax * i) / blocks;

      // preserved as nextDouble to ensure the rand gets ticked the same amount
      float size = ((float) rand.nextDouble() * blocks) / 16f;

      float hMod = ((MathHelper.sin((i * (float) Math.PI) / blocks) + 1f) * size + 1f) * .5f;
      float vMod = ((MathHelper.sin((i * (float) Math.PI) / blocks) + 1f) * size + 1f) * .5f;

      int xStart = MathHelper.floor_float(xCenter - hMod);
      int yStart = MathHelper.floor_float(yCenter - vMod);
      int zStart = MathHelper.floor_float(zCenter - hMod);

      int xStop = MathHelper.floor_float(xCenter + hMod);
      int yStop = MathHelper.floor_float(yCenter + vMod);
      int zStop = MathHelper.floor_float(zCenter + hMod);

      for (int blockX = xStart; blockX <= xStop; blockX++) {
        float xDistSq = ((blockX + .5f) - xCenter) / hMod;
        xDistSq *= xDistSq;
        if (xDistSq >= 1f) {
          continue;
        }

        for (int blockY = yStart; blockY <= yStop; blockY++) {
          float yDistSq = ((blockY + .5f) - yCenter) / vMod;
          yDistSq *= yDistSq;
          float xyDistSq = yDistSq + xDistSq;
          if (xyDistSq >= 1f) {
            continue;
          }

          for (int blockZ = zStart; blockZ <= zStop; blockZ++) {
            float zDistSq = ((blockZ + .5f) - zCenter) / hMod;
            zDistSq *= zDistSq;
            if (zDistSq + xyDistSq >= 1f) {
              continue;
            }

            r |= generateBlock(world, blockX, blockY, blockZ, genBlock, cluster);
          }
        }
      }
    }

    return r;
  }

  public boolean generateTiny(World world, Random random, int x, int y, int z) {

    boolean r = false;
    // not <=; generating up to clusterSize blocks
    for (int i = 0; i < genClusterSize; i++) {
      int d0 = x + random.nextInt(2);
      int d1 = y + random.nextInt(2);
      int d2 = z + random.nextInt(2);

      r |= generateBlock(world, d0, d1, d2, genBlock, cluster);
    }
    return r;
  }

  public static boolean canGenerateInBlock(World world, int x, int y, int z, WeightedRandomBlock[] mat) {

    if (mat == null || mat.length == 0)
      return true;

    Block block = world.getBlock(x, y, z);
    for (int j = 0, e = mat.length; j < e; ++j) {
      WeightedRandomBlock genBlock = mat[j];
      if ((-1 == genBlock.metadata || genBlock.metadata == world.getBlockMetadata(x, y, z)) &&
          (block.isReplaceableOreGen(world, x, y, z, genBlock.block) || block.isAssociatedBlock(genBlock.block))) {
        return true;
      }
    }
    return false;
  }

  public static boolean generateBlock(World world, int x, int y, int z, WeightedRandomBlock[] mat, List<WeightedRandomBlock> o) {

    if (mat == null || mat.length == 0)
      return generateBlock(world, x, y, z, o);

    if (canGenerateInBlock(world, x, y, z, mat)) {
      return generateBlock(world, x, y, z, o);
    }
    return false;
  }

  public static boolean generateBlock(World world, int x, int y, int z, List<WeightedRandomBlock> o) {

    WeightedRandomBlock ore = (WeightedRandomBlock) WeightedRandom.getRandomItem(world.rand, o);
    return world.setBlock(x, y, z, ore.block, ore.metadata, 2);
  }

  public static WeightedRandomBlock selectBlock(World world, List<WeightedRandomBlock> o) {

    return (WeightedRandomBlock) WeightedRandom.getRandomItem(world.rand, o);
  }

}
TOP

Related Classes of cofh.lib.world.WorldGenMinableCluster

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.