public void strikePlayers(List<Player> toStrike) {
    for (Player player : toStrike) {
      Point playerPos = player.getScene().getPosition();
      final int posX = GenericMath.floor(playerPos.getX());
      final int posY = GenericMath.floor(playerPos.getY());
      final int posZ = GenericMath.floor(playerPos.getZ());
      for (int tries = 0; tries < 10; tries++) {
        // pick a random chunk between -4, -4, to 4, 4 relative to the player's position to strike
        // at
        int cx = (ra.nextBoolean() ? -1 : 1) * ra.nextInt(5);
        int cz = (ra.nextBoolean() ? -1 : 1) * ra.nextInt(5);

        // pick random coords to try to strike at inside the chunk (0, 0) to (15, 15)
        int rx = ra.nextInt(16);
        int rz = ra.nextInt(16);

        // pick a offset from the player's y position to strike at (-15 - +15) of their position
        int offsetY = (ra.nextBoolean() ? -1 : 1) * ra.nextInt(15);

        int x = posX + cx * 16 + rx;
        int y = posY + offsetY;
        int z = posZ + cz * 16 + rz;

        if (weather.isRainingAt(x, y, z, false)) {
          int lightning = 1;
          // 30% chance of extra lightning at the spot
          if (ra.nextInt(10) < 3) {
            lightning += ra.nextInt(MAX_LIGHTNING_BRANCHES);
          }
          for (int strikes = 0; strikes < lightning; strikes++) {
            float adjustX = 0.5F;
            float adjustY = 0.0F;
            float adjustZ = 0.5F;
            // if there are extra strikes, tweak their placement slightly
            if (strikes > 0) {
              adjustX += (ra.nextBoolean() ? -1 : 1) * ra.nextInt(2);
              adjustY += (ra.nextBoolean() ? -1 : 1) * ra.nextInt(8);
              adjustZ += (ra.nextBoolean() ? -1 : 1) * ra.nextInt(2);
            }
            World world = getWorld();
            Point point = new Point(world, x + adjustX, y + adjustY, z + adjustZ);
            world.createAndSpawnEntity(point, Lightning.class, LoadOption.NO_LOAD);
            for (Player p : GeneralEffects.LIGHTNING_THUNDER.getNearbyPlayers(point, null, 600)) {
              double dist = p.getScene().getPosition().distanceSquared(point);
              float volume = (float) (10000F - Math.pow(dist, 0.73));
              if (volume > 0) {
                GeneralEffects.LIGHTNING_THUNDER.adjust(volume, 0.7F).play(p, point);
              }
            }
          }
          // success, go to the next player
          break;
        }
      }
    }
  }
Beispiel #2
0
  @Override
  public void onDynamicUpdate(Block block, long updateTime, int data) {
    final Random rand = GenericMath.getRandom();
    if (rand.nextInt(25) == 0) {
      // can we spread?
      int max = MAX_PER_GROUP;
      for (IntVector3 coord : MUSHROOM_RANGE) {
        if (block.translate(coord).isMaterial(this) && --max <= 0) {
          return;
        }
      }
      Cause<?> cause = toCause(block);
      // spread from the source (4 times)
      Block newShroom;
      for (int i = 0; i < 4; i++) {
        newShroom =
            block.translate(
                rand.nextInt(3) - 1, rand.nextInt(2) - rand.nextInt(2), rand.nextInt(3) - 1);
        if (newShroom.isMaterial(VanillaMaterials.AIR)
            && this.canCreate(newShroom, (short) 0, cause)) {
          block = newShroom;
        }
      }
      // try to place at last
      if (block.isMaterial(VanillaMaterials.AIR) && this.canCreate(block, (short) 0, cause)) {
        this.onCreate(block, (short) 0, cause);
      }
    }

    // TODO : delay before update
    block.dynamicUpdate(updateTime + getGrowthTime(block), true);
  }
  public SSAOPostProcessEffect() {
    kernel = new Vector3[kernelSize];
    Random rng = new Random();
    for (int i = 0; i < kernelSize; i++) {
      // Create a set of random vectors along the surface of a hemisphere.
      kernel[i] =
          new Vector3((rng.nextFloat() * 2) - 1, (rng.nextFloat() * 2) - 1, rng.nextFloat());
      // Normalize the vector
      kernel[i] = kernel[i].normalize();

      // Scale it into the hemisphere so the vectors aren't all along the surface.
      // We want the distance from the origin to fall off as we generate more points.
      float scale = (float) i / (float) kernelSize;
      scale = GenericMath.lerp(0.1f, 1.0f, scale * scale);

      kernel[i] = kernel[i].multiply(scale);
    }

    // Generate the noise texture.
    int[] texture = new int[noiseSize * noiseSize];
    for (int i = 0; i < noiseSize * noiseSize; i++) {
      Color c = new Color(rng.nextFloat(), rng.nextFloat(), 0);
      texture[i] = c.getRGB();
    }
    Vector2 resolution = ((Client) Spout.getEngine()).getResolution();
    noiseScale = new Vector2(resolution.getX() / noiseSize, resolution.getY() / noiseSize);
    noise = new ClientTexture(texture, noiseSize, noiseSize);
  }
Beispiel #4
0
  @Override
  public void onDynamicUpdate(Block block, long updateTime, int data) {
    if (block.translate(BlockFace.TOP).getLight() < this.getMinimumLightToGrow()) {
      block.dynamicUpdate(updateTime + getGrowthTime(block), true);
      return;
    }
    int chance = VanillaBlockMaterial.getCropGrowthChance(block) + 1;
    final Random rand = GenericMath.getRandom();
    if (rand.nextInt(chance) == 0) {
      if (isFullyGrown(block)) {
        for (int i = 0; i < BlockFaces.NESW.size(); i++) {
          Block spread = block.translate(BlockFaces.NESW.get(i));
          BlockMaterial material = spread.getMaterial();
          if (material == VanillaMaterials.AIR) {
            BlockMaterial belowSpread = spread.translate(BlockFace.BOTTOM).getMaterial();
            if (belowSpread.isMaterial(
                VanillaMaterials.FARMLAND, VanillaMaterials.DIRT, VanillaMaterials.GRASS)) {
              spread.setMaterial(this.getLastStageMaterial());
              break;
            }
          } else if (material == getLastStageMaterial()) {
            break;
          }
        }
      } else {
        block.addData(1);
      }
    }

    block.dynamicUpdate(updateTime + getGrowthTime(block), true);
  }
Beispiel #5
0
 @Override
 public void onTick(float dt) {
   final Random random = GenericMath.getRandom();
   float secondsUntilWeatherChange = sky.getData().get(VanillaData.WEATHER_CHANGE_TIME);
   secondsUntilWeatherChange -= dt;
   if (forceWeatherUpdate.compareAndSet(true, false) || secondsUntilWeatherChange <= 0) {
     this.sky.updateWeather(getCurrent(), getForecast());
     sky.getData().put(VanillaData.WORLD_WEATHER, getForecast());
     final Weather current = getCurrent();
     Weather forecast = current;
     while (forecast == current) {
       // When Rain/Snow or Thunderstorms occur, always go to Clear after.
       if (current == Weather.RAIN || current == Weather.THUNDERSTORM) {
         forecast = Weather.CLEAR;
       } else {
         forecast = Weather.get(random.nextInt(3));
       }
       setForecast(forecast);
     }
     setForecast(forecast);
     secondsUntilWeatherChange =
         current.getBaseWeatherTime() + random.nextInt(current.getRandomWeatherTime());
     if (Spout.debugMode()) {
       Spout.getLogger()
           .info(
               "Weather changed to: "
                   + current
                   + ", next change in "
                   + secondsUntilWeatherChange / 1000F
                   + "s");
     }
   }
   float currentRainStrength = sky.getData().get(VanillaData.CURRENT_RAIN_STRENGTH);
   sky.getData().put(VanillaData.PREVIOUS_RAIN_STRENGTH, currentRainStrength);
   if (this.isRaining()) {
     currentRainStrength = Math.min(1.0f, currentRainStrength + 0.01f);
   } else {
     currentRainStrength = Math.max(0.0f, currentRainStrength - 0.01f);
   }
   sky.getData().put(VanillaData.CURRENT_RAIN_STRENGTH, currentRainStrength);
   if (hasLightning()) {
     lightning.onTick(dt);
   }
   if (getCurrent().isRaining()) {
     snowfall.onTick(dt);
   }
   sky.getData().put(VanillaData.WEATHER_CHANGE_TIME, secondsUntilWeatherChange);
 }
Beispiel #6
0
 private long getGrowthTime(Block block) {
   return 120000L + GenericMath.getRandom().nextInt(120000);
 }
Beispiel #7
0
  @Override
  public void onInteractBy(Entity entity, Block block, Action type, BlockFace clickedFace) {
    super.onInteractBy(entity, block, type, clickedFace);
    Slot inv = PlayerUtil.getHeldSlot(entity);

    if (inv != null
        && inv.get() != null
        && inv.get().isMaterial(Dye.BONE_MEAL)
        && type.equals(Action.RIGHT_CLICK)) {
      // This flag is used to determine if we should remove a Bone Meal if at least one block
      // gets a Tall Grass attached to the top of it, then we should remove a bone meal.
      boolean shouldConsume = false;

      final Random random = GenericMath.getRandom();
      // Minecraft does grass growing by Bone Meal as follows. Keep in mind the radius is 8.
      // - Tall Grass is placed 9/10 times.
      // - If Tall Grass fails, place Dandelion 2/3 times (within the 1/10 window Tall Grass failed
      // on)
      // - If Dandelion fails, place Rose within the 1/3 times window that Dandelion failed (which
      // is within the 1/10 window Tall Grass failed on).
      for (int dx = -4; dx < 4; dx++) {
        for (int dy = -1; dy <= 1; dy++) {
          for (int dz = -4; dz < 4; dz++) {
            // Fertilization only occurs 1/3 times.
            if (random.nextInt(3) != 2) {
              continue;
            }
            // Grass/flowers have lower chance to go to a lower/higher height than the center block
            // is at.
            // It incurs another 1/3 times. Only do this when iterating over -1 or 1 on the dy,
            // otherwise its on the same
            // plane and we don't care.
            if (dy != 0) {
              if (random.nextInt(3) != 2) {
                continue;
              }
            }

            final Block around = block.translate(dx, dy, dz);

            // Only spread to Grass blocks
            if (!around.getMaterial().equals(VanillaMaterials.GRASS)) {
              continue;
            }

            final Block aboveAround = around.translate(BlockFace.TOP);

            // Make sure the block above the translated one is Air.
            if (!aboveAround.getMaterial().equals(VanillaMaterials.AIR)) {
              continue;
            }

            if (random.nextInt(10) != 0) {
              if (VanillaMaterials.TALL_GRASS.canAttachTo(around, BlockFace.TOP)) {
                aboveAround.setMaterial(VanillaMaterials.TALL_GRASS);
                shouldConsume = true;
              }
            } else if (random.nextInt(3) != 0) {
              if (VanillaMaterials.DANDELION.canAttachTo(around, BlockFace.TOP)) {
                aboveAround.setMaterial(VanillaMaterials.DANDELION);
                shouldConsume = true;
              }
            } else {
              if (VanillaMaterials.ROSE.canAttachTo(around, BlockFace.TOP)) {
                aboveAround.setMaterial(VanillaMaterials.ROSE);
                shouldConsume = true;
              }
            }
          }
        }
      }

      if (!PlayerUtil.isCostSuppressed(entity) && shouldConsume) {
        inv.addAmount(-1);
      }
    }
  }
Beispiel #8
0
 @Override
 public long getSpreadingTime(Block b) {
   return 60000L + GenericMath.getRandom().nextInt(60000) * 3;
 }
Beispiel #9
0
 @Override
 public SpoutBlock getBlock(float x, float y, float z) {
   return this.getBlock(GenericMath.floor(x), GenericMath.floor(y), GenericMath.floor(z));
 }
Beispiel #10
0
 protected long getGrowthTime(Block block) {
   return 10000L + GenericMath.getRandom().nextInt(60000);
 }