@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); }
@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); } } } } } } }
@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)); }