Search in sources :

Example 31 with Entity

use of cn.nukkit.entity.Entity in project Nukkit by Nukkit.

the class Level method unloadChunk.

public boolean unloadChunk(int x, int z, boolean safe, boolean trySave) {
    if (safe && this.isChunkInUse(x, z)) {
        return false;
    }
    if (!this.isChunkLoaded(x, z)) {
        return true;
    }
    this.timings.doChunkUnload.startTiming();
    long index = Level.chunkHash(x, z);
    BaseFullChunk chunk = this.getChunk(x, z);
    if (chunk != null && chunk.getProvider() != null) {
        ChunkUnloadEvent ev = new ChunkUnloadEvent(chunk);
        this.server.getPluginManager().callEvent(ev);
        if (ev.isCancelled()) {
            this.timings.doChunkUnload.stopTiming();
            return false;
        }
    }
    try {
        if (chunk != null) {
            if (trySave && this.getAutoSave()) {
                int entities = 0;
                for (Entity e : chunk.getEntities().values()) {
                    if (e instanceof Player) {
                        continue;
                    }
                    ++entities;
                }
                if (chunk.hasChanged() || !chunk.getBlockEntities().isEmpty() || entities > 0) {
                    this.provider.setChunk(x, z, chunk);
                    this.provider.saveChunk(x, z);
                }
            }
            for (ChunkLoader loader : this.getChunkLoaders(x, z)) {
                loader.onChunkUnloaded(chunk);
            }
        }
        this.provider.unloadChunk(x, z, safe);
    } catch (Exception e) {
        MainLogger logger = this.server.getLogger();
        logger.error(this.server.getLanguage().translateString("nukkit.level.chunkUnloadError", e.toString()));
        logger.logException(e);
    }
    this.timings.doChunkUnload.stopTiming();
    return true;
}
Also used : BlockEntity(cn.nukkit.blockentity.BlockEntity) Entity(cn.nukkit.entity.Entity) Player(cn.nukkit.Player) BaseFullChunk(cn.nukkit.level.format.generic.BaseFullChunk) IOException(java.io.IOException)

Example 32 with Entity

use of cn.nukkit.entity.Entity in project Nukkit by Nukkit.

the class Level method adjustPosToNearbyEntity.

public Vector3 adjustPosToNearbyEntity(Vector3 pos) {
    pos.y = this.getHighestBlockAt(pos.getFloorX(), pos.getFloorZ());
    AxisAlignedBB axisalignedbb = new SimpleAxisAlignedBB(pos.x, pos.y, pos.z, pos.getX(), 255, pos.getZ()).expand(3, 3, 3);
    List<Entity> list = new ArrayList<>();
    for (Entity entity : this.getCollidingEntities(axisalignedbb)) {
        if (entity.isAlive() && canBlockSeeSky(entity)) {
            list.add(entity);
        }
    }
    if (!list.isEmpty()) {
        return list.get(ThreadLocalRandom.current().nextInt(list.size())).getPosition();
    } else {
        if (pos.getY() == -1) {
            pos = pos.up(2);
        }
        return pos;
    }
}
Also used : BlockEntity(cn.nukkit.blockentity.BlockEntity) Entity(cn.nukkit.entity.Entity)

Example 33 with Entity

use of cn.nukkit.entity.Entity in project Nukkit by Nukkit.

the class Level method tickChunks.

private void tickChunks() {
    if (this.chunksPerTicks <= 0 || this.loaders.isEmpty()) {
        this.chunkTickList.clear();
        return;
    }
    int chunksPerLoader = Math.min(200, Math.max(1, (int) (((double) (this.chunksPerTicks - this.loaders.size()) / this.loaders.size() + 0.5))));
    int randRange = 3 + chunksPerLoader / 30;
    randRange = randRange > this.chunkTickRadius ? this.chunkTickRadius : randRange;
    ThreadLocalRandom random = ThreadLocalRandom.current();
    if (!this.loaders.isEmpty()) {
        for (ChunkLoader loader : this.loaders.values()) {
            int chunkX = (int) loader.getX() >> 4;
            int chunkZ = (int) loader.getZ() >> 4;
            long index = Level.chunkHash(chunkX, chunkZ);
            int existingLoaders = Math.max(0, this.chunkTickList.getOrDefault(index, 0));
            this.chunkTickList.put(index, (Integer) (existingLoaders + 1));
            for (int chunk = 0; chunk < chunksPerLoader; ++chunk) {
                int dx = random.nextInt(2 * randRange) - randRange;
                int dz = random.nextInt(2 * randRange) - randRange;
                long hash = Level.chunkHash(dx + chunkX, dz + chunkZ);
                if (!this.chunkTickList.containsKey(hash) && provider.isChunkLoaded(hash)) {
                    this.chunkTickList.put(hash, (Integer) (-1));
                }
            }
        }
    }
    int blockTest = 0;
    if (!chunkTickList.isEmpty()) {
        ObjectIterator<Long2ObjectMap.Entry<Integer>> iter = chunkTickList.long2ObjectEntrySet().fastIterator();
        while (iter.hasNext()) {
            Long2ObjectMap.Entry<Integer> entry = iter.next();
            long index = entry.getLongKey();
            if (!areNeighboringChunksLoaded(index)) {
                iter.remove();
                continue;
            }
            int loaders = entry.getValue();
            int chunkX = getHashX(index);
            int chunkZ = getHashZ(index);
            FullChunk chunk;
            if ((chunk = this.getChunk(chunkX, chunkZ, false)) == null) {
                iter.remove();
                continue;
            } else if (loaders <= 0) {
                iter.remove();
            }
            for (Entity entity : chunk.getEntities().values()) {
                entity.scheduleUpdate();
            }
            int tickSpeed = 3;
            if (tickSpeed > 0) {
                if (this.useSections) {
                    for (ChunkSection section : ((Chunk) chunk).getSections()) {
                        if (!(section instanceof EmptyChunkSection)) {
                            int Y = section.getY();
                            this.updateLCG = this.updateLCG * 3 + 1013904223;
                            int k = this.updateLCG >> 2;
                            for (int i = 0; i < tickSpeed; ++i, k >>= 10) {
                                int x = k & 0x0f;
                                int y = k >> 8 & 0x0f;
                                int z = k >> 16 & 0x0f;
                                int fullId = section.getFullBlock(x, y, z);
                                int blockId = fullId >> 4;
                                if (randomTickBlocks[blockId]) {
                                    Block block = Block.get(fullId, this, chunkX * 16 + x, (Y << 4) + y, chunkZ * 16 + z);
                                    block.onUpdate(BLOCK_UPDATE_RANDOM);
                                }
                            }
                        }
                    }
                } else {
                    for (int Y = 0; Y < 8 && (Y < 3 || blockTest != 0); ++Y) {
                        blockTest = 0;
                        this.updateLCG = this.updateLCG * 3 + 1013904223;
                        int k = this.updateLCG >> 2;
                        for (int i = 0; i < tickSpeed; ++i, k >>= 10) {
                            int x = k & 0x0f;
                            int y = k >> 8 & 0x0f;
                            int z = k >> 16 & 0x0f;
                            int fullId = chunk.getFullBlock(x, y + (Y << 4), z);
                            int blockId = fullId >> 4;
                            blockTest |= fullId;
                            if (this.randomTickBlocks[blockId]) {
                                Block block = Block.get(fullId, this, x, y + (Y << 4), z);
                                block.onUpdate(BLOCK_UPDATE_RANDOM);
                            }
                        }
                    }
                }
            }
        }
    }
    if (this.clearChunksOnTick) {
        this.chunkTickList.clear();
    }
}
Also used : BlockEntity(cn.nukkit.blockentity.BlockEntity) Entity(cn.nukkit.entity.Entity) Long2ObjectMap(it.unimi.dsi.fastutil.longs.Long2ObjectMap) Chunk(cn.nukkit.level.format.Chunk) BaseFullChunk(cn.nukkit.level.format.generic.BaseFullChunk) FullChunk(cn.nukkit.level.format.FullChunk) EmptyChunkSection(cn.nukkit.level.format.generic.EmptyChunkSection) BaseFullChunk(cn.nukkit.level.format.generic.BaseFullChunk) FullChunk(cn.nukkit.level.format.FullChunk) ThreadLocalRandom(java.util.concurrent.ThreadLocalRandom) ItemBlock(cn.nukkit.item.ItemBlock) Block(cn.nukkit.block.Block) EmptyChunkSection(cn.nukkit.level.format.generic.EmptyChunkSection) ChunkSection(cn.nukkit.level.format.ChunkSection)

Example 34 with Entity

use of cn.nukkit.entity.Entity in project Nukkit by Nukkit.

the class Level method dropExpOrb.

public void dropExpOrb(Vector3 source, int exp, Vector3 motion, int delay) {
    motion = (motion == null) ? new Vector3(new java.util.Random().nextDouble() * 0.2 - 0.1, 0.2, new java.util.Random().nextDouble() * 0.2 - 0.1) : motion;
    CompoundTag nbt = new CompoundTag().putList(new ListTag<DoubleTag>("Pos").add(new DoubleTag("", source.getX())).add(new DoubleTag("", source.getY())).add(new DoubleTag("", source.getZ()))).putList(new ListTag<DoubleTag>("Motion").add(new DoubleTag("", motion.getX())).add(new DoubleTag("", motion.getY())).add(new DoubleTag("", motion.getZ()))).putList(new ListTag<FloatTag>("Rotation").add(new FloatTag("", 0)).add(new FloatTag("", 0)));
    Entity entity = new EntityXPOrb(this.getChunk(source.getFloorX() >> 4, source.getFloorZ() >> 4), nbt);
    EntityXPOrb xpOrb = (EntityXPOrb) entity;
    xpOrb.setExp(exp);
    xpOrb.setPickupDelay(delay);
    xpOrb.saveNBT();
    xpOrb.spawnToAll();
}
Also used : BlockEntity(cn.nukkit.blockentity.BlockEntity) Entity(cn.nukkit.entity.Entity) ThreadLocalRandom(java.util.concurrent.ThreadLocalRandom) EntityXPOrb(cn.nukkit.entity.item.EntityXPOrb)

Example 35 with Entity

use of cn.nukkit.entity.Entity in project Nukkit by Nukkit.

the class Chunk method toBinary.

@Override
public byte[] toBinary() {
    CompoundTag nbt = this.getNBT().copy();
    nbt.putInt("xPos", this.getX());
    nbt.putInt("zPos", this.getZ());
    ListTag<CompoundTag> sectionList = new ListTag<>("Sections");
    for (cn.nukkit.level.format.ChunkSection section : this.getSections()) {
        if (section instanceof EmptyChunkSection) {
            continue;
        }
        CompoundTag s = new CompoundTag(null);
        s.putByte("Y", (section.getY()));
        s.putByteArray("Blocks", section.getIdArray());
        s.putByteArray("Data", section.getDataArray());
        s.putByteArray("BlockLight", section.getLightArray());
        s.putByteArray("SkyLight", section.getSkyLightArray());
        sectionList.add(s);
    }
    nbt.putList(sectionList);
    nbt.putIntArray("BiomeColors", this.getBiomeColorArray());
    int[] heightInts = new int[256];
    byte[] heightBytes = this.getHeightMapArray();
    for (int i = 0; i < heightInts.length; i++) {
        heightInts[i] = heightBytes[i] & 0xFF;
    }
    nbt.putIntArray("HeightMap", heightInts);
    ArrayList<CompoundTag> entities = new ArrayList<>();
    for (Entity entity : this.getEntities().values()) {
        if (!(entity instanceof Player) && !entity.closed) {
            entity.saveNBT();
            entities.add(entity.namedTag);
        }
    }
    ListTag<CompoundTag> entityListTag = new ListTag<>("Entities");
    entityListTag.setAll(entities);
    nbt.putList(entityListTag);
    ArrayList<CompoundTag> tiles = new ArrayList<>();
    for (BlockEntity blockEntity : this.getBlockEntities().values()) {
        blockEntity.saveNBT();
        tiles.add(blockEntity.namedTag);
    }
    ListTag<CompoundTag> tileListTag = new ListTag<>("TileEntities");
    tileListTag.setAll(tiles);
    nbt.putList(tileListTag);
    Set<BlockUpdateEntry> entries = this.provider.getLevel().getPendingBlockUpdates(this);
    if (entries != null) {
        ListTag<CompoundTag> tileTickTag = new ListTag<>("TileTicks");
        long totalTime = this.provider.getLevel().getCurrentTick();
        for (BlockUpdateEntry entry : entries) {
            CompoundTag entryNBT = new CompoundTag().putString("i", entry.block.getSaveId()).putInt("x", entry.pos.getFloorX()).putInt("y", entry.pos.getFloorY()).putInt("z", entry.pos.getFloorZ()).putInt("t", (int) (entry.delay - totalTime)).putInt("p", entry.priority);
            tileTickTag.add(entryNBT);
        }
        nbt.putList(tileTickTag);
    }
    BinaryStream extraData = new BinaryStream();
    Map<Integer, Integer> extraDataArray = this.getBlockExtraDataArray();
    extraData.putInt(extraDataArray.size());
    for (Integer key : extraDataArray.keySet()) {
        extraData.putInt(key);
        extraData.putShort(extraDataArray.get(key));
    }
    nbt.putByteArray("ExtraData", extraData.getBuffer());
    CompoundTag chunk = new CompoundTag("");
    chunk.putCompound("Level", nbt);
    try {
        return Zlib.deflate(NBTIO.write(chunk, ByteOrder.BIG_ENDIAN), RegionLoader.COMPRESSION_LEVEL);
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}
Also used : Entity(cn.nukkit.entity.Entity) BlockEntity(cn.nukkit.blockentity.BlockEntity) Player(cn.nukkit.Player) IOException(java.io.IOException) EmptyChunkSection(cn.nukkit.level.format.generic.EmptyChunkSection) BlockEntity(cn.nukkit.blockentity.BlockEntity)

Aggregations

Entity (cn.nukkit.entity.Entity)36 BlockEntity (cn.nukkit.blockentity.BlockEntity)17 Player (cn.nukkit.Player)13 Block (cn.nukkit.block.Block)7 CompoundTag (cn.nukkit.nbt.tag.CompoundTag)7 ItemBlock (cn.nukkit.item.ItemBlock)6 Item (cn.nukkit.item.Item)5 BaseFullChunk (cn.nukkit.level.format.generic.BaseFullChunk)5 ListTag (cn.nukkit.nbt.tag.ListTag)5 FullChunk (cn.nukkit.level.format.FullChunk)4 BlockAir (cn.nukkit.block.BlockAir)3 EntityDamageByEntityEvent (cn.nukkit.event.entity.EntityDamageByEntityEvent)3 EmptyChunkSection (cn.nukkit.level.format.generic.EmptyChunkSection)3 Vector3 (cn.nukkit.math.Vector3)3 DoubleTag (cn.nukkit.nbt.tag.DoubleTag)3 FloatTag (cn.nukkit.nbt.tag.FloatTag)3 IOException (java.io.IOException)3 EntityItem (cn.nukkit.entity.item.EntityItem)2 BlockUpdateEvent (cn.nukkit.event.block.BlockUpdateEvent)2 EntityInventoryChangeEvent (cn.nukkit.event.entity.EntityInventoryChangeEvent)2