Search in sources :

Example 1 with BlockUpdateEvent

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

Example 2 with BlockUpdateEvent

use of cn.nukkit.event.block.BlockUpdateEvent 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 3 with BlockUpdateEvent

use of cn.nukkit.event.block.BlockUpdateEvent in project Nukkit by Nukkit.

the class Level method updateAround.

public void updateAround(int x, int y, int z) {
    BlockUpdateEvent ev;
    this.server.getPluginManager().callEvent(ev = new BlockUpdateEvent(this.getBlock(x, y - 1, z)));
    if (!ev.isCancelled()) {
        ev.getBlock().onUpdate(BLOCK_UPDATE_NORMAL);
    }
    this.server.getPluginManager().callEvent(ev = new BlockUpdateEvent(this.getBlock(x, y + 1, z)));
    if (!ev.isCancelled()) {
        ev.getBlock().onUpdate(BLOCK_UPDATE_NORMAL);
    }
    this.server.getPluginManager().callEvent(ev = new BlockUpdateEvent(this.getBlock(x - 1, y, z)));
    if (!ev.isCancelled()) {
        ev.getBlock().onUpdate(BLOCK_UPDATE_NORMAL);
    }
    this.server.getPluginManager().callEvent(ev = new BlockUpdateEvent(this.getBlock(x + 1, y, z)));
    if (!ev.isCancelled()) {
        ev.getBlock().onUpdate(BLOCK_UPDATE_NORMAL);
    }
    this.server.getPluginManager().callEvent(ev = new BlockUpdateEvent(this.getBlock(x, y, z - 1)));
    if (!ev.isCancelled()) {
        ev.getBlock().onUpdate(BLOCK_UPDATE_NORMAL);
    }
    this.server.getPluginManager().callEvent(ev = new BlockUpdateEvent(this.getBlock(x, y, z + 1)));
    if (!ev.isCancelled()) {
        ev.getBlock().onUpdate(BLOCK_UPDATE_NORMAL);
    }
}
Also used : BlockUpdateEvent(cn.nukkit.event.block.BlockUpdateEvent)

Aggregations

BlockUpdateEvent (cn.nukkit.event.block.BlockUpdateEvent)3 Block (cn.nukkit.block.Block)2 Entity (cn.nukkit.entity.Entity)2 ItemBlock (cn.nukkit.item.ItemBlock)2 Player (cn.nukkit.Player)1 BlockAir (cn.nukkit.block.BlockAir)1 BlockTNT (cn.nukkit.block.BlockTNT)1 BlockEntity (cn.nukkit.blockentity.BlockEntity)1 EntityDamageByBlockEvent (cn.nukkit.event.entity.EntityDamageByBlockEvent)1 EntityDamageByEntityEvent (cn.nukkit.event.entity.EntityDamageByEntityEvent)1 EntityDamageEvent (cn.nukkit.event.entity.EntityDamageEvent)1 EntityExplodeEvent (cn.nukkit.event.entity.EntityExplodeEvent)1 Item (cn.nukkit.item.Item)1 BaseFullChunk (cn.nukkit.level.format.generic.BaseFullChunk)1 HugeExplodeSeedParticle (cn.nukkit.level.particle.HugeExplodeSeedParticle)1 ExplodePacket (cn.nukkit.network.protocol.ExplodePacket)1 ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1