예제 #1
0
  /** 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));
  }
예제 #2
0
 @Override
 public GlowWorld getWorld(UUID uid) {
   for (GlowWorld world : worlds.getWorlds()) {
     if (uid.equals(world.getUID())) {
       return world;
     }
   }
   return null;
 }
예제 #3
0
 @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;
 }
예제 #4
0
  ///////////////////////////////////////
  // 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);
    }
  }
예제 #5
0
 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;
 }
예제 #6
0
  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;
    }
  }
예제 #7
0
 @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;
 }
예제 #8
0
  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;
  }
예제 #9
0
 /** 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());
     }*/
   }
 }
예제 #10
0
 private double calculateDamage(GlowEntity entity, double disDivPower) {
   double damage = world.rayTrace(location, entity);
   return (damage * (1D - disDivPower));
 }
예제 #11
0
 /**
  * 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());
 }