@Override
 public void onPostDestroy(Block block, Set<Flag> flags) {
   // TODO stack items together for more performance
   final Random random = GenericMath.getRandom();
   for (ItemStack item : this.getDrops().getDrops(random, flags)) {
     Item.dropNaturally(block.getPosition(), item);
   }
 }
 /**
  * Called when this block is destroyed because of an explosion
  *
  * @param block that got ignition
  * @param cause of the ignition
  */
 public void onIgnite(Block block, Cause<?> cause) {
   HashSet<Flag> dropFlags = new HashSet<Flag>();
   if (GenericMath.getRandom().nextInt(100) < 77) {
     dropFlags.add(DropFlags.NO_DROPS);
   } else {
     dropFlags.add(DropFlags.EXPLOSION_DROPS);
   }
   this.destroy(block, dropFlags, cause);
 }
 @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 (VanillaPlugin.getInstance().getEngine().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 #4
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)) {
      if (!PlayerUtil.isCostSuppressed(entity)) {
        inv.addAmount(-1);
      }
      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);
              }
            } else if (random.nextInt(3) != 0) {
              if (VanillaMaterials.DANDELION.canAttachTo(around, BlockFace.TOP)) {
                aboveAround.setMaterial(VanillaMaterials.DANDELION);
              }
            } else {
              if (VanillaMaterials.ROSE.canAttachTo(around, BlockFace.TOP)) {
                aboveAround.setMaterial(VanillaMaterials.ROSE);
              }
            }
          }
        }
      }
    }
  }
Beispiel #5
0
 @Override
 public long getSpreadingTime(Block b) {
   return 60000L + GenericMath.getRandom().nextInt(60000) * 3;
 }
  private void generateCaveBranch(
      CuboidBlockMaterialBuffer blockData,
      Vector3f chunk,
      Vector3f target,
      double horizontalScale,
      double verticalScale,
      double horizontalAngle,
      double verticalAngle,
      int startingNode,
      int nodeAmount,
      Random random) {

    final Vector3f middle = new Vector3f(chunk.getX() + 8, 0, chunk.getZ() + 8);
    double horizontalOffset = 0;
    double verticalOffset = 0;
    random = new Random(random.nextLong());

    if (nodeAmount <= 0) {
      final int size = (OVERLAP - 1) * 16;
      nodeAmount = size - random.nextInt(size / 4);
    }

    final int intersectionNode = random.nextInt(nodeAmount / 2) + nodeAmount / 4;
    final boolean extraVerticalScale = random.nextInt(6) == 0;
    final boolean lastNode;

    if (startingNode == -1) {
      startingNode = nodeAmount / 2;
      lastNode = true;
    } else {
      lastNode = false;
    }

    for (; startingNode < nodeAmount; startingNode++) {
      final double horizontalSize =
          1.5 + TrigMath.sin((float) (startingNode * Math.PI / nodeAmount)) * horizontalScale;
      final double verticalSize = horizontalSize * verticalScale;
      target = target.add(Vector3f.createDirection((float) horizontalAngle, (float) verticalAngle));

      if (extraVerticalScale) {
        verticalAngle *= 0.92;
      } else {
        verticalAngle *= 0.7;
      }

      verticalAngle += verticalOffset * 0.1;
      horizontalAngle += horizontalOffset * 0.1;
      verticalOffset *= 0.9;
      horizontalOffset *= 0.75;
      verticalOffset += (random.nextDouble() - random.nextDouble()) * random.nextDouble() * 2;
      horizontalOffset += (random.nextDouble() - random.nextDouble()) * random.nextDouble() * 4;

      if (!lastNode) {

        if (startingNode == intersectionNode && horizontalScale > 1) {
          generateCaveBranch(
              blockData,
              chunk,
              target,
              random.nextDouble() * 0.5f + 0.5f,
              1,
              horizontalAngle - ((float) Math.PI / 2),
              verticalAngle / 3,
              startingNode,
              nodeAmount,
              new Random(random.nextLong()));
          generateCaveBranch(
              blockData,
              chunk,
              target,
              random.nextDouble() * 0.5f + 0.5f,
              1,
              horizontalAngle + ((float) Math.PI / 2),
              verticalAngle / 3,
              startingNode,
              nodeAmount,
              new Random(random.nextLong()));
          return;
        }

        if (random.nextInt(4) == 0) {
          continue;
        }
      }

      final double xOffset = target.getX() - middle.getX();
      final double zOffset = target.getZ() - middle.getZ();
      final double nodesLeft = nodeAmount - startingNode;
      final double offsetHorizontalScale = horizontalScale + 18;

      if ((xOffset * xOffset + zOffset * zOffset) - nodesLeft * nodesLeft
          > offsetHorizontalScale * offsetHorizontalScale) {
        return;
      }

      if (target.getX() < middle.getX() - 16 - horizontalSize * 2
          || target.getZ() < middle.getZ() - 16 - horizontalSize * 2
          || target.getX() > middle.getX() + 16 + horizontalSize * 2
          || target.getZ() > middle.getZ() + 16 + horizontalSize * 2) {
        continue;
      }

      final Vector3f start =
          new Vector3f(
              GenericMath.floor(target.getX() - horizontalSize) - chunk.getFloorX() - 1,
              GenericMath.floor(target.getY() - verticalSize) - 1,
              GenericMath.floor(target.getZ() - horizontalSize) - chunk.getFloorZ() - 1);
      final Vector3f end =
          new Vector3f(
              GenericMath.floor(target.getX() + horizontalSize) - chunk.getFloorX() + 1,
              GenericMath.floor(target.getY() + verticalSize) + 1,
              GenericMath.floor(target.getZ() + horizontalSize) - chunk.getFloorZ() + 1);
      final NetherCaveNode node =
          new NetherCaveNode(blockData, chunk, start, end, target, verticalSize, horizontalSize);

      if (node.canPlace()) {
        node.place();
      }

      if (lastNode) {
        break;
      }
    }
  }
 private static Vector3f clamp(Vector3f point) {
   return new Vector3f(
       GenericMath.clamp(point.getFloorX(), 0, 16),
       GenericMath.clamp(point.getFloorY(), 1, 120),
       GenericMath.clamp(point.getFloorZ(), 0, 16));
 }