Search in sources :

Example 1 with FullChunk

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

the class ItemPainting method onActivate.

@Override
public boolean onActivate(Level level, Player player, Block block, Block target, BlockFace face, double fx, double fy, double fz) {
    FullChunk chunk = level.getChunk((int) block.getX() >> 4, (int) block.getZ() >> 4);
    if (chunk == null) {
        return false;
    }
    if (!target.isTransparent() && face.getIndex() > 1 && !block.isSolid()) {
        int[] direction = { 2, 0, 1, 3 };
        int[] right = { 4, 5, 3, 2 };
        List<EntityPainting.Motive> validMotives = new ArrayList<>();
        for (EntityPainting.Motive motive : EntityPainting.motives) {
            boolean valid = true;
            for (int x = 0; x < motive.width && valid; x++) {
                for (int z = 0; z < motive.height && valid; z++) {
                    if (target.getSide(BlockFace.fromIndex(right[face.getIndex() - 2]), x).isTransparent() || target.up(z).isTransparent() || block.getSide(BlockFace.fromIndex(right[face.getIndex() - 2]), x).isSolid() || block.up(z).isSolid()) {
                        valid = false;
                    }
                }
            }
            if (valid) {
                validMotives.add(motive);
            }
        }
        CompoundTag nbt = new CompoundTag().putByte("Direction", direction[face.getIndex() - 2]).putString("Motive", validMotives.get(ThreadLocalRandom.current().nextInt(validMotives.size())).title).putList(new ListTag<DoubleTag>("Pos").add(new DoubleTag("0", target.x)).add(new DoubleTag("1", target.y)).add(new DoubleTag("2", target.z))).putList(new ListTag<DoubleTag>("Motion").add(new DoubleTag("0", 0)).add(new DoubleTag("1", 0)).add(new DoubleTag("2", 0))).putList(new ListTag<FloatTag>("Rotation").add(new FloatTag("0", direction[face.getIndex() - 2] * 90)).add(new FloatTag("1", 0)));
        EntityPainting entity = new EntityPainting(chunk, nbt);
        if (player.isSurvival()) {
            Item item = player.getInventory().getItemInHand();
            item.setCount(item.getCount() - 1);
            player.getInventory().setItemInHand(item);
        }
        entity.spawnToAll();
        return true;
    }
    return false;
}
Also used : ArrayList(java.util.ArrayList) EntityPainting(cn.nukkit.entity.item.EntityPainting) DoubleTag(cn.nukkit.nbt.tag.DoubleTag) ListTag(cn.nukkit.nbt.tag.ListTag) FullChunk(cn.nukkit.level.format.FullChunk) FloatTag(cn.nukkit.nbt.tag.FloatTag) CompoundTag(cn.nukkit.nbt.tag.CompoundTag)

Example 2 with FullChunk

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

the class ItemSpawnEgg method onActivate.

@Override
public boolean onActivate(Level level, Player player, Block block, Block target, BlockFace face, double fx, double fy, double fz) {
    FullChunk chunk = level.getChunk((int) block.getX() >> 4, (int) block.getZ() >> 4);
    if (chunk == null) {
        return false;
    }
    CompoundTag nbt = new CompoundTag().putList(new ListTag<DoubleTag>("Pos").add(new DoubleTag("", block.getX() + 0.5)).add(new DoubleTag("", block.getY())).add(new DoubleTag("", block.getZ() + 0.5))).putList(new ListTag<DoubleTag>("Motion").add(new DoubleTag("", 0)).add(new DoubleTag("", 0)).add(new DoubleTag("", 0))).putList(new ListTag<FloatTag>("Rotation").add(new FloatTag("", new Random().nextFloat() * 360)).add(new FloatTag("", 0)));
    if (this.hasCustomName()) {
        nbt.putString("CustomName", this.getCustomName());
    }
    Entity entity = Entity.createEntity(this.meta, chunk, nbt);
    if (entity != null) {
        if (player.isSurvival()) {
            Item item = player.getInventory().getItemInHand();
            item.setCount(item.getCount() - 1);
            player.getInventory().setItemInHand(item);
        }
        entity.spawnToAll();
        return true;
    }
    return false;
}
Also used : Entity(cn.nukkit.entity.Entity) FullChunk(cn.nukkit.level.format.FullChunk) FloatTag(cn.nukkit.nbt.tag.FloatTag) Random(java.util.Random) DoubleTag(cn.nukkit.nbt.tag.DoubleTag) ListTag(cn.nukkit.nbt.tag.ListTag) CompoundTag(cn.nukkit.nbt.tag.CompoundTag)

Example 3 with FullChunk

use of cn.nukkit.level.format.FullChunk 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 4 with FullChunk

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

the class Level method doTick.

public void doTick(int currentTick) {
    this.timings.doTick.startTiming();
    updateBlockLight(lightQueue);
    this.checkTime();
    // Tick Weather
    this.rainTime--;
    if (this.rainTime <= 0) {
        if (!this.setRaining(!this.raining)) {
            if (this.raining) {
                setRainTime(ThreadLocalRandom.current().nextInt(12000) + 12000);
            } else {
                setRainTime(ThreadLocalRandom.current().nextInt(168000) + 12000);
            }
        }
    }
    this.thunderTime--;
    if (this.thunderTime <= 0) {
        if (!this.setThundering(!this.thundering)) {
            if (this.thundering) {
                setThunderTime(ThreadLocalRandom.current().nextInt(12000) + 3600);
            } else {
                setThunderTime(ThreadLocalRandom.current().nextInt(168000) + 12000);
            }
        }
    }
    if (this.isThundering()) {
        Map<Long, ? extends FullChunk> chunks = getChunks();
        if (chunks instanceof Long2ObjectOpenHashMap) {
            Long2ObjectOpenHashMap<? extends FullChunk> fastChunks = (Long2ObjectOpenHashMap) chunks;
            ObjectIterator<? extends Long2ObjectMap.Entry<? extends FullChunk>> iter = fastChunks.long2ObjectEntrySet().fastIterator();
            while (iter.hasNext()) {
                Long2ObjectMap.Entry<? extends FullChunk> entry = iter.next();
                performThunder(entry.getLongKey(), entry.getValue());
            }
        } else {
            for (Map.Entry<Long, ? extends FullChunk> entry : getChunks().entrySet()) {
                performThunder(entry.getKey(), entry.getValue());
            }
        }
    }
    this.skyLightSubtracted = this.calculateSkylightSubtracted(1);
    this.levelCurrentTick++;
    this.unloadChunks();
    this.timings.doTickPending.startTiming();
    int polled = 0;
    this.updateQueue.tick(this.getCurrentTick());
    this.timings.doTickPending.stopTiming();
    TimingsHistory.entityTicks += this.updateEntities.size();
    this.timings.entityTick.startTiming();
    if (!this.updateEntities.isEmpty()) {
        for (long id : new ArrayList<>(this.updateEntities.keySet())) {
            Entity entity = this.updateEntities.get(id);
            if (entity.closed || !entity.onUpdate(currentTick)) {
                this.updateEntities.remove(id);
            }
        }
    }
    this.timings.entityTick.stopTiming();
    TimingsHistory.tileEntityTicks += this.updateBlockEntities.size();
    this.timings.blockEntityTick.startTiming();
    if (!this.updateBlockEntities.isEmpty()) {
        for (long id : new ArrayList<>(this.updateBlockEntities.keySet())) {
            if (!this.updateBlockEntities.get(id).onUpdate()) {
                this.updateBlockEntities.remove(id);
            }
        }
    }
    this.timings.blockEntityTick.stopTiming();
    this.timings.tickChunks.startTiming();
    this.tickChunks();
    this.timings.tickChunks.stopTiming();
    if (!this.changedBlocks.isEmpty()) {
        if (!this.players.isEmpty()) {
            ObjectIterator<Long2ObjectMap.Entry<SoftReference<Map<Character, Object>>>> iter = changedBlocks.long2ObjectEntrySet().fastIterator();
            while (iter.hasNext()) {
                Long2ObjectMap.Entry<SoftReference<Map<Character, Object>>> entry = iter.next();
                long index = entry.getKey();
                Map<Character, Object> blocks = entry.getValue().get();
                int chunkX = Level.getHashX(index);
                int chunkZ = Level.getHashZ(index);
                if (blocks == null || blocks.size() > MAX_BLOCK_CACHE) {
                    FullChunk chunk = this.getChunk(chunkX, chunkZ);
                    for (Player p : this.getChunkPlayers(chunkX, chunkZ).values()) {
                        p.onChunkChanged(chunk);
                    }
                } else {
                    Collection<Player> toSend = this.getChunkPlayers(chunkX, chunkZ).values();
                    Player[] playerArray = toSend.toArray(new Player[toSend.size()]);
                    Vector3[] blocksArray = new Vector3[blocks.size()];
                    int i = 0;
                    for (char blockHash : blocks.keySet()) {
                        Vector3 hash = getBlockXYZ(index, blockHash);
                        blocksArray[i++] = hash;
                    }
                    this.sendBlocks(playerArray, blocksArray, UpdateBlockPacket.FLAG_ALL);
                }
            }
        }
        this.changedBlocks.clear();
    }
    this.processChunkRequest();
    if (this.sleepTicks > 0 && --this.sleepTicks <= 0) {
        this.checkSleep();
    }
    for (long index : this.chunkPackets.keySet()) {
        int chunkX = Level.getHashX(index);
        int chunkZ = Level.getHashZ(index);
        Player[] chunkPlayers = this.getChunkPlayers(chunkX, chunkZ).values().stream().toArray(Player[]::new);
        if (chunkPlayers.length > 0) {
            for (DataPacket pk : this.chunkPackets.get(index)) {
                Server.broadcastPacket(chunkPlayers, pk);
            }
        }
    }
    if (gameRules.isStale()) {
        GameRulesChangedPacket packet = new GameRulesChangedPacket();
        packet.gameRules = gameRules;
        Server.broadcastPacket(players.values().toArray(new Player[players.size()]), packet);
        gameRules.refresh();
    }
    this.chunkPackets.clear();
    this.timings.doTick.stopTiming();
}
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) SoftReference(java.lang.ref.SoftReference) Player(cn.nukkit.Player) Long2ObjectMap(it.unimi.dsi.fastutil.longs.Long2ObjectMap) Long2ObjectOpenHashMap(it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap) 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 5 with FullChunk

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

the class Level method getSafeSpawn.

public Position getSafeSpawn(Vector3 spawn) {
    if (spawn == null || spawn.y < 1) {
        spawn = this.getSpawnLocation();
    }
    if (spawn != null) {
        Vector3 v = spawn.floor();
        FullChunk chunk = this.getChunk((int) v.x >> 4, (int) v.z >> 4, false);
        int x = (int) v.x & 0x0f;
        int z = (int) v.z & 0x0f;
        if (chunk != null) {
            int y = (int) Math.min(254, v.y);
            boolean wasAir = chunk.getBlockId(x, y - 1, z) == 0;
            for (; y > 0; --y) {
                int b = chunk.getFullBlock(x, y, z);
                Block block = Block.get(b >> 4, b & 0x0f);
                if (this.isFullBlock(block)) {
                    if (wasAir) {
                        y++;
                        break;
                    }
                } else {
                    wasAir = true;
                }
            }
            for (; y >= 0 && y < 256; ++y) {
                int b = chunk.getFullBlock(x, y + 1, z);
                Block block = Block.get(b >> 4, b & 0x0f);
                if (!this.isFullBlock(block)) {
                    b = chunk.getFullBlock(x, y, z);
                    block = Block.get(b >> 4, b & 0x0f);
                    if (!this.isFullBlock(block)) {
                        return new Position(spawn.x, y == (int) spawn.y ? spawn.y : y, spawn.z, this);
                    }
                } else {
                    ++y;
                }
            }
            v.y = y;
        }
        return new Position(spawn.x, v.y, spawn.z, this);
    }
    return null;
}
Also used : BaseFullChunk(cn.nukkit.level.format.generic.BaseFullChunk) FullChunk(cn.nukkit.level.format.FullChunk) ItemBlock(cn.nukkit.item.ItemBlock) Block(cn.nukkit.block.Block)

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