public Chunk getOrCreateChunk(int x, int z) {
    random.setSeed((long) x * 341873128712L + (long) z * 132897987541L);

    Chunk chunk;

    // Get default biome data for chunk
    CustomBiomeGrid biomegrid = new CustomBiomeGrid();
    biomegrid.biome = new BiomeGenBase[256];
    world.getWorldChunkManager().getBiomeGenAt(biomegrid.biome, x << 4, z << 4, 16, 16, false);

    // Try extended block method (1.2+)
    short[][] xbtypes =
        generator.generateExtBlockSections(
            CraftServer.instance().getWorld(world.provider.dimensionId),
            this.random,
            x,
            z,
            biomegrid);
    if (xbtypes != null) {
      chunk = new Chunk(this.world, x, z);

      ExtendedBlockStorage[] csect = chunk.getBlockStorageArray();
      int scnt = Math.min(csect.length, xbtypes.length);

      // Loop through returned sections
      for (int sec = 0; sec < scnt; sec++) {
        if (xbtypes[sec] == null) {
          continue;
        }
        byte[] secBlkID = new byte[4096]; // Allocate blk ID bytes
        byte[] secExtBlkID = (byte[]) null; // Delay getting extended ID nibbles
        short[] bdata = xbtypes[sec];
        // Loop through data, 2 blocks at a time
        for (int i = 0, j = 0; i < bdata.length; i += 2, j++) {
          short b1 = bdata[i];
          short b2 = bdata[i + 1];
          byte extb = (byte) ((b1 >> 8) | ((b2 >> 4) & 0xF0));

          secBlkID[i] = (byte) b1;
          secBlkID[(i + 1)] = (byte) b2;

          if (extb != 0) { // If extended block ID data
            if (secExtBlkID == null) { // Allocate if needed
              secExtBlkID = new byte[2048];
            }
            secExtBlkID[j] = extb;
          }
        }
        // Build chunk section
        csect[sec] = new ExtendedBlockStorage(sec << 4, false); // , secBlkID, secExtBlkID);
      }
    } else { // Else check for byte-per-block section data
      byte[][] btypes =
          generator.generateBlockSections(getWorld(world), this.random, x, z, biomegrid);

      if (btypes != null) {
        chunk = new Chunk(this.world, x, z);

        ExtendedBlockStorage[] csect = chunk.getBlockStorageArray();
        int scnt = Math.min(csect.length, btypes.length);

        for (int sec = 0; sec < scnt; sec++) {
          if (btypes[sec] == null) {
            continue;
          }
          csect[sec] = new ExtendedBlockStorage(sec << 4, false); // , btypes[sec], null);
        }
      } else { // Else, fall back to pre 1.2 method
        @SuppressWarnings("deprecation")
        byte[] types = generator.generate(getWorld(world), this.random, x, z);
        int ydim = types.length / 256;
        int scnt = ydim / 16;

        chunk = new Chunk(this.world, x, z); // Create empty chunk

        ExtendedBlockStorage[] csect = chunk.getBlockStorageArray();

        scnt = Math.min(scnt, csect.length);
        // Loop through sections
        for (int sec = 0; sec < scnt; sec++) {
          ExtendedBlockStorage cs = null; // Add sections when needed
          byte[] csbytes = (byte[]) null;

          for (int cy = 0; cy < 16; cy++) {
            int cyoff = cy | (sec << 4);

            for (int cx = 0; cx < 16; cx++) {
              int cxyoff = (cx * ydim * 16) + cyoff;

              for (int cz = 0; cz < 16; cz++) {
                byte blk = types[cxyoff + (cz * ydim)];

                if (blk != 0) { // If non-empty
                  if (cs == null) { // If no section yet, get one
                    cs = csect[sec] = new ExtendedBlockStorage(sec << 4, true);
                    csbytes = cs.getBlockLSBArray();
                  }
                  csbytes[(cy << 8) | (cz << 4) | cx] = blk;
                }
              }
            }
          }
          // If section built, finish prepping its state
          if (cs != null) {
            cs.getYLocation();
          }
        }
      }
    }
    // Set biome grid
    byte[] biomeIndex = chunk.getBiomeArray();
    for (int i = 0; i < biomeIndex.length; i++) {
      biomeIndex[i] = (byte) (biomegrid.biome[i].biomeID & 0xFF);
    }
    // Initialize lighting
    chunk.generateSkylightMap();

    return chunk;
  }
예제 #2
0
  /** Initialize a single chunk from the chunk generator. */
  private void generateChunk(GlowChunk chunk, int x, int z) {
    Random random = new Random((long) x * 341873128712L + (long) z * 132897987541L);
    BiomeGrid biomes = new BiomeGrid();

    int[] biomeValues =
        biomeGrid[0].generateValues(
            x * GlowChunk.WIDTH, z * GlowChunk.HEIGHT, GlowChunk.WIDTH, GlowChunk.HEIGHT);
    for (int i = 0; i < biomeValues.length; i++) {
      biomes.biomes[i] = (byte) biomeValues[i];
    }

    // extended sections with data
    if (generator instanceof GlowChunkGenerator) {
      short[][] extSections =
          ((GlowChunkGenerator) generator)
              .generateExtBlockSectionsWithData(world, random, x, z, biomes);
      if (extSections != null) {
        GlowChunk.ChunkSection[] sections = new GlowChunk.ChunkSection[extSections.length];
        for (int i = 0; i < extSections.length; ++i) {
          // this is sort of messy.
          if (extSections[i] != null) {
            sections[i] = new GlowChunk.ChunkSection();
            for (int j = 0; j < extSections[i].length; ++j) {
              sections[i].types[j] = (char) extSections[i][j];
            }
            sections[i].recount();
          }
        }
        chunk.initializeSections(sections);
        chunk.setBiomes(biomes.biomes);
        chunk.automaticHeightMap();
        return;
      }
    }

    // extended sections
    short[][] extSections = generator.generateExtBlockSections(world, random, x, z, biomes);
    if (extSections != null) {
      GlowChunk.ChunkSection[] sections = new GlowChunk.ChunkSection[extSections.length];
      for (int i = 0; i < extSections.length; ++i) {
        // this is sort of messy.
        if (extSections[i] != null) {
          sections[i] = new GlowChunk.ChunkSection();
          for (int j = 0; j < extSections[i].length; ++j) {
            sections[i].types[j] = (char) (extSections[i][j] << 4);
          }
          sections[i].recount();
        }
      }
      chunk.initializeSections(sections);
      chunk.setBiomes(biomes.biomes);
      chunk.automaticHeightMap();
      return;
    }

    // normal sections
    byte[][] blockSections = generator.generateBlockSections(world, random, x, z, biomes);
    if (blockSections != null) {
      GlowChunk.ChunkSection[] sections = new GlowChunk.ChunkSection[blockSections.length];
      for (int i = 0; i < blockSections.length; ++i) {
        // this is sort of messy.
        if (blockSections[i] != null) {
          sections[i] = new GlowChunk.ChunkSection();
          for (int j = 0; j < blockSections[i].length; ++j) {
            sections[i].types[j] = (char) (blockSections[i][j] << 4);
          }
          sections[i].recount();
        }
      }
      chunk.initializeSections(sections);
      chunk.setBiomes(biomes.biomes);
      chunk.automaticHeightMap();
      return;
    }

    // deprecated flat generation
    byte[] types = generator.generate(world, random, x, z);
    GlowChunk.ChunkSection[] sections = new GlowChunk.ChunkSection[8];
    for (int sy = 0; sy < sections.length; ++sy) {
      GlowChunk.ChunkSection sec = new GlowChunk.ChunkSection();
      int by = 16 * sy;
      for (int cx = 0; cx < 16; ++cx) {
        for (int cz = 0; cz < 16; ++cz) {
          for (int cy = by; cy < by + 16; ++cy) {
            char type = (char) types[(cx * 16 + cz) * 128 + cy];
            sec.types[sec.index(cx, cy, cz)] = (char) (type << 4);
          }
        }
      }
      sec.recount();
      sections[sy] = sec;
    }
    chunk.initializeSections(sections);
    chunk.setBiomes(biomes.biomes);
    chunk.automaticHeightMap();
  }
 public short[][] generateExtBlockSections(
     org.bukkit.World world, Random random, int x, int z, BiomeGrid biomes) {
   return generator.generateExtBlockSections(world, random, x, z, biomes);
 }