public boolean explodeWithEvent() { if (power < 0.1f) return true; Set<BlockVector> droppedBlocks = calculateBlocks(); EntityExplodeEvent event = EventFactory.callEvent( new EntityExplodeEvent(source, location, toBlockList(droppedBlocks), yield)); if (event.isCancelled()) return false; this.yield = event.getYield(); playOutSoundAndParticles(); List<Block> blocks = toBlockList(droppedBlocks); for (Block block : blocks) { handleBlockExplosion((GlowBlock) block); } if (incendiary) { for (Block block : blocks) { setBlockOnFire((GlowBlock) block); } } Collection<GlowPlayer> affectedPlayers = damageEntities(); for (GlowPlayer player : affectedPlayers) { playOutExplosion(player, droppedBlocks); } return true; }
/** Populate a single chunk if needed. */ private void populateChunk(int x, int z, boolean force) { GlowChunk chunk = getChunk(x, z); // cancel out if it's already populated if (chunk.isPopulated()) { return; } // cancel out if the 3x3 around it isn't available for (int x2 = x - 1; x2 <= x + 1; ++x2) { for (int z2 = z - 1; z2 <= z + 1; ++z2) { if (!getChunk(x2, z2).isLoaded() && (!force || !loadChunk(x2, z2, true))) { return; } } } // it might have loaded since before, so check again that it's not already populated if (chunk.isPopulated()) { return; } chunk.setPopulated(true); Random random = new Random(world.getSeed()); long xRand = random.nextLong() / 2 * 2 + 1; long zRand = random.nextLong() / 2 * 2 + 1; random.setSeed((long) x * xRand + (long) z * zRand ^ world.getSeed()); for (BlockPopulator p : world.getPopulators()) { p.populate(world, random, chunk); } EventFactory.callEvent(new ChunkPopulateEvent(chunk)); }
/** * Call the ChunkIoService to load a chunk, optionally generating the chunk. * * @param x The X coordinate of the chunk to load. * @param z The Y coordinate of the chunk to load. * @param generate Whether to generate the chunk if needed. * @return True on success, false on failure. */ public boolean loadChunk(int x, int z, boolean generate) { GlowChunk chunk = getChunk(x, z); // try to load chunk try { if (service.read(chunk)) { EventFactory.callEvent(new ChunkLoadEvent(chunk, false)); return true; } } catch (Exception e) { GlowServer.logger.log(Level.SEVERE, "Error while loading chunk (" + x + "," + z + ")", e); // an error in chunk reading may have left the chunk in an invalid state // (i.e. double initialization errors), so it's forcibly unloaded here chunk.unload(false, false); } // stop here if we can't generate if (!generate) { return false; } // get generating try { generateChunk(chunk, x, z); } catch (Throwable ex) { GlowServer.logger.log(Level.SEVERE, "Error while generating chunk (" + x + "," + z + ")", ex); return false; } EventFactory.callEvent(new ChunkLoadEvent(chunk, true)); // right now, forcePopulate takes care of populating chunks that players actually see. /*for (int x2 = x - 1; x2 <= x + 1; ++x2) { for (int z2 = z - 1; z2 <= z + 1; ++z2) { populateChunk(x2, z2, false); } }*/ return true; }
private void setBlockOnFire(GlowBlock block) { if (random.nextInt(3) != 0) return; Block below = block.getRelative(BlockFace.DOWN); // TODO: check for flammable blocks Material belowType = below.getType(); if (belowType == Material.AIR || belowType == Material.FIRE) return; BlockIgniteEvent event = EventFactory.callEvent( new BlockIgniteEvent(block, BlockIgniteEvent.IgniteCause.EXPLOSION, source)); if (event.isCancelled()) return; block.setType(Material.FIRE); }