Search in sources :

Example 11 with BlockAir

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

the class Explosion method explodeB.

public boolean explodeB() {
    HashMap<BlockVector3, Boolean> updateBlocks = new HashMap<>();
    List<Vector3> send = new ArrayList<>();
    Vector3 source = (new Vector3(this.source.x, this.source.y, this.source.z)).floor();
    double yield = (1d / this.size) * 100d;
    if (this.what instanceof Entity) {
        EntityExplodeEvent ev = new EntityExplodeEvent((Entity) this.what, this.source, this.affectedBlocks, yield);
        this.level.getServer().getPluginManager().callEvent(ev);
        if (ev.isCancelled()) {
            return false;
        } else {
            yield = ev.getYield();
            this.affectedBlocks = ev.getBlockList();
        }
    }
    double explosionSize = this.size * 2d;
    double minX = NukkitMath.floorDouble(this.source.x - explosionSize - 1);
    double maxX = NukkitMath.ceilDouble(this.source.x + explosionSize + 1);
    double minY = NukkitMath.floorDouble(this.source.y - explosionSize - 1);
    double maxY = NukkitMath.ceilDouble(this.source.y + explosionSize + 1);
    double minZ = NukkitMath.floorDouble(this.source.z - explosionSize - 1);
    double maxZ = NukkitMath.ceilDouble(this.source.z + explosionSize + 1);
    AxisAlignedBB explosionBB = new SimpleAxisAlignedBB(minX, minY, minZ, maxX, maxY, maxZ);
    Entity[] list = this.level.getNearbyEntities(explosionBB, this.what instanceof Entity ? (Entity) this.what : null);
    for (Entity entity : list) {
        double distance = entity.distance(this.source) / explosionSize;
        if (distance <= 1) {
            Vector3 motion = entity.subtract(this.source).normalize();
            int exposure = 1;
            double impact = (1 - distance) * exposure;
            int damage = (int) (((impact * impact + impact) / 2) * 8 * explosionSize + 1);
            if (this.what instanceof Entity) {
                entity.attack(new EntityDamageByEntityEvent((Entity) this.what, entity, DamageCause.ENTITY_EXPLOSION, damage));
            } else if (this.what instanceof Block) {
                entity.attack(new EntityDamageByBlockEvent((Block) this.what, entity, DamageCause.BLOCK_EXPLOSION, damage));
            } else {
                entity.attack(new EntityDamageEvent(entity, DamageCause.BLOCK_EXPLOSION, damage));
            }
            entity.setMotion(motion.multiply(impact));
        }
    }
    ItemBlock air = new ItemBlock(new BlockAir());
    // Iterator iter = this.affectedBlocks.entrySet().iterator();
    for (Block block : this.affectedBlocks) {
        // Block block = (Block) ((HashMap.Entry) iter.next()).getValue();
        if (block.getId() == Block.TNT) {
            ((BlockTNT) block).prime(new NukkitRandom().nextRange(10, 30));
        } else if (Math.random() * 100 < yield) {
            for (Item drop : block.getDrops(air)) {
                this.level.dropItem(block.add(0.5, 0.5, 0.5), drop);
            }
        }
        this.level.setBlockIdAt((int) block.x, (int) block.y, (int) block.z, 0);
        Vector3 pos = new Vector3(block.x, block.y, block.z);
        for (BlockFace side : BlockFace.values()) {
            Vector3 sideBlock = pos.getSide(side);
            BlockVector3 index = Level.blockHash((int) sideBlock.x, (int) sideBlock.y, (int) sideBlock.z);
            if (!this.affectedBlocks.contains(sideBlock) && !updateBlocks.containsKey(index)) {
                BlockUpdateEvent ev = new BlockUpdateEvent(this.level.getBlock(sideBlock));
                this.level.getServer().getPluginManager().callEvent(ev);
                if (!ev.isCancelled()) {
                    ev.getBlock().onUpdate(Level.BLOCK_UPDATE_NORMAL);
                }
                updateBlocks.put(index, true);
            }
        }
        send.add(new Vector3(block.x - source.x, block.y - source.y, block.z - source.z));
    }
    ExplodePacket pk = new ExplodePacket();
    pk.x = (float) this.source.x;
    pk.y = (float) this.source.y;
    pk.z = (float) this.source.z;
    pk.radius = (float) this.size;
    pk.records = send.stream().toArray(Vector3[]::new);
    this.level.addChunkPacket((int) source.x >> 4, (int) source.z >> 4, pk);
    this.level.addParticle(new HugeExplodeSeedParticle(this.source));
    this.level.addSound(new Vector3(this.source.x, this.source.y, this.source.z), Sound.RANDOM_EXPLODE);
    return true;
}
Also used : Entity(cn.nukkit.entity.Entity) EntityExplodeEvent(cn.nukkit.event.entity.EntityExplodeEvent) HashMap(java.util.HashMap) EntityDamageByBlockEvent(cn.nukkit.event.entity.EntityDamageByBlockEvent) ArrayList(java.util.ArrayList) ExplodePacket(cn.nukkit.network.protocol.ExplodePacket) Item(cn.nukkit.item.Item) HugeExplodeSeedParticle(cn.nukkit.level.particle.HugeExplodeSeedParticle) EntityDamageEvent(cn.nukkit.event.entity.EntityDamageEvent) BlockAir(cn.nukkit.block.BlockAir) ItemBlock(cn.nukkit.item.ItemBlock) BlockTNT(cn.nukkit.block.BlockTNT) EntityDamageByEntityEvent(cn.nukkit.event.entity.EntityDamageByEntityEvent) BlockUpdateEvent(cn.nukkit.event.block.BlockUpdateEvent) ItemBlock(cn.nukkit.item.ItemBlock) Block(cn.nukkit.block.Block)

Example 12 with BlockAir

use of cn.nukkit.block.BlockAir 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 13 with BlockAir

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

Aggregations

BlockAir (cn.nukkit.block.BlockAir)13 ItemBlock (cn.nukkit.item.ItemBlock)11 Item (cn.nukkit.item.Item)8 Block (cn.nukkit.block.Block)4 Player (cn.nukkit.Player)3 Entity (cn.nukkit.entity.Entity)3 Enchantment (cn.nukkit.item.enchantment.Enchantment)3 BlockEntity (cn.nukkit.blockentity.BlockEntity)2 EntityItem (cn.nukkit.entity.item.EntityItem)2 EntityArrow (cn.nukkit.entity.projectile.EntityArrow)2 EntityDamageByEntityEvent (cn.nukkit.event.entity.EntityDamageByEntityEvent)2 EntityInventoryChangeEvent (cn.nukkit.event.entity.EntityInventoryChangeEvent)2 CompoundTag (cn.nukkit.nbt.tag.CompoundTag)2 Random (java.util.Random)2 BlockFurnace (cn.nukkit.block.BlockFurnace)1 BlockFurnaceBurning (cn.nukkit.block.BlockFurnaceBurning)1 BlockLiquid (cn.nukkit.block.BlockLiquid)1 BlockTNT (cn.nukkit.block.BlockTNT)1 BlockWater (cn.nukkit.block.BlockWater)1 BlockEntityChest (cn.nukkit.blockentity.BlockEntityChest)1