Search in sources :

Example 6 with FullChunk

use of cn.nukkit.level.format.FullChunk in project Nukkit by Nukkit.

the class LevelProviderConverter method perform.

LevelProvider perform() throws IOException {
    new File(path).mkdir();
    File dat = new File(provider.getPath(), "level.dat.old");
    new File(provider.getPath(), "level.dat").renameTo(dat);
    Utils.copyFile(dat, new File(path, "level.dat"));
    LevelProvider result;
    try {
        if (provider instanceof LevelDB) {
            try (FileInputStream stream = new FileInputStream(path + "level.dat")) {
                stream.skip(8);
                CompoundTag levelData = NBTIO.read(stream, ByteOrder.LITTLE_ENDIAN);
                if (levelData != null) {
                    NBTIO.writeGZIPCompressed(new CompoundTag().putCompound("Data", levelData), new FileOutputStream(path + "level.dat"));
                } else {
                    throw new IOException("LevelData can not be null");
                }
            } catch (IOException e) {
                throw new LevelException("Invalid level.dat");
            }
        }
        result = toClass.getConstructor(Level.class, String.class).newInstance(level, path);
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
    if (toClass == Anvil.class) {
        if (provider instanceof McRegion) {
            new File(path, "region").mkdir();
            for (File file : new File(provider.getPath() + "region/").listFiles()) {
                Matcher m = Pattern.compile("-?\\d+").matcher(file.getName());
                int regionX, regionZ;
                try {
                    if (m.find()) {
                        regionX = Integer.parseInt(m.group());
                    } else
                        continue;
                    if (m.find()) {
                        regionZ = Integer.parseInt(m.group());
                    } else
                        continue;
                } catch (NumberFormatException e) {
                    continue;
                }
                RegionLoader region = new RegionLoader(provider, regionX, regionZ);
                for (Integer index : region.getLocationIndexes()) {
                    int chunkX = index & 0x1f;
                    int chunkZ = index >> 5;
                    BaseFullChunk old = region.readChunk(chunkX, chunkZ);
                    if (old == null)
                        continue;
                    int x = (regionX << 5) | chunkX;
                    int z = (regionZ << 5) | chunkZ;
                    FullChunk chunk = new ChunkConverter(result).from(old).to(Chunk.class).perform();
                    result.saveChunk(x, z, chunk);
                }
                region.close();
            }
        }
        if (provider instanceof LevelDB) {
            new File(path, "region").mkdir();
            for (byte[] key : ((LevelDB) provider).getTerrainKeys()) {
                int x = getChunkX(key);
                int z = getChunkZ(key);
                BaseFullChunk old = ((LevelDB) provider).readChunk(x, z);
                FullChunk chunk = new ChunkConverter(result).from(old).to(Chunk.class).perform();
                result.saveChunk(x, z, chunk);
            }
        }
        result.doGarbageCollection();
    }
    return result;
}
Also used : LevelDB(cn.nukkit.level.format.leveldb.LevelDB) Matcher(java.util.regex.Matcher) LevelProvider(cn.nukkit.level.format.LevelProvider) LevelException(cn.nukkit.utils.LevelException) IOException(java.io.IOException) Chunk(cn.nukkit.level.format.anvil.Chunk) BaseFullChunk(cn.nukkit.level.format.generic.BaseFullChunk) FullChunk(cn.nukkit.level.format.FullChunk) FileInputStream(java.io.FileInputStream) IOException(java.io.IOException) LevelException(cn.nukkit.utils.LevelException) RegionLoader(cn.nukkit.level.format.mcregion.RegionLoader) BaseFullChunk(cn.nukkit.level.format.generic.BaseFullChunk) FullChunk(cn.nukkit.level.format.FullChunk) ChunkConverter(cn.nukkit.level.format.generic.ChunkConverter) FileOutputStream(java.io.FileOutputStream) BaseFullChunk(cn.nukkit.level.format.generic.BaseFullChunk) McRegion(cn.nukkit.level.format.mcregion.McRegion) File(java.io.File) CompoundTag(cn.nukkit.nbt.tag.CompoundTag)

Example 7 with FullChunk

use of cn.nukkit.level.format.FullChunk in project Nukkit by Nukkit.

the class Nether method generateChunk.

@Override
public void generateChunk(int chunkX, int chunkZ) {
    this.nukkitRandom.setSeed(chunkX * localSeed1 ^ chunkZ * localSeed2 ^ this.level.getSeed());
    double[][][] noise = Generator.getFastNoise3D(this.noiseBase, 16, 128, 16, 4, 8, 4, chunkX * 16, 0, chunkZ * 16);
    FullChunk chunk = this.level.getChunk(chunkX, chunkZ);
    for (int x = 0; x < 16; ++x) {
        for (int z = 0; z < 16; ++z) {
            Biome biome = Biome.getBiome(Biome.HELL);
            chunk.setBiomeId(x, z, Biome.HELL);
            int biomecolor = biome.getColor();
            chunk.setBiomeColor(x, z, (biomecolor >> 16), (biomecolor >> 8) & 0xff, (biomecolor & 0xff));
            chunk.setBlockId(x, 0, z, Block.BEDROCK);
            chunk.setBlockId(x, 127, z, Block.BEDROCK);
            for (int y = 1; y <= bedrockDepth; y++) {
                if (nukkitRandom.nextRange(1, 5) == 1) {
                    chunk.setBlockId(x, y, z, Block.BEDROCK);
                    chunk.setBlockId(x, 127 - y, z, Block.BEDROCK);
                }
            }
            for (int y = 1; y < 127; ++y) {
                double noiseValue = (Math.abs(this.emptyHeight - y) / this.emptyHeight) * this.emptyAmplitude - noise[x][z][y];
                noiseValue -= 1 - this.density;
                if (noiseValue > 0) {
                    chunk.setBlockId(x, y, z, Block.NETHERRACK);
                } else if (y <= this.waterHeight) {
                    chunk.setBlockId(x, y, z, Block.STILL_LAVA);
                    chunk.setBlockLight(x, y + 1, z, 15);
                }
            }
        }
    }
    for (Populator populator : this.generationPopulators) {
        populator.populate(this.level, chunkX, chunkZ, this.nukkitRandom);
    }
}
Also used : FullChunk(cn.nukkit.level.format.FullChunk) Biome(cn.nukkit.level.generator.biome.Biome)

Example 8 with FullChunk

use of cn.nukkit.level.format.FullChunk in project Nukkit by Nukkit.

the class Normal method generateChunk.

@Override
public void generateChunk(int chunkX, int chunkZ) {
    this.nukkitRandom.setSeed(chunkX * localSeed1 ^ chunkZ * localSeed2 ^ this.level.getSeed());
    double[][] seaFloorNoise = Generator.getFastNoise2D(this.noiseSeaFloor, 16, 16, 4, chunkX * 16, 0, chunkZ * 16);
    double[][] landNoise = Generator.getFastNoise2D(this.noiseLand, 16, 16, 4, chunkX * 16, 0, chunkZ * 16);
    double[][] mountainNoise = Generator.getFastNoise2D(this.noiseMountains, 16, 16, 4, chunkX * 16, 0, chunkZ * 16);
    double[][] baseNoise = Generator.getFastNoise2D(this.noiseBaseGround, 16, 16, 4, chunkX * 16, 0, chunkZ * 16);
    double[][] riverNoise = Generator.getFastNoise2D(this.noiseRiver, 16, 16, 4, chunkX * 16, 0, chunkZ * 16);
    FullChunk chunk = this.level.getChunk(chunkX, chunkZ);
    for (int genx = 0; genx < 16; genx++) {
        for (int genz = 0; genz < 16; genz++) {
            Biome biome;
            boolean canBaseGround = false;
            boolean canRiver = true;
            // using a quadratic function which smooth the world
            // y = (2.956x)^2 - 0.6,  (0 <= x <= 2)
            double landHeightNoise = landNoise[genx][genz] + 1F;
            landHeightNoise *= 2.956;
            landHeightNoise = landHeightNoise * landHeightNoise;
            landHeightNoise = landHeightNoise - 0.6F;
            landHeightNoise = landHeightNoise > 0 ? landHeightNoise : 0;
            // generate mountains
            double mountainHeightGenerate = mountainNoise[genx][genz] - 0.2F;
            mountainHeightGenerate = mountainHeightGenerate > 0 ? mountainHeightGenerate : 0;
            int mountainGenerate = (int) (mountainHeight * mountainHeightGenerate);
            int landHeightGenerate = (int) (landHeightRange * landHeightNoise);
            if (landHeightGenerate > landHeightRange) {
                if (landHeightGenerate > landHeightRange) {
                    canBaseGround = true;
                }
                landHeightGenerate = landHeightRange;
            }
            int genyHeight = seaFloorHeight + landHeightGenerate;
            genyHeight += mountainGenerate;
            // prepare for generate ocean, desert, and land
            if (genyHeight < beathStartHeight) {
                if (genyHeight < beathStartHeight - 5) {
                    genyHeight += (int) (seaFloorGenerateRange * seaFloorNoise[genx][genz]);
                }
                biome = Biome.getBiome(Biome.OCEAN);
                if (genyHeight < seaFloorHeight - seaFloorGenerateRange) {
                    genyHeight = seaFloorHeight;
                }
                canRiver = false;
            } else if (genyHeight <= beathStopHeight && genyHeight >= beathStartHeight) {
                biome = Biome.getBiome(Biome.BEACH);
            } else {
                biome = this.pickBiome(chunkX * 16 + genx, chunkZ * 16 + genz);
                if (canBaseGround) {
                    int baseGroundHeight = (int) (landHeightRange * landHeightNoise) - landHeightRange;
                    int baseGroundHeight2 = (int) (basegroundHeight * (baseNoise[genx][genz] + 1F));
                    if (baseGroundHeight2 > baseGroundHeight)
                        baseGroundHeight2 = baseGroundHeight;
                    if (baseGroundHeight2 > mountainGenerate)
                        baseGroundHeight2 = baseGroundHeight2 - mountainGenerate;
                    else
                        baseGroundHeight2 = 0;
                    genyHeight += baseGroundHeight2;
                }
            }
            if (canRiver && genyHeight <= seaHeight - 5) {
                canRiver = false;
            }
            // generate river
            if (canRiver) {
                double riverGenerate = riverNoise[genx][genz];
                if (riverGenerate > -0.25F && riverGenerate < 0.25F) {
                    riverGenerate = riverGenerate > 0 ? riverGenerate : -riverGenerate;
                    riverGenerate = 0.25F - riverGenerate;
                    // y=x^2 * 4 - 0.0000001
                    riverGenerate = riverGenerate * riverGenerate * 4F;
                    // smooth again
                    riverGenerate = riverGenerate - 0.0000001F;
                    riverGenerate = riverGenerate > 0 ? riverGenerate : 0;
                    genyHeight -= riverGenerate * 64;
                    if (genyHeight < seaHeight) {
                        biome = Biome.getBiome(Biome.RIVER);
                        // to generate river floor
                        if (genyHeight <= seaHeight - 8) {
                            int genyHeight1 = seaHeight - 9 + (int) (basegroundHeight * (baseNoise[genx][genz] + 1F));
                            int genyHeight2 = genyHeight < seaHeight - 7 ? seaHeight - 7 : genyHeight;
                            genyHeight = genyHeight1 > genyHeight2 ? genyHeight1 : genyHeight2;
                        }
                    }
                }
            }
            chunk.setBiomeId(genx, genz, biome.getId());
            // biome color
            // todo: smooth chunk color
            int biomecolor = biome.getColor();
            chunk.setBiomeColor(genx, genz, (biomecolor >> 16), (biomecolor >> 8) & 0xff, (biomecolor & 0xff));
            // generating
            int generateHeight = genyHeight > seaHeight ? genyHeight : seaHeight;
            for (int geny = 0; geny <= generateHeight; geny++) {
                if (geny <= bedrockDepth && (geny == 0 || nukkitRandom.nextRange(1, 5) == 1)) {
                    chunk.setBlock(genx, geny, genz, Block.BEDROCK);
                } else if (geny > genyHeight) {
                    if ((biome.getId() == Biome.ICE_PLAINS || biome.getId() == Biome.TAIGA) && geny == seaHeight) {
                        chunk.setBlock(genx, geny, genz, Block.ICE);
                    } else {
                        chunk.setBlock(genx, geny, genz, Block.STILL_WATER);
                    }
                } else {
                    chunk.setBlock(genx, geny, genz, Block.STONE);
                }
            }
        }
    }
    // populator chunk
    for (Populator populator : this.generationPopulators) {
        populator.populate(this.level, chunkX, chunkZ, this.nukkitRandom);
    }
}
Also used : FullChunk(cn.nukkit.level.format.FullChunk) Biome(cn.nukkit.level.generator.biome.Biome)

Example 9 with FullChunk

use of cn.nukkit.level.format.FullChunk in project Nukkit by Nukkit.

the class PopulatorGroundCover method populate.

@Override
public void populate(ChunkManager level, int chunkX, int chunkZ, NukkitRandom random) {
    FullChunk chunk = level.getChunk(chunkX, chunkZ);
    for (int x = 0; x < 16; ++x) {
        for (int z = 0; z < 16; ++z) {
            Biome biome = Biome.getBiome(chunk.getBiomeId(x, z));
            Block[] cover = biome.getGroundCover();
            if (cover != null && cover.length > 0) {
                int diffY = 0;
                if (!cover[0].isSolid()) {
                    diffY = 1;
                }
                int height = chunk.getHeightMap(x, z);
                if (height == 0 || height == 255)
                    height = 126;
                int y;
                for (y = height + 1; y > 0; --y) {
                    int fullId = chunk.getFullBlock(x, y, z);
                    if (fullId != 0 && !Block.get(fullId >> 4).isTransparent()) {
                        break;
                    }
                }
                int startY = Math.min(127, y + diffY);
                int endY = startY - cover.length;
                for (y = startY; y > endY && y >= 0; --y) {
                    Block b = cover[startY - y];
                    int blockId = chunk.getBlockId(x, y, z);
                    if (blockId == 0 && b.isSolid()) {
                        break;
                    }
                    if (b.getDamage() == 0) {
                        chunk.setBlockId(x, y, z, b.getId());
                    } else {
                        chunk.setBlock(x, y, z, b.getId(), b.getDamage());
                    }
                }
            }
        }
    }
}
Also used : FullChunk(cn.nukkit.level.format.FullChunk) Biome(cn.nukkit.level.generator.biome.Biome) Block(cn.nukkit.block.Block)

Example 10 with FullChunk

use of cn.nukkit.level.format.FullChunk in project Nukkit by Nukkit.

the class Level method doChunkGarbageCollection.

public void doChunkGarbageCollection() {
    this.timings.doChunkGC.startTiming();
    // remove all invaild block entities.
    List<BlockEntity> toClose = new ArrayList<>();
    if (!blockEntities.isEmpty()) {
        Iterator<Map.Entry<Long, BlockEntity>> iter = blockEntities.entrySet().iterator();
        while (iter.hasNext()) {
            Map.Entry<Long, BlockEntity> entry = iter.next();
            BlockEntity aBlockEntity = entry.getValue();
            if (aBlockEntity != null) {
                if (!aBlockEntity.isValid()) {
                    iter.remove();
                    aBlockEntity.close();
                }
            } else {
                iter.remove();
            }
        }
    }
    for (Map.Entry<Long, ? extends FullChunk> entry : provider.getLoadedChunks().entrySet()) {
        long index = entry.getKey();
        if (!this.unloadQueue.containsKey(index)) {
            FullChunk chunk = entry.getValue();
            int X = chunk.getX();
            int Z = chunk.getZ();
            if (!this.isSpawnChunk(X, Z)) {
                this.unloadChunkRequest(X, Z, true);
            }
        }
    }
    this.provider.doGarbageCollection();
    this.timings.doChunkGC.stopTiming();
}
Also used : BaseFullChunk(cn.nukkit.level.format.generic.BaseFullChunk) FullChunk(cn.nukkit.level.format.FullChunk) Long2ObjectOpenHashMap(it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap) Int2ObjectOpenHashMap(it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Long2ObjectMap(it.unimi.dsi.fastutil.longs.Long2ObjectMap) BlockEntity(cn.nukkit.blockentity.BlockEntity)

Aggregations

FullChunk (cn.nukkit.level.format.FullChunk)16 BaseFullChunk (cn.nukkit.level.format.generic.BaseFullChunk)8 Biome (cn.nukkit.level.generator.biome.Biome)5 BlockEntity (cn.nukkit.blockentity.BlockEntity)4 Entity (cn.nukkit.entity.Entity)4 Long2ObjectMap (it.unimi.dsi.fastutil.longs.Long2ObjectMap)4 Block (cn.nukkit.block.Block)3 CompoundTag (cn.nukkit.nbt.tag.CompoundTag)3 Int2ObjectOpenHashMap (it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap)3 Long2ObjectOpenHashMap (it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap)3 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)3 ItemBlock (cn.nukkit.item.ItemBlock)2 DoubleTag (cn.nukkit.nbt.tag.DoubleTag)2 FloatTag (cn.nukkit.nbt.tag.FloatTag)2 ListTag (cn.nukkit.nbt.tag.ListTag)2 Player (cn.nukkit.Player)1 EntityPainting (cn.nukkit.entity.item.EntityPainting)1 Chunk (cn.nukkit.level.format.Chunk)1 ChunkSection (cn.nukkit.level.format.ChunkSection)1 LevelProvider (cn.nukkit.level.format.LevelProvider)1