mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2026-04-05 23:36:12 +00:00
Restructure Packages (read commit description)
There are now three root packages - Engine: Generator & JSON Scaffolding - Core: Managers, Commands, NMS - Util: Random utility packages
This commit is contained in:
@@ -0,0 +1,238 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2021 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.engine.modifier;
|
||||
|
||||
import com.volmit.iris.engine.noise.FastNoiseDouble;
|
||||
import com.volmit.iris.engine.object.IrisBiome;
|
||||
import com.volmit.iris.engine.object.IrisCaveLayer;
|
||||
import com.volmit.iris.engine.framework.Engine;
|
||||
import com.volmit.iris.engine.framework.EngineAssignedModifier;
|
||||
import com.volmit.iris.engine.hunk.Hunk;
|
||||
import com.volmit.iris.util.*;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
public class IrisCaveModifier extends EngineAssignedModifier<BlockData> {
|
||||
public static final BlockData CAVE_AIR = B.get("CAVE_AIR");
|
||||
public static final BlockData AIR = B.get("AIR");
|
||||
private static final KList<CaveResult> EMPTY = new KList<>();
|
||||
private final FastNoiseDouble gg;
|
||||
private final RNG rng;
|
||||
|
||||
public IrisCaveModifier(Engine engine) {
|
||||
super(engine, "Cave");
|
||||
rng = new RNG(engine.getWorld().getSeed() + 28934555);
|
||||
gg = new FastNoiseDouble(324895L * rng.nextParallelRNG(49678).imax());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onModify(int x, int z, Hunk<BlockData> a) {
|
||||
if (!getDimension().isCaves()) {
|
||||
return;
|
||||
}
|
||||
|
||||
PrecisionStopwatch p = PrecisionStopwatch.start();
|
||||
for (int i = 0; i < a.getWidth(); i++) {
|
||||
for (int j = 0; j < a.getDepth(); j++) {
|
||||
KList<CaveResult> caves = genCaves(x + i, z + j, i, j, a);
|
||||
int he = (int) Math.round(getComplex().getHeightStream().get(x + i, z + j));
|
||||
if (caves != null && caves.isNotEmpty()) {
|
||||
IrisBiome cave = getComplex().getCaveBiomeStream().get(x + i, z + j);
|
||||
|
||||
if (cave == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (CaveResult cl : caves) {
|
||||
if (cl.getFloor() < 0 || cl.getFloor() > getEngine().getHeight() || cl.getCeiling() > getEngine().getHeight() || cl.getCeiling() < 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
KList<BlockData> floor = cave.generateLayers(x + i, z + j, rng, cl.getFloor(), cl.getFloor(), getData(), getComplex());
|
||||
KList<BlockData> ceiling = cave.generateLayers(x + i + 656, z + j - 656, rng,
|
||||
he - cl.getCeiling(),
|
||||
he - cl.getCeiling(), getData(), getComplex());
|
||||
|
||||
for (int g = 0; g < floor.size(); g++) {
|
||||
a.set(i, cl.getFloor() - g, j, floor.get(g));
|
||||
}
|
||||
|
||||
for (int g = ceiling.size() - 1; g > 0; g--) {
|
||||
a.set(i, cl.getCeiling() + g, j, ceiling.get(g));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
getEngine().getMetrics().getCave().put(p.getMilliseconds());
|
||||
}
|
||||
|
||||
public KList<CaveResult> genCaves(double wxx, double wzz, int x, int z, Hunk<BlockData> data) {
|
||||
if (!getDimension().isCaves()) {
|
||||
return EMPTY;
|
||||
}
|
||||
|
||||
KList<CaveResult> result = new KList<>();
|
||||
gg.setNoiseType(FastNoiseDouble.NoiseType.Cellular);
|
||||
gg.setCellularReturnType(FastNoiseDouble.CellularReturnType.Distance2Sub);
|
||||
gg.setCellularDistanceFunction(FastNoiseDouble.CellularDistanceFunction.Natural);
|
||||
|
||||
for (int i = 0; i < getDimension().getCaveLayers().size(); i++) {
|
||||
IrisCaveLayer layer = getDimension().getCaveLayers().get(i);
|
||||
generateCave(result, wxx, wzz, x, z, data, layer, i);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public void generateCave(KList<CaveResult> result, double wxx, double wzz, int x, int z, Hunk<BlockData> data, IrisCaveLayer layer, int seed) {
|
||||
double scale = layer.getCaveZoom();
|
||||
Function<Integer, BlockData> fluid = (height) ->
|
||||
{
|
||||
if (!layer.getFluid().hasFluid(getData())) {
|
||||
return CAVE_AIR;
|
||||
}
|
||||
|
||||
if (layer.getFluid().isInverseHeight() && height >= layer.getFluid().getFluidHeight()) {
|
||||
return layer.getFluid().getFluid(getData());
|
||||
} else if (!layer.getFluid().isInverseHeight() && height <= layer.getFluid().getFluidHeight()) {
|
||||
return layer.getFluid().getFluid(getData());
|
||||
}
|
||||
|
||||
return CAVE_AIR;
|
||||
};
|
||||
|
||||
int surface = (int) Math.round(getComplex().getHeightStream().get(wxx, wzz));
|
||||
double wx = wxx + layer.getHorizontalSlope().get(rng, wxx, wzz);
|
||||
double wz = wzz + layer.getHorizontalSlope().get(rng, -wzz, -wxx);
|
||||
double baseWidth = (14 * scale);
|
||||
double distanceCheck = 0.0132 * baseWidth;
|
||||
double distanceTake = 0.0022 * baseWidth;
|
||||
double caveHeightNoise = layer.getVerticalSlope().get(rng, wxx, wzz);
|
||||
|
||||
if (caveHeightNoise > 259 || caveHeightNoise < -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: WARNING HEIGHT
|
||||
int ceiling = -256;
|
||||
int floor = 512;
|
||||
|
||||
for (double tunnelHeight = 1; tunnelHeight <= baseWidth; tunnelHeight++) {
|
||||
double distance = (gg.GetCellular(((wx + (10000 * seed)) / layer.getCaveZoom()), ((wz - (10000 * seed)) / layer.getCaveZoom())) + 1D) / 2D;
|
||||
if (distance < distanceCheck - (tunnelHeight * distanceTake)) {
|
||||
int caveHeight = (int) Math.round(caveHeightNoise);
|
||||
int pu = (int) (caveHeight + tunnelHeight);
|
||||
int pd = (int) (caveHeight - tunnelHeight);
|
||||
|
||||
if (pd > surface + 1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!layer.isCanBreakSurface() && pu > surface - 3) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((pu > 255 && pd > 255) || (pu < 0 && pd < 0)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (data == null) {
|
||||
ceiling = Math.max(pu, ceiling);
|
||||
floor = Math.min(pu, floor);
|
||||
ceiling = Math.max(pd, ceiling);
|
||||
floor = Math.min(pd, floor);
|
||||
|
||||
if (tunnelHeight == 1) {
|
||||
ceiling = Math.max(caveHeight, ceiling);
|
||||
floor = Math.min(caveHeight, floor);
|
||||
}
|
||||
} else {
|
||||
if (dig(x, pu, z, data, fluid)) {
|
||||
ceiling = Math.max(pu, ceiling);
|
||||
floor = Math.min(pu, floor);
|
||||
}
|
||||
|
||||
if (dig(x, pd, z, data, fluid)) {
|
||||
ceiling = Math.max(pd, ceiling);
|
||||
floor = Math.min(pd, floor);
|
||||
}
|
||||
|
||||
if (tunnelHeight == 1) {
|
||||
if (dig(x, caveHeight, z, data, fluid)) {
|
||||
ceiling = Math.max(caveHeight, ceiling);
|
||||
floor = Math.min(caveHeight, floor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (floor >= 0 && ceiling <= 255) {
|
||||
result.add(new CaveResult(floor, ceiling));
|
||||
}
|
||||
}
|
||||
|
||||
private Material mat(int x, int y, int z, Hunk<BlockData> data) {
|
||||
BlockData d = data.get(Math.max(x, 0), Math.max(y, 0), Math.max(z, 0));
|
||||
|
||||
if (d != null) {
|
||||
return d.getMaterial();
|
||||
}
|
||||
|
||||
return Material.CAVE_AIR;
|
||||
}
|
||||
|
||||
public boolean dig(int x, int y, int z, Hunk<BlockData> data, Function<Integer, BlockData> caveFluid) {
|
||||
Material a = mat(x, y, z, data);
|
||||
Material c = mat(x, y + 1, z, data);
|
||||
Material d = mat(x, y + 2, z, data);
|
||||
Material e = mat(x, y + 3, z, data);
|
||||
Material f = mat(x, y - 1, z, data);
|
||||
BlockData b = caveFluid.apply(y);
|
||||
BlockData b2 = caveFluid.apply(y + 1);
|
||||
|
||||
if (can(a) && canAir(c, b) && canAir(f, b) && canWater(d) && canWater(e)) {
|
||||
data.set(x, y, z, b);
|
||||
data.set(x, y + 1, z, b2);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean canAir(Material m, BlockData caveFluid) {
|
||||
return (B.isSolid(m) ||
|
||||
(B.isDecorant(m.createBlockData())) || m.equals(Material.AIR)
|
||||
|| m.equals(caveFluid.getMaterial()) ||
|
||||
m.equals(B.getMaterial("CAVE_AIR")))
|
||||
&& !m.equals(Material.BEDROCK);
|
||||
}
|
||||
|
||||
public boolean canWater(Material m) {
|
||||
return !m.equals(Material.WATER);
|
||||
}
|
||||
|
||||
public boolean can(Material m) {
|
||||
return B.isSolid(m) && !m.equals(Material.BEDROCK);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,138 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2021 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.engine.modifier;
|
||||
|
||||
import com.volmit.iris.engine.object.IrisBiome;
|
||||
import com.volmit.iris.engine.object.IrisDepositGenerator;
|
||||
import com.volmit.iris.engine.object.IrisObject;
|
||||
import com.volmit.iris.engine.object.IrisRegion;
|
||||
import com.volmit.iris.engine.framework.Engine;
|
||||
import com.volmit.iris.engine.framework.EngineAssignedModifier;
|
||||
import com.volmit.iris.engine.hunk.Hunk;
|
||||
import com.volmit.iris.util.HeightMap;
|
||||
import com.volmit.iris.util.PrecisionStopwatch;
|
||||
import com.volmit.iris.util.RNG;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.util.BlockVector;
|
||||
|
||||
public class IrisDepositModifier extends EngineAssignedModifier<BlockData> {
|
||||
private final RNG rng;
|
||||
|
||||
public IrisDepositModifier(Engine engine) {
|
||||
super(engine, "Deposit");
|
||||
rng = new RNG(getEngine().getWorld().getSeed() + 12938).nextParallelRNG(28348777);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onModify(int x, int z, Hunk<BlockData> output) {
|
||||
PrecisionStopwatch p = PrecisionStopwatch.start();
|
||||
generateDeposits(rng, output, Math.floorDiv(x, 16), Math.floorDiv(z, 16));
|
||||
getEngine().getMetrics().getDeposit().put(p.getMilliseconds());
|
||||
}
|
||||
|
||||
public void generateDeposits(RNG rx, Hunk<BlockData> terrain, int x, int z) {
|
||||
RNG ro = rx.nextParallelRNG(x * x).nextParallelRNG(z * z);
|
||||
IrisRegion region = getComplex().getRegionStream().get((x * 16) + 7, (z * 16) + 7);
|
||||
IrisBiome biome = getComplex().getTrueBiomeStream().get((x * 16) + 7, (z * 16) + 7);
|
||||
|
||||
for (IrisDepositGenerator k : getDimension().getDeposits()) {
|
||||
generate(k, terrain, ro, x, z, false);
|
||||
}
|
||||
|
||||
for (IrisDepositGenerator k : region.getDeposits()) {
|
||||
for (int l = 0; l < ro.i(k.getMinPerChunk(), k.getMaxPerChunk()); l++) {
|
||||
generate(k, terrain, ro, x, z, false);
|
||||
}
|
||||
}
|
||||
|
||||
for (IrisDepositGenerator k : biome.getDeposits()) {
|
||||
for (int l = 0; l < ro.i(k.getMinPerChunk(), k.getMaxPerChunk()); l++) {
|
||||
generate(k, terrain, ro, x, z, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void generate(IrisDepositGenerator k, Hunk<BlockData> data, RNG rng, int cx, int cz, boolean safe) {
|
||||
generate(k, data, rng, cx, cz, safe, null);
|
||||
}
|
||||
|
||||
public void generate(IrisDepositGenerator k, Hunk<BlockData> data, RNG rng, int cx, int cz, boolean safe, HeightMap he) {
|
||||
for (int l = 0; l < rng.i(k.getMinPerChunk(), k.getMaxPerChunk()); l++) {
|
||||
IrisObject clump = k.getClump(rng, getData());
|
||||
|
||||
int af = (int) Math.ceil(clump.getW() / 2D);
|
||||
int bf = (int) Math.floor(16D - (clump.getW() / 2D));
|
||||
|
||||
if (af > bf || af < 0 || bf > 15 || af > 15 || bf < 0) {
|
||||
af = 6;
|
||||
bf = 9;
|
||||
}
|
||||
|
||||
int x = rng.i(af, bf);
|
||||
int z = rng.i(af, bf);
|
||||
int height = (he != null ? he.getHeight((cx << 4) + x, (cz << 4) + z) : (int) (Math.round(
|
||||
getComplex().getHeightStream().get((cx << 4) + x, (cz << 4) + z)
|
||||
))) - 7;
|
||||
|
||||
if (height <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
int i = Math.max(0, k.getMinHeight());
|
||||
// TODO: WARNING HEIGHT
|
||||
int a = Math.min(height, Math.min(256, k.getMaxHeight()));
|
||||
|
||||
if (i >= a) {
|
||||
return;
|
||||
}
|
||||
|
||||
int h = rng.i(i, a);
|
||||
|
||||
if (h > k.getMaxHeight() || h < k.getMinHeight() || h > height - 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (BlockVector j : clump.getBlocks().keySet()) {
|
||||
int nx = j.getBlockX() + x;
|
||||
int ny = j.getBlockY() + h;
|
||||
int nz = j.getBlockZ() + z;
|
||||
|
||||
if (ny > height || nx > 15 || nx < 0 || ny > 255 || ny < 0 || nz < 0 || nz > 15) {
|
||||
continue;
|
||||
}
|
||||
|
||||
boolean allow = false;
|
||||
|
||||
BlockData b = data.get(nx, ny, nz);
|
||||
if (b != null) {
|
||||
for (BlockData f : getDimension().getRockPalette().getBlockData(getData())) {
|
||||
if (f.getMaterial().equals(b.getMaterial())) {
|
||||
allow = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (allow) {
|
||||
data.set(nx, ny, nz, clump.getBlocks().get(j));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,481 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2021 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.engine.modifier;
|
||||
|
||||
import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.engine.object.IrisBiome;
|
||||
import com.volmit.iris.engine.framework.Engine;
|
||||
import com.volmit.iris.engine.framework.EngineAssignedModifier;
|
||||
import com.volmit.iris.engine.hunk.Hunk;
|
||||
import com.volmit.iris.engine.parallel.BurstExecutor;
|
||||
import com.volmit.iris.engine.parallel.MultiBurst;
|
||||
import com.volmit.iris.util.B;
|
||||
import com.volmit.iris.util.CaveResult;
|
||||
import com.volmit.iris.util.PrecisionStopwatch;
|
||||
import com.volmit.iris.util.RNG;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.block.data.Levelled;
|
||||
import org.bukkit.block.data.Waterlogged;
|
||||
import org.bukkit.block.data.type.Slab;
|
||||
|
||||
public class IrisPostModifier extends EngineAssignedModifier<BlockData> {
|
||||
private static final BlockData AIR = B.get("CAVE_AIR");
|
||||
private static final BlockData WATER = B.get("WATER");
|
||||
private final RNG rng;
|
||||
|
||||
public IrisPostModifier(Engine engine) {
|
||||
super(engine, "Post");
|
||||
rng = new RNG(getEngine().getWorld().getSeed() + 12938).nextParallelRNG(28348777);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onModify(int x, int z, Hunk<BlockData> output) {
|
||||
PrecisionStopwatch p = PrecisionStopwatch.start();
|
||||
BurstExecutor b = MultiBurst.burst.burst(output.getWidth() * output.getDepth());
|
||||
int i, j;
|
||||
for (i = 0; i < output.getWidth(); i++) {
|
||||
int ii = i;
|
||||
for (j = 0; j < output.getDepth(); j++) {
|
||||
int jj = j;
|
||||
b.queue(() -> post(ii, jj, output, ii + x, jj + z));
|
||||
}
|
||||
}
|
||||
b.complete();
|
||||
getEngine().getMetrics().getPost().put(p.getMilliseconds());
|
||||
}
|
||||
|
||||
@SuppressWarnings("SynchronizationOnLocalVariableOrMethodParameter")
|
||||
private void post(int currentPostX, int currentPostZ, Hunk<BlockData> currentData, int x, int z) {
|
||||
|
||||
int h = getFramework().getEngineParallax().trueHeight(x, z);
|
||||
int ha = getFramework().getEngineParallax().trueHeight(x + 1, z);
|
||||
int hb = getFramework().getEngineParallax().trueHeight(x, z + 1);
|
||||
int hc = getFramework().getEngineParallax().trueHeight(x - 1, z);
|
||||
int hd = getFramework().getEngineParallax().trueHeight(x, z - 1);
|
||||
|
||||
// Floating Nibs
|
||||
int g = 0;
|
||||
|
||||
if (h < 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
g += ha < h - 1 ? 1 : 0;
|
||||
g += hb < h - 1 ? 1 : 0;
|
||||
g += hc < h - 1 ? 1 : 0;
|
||||
g += hd < h - 1 ? 1 : 0;
|
||||
|
||||
if (g == 4 && isAir(x, h - 1, z, currentPostX, currentPostZ, currentData)) {
|
||||
setPostBlock(x, h, z, AIR, currentPostX, currentPostZ, currentData);
|
||||
|
||||
for (int i = h - 1; i > 0; i--) {
|
||||
if (!isAir(x, i, z, currentPostX, currentPostZ, currentData)) {
|
||||
h = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Nibs
|
||||
g = 0;
|
||||
g += ha == h - 1 ? 1 : 0;
|
||||
g += hb == h - 1 ? 1 : 0;
|
||||
g += hc == h - 1 ? 1 : 0;
|
||||
g += hd == h - 1 ? 1 : 0;
|
||||
|
||||
if (g >= 4) {
|
||||
BlockData bc = getPostBlock(x, h, z, currentPostX, currentPostZ, currentData);
|
||||
BlockData b = getPostBlock(x, h + 1, z, currentPostX, currentPostZ, currentData);
|
||||
Material m = bc.getMaterial();
|
||||
|
||||
if ((b.getMaterial().isOccluding() && b.getMaterial().isSolid())) {
|
||||
if (m.isSolid()) {
|
||||
setPostBlock(x, h, z, b, currentPostX, currentPostZ, currentData);
|
||||
h--;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Potholes
|
||||
g = 0;
|
||||
g += ha == h + 1 ? 1 : 0;
|
||||
g += hb == h + 1 ? 1 : 0;
|
||||
g += hc == h + 1 ? 1 : 0;
|
||||
g += hd == h + 1 ? 1 : 0;
|
||||
|
||||
if (g >= 4) {
|
||||
BlockData ba = getPostBlock(x, ha, z, currentPostX, currentPostZ, currentData);
|
||||
BlockData bb = getPostBlock(x, hb, z, currentPostX, currentPostZ, currentData);
|
||||
BlockData bc = getPostBlock(x, hc, z, currentPostX, currentPostZ, currentData);
|
||||
BlockData bd = getPostBlock(x, hd, z, currentPostX, currentPostZ, currentData);
|
||||
g = 0;
|
||||
g = B.isSolid(ba) ? g + 1 : g;
|
||||
g = B.isSolid(bb) ? g + 1 : g;
|
||||
g = B.isSolid(bc) ? g + 1 : g;
|
||||
g = B.isSolid(bd) ? g + 1 : g;
|
||||
|
||||
if (g >= 3) {
|
||||
setPostBlock(x, h + 1, z, getPostBlock(x, h, z, currentPostX, currentPostZ, currentData), currentPostX, currentPostZ, currentData);
|
||||
h++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Wall Patcher
|
||||
IrisBiome biome = getComplex().getTrueBiomeStream().get(x, z);
|
||||
|
||||
if (getDimension().isPostProcessingWalls()) {
|
||||
if (!biome.getWall().getPalette().isEmpty()) {
|
||||
if (ha < h - 2 || hb < h - 2 || hc < h - 2 || hd < h - 2) {
|
||||
boolean brokeGround = false;
|
||||
int max = Math.abs(Math.max(h - ha, Math.max(h - hb, Math.max(h - hc, h - hd))));
|
||||
|
||||
for (int i = h; i > h - max; i--) {
|
||||
BlockData d = biome.getWall().get(rng, x + i, i + h, z + i, getData());
|
||||
|
||||
if (d != null) {
|
||||
if (isAirOrWater(x, i, z, currentPostX, currentPostZ, currentData)) {
|
||||
if (brokeGround) {
|
||||
break;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
setPostBlock(x, i, z, d, currentPostX, currentPostZ, currentData);
|
||||
brokeGround = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Slab
|
||||
if (getDimension().isPostProcessingSlabs()) {
|
||||
//@builder
|
||||
if ((ha == h + 1 && isSolidNonSlab(x + 1, ha, z, currentPostX, currentPostZ, currentData))
|
||||
|| (hb == h + 1 && isSolidNonSlab(x, hb, z + 1, currentPostX, currentPostZ, currentData))
|
||||
|| (hc == h + 1 && isSolidNonSlab(x - 1, hc, z, currentPostX, currentPostZ, currentData))
|
||||
|| (hd == h + 1 && isSolidNonSlab(x, hd, z - 1, currentPostX, currentPostZ, currentData)))
|
||||
//@done
|
||||
{
|
||||
BlockData d = biome.getSlab().get(rng, x, h, z, getData());
|
||||
|
||||
if (d != null) {
|
||||
boolean cancel = B.isAir(d);
|
||||
|
||||
if (d.getMaterial().equals(Material.SNOW) && h + 1 <= getDimension().getFluidHeight()) {
|
||||
cancel = true;
|
||||
}
|
||||
|
||||
if (isSnowLayer(x, h, z, currentPostX, currentPostZ, currentData)) {
|
||||
cancel = true;
|
||||
}
|
||||
|
||||
if (!cancel && isAirOrWater(x, h + 1, z, currentPostX, currentPostZ, currentData)) {
|
||||
setPostBlock(x, h + 1, z, d, currentPostX, currentPostZ, currentData);
|
||||
h++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Waterlogging
|
||||
BlockData b = getPostBlock(x, h, z, currentPostX, currentPostZ, currentData);
|
||||
|
||||
if (b instanceof Waterlogged) {
|
||||
Waterlogged ww = (Waterlogged) b.clone();
|
||||
boolean w = false;
|
||||
|
||||
if (h <= getDimension().getFluidHeight() + 1) {
|
||||
if (isWaterOrWaterlogged(x, h + 1, z, currentPostX, currentPostZ, currentData)) {
|
||||
w = true;
|
||||
} else if ((isWaterOrWaterlogged(x + 1, h, z, currentPostX, currentPostZ, currentData) || isWaterOrWaterlogged(x - 1, h, z, currentPostX, currentPostZ, currentData) || isWaterOrWaterlogged(x, h, z + 1, currentPostX, currentPostZ, currentData) || isWaterOrWaterlogged(x, h, z - 1, currentPostX, currentPostZ, currentData))) {
|
||||
w = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (w != ww.isWaterlogged()) {
|
||||
ww.setWaterlogged(w);
|
||||
setPostBlock(x, h, z, ww, currentPostX, currentPostZ, currentData);
|
||||
}
|
||||
} else if (b.getMaterial().equals(Material.AIR) && h <= getDimension().getFluidHeight()) {
|
||||
if ((isWaterOrWaterlogged(x + 1, h, z, currentPostX, currentPostZ, currentData) || isWaterOrWaterlogged(x - 1, h, z, currentPostX, currentPostZ, currentData) || isWaterOrWaterlogged(x, h, z + 1, currentPostX, currentPostZ, currentData) || isWaterOrWaterlogged(x, h, z - 1, currentPostX, currentPostZ, currentData))) {
|
||||
setPostBlock(x, h, z, WATER, currentPostX, currentPostZ, currentData);
|
||||
}
|
||||
}
|
||||
|
||||
// Foliage
|
||||
b = getPostBlock(x, h + 1, z, currentPostX, currentPostZ, currentData);
|
||||
|
||||
if (B.isFoliage(b) || b.getMaterial().equals(Material.DEAD_BUSH)) {
|
||||
Material onto = getPostBlock(x, h, z, currentPostX, currentPostZ, currentData).getMaterial();
|
||||
|
||||
if (!B.canPlaceOnto(b.getMaterial(), onto)) {
|
||||
setPostBlock(x, h + 1, z, AIR, currentPostX, currentPostZ, currentData);
|
||||
}
|
||||
}
|
||||
|
||||
if (getDimension().isPostProcessCaves()) {
|
||||
IrisBiome cave = getComplex().getCaveBiomeStream().get(x, z);
|
||||
|
||||
if (cave != null) {
|
||||
for (CaveResult i : ((IrisCaveModifier) getFramework().getCaveModifier()).genCaves(x, z, 0, 0, null)) {
|
||||
if (i.getCeiling() >= currentData.getMax2DParallelism() || i.getFloor() < 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int f = i.getFloor();
|
||||
int fa = nearestCaveFloor(f, x + 1, z, currentPostX, currentPostZ, currentData);
|
||||
int fb = nearestCaveFloor(f, x, z + 1, currentPostX, currentPostZ, currentData);
|
||||
int fc = nearestCaveFloor(f, x - 1, z, currentPostX, currentPostZ, currentData);
|
||||
int fd = nearestCaveFloor(f, x, z - 1, currentPostX, currentPostZ, currentData);
|
||||
int c = i.getCeiling();
|
||||
int ca = nearestCaveCeiling(c, x + 1, z, currentPostX, currentPostZ, currentData);
|
||||
int cb = nearestCaveCeiling(c, x, z + 1, currentPostX, currentPostZ, currentData);
|
||||
int cc = nearestCaveCeiling(c, x - 1, z, currentPostX, currentPostZ, currentData);
|
||||
int cd = nearestCaveCeiling(c, x, z - 1, currentPostX, currentPostZ, currentData);
|
||||
|
||||
// Cave Nibs
|
||||
g = 0;
|
||||
g += fa == f - 1 ? 1 : 0;
|
||||
g += fb == f - 1 ? 1 : 0;
|
||||
g += fc == f - 1 ? 1 : 0;
|
||||
g += fd == f - 1 ? 1 : 0;
|
||||
|
||||
if (g >= 4) {
|
||||
BlockData bc = getPostBlock(x, f, z, currentPostX, currentPostZ, currentData);
|
||||
b = getPostBlock(x, f + 1, z, currentPostX, currentPostZ, currentData);
|
||||
Material m = bc.getMaterial();
|
||||
|
||||
if (m.isSolid()) {
|
||||
setPostBlock(x, f, z, b, currentPostX, currentPostZ, currentData);
|
||||
h--;
|
||||
}
|
||||
} else {
|
||||
// Cave Potholes
|
||||
g = 0;
|
||||
g += fa == f + 1 ? 1 : 0;
|
||||
g += fb == f + 1 ? 1 : 0;
|
||||
g += fc == f + 1 ? 1 : 0;
|
||||
g += fd == f + 1 ? 1 : 0;
|
||||
|
||||
if (g >= 4) {
|
||||
BlockData ba = getPostBlock(x, fa, z, currentPostX, currentPostZ, currentData);
|
||||
BlockData bb = getPostBlock(x, fb, z, currentPostX, currentPostZ, currentData);
|
||||
BlockData bc = getPostBlock(x, fc, z, currentPostX, currentPostZ, currentData);
|
||||
BlockData bd = getPostBlock(x, fd, z, currentPostX, currentPostZ, currentData);
|
||||
g = 0;
|
||||
g = B.isSolid(ba) ? g + 1 : g;
|
||||
g = B.isSolid(bb) ? g + 1 : g;
|
||||
g = B.isSolid(bc) ? g + 1 : g;
|
||||
g = B.isSolid(bd) ? g + 1 : g;
|
||||
|
||||
if (g >= 4) {
|
||||
setPostBlock(x, f + 1, z, getPostBlock(x, f, z, currentPostX, currentPostZ, currentData), currentPostX, currentPostZ, currentData);
|
||||
h++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (getDimension().isPostProcessingSlabs()) {
|
||||
//@builder
|
||||
if ((fa == f + 1 && isSolidNonSlab(x + 1, fa, z, currentPostX, currentPostZ, currentData))
|
||||
|| (fb == f + 1 && isSolidNonSlab(x, fb, z + 1, currentPostX, currentPostZ, currentData))
|
||||
|| (fc == f + 1 && isSolidNonSlab(x - 1, fc, z, currentPostX, currentPostZ, currentData))
|
||||
|| (fd == f + 1 && isSolidNonSlab(x, fd, z - 1, currentPostX, currentPostZ, currentData)))
|
||||
//@done
|
||||
{
|
||||
BlockData d = cave.getSlab().get(rng, x, f, z, getData());
|
||||
|
||||
if (d != null) {
|
||||
boolean cancel = B.isAir(d);
|
||||
|
||||
if (d.getMaterial().equals(Material.SNOW) && f + 1 <= getDimension().getFluidHeight()) {
|
||||
cancel = true;
|
||||
}
|
||||
|
||||
if (isSnowLayer(x, f, z, currentPostX, currentPostZ, currentData)) {
|
||||
cancel = true;
|
||||
}
|
||||
|
||||
if (!cancel && isAirOrWater(x, f + 1, z, currentPostX, currentPostZ, currentData)) {
|
||||
setPostBlock(x, f + 1, z, d, currentPostX, currentPostZ, currentData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//@builder
|
||||
if ((ca == c - 1 && isSolidNonSlab(x + 1, ca, z, currentPostX, currentPostZ, currentData))
|
||||
|| (cb == c - 1 && isSolidNonSlab(x, cb, z + 1, currentPostX, currentPostZ, currentData))
|
||||
|| (cc == c - 1 && isSolidNonSlab(x - 1, cc, z, currentPostX, currentPostZ, currentData))
|
||||
|| (cd == c - 1 && isSolidNonSlab(x, cd, z - 1, currentPostX, currentPostZ, currentData)))
|
||||
//@done
|
||||
{
|
||||
BlockData d = cave.getSlab().get(rng, x, c, z, getData());
|
||||
|
||||
if (d != null) {
|
||||
boolean cancel = B.isAir(d);
|
||||
|
||||
if (!(d instanceof Slab)) {
|
||||
cancel = true;
|
||||
}
|
||||
|
||||
if (isSnowLayer(x, c, z, currentPostX, currentPostZ, currentData)) {
|
||||
cancel = true;
|
||||
}
|
||||
|
||||
if (!cancel && isAirOrWater(x, c, z, currentPostX, currentPostZ, currentData)) {
|
||||
try {
|
||||
Slab slab = (Slab) d.clone();
|
||||
slab.setType(Slab.Type.TOP);
|
||||
setPostBlock(x, c, z, slab, currentPostX, currentPostZ, currentData);
|
||||
} catch (Throwable e) {
|
||||
Iris.reportError(e);
|
||||
try {
|
||||
Slab slab = (Slab) d.clone();
|
||||
|
||||
synchronized (slab) {
|
||||
slab.setType(Slab.Type.TOP);
|
||||
setPostBlock(x, c, z, slab, currentPostX, currentPostZ, currentData);
|
||||
}
|
||||
} catch (Throwable ee) {
|
||||
Iris.reportError(ee);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private int nearestCaveFloor(int floor, int x, int z, int currentPostX, int currentPostZ, Hunk<BlockData> currentData) {
|
||||
if (floor >= currentData.getHeight()) {
|
||||
return currentData.getHeight() - 1;
|
||||
}
|
||||
|
||||
if (B.isAir(getPostBlock(x, floor, z, currentPostX, currentPostZ, currentData))) {
|
||||
if (B.isAir(getPostBlock(x, floor - 1, z, currentPostX, currentPostZ, currentData))) {
|
||||
return floor - 2;
|
||||
}
|
||||
|
||||
return floor - 1;
|
||||
} else {
|
||||
if (!B.isAir(getPostBlock(x, floor + 1, z, currentPostX, currentPostZ, currentData))) {
|
||||
if (!B.isAir(getPostBlock(x, floor + 2, z, currentPostX, currentPostZ, currentData))) {
|
||||
return floor + 2;
|
||||
}
|
||||
|
||||
return floor + 1;
|
||||
}
|
||||
|
||||
return floor;
|
||||
}
|
||||
}
|
||||
|
||||
private int nearestCaveCeiling(int ceiling, int x, int z, int currentPostX, int currentPostZ, Hunk<BlockData> currentData) {
|
||||
if (ceiling >= currentData.getHeight()) {
|
||||
return currentData.getHeight() - 1;
|
||||
}
|
||||
|
||||
if (B.isAir(getPostBlock(x, ceiling, z, currentPostX, currentPostZ, currentData))) {
|
||||
if (B.isAir(getPostBlock(x, ceiling + 1, z, currentPostX, currentPostZ, currentData))) {
|
||||
return ceiling + 2;
|
||||
}
|
||||
|
||||
return ceiling + 1;
|
||||
} else {
|
||||
if (!B.isAir(getPostBlock(x, ceiling - 1, z, currentPostX, currentPostZ, currentData))) {
|
||||
if (!B.isAir(getPostBlock(x, ceiling - 2, z, currentPostX, currentPostZ, currentData))) {
|
||||
return ceiling - 2;
|
||||
}
|
||||
|
||||
return ceiling - 1;
|
||||
}
|
||||
|
||||
return ceiling;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isAir(int x, int y, int z, int currentPostX, int currentPostZ, Hunk<BlockData> currentData) {
|
||||
BlockData d = getPostBlock(x, y, z, currentPostX, currentPostZ, currentData);
|
||||
return d.getMaterial().equals(Material.AIR) || d.getMaterial().equals(Material.CAVE_AIR);
|
||||
}
|
||||
|
||||
public boolean hasGravity(int x, int y, int z, int currentPostX, int currentPostZ, Hunk<BlockData> currentData) {
|
||||
BlockData d = getPostBlock(x, y, z, currentPostX, currentPostZ, currentData);
|
||||
return d.getMaterial().equals(Material.SAND) || d.getMaterial().equals(Material.RED_SAND) || d.getMaterial().equals(Material.BLACK_CONCRETE_POWDER) || d.getMaterial().equals(Material.BLUE_CONCRETE_POWDER) || d.getMaterial().equals(Material.BROWN_CONCRETE_POWDER) || d.getMaterial().equals(Material.CYAN_CONCRETE_POWDER) || d.getMaterial().equals(Material.GRAY_CONCRETE_POWDER) || d.getMaterial().equals(Material.GREEN_CONCRETE_POWDER) || d.getMaterial().equals(Material.LIGHT_BLUE_CONCRETE_POWDER) || d.getMaterial().equals(Material.LIGHT_GRAY_CONCRETE_POWDER) || d.getMaterial().equals(Material.LIME_CONCRETE_POWDER) || d.getMaterial().equals(Material.MAGENTA_CONCRETE_POWDER) || d.getMaterial().equals(Material.ORANGE_CONCRETE_POWDER) || d.getMaterial().equals(Material.PINK_CONCRETE_POWDER) || d.getMaterial().equals(Material.PURPLE_CONCRETE_POWDER) || d.getMaterial().equals(Material.RED_CONCRETE_POWDER) || d.getMaterial().equals(Material.WHITE_CONCRETE_POWDER) || d.getMaterial().equals(Material.YELLOW_CONCRETE_POWDER);
|
||||
}
|
||||
|
||||
public boolean isSolid(int x, int y, int z, int currentPostX, int currentPostZ, Hunk<BlockData> currentData) {
|
||||
BlockData d = getPostBlock(x, y, z, currentPostX, currentPostZ, currentData);
|
||||
return d.getMaterial().isSolid();
|
||||
}
|
||||
|
||||
public boolean isSolidNonSlab(int x, int y, int z, int currentPostX, int currentPostZ, Hunk<BlockData> currentData) {
|
||||
BlockData d = getPostBlock(x, y, z, currentPostX, currentPostZ, currentData);
|
||||
return d.getMaterial().isSolid() && !(d instanceof Slab);
|
||||
}
|
||||
|
||||
public boolean isAirOrWater(int x, int y, int z, int currentPostX, int currentPostZ, Hunk<BlockData> currentData) {
|
||||
BlockData d = getPostBlock(x, y, z, currentPostX, currentPostZ, currentData);
|
||||
return d.getMaterial().equals(Material.WATER) || d.getMaterial().equals(Material.AIR) || d.getMaterial().equals(Material.CAVE_AIR);
|
||||
}
|
||||
|
||||
public boolean isSlab(int x, int y, int z, int currentPostX, int currentPostZ, Hunk<BlockData> currentData) {
|
||||
BlockData d = getPostBlock(x, y, z, currentPostX, currentPostZ, currentData);
|
||||
return d instanceof Slab;
|
||||
}
|
||||
|
||||
public boolean isSnowLayer(int x, int y, int z, int currentPostX, int currentPostZ, Hunk<BlockData> currentData) {
|
||||
BlockData d = getPostBlock(x, y, z, currentPostX, currentPostZ, currentData);
|
||||
return d.getMaterial().equals(Material.SNOW);
|
||||
}
|
||||
|
||||
public boolean isWater(int x, int y, int z, int currentPostX, int currentPostZ, Hunk<BlockData> currentData) {
|
||||
BlockData d = getPostBlock(x, y, z, currentPostX, currentPostZ, currentData);
|
||||
return d.getMaterial().equals(Material.WATER);
|
||||
}
|
||||
|
||||
public boolean isWaterOrWaterlogged(int x, int y, int z, int currentPostX, int currentPostZ, Hunk<BlockData> currentData) {
|
||||
BlockData d = getPostBlock(x, y, z, currentPostX, currentPostZ, currentData);
|
||||
return d.getMaterial().equals(Material.WATER) || (d instanceof Waterlogged && ((Waterlogged) d).isWaterlogged());
|
||||
}
|
||||
|
||||
public boolean isLiquid(int x, int y, int z, int currentPostX, int currentPostZ, Hunk<BlockData> currentData) {
|
||||
BlockData d = getPostBlock(x, y, z, currentPostX, currentPostZ, currentData);
|
||||
return d instanceof Levelled;
|
||||
}
|
||||
|
||||
|
||||
public void setPostBlock(int x, int y, int z, BlockData d, int currentPostX, int currentPostZ, Hunk<BlockData> currentData) {
|
||||
if (y < currentData.getHeight()) {
|
||||
currentData.set(x & 15, y, z & 15, d);
|
||||
}
|
||||
}
|
||||
|
||||
public BlockData getPostBlock(int x, int y, int z, int cpx, int cpz, Hunk<BlockData> h) {
|
||||
BlockData b = h.getClosest(x & 15, y, z & 15);
|
||||
|
||||
return b == null ? AIR : b;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,281 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2021 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.engine.modifier;
|
||||
|
||||
import com.volmit.iris.engine.noise.CNG;
|
||||
import com.volmit.iris.engine.object.NoiseStyle;
|
||||
import com.volmit.iris.engine.framework.Engine;
|
||||
import com.volmit.iris.engine.framework.EngineAssignedModifier;
|
||||
import com.volmit.iris.engine.hunk.Hunk;
|
||||
import com.volmit.iris.util.*;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
|
||||
@SuppressWarnings("ALL")
|
||||
public class IrisRavineModifier extends EngineAssignedModifier<BlockData> {
|
||||
private static final BlockData CAVE_AIR = B.get("CAVE_AIR");
|
||||
private static final BlockData LAVA = B.get("LAVA");
|
||||
private final CNG cng;
|
||||
private final RNG rng;
|
||||
|
||||
public IrisRavineModifier(Engine engine) {
|
||||
super(engine, "Ravine");
|
||||
rng = new RNG(getEngine().getWorld().getSeed()).nextParallelRNG(29596878);
|
||||
cng = NoiseStyle.IRIS_THICK.create(rng);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onModify(int x, int z, Hunk<BlockData> output) {
|
||||
if (!getDimension().isRavines()) {
|
||||
return;
|
||||
}
|
||||
|
||||
PrecisionStopwatch p = PrecisionStopwatch.start();
|
||||
generateRavines(rng, Math.floorDiv(x, 16), Math.floorDiv(z, 16), output);
|
||||
getEngine().getMetrics().getRavine().put(p.getMilliseconds());
|
||||
}
|
||||
|
||||
private void set(Hunk<BlockData> pos, int x, int y, int z, BlockData b) {
|
||||
pos.set(x, y, z, b);
|
||||
}
|
||||
|
||||
private BlockData get(Hunk<BlockData> pos, int x, int y, int z) {
|
||||
BlockData bb = pos.get(x, y, z);
|
||||
|
||||
if (bb == null) {
|
||||
bb = CAVE_AIR;
|
||||
}
|
||||
|
||||
return bb;
|
||||
}
|
||||
|
||||
private BlockData getSurfaceBlock(int n6, int i, RNG rmg) {
|
||||
return getComplex().getTrueBiomeStream().get(n6, i).getSurfaceBlock(n6, i, rmg, getData());
|
||||
}
|
||||
|
||||
private final float[] ravineCache = new float[1024];
|
||||
|
||||
private void doRavine(long seed, int tx, int tz, ChunkPosition pos, double sx, double sy, double sz, float f, float f2, float f3, @SuppressWarnings("SameParameterValue") int n3, @SuppressWarnings("SameParameterValue") int n4, @SuppressWarnings("SameParameterValue") double d4, RNG bbx, Hunk<BlockData> terrain) {
|
||||
int n5;
|
||||
RNG random = new RNG(seed);
|
||||
double x = tx * 16 + 8;
|
||||
double z = tz * 16 + 8;
|
||||
float f4 = 0.0f;
|
||||
float f5 = 0.0f;
|
||||
if (n4 <= 0) {
|
||||
n5 = 8 * 16 - 16;
|
||||
n4 = n5 - random.nextInt(n5 / 4);
|
||||
}
|
||||
n5 = 0;
|
||||
if (n3 == -1) {
|
||||
n3 = n4 / 2;
|
||||
n5 = 1;
|
||||
}
|
||||
float f6 = 1.0f;
|
||||
// TODO: WARNING HEIGHT
|
||||
for (int i = 0; i < 256; ++i) {
|
||||
if (i == 0 || random.nextInt(getDimension().getRavineRibRarity()) == 0) {
|
||||
f6 = 1.0f + random.nextFloat() * random.nextFloat() * 1.0f;
|
||||
}
|
||||
this.ravineCache[i] = f6 * f6;
|
||||
}
|
||||
while (n3 < n4) {
|
||||
double d7 = 1.5 + (double) (MathHelper.sin((float) n3 * 3.1415927f / (float) n4) * f * 1.0f);
|
||||
double d8 = d7 * d4;
|
||||
d7 *= (double) random.nextFloat() * 0.25 + 0.75;
|
||||
d8 *= (double) random.nextFloat() * 0.25 + 0.75;
|
||||
float f7 = MathHelper.cos(f3);
|
||||
float f8 = MathHelper.sin(f3);
|
||||
sx = sx + (double) (MathHelper.cos(f2) * f7);
|
||||
sy += f8;
|
||||
sz += MathHelper.sin(f2) * f7;
|
||||
f3 *= 0.7f;
|
||||
f3 += f5 * 0.05f;
|
||||
f2 += f4 * 0.05f;
|
||||
f5 *= 0.8f;
|
||||
f4 *= 0.5f;
|
||||
f5 += (random.nextFloat() - random.nextFloat()) * random.nextFloat() * 2.0f;
|
||||
f4 += (random.nextFloat() - random.nextFloat()) * random.nextFloat() * 4.0f;
|
||||
if (n5 != 0 || random.nextInt(4) != 0) {
|
||||
double d9 = sx - x;
|
||||
double d10 = sz - z;
|
||||
double d11 = n4 - n3;
|
||||
double d12 = f + 2.0f + 16.0f;
|
||||
if (d9 * d9 + d10 * d10 - d11 * d11 > d12 * d12) {
|
||||
return;
|
||||
}
|
||||
if (sx >= x - 16.0 - d7 * 2.0 && sz >= z - 16.0 - d7 * 2.0 && sx <= x + 16.0 + d7 * 2.0 && sz <= z + 16.0 + d7 * 2.0) {
|
||||
int n6;
|
||||
int n7 = MathHelper.floor(sx - d7) - tx * 16 - 1;
|
||||
int n8 = MathHelper.floor(sx + d7) - tx * 16 + 1;
|
||||
int n9 = MathHelper.floor(sy - d8) - 1;
|
||||
int n10 = MathHelper.floor(sy + d8) + 1;
|
||||
int n11 = MathHelper.floor(sz - d7) - tz * 16 - 1;
|
||||
int n12 = MathHelper.floor(sz + d7) - tz * 16 + 1;
|
||||
if (n7 < 0) {
|
||||
n7 = 0;
|
||||
}
|
||||
if (n8 > 16) {
|
||||
n8 = 16;
|
||||
}
|
||||
if (n9 < 1) {
|
||||
n9 = 1;
|
||||
}
|
||||
if (n10 > 248) {
|
||||
n10 = 248;
|
||||
}
|
||||
if (n11 < 0) {
|
||||
n11 = 0;
|
||||
}
|
||||
if (n12 > 16) {
|
||||
n12 = 16;
|
||||
}
|
||||
boolean bl = false;
|
||||
for (int i = n7; !bl && i < n8; ++i) {
|
||||
for (n6 = n11; !bl && n6 < n12; ++n6) {
|
||||
for (int j = n10 + 1; !bl && j >= n9 - 1; --j) {
|
||||
// TODO: WARNING HEIGHT
|
||||
if (j < 0 || j >= 256) {
|
||||
continue;
|
||||
}
|
||||
|
||||
BlockData bb = get(terrain, i, j, n6);
|
||||
|
||||
if (B.isWater(bb)) {
|
||||
bl = true;
|
||||
}
|
||||
|
||||
if (j == n9 - 1 || i == n7 || i == n8 - 1 || n6 == n11 || n6 == n12 - 1) {
|
||||
continue;
|
||||
}
|
||||
j = n9;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!bl) {
|
||||
BlockPosition bps = new BlockPosition(0, 0, 0);
|
||||
for (n6 = n7; n6 < n8; ++n6) {
|
||||
double d13 = ((double) (n6 + tx * 16) + 0.5 - sx) / d7;
|
||||
for (int i = n11; i < n12; ++i) {
|
||||
double d14 = ((double) (i + tz * 16) + 0.5 - sz) / d7;
|
||||
boolean bl2 = false;
|
||||
if (d13 * d13 + d14 * d14 >= 1.0) {
|
||||
continue;
|
||||
}
|
||||
for (int j = n10; j > n9; --j) {
|
||||
double d15 = ((double) (j - 1) + 0.5 - sy) / d8;
|
||||
if ((d13 * d13 + d14 * d14) * (double) this.ravineCache[j - 1] + d15 * d15 / 6.0 >= 1.0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
BlockData blockData = get(terrain, n6, j, i);
|
||||
|
||||
if (isSurface(blockData)) {
|
||||
bl2 = true;
|
||||
}
|
||||
|
||||
if (j - 1 < 10) {
|
||||
set(terrain, n6, j, i, LAVA);
|
||||
continue;
|
||||
}
|
||||
|
||||
set(terrain, n6, j, i, CAVE_AIR);
|
||||
if (!bl2 || !isDirt(get(terrain, n6, j - 1, i))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
cSet(bps, n6 + tx * 16, 0, i + tz * 16);
|
||||
set(terrain, n6, j - 1, i, getSurfaceBlock(n6, i, rng));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (n5 != 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
++n3;
|
||||
}
|
||||
}
|
||||
|
||||
private BlockPosition cSet(BlockPosition bb, double var0, @SuppressWarnings("SameParameterValue") double var2, double var4) {
|
||||
bb.setX(MathHelper.floor(var0));
|
||||
bb.setY(MathHelper.floor(var2));
|
||||
bb.setZ(MathHelper.floor(var4));
|
||||
|
||||
return bb;
|
||||
}
|
||||
|
||||
private boolean isDirt(BlockData d) {
|
||||
//@builder
|
||||
Material m = d.getMaterial();
|
||||
return m.equals(Material.DIRT) ||
|
||||
m.equals(Material.COARSE_DIRT) ||
|
||||
m.equals(Material.SAND);
|
||||
//@done
|
||||
}
|
||||
|
||||
private boolean isSurface(BlockData d) {
|
||||
//@builder
|
||||
Material m = d.getMaterial();
|
||||
return m.equals(Material.GRASS_BLOCK) ||
|
||||
m.equals(Material.DIRT) ||
|
||||
m.equals(Material.COARSE_DIRT) ||
|
||||
m.equals(Material.PODZOL) ||
|
||||
m.equals(Material.SAND);
|
||||
//@done
|
||||
}
|
||||
|
||||
public void genRavines(int n, int n2, ChunkPosition chunkSnapshot, RNG bbb, Hunk<BlockData> terrain) {
|
||||
RNG b = this.rng.nextParallelRNG(21949666);
|
||||
RNG bx = this.rng.nextParallelRNG(6676121);
|
||||
long l = b.nextLong();
|
||||
long l2 = b.nextLong();
|
||||
for (int i = n - 8; i <= n + 8; ++i) {
|
||||
for (int j = n2 - 8; j <= n2 + 8; ++j) {
|
||||
long l3 = (long) i * l;
|
||||
long l4 = (long) j * l2;
|
||||
bx = this.rng.nextParallelRNG((int) (l3 ^ l4 ^ 6676121));
|
||||
doRavines(i, j, n, n2, chunkSnapshot, bx, terrain);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void doRavines(int tx, int tz, int sx, int sz, ChunkPosition chunkSnapshot, RNG b, Hunk<BlockData> terrain) {
|
||||
if (b.nextInt(getDimension().getRavineRarity()) != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
double x = tx * 16 + b.nextInt(16);
|
||||
double d2 = b.nextInt(b.nextInt(40) + 8) + 20;
|
||||
double z = tz * 16 + b.nextInt(16);
|
||||
int n5 = 1;
|
||||
for (int i = 0; i < n5; ++i) {
|
||||
float f = b.nextFloat() * 3.1415927f * 2.0f;
|
||||
float f2 = (b.nextFloat() - 0.5f) * 2.0f / 8.0f;
|
||||
float f3 = (b.nextFloat() * 2.0f + b.nextFloat()) * 2.0f;
|
||||
this.doRavine(b.nextLong(), sx, sz, chunkSnapshot, x, d2, z, f3, f, f2, 0, 0, 3.0, b, terrain);
|
||||
}
|
||||
}
|
||||
|
||||
public void generateRavines(RNG nextParallelRNG, int x, int z, Hunk<BlockData> terrain) {
|
||||
genRavines(x, z, new ChunkPosition(x, z), nextParallelRNG.nextParallelRNG(x).nextParallelRNG(z), terrain);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user