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;
}
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;
}
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);
}
}
Aggregations