This commit is contained in:
Daniel Mills 2020-08-15 23:07:39 -04:00
parent da79b4e2ea
commit 86be84b015
10 changed files with 1162 additions and 641 deletions

File diff suppressed because it is too large Load Diff

View File

@ -25,7 +25,8 @@ import lombok.EqualsAndHashCode;
@Data
@EqualsAndHashCode(callSuper = false)
public abstract class BiomeChunkGenerator extends DimensionChunkGenerator {
public abstract class BiomeChunkGenerator extends DimensionChunkGenerator
{
protected IrisLock regLock;
private KMap<String, IrisGenerator> generators;
private KMap<String, IrisGenerator> ceilingGenerators;
@ -33,14 +34,16 @@ public abstract class BiomeChunkGenerator extends DimensionChunkGenerator {
protected CNG masterFracture;
protected ChronoLatch cwarn = new ChronoLatch(1000);
public BiomeChunkGenerator(String dimensionName) {
public BiomeChunkGenerator(String dimensionName)
{
super(dimensionName);
generators = new KMap<>();
ceilingGenerators = new KMap<>();
regLock = new IrisLock("BiomeChunkGenerator");
}
public void onInit(World world, RNG rng) {
public void onInit(World world, RNG rng)
{
super.onInit(world, rng);
loadGenerators();
glBiome = new GenLayerBiome(this, masterRandom.nextParallelRNG(1));
@ -48,17 +51,20 @@ public abstract class BiomeChunkGenerator extends DimensionChunkGenerator {
}
@Override
public void onHotload() {
public void onHotload()
{
super.onHotload();
loadGenerators();
glBiome = new GenLayerBiome(this, masterRandom.nextParallelRNG(1));
}
public void registerGenerator(IrisGenerator g, IrisDimension dim) {
public void registerGenerator(IrisGenerator g, IrisDimension dim)
{
KMap<String, IrisGenerator> generators = dim.isInverted() ? ceilingGenerators : this.generators;
regLock.lock();
if (g.getLoadKey() == null || generators.containsKey(g.getLoadKey())) {
if(g.getLoadKey() == null || generators.containsKey(g.getLoadKey()))
{
regLock.unlock();
return;
}
@ -67,83 +73,100 @@ public abstract class BiomeChunkGenerator extends DimensionChunkGenerator {
generators.put(g.getLoadKey(), g);
}
protected KMap<String, IrisGenerator> getGenerators() {
protected KMap<String, IrisGenerator> getGenerators()
{
return getDimension().isInverted() ? ceilingGenerators : generators;
}
protected double getBiomeHeight(double rx, double rz, int x, int z) {
protected double getBiomeHeight(double rx, double rz, int x, int z)
{
double h = 0;
for (IrisGenerator i : getGenerators().values()) {
for(IrisGenerator i : getGenerators().values())
{
h += interpolateGenerator(rx, rz, i);
}
return h;
}
protected double interpolateGenerator(double rx, double rz, IrisGenerator gen) {
double hi = IrisInterpolation.getNoise(gen.getInterpolationFunction(), (int) Math.round(rx),
(int) Math.round(rz), gen.getInterpolationScale(), (xx, zz) -> {
try {
IrisBiome b = sampleBiome((int) xx, (int) zz).getBiome();
for (IrisBiomeGeneratorLink i : b.getGenerators()) {
if (i.getGenerator().equals(gen.getLoadKey())) {
return i.getMax();
}
}
protected double interpolateGenerator(double rx, double rz, IrisGenerator gen)
{
double hi = IrisInterpolation.getNoise(gen.getInterpolationFunction(), (int) Math.round(rx), (int) Math.round(rz), gen.getInterpolationScale(), (xx, zz) ->
{
try
{
IrisBiome b = sampleBiome((int) xx, (int) zz).getBiome();
for(IrisBiomeGeneratorLink i : b.getGenerators())
{
if(i.getGenerator().equals(gen.getLoadKey()))
{
return i.getMax();
}
}
catch (Throwable e) {
Iris.warn("Failed to sample biome at " + rx + " " + rz + " using the generator "
+ gen.getLoadKey());
}
catch(Throwable e)
{
e.printStackTrace();
Iris.warn("Failed to sample hi biome at " + rx + " " + rz + " using the generator " + gen.getLoadKey());
}
return 0;
});
double lo = IrisInterpolation.getNoise(gen.getInterpolationFunction(), (int) Math.round(rx), (int) Math.round(rz), gen.getInterpolationScale(), (xx, zz) ->
{
try
{
IrisBiome b = sampleBiome((int) xx, (int) zz).getBiome();
for(IrisBiomeGeneratorLink i : b.getGenerators())
{
if(i.getGenerator().equals(gen.getLoadKey()))
{
return i.getMin();
}
return 0;
});
}
}
double lo = IrisInterpolation.getNoise(gen.getInterpolationFunction(), (int) Math.round(rx),
(int) Math.round(rz), gen.getInterpolationScale(), (xx, zz) -> {
try {
IrisBiome b = sampleBiome((int) xx, (int) zz).getBiome();
catch(Throwable e)
{
e.printStackTrace();
Iris.warn("Failed to sample lo biome at " + rx + " " + rz + " using the generator " + gen.getLoadKey());
}
for (IrisBiomeGeneratorLink i : b.getGenerators()) {
if (i.getGenerator().equals(gen.getLoadKey())) {
return i.getMin();
}
}
}
catch (Throwable e) {
Iris.warn("Failed to sample biome at " + rx + " " + rz + " using the generator "
+ gen.getLoadKey());
}
return 0;
});
return 0;
});
return M.lerp(lo, hi, gen.getHeight(rx, rz, world.getSeed() + 239945));
}
protected void loadGenerators() {
protected void loadGenerators()
{
generators.clear();
ceilingGenerators.clear();
loadGenerators(((CeilingChunkGenerator) this).getFloorDimension());
loadGenerators(((CeilingChunkGenerator) this).getCeilingDimension());
}
protected void loadGenerators(IrisDimension dim) {
if (dim == null) {
protected void loadGenerators(IrisDimension dim)
{
if(dim == null)
{
return;
}
KList<String> touch = new KList<>();
KList<String> loadQueue = new KList<>();
for (String i : dim.getRegions()) {
for(String i : dim.getRegions())
{
IrisRegion r = loadRegion(i);
if (r != null) {
if(r != null)
{
loadQueue.addAll(r.getLandBiomes());
loadQueue.addAll(r.getSeaBiomes());
loadQueue.addAll(r.getShoreBiomes());
@ -152,10 +175,12 @@ public abstract class BiomeChunkGenerator extends DimensionChunkGenerator {
}
}
while (!loadQueue.isEmpty()) {
while(!loadQueue.isEmpty())
{
String next = loadQueue.pop();
if (!touch.contains(next)) {
if(!touch.contains(next))
{
touch.add(next);
IrisBiome biome = loadBiome(next);
biome.getGenerators().forEach((i) -> registerGenerator(i.getCachedGenerator(this), dim));
@ -164,32 +189,40 @@ public abstract class BiomeChunkGenerator extends DimensionChunkGenerator {
}
}
public IrisRegion sampleRegion(int x, int z) {
public IrisRegion sampleRegion(int x, int z)
{
double wx = getModifiedX(x, z);
double wz = getModifiedZ(x, z);
return glBiome.getRegion(wx, wz);
}
public BiomeResult sampleBiome(int x, int z) {
return getCache().getRawBiome(x, z, () -> {
if (!getDimension().getFocus().equals("")) {
public BiomeResult sampleBiome(int x, int z)
{
return getCache().getRawBiome(x, z, () ->
{
if(!getDimension().getFocus().equals(""))
{
IrisBiome biome = loadBiome(getDimension().getFocus());
for (String i : getDimension().getRegions()) {
for(String i : getDimension().getRegions())
{
IrisRegion reg = loadRegion(i);
if (reg.getLandBiomes().contains(biome.getLoadKey())) {
if(reg.getLandBiomes().contains(biome.getLoadKey()))
{
biome.setInferredType(InferredType.LAND);
break;
}
if (reg.getSeaBiomes().contains(biome.getLoadKey())) {
if(reg.getSeaBiomes().contains(biome.getLoadKey()))
{
biome.setInferredType(InferredType.SEA);
break;
}
if (reg.getShoreBiomes().contains(biome.getLoadKey())) {
if(reg.getShoreBiomes().contains(biome.getLoadKey()))
{
biome.setInferredType(InferredType.SHORE);
break;
}

View File

@ -46,7 +46,8 @@ import net.md_5.bungee.api.ChatColor;
@Data
@EqualsAndHashCode(callSuper = false)
public abstract class ContextualChunkGenerator extends ChunkGenerator implements Listener {
public abstract class ContextualChunkGenerator extends ChunkGenerator implements Listener
{
private AtomicMulticache cache;
private IrisDataManager data;
protected boolean failing;
@ -65,8 +66,10 @@ public abstract class ContextualChunkGenerator extends ChunkGenerator implements
protected long hlast;
private boolean fastPregen = false;
protected boolean pregenDone;
private volatile boolean hotloadable = false;
public ContextualChunkGenerator() {
public ContextualChunkGenerator()
{
pushLatch = new ChronoLatch(3000);
tickLatch = new ChronoLatch(650);
perSecond = new ChronoLatch(1000);
@ -101,57 +104,72 @@ public abstract class ContextualChunkGenerator extends ChunkGenerator implements
protected abstract void onPlayerLeft(Player p);
public IrisRegion loadRegion(String i) {
public IrisRegion loadRegion(String i)
{
return getData().getRegionLoader().load(i);
}
public IrisBiome loadBiome(String i) {
public IrisBiome loadBiome(String i)
{
return getData().getBiomeLoader().load(i);
}
public IrisStructure loadStructure(String i) {
public IrisStructure loadStructure(String i)
{
return getData().getStructureLoader().load(i);
}
public IrisObject loadObject(String i) {
public IrisObject loadObject(String i)
{
return getData().getObjectLoader().load(i);
}
public IrisDimension loadDimension(String i) {
public IrisDimension loadDimension(String i)
{
return (getData() == null ? Iris.globaldata : getData()).getDimensionLoader().load(i);
}
public IrisGenerator loadGenerator(String i) {
public IrisGenerator loadGenerator(String i)
{
return getData().getGeneratorLoader().load(i);
}
public IrisDataManager getData() {
public IrisDataManager getData()
{
return isDev() ? Iris.globaldata : data;
}
private void init(World world, RNG rng) {
if (initialized) {
private void init(World world, RNG rng)
{
if(initialized)
{
return;
}
data = new IrisDataManager(getWorld().getWorldFolder());
this.world = world;
data = new IrisDataManager(getWorld().getWorldFolder());
this.masterRandom = new RNG(world.getSeed());
metrics = new IrisMetrics(128);
initialized = true;
Bukkit.getServer().getPluginManager().registerEvents(this, Iris.instance);
task = Bukkit.getScheduler().scheduleSyncRepeatingTask(Iris.instance, this::tick, 0, 0);
onInit(world, masterRandom);
setHotloadable(true);
}
private void tick() {
if (dev) {
if (perSecond.flip()) {
if (generated > (fastPregen ? 1950 : 770)) {
private void tick()
{
if(dev)
{
if(perSecond.flip())
{
if(generated > (fastPregen ? 1950 : 770))
{
pregenDone = true;
}
if (pregenDone) {
if(pregenDone)
{
metrics.getPerSecond().put(generated);
generated = 0;
}
@ -160,7 +178,8 @@ public abstract class ContextualChunkGenerator extends ChunkGenerator implements
}
}
else {
else
{
pregenDone = true;
fastPregen = false;
}
@ -169,80 +188,100 @@ public abstract class ContextualChunkGenerator extends ChunkGenerator implements
}
@EventHandler
public void on(PlayerTeleportEvent e) {
if (e.getFrom().getWorld().equals(world) && !e.getTo().getWorld().equals(world)) {
public void on(PlayerTeleportEvent e)
{
if(e.getFrom().getWorld().equals(world) && !e.getTo().getWorld().equals(world))
{
tick();
onPlayerLeft(e.getPlayer());
}
if (!e.getFrom().getWorld().equals(world) && e.getTo().getWorld().equals(world)) {
if(!e.getFrom().getWorld().equals(world) && e.getTo().getWorld().equals(world))
{
tick();
onPlayerJoin(e.getPlayer());
}
}
@EventHandler
public void on(PlayerQuitEvent e) {
if (e.getPlayer().getWorld().equals(world)) {
public void on(PlayerQuitEvent e)
{
if(e.getPlayer().getWorld().equals(world))
{
tick();
onPlayerLeft(e.getPlayer());
}
}
@EventHandler
public void on(PlayerJoinEvent e) {
if (e.getPlayer().getWorld().equals(world)) {
public void on(PlayerJoinEvent e)
{
if(e.getPlayer().getWorld().equals(world))
{
tick();
onPlayerJoin(e.getPlayer());
}
}
@EventHandler
public void on(ChunkLoadEvent e) {
if (e.getWorld().equals(world)) {
public void on(ChunkLoadEvent e)
{
if(e.getWorld().equals(world))
{
tick();
onChunkLoaded(e.getChunk());
}
}
@EventHandler
public void on(ChunkUnloadEvent e) {
if (e.getWorld().equals(world)) {
public void on(ChunkUnloadEvent e)
{
if(e.getWorld().equals(world))
{
tick();
onChunkUnloaded(e.getChunk());
}
}
@EventHandler
public void on(WorldUnloadEvent e) {
if (world != null && e.getWorld().equals(world)) {
public void on(WorldUnloadEvent e)
{
if(world != null && e.getWorld().equals(world))
{
close();
}
}
public void close() {
public void close()
{
HandlerList.unregisterAll(this);
Bukkit.getScheduler().cancelTask(getTask());
onClose();
}
@Override
public boolean canSpawn(World world, int x, int z) {
public boolean canSpawn(World world, int x, int z)
{
return super.canSpawn(world, x, z);
}
protected ChunkData generateChunkDataFailure(World world, Random no, int x, int z, BiomeGrid biomeGrid) {
protected ChunkData generateChunkDataFailure(World world, Random no, int x, int z, BiomeGrid biomeGrid)
{
ChunkData c = Bukkit.createChunkData(world);
for (int i = 0; i < 16; i++) {
for (int j = 0; j < 16; j++) {
for(int i = 0; i < 16; i++)
{
for(int j = 0; j < 16; j++)
{
int h = 0;
if (j == i || j + i == 16) {
if(j == i || j + i == 16)
{
c.setBlock(i, h, j, B.getBlockData("RED_TERRACOTTA"));
}
else {
else
{
c.setBlock(i, h, j, B.getBlockData("BLACK_TERRACOTTA"));
}
}
@ -251,18 +290,23 @@ public abstract class ContextualChunkGenerator extends ChunkGenerator implements
return c;
}
protected ChunkData generateChunkFastPregen(World world, Random no, int x, int z, BiomeGrid biomeGrid) {
protected ChunkData generateChunkFastPregen(World world, Random no, int x, int z, BiomeGrid biomeGrid)
{
ChunkData c = Bukkit.createChunkData(world);
for (int i = 0; i < 16; i++) {
for (int j = 0; j < 16; j++) {
for(int i = 0; i < 16; i++)
{
for(int j = 0; j < 16; j++)
{
int h = 0;
if (j == i || j + i == 16) {
if(j == i || j + i == 16)
{
c.setBlock(i, h, j, B.getBlockData("BLUE_TERRACOTTA"));
}
else {
else
{
c.setBlock(i, h, j, B.getBlockData("WHITE_TERRACOTTA"));
}
}
@ -272,33 +316,39 @@ public abstract class ContextualChunkGenerator extends ChunkGenerator implements
}
@Override
public ChunkData generateChunkData(World world, Random no, int x, int z, BiomeGrid biomeGrid) {
public ChunkData generateChunkData(World world, Random no, int x, int z, BiomeGrid biomeGrid)
{
hlock.lock();
if (!dev) {
setHotloadable(false);
if(!dev)
{
pregenDone = true;
fastPregen = false;
}
PrecisionStopwatch sx = PrecisionStopwatch.start();
if (failing) {
if(failing)
{
hlock.unlock();
return generateChunkDataFailure(world, no, x, z, biomeGrid);
}
try {
checkHotload(world);
try
{
PrecisionStopwatch s = PrecisionStopwatch.start();
RNG random = new RNG(world.getSeed());
init(world, random.nextParallelRNG(0));
ChunkData c = Bukkit.createChunkData(world);
if (!pregenDone && fastPregen) {
if(!pregenDone && fastPregen)
{
c = generateChunkFastPregen(world, no, x, z, biomeGrid);
}
else {
else
{
onGenerate(random, x, z, c, biomeGrid);
}
@ -308,69 +358,85 @@ public abstract class ContextualChunkGenerator extends ChunkGenerator implements
CNG.hits = 0;
Iris.instance.hit(hits);
metrics.getLoss().put(sx.getMilliseconds() - s.getMilliseconds());
setHotloadable(true);
hlock.unlock();
return c;
}
catch (Throwable e) {
catch(Throwable e)
{
fail(e);
}
setHotloadable(true);
hlock.unlock();
return generateChunkDataFailure(world, no, x, z, biomeGrid);
}
public void checkHotload() {
if (M.ms() - hlast < 1000) {
public void checkHotload()
{
if(M.ms() - hlast < 1000)
{
return;
}
hlock.lock();
if (world != null) {
if(world != null)
{
checkHotload(world);
}
hlock.unlock();
}
private void checkHotload(World world) {
if (pushLatch.flip()) {
private void checkHotload(World world)
{
if(!isHotloadable())
{
return;
}
if (this.world == null) {
if(pushLatch.flip())
{
if(this.world == null)
{
this.world = world;
}
Iris.hotloader.check((IrisContext) this);
if (this instanceof IrisContext) {
if(this instanceof IrisContext)
{
IrisContext.pushContext((IrisContext) this);
}
}
}
public void onHotload() {
public void onHotload()
{
hlast = M.ms();
}
protected void fail(Throwable e) {
if (failing) {
protected void fail(Throwable e)
{
if(failing)
{
return;
}
failing = true;
e.printStackTrace();
J.a(() -> {
J.a(() ->
{
J.sleep(1000);
Iris.error(
"---------------------------------------------------------------------------------------------------------");
Iris.error("---------------------------------------------------------------------------------------------------------");
e.printStackTrace();
Iris.error(
"---------------------------------------------------------------------------------------------------------");
Iris.error("---------------------------------------------------------------------------------------------------------");
Iris.error("ERROR! Failed to generate chunk! Iris has entered a failed state!");
Iris.error(
"---------------------------------------------------------------------------------------------------------");
Iris.error("---------------------------------------------------------------------------------------------------------");
for (Player i : world.getPlayers()) {
for(Player i : world.getPlayers())
{
Iris.instance.imsg(i, ChatColor.DARK_RED + "Iris Generator has crashed!");
Iris.instance.imsg(i, ChatColor.RED + "- Check the console for the error.");
Iris.instance.imsg(i, ChatColor.RED + "- To Regen, use /iris std open <dim>");
@ -382,17 +448,20 @@ public abstract class ContextualChunkGenerator extends ChunkGenerator implements
}
@Override
public List<BlockPopulator> getDefaultPopulators(World world) {
public List<BlockPopulator> getDefaultPopulators(World world)
{
return super.getDefaultPopulators(world);
}
@Override
public Location getFixedSpawnLocation(World world, Random random) {
public Location getFixedSpawnLocation(World world, Random random)
{
return super.getFixedSpawnLocation(world, random);
}
@Override
public boolean isParallelCapable() {
public boolean isParallelCapable()
{
return true;
}
}

View File

@ -4,6 +4,7 @@ import java.awt.Color;
import java.io.IOException;
import java.lang.reflect.Method;
import org.bukkit.Bukkit;
import org.bukkit.Chunk;
import org.bukkit.Location;
import org.bukkit.World;
@ -28,94 +29,114 @@ import lombok.EqualsAndHashCode;
@Data
@EqualsAndHashCode(callSuper = false)
public class IrisChunkGenerator extends CeilingChunkGenerator implements IrisContext {
public class IrisChunkGenerator extends CeilingChunkGenerator implements IrisContext
{
private Method initLighting;
private IrisLock lock;
private IrisBiome hb = null;
private IrisRegion hr = null;
private KMap<Player, IrisBiome> b = new KMap<>();
public IrisChunkGenerator(String dimensionName, int threads) {
public IrisChunkGenerator(String dimensionName, int threads)
{
super(dimensionName, threads);
lock = new IrisLock("IrisChunkGenerator");
}
public IrisChunkGenerator(String dimensionName) {
public IrisChunkGenerator(String dimensionName)
{
super(dimensionName, 16);
lock = new IrisLock("IrisChunkGenerator");
}
public IrisChunkGenerator(int tc) {
public IrisChunkGenerator(int tc)
{
super("", tc);
lock = new IrisLock("IrisChunkGenerator");
}
public void hotload() {
public void hotload()
{
onHotload();
}
public void retry() {
if (failing) {
public void retry()
{
if(failing)
{
failing = false;
hotload();
}
}
@Override
protected void onGenerate(RNG random, int x, int z, ChunkData data, BiomeGrid grid) {
protected void onGenerate(RNG random, int x, int z, ChunkData data, BiomeGrid grid)
{
lock.lock();
super.onGenerate(random, x, z, data, grid);
lock.unlock();
}
public void onInit(World world, RNG rng) {
try {
public void onInit(World world, RNG rng)
{
try
{
super.onInit(world, rng);
}
catch (Throwable e) {
catch(Throwable e)
{
fail(e);
}
}
@Override
public BiomeResult getBiome(int x, int z) {
public BiomeResult getBiome(int x, int z)
{
return sampleBiome(x, z);
}
@Override
public IrisRegion getRegion(int x, int z) {
public IrisRegion getRegion(int x, int z)
{
return sampleRegion(x, z);
}
@Override
public int getHeight(int x, int z) {
public int getHeight(int x, int z)
{
return sampleHeight(x, z);
}
@Override
public void onTick(int ticks) {
public void onTick(int ticks)
{
super.onTick(ticks);
for (Player i : getWorld().getPlayers()) {
for(Player i : getWorld().getPlayers())
{
Location l = i.getLocation();
IrisRegion r = sampleRegion(l.getBlockX(), l.getBlockZ());
IrisBiome b = sampleTrueBiome(l.getBlockX(), l.getBlockY(), l.getBlockZ()).getBiome();
for (IrisEffect j : r.getEffects()) {
for(IrisEffect j : r.getEffects())
{
j.apply(i, this);
}
for (IrisEffect j : b.getEffects()) {
for(IrisEffect j : b.getEffects())
{
j.apply(i, this);
}
}
}
@Override
protected void onClose() {
protected void onClose()
{
super.onClose();
try {
try
{
parallaxMap.saveAll();
ceilingParallaxMap.saveAll();
parallaxMap.getLoadedChunks().clear();
@ -124,7 +145,8 @@ public class IrisChunkGenerator extends CeilingChunkGenerator implements IrisCon
ceilingParallaxMap.getLoadedRegions().clear();
}
catch (IOException e) {
catch(IOException e)
{
e.printStackTrace();
}
@ -135,45 +157,61 @@ public class IrisChunkGenerator extends CeilingChunkGenerator implements IrisCon
}
@Override
protected void onFailure(Throwable e) {
protected void onFailure(Throwable e)
{
}
@Override
protected void onChunkLoaded(Chunk c) {
protected void onChunkLoaded(Chunk c)
{
}
@Override
protected void onChunkUnloaded(Chunk c) {
protected void onChunkUnloaded(Chunk c)
{
}
@Override
protected void onPlayerJoin(Player p) {
protected void onPlayerJoin(Player p)
{
}
@Override
public void onPlayerLeft(Player p) {
public void onPlayerLeft(Player p)
{
super.onPlayerLeft(p);
}
@Override
public void onHotloaded() {
public void onHotloaded()
{
if(!isHotloadable())
{
Iris.warn("Hotload skipped (During Chunk Gen). Retrying.");
Bukkit.getScheduler().scheduleSyncDelayedTask(Iris.instance, this::onHotloaded);
return;
}
CNG.creates = 0;
getData().dump();
onHotload();
}
public long guessMemoryUsage() {
public long guessMemoryUsage()
{
long bytes = 1024 * 1024 * (8 + (getThreads() / 3));
for (AtomicRegionData i : parallaxMap.getLoadedRegions().values()) {
for(AtomicRegionData i : parallaxMap.getLoadedRegions().values())
{
bytes += i.guessMemoryUsage();
}
for (AtomicRegionData i : ceilingParallaxMap.getLoadedRegions().values()) {
for(AtomicRegionData i : ceilingParallaxMap.getLoadedRegions().values())
{
bytes += i.guessMemoryUsage();
}
@ -186,34 +224,41 @@ public class IrisChunkGenerator extends CeilingChunkGenerator implements IrisCon
}
@Override
public boolean shouldGenerateCaves() {
public boolean shouldGenerateCaves()
{
return false;
}
@Override
public boolean shouldGenerateDecorations() {
public boolean shouldGenerateDecorations()
{
return false;
}
@Override
public boolean shouldGenerateMobs() {
public boolean shouldGenerateMobs()
{
return true;
}
@Override
public boolean shouldGenerateStructures() {
if (!isInitialized()) {
public boolean shouldGenerateStructures()
{
if(!isInitialized())
{
return false;
}
return getDimension().isVanillaStructures();
}
public Function2<Double, Double, Color> createRenderer() {
public Function2<Double, Double, Color> createRenderer()
{
return (x, z) -> render(x, z);
}
private Color render(double x, double z) {
private Color render(double x, double z)
{
int ix = (int) x;
int iz = (int) z;
double height = getTerrainHeight(ix, iz);
@ -225,22 +270,24 @@ public class IrisChunkGenerator extends CeilingChunkGenerator implements IrisCon
shift -= shift2;
float sat = 0;
if (hr.getLoadKey().equals(region.getLoadKey())) {
if(hr.getLoadKey().equals(region.getLoadKey()))
{
sat += 0.2;
}
if (hb.getLoadKey().equals(biome.getLoadKey())) {
if(hb.getLoadKey().equals(biome.getLoadKey()))
{
sat += 0.3;
}
Color c = Color.getHSBColor((biome.isLand() ? 0.233f : 0.644f) - shift, 0.25f + shift + sat,
(float) (Math.max(0, Math.min(height + getFluidHeight(), 255)) / 255));
Color c = Color.getHSBColor((biome.isLand() ? 0.233f : 0.644f) - shift, 0.25f + shift + sat, (float) (Math.max(0, Math.min(height + getFluidHeight(), 255)) / 255));
return c;
}
public String textFor(double x, double z) {
public String textFor(double x, double z)
{
int ix = (int) x;
int iz = (int) z;
@ -249,8 +296,6 @@ public class IrisChunkGenerator extends CeilingChunkGenerator implements IrisCon
IrisBiome biome = sampleTrueBiome(ix, iz, height).getBiome();
hb = biome;
hr = region;
return biome.getName() + " ("
+ Form.capitalizeWords(biome.getInferredType().name().toLowerCase().replaceAll("\\Q_\\E", " ") + ") in "
+ region.getName() + "\nY: " + (int) height);
return biome.getName() + " (" + Form.capitalizeWords(biome.getInferredType().name().toLowerCase().replaceAll("\\Q_\\E", " ") + ") in " + region.getName() + "\nY: " + (int) height);
}
}

View File

@ -4,7 +4,6 @@ import com.volmit.iris.gen.ContextualChunkGenerator;
import com.volmit.iris.noise.CNG;
import com.volmit.iris.object.InferredType;
import com.volmit.iris.object.IrisRegion;
import com.volmit.iris.object.NoiseStyle;
import com.volmit.iris.util.BiomeResult;
import com.volmit.iris.util.RNG;
@ -21,7 +20,7 @@ public class BiomeDataProvider
{
this.type = type;
this.layer = layer;
generator = NoiseStyle.CELLULAR_IRIS_DOUBLE.create(rng.nextParallelRNG(4645079 + (type.ordinal() * 23845)));
generator = layer.getIris().getDimension().getBiomeStyle(type).create(rng.nextParallelRNG(4645079 + (type.ordinal() * 23845)));
}
public BiomeResult generatePureData(ContextualChunkGenerator g, double bx, double bz, int rawX, int rawZ, IrisRegion regionData)

View File

@ -8,19 +8,20 @@ import com.volmit.iris.util.KList;
import com.volmit.iris.util.NoiseInjector;
import com.volmit.iris.util.RNG;
public class CNG {
public class CNG
{
public static long hits = 0;
public static long creates = 0;
public static final NoiseInjector ADD = (s, v) -> new double[] { s + v, 1 };
public static final NoiseInjector SRC_SUBTRACT = (s, v) -> new double[] { s - v < 0 ? 0 : s - v, -1 };
public static final NoiseInjector DST_SUBTRACT = (s, v) -> new double[] { v - s < 0 ? 0 : s - v, -1 };
public static final NoiseInjector MULTIPLY = (s, v) -> new double[] { s * v, 0 };
public static final NoiseInjector MAX = (s, v) -> new double[] { Math.max(s, v), 0 };
public static final NoiseInjector MIN = (s, v) -> new double[] { Math.min(s, v), 0 };
public static final NoiseInjector SRC_MOD = (s, v) -> new double[] { s % v, 0 };
public static final NoiseInjector SRC_POW = (s, v) -> new double[] { Math.pow(s, v), 0 };
public static final NoiseInjector DST_MOD = (s, v) -> new double[] { v % s, 0 };
public static final NoiseInjector DST_POW = (s, v) -> new double[] { Math.pow(v, s), 0 };
public static final NoiseInjector ADD = (s, v) -> new double[] {s + v, 1};
public static final NoiseInjector SRC_SUBTRACT = (s, v) -> new double[] {s - v < 0 ? 0 : s - v, -1};
public static final NoiseInjector DST_SUBTRACT = (s, v) -> new double[] {v - s < 0 ? 0 : s - v, -1};
public static final NoiseInjector MULTIPLY = (s, v) -> new double[] {s * v, 0};
public static final NoiseInjector MAX = (s, v) -> new double[] {Math.max(s, v), 0};
public static final NoiseInjector MIN = (s, v) -> new double[] {Math.min(s, v), 0};
public static final NoiseInjector SRC_MOD = (s, v) -> new double[] {s % v, 0};
public static final NoiseInjector SRC_POW = (s, v) -> new double[] {Math.pow(s, v), 0};
public static final NoiseInjector DST_MOD = (s, v) -> new double[] {v % s, 0};
public static final NoiseInjector DST_POW = (s, v) -> new double[] {Math.pow(v, s), 0};
private double scale;
private double bakedScale;
private double fscale;
@ -36,31 +37,38 @@ public class CNG {
private double down;
private double power;
public NoiseGenerator getGen() {
public NoiseGenerator getGen()
{
return generator;
}
public static CNG signature(RNG rng) {
public static CNG signature(RNG rng)
{
return signature(rng, NoiseType.SIMPLEX);
}
public static CNG signatureHalf(RNG rng) {
public static CNG signatureHalf(RNG rng)
{
return signatureHalf(rng, NoiseType.SIMPLEX);
}
public static CNG signatureThick(RNG rng) {
public static CNG signatureThick(RNG rng)
{
return signatureThick(rng, NoiseType.SIMPLEX);
}
public static CNG signatureDouble(RNG rng) {
public static CNG signatureDouble(RNG rng)
{
return signatureDouble(rng, NoiseType.SIMPLEX);
}
public static CNG signatureDouble(RNG rng, NoiseType t) {
public static CNG signatureDouble(RNG rng, NoiseType t)
{
return signatureThick(rng, t).fractureWith(signature(rng.nextParallelRNG(4956)), 93);
}
public static CNG signature(RNG rng, NoiseType t) {
public static CNG signature(RNG rng, NoiseType t)
{
// @builder
return new CNG(rng.nextParallelRNG(17), t, 1D, 1)
.fractureWith(
@ -72,7 +80,8 @@ public class CNG {
// @done
}
public static CNG signatureThick(RNG rng, NoiseType t) {
public static CNG signatureThick(RNG rng, NoiseType t)
{
// @builder
return new CNG(rng.nextParallelRNG(133), t, 1D, 1)
.fractureWith(
@ -84,7 +93,8 @@ public class CNG {
// @done
}
public static CNG signatureHalf(RNG rng, NoiseType t) {
public static CNG signatureHalf(RNG rng, NoiseType t)
{
// @builder
return new CNG(rng.nextParallelRNG(127), t, 1D, 1)
.fractureWith(
@ -96,19 +106,23 @@ public class CNG {
// @done
}
public CNG(RNG random) {
public CNG(RNG random)
{
this(random, 1);
}
public CNG(RNG random, int octaves) {
public CNG(RNG random, int octaves)
{
this(random, 1D, octaves);
}
public CNG(RNG random, double opacity, int octaves) {
public CNG(RNG random, double opacity, int octaves)
{
this(random, NoiseType.SIMPLEX, opacity, octaves);
}
public CNG(RNG random, NoiseType t, double opacity, int octaves) {
public CNG(RNG random, NoiseType t, double opacity, int octaves)
{
creates++;
this.oct = octaves;
this.rng = random;
@ -124,19 +138,23 @@ public class CNG {
this.opacity = opacity;
this.injector = ADD;
if (generator instanceof OctaveNoise) {
if(generator instanceof OctaveNoise)
{
((OctaveNoise) generator).setOctaves(octaves);
}
}
public CNG bake() {
public CNG bake()
{
bakedScale *= scale;
scale = 1;
return this;
}
public CNG child(CNG c) {
if (children == null) {
public CNG child(CNG c)
{
if(children == null)
{
children = new KList<>();
}
@ -145,114 +163,141 @@ public class CNG {
}
@Deprecated
public RNG nextRNG() {
public RNG nextRNG()
{
return getRNG().nextRNG();
}
public RNG getRNG() {
public RNG getRNG()
{
return rng;
}
public CNG fractureWith(CNG c, double scale) {
public CNG fractureWith(CNG c, double scale)
{
fracture = c;
fscale = scale;
return this;
}
public CNG scale(double c) {
public CNG scale(double c)
{
scale = c;
return this;
}
public CNG patch(double c) {
public CNG patch(double c)
{
patch = c;
return this;
}
public CNG up(double c) {
public CNG up(double c)
{
up = c;
return this;
}
public CNG down(double c) {
public CNG down(double c)
{
down = c;
return this;
}
public CNG injectWith(NoiseInjector i) {
public CNG injectWith(NoiseInjector i)
{
injector = i;
return this;
}
public <T extends IRare> T fitRarity(KList<T> b, double... dim) {
if (b.size() == 0) {
public <T extends IRare> T fitRarity(KList<T> b, double... dim)
{
if(b.size() == 0)
{
return null;
}
if (b.size() == 1) {
if(b.size() == 1)
{
return b.get(0);
}
KList<T> rarityMapped = new KList<>();
boolean o = false;
int max = 1;
for (T i : b) {
if (i.getRarity() > max) {
for(T i : b)
{
if(i.getRarity() > max)
{
max = i.getRarity();
}
}
max++;
for (T i : b) {
for (int j = 0; j < max - i.getRarity(); j++) {
if (o = !o) {
for(T i : b)
{
for(int j = 0; j < max - i.getRarity(); j++)
{
if(o = !o)
{
rarityMapped.add(i);
}
else {
else
{
rarityMapped.add(0, i);
}
}
}
if (rarityMapped.size() == 1) {
if(rarityMapped.size() == 1)
{
return rarityMapped.get(0);
}
if (rarityMapped.isEmpty()) {
if(rarityMapped.isEmpty())
{
throw new RuntimeException("BAD RARITY MAP! RELATED TO: " + b.toString(", or possibly "));
}
return fit(rarityMapped, dim);
}
public <T> T fit(T[] v, double... dim) {
if (v.length == 0) {
public <T> T fit(T[] v, double... dim)
{
if(v.length == 0)
{
return null;
}
if (v.length == 1) {
if(v.length == 1)
{
return v[0];
}
return v[fit(0, v.length - 1, dim)];
}
public <T> T fit(List<T> v, double... dim) {
if (v.size() == 0) {
public <T> T fit(List<T> v, double... dim)
{
if(v.size() == 0)
{
return null;
}
if (v.size() == 1) {
if(v.size() == 1)
{
return v.get(0);
}
return v.get(fit(0, v.size() - 1, dim));
}
public int fit(int min, int max, double... dim) {
if (min == max) {
public int fit(int min, int max, double... dim)
{
if(min == max)
{
return min;
}
@ -261,8 +306,10 @@ public class CNG {
return (int) Math.round(IrisInterpolation.lerp(min, max, noise));
}
public int fit(double min, double max, double... dim) {
if (min == max) {
public int fit(double min, double max, double... dim)
{
if(min == max)
{
return (int) Math.round(min);
}
@ -271,8 +318,10 @@ public class CNG {
return (int) Math.round(IrisInterpolation.lerp(min, max, noise));
}
public double fitDouble(double min, double max, double... dim) {
if (min == max) {
public double fitDouble(double min, double max, double... dim)
{
if(min == max)
{
return min;
}
@ -281,21 +330,24 @@ public class CNG {
return IrisInterpolation.lerp(min, max, noise);
}
public double noise(double... dim) {
public double noise(double... dim)
{
double scale = this.bakedScale * this.scale;
double f = fracture != null ? (fracture.noise(dim) - 0.5) * fscale : 0D;
double f = (fracture != null ? (fracture.noise(dim) - 0.5) * fscale : 0D);
double x = dim.length > 0 ? dim[0] + f : 0D;
double y = dim.length > 1 ? dim[1] - f : 0D;
double z = dim.length > 2 ? dim[2] + f : 0D;
double z = dim.length > 1 ? dim[1] - f : 0D;
double y = dim.length > 2 ? dim[2] + f : 0D;
double n = generator.noise(x * scale, y * scale, z * scale) * opacity;
n = power != 1D ? Math.pow(n, power) : n;
double m = 1;
hits += oct;
if (children == null) {
if(children == null)
{
return (n - down + up) * patch;
}
for (CNG i : children) {
for(CNG i : children)
{
double[] r = injector.combine(n, i.noise(dim));
n = r[0];
m += r[1];
@ -304,17 +356,20 @@ public class CNG {
return ((n / m) - down + up) * patch;
}
public CNG pow(double power) {
public CNG pow(double power)
{
this.power = power;
return this;
}
public CNG oct(int octaves) {
public CNG oct(int octaves)
{
oct = octaves;
return this;
}
public double getScale() {
public double getScale()
{
return scale;
}
}

View File

@ -26,7 +26,8 @@ import lombok.EqualsAndHashCode;
@Desc("Represents a biome in iris. Biomes are placed inside of regions and hold objects.")
@Data
@EqualsAndHashCode(callSuper = false)
public class IrisBiome extends IrisRegistrant implements IRare {
public class IrisBiome extends IrisRegistrant implements IRare
{
@MinNumber(2)
@Required
@DontObfuscate
@ -39,13 +40,13 @@ public class IrisBiome extends IrisRegistrant implements IRare {
private KList<IrisEffect> effects = new KList<>();
@DontObfuscate
@DependsOn({ "biomeStyle", "biomeZoom", "biomeScatter" })
@DependsOn({"biomeStyle", "biomeZoom", "biomeScatter"})
@Desc("This changes the dispersion of the biome colors if multiple derivatives are chosen.")
private IrisGeneratorStyle biomeStyle = NoiseStyle.SIMPLEX.style();
@MinNumber(0.0001)
@DontObfuscate
@DependsOn({ "biomeStyle", "biomeZoom", "biomeScatter" })
@DependsOn({"biomeStyle", "biomeZoom", "biomeScatter"})
@Desc("This zooms in the biome colors if multiple derivatives are chosen")
private double biomeZoom = 1;
@ -75,12 +76,12 @@ public class IrisBiome extends IrisRegistrant implements IRare {
private KList<Biome> biomeSkyScatter = new KList<>();
@DontObfuscate
@DependsOn({ "children" })
@DependsOn({"children"})
@Desc("If this biome has children biomes, and the gen layer chooses one of this biomes children, how much smaller will it be (inside of this biome). Higher values means a smaller biome relative to this biome's size. Set higher than 1.0 and below 3.0 for best results.")
private double childShrinkFactor = 1.5;
@DontObfuscate
@DependsOn({ "children" })
@DependsOn({"children"})
@Desc("If this biome has children biomes, and the gen layer chooses one of this biomes children, How will it be shaped?")
private IrisGeneratorStyle childStyle = NoiseStyle.CELLULAR_IRIS_DOUBLE.style();
@ -122,8 +123,7 @@ public class IrisBiome extends IrisRegistrant implements IRare {
@ArrayType(min = 1, type = IrisBiomeGeneratorLink.class)
@DontObfuscate
@Desc("Generators for this biome. Multiple generators with different interpolation sizes will mix with other biomes how you would expect. This defines your biome height relative to the fluid height. Use negative for oceans.")
private KList<IrisBiomeGeneratorLink> generators = new KList<IrisBiomeGeneratorLink>()
.qadd(new IrisBiomeGeneratorLink());
private KList<IrisBiomeGeneratorLink> generators = new KList<IrisBiomeGeneratorLink>().qadd(new IrisBiomeGeneratorLink());
@ArrayType(min = 1, type = IrisStructurePlacement.class)
@DontObfuscate
@ -143,67 +143,80 @@ public class IrisBiome extends IrisRegistrant implements IRare {
private transient AtomicCache<KList<CNG>> layerHeightGenerators = new AtomicCache<>();
private transient AtomicCache<KList<CNG>> layerSeaHeightGenerators = new AtomicCache<>();
public IrisBiome() {
public IrisBiome()
{
}
public double getHeight(ContextualChunkGenerator xg, double x, double z, long seed) {
public double getHeight(ContextualChunkGenerator xg, double x, double z, long seed)
{
double height = 0;
for (IrisBiomeGeneratorLink i : generators) {
for(IrisBiomeGeneratorLink i : generators)
{
height += i.getHeight(xg, x, z, seed);
}
return Math.max(0, Math.min(height, 255));
}
public CNG getBiomeGenerator(RNG random) {
return biomeGenerator.aquire(() -> {
public CNG getBiomeGenerator(RNG random)
{
return biomeGenerator.aquire(() ->
{
return biomeStyle.create(random.nextParallelRNG(213949 + 228888 + getRarity() + getName().length()));
});
}
public CNG getChildrenGenerator(RNG random, int sig, double scale) {
return childrenCell
.aquire(() -> getChildStyle().create(random.nextParallelRNG(sig * 2137)).bake().scale(scale).bake());
public CNG getChildrenGenerator(RNG random, int sig, double scale)
{
return childrenCell.aquire(() -> getChildStyle().create(random.nextParallelRNG(sig * 2137)).bake().scale(scale).bake());
}
public KList<BlockData> generateLayers(double wx, double wz, RNG random, int maxDepth, int height) {
if (isLockLayers()) {
public KList<BlockData> generateLayers(double wx, double wz, RNG random, int maxDepth, int height)
{
if(isLockLayers())
{
return generateLockedLayers(wx, wz, random, maxDepth, height);
}
KList<BlockData> data = new KList<>();
if (maxDepth <= 0) {
if(maxDepth <= 0)
{
return data;
}
for (int i = 0; i < layers.size(); i++) {
for(int i = 0; i < layers.size(); i++)
{
CNG hgen = getLayerHeightGenerators(random).get(i);
int d = hgen.fit(layers.get(i).getMinHeight(), layers.get(i).getMaxHeight(), wx / layers.get(i).getZoom(),
wz / layers.get(i).getZoom());
int d = hgen.fit(layers.get(i).getMinHeight(), layers.get(i).getMaxHeight(), wx / layers.get(i).getZoom(), wz / layers.get(i).getZoom());
if (d < 0) {
if(d < 0)
{
continue;
}
for (int j = 0; j < d; j++) {
if (data.size() >= maxDepth) {
for(int j = 0; j < d; j++)
{
if(data.size() >= maxDepth)
{
break;
}
try {
data.add(getLayers().get(i).get(random.nextParallelRNG(i + j), (wx + j) / layers.get(i).getZoom(),
j, (wz - j) / layers.get(i).getZoom()));
try
{
data.add(getLayers().get(i).get(random.nextParallelRNG(i + j), (wx + j) / layers.get(i).getZoom(), j, (wz - j) / layers.get(i).getZoom()));
}
catch (Throwable e) {
catch(Throwable e)
{
e.printStackTrace();
}
}
if (data.size() >= maxDepth) {
if(data.size() >= maxDepth)
{
break;
}
}
@ -211,40 +224,47 @@ public class IrisBiome extends IrisRegistrant implements IRare {
return data;
}
public KList<BlockData> generateLockedLayers(double wx, double wz, RNG random, int maxDepth, int height) {
public KList<BlockData> generateLockedLayers(double wx, double wz, RNG random, int maxDepth, int height)
{
KList<BlockData> data = new KList<>();
KList<BlockData> real = new KList<>();
if (maxDepth <= 0) {
if(maxDepth <= 0)
{
return data;
}
for (int i = 0; i < layers.size(); i++) {
for(int i = 0; i < layers.size(); i++)
{
CNG hgen = getLayerHeightGenerators(random).get(i);
int d = hgen.fit(layers.get(i).getMinHeight(), layers.get(i).getMaxHeight(), wx / layers.get(i).getZoom(),
wz / layers.get(i).getZoom());
int d = hgen.fit(layers.get(i).getMinHeight(), layers.get(i).getMaxHeight(), wx / layers.get(i).getZoom(), wz / layers.get(i).getZoom());
if (d < 0) {
if(d < 0)
{
continue;
}
for (int j = 0; j < d; j++) {
try {
data.add(getLayers().get(i).get(random.nextParallelRNG(i + j), (wx + j) / layers.get(i).getZoom(),
j, (wz - j) / layers.get(i).getZoom()));
for(int j = 0; j < d; j++)
{
try
{
data.add(getLayers().get(i).get(random.nextParallelRNG(i + j), (wx + j) / layers.get(i).getZoom(), j, (wz - j) / layers.get(i).getZoom()));
}
catch (Throwable e) {
catch(Throwable e)
{
e.printStackTrace();
}
}
}
if (data.isEmpty()) {
if(data.isEmpty())
{
return real;
}
for (int i = 0; i < maxDepth; i++) {
for(int i = 0; i < maxDepth; i++)
{
int offset = (getMaxHeight() - height) - i;
int index = offset % data.size();
real.add(data.get(index < 0 ? 0 : index));
@ -253,11 +273,14 @@ public class IrisBiome extends IrisRegistrant implements IRare {
return real;
}
private int getMaxHeight() {
return maxHeight.aquire(() -> {
private int getMaxHeight()
{
return maxHeight.aquire(() ->
{
int maxHeight = 0;
for (IrisBiomeGeneratorLink i : getGenerators()) {
for(IrisBiomeGeneratorLink i : getGenerators())
{
maxHeight += i.getMax();
}
@ -265,39 +288,46 @@ public class IrisBiome extends IrisRegistrant implements IRare {
});
}
public IrisBiome infer(InferredType t, InferredType type) {
public IrisBiome infer(InferredType t, InferredType type)
{
setInferredType(t.equals(InferredType.DEFER) ? type : t);
return this;
}
public KList<BlockData> generateSeaLayers(double wx, double wz, RNG random, int maxDepth) {
public KList<BlockData> generateSeaLayers(double wx, double wz, RNG random, int maxDepth)
{
KList<BlockData> data = new KList<>();
for (int i = 0; i < seaLayers.size(); i++) {
for(int i = 0; i < seaLayers.size(); i++)
{
CNG hgen = getLayerSeaHeightGenerators(random).get(i);
int d = hgen.fit(seaLayers.get(i).getMinHeight(), seaLayers.get(i).getMaxHeight(),
wx / seaLayers.get(i).getZoom(), wz / seaLayers.get(i).getZoom());
int d = hgen.fit(seaLayers.get(i).getMinHeight(), seaLayers.get(i).getMaxHeight(), wx / seaLayers.get(i).getZoom(), wz / seaLayers.get(i).getZoom());
if (d < 0) {
if(d < 0)
{
continue;
}
for (int j = 0; j < d; j++) {
if (data.size() >= maxDepth) {
for(int j = 0; j < d; j++)
{
if(data.size() >= maxDepth)
{
break;
}
try {
data.add(getSeaLayers().get(i).get(random.nextParallelRNG(i + j),
(wx + j) / seaLayers.get(i).getZoom(), j, (wz - j) / seaLayers.get(i).getZoom()));
try
{
data.add(getSeaLayers().get(i).get(random.nextParallelRNG(i + j), (wx + j) / seaLayers.get(i).getZoom(), j, (wz - j) / seaLayers.get(i).getZoom()));
}
catch (Throwable e) {
catch(Throwable e)
{
e.printStackTrace();
}
}
if (data.size() >= maxDepth) {
if(data.size() >= maxDepth)
{
break;
}
}
@ -305,13 +335,16 @@ public class IrisBiome extends IrisRegistrant implements IRare {
return data;
}
public KList<CNG> getLayerHeightGenerators(RNG rng) {
return layerHeightGenerators.aquire(() -> {
public KList<CNG> getLayerHeightGenerators(RNG rng)
{
return layerHeightGenerators.aquire(() ->
{
KList<CNG> layerHeightGenerators = new KList<>();
int m = 7235;
for (IrisBiomePaletteLayer i : getLayers()) {
for(IrisBiomePaletteLayer i : getLayers())
{
layerHeightGenerators.add(i.getHeightGenerator(rng.nextParallelRNG((m++) * m * m * m)));
}
@ -319,13 +352,16 @@ public class IrisBiome extends IrisRegistrant implements IRare {
});
}
public KList<CNG> getLayerSeaHeightGenerators(RNG rng) {
return layerSeaHeightGenerators.aquire(() -> {
public KList<CNG> getLayerSeaHeightGenerators(RNG rng)
{
return layerSeaHeightGenerators.aquire(() ->
{
KList<CNG> layerSeaHeightGenerators = new KList<>();
int m = 7735;
for (IrisBiomePaletteLayer i : getSeaLayers()) {
for(IrisBiomePaletteLayer i : getSeaLayers())
{
layerSeaHeightGenerators.add(i.getHeightGenerator(rng.nextParallelRNG((m++) * m * m * m)));
}
@ -333,45 +369,57 @@ public class IrisBiome extends IrisRegistrant implements IRare {
});
}
public boolean isLand() {
if (inferredType == null) {
public boolean isLand()
{
if(inferredType == null)
{
return true;
}
return inferredType.equals(InferredType.LAND);
}
public boolean isSea() {
if (inferredType == null) {
public boolean isSea()
{
if(inferredType == null)
{
return false;
}
return inferredType.equals(InferredType.SEA);
}
public boolean isShore() {
if (inferredType == null) {
public boolean isShore()
{
if(inferredType == null)
{
return false;
}
return inferredType.equals(InferredType.SHORE);
}
public Biome getSkyBiome(RNG rng, double x, double y, double z) {
if (biomeSkyScatter.size() == 1) {
public Biome getSkyBiome(RNG rng, double x, double y, double z)
{
if(biomeSkyScatter.size() == 1)
{
return biomeSkyScatter.get(0);
}
if (biomeSkyScatter.isEmpty()) {
if(biomeSkyScatter.isEmpty())
{
return getGroundBiome(rng, x, y, z);
}
return biomeSkyScatter.get(getBiomeGenerator(rng).fit(0, biomeSkyScatter.size() - 1, x, y, z));
}
public KList<IrisBiome> getRealChildren(ContextualChunkGenerator g) {
return realChildren.aquire(() -> {
public KList<IrisBiome> getRealChildren(ContextualChunkGenerator g)
{
return realChildren.aquire(() ->
{
KList<IrisBiome> realChildren = new KList<>();
for (String i : getChildren()) {
for(String i : getChildren())
{
realChildren.add(g != null ? g.loadBiome(i) : Iris.globaldata.getBiomeLoader().load(i));
}
@ -379,13 +427,16 @@ public class IrisBiome extends IrisRegistrant implements IRare {
});
}
public KList<String> getAllChildren(ContextualChunkGenerator g, int limit) {
public KList<String> getAllChildren(ContextualChunkGenerator g, int limit)
{
KSet<String> m = new KSet<>();
m.addAll(getChildren());
limit--;
if (limit > 0) {
for (String i : getChildren()) {
if(limit > 0)
{
for(String i : getChildren())
{
IrisBiome b = g != null ? g.loadBiome(i) : Iris.globaldata.getBiomeLoader().load(i);
int l = limit;
m.addAll(b.getAllChildren(g, l));
@ -395,12 +446,15 @@ public class IrisBiome extends IrisRegistrant implements IRare {
return new KList<String>(m);
}
public Biome getGroundBiome(RNG rng, double x, double y, double z) {
if (biomeSkyScatter.isEmpty()) {
public Biome getGroundBiome(RNG rng, double x, double y, double z)
{
if(biomeSkyScatter.isEmpty())
{
return getDerivative();
}
if (biomeScatter.size() == 1) {
if(biomeScatter.size() == 1)
{
return biomeScatter.get(0);
}

View File

@ -20,14 +20,15 @@ import lombok.Data;
@Desc("A biome decorator is used for placing flowers, grass, cacti and so on")
@Data
public class IrisBiomeDecorator {
public class IrisBiomeDecorator
{
@DontObfuscate
@Desc("The varience dispersion is used when multiple blocks are put in the palette. Scatter scrambles them, Wispy shows streak-looking varience")
private IrisGeneratorStyle variance = NoiseStyle.STATIC.style();
@DontObfuscate
@Desc("Dispersion is used to pick places to spawn. Scatter randomly places them (vanilla) or Wispy for a streak like patch system.")
private IrisGeneratorStyle dispersion = NoiseStyle.STATIC.style();
private IrisGeneratorStyle style = NoiseStyle.STATIC.style();
@DependsOn({"stackMin", "stackMax"})
@DontObfuscate
@ -86,64 +87,78 @@ public class IrisBiomeDecorator {
private transient AtomicCache<CNG> heightGenerator = new AtomicCache<>();
private transient AtomicCache<KList<BlockData>> blockData = new AtomicCache<>();
public int getHeight(RNG rng, double x, double z) {
if (stackMin == stackMax) {
public int getHeight(RNG rng, double x, double z)
{
if(stackMin == stackMax)
{
return stackMin;
}
return getHeightGenerator(rng).fit(stackMin, stackMax, x / verticalZoom, z / verticalZoom);
}
public CNG getHeightGenerator(RNG rng) {
return heightGenerator.aquire(() -> {
public CNG getHeightGenerator(RNG rng)
{
return heightGenerator.aquire(() ->
{
return heightVariance.create(rng.nextParallelRNG(getBlockData().size() + stackMax + stackMin));
});
}
public CNG getGenerator(RNG rng) {
public CNG getGenerator(RNG rng)
{
long key = rng.nextParallelRNG(1).nextLong();
if (layerGenerators == null) {
if(layerGenerators == null)
{
layerGenerators = new KMap<>();
}
if (!layerGenerators.containsKey(key)) {
layerGenerators.put(key, dispersion.create(rng.nextParallelRNG((int) (getBlockData().size() + key))));
if(!layerGenerators.containsKey(key))
{
layerGenerators.put(key, style.create(rng.nextParallelRNG((int) (getBlockData().size() + key))));
}
return layerGenerators.get(key);
}
public CNG getVarianceGenerator(RNG rng) {
public CNG getVarianceGenerator(RNG rng)
{
long key = rng.nextParallelRNG(4).nextLong();
if (layerVarianceGenerators == null) {
if(layerVarianceGenerators == null)
{
layerVarianceGenerators = new KMap<>();
}
if (!layerVarianceGenerators.containsKey(key)) {
layerVarianceGenerators.put(key,
variance.create(rng.nextParallelRNG((int) (getBlockData().size() + key))).scale(1D / varianceZoom));
if(!layerVarianceGenerators.containsKey(key))
{
layerVarianceGenerators.put(key, variance.create(rng.nextParallelRNG((int) (getBlockData().size() + key))).scale(1D / varianceZoom));
}
return layerVarianceGenerators.get(key);
}
public KList<String> add(String b) {
public KList<String> add(String b)
{
palette.add(b);
return palette;
}
public BlockData getBlockData(RNG rng, double x, double z) {
if (getGenerator(rng) == null) {
public BlockData getBlockData(RNG rng, double x, double z)
{
if(getGenerator(rng) == null)
{
return null;
}
if (getBlockData() == null) {
if(getBlockData() == null)
{
return null;
}
if (getBlockData().isEmpty()) {
if(getBlockData().isEmpty())
{
return null;
}
@ -152,8 +167,10 @@ public class IrisBiomeDecorator {
xx /= getZoom();
zz /= getZoom();
if (getGenerator(rng).fitDouble(0D, 1D, xx, zz) <= chance) {
if (getBlockData().size() == 1) {
if(getGenerator(rng).fitDouble(0D, 1D, xx, zz) <= chance)
{
if(getBlockData().size() == 1)
{
return getBlockData().get(0);
}
@ -163,12 +180,16 @@ public class IrisBiomeDecorator {
return null;
}
public KList<BlockData> getBlockData() {
return blockData.aquire(() -> {
public KList<BlockData> getBlockData()
{
return blockData.aquire(() ->
{
KList<BlockData> blockData = new KList<>();
for (String i : palette) {
for(String i : palette)
{
BlockData bx = B.getBlockData(i);
if (bx != null) {
if(bx != null)
{
blockData.add(bx);
}
}

View File

@ -29,7 +29,8 @@ import lombok.EqualsAndHashCode;
@Desc("Represents a dimension")
@Data
@EqualsAndHashCode(callSuper = false)
public class IrisDimension extends IrisRegistrant {
public class IrisDimension extends IrisRegistrant
{
public static final BlockData STONE = Material.STONE.createBlockData();
public static final BlockData WATER = Material.WATER.createBlockData();
@ -66,8 +67,28 @@ public class IrisDimension extends IrisRegistrant {
private IrisGeneratorStyle continentalStyle = NoiseStyle.CELLULAR_IRIS_DOUBLE.style();
@DontObfuscate
@Desc("The placement style of land/sea")
private IrisGeneratorStyle coordinateFracture = NoiseStyle.FLAT.style();
@Desc("The placement style of biomes")
private IrisGeneratorStyle landBiomeStyle = NoiseStyle.CELLULAR_IRIS_DOUBLE.style();
@DontObfuscate
@Desc("The placement style of biomes")
private IrisGeneratorStyle shoreBiomeStyle = NoiseStyle.CELLULAR_IRIS_DOUBLE.style();
@DontObfuscate
@Desc("The placement style of biomes")
private IrisGeneratorStyle seaBiomeStyle = NoiseStyle.CELLULAR_IRIS_DOUBLE.style();
@DontObfuscate
@Desc("The placement style of biomes")
private IrisGeneratorStyle caveBiomeStyle = NoiseStyle.CELLULAR_IRIS_DOUBLE.style();
@DontObfuscate
@Desc("The placement style of biomes")
private IrisGeneratorStyle islandBiomeStyle = NoiseStyle.CELLULAR_IRIS_DOUBLE.style();
@DontObfuscate
@Desc("The placement style of biomes")
private IrisGeneratorStyle skylandBiomeStyle = NoiseStyle.CELLULAR_IRIS_DOUBLE.style();
@MinNumber(-256)
@MaxNumber(256)
@ -277,29 +298,33 @@ public class IrisDimension extends IrisRegistrant {
private transient AtomicCache<Double> rad = new AtomicCache<>();
private transient boolean inverted = false;
public KList<IrisPostBlockFilter> getPostBlockProcessors(PostBlockChunkGenerator g) {
return cacheFilters.aquire(() -> {
public KList<IrisPostBlockFilter> getPostBlockProcessors(PostBlockChunkGenerator g)
{
return cacheFilters.aquire(() ->
{
KList<IrisPostBlockFilter> cacheFilters = new KList<>();
for (IrisPostProcessor i : getPostProcessors()) {
for(IrisPostProcessor i : getPostProcessors())
{
cacheFilters.add(g.createProcessor(i.getProcessor(), i.getPhase()));
}
g.setMinPhase(0);
g.setMaxPhase(0);
for (IrisPostBlockFilter i : cacheFilters) {
for(IrisPostBlockFilter i : cacheFilters)
{
g.setMinPhase(Math.min(g.getMinPhase(), i.getPhase()));
g.setMaxPhase(Math.max(g.getMaxPhase(), i.getPhase()));
}
Iris.info("Post Processing: " + cacheFilters.size() + " filters. Phases: " + g.getMinPhase() + " - "
+ g.getMaxPhase());
Iris.info("Post Processing: " + cacheFilters.size() + " filters. Phases: " + g.getMinPhase() + " - " + g.getMaxPhase());
return cacheFilters;
});
}
public static KList<IrisCompatabilityFilter> getDefaultCompatability() {
public static KList<IrisCompatabilityFilter> getDefaultCompatability()
{
KList<IrisCompatabilityFilter> filters = new KList<>();
// Below 1.16
@ -438,15 +463,18 @@ public class IrisDimension extends IrisRegistrant {
return filters;
}
public CNG getCoordFracture(RNG rng, int signature) {
return coordFracture.aquire(() -> {
public CNG getCoordFracture(RNG rng, int signature)
{
return coordFracture.aquire(() ->
{
CNG coordFracture = CNG.signature(rng.nextParallelRNG(signature));
coordFracture.scale(0.012 / coordFractureZoom);
return coordFracture;
});
}
private KList<IrisPostProcessor> getDefaultPostProcessors() {
private KList<IrisPostProcessor> getDefaultPostProcessors()
{
KList<IrisPostProcessor> p = new KList<IrisPostProcessor>();
p.add(new IrisPostProcessor("wall-painter"));
@ -456,32 +484,40 @@ public class IrisDimension extends IrisRegistrant {
return p;
}
public BlockData getRock(RNG rng, double x, double y, double z) {
if (getRockData().isEmpty()) {
public BlockData getRock(RNG rng, double x, double y, double z)
{
if(getRockData().isEmpty())
{
return STONE;
}
if (getRockData().size() == 1) {
if(getRockData().size() == 1)
{
return getRockData().get(0);
}
return getRockGenerator(rng).fit(getRockData(), x, y, z);
}
public CNG getRockGenerator(RNG rng) {
return rockLayerGenerator.aquire(() -> {
RNG rngx = rng.nextParallelRNG(
(int) (getRockData().size() * getRegions().size() * getCaveScale() * getLandZoom() * 10357));
public CNG getRockGenerator(RNG rng)
{
return rockLayerGenerator.aquire(() ->
{
RNG rngx = rng.nextParallelRNG((int) (getRockData().size() * getRegions().size() * getCaveScale() * getLandZoom() * 10357));
return rockStyle.create(rngx);
});
}
public KList<BlockData> getRockData() {
return rockData.aquire(() -> {
public KList<BlockData> getRockData()
{
return rockData.aquire(() ->
{
KList<BlockData> rockData = new KList<>();
for (String ix : rockPalette) {
for(String ix : rockPalette)
{
BlockData bx = B.getBlockData(ix);
if (bx != null) {
if(bx != null)
{
rockData.add(bx);
}
}
@ -490,32 +526,40 @@ public class IrisDimension extends IrisRegistrant {
});
}
public BlockData getFluid(RNG rng, double x, double y, double z) {
if (getFluidData().isEmpty()) {
public BlockData getFluid(RNG rng, double x, double y, double z)
{
if(getFluidData().isEmpty())
{
return WATER;
}
if (getFluidData().size() == 1) {
if(getFluidData().size() == 1)
{
return getFluidData().get(0);
}
return getFluidGenerator(rng).fit(getFluidData(), x, y, z);
}
public CNG getFluidGenerator(RNG rng) {
return fluidLayerGenerator.aquire(() -> {
RNG rngx = rng.nextParallelRNG(getFluidData().size()
* (int) (getRockData().size() * getRegions().size() * getCaveScale() * getLandZoom() * 10357));
public CNG getFluidGenerator(RNG rng)
{
return fluidLayerGenerator.aquire(() ->
{
RNG rngx = rng.nextParallelRNG(getFluidData().size() * (int) (getRockData().size() * getRegions().size() * getCaveScale() * getLandZoom() * 10357));
return fluidStyle.create(rngx);
});
}
public KList<BlockData> getFluidData() {
return fluidData.aquire(() -> {
public KList<BlockData> getFluidData()
{
return fluidData.aquire(() ->
{
KList<BlockData> fluidData = new KList<>();
for (String ix : fluidPalette) {
for(String ix : fluidPalette)
{
BlockData bx = B.getBlockData(ix);
if (bx != null) {
if(bx != null)
{
fluidData.add(bx);
}
}
@ -524,40 +568,49 @@ public class IrisDimension extends IrisRegistrant {
});
}
public double getDimensionAngle() {
public double getDimensionAngle()
{
return rad.aquire(() -> Math.toRadians(dimensionAngleDeg));
}
public double sinRotate() {
public double sinRotate()
{
return sinr.aquire(() -> Math.sin(getDimensionAngle()));
}
public double cosRotate() {
public double cosRotate()
{
return cosr.aquire(() -> Math.cos(getDimensionAngle()));
}
public KList<IrisRegion> getAllRegions(ContextualChunkGenerator g) {
public KList<IrisRegion> getAllRegions(ContextualChunkGenerator g)
{
KList<IrisRegion> r = new KList<>();
for (String i : getRegions()) {
for(String i : getRegions())
{
r.add(g != null ? g.loadRegion(i) : Iris.globaldata.getRegionLoader().load(i));
}
return r;
}
public KList<IrisBiome> getAllBiomes(ContextualChunkGenerator g) {
public KList<IrisBiome> getAllBiomes(ContextualChunkGenerator g)
{
KList<IrisBiome> r = new KList<>();
for (IrisRegion i : getAllRegions(g)) {
for(IrisRegion i : getAllRegions(g))
{
r.addAll(i.getAllBiomes(g));
}
return r;
}
public ChunkPosition getParallaxSize(ContextualChunkGenerator g) {
return parallaxSize.aquire(() -> {
public ChunkPosition getParallaxSize(ContextualChunkGenerator g)
{
return parallaxSize.aquire(() ->
{
int x = 0;
int z = 0;
@ -565,40 +618,50 @@ public class IrisDimension extends IrisRegistrant {
KList<IrisRegion> r = getAllRegions(g);
KList<IrisBiome> b = getAllBiomes(g);
for (IrisBiome i : b) {
for (IrisObjectPlacement j : i.getObjects()) {
for(IrisBiome i : b)
{
for(IrisObjectPlacement j : i.getObjects())
{
objects.addAll(j.getPlace());
}
}
for (String i : objects) {
try {
for(String i : objects)
{
try
{
BlockVector bv = IrisObject.sampleSize(g.getData().getObjectLoader().findFile(i));
x = bv.getBlockX() > x ? bv.getBlockX() : x;
z = bv.getBlockZ() > z ? bv.getBlockZ() : z;
}
catch (Throwable e) {
catch(Throwable e)
{
}
}
for (IrisDepositGenerator i : getDeposits()) {
for(IrisDepositGenerator i : getDeposits())
{
int max = i.getMaxDimension();
x = max > x ? max : x;
z = max > z ? max : z;
}
for (IrisRegion v : r) {
for (IrisDepositGenerator i : v.getDeposits()) {
for(IrisRegion v : r)
{
for(IrisDepositGenerator i : v.getDeposits())
{
int max = i.getMaxDimension();
x = max > x ? max : x;
z = max > z ? max : z;
}
}
for (IrisBiome v : b) {
for (IrisDepositGenerator i : v.getDeposits()) {
for(IrisBiome v : b)
{
for(IrisDepositGenerator i : v.getDeposits())
{
int max = i.getMaxDimension();
x = max > x ? max : x;
z = max > z ? max : z;
@ -614,13 +677,39 @@ public class IrisDimension extends IrisRegistrant {
});
}
public BlockData resolve(String bd) {
for (IrisCompatabilityFilter i : getCompatability()) {
if (i.getWhen().equalsIgnoreCase(bd)) {
public BlockData resolve(String bd)
{
for(IrisCompatabilityFilter i : getCompatability())
{
if(i.getWhen().equalsIgnoreCase(bd))
{
return i.getReplace();
}
}
return null;
}
public IrisGeneratorStyle getBiomeStyle(InferredType type)
{
switch(type)
{
case CAVE:
return caveBiomeStyle;
case ISLAND:
return islandBiomeStyle;
case LAND:
return landBiomeStyle;
case SEA:
return seaBiomeStyle;
case SHORE:
return shoreBiomeStyle;
case SKYLAND:
return skylandBiomeStyle;
default:
break;
}
return landBiomeStyle;
}
}

View File

@ -9,7 +9,8 @@ import com.volmit.iris.object.IrisRegistrant;
import lombok.Data;
@Data
public class ResourceLoader<T extends IrisRegistrant> {
public class ResourceLoader<T extends IrisRegistrant>
{
protected File root;
protected String folderName;
protected String resourceTypeName;
@ -21,7 +22,8 @@ public class ResourceLoader<T extends IrisRegistrant> {
protected IrisLock lock;
protected String preferredFolder = null;
public ResourceLoader(File root, String folderName, String resourceTypeName, Class<? extends T> objectClass) {
public ResourceLoader(File root, String folderName, String resourceTypeName, Class<? extends T> objectClass)
{
lock = new IrisLock("Res");
folderMapCache = new KMap<>();
this.objectClass = objectClass;
@ -32,12 +34,15 @@ public class ResourceLoader<T extends IrisRegistrant> {
loadCache = new KMap<>();
}
public long count() {
public long count()
{
return loadCache.size();
}
protected T loadFile(File j, String key, String name) {
try {
protected T loadFile(File j, String key, String name)
{
try
{
T t = new Gson().fromJson(IO.readAll(j), objectClass);
loadCache.put(key, t);
Iris.hotloader.track(j);
@ -48,32 +53,39 @@ public class ResourceLoader<T extends IrisRegistrant> {
return t;
}
catch (Throwable e) {
catch(Throwable e)
{
lock.unlock();
Iris.warn("Couldn't read " + resourceTypeName + " file: " + j.getPath() + ": " + e.getMessage());
return null;
}
}
public T load(String name) {
public T load(String name)
{
String key = name + "-" + cname;
if (loadCache.containsKey(key)) {
if(loadCache.containsKey(key))
{
T t = loadCache.get(key);
return t;
}
lock.lock();
for (File i : getFolders(name)) {
for (File j : i.listFiles()) {
if (j.isFile() && j.getName().endsWith(".json") && j.getName().split("\\Q.\\E")[0].equals(name)) {
for(File i : getFolders(name))
{
for(File j : i.listFiles())
{
if(j.isFile() && j.getName().endsWith(".json") && j.getName().split("\\Q.\\E")[0].equals(name))
{
return loadFile(j, key, name);
}
}
File file = new File(i, name + ".json");
if (file.exists()) {
if(file.exists())
{
return loadFile(file, key, name);
}
}
@ -84,15 +96,21 @@ public class ResourceLoader<T extends IrisRegistrant> {
return null;
}
public KList<File> getFolders() {
public KList<File> getFolders()
{
lock.lock();
if (folderCache == null) {
if(folderCache == null)
{
folderCache = new KList<>();
for (File i : root.listFiles()) {
if (i.isDirectory()) {
for (File j : i.listFiles()) {
if (j.isDirectory() && j.getName().equals(folderName)) {
for(File i : root.listFiles())
{
if(i.isDirectory())
{
for(File j : i.listFiles())
{
if(j.isDirectory() && j.getName().equals(folderName))
{
folderCache.add(j);
break;
}
@ -100,9 +118,12 @@ public class ResourceLoader<T extends IrisRegistrant> {
}
}
if (preferredFolder != null) {
for (File i : folderCache.copy()) {
if (i.getParentFile().getName().equals(preferredFolder)) {
if(preferredFolder != null)
{
for(File i : folderCache.copy())
{
if(i.getParentFile().getName().equals(preferredFolder))
{
folderCache.remove(i);
folderCache.add(0, i);
}
@ -114,12 +135,16 @@ public class ResourceLoader<T extends IrisRegistrant> {
return folderCache;
}
public KList<File> getFolders(String rc) {
public KList<File> getFolders(String rc)
{
KList<File> folders = getFolders().copy();
if (rc.contains(":")) {
for (File i : folders.copy()) {
if (!rc.startsWith(i.getName() + ":")) {
if(rc.contains(":"))
{
for(File i : folders.copy())
{
if(!rc.startsWith(i.getName() + ":"))
{
folders.remove(i);
}
}
@ -128,23 +153,28 @@ public class ResourceLoader<T extends IrisRegistrant> {
return folders;
}
public void clearCache() {
public void clearCache()
{
loadCache.clear();
folderCache = null;
}
public File fileFor(T b) {
for (File i : getFolders()) {
for (File j : i.listFiles()) {
if (j.isFile() && j.getName().endsWith(".json")
&& j.getName().split("\\Q.\\E")[0].equals(b.getLoadKey())) {
public File fileFor(T b)
{
for(File i : getFolders())
{
for(File j : i.listFiles())
{
if(j.isFile() && j.getName().endsWith(".json") && j.getName().split("\\Q.\\E")[0].equals(b.getLoadKey()))
{
return j;
}
}
File file = new File(i, b.getLoadKey() + ".json");
if (file.exists()) {
if(file.exists())
{
return file;
}
}
@ -152,11 +182,13 @@ public class ResourceLoader<T extends IrisRegistrant> {
return null;
}
public boolean isLoaded(String next) {
public boolean isLoaded(String next)
{
return loadCache.containsKey(next);
}
public void preferFolder(String name) {
public void preferFolder(String name)
{
preferredFolder = name;
}
}