/** 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)); }
@Override public GlowWorld getWorld(UUID uid) { for (GlowWorld world : worlds.getWorlds()) { if (uid.equals(world.getUID())) { return world; } } return null; }
@Override public Collection<GlowPlayer> getOnlinePlayers() { // todo: provide a view instead of reassembling the list each time ArrayList<GlowPlayer> result = new ArrayList<>(); for (GlowWorld world : worlds.getWorlds()) { for (GlowPlayer player : world.getRawPlayers()) { result.add(player); } } return result; }
/////////////////////////////////////// // Visualize private void playOutSoundAndParticles() { world.playSound( location, Sound.EXPLODE, 4, (1.0F + (random.nextFloat() - random.nextFloat()) * 0.2F) * 0.7F); if (this.power >= 2.0F && this.breakBlocks) { // send huge explosion world.spigot().playEffect(location, Effect.EXPLOSION_HUGE); } else { // send large explosion world.spigot().playEffect(location, Effect.EXPLOSION_LARGE); } }
private List<Block> toBlockList(Collection<BlockVector> locs) { List<Block> blocks = new ArrayList<>(locs.size()); for (BlockVector location : locs) blocks.add( world.getBlockAt(location.getBlockX(), location.getBlockY(), location.getBlockZ())); return blocks; }
private void calculateRay(int ox, int oy, int oz, Collection<BlockVector> result) { double x = ox / 7.5 - 1; double y = oy / 7.5 - 1; double z = oz / 7.5 - 1; Vector direction = new Vector(x, y, z); direction.normalize(); direction.multiply(0.3f); // 0.3 blocks away with each step Location current = location.clone(); float currentPower = calculateStartPower(); while (currentPower > 0) { GlowBlock block = world.getBlockAt(current); if (block.getType() != Material.AIR) { double blastDurability = getBlastDurability(block) / 5d; blastDurability += 0.3F; blastDurability *= 0.3F; currentPower -= blastDurability; if (currentPower > 0) { result.add(new BlockVector(block.getX(), block.getY(), block.getZ())); } } current.add(direction); currentPower -= 0.225f; } }
@Override public boolean unloadWorld(World bWorld, boolean save) { if (!(bWorld instanceof GlowWorld)) { return false; } GlowWorld world = (GlowWorld) bWorld; if (save) { world.setAutoSave(false); world.save(false); } if (worlds.removeWorld(world)) { world.unload(); return true; } return false; }
private Collection<GlowLivingEntity> getNearbyEntities() { // TODO: fetch only necessary entities List<LivingEntity> entities = world.getLivingEntities(); List<GlowLivingEntity> nearbyEntities = new ArrayList<>(); for (LivingEntity entity : entities) { if (distanceTo(entity) / (double) power < 1.) { nearbyEntities.add((GlowLivingEntity) entity); } } return nearbyEntities; }
/** Unload chunks with no locks on them. */ public void unloadOldChunks() { for (Map.Entry<GlowChunk.Key, GlowChunk> entry : chunks.entrySet()) { Set<ChunkLock> lockSet = locks.get(entry.getKey()); if (lockSet == null || lockSet.size() == 0) { if (!entry.getValue().unload(true, true)) { GlowServer.logger.warning( "Failed to unload chunk " + world.getName() + ":" + entry.getKey()); } } // cannot remove old chunks from cache - GlowBlock and GlowBlockState keep references. // they must either be changed to look up the chunk again all the time, or this code left out. /*if (!entry.getValue().isLoaded()) { //GlowServer.logger.info("Removing from cache " + entry.getKey()); chunks.entrySet().remove(entry); locks.remove(entry.getKey()); }*/ } }
private double calculateDamage(GlowEntity entity, double disDivPower) { double damage = world.rayTrace(location, entity); return (damage * (1D - disDivPower)); }
/** * Creates a new chunk manager with the specified I/O service and world generator. * * @param service The I/O service. * @param generator The world generator. */ public ChunkManager(GlowWorld world, ChunkIoService service, ChunkGenerator generator) { this.world = world; this.service = service; this.generator = generator; biomeGrid = MapLayer.initialize(world.getSeed(), world.getEnvironment(), world.getWorldType()); }