예제 #1
0
 public final int getBlockTypeIDAt(BlockStep s) {
   if (s == BlockStep.Y_MINUS) {
     if (y > 0) return snap.getBlockTypeId(bx, y - 1, bz);
   } else if (s == BlockStep.Y_PLUS) {
     if (y < (worldheight - 1)) return snap.getBlockTypeId(bx, y + 1, bz);
   } else {
     BlockStep ls = laststep;
     stepPosition(s);
     int tid = snap.getBlockTypeId(bx, y, bz);
     unstepPosition();
     laststep = ls;
     return tid;
   }
   return 0;
 }
예제 #2
0
 public final int getBlockEmittedLight() {
   try {
     return snap.getBlockEmittedLight(bx, y, bz);
   } catch (ArrayIndexOutOfBoundsException aioobx) {
     return 0;
   }
 }
예제 #3
0
 public int getBlockSkyLight() {
   try {
     return snap.getBlockSkyLight(bx, y, bz);
   } catch (ArrayIndexOutOfBoundsException aioobx) {
     return 15;
   }
 }
예제 #4
0
    private void biomePrep() {
      if (sameneighborbiomecnt != null) return;
      int x_size = x_dim << 4;
      int z_size = (z_max - z_min + 1) << 4;
      sameneighborbiomecnt = new byte[x_size][];
      biomemap = new BiomeMap[x_size][];
      for (int i = 0; i < x_size; i++) {
        sameneighborbiomecnt[i] = new byte[z_size];
        biomemap[i] = new BiomeMap[z_size];
      }
      Object[] biomebase = null;
      ChunkSnapshot biome_css = null;
      for (int i = 0; i < x_size; i++) {
        initialize(i + x_base, 64, z_base);
        for (int j = 0; j < z_size; j++) {
          BiomeMap bm;

          if (snap != biome_css) {
            biomebase = null;
            biome_css = snap;
            if (biome_css instanceof SpoutChunkSnapshot) {
              biome_css = ((SpoutChunkSnapshot) biome_css).chunk;
            }
            biomebase = helper.getBiomeBaseFromSnapshot(biome_css);
          }
          if (biomebase != null) {
            bm = BiomeMap.byBiomeID(helper.getBiomeBaseID(biomebase[bz << 4 | bx]));
          } else {
            Biome bb = snap.getBiome(bx, bz);
            if (bb == null) bm = BiomeMap.NULL;
            else bm = biome_to_bmap[bb.ordinal()];
          }
          biomemap[i][j] = bm;
          int cnt = 0;
          if (i > 0) {
            if (bm == biomemap[i - 1][j]) {
                /* Same as one to left */
              cnt++;
              sameneighborbiomecnt[i - 1][j]++;
            }
            if ((j > 0) && (bm == biomemap[i - 1][j - 1])) {
              cnt++;
              sameneighborbiomecnt[i - 1][j - 1]++;
            }
            if ((j < (z_size - 1)) && (bm == biomemap[i - 1][j + 1])) {
              cnt++;
              sameneighborbiomecnt[i - 1][j + 1]++;
            }
          }
          if ((j > 0) && (biomemap[i][j] == biomemap[i][j - 1])) {
              /* Same as one to above */
            cnt++;
            sameneighborbiomecnt[i][j - 1]++;
          }
          sameneighborbiomecnt[i][j] = (byte) cnt;

          stepPosition(BlockStep.Z_PLUS);
        }
      }
    }
예제 #5
0
  @Override
  public void populate(World world, Random random, Chunk source) {
    ChunkSnapshot snapshot = source.getChunkSnapshot();

    if (random.nextInt(100) < CHANCE_OF_1) {
      {
        int x, z, x2, z2;
        if (random.nextBoolean()) {
          x = random.nextBoolean() ? 0 : 15;
          x2 = x == 0 ? 1 : 14;
          z2 = z = random.nextInt(14) + 1;
        } else {
          x2 = x = random.nextInt(14) + 1;
          z = random.nextBoolean() ? 0 : 15;
          z2 = z == 0 ? 1 : 14;
        }
        if (snapshot.getHighestBlockYAt(x, z) > FLOOR_HEIGHT + MAX_HEIGHT
            && snapshot.getHighestBlockYAt(x2, z2) <= FLOOR_HEIGHT + MIN_HEIGHT) {
          Material type =
              random.nextInt(100) < LIT_CHANCE ? Material.JACK_O_LANTERN : Material.PUMPKIN;
          source
              .getBlock(
                  x,
                  snapshot.getHighestBlockYAt(x2, z2)
                      + random.nextInt(MAX_HEIGHT - MIN_HEIGHT + 1)
                      + MIN_HEIGHT,
                  z)
              .setTypeIdAndData(type.getId(), getData(x, z, x2, z2, type), true);
        }
      }

      if (random.nextInt(100) < CHANCE_OF_2) {
        int x, z, x2, z2;
        if (random.nextBoolean()) {
          x = random.nextBoolean() ? 0 : 15;
          x2 = x == 0 ? 1 : 14;
          z2 = z = random.nextInt(14) + 1;
        } else {
          x2 = x = random.nextInt(14) + 1;
          z = random.nextBoolean() ? 0 : 15;
          z2 = z == 0 ? 1 : 14;
        }
        if (snapshot.getHighestBlockYAt(x, z) > FLOOR_HEIGHT + MAX_HEIGHT
            && snapshot.getHighestBlockYAt(x2, z2) <= FLOOR_HEIGHT + MIN_HEIGHT) {
          Material type =
              random.nextInt(100) < LIT_CHANCE ? Material.JACK_O_LANTERN : Material.PUMPKIN;
          source
              .getBlock(
                  x,
                  snapshot.getHighestBlockYAt(x2, z2)
                      + random.nextInt(MAX_HEIGHT - MIN_HEIGHT + 1)
                      + MIN_HEIGHT,
                  z)
              .setTypeIdAndData(type.getId(), getData(x, z, x2, z2, type), true);
        }
      }
    }
  }
  @Override
  public void render(ChunkSnapshot chunkSnapshot) {
    BufferedImage image = ImageProvider.createImage(Coordinate.SIZE_CHUNK);
    Graphics2D g = (Graphics2D) image.getGraphics();
    for (int x = 0; x < 16; x++) {
      for (int z = 0; z < 16; z++) {
        // TODO: Handle cases where we can start at an opaque non-terrain block
        for (int y = TerrainHelper.getTerrainHeight(x, z, chunkSnapshot);
            y <= chunkSnapshot.getHighestBlockYAt(x, z);
            y++) {
          Material material = Material.getMaterial(chunkSnapshot.getBlockTypeId(x, y, z));
          Color color = getMaterialColor(material, chunkSnapshot, x, y, z);

          if (TerrainHelper.isTerrain(material)) {
            double shading = computeDiffuseShading(chunkSnapshot, x, z, this.normalMap);
            if (shading >= 0) {
              color = tintOrShadeColor(color, shading, 1.0);
            }
          } else if (TerrainHelper.isStructure(material)) {
            double shading = computeDiffuseShading(chunkSnapshot, x, z, this.structureMap);
            if (shading >= 0) {
              if (material.equals(Material.LEAVES)) {
                color = tintOrShadeColor(color, shading, 0.3);
              } else {
                color = tintOrShadeColor(color, shading, 1.0);
              }
            }
          }

          g.setColor(color);
          g.fillRect(x, z, 1, 1);
        }
      }
    }
    imageProvider.setImage(Coordinate.fromSnapshot(chunkSnapshot), image);
  }
 private Color getMaterialColor(
     Material material, ChunkSnapshot chunkSnapshot, int x, int y, int z) {
   MaterialColor materialColor = colorPalette.getMaterialColor(material);
   if (materialColor != null) {
     Color color =
         materialColor.getColor(
             chunkSnapshot.getBlockData(x, y, z),
             x + (chunkSnapshot.getX() * 16),
             z + (chunkSnapshot.getZ() * 16),
             chunkSnapshot.getRawBiomeRainfall(x, z),
             chunkSnapshot.getRawBiomeTemperature(x, z),
             chunkSnapshot.getBiome(x, z));
     if (color != null) {
       if (material.equals(Material.STATIONARY_WATER) && isUnderWater(chunkSnapshot, x, y, z)) {
         color = setAlpha(color, 32);
       }
       return color;
     }
   }
   // RealtimeRender.getLogger().warning(String.format("RealtimeRender: missing color for material
   // '%s'!", material.toString()));
   return new Color(0xFF00FF);
 }
예제 #8
0
 public final Biome getBiome(int x, int z) {
   return chunk.getBiome(x, z);
 }
예제 #9
0
  public int loadChunks(int max_to_load) {
    if (dw.isLoaded() == false) return 0;
    long t0 = System.nanoTime();
    Object queue = helper.getUnloadQueue(helper.getNMSWorld(w));

    int cnt = 0;
    if (iterator == null) iterator = chunks.listIterator();

    DynmapCore.setIgnoreChunkLoads(true);
    // boolean isnormral = w.getEnvironment() == Environment.NORMAL;
    // Load the required chunks.
    while ((cnt < max_to_load) && iterator.hasNext()) {
      DynmapChunk chunk = iterator.next();
      boolean vis = true;
      if (visible_limits != null) {
        vis = false;
        for (VisibilityLimit limit : visible_limits) {
          if ((chunk.x >= limit.x0)
              && (chunk.x <= limit.x1)
              && (chunk.z >= limit.z0)
              && (chunk.z <= limit.z1)) {
            vis = true;
            break;
          }
        }
      }
      if (vis && (hidden_limits != null)) {
        for (VisibilityLimit limit : hidden_limits) {
          if ((chunk.x >= limit.x0)
              && (chunk.x <= limit.x1)
              && (chunk.z >= limit.z0)
              && (chunk.z <= limit.z1)) {
            vis = false;
            break;
          }
        }
      }
      /* Check if cached chunk snapshot found */
      ChunkSnapshot ss = null;
      DynIntHashMap tileData = null;
      SnapshotRec ssr =
          DynmapPlugin.plugin.sscache.getSnapshot(
              dw.getName(), chunk.x, chunk.z, blockdata, biome, biomeraw, highesty);
      if (ssr != null) {
        ss = ssr.ss;
        if (!vis) {
          if (hidestyle == HiddenChunkStyle.FILL_STONE_PLAIN) ss = STONE;
          else if (hidestyle == HiddenChunkStyle.FILL_OCEAN) ss = OCEAN;
          else ss = EMPTY;
        }
        int idx = (chunk.x - x_min) + (chunk.z - z_min) * x_dim;
        snaparray[idx] = ss;
        snaptile[idx] = ssr.tileData;

        continue;
      }
      chunks_attempted++;
      boolean wasLoaded = w.isChunkLoaded(chunk.x, chunk.z);
      boolean didload = false;
      boolean isunloadpending = false;
      if (queue != null) {
        isunloadpending = helper.isInUnloadQueue(queue, chunk.x, chunk.z);
      }
      if (isunloadpending) {
          /* Workaround: can't be pending if not loaded */
        wasLoaded = true;
      }
      try {
        if (!wasLoaded) {
          didload = w.loadChunk(chunk.x, chunk.z, false);
        } else {
            /* If already was loaded, no need to load */
          didload = true;
        }
      } catch (Throwable t) {
          /* Catch chunk error from Bukkit */
        Log.warning("Bukkit error loading chunk " + chunk.x + "," + chunk.z + " on " + w.getName());
        if (!wasLoaded) {
            /* If wasn't loaded, we loaded it if it now is */
          didload = w.isChunkLoaded(chunk.x, chunk.z);
        }
      }
      boolean didgenerate = false;
      /* If we didn't load, and we're supposed to generate, do it */
      if ((!didload) && do_generate && vis)
        didgenerate = didload = w.loadChunk(chunk.x, chunk.z, true);
      /* If it did load, make cache of it */
      if (didload) {
        tileData = new DynIntHashMap();

        Chunk c = w.getChunkAt(chunk.x, chunk.z); /* Get the chunk */
        /* Test if chunk isn't populated */
        boolean populated = true;
        // TODO: figure out why this doesn't appear to be reliable in Bukkit
        // if((nmschunk != null) && (doneflag != null)) {
        //    try {
        //        populated = doneflag.getBoolean(nmschunk);
        //    } catch (IllegalArgumentException e) {
        //    } catch (IllegalAccessException e) {
        //    }
        // }
        if (!vis) {
          if (hidestyle == HiddenChunkStyle.FILL_STONE_PLAIN) ss = STONE;
          else if (hidestyle == HiddenChunkStyle.FILL_OCEAN) ss = OCEAN;
          else ss = EMPTY;
        } else if (!populated) {
            /* If not populated, treat as empty */
          ss = EMPTY;
        } else {
          if (blockdata || highesty) {
            ss = c.getChunkSnapshot(highesty, biome, biomeraw);
            if (use_spout) {
              ss = checkSpoutData(c, ss);
            }
            /* Get tile entity data */
            List<Object> vals = new ArrayList<Object>();
            Map tileents = helper.getTileEntitiesForChunk(c);
            for (Object t : tileents.values()) {
              int te_x = helper.getTileEntityX(t);
              int te_y = helper.getTileEntityY(t);
              int te_z = helper.getTileEntityZ(t);
              int cx = te_x & 0xF;
              int cz = te_z & 0xF;
              int blkid = ss.getBlockTypeId(cx, te_y, cz);
              int blkdat = ss.getBlockData(cx, te_y, cz);
              String[] te_fields = HDBlockModels.getTileEntityFieldsNeeded(blkid, blkdat);
              if (te_fields != null) {
                Object nbtcompound = helper.readTileEntityNBT(t);

                vals.clear();
                for (String id : te_fields) {
                  Object val = helper.getFieldValue(nbtcompound, id);
                  if (val != null) {
                    vals.add(id);
                    vals.add(val);
                  }
                }
                if (vals.size() > 0) {
                  Object[] vlist = vals.toArray(new Object[vals.size()]);
                  tileData.put(getIndexInChunk(cx, te_y, cz), vlist);
                }
              }
            }
          } else ss = w.getEmptyChunkSnapshot(chunk.x, chunk.z, biome, biomeraw);
          if (ss != null) {
            ssr = new SnapshotRec();
            ssr.ss = ss;
            ssr.tileData = tileData;
            DynmapPlugin.plugin.sscache.putSnapshot(
                dw.getName(), chunk.x, chunk.z, ssr, blockdata, biome, biomeraw, highesty);
          }
        }
        snaparray[(chunk.x - x_min) + (chunk.z - z_min) * x_dim] = ss;
        snaptile[(chunk.x - x_min) + (chunk.z - z_min) * x_dim] = tileData;

        /* If wasn't loaded before, we need to do unload */
        if (!wasLoaded) {
          chunks_read++;
          /* It looks like bukkit "leaks" entities - they don't get removed from the world-level table
           * when chunks are unloaded but not saved - removing them seems to do the trick */
          if (!(didgenerate && do_save)) {
            helper.removeEntitiesFromChunk(c);
          }
          /* Since we only remember ones we loaded, and we're synchronous, no player has
           * moved, so it must be safe (also prevent chunk leak, which appears to happen
           * because isChunkInUse defined "in use" as being within 256 blocks of a player,
           * while the actual in-use chunk area for a player where the chunks are managed
           * by the MC base server is 21x21 (or about a 160 block radius).
           * Also, if we did generate it, need to save it */
          w.unloadChunk(chunk.x, chunk.z, didgenerate && do_save, false);
        } else if (isunloadpending) {
            /* Else, if loaded and unload is pending */
          w.unloadChunkRequest(chunk.x, chunk.z); /* Request new unload */
        }
      }
      cnt++;
    }
    DynmapCore.setIgnoreChunkLoads(false);

    if (iterator.hasNext() == false) {
        /* If we're done */
      isempty = true;
      /* Fill missing chunks with empty dummy chunk */
      for (int i = 0; i < snaparray.length; i++) {
        if (snaparray[i] == null) snaparray[i] = EMPTY;
        else if (snaparray[i] != EMPTY) isempty = false;
      }
    }
    total_loadtime += System.nanoTime() - t0;

    return cnt;
  }
예제 #10
0
 public boolean isSectionEmpty(int sy) {
   return chunk.isSectionEmpty(sy);
 }
예제 #11
0
 public final int getHighestBlockYAt(int x, int z) {
   return chunk.getHighestBlockYAt(x, z);
 }
예제 #12
0
 public final int getBlockEmittedLight(int x, int y, int z) {
   return chunk.getBlockEmittedLight(x, y, z);
 }
예제 #13
0
 public final int getBlockData(int x, int y, int z) {
   return chunk.getBlockData(x, y, z);
 }
예제 #14
0
 public final int getBlockTypeId(int x, int y, int z) {
   int id = customids[(x << shiftx) | (z << shiftz) | y];
   if (id != 0) return id;
   return chunk.getBlockTypeId(x, y, z);
 }
예제 #15
0
 public final long getCaptureFullTime() {
   return chunk.getCaptureFullTime();
 }
예제 #16
0
 public final double getRawBiomeRainfall(int x, int z) {
   return chunk.getRawBiomeRainfall(x, z);
 }
예제 #17
0
 public final int getBlockTypeID() {
   if (typeid < 0) {
     typeid = snap.getBlockTypeId(bx, y, bz);
   }
   return typeid;
 }
예제 #18
0
 public final String getWorldName() {
   return chunk.getWorldName();
 }
예제 #19
0
 public final int getZ() {
   return chunk.getZ();
 }
예제 #20
0
 public final int getBlockData() {
   if (blkdata < 0) {
     blkdata = snap.getBlockData(bx, y, bz);
   }
   return blkdata;
 }
예제 #21
0
 public final double getRawBiomeRainfall() {
   return snap.getRawBiomeRainfall(bx, bz);
 }
예제 #22
0
 public final double getRawBiomeTemperature() {
   return snap.getRawBiomeTemperature(bx, bz);
 }
 private static boolean isUnderWater(ChunkSnapshot chunkSnapshot, int x, int y, int z) {
   return Material.getMaterial(chunkSnapshot.getBlockTypeId(x, y + 1, z))
       == Material.STATIONARY_WATER;
 }
예제 #24
0
 public final double getRawBiomeTemperature(int x, int z) {
   return chunk.getRawBiomeTemperature(x, z);
 }