diff --git a/build.gradle b/build.gradle index 087324e56..90fe9be65 100644 --- a/build.gradle +++ b/build.gradle @@ -37,7 +37,7 @@ registerCustomOutputTask('Coco', 'D://mcsm/plugins') registerCustomOutputTask('Strange', 'D://Servers/1.17 Test Server/plugins') registerCustomOutputTask('Vatuu', 'D://Minecraft/Servers/1.19.4/plugins') registerCustomOutputTask('CrazyDev22', 'C://Users/Julian/Desktop/server/plugins') -registerCustomOutputTask('Pixel', 'C://Users/repix/Iris Dimension Engine/1.20.4 - Iris Development/plugins') +registerCustomOutputTask('Pixel', 'C://Users/repix/Iris Dimension Engine/1.20.4 - Development/plugins') // ========================== UNIX ============================== registerCustomOutputTaskUnix('CyberpwnLT', '/Users/danielmills/development/server/plugins') registerCustomOutputTaskUnix('PsychoLT', '/Volumes/PRO-G40/Minecraft/MinecraftDevelopment/Server/plugins') diff --git a/core/src/main/java/com/volmit/iris/Iris.java b/core/src/main/java/com/volmit/iris/Iris.java index e32c8239d..9fec3b7e8 100644 --- a/core/src/main/java/com/volmit/iris/Iris.java +++ b/core/src/main/java/com/volmit/iris/Iris.java @@ -739,7 +739,7 @@ public class Iris extends VolmitPlugin implements Listener { service(StudioSVC.class).installIntoWorld(getSender(), dim.getLoadKey(), w.worldFolder()); } - return new BukkitChunkGenerator(w, false, ff, dim.getLoadKey()); + return new BukkitChunkGenerator(w, false, ff, dim.getLoadKey(), false); } public void splash() { diff --git a/core/src/main/java/com/volmit/iris/core/IrisSettings.java b/core/src/main/java/com/volmit/iris/core/IrisSettings.java index 4abe1ba79..335207de5 100644 --- a/core/src/main/java/com/volmit/iris/core/IrisSettings.java +++ b/core/src/main/java/com/volmit/iris/core/IrisSettings.java @@ -177,7 +177,6 @@ public class IrisSettings { public static class IrisSettingsGenerator { public String defaultWorldType = "overworld"; public int maxBiomeChildDepth = 4; - // public boolean forceConvertTo320Height = false; public boolean preventLeafDecay = true; } diff --git a/core/src/main/java/com/volmit/iris/core/commands/CommandIris.java b/core/src/main/java/com/volmit/iris/core/commands/CommandIris.java index bf7b05b48..d07c0ef42 100644 --- a/core/src/main/java/com/volmit/iris/core/commands/CommandIris.java +++ b/core/src/main/java/com/volmit/iris/core/commands/CommandIris.java @@ -30,6 +30,7 @@ import com.volmit.iris.core.safeguard.UtilsSFG; import com.volmit.iris.engine.object.IrisWorld; import com.volmit.iris.engine.platform.BukkitChunkGenerator; import com.volmit.iris.engine.platform.DummyChunkGenerator; +import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.decree.DecreeExecutor; import com.volmit.iris.util.decree.DecreeOrigin; import com.volmit.iris.util.decree.annotations.Decree; @@ -89,7 +90,9 @@ public class CommandIris implements DecreeExecutor { @Param(aliases = "dimension", description = "The dimension type to create the world with", defaultValue = "default") IrisDimension type, @Param(description = "The seed to generate the world with", defaultValue = "1337") - long seed + long seed, + @Param(description = "If it should convert the dimension to match the vanilla height system.", defaultValue = "false") + boolean vanillaheight ) { if(sender() instanceof Player) { if (incompatibilities.get("Multiverse-Core")) { @@ -133,6 +136,7 @@ public class CommandIris implements DecreeExecutor { .seed(seed) .sender(sender()) .studio(false) + .smartVanillaHeight(vanillaheight) .create(); } catch (Throwable e) { sender().sendMessage(C.RED + "Exception raised during creation. See the console for more details."); @@ -216,41 +220,41 @@ public class CommandIris implements DecreeExecutor { Iris.service(StudioSVC.class).open(sender(), 1337, "overworld"); } - @Decree(description = "Check if iris has access to that specific world") - public void hasAccess( - @Param(description = "The world to access", aliases = {"world"}) - World world - ) { - Engine engine = IrisToolbelt.access(world).getEngine(); - if (engine != null) { - sender().sendMessage("Access granted successfully."); - } else { - sender().sendMessage(C.RED + "Failed to grant access."); - } - } + @Decree(description = "Check access of all worlds.", aliases = {"accesslist"}) + public void worlds() { + KList IrisWorlds = new KList<>(); + KList BukkitWorlds = new KList<>(); - @Decree(description = "All Iris Worlds on the server.", aliases = {"worlds"}) - public void irisworlds() { - List IrisWorlds = new ArrayList<>(); - for (World world : Bukkit.getWorlds()) { + for (World w : Bukkit.getServer().getWorlds()) { try { - if (IrisToolbelt.access(world).getEngine() != null) { - IrisWorlds.add(world); + Engine engine = IrisToolbelt.access(w).getEngine(); + if (engine != null) { + IrisWorlds.add(w); } } catch (Exception e) { - // no + BukkitWorlds.add(w); } } + if (sender().isPlayer()) { - sender.sendMessage(C.IRIS + "Iris Worlds:"); - for (World world : IrisWorlds) { - sender.sendMessage(C.GREEN + "- " + world.getName()); + sender().sendMessage(C.BLUE + "Iris Worlds: "); + for (World IrisWorld : IrisWorlds.copy()) { + sender().sendMessage(C.IRIS + "- " +IrisWorld.getName()); + } + sender().sendMessage(C.GOLD + "Bukkit Worlds: "); + for (World BukkitWorld : BukkitWorlds.copy()) { + sender().sendMessage(C.GRAY + "- " +BukkitWorld.getName()); } } else { - Iris.info(C.IRIS + "Iris Worlds:"); - for (World world : IrisWorlds) { - sender.sendMessage(C.GREEN + "- " + world.getName()); + Iris.info(C.BLUE + "Iris Worlds: "); + for (World IrisWorld : IrisWorlds.copy()) { + Iris.info(C.IRIS + "- " +IrisWorld.getName()); } + Iris.info(C.GOLD + "Bukkit Worlds: "); + for (World BukkitWorld : BukkitWorlds.copy()) { + Iris.info(C.GRAY + "- " +BukkitWorld.getName()); + } + } } @@ -622,6 +626,6 @@ public class CommandIris implements DecreeExecutor { ff.mkdirs(); service(StudioSVC.class).installIntoWorld(sender, dim.getLoadKey(), ff.getParentFile()); } - return new BukkitChunkGenerator(w, false, ff, dim.getLoadKey()); + return new BukkitChunkGenerator(w, false, ff, dim.getLoadKey(), false); } } diff --git a/core/src/main/java/com/volmit/iris/core/commands/CommandStudio.java b/core/src/main/java/com/volmit/iris/core/commands/CommandStudio.java index 7e3f7e5a6..bea1dcd2b 100644 --- a/core/src/main/java/com/volmit/iris/core/commands/CommandStudio.java +++ b/core/src/main/java/com/volmit/iris/core/commands/CommandStudio.java @@ -85,7 +85,7 @@ import java.util.function.Supplier; public class CommandStudio implements DecreeExecutor { private CommandFind find; private CommandEdit edit; - private CommandDeepSearch deepSearch; + //private CommandDeepSearch deepSearch; public static String hrf(Duration duration) { return duration.toString().substring(2).replaceAll("(\\d[HMS])(?!$)", "$1 ").toLowerCase(); diff --git a/core/src/main/java/com/volmit/iris/core/gui/components/IrisRenderer.java b/core/src/main/java/com/volmit/iris/core/gui/components/IrisRenderer.java index 2820b8999..a96432427 100644 --- a/core/src/main/java/com/volmit/iris/core/gui/components/IrisRenderer.java +++ b/core/src/main/java/com/volmit/iris/core/gui/components/IrisRenderer.java @@ -55,10 +55,10 @@ public class IrisRenderer { IrisBiome b = renderer.getBiome((int) Math.round(x), renderer.getMaxHeight() - 1, (int) Math.round(z)); IrisBiomeGeneratorLink g = b.getGenerators().get(0); Color c; - if (g.getMax() <= 0) { + if (g.getMax(renderer) <= 0) { // Max is below water level, so it is most likely an ocean biome c = Color.BLUE; - } else if (g.getMin() < 0) { + } else if (g.getMin(renderer) < 0) { // Min is below water level, but max is not, so it is most likely a shore biome c = Color.YELLOW; } else { diff --git a/core/src/main/java/com/volmit/iris/core/pregenerator/ChunkUpdater.java b/core/src/main/java/com/volmit/iris/core/pregenerator/ChunkUpdater.java new file mode 100644 index 000000000..ec191cbb9 --- /dev/null +++ b/core/src/main/java/com/volmit/iris/core/pregenerator/ChunkUpdater.java @@ -0,0 +1,119 @@ +package com.volmit.iris.core.pregenerator; + +import com.volmit.iris.Iris; +import com.volmit.iris.util.collection.KList; +import com.volmit.iris.util.collection.KMap; +import com.volmit.iris.util.math.Position2; +import com.volmit.iris.util.math.RollingSequence; +import com.volmit.iris.util.math.Spiraler; +import com.volmit.iris.util.nbt.mca.Chunk; +import com.volmit.iris.util.nbt.mca.MCAFile; +import com.volmit.iris.util.nbt.mca.MCAUtil; +import org.bukkit.World; + +import java.io.File; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; + +public class ChunkUpdater { + private AtomicBoolean cancelled = new AtomicBoolean(false); + private KList cache; + private final RollingSequence chunksPerSecond; + private final RollingSequence mcaregionsPerSecond; + private final AtomicInteger worldheightsize; + private final AtomicInteger worldwidthsize; + private final AtomicInteger totalChunks; + private final AtomicInteger totalMaxChunks; + private final AtomicInteger totalMcaregions; + private final AtomicInteger position; + private final KMap chunk; + private final File[] McaFiles; + private final World world; + + public ChunkUpdater(World world) { + this.chunksPerSecond = new RollingSequence(10); + this.mcaregionsPerSecond = new RollingSequence(10); + this.world = world; + this.chunk = new KMap<>(); + this.McaFiles = new File(world.getWorldFolder(), "region").listFiles((dir, name) -> name.endsWith(".mca")); + this.worldheightsize = new AtomicInteger(calculateWorldDimensions(new File(world.getWorldFolder(), "region"), 1)); + this.worldwidthsize = new AtomicInteger(calculateWorldDimensions(new File(world.getWorldFolder(), "region"), 0)); + this.totalMaxChunks = new AtomicInteger((worldheightsize.get() / 16 ) * (worldwidthsize.get() / 16)); + this.position = new AtomicInteger(0); + this.cancelled = new AtomicBoolean(false); + this.cache = new KList<>(); + this.totalChunks = new AtomicInteger(0); + this.totalMcaregions = new AtomicInteger(0); + Initialize(); + + } + + public void Initialize() { + Iris.info("Initializing.."); + try { + for (File file : McaFiles) { + MCAFile MCARegion = MCAUtil.read(file); + //MCARegion.hasChunk(x,z); + + + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + public void cache() { + int position = this.position.get(); + for(; position < this.totalMaxChunks.get(); position++) { + cache.add(getChunk(position)); + } + } + + public int calculateWorldDimensions(File regionDir, Integer o) { + File[] files = regionDir.listFiles((dir, name) -> name.endsWith(".mca")); + + int minX = Integer.MAX_VALUE; + int maxX = Integer.MIN_VALUE; + int minZ = Integer.MAX_VALUE; + int maxZ = Integer.MIN_VALUE; + + for (File file : files) { + String[] parts = file.getName().split("\\."); + int x = Integer.parseInt(parts[1]); + int z = Integer.parseInt(parts[2]); + + if (x < minX) minX = x; + if (x > maxX) maxX = x; + if (z < minZ) minZ = z; + if (z > maxZ) maxZ = z; + } + + int height = (maxX - minX + 1) * 32 * 16; + int width = (maxZ - minZ + 1) * 32 * 16; + + if (o == 1) { + return height; + } + if (o == 0) { + return width; + } + return 0; + } + + public Position2 getChunk(int position) { + int p = -1; + AtomicInteger xx = new AtomicInteger(); + AtomicInteger zz = new AtomicInteger(); + Spiraler s = new Spiraler(worldheightsize.get() * 2, worldwidthsize.get() * 2, (x, z) -> { + xx.set(x); + zz.set(z); + }); + + while (s.hasNext() && p++ < position) { + s.next(); + } + + return new Position2(xx.get(), zz.get()); + } +} diff --git a/core/src/main/java/com/volmit/iris/core/service/IrisEngineSVC.java b/core/src/main/java/com/volmit/iris/core/service/IrisEngineSVC.java index b2595e3ad..2220ccc26 100644 --- a/core/src/main/java/com/volmit/iris/core/service/IrisEngineSVC.java +++ b/core/src/main/java/com/volmit/iris/core/service/IrisEngineSVC.java @@ -78,6 +78,9 @@ public class IrisEngineSVC implements IrisService { t = t - 200; } this.setup(); + this.TrimLogic(); + this.UnloadLogic(); + trimAlive.begin(); unloadAlive.begin(); trimActiveAlive.begin(); @@ -85,8 +88,8 @@ public class IrisEngineSVC implements IrisService { updateTicker.start(); cacheTicker.start(); - trimTicker.start(); - unloadTicker.start(); + //trimTicker.start(); + //unloadTicker.start(); instance = this; } @@ -104,10 +107,6 @@ public class IrisEngineSVC implements IrisService { return tectonicLimit.get(); } - public void EngineReport() { - Iris.info(C.RED + "CRITICAL ENGINE FAILURE! The Tectonic Trim subsystem has not responded for: " + Form.duration(trimAlive.getMillis()) + "."); - } - @EventHandler public void onWorldUnload(WorldUnloadEvent event) { updateWorlds(); @@ -179,9 +178,9 @@ public class IrisEngineSVC implements IrisService { } if (!isServerShuttingDown && isServerLoaded) { if (!trimTicker.isAlive()) { - Iris.info(C.IRIS + "TrimTicker found dead! Booting it up!"); + Iris.info(C.RED + "TrimTicker found dead! Booting it up!"); try { - trimTicker.start(); + TrimLogic(); } catch (Exception e) { Iris.error("What happened?"); e.printStackTrace(); @@ -189,9 +188,9 @@ public class IrisEngineSVC implements IrisService { } if (!unloadTicker.isAlive()) { - Iris.info(C.IRIS + "UnloadTicker found dead! Booting it up!"); + Iris.info(C.RED + "UnloadTicker found dead! Booting it up!"); try { - unloadTicker.start(); + UnloadLogic(); } catch (Exception e) { Iris.error("What happened?"); e.printStackTrace(); @@ -205,63 +204,72 @@ public class IrisEngineSVC implements IrisService { return 1000; } }; + } + public void TrimLogic() { + if (trimTicker == null || !trimTicker.isAlive()) { + trimTicker = new Looper() { + private final Supplier supplier = createSupplier(); - trimTicker = new Looper() { - private final Supplier supplier = createSupplier(); - @Override - protected long loop() { - long start = System.currentTimeMillis(); - trimAlive.reset(); - try { - Engine engine = supplier.get(); - if (engine != null) { - engine.getMantle().trim(tectonicLimit.get() / lastUse.size()); - } - } catch (Throwable e) { - Iris.reportError(e); - Iris.info(C.RED + "EngineSVC: Failed to trim. Please contact support!"); - e.printStackTrace(); - return -1; - } - - int size = lastUse.size(); - long time = (size > 0 ? 1000/size : 1000) - (System.currentTimeMillis() - start); - if (time <= 0) - return 0; - return time; - } - }; - - unloadTicker = new Looper() { - private final Supplier supplier = createSupplier(); - - @Override - protected long loop() { - long start = System.currentTimeMillis(); - unloadAlive.reset(); - try { - Engine engine = supplier.get(); - if (engine != null) { - long unloadStart = System.currentTimeMillis(); - int count = engine.getMantle().unloadTectonicPlate(tectonicLimit.get() / lastUse.size()); - if (count > 0) { - Iris.debug(C.GOLD + "Unloaded " + C.YELLOW + count + " TectonicPlates in " + C.RED + Form.duration(System.currentTimeMillis() - unloadStart, 2)); + @Override + protected long loop() { + long start = System.currentTimeMillis(); + trimAlive.reset(); + try { + Engine engine = supplier.get(); + if (engine != null) { + engine.getMantle().trim(tectonicLimit.get() / lastUse.size()); } + } catch (Throwable e) { + Iris.reportError(e); + Iris.info(C.RED + "EngineSVC: Failed to trim."); + e.printStackTrace(); + return -1; } - } catch (Throwable e) { - Iris.reportError(e); - Iris.info(C.RED + "EngineSVC: Failed to unload."); - e.printStackTrace(); - return -1; - } - int size = lastUse.size(); - long time = (size > 0 ? 1000/size : 1000) - (System.currentTimeMillis() - start); - if (time <= 0) - return 0; - return time; - } - }; + int size = lastUse.size(); + long time = (size > 0 ? 1000 / size : 1000) - (System.currentTimeMillis() - start); + if (time <= 0) + return 0; + return time; + } + }; + trimTicker.start(); + } + } + public void UnloadLogic() { + if (unloadTicker == null || !unloadTicker.isAlive()) { + unloadTicker = new Looper() { + private final Supplier supplier = createSupplier(); + + @Override + protected long loop() { + long start = System.currentTimeMillis(); + unloadAlive.reset(); + try { + Engine engine = supplier.get(); + if (engine != null) { + long unloadStart = System.currentTimeMillis(); + int count = engine.getMantle().unloadTectonicPlate(tectonicLimit.get() / lastUse.size()); + if (count > 0) { + Iris.debug(C.GOLD + "Unloaded " + C.YELLOW + count + " TectonicPlates in " + C.RED + Form.duration(System.currentTimeMillis() - unloadStart, 2)); + } + } + } catch (Throwable e) { + Iris.reportError(e); + Iris.info(C.RED + "EngineSVC: Failed to unload."); + e.printStackTrace(); + return -1; + } + + int size = lastUse.size(); + long time = (size > 0 ? 1000 / size : 1000) - (System.currentTimeMillis() - start); + if (time <= 0) + return 0; + return time; + } + }; + unloadTicker.start(); + } } private Supplier createSupplier() { @@ -281,7 +289,8 @@ public class IrisEngineSVC implements IrisService { if (generator != null) { Engine engine = generator.getEngine(); - if (engine != null && !engine.isStudio()) { + boolean closed = engine.getMantle().getData().isClosed(); + if (engine != null && !engine.isStudio() && !closed) { lastUseLock.lock(); lastUse.put(world, System.currentTimeMillis()); lastUseLock.unlock(); diff --git a/core/src/main/java/com/volmit/iris/core/tools/IrisCreator.java b/core/src/main/java/com/volmit/iris/core/tools/IrisCreator.java index 3e90aced1..e67908d0f 100644 --- a/core/src/main/java/com/volmit/iris/core/tools/IrisCreator.java +++ b/core/src/main/java/com/volmit/iris/core/tools/IrisCreator.java @@ -86,6 +86,7 @@ public class IrisCreator { * Benchmark mode */ private boolean benchmark = false; + private boolean smartVanillaHeight = false; public static boolean removeFromBukkitYml(String name) throws IOException { YamlConfiguration yml = YamlConfiguration.loadConfiguration(BUKKIT_YML); @@ -149,6 +150,7 @@ public class IrisCreator { .name(name) .seed(seed) .studio(studio) + .smartVanillaHeight(smartVanillaHeight) .create(); ServerConfigurator.installDataPacks(false); diff --git a/core/src/main/java/com/volmit/iris/core/tools/IrisWorldCreator.java b/core/src/main/java/com/volmit/iris/core/tools/IrisWorldCreator.java index cd6c17a91..b815d3809 100644 --- a/core/src/main/java/com/volmit/iris/core/tools/IrisWorldCreator.java +++ b/core/src/main/java/com/volmit/iris/core/tools/IrisWorldCreator.java @@ -32,6 +32,7 @@ public class IrisWorldCreator { private String name; private boolean studio = false; private String dimensionName = null; + private boolean smartVanillaHeight = false; private long seed = 1337; public IrisWorldCreator() { @@ -63,6 +64,11 @@ public class IrisWorldCreator { return this; } + public IrisWorldCreator smartVanillaHeight(boolean smartVanillaHeight) { + this.smartVanillaHeight = smartVanillaHeight; + return this; + } + public WorldCreator create() { IrisDimension dim = IrisData.loadAnyDimension(dimensionName); @@ -76,7 +82,7 @@ public class IrisWorldCreator { .build(); ChunkGenerator g = new BukkitChunkGenerator(w, studio, studio ? dim.getLoader().getDataFolder() : - new File(w.worldFolder(), "iris/pack"), dimensionName); + new File(w.worldFolder(), "iris/pack"), dimensionName, smartVanillaHeight); return new WorldCreator(name) diff --git a/core/src/main/java/com/volmit/iris/engine/IrisComplex.java b/core/src/main/java/com/volmit/iris/engine/IrisComplex.java index db92954a8..3b271951f 100644 --- a/core/src/main/java/com/volmit/iris/engine/IrisComplex.java +++ b/core/src/main/java/com/volmit/iris/engine/IrisComplex.java @@ -292,7 +292,7 @@ public class IrisComplex implements DataProvider { double b = 0; for (IrisGenerator gen : generators) { - b += bx.getGenLinkMax(gen.getLoadKey()); + b += bx.getGenLinkMax(gen.getLoadKey(), engine); } return b; @@ -311,7 +311,7 @@ public class IrisComplex implements DataProvider { double b = 0; for (IrisGenerator gen : generators) { - b += bx.getGenLinkMin(gen.getLoadKey()); + b += bx.getGenLinkMin(gen.getLoadKey(), engine); } return b; diff --git a/core/src/main/java/com/volmit/iris/engine/object/IrisBiome.java b/core/src/main/java/com/volmit/iris/engine/object/IrisBiome.java index c08d3fa11..d75dca7ad 100644 --- a/core/src/main/java/com/volmit/iris/engine/object/IrisBiome.java +++ b/core/src/main/java/com/volmit/iris/engine/object/IrisBiome.java @@ -194,13 +194,14 @@ public class IrisBiome extends IrisRegistrant implements IRare { return getCustomDerivitives() != null && getCustomDerivitives().isNotEmpty(); } - public double getGenLinkMax(String loadKey) { + public double getGenLinkMax(String loadKey, Engine engine) { Integer v = genCacheMax.aquire(() -> { KMap l = new KMap<>(); for (IrisBiomeGeneratorLink i : getGenerators()) { - l.put(i.getGenerator(), i.getMax()); + l.put(i.getGenerator(), i.getMax(engine)); + } return l; @@ -209,13 +210,13 @@ public class IrisBiome extends IrisRegistrant implements IRare { return v == null ? 0 : v; } - public double getGenLinkMin(String loadKey) { + public double getGenLinkMin(String loadKey, Engine engine) { Integer v = genCacheMin.aquire(() -> { KMap l = new KMap<>(); for (IrisBiomeGeneratorLink i : getGenerators()) { - l.put(i.getGenerator(), i.getMin()); + l.put(i.getGenerator(), i.getMin(engine)); } return l; @@ -450,26 +451,26 @@ public class IrisBiome extends IrisRegistrant implements IRare { return real; } - public int getMaxHeight() { + public int getMaxHeight(Engine engine) { return maxHeight.aquire(() -> { int maxHeight = 0; for (IrisBiomeGeneratorLink i : getGenerators()) { - maxHeight += i.getMax(); + maxHeight += i.getMax(engine); } return maxHeight; }); } - public int getMaxWithObjectHeight(IrisData data) { + public int getMaxWithObjectHeight(IrisData data, Engine engine) { return maxWithObjectHeight.aquire(() -> { int maxHeight = 0; for (IrisBiomeGeneratorLink i : getGenerators()) { - maxHeight += i.getMax(); + maxHeight += i.getMax(engine); } int gg = 0; diff --git a/core/src/main/java/com/volmit/iris/engine/object/IrisBiomeGeneratorLink.java b/core/src/main/java/com/volmit/iris/engine/object/IrisBiomeGeneratorLink.java index 2571389ca..5a7a71920 100644 --- a/core/src/main/java/com/volmit/iris/engine/object/IrisBiomeGeneratorLink.java +++ b/core/src/main/java/com/volmit/iris/engine/object/IrisBiomeGeneratorLink.java @@ -18,14 +18,13 @@ package com.volmit.iris.engine.object; -import com.volmit.iris.core.IrisSettings; +import com.volmit.iris.Iris; import com.volmit.iris.engine.data.cache.AtomicCache; +import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.object.annotations.*; import com.volmit.iris.util.data.DataProvider; import com.volmit.iris.util.interpolation.IrisInterpolation; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; +import lombok.*; import lombok.experimental.Accessors; @Snippet("generator-layer") @@ -40,22 +39,23 @@ public class IrisBiomeGeneratorLink { @RegistryListResource(IrisGenerator.class) @Desc("The generator id") private String generator = "default"; - @DependsOn({"min", "max"}) + @DependsOn({ "min", "max" }) @Required @MinNumber(-2032) // TODO: WARNING HEIGHT @MaxNumber(2032) // TODO: WARNING HEIGHT @Desc("The min block value (value + fluidHeight)") + @Getter(AccessLevel.NONE) private int min = 0; - @DependsOn({"min", "max"}) + @DependsOn({ "min", "max" }) @Required @MinNumber(-2032) // TODO: WARNING HEIGHT @MaxNumber(2032) // TODO: WARNING HEIGHT + @Getter(AccessLevel.NONE) @Desc("The max block value (value + fluidHeight)") private int max = 0; public IrisGenerator getCachedGenerator(DataProvider g) { - return gen.aquire(() -> - { + return gen.aquire(() -> { IrisGenerator gen = g.getData().getGeneratorLoader().load(getGenerator()); if (gen == null) { @@ -66,21 +66,74 @@ public class IrisBiomeGeneratorLink { }); } + private int[] getBiomeGeneratorsRaw(Engine engine) { + int max = engine.getDimension().getMinHeight(); + int min = engine.getDimension().getMaxHeight(); + for (IrisBiome biome : engine.getAllBiomes()) { + for (IrisBiomeGeneratorLink i : biome.getGenerators()) { + int biomeRawMax = i.getMaxRaw(); + int biomeRawMin = i.getMinRaw(); + if (max < biomeRawMax) + max = biomeRawMax; + if (min > biomeRawMin) + min = biomeRawMin; + } + } + + return new int[] { min, max }; + } + + private int calculateHeight(Engine engine, int option) { + int dmx = engine.getDimension().getMaxHeight(); + int dmn = engine.getDimension().getMinHeight(); + int[] heights = getBiomeGeneratorsRaw(engine); + int gmx = heights[1]; + int gmn = heights[0]; + + int mx = max; + int mn = min; + if (engine.getDimension().isSmartVanillaHeight()) { + if (mx > 0) + mx = Math.min((int) (((float) mx / (float) gmx) * 300.0f), 300); + if (mx < 0) + mx = Math.min((int) (((float) mx / (float) gmn) * 300.0f), 56); + + if (mn > 0) + mn = Math.min((int) (((float) mn / (float) gmx) * 300.0f), 300); + if (mn < 0) + mn = Math.min((int) (((float) mn / (float) gmn) * 300.0f), 56); + } + + if (option == 1) { + return mx; + } + if (option == 0) { + return mn; + } + Iris.error("Fatal Generator error!"); + return 0; + } + + public int getMax(Engine engine) { + return calculateHeight(engine, 1); + } + + public int getMin(Engine engine) { + return calculateHeight(engine, 0); + } + + private int getMaxRaw() { + return max; + } + + private int getMinRaw() { + return min; + } + public double getHeight(DataProvider xg, double x, double z, long seed) { double g = getCachedGenerator(xg).getHeight(x, z, seed); g = g < 0 ? 0 : g; g = g > 1 ? 1 : g; -// if (IrisSettings.get().getGenerator().forceConvertTo320Height) { -// if (max > 320 || min > 320) { -// double scaleFactor = 320.0 / Math.max(max, min); -// min *= (int) scaleFactor; -// max *= (int) scaleFactor; -// if (min < 0) { -// -// } -// } -// } - // todo This return IrisInterpolation.lerp(min, max, g); } diff --git a/core/src/main/java/com/volmit/iris/engine/object/IrisDimension.java b/core/src/main/java/com/volmit/iris/engine/object/IrisDimension.java index 488171296..aee21600b 100644 --- a/core/src/main/java/com/volmit/iris/engine/object/IrisDimension.java +++ b/core/src/main/java/com/volmit/iris/engine/object/IrisDimension.java @@ -19,6 +19,7 @@ package com.volmit.iris.engine.object; import com.volmit.iris.Iris; +import com.volmit.iris.core.IrisSettings; import com.volmit.iris.core.loader.IrisData; import com.volmit.iris.core.loader.IrisRegistrant; import com.volmit.iris.engine.data.cache.AtomicCache; @@ -210,6 +211,8 @@ public class IrisDimension extends IrisRegistrant { private IrisCarving carving = new IrisCarving(); @Desc("Configuration of fluid bodies such as rivers & lakes") private IrisFluidBodies fluidBodies = new IrisFluidBodies(); + @Desc("forceConvertTo320Height") + private Boolean forceConvertTo320Height = false; @Desc("The world environment") private Environment environment = Environment.NORMAL; @RegistryListResource(IrisRegion.class) @@ -231,6 +234,8 @@ public class IrisDimension extends IrisRegistrant { private IrisRange dimensionHeightEnd = new IrisRange(-64, 320); @Desc("Define the min and max Y bounds of this dimension. Please keep in mind that Iris internally generates from 0 to (max - min). \n\nFor example at -64 to 320, Iris is internally generating to 0 to 384, then on outputting chunks, it shifts it down by the min height (64 blocks). The default is -64 to 320. \n\nThe fluid height is placed at (fluid height + min height). So a fluid height of 63 would actually show up in the world at 1.") private IrisRange dimensionHeightNether = new IrisRange(-64, 320); + @Desc("Enable smart vanilla height") + private boolean smartVanillaHeight = false; @RegistryListResource(IrisBiome.class) @Desc("Keep this either undefined or empty. Setting any biome name into this will force iris to only generate the specified biome. Great for testing.") private String focus = ""; diff --git a/core/src/main/java/com/volmit/iris/engine/platform/BukkitChunkGenerator.java b/core/src/main/java/com/volmit/iris/engine/platform/BukkitChunkGenerator.java index 50206b6d1..ce0bebd74 100644 --- a/core/src/main/java/com/volmit/iris/engine/platform/BukkitChunkGenerator.java +++ b/core/src/main/java/com/volmit/iris/engine/platform/BukkitChunkGenerator.java @@ -58,6 +58,8 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.io.File; +import java.io.FileWriter; +import java.io.IOException; import java.lang.reflect.Field; import java.util.List; import java.util.Random; @@ -82,6 +84,7 @@ public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChun private final AtomicBoolean setup; private final boolean studio; private final AtomicInteger a = new AtomicInteger(0); + private final boolean smartVanillaHeight; private Engine engine; private Looper hotloader; private StudioMode lastMode; @@ -91,7 +94,7 @@ public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChun private boolean initialized = false; - public BukkitChunkGenerator(IrisWorld world, boolean studio, File dataLocation, String dimensionKey) { + public BukkitChunkGenerator(IrisWorld world, boolean studio, File dataLocation, String dimensionKey, boolean smartVanillaHeight) { setup = new AtomicBoolean(false); studioGenerator = null; dummyBiomeProvider = new DummyBiomeProvider(); @@ -103,6 +106,7 @@ public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChun this.dataLocation = dataLocation; this.dimensionKey = dimensionKey; this.folder = new ReactiveFolder(dataLocation, (_a, _b, _c) -> hotload()); + this.smartVanillaHeight = smartVanillaHeight; Bukkit.getServer().getPluginManager().registerEvents(this, Iris.instance); } @@ -181,6 +185,14 @@ public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChun throw new RuntimeException("Missing Dimension: " + dimensionKey); } } + if (smartVanillaHeight) { + dimension.setSmartVanillaHeight(true); + try (FileWriter writer = new FileWriter(data.getDimensionLoader().fileFor(dimension))) { + writer.write(data.getGson().toJson(dimension)); + } catch (IOException e) { + e.printStackTrace(); + } + } lastMode = StudioMode.NORMAL; engine = new IrisEngine(new EngineTarget(world, dimension, data), studio);