Search in sources :

Example 1 with BaseFullChunk

use of cn.nukkit.level.format.generic.BaseFullChunk in project Nukkit by Nukkit.

the class Level method setChunk.

public void setChunk(int chunkX, int chunkZ, BaseFullChunk chunk, boolean unload) {
    if (chunk == null) {
        return;
    }
    long index = Level.chunkHash(chunkX, chunkZ);
    FullChunk oldChunk = this.getChunk(chunkX, chunkZ, false);
    if (unload && oldChunk != null) {
        this.unloadChunk(chunkX, chunkZ, false, false);
        this.provider.setChunk(chunkX, chunkZ, chunk);
    } else {
        Map<Long, Entity> oldEntities = oldChunk != null ? oldChunk.getEntities() : Collections.emptyMap();
        Map<Long, BlockEntity> oldBlockEntities = oldChunk != null ? oldChunk.getBlockEntities() : Collections.emptyMap();
        if (!oldEntities.isEmpty()) {
            Iterator<Map.Entry<Long, Entity>> iter = oldEntities.entrySet().iterator();
            while (iter.hasNext()) {
                Map.Entry<Long, Entity> entry = iter.next();
                Entity entity = entry.getValue();
                chunk.addEntity(entity);
                if (oldChunk != null) {
                    iter.remove();
                    oldChunk.removeEntity(entity);
                    entity.chunk = chunk;
                }
            }
        }
        if (!oldBlockEntities.isEmpty()) {
            Iterator<Map.Entry<Long, BlockEntity>> iter = oldBlockEntities.entrySet().iterator();
            while (iter.hasNext()) {
                Map.Entry<Long, BlockEntity> entry = iter.next();
                BlockEntity blockEntity = entry.getValue();
                chunk.addBlockEntity(blockEntity);
                if (oldChunk != null) {
                    iter.remove();
                    oldChunk.removeBlockEntity(blockEntity);
                    blockEntity.chunk = chunk;
                }
            }
        }
        this.provider.setChunk(chunkX, chunkZ, chunk);
    }
    chunk.setChanged();
    if (!this.isChunkInUse(index)) {
        this.unloadChunkRequest(chunkX, chunkZ);
    } else {
        for (ChunkLoader loader : this.getChunkLoaders(chunkX, chunkZ)) {
            loader.onChunkChanged(chunk);
        }
    }
}
Also used : BlockEntity(cn.nukkit.blockentity.BlockEntity) Entity(cn.nukkit.entity.Entity) 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)

Example 2 with BaseFullChunk

use of cn.nukkit.level.format.generic.BaseFullChunk in project Nukkit by Nukkit.

the class Level method getBlock.

public Block getBlock(int x, int y, int z) {
    int fullState;
    if (y >= 0 && y < 256) {
        int cx = x >> 4;
        int cz = z >> 4;
        BaseFullChunk chunk = getChunk(cx, cz);
        if (chunk != null) {
            fullState = chunk.getFullBlock(x & 0xF, y, z & 0xF);
        } else {
            fullState = 0;
        }
    } else {
        fullState = 0;
    }
    Block block = this.blockStates[fullState & 0xFFF].clone();
    block.x = x;
    block.y = y;
    block.z = z;
    block.level = this;
    return block;
}
Also used : BaseFullChunk(cn.nukkit.level.format.generic.BaseFullChunk) ItemBlock(cn.nukkit.item.ItemBlock) Block(cn.nukkit.block.Block)

Example 3 with BaseFullChunk

use of cn.nukkit.level.format.generic.BaseFullChunk in project Nukkit by Nukkit.

the class Level method updateBlockLight.

public void updateBlockLight(Map<Long, Map<Character, Object>> map) {
    int size = map.size();
    if (size == 0) {
        return;
    }
    Queue<BlockVector3> lightPropagationQueue = new ConcurrentLinkedQueue<>();
    Queue<Object[]> lightRemovalQueue = new ConcurrentLinkedQueue<>();
    Map<BlockVector3, Object> visited = new ConcurrentHashMap<>(8, 0.9f, 1);
    Map<BlockVector3, Object> removalVisited = new ConcurrentHashMap<>(8, 0.9f, 1);
    Iterator<Map.Entry<Long, Map<Character, Object>>> iter = map.entrySet().iterator();
    while (iter.hasNext() && size-- > 0) {
        Map.Entry<Long, Map<Character, Object>> entry = iter.next();
        iter.remove();
        long index = entry.getKey();
        Map<Character, Object> blocks = entry.getValue();
        int chunkX = Level.getHashX(index);
        int chunkZ = Level.getHashZ(index);
        int bx = chunkX << 4;
        int bz = chunkZ << 4;
        for (char blockHash : blocks.keySet()) {
            int hi = (byte) (blockHash >>> 8);
            int lo = (byte) blockHash;
            int y = lo & 0xFF;
            int x = (hi & 0xF) + bx;
            int z = ((hi >> 4) & 0xF) + bz;
            BaseFullChunk chunk = getChunk(x >> 4, z >> 4, false);
            if (chunk != null) {
                int lcx = x & 0xF;
                int lcz = z & 0xF;
                int oldLevel = chunk.getBlockLight(lcx, y, lcz);
                int newLevel = Block.light[chunk.getBlockId(lcx, y, lcz)];
                if (oldLevel != newLevel) {
                    this.setBlockLightAt(x, y, z, newLevel);
                    if (newLevel < oldLevel) {
                        removalVisited.put(Level.blockHash(x, y, z), changeBlocksPresent);
                        lightRemovalQueue.add(new Object[] { new BlockVector3(x, y, z), oldLevel });
                    } else {
                        visited.put(Level.blockHash(x, y, z), changeBlocksPresent);
                        lightPropagationQueue.add(new BlockVector3(x, y, z));
                    }
                }
            }
        }
    }
    while (!lightRemovalQueue.isEmpty()) {
        Object[] val = lightRemovalQueue.poll();
        BlockVector3 node = (BlockVector3) val[0];
        int lightLevel = (int) val[1];
        this.computeRemoveBlockLight((int) node.x - 1, (int) node.y, (int) node.z, lightLevel, lightRemovalQueue, lightPropagationQueue, removalVisited, visited);
        this.computeRemoveBlockLight((int) node.x + 1, (int) node.y, (int) node.z, lightLevel, lightRemovalQueue, lightPropagationQueue, removalVisited, visited);
        this.computeRemoveBlockLight((int) node.x, (int) node.y - 1, (int) node.z, lightLevel, lightRemovalQueue, lightPropagationQueue, removalVisited, visited);
        this.computeRemoveBlockLight((int) node.x, (int) node.y + 1, (int) node.z, lightLevel, lightRemovalQueue, lightPropagationQueue, removalVisited, visited);
        this.computeRemoveBlockLight((int) node.x, (int) node.y, (int) node.z - 1, lightLevel, lightRemovalQueue, lightPropagationQueue, removalVisited, visited);
        this.computeRemoveBlockLight((int) node.x, (int) node.y, (int) node.z + 1, lightLevel, lightRemovalQueue, lightPropagationQueue, removalVisited, visited);
    }
    while (!lightPropagationQueue.isEmpty()) {
        BlockVector3 node = lightPropagationQueue.poll();
        int lightLevel = this.getBlockLightAt((int) node.x, (int) node.y, (int) node.z) - Block.lightFilter[this.getBlockIdAt((int) node.x, (int) node.y, (int) node.z)];
        if (lightLevel >= 1) {
            this.computeSpreadBlockLight((int) node.x - 1, (int) node.y, (int) node.z, lightLevel, lightPropagationQueue, visited);
            this.computeSpreadBlockLight((int) node.x + 1, (int) node.y, (int) node.z, lightLevel, lightPropagationQueue, visited);
            this.computeSpreadBlockLight((int) node.x, (int) node.y - 1, (int) node.z, lightLevel, lightPropagationQueue, visited);
            this.computeSpreadBlockLight((int) node.x, (int) node.y + 1, (int) node.z, lightLevel, lightPropagationQueue, visited);
            this.computeSpreadBlockLight((int) node.x, (int) node.y, (int) node.z - 1, lightLevel, lightPropagationQueue, visited);
            this.computeSpreadBlockLight(node.x, (int) node.y, (int) node.z + 1, lightLevel, lightPropagationQueue, visited);
        }
    }
}
Also used : BaseFullChunk(cn.nukkit.level.format.generic.BaseFullChunk) ConcurrentLinkedQueue(java.util.concurrent.ConcurrentLinkedQueue) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) 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)

Example 4 with BaseFullChunk

use of cn.nukkit.level.format.generic.BaseFullChunk in project Nukkit by Nukkit.

the class Level method forceLoadChunk.

private BaseFullChunk forceLoadChunk(long index, int x, int z, boolean generate) {
    this.timings.syncChunkLoadTimer.startTiming();
    BaseFullChunk chunk = this.provider.getChunk(x, z, generate);
    if (chunk == null) {
        if (generate) {
            throw new IllegalStateException("Could not create new Chunk");
        }
        this.timings.syncChunkLoadTimer.stopTiming();
        return chunk;
    }
    if (chunk.getProvider() != null) {
        this.server.getPluginManager().callEvent(new ChunkLoadEvent(chunk, !chunk.isGenerated()));
    } else {
        this.unloadChunk(x, z, false);
        this.timings.syncChunkLoadTimer.stopTiming();
        return chunk;
    }
    chunk.initChunk();
    if (!chunk.isLightPopulated() && chunk.isPopulated() && (boolean) this.getServer().getConfig("chunk-ticking.light-updates", false)) {
        this.getServer().getScheduler().scheduleAsyncTask(new LightPopulationTask(this, chunk));
    }
    if (this.isChunkInUse(index)) {
        this.unloadQueue.remove(index);
        for (ChunkLoader loader : this.getChunkLoaders(x, z)) {
            loader.onChunkLoaded(chunk);
        }
    } else {
        this.unloadQueue.put(index, (Long) System.currentTimeMillis());
    }
    this.timings.syncChunkLoadTimer.stopTiming();
    return chunk;
}
Also used : BaseFullChunk(cn.nukkit.level.format.generic.BaseFullChunk)

Example 5 with BaseFullChunk

use of cn.nukkit.level.format.generic.BaseFullChunk in project Nukkit by Nukkit.

the class Level method setBlock.

public boolean setBlock(int x, int y, int z, Block block, boolean direct, boolean update) {
    if (y < 0 || y >= 256) {
        return false;
    }
    BaseFullChunk chunk = this.getChunk(x >> 4, z >> 4, true);
    Block blockPrevious;
    // synchronized (chunk) {
    blockPrevious = chunk.getAndSetBlock(x & 0xF, y, z & 0xF, block);
    if (blockPrevious.getFullId() == block.getFullId()) {
        return false;
    }
    // }
    block.x = x;
    block.y = y;
    block.z = z;
    block.level = this;
    int cx = x >> 4;
    int cz = z >> 4;
    long index = Level.chunkHash(cx, cz);
    if (direct) {
        this.sendBlocks(this.getChunkPlayers(cx, cz).values().stream().toArray(Player[]::new), new Block[] { block }, UpdateBlockPacket.FLAG_ALL_PRIORITY);
    } else {
        addBlockChange(index, x, y, z);
    }
    for (ChunkLoader loader : this.getChunkLoaders(cx, cz)) {
        loader.onBlockChanged(block);
    }
    if (update) {
        if (blockPrevious.isTransparent() != block.isTransparent() || blockPrevious.getLightLevel() != block.getLightLevel()) {
            addLightUpdate(x, y, z);
        }
        BlockUpdateEvent ev = new BlockUpdateEvent(block);
        this.server.getPluginManager().callEvent(ev);
        if (!ev.isCancelled()) {
            for (Entity entity : this.getNearbyEntities(new SimpleAxisAlignedBB(x - 1, y - 1, z - 1, x + 1, y + 1, z + 1))) {
                entity.scheduleUpdate();
            }
            block = ev.getBlock();
            block.onUpdate(BLOCK_UPDATE_NORMAL);
            this.updateAround(x, y, z);
        }
    }
    return true;
}
Also used : BlockEntity(cn.nukkit.blockentity.BlockEntity) Entity(cn.nukkit.entity.Entity) Player(cn.nukkit.Player) BlockUpdateEvent(cn.nukkit.event.block.BlockUpdateEvent) BaseFullChunk(cn.nukkit.level.format.generic.BaseFullChunk) ItemBlock(cn.nukkit.item.ItemBlock) Block(cn.nukkit.block.Block)

Aggregations

BaseFullChunk (cn.nukkit.level.format.generic.BaseFullChunk)26 IOException (java.io.IOException)5 BlockEntity (cn.nukkit.blockentity.BlockEntity)4 FullChunk (cn.nukkit.level.format.FullChunk)4 Player (cn.nukkit.Player)3 Entity (cn.nukkit.entity.Entity)3 Level (cn.nukkit.level.Level)3 Block (cn.nukkit.block.Block)2 ItemBlock (cn.nukkit.item.ItemBlock)2 SimpleChunkManager (cn.nukkit.level.SimpleChunkManager)2 BaseRegionLoader (cn.nukkit.level.format.generic.BaseRegionLoader)2 Generator (cn.nukkit.level.generator.Generator)2 CompoundTag (cn.nukkit.nbt.tag.CompoundTag)2 Int2ObjectOpenHashMap (it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap)2 Long2ObjectMap (it.unimi.dsi.fastutil.longs.Long2ObjectMap)2 Long2ObjectOpenHashMap (it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap)2 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)2 BlockEntitySpawnable (cn.nukkit.blockentity.BlockEntitySpawnable)1 BlockUpdateEvent (cn.nukkit.event.block.BlockUpdateEvent)1 LevelProvider (cn.nukkit.level.format.LevelProvider)1