Search in sources :

Example 26 with Block

use of cn.nukkit.block.Block in project Nukkit by Nukkit.

the class Level method useItemOn.

public Item useItemOn(Vector3 vector, Item item, BlockFace face, float fx, float fy, float fz, Player player, boolean playSound) {
    Block target = this.getBlock(vector);
    Block block = target.getSide(face);
    if (block.y > 255 || block.y < 0) {
        return null;
    }
    if (target.getId() == Item.AIR) {
        return null;
    }
    if (player != null) {
        PlayerInteractEvent ev = new PlayerInteractEvent(player, item, target, face, target.getId() == 0 ? Action.RIGHT_CLICK_AIR : Action.RIGHT_CLICK_BLOCK);
        if (player.getGamemode() > 2) {
            ev.setCancelled();
        }
        int distance = this.server.getSpawnRadius();
        if (!player.isOp() && distance > -1) {
            Vector2 t = new Vector2(target.x, target.z);
            Vector2 s = new Vector2(this.getSpawnLocation().x, this.getSpawnLocation().z);
            if (!this.server.getOps().getAll().isEmpty() && t.distance(s) <= distance) {
                ev.setCancelled();
            }
        }
        this.server.getPluginManager().callEvent(ev);
        if (!ev.isCancelled()) {
            target.onUpdate(BLOCK_UPDATE_TOUCH);
            if ((!player.isSneaking() || player.getInventory().getItemInHand().isNull()) && target.canBeActivated() && target.onActivate(item, player)) {
                return item;
            }
            if (item.canBeActivated() && item.onActivate(this, player, block, target, face, fx, fy, fz)) {
                if (item.getCount() <= 0) {
                    item = new ItemBlock(new BlockAir(), 0, 0);
                    return item;
                }
            }
        } else {
            return null;
        }
    } else if (target.canBeActivated() && target.onActivate(item, null)) {
        return item;
    }
    Block hand;
    if (item.canBePlaced()) {
        hand = item.getBlock();
        hand.position(block);
    } else {
        return null;
    }
    if (!(block.canBeReplaced() || (hand.getId() == Item.SLAB && block.getId() == Item.SLAB))) {
        return null;
    }
    if (target.canBeReplaced()) {
        block = target;
        hand.position(block);
    }
    if (!hand.canPassThrough() && hand.getBoundingBox() != null) {
        Entity[] entities = this.getCollidingEntities(hand.getBoundingBox());
        int realCount = 0;
        for (Entity e : entities) {
            if (e instanceof EntityArrow || e instanceof EntityItem || (e instanceof Player && ((Player) e).isSpectator())) {
                continue;
            }
            ++realCount;
        }
        if (player != null) {
            Vector3 diff = player.getNextPosition().subtract(player.getPosition());
            if (diff.lengthSquared() > 0.00001) {
                AxisAlignedBB bb = player.getBoundingBox().getOffsetBoundingBox(diff.x, diff.y, diff.z);
                if (hand.getBoundingBox().intersectsWith(bb)) {
                    ++realCount;
                }
            }
        }
        if (realCount > 0) {
            // Entity in block
            return null;
        }
    }
    Tag tag = item.getNamedTagEntry("CanPlaceOn");
    if (tag instanceof ListTag) {
        boolean canPlace = false;
        for (Tag v : ((ListTag<Tag>) tag).getAll()) {
            if (v instanceof StringTag) {
                Item entry = Item.fromString(((StringTag) v).data);
                if (entry.getId() > 0 && entry.getBlock() != null && entry.getBlock().getId() == target.getId()) {
                    canPlace = true;
                    break;
                }
            }
        }
        if (!canPlace) {
            return null;
        }
    }
    if (player != null) {
        BlockPlaceEvent event = new BlockPlaceEvent(player, hand, block, target, item);
        int distance = this.server.getSpawnRadius();
        if (!player.isOp() && distance > -1) {
            Vector2 t = new Vector2(target.x, target.z);
            Vector2 s = new Vector2(this.getSpawnLocation().x, this.getSpawnLocation().z);
            if (!this.server.getOps().getAll().isEmpty() && t.distance(s) <= distance) {
                event.setCancelled();
            }
        }
        this.server.getPluginManager().callEvent(event);
        if (event.isCancelled()) {
            return null;
        }
    }
    if (!hand.place(item, block, target, face, fx, fy, fz, player)) {
        return null;
    }
    if (player != null) {
        if (!player.isCreative()) {
            item.setCount(item.getCount() - 1);
        }
    }
    if (playSound) {
        this.addLevelSoundEvent(hand, LevelSoundEventPacket.SOUND_PLACE, 1, item.getId(), false);
    }
    if (item.getCount() <= 0) {
        item = new ItemBlock(new BlockAir(), 0, 0);
    }
    return item;
}
Also used : BlockAir(cn.nukkit.block.BlockAir) BlockEntity(cn.nukkit.blockentity.BlockEntity) Entity(cn.nukkit.entity.Entity) EntityArrow(cn.nukkit.entity.projectile.EntityArrow) Player(cn.nukkit.Player) BlockPlaceEvent(cn.nukkit.event.block.BlockPlaceEvent) PlayerInteractEvent(cn.nukkit.event.player.PlayerInteractEvent) ItemBlock(cn.nukkit.item.ItemBlock) EntityItem(cn.nukkit.entity.item.EntityItem) Item(cn.nukkit.item.Item) ItemBlock(cn.nukkit.item.ItemBlock) Block(cn.nukkit.block.Block) EntityItem(cn.nukkit.entity.item.EntityItem)

Example 27 with Block

use of cn.nukkit.block.Block in project Nukkit by Nukkit.

the class Level method getCollisionBlocks.

public Block[] getCollisionBlocks(AxisAlignedBB bb, boolean targetFirst) {
    int minX = NukkitMath.floorDouble(bb.getMinX());
    int minY = NukkitMath.floorDouble(bb.getMinY());
    int minZ = NukkitMath.floorDouble(bb.getMinZ());
    int maxX = NukkitMath.ceilDouble(bb.getMaxX());
    int maxY = NukkitMath.ceilDouble(bb.getMaxY());
    int maxZ = NukkitMath.ceilDouble(bb.getMaxZ());
    List<Block> collides = new ArrayList<>();
    if (targetFirst) {
        for (int z = minZ; z <= maxZ; ++z) {
            for (int x = minX; x <= maxX; ++x) {
                for (int y = minY; y <= maxY; ++y) {
                    Block block = this.getBlock(this.temporalVector.setComponents(x, y, z));
                    if (block.getId() != 0 && block.collidesWithBB(bb)) {
                        return new Block[] { block };
                    }
                }
            }
        }
    } else {
        for (int z = minZ; z <= maxZ; ++z) {
            for (int x = minX; x <= maxX; ++x) {
                for (int y = minY; y <= maxY; ++y) {
                    Block block = this.getBlock(this.temporalVector.setComponents(x, y, z));
                    if (block.getId() != 0 && block.collidesWithBB(bb)) {
                        collides.add(block);
                    }
                }
            }
        }
    }
    return collides.stream().toArray(Block[]::new);
}
Also used : ItemBlock(cn.nukkit.item.ItemBlock) Block(cn.nukkit.block.Block)

Example 28 with Block

use of cn.nukkit.block.Block in project Nukkit by Nukkit.

the class Level method useBreakOn.

public Item useBreakOn(Vector3 vector, Item item, Player player, boolean createParticles) {
    if (player != null && player.getGamemode() > 1) {
        return null;
    }
    Block target = this.getBlock(vector);
    Item[] drops;
    if (item == null) {
        item = new ItemBlock(new BlockAir(), 0, 0);
    }
    if (player != null) {
        double breakTime = target.getBreakTime(item, player);
        if (player.isCreative() && breakTime > 0.15) {
            breakTime = 0.15;
        }
        if (player.hasEffect(Effect.SWIFTNESS)) {
            breakTime *= 1 - (0.2 * (player.getEffect(Effect.SWIFTNESS).getAmplifier() + 1));
        }
        if (player.hasEffect(Effect.MINING_FATIGUE)) {
            breakTime *= 1 - (0.3 * (player.getEffect(Effect.MINING_FATIGUE).getAmplifier() + 1));
        }
        Enchantment eff = item.getEnchantment(Enchantment.ID_EFFICIENCY);
        if (eff != null && eff.getLevel() > 0) {
            breakTime *= 1 - (0.3 * eff.getLevel());
        }
        breakTime -= 0.15;
        BlockBreakEvent ev = new BlockBreakEvent(player, target, item, player.isCreative(), (player.lastBreak + breakTime * 1000) > System.currentTimeMillis());
        double distance;
        if (player.isSurvival() && !target.isBreakable(item)) {
            ev.setCancelled();
        } else if (!player.isOp() && (distance = this.server.getSpawnRadius()) > -1) {
            Vector2 t = new Vector2(target.x, target.z);
            Vector2 s = new Vector2(this.getSpawnLocation().x, this.getSpawnLocation().z);
            if (!this.server.getOps().getAll().isEmpty() && t.distance(s) <= distance) {
                ev.setCancelled();
            }
        }
        this.server.getPluginManager().callEvent(ev);
        if (ev.isCancelled()) {
            return null;
        }
        if (!ev.getInstaBreak() && ev.isFastBreak()) {
            return null;
        }
        player.lastBreak = System.currentTimeMillis();
        drops = ev.getDrops();
    } else if (!target.isBreakable(item)) {
        return null;
    } else {
        drops = target.getDrops(item);
    }
    Block above = this.getBlock(new Vector3(target.x, target.y + 1, target.z));
    if (above != null) {
        if (above.getId() == Item.FIRE) {
            this.setBlock(above, new BlockAir(), true);
        }
    }
    Tag tag = item.getNamedTagEntry("CanDestroy");
    if (tag instanceof ListTag) {
        boolean canBreak = false;
        for (Tag v : ((ListTag<Tag>) tag).getAll()) {
            if (v instanceof StringTag) {
                Item entry = Item.fromString(((StringTag) v).data);
                if (entry.getId() > 0 && entry.getBlock() != null && entry.getBlock().getId() == target.getId()) {
                    canBreak = true;
                    break;
                }
            }
        }
        if (!canBreak) {
            return null;
        }
    }
    if (createParticles) {
        Map<Integer, Player> players = this.getChunkPlayers((int) target.x >> 4, (int) target.z >> 4);
        this.addParticle(new DestroyBlockParticle(target.add(0.5), target), players.values());
        if (player != null) {
            players.remove(player.getLoaderId());
        }
    }
    target.onBreak(item);
    BlockEntity blockEntity = this.getBlockEntity(target);
    if (blockEntity != null) {
        if (blockEntity instanceof InventoryHolder) {
            if (blockEntity instanceof BlockEntityChest) {
                ((BlockEntityChest) blockEntity).unpair();
            }
            for (Item chestItem : ((InventoryHolder) blockEntity).getInventory().getContents().values()) {
                this.dropItem(target, chestItem);
            }
        }
        blockEntity.close();
        this.updateComparatorOutputLevel(target);
    }
    item.useOn(target);
    if (item.isTool() && item.getDamage() >= item.getMaxDurability()) {
        item = new ItemBlock(new BlockAir(), 0, 0);
    }
    if (this.gameRules.getBoolean(GameRule.DO_TILE_DROPS)) {
        int dropExp = target.getDropExp();
        if (player != null) {
            player.addExperience(dropExp);
            if (player.isSurvival()) {
                for (int ii = 1; ii <= dropExp; ii++) {
                    this.dropExpOrb(target, 1);
                }
            }
        }
        if (player == null || player.isSurvival()) {
            for (Item drop : drops) {
                if (drop.getCount() > 0) {
                    this.dropItem(vector.add(0.5, 0.5, 0.5), drop);
                }
            }
        }
    }
    return item;
}
Also used : BlockAir(cn.nukkit.block.BlockAir) Player(cn.nukkit.Player) DestroyBlockParticle(cn.nukkit.level.particle.DestroyBlockParticle) ItemBlock(cn.nukkit.item.ItemBlock) EntityItem(cn.nukkit.entity.item.EntityItem) Item(cn.nukkit.item.Item) BlockEntityChest(cn.nukkit.blockentity.BlockEntityChest) ItemBlock(cn.nukkit.item.ItemBlock) Block(cn.nukkit.block.Block) BlockBreakEvent(cn.nukkit.event.block.BlockBreakEvent) Enchantment(cn.nukkit.item.enchantment.Enchantment) InventoryHolder(cn.nukkit.inventory.InventoryHolder) BlockEntity(cn.nukkit.blockentity.BlockEntity)

Example 29 with Block

use of cn.nukkit.block.Block 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)

Aggregations

Block (cn.nukkit.block.Block)29 ItemBlock (cn.nukkit.item.ItemBlock)13 Entity (cn.nukkit.entity.Entity)7 BlockEntity (cn.nukkit.blockentity.BlockEntity)5 Vector3 (cn.nukkit.math.Vector3)5 Player (cn.nukkit.Player)4 BlockAir (cn.nukkit.block.BlockAir)4 Item (cn.nukkit.item.Item)4 BaseFullChunk (cn.nukkit.level.format.generic.BaseFullChunk)4 FullChunk (cn.nukkit.level.format.FullChunk)3 BlockFire (cn.nukkit.block.BlockFire)2 BlockWater (cn.nukkit.block.BlockWater)2 EntityItem (cn.nukkit.entity.item.EntityItem)2 BlockIgniteEvent (cn.nukkit.event.block.BlockIgniteEvent)2 BlockUpdateEvent (cn.nukkit.event.block.BlockUpdateEvent)2 PlayerInteractEvent (cn.nukkit.event.player.PlayerInteractEvent)2 ArrayList (java.util.ArrayList)2 BlockBrewingStand (cn.nukkit.block.BlockBrewingStand)1 BlockDirt (cn.nukkit.block.BlockDirt)1 BlockHugeMushroomBrown (cn.nukkit.block.BlockHugeMushroomBrown)1