diff --git a/build.gradle b/build.gradle index 09d93cc4a..e95dc94f5 100644 --- a/build.gradle +++ b/build.gradle @@ -32,7 +32,7 @@ plugins { } group 'com.volmit.iris' -version '1.7.9' +version '1.7.11' def apiVersion = '1.17' def name = getRootProject().getName() // See settings.gradle def main = 'com.volmit.iris.Iris' @@ -191,7 +191,7 @@ dependencies { implementation 'it.unimi.dsi:fastutil:8.5.4' implementation 'com.googlecode.concurrentlinkedhashmap:concurrentlinkedhashmap-lru:1.4.2' implementation 'org.zeroturnaround:zt-zip:1.14' - implementation 'com.google.code.gson:gson:2.8.7' + implementation 'com.google.code.gson:gson:2.8.8' implementation 'org.ow2.asm:asm:9.2' implementation 'com.google.guava:guava:30.1.1-jre' implementation 'bsf:bsf:2.4.0' diff --git a/src/main/java/com/volmit/iris/Iris.java b/src/main/java/com/volmit/iris/Iris.java index 62d7591a2..54280530b 100644 --- a/src/main/java/com/volmit/iris/Iris.java +++ b/src/main/java/com/volmit/iris/Iris.java @@ -27,7 +27,7 @@ import com.volmit.iris.core.link.MultiverseCoreLink; import com.volmit.iris.core.link.MythicMobsLink; import com.volmit.iris.core.link.OraxenLink; import com.volmit.iris.core.nms.INMS; -import com.volmit.iris.core.project.loader.IrisData; +import com.volmit.iris.core.loader.IrisData; import com.volmit.iris.core.service.StudioSVC; import com.volmit.iris.engine.object.biome.IrisBiome; import com.volmit.iris.engine.object.biome.IrisBiomeCustom; @@ -39,6 +39,7 @@ import com.volmit.iris.engine.platform.DummyChunkGenerator; import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.collection.KMap; import com.volmit.iris.util.collection.KSet; +import com.volmit.iris.util.exceptions.IrisException; import com.volmit.iris.util.format.C; import com.volmit.iris.util.format.Form; import com.volmit.iris.util.function.NastyRunnable; @@ -58,6 +59,8 @@ import io.papermc.lib.PaperLib; import net.kyori.adventure.platform.bukkit.BukkitAudiences; import net.kyori.adventure.text.serializer.ComponentSerializer; import org.bukkit.Bukkit; +import org.bukkit.GameMode; +import org.bukkit.Location; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; @@ -137,6 +140,23 @@ public class Iris extends VolmitPlugin implements Listener { J.s(this::setupPapi); J.a(this::verifyDataPacksPost, 20); splash(); + + if(IrisSettings.get().getGeneral().isAutoStartDefaultStudio()) + { + Iris.info("Starting up auto Studio!"); + try { + Player r = new KList<>(getServer().getOnlinePlayers()).getRandom(); + Iris.service(StudioSVC.class).open(r != null ? new VolmitSender(r) : sender, 1337, IrisSettings.get().getGenerator().getDefaultWorldType(), (w) -> { + J.s(() -> {for(Player i : getServer().getOnlinePlayers()) + { + i.setGameMode(GameMode.SPECTATOR); + i.teleport(new Location(w, 0, 200, 0)); + }}); + }); + } catch (IrisException e) { + e.printStackTrace(); + } + } } @SuppressWarnings("unchecked") @@ -372,6 +392,8 @@ public class Iris extends VolmitPlugin implements Listener { sender.sendMessage("You need to restart your server to use these packs."); } } + + J.sleep(3000); } } diff --git a/src/main/java/com/volmit/iris/core/IrisSettings.java b/src/main/java/com/volmit/iris/core/IrisSettings.java index 804e91dae..bd23ba419 100644 --- a/src/main/java/com/volmit/iris/core/IrisSettings.java +++ b/src/main/java/com/volmit/iris/core/IrisSettings.java @@ -102,6 +102,7 @@ public class IrisSettings { public boolean keepProductionOnReload = false; public boolean pluginMetrics = true; public boolean splashLogoStartup = true; + public boolean autoStartDefaultStudio = false; public String forceMainWorld = ""; public int spinh = -20; public int spins = 7; diff --git a/src/main/java/com/volmit/iris/core/command/CommandIris.java b/src/main/java/com/volmit/iris/core/command/CommandIris.java index c54885676..20601d459 100644 --- a/src/main/java/com/volmit/iris/core/command/CommandIris.java +++ b/src/main/java/com/volmit/iris/core/command/CommandIris.java @@ -25,8 +25,8 @@ import com.volmit.iris.core.command.pregen.CommandIrisPregen; import com.volmit.iris.core.command.studio.CommandIrisStudio; import com.volmit.iris.core.command.what.CommandIrisWhat; import com.volmit.iris.core.command.world.CommandIrisCreate; +import com.volmit.iris.core.command.world.CommandIrisRegen; import com.volmit.iris.core.command.world.CommandIrisUpdateWorld; -import com.volmit.iris.core.command.world.CommandIrisVerify; import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.plugin.Command; import com.volmit.iris.util.plugin.MortarCommand; @@ -37,7 +37,7 @@ public class CommandIris extends MortarCommand { private CommandIrisCreate create; @Command - private CommandIrisVerify verify; + private CommandIrisRegen regen; @Command private CommandIrisDebug debug; diff --git a/src/main/java/com/volmit/iris/core/command/CommandIrisBitwise.java b/src/main/java/com/volmit/iris/core/command/CommandIrisBitwise.java index 86cb66997..b118b7ba6 100644 --- a/src/main/java/com/volmit/iris/core/command/CommandIrisBitwise.java +++ b/src/main/java/com/volmit/iris/core/command/CommandIrisBitwise.java @@ -19,10 +19,14 @@ package com.volmit.iris.core.command; import com.volmit.iris.Iris; +import com.volmit.iris.core.pack.IrisPack; import com.volmit.iris.util.collection.KList; +import com.volmit.iris.util.exceptions.IrisException; import com.volmit.iris.util.plugin.MortarCommand; import com.volmit.iris.util.plugin.VolmitSender; +import java.util.concurrent.ExecutionException; + public class CommandIrisBitwise extends MortarCommand { public CommandIrisBitwise() { super("bitwise", "bits", "bw"); diff --git a/src/main/java/com/volmit/iris/core/command/CommandIrisDebug.java b/src/main/java/com/volmit/iris/core/command/CommandIrisDebug.java index 838e8473d..8b2ebf91b 100644 --- a/src/main/java/com/volmit/iris/core/command/CommandIrisDebug.java +++ b/src/main/java/com/volmit/iris/core/command/CommandIrisDebug.java @@ -28,6 +28,8 @@ import com.volmit.iris.util.plugin.VolmitSender; public class CommandIrisDebug extends MortarCommand { @Command private CommandIrisDebugSpawnerBoost boost; + @Command + private CommandIrisDebugReupdate reupdate; public CommandIrisDebug() { super("debug", "dbg"); diff --git a/src/main/java/com/volmit/iris/core/command/CommandIrisDebugReupdate.java b/src/main/java/com/volmit/iris/core/command/CommandIrisDebugReupdate.java new file mode 100644 index 000000000..52e157b63 --- /dev/null +++ b/src/main/java/com/volmit/iris/core/command/CommandIrisDebugReupdate.java @@ -0,0 +1,58 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.core.command; + +import com.volmit.iris.Iris; +import com.volmit.iris.core.tools.IrisToolbelt; +import com.volmit.iris.engine.framework.Engine; +import com.volmit.iris.util.collection.KList; +import com.volmit.iris.util.mantle.MantleFlag; +import com.volmit.iris.util.plugin.MortarCommand; +import com.volmit.iris.util.plugin.VolmitSender; +import org.bukkit.Chunk; + +public class CommandIrisDebugReupdate extends MortarCommand { + public CommandIrisDebugReupdate() { + super("reupdate", "rupt"); + requiresPermission(Iris.perm.studio); + setDescription("Force update a chunk again"); + setCategory("Studio"); + } + + + @Override + public void addTabOptions(VolmitSender sender, String[] args, KList list) { + + } + + @Override + public boolean handle(VolmitSender sender, String[] args) { + + Chunk c = sender.player().getLocation().getChunk(); + Engine e = IrisToolbelt.access(sender.player().getWorld()).getEngine(); + e.getMantle().getMantle().flag(c.getX(), c.getZ(), MantleFlag.UPDATE, false); + e.updateChunk(c); + return true; + } + + @Override + protected String getArgsUsage() { + return " [|,&,^,>>,<<,%] "; + } +} diff --git a/src/main/java/com/volmit/iris/core/command/jigsaw/CommandIrisJigsawEdit.java b/src/main/java/com/volmit/iris/core/command/jigsaw/CommandIrisJigsawEdit.java index cee87332c..1a752b556 100644 --- a/src/main/java/com/volmit/iris/core/command/jigsaw/CommandIrisJigsawEdit.java +++ b/src/main/java/com/volmit/iris/core/command/jigsaw/CommandIrisJigsawEdit.java @@ -21,7 +21,7 @@ package com.volmit.iris.core.command.jigsaw; import com.volmit.iris.Iris; import com.volmit.iris.core.IrisSettings; import com.volmit.iris.core.edit.JigsawEditor; -import com.volmit.iris.core.project.loader.IrisData; +import com.volmit.iris.core.loader.IrisData; import com.volmit.iris.engine.object.jigsaw.IrisJigsawPiece; import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.plugin.MortarCommand; diff --git a/src/main/java/com/volmit/iris/core/command/jigsaw/CommandIrisJigsawNew.java b/src/main/java/com/volmit/iris/core/command/jigsaw/CommandIrisJigsawNew.java index 19bdec8eb..8425801a8 100644 --- a/src/main/java/com/volmit/iris/core/command/jigsaw/CommandIrisJigsawNew.java +++ b/src/main/java/com/volmit/iris/core/command/jigsaw/CommandIrisJigsawNew.java @@ -21,7 +21,7 @@ package com.volmit.iris.core.command.jigsaw; import com.volmit.iris.Iris; import com.volmit.iris.core.IrisSettings; import com.volmit.iris.core.edit.JigsawEditor; -import com.volmit.iris.core.project.loader.IrisData; +import com.volmit.iris.core.loader.IrisData; import com.volmit.iris.engine.object.objects.IrisObject; import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.plugin.MortarCommand; diff --git a/src/main/java/com/volmit/iris/core/command/jigsaw/CommandIrisJigsawPlace.java b/src/main/java/com/volmit/iris/core/command/jigsaw/CommandIrisJigsawPlace.java index 5e25799ee..d4644616a 100644 --- a/src/main/java/com/volmit/iris/core/command/jigsaw/CommandIrisJigsawPlace.java +++ b/src/main/java/com/volmit/iris/core/command/jigsaw/CommandIrisJigsawPlace.java @@ -20,7 +20,7 @@ package com.volmit.iris.core.command.jigsaw; import com.volmit.iris.Iris; import com.volmit.iris.core.IrisSettings; -import com.volmit.iris.core.project.loader.IrisData; +import com.volmit.iris.core.loader.IrisData; import com.volmit.iris.core.tools.IrisToolbelt; import com.volmit.iris.engine.jigsaw.PlannedStructure; import com.volmit.iris.engine.object.basic.IrisPosition; diff --git a/src/main/java/com/volmit/iris/core/command/object/CommandIrisObjectAnalyze.java b/src/main/java/com/volmit/iris/core/command/object/CommandIrisObjectAnalyze.java index ab9f42b73..aa0597786 100644 --- a/src/main/java/com/volmit/iris/core/command/object/CommandIrisObjectAnalyze.java +++ b/src/main/java/com/volmit/iris/core/command/object/CommandIrisObjectAnalyze.java @@ -20,7 +20,7 @@ package com.volmit.iris.core.command.object; import com.volmit.iris.Iris; import com.volmit.iris.core.IrisSettings; -import com.volmit.iris.core.project.loader.IrisData; +import com.volmit.iris.core.loader.IrisData; import com.volmit.iris.core.tools.IrisToolbelt; import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.plugin.MortarCommand; diff --git a/src/main/java/com/volmit/iris/core/command/object/CommandIrisObjectPaste.java b/src/main/java/com/volmit/iris/core/command/object/CommandIrisObjectPaste.java index 714cb9927..63745563e 100644 --- a/src/main/java/com/volmit/iris/core/command/object/CommandIrisObjectPaste.java +++ b/src/main/java/com/volmit/iris/core/command/object/CommandIrisObjectPaste.java @@ -20,8 +20,7 @@ package com.volmit.iris.core.command.object; import com.volmit.iris.Iris; import com.volmit.iris.core.IrisSettings; -import com.volmit.iris.core.project.loader.IrisData; -import com.volmit.iris.core.service.ObjectSVC; +import com.volmit.iris.core.loader.IrisData; import com.volmit.iris.core.service.StudioSVC; import com.volmit.iris.core.service.WandSVC; import com.volmit.iris.core.tools.IrisToolbelt; diff --git a/src/main/java/com/volmit/iris/core/command/object/CommandIrisObjectPasteMatter.java b/src/main/java/com/volmit/iris/core/command/object/CommandIrisObjectPasteMatter.java index 7c13e6c54..dca4b3d22 100644 --- a/src/main/java/com/volmit/iris/core/command/object/CommandIrisObjectPasteMatter.java +++ b/src/main/java/com/volmit/iris/core/command/object/CommandIrisObjectPasteMatter.java @@ -20,7 +20,7 @@ package com.volmit.iris.core.command.object; import com.volmit.iris.Iris; import com.volmit.iris.core.IrisSettings; -import com.volmit.iris.core.project.loader.IrisData; +import com.volmit.iris.core.loader.IrisData; import com.volmit.iris.core.tools.IrisToolbelt; import com.volmit.iris.engine.object.common.IObjectPlacer; import com.volmit.iris.engine.object.tile.TileData; diff --git a/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioExecute.java b/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioExecute.java index e9c68a0ce..2110395e5 100644 --- a/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioExecute.java +++ b/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioExecute.java @@ -20,7 +20,7 @@ package com.volmit.iris.core.command.studio; import com.volmit.iris.Iris; import com.volmit.iris.core.IrisSettings; -import com.volmit.iris.core.project.loader.IrisData; +import com.volmit.iris.core.loader.IrisData; import com.volmit.iris.core.tools.IrisToolbelt; import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.plugin.MortarCommand; diff --git a/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioExplorerGenerator.java b/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioExplorerGenerator.java index e20d8b53d..48c4b5c84 100644 --- a/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioExplorerGenerator.java +++ b/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioExplorerGenerator.java @@ -21,7 +21,7 @@ package com.volmit.iris.core.command.studio; import com.volmit.iris.Iris; import com.volmit.iris.core.IrisSettings; import com.volmit.iris.core.gui.NoiseExplorerGUI; -import com.volmit.iris.core.project.loader.IrisData; +import com.volmit.iris.core.loader.IrisData; import com.volmit.iris.core.service.StudioSVC; import com.volmit.iris.core.tools.IrisToolbelt; import com.volmit.iris.engine.object.noise.IrisGenerator; diff --git a/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioGoto.java b/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioGoto.java index 0146a3a6f..b79ed2d7a 100644 --- a/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioGoto.java +++ b/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioGoto.java @@ -19,7 +19,7 @@ package com.volmit.iris.core.command.studio; import com.volmit.iris.Iris; -import com.volmit.iris.core.project.loader.IrisData; +import com.volmit.iris.core.loader.IrisData; import com.volmit.iris.core.tools.IrisToolbelt; import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.object.basic.IrisPosition; diff --git a/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioProfile.java b/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioProfile.java index 3cea777b1..20f61465e 100644 --- a/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioProfile.java +++ b/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioProfile.java @@ -21,7 +21,7 @@ package com.volmit.iris.core.command.studio; import com.volmit.iris.Iris; import com.volmit.iris.core.IrisSettings; import com.volmit.iris.core.project.IrisProject; -import com.volmit.iris.core.project.loader.IrisData; +import com.volmit.iris.core.loader.IrisData; import com.volmit.iris.core.service.StudioSVC; import com.volmit.iris.engine.object.biome.IrisBiome; import com.volmit.iris.engine.object.biome.IrisBiomePaletteLayer; diff --git a/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioSummon.java b/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioSummon.java index 0c4ee142a..611ec4045 100644 --- a/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioSummon.java +++ b/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioSummon.java @@ -20,7 +20,7 @@ package com.volmit.iris.core.command.studio; import com.volmit.iris.Iris; import com.volmit.iris.core.IrisSettings; -import com.volmit.iris.core.project.loader.IrisData; +import com.volmit.iris.core.loader.IrisData; import com.volmit.iris.core.tools.IrisToolbelt; import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.object.entity.IrisEntity; @@ -81,7 +81,8 @@ public class CommandIrisStudioSummon extends MortarCommand { return true; } - Location vl = sender.player().getLocation().clone().add(0, 3, 0); + + Location vl = sender.player().getTargetBlockExact(256).getLocation().clone().add(0, 1, 0); e.spawn(g, vl); } } else { diff --git a/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioUpdate.java b/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioUpdate.java index dcb5d5ee1..974d481cf 100644 --- a/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioUpdate.java +++ b/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioUpdate.java @@ -21,7 +21,7 @@ package com.volmit.iris.core.command.studio; import com.volmit.iris.Iris; import com.volmit.iris.core.IrisSettings; import com.volmit.iris.core.project.IrisProject; -import com.volmit.iris.core.project.loader.IrisData; +import com.volmit.iris.core.loader.IrisData; import com.volmit.iris.core.service.StudioSVC; import com.volmit.iris.engine.object.objects.IrisObject; import com.volmit.iris.util.collection.KList; diff --git a/src/main/java/com/volmit/iris/core/command/what/CommandIrisWhatFeatures.java b/src/main/java/com/volmit/iris/core/command/what/CommandIrisWhatFeatures.java index bd93f2018..e1cbaadd3 100644 --- a/src/main/java/com/volmit/iris/core/command/what/CommandIrisWhatFeatures.java +++ b/src/main/java/com/volmit/iris/core/command/what/CommandIrisWhatFeatures.java @@ -52,7 +52,7 @@ public class CommandIrisWhatFeatures extends MortarCommand { if (IrisToolbelt.isIrisWorld(c.getWorld())) { int m = 1; - for (IrisFeaturePositional i : IrisToolbelt.access(c.getWorld()).getEngine().getMantle().getFeaturesInChunk(c)) { + for (IrisFeaturePositional i : IrisToolbelt.access(c.getWorld()).getEngine().getMantle().forEachFeature(c)) { sender.sendMessage("#" + m++ + " " + new JSONObject(new Gson().toJson(i)).toString(4)); } } else { diff --git a/src/main/java/com/volmit/iris/core/command/world/CommandIrisRegen.java b/src/main/java/com/volmit/iris/core/command/world/CommandIrisRegen.java new file mode 100644 index 000000000..a0cce0f21 --- /dev/null +++ b/src/main/java/com/volmit/iris/core/command/world/CommandIrisRegen.java @@ -0,0 +1,129 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.core.command.world; + +import com.volmit.iris.Iris; +import com.volmit.iris.core.tools.IrisToolbelt; +import com.volmit.iris.engine.framework.Engine; +import com.volmit.iris.engine.platform.PlatformChunkGenerator; +import com.volmit.iris.util.collection.KList; +import com.volmit.iris.util.format.Form; +import com.volmit.iris.util.parallel.BurstExecutor; +import com.volmit.iris.util.parallel.MultiBurst; +import com.volmit.iris.util.plugin.MortarCommand; +import com.volmit.iris.util.plugin.VolmitSender; +import com.volmit.iris.util.scheduling.J; +import com.volmit.iris.util.scheduling.jobs.QueueJob; +import org.bukkit.Chunk; + +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; + +public class CommandIrisRegen extends MortarCommand { + public CommandIrisRegen() { + super("regen"); + requiresPermission(Iris.perm.studio); + setDescription("Regenerate nearby chunks"); + setCategory("Studio"); + } + + @Override + public void addTabOptions(VolmitSender sender, String[] args, KList list) { + + } + + @Override + public boolean handle(VolmitSender sender, String[] args) { + if (!sender.isPlayer()) { + sender.sendMessage("Must be in an iris world."); + } + + if (IrisToolbelt.isIrisWorld(sender.player().getWorld())) { + J.a(() -> { + PlatformChunkGenerator plat = IrisToolbelt.access(sender.player().getWorld()); + Engine engine = plat.getEngine(); + try { + int vd = Integer.parseInt(args[0]); + int rg = 0; + Chunk cx = sender.player().getLocation().getChunk(); + KList js = new KList<>(); + BurstExecutor b = MultiBurst.burst.burst(); + b.setMulticore(false); + int rad = engine.getMantle().getRealRadius(); + for (int i = -(vd + rad); i <= vd + rad; i++) { + for (int j = -(vd + rad); j <= vd + rad; j++) { + engine.getMantle().getMantle().deleteChunk(i + cx.getX(), j + cx.getZ()); + } + } + + for (int i = -vd; i <= vd; i++) { + for (int j = -vd; j <= vd; j++) { + int finalJ = j; + int finalI = i; + b.queue(() -> plat.injectChunkReplacement(sender.player().getWorld(), finalI + cx.getX(), finalJ + cx.getZ(), (f) -> { + synchronized (js) { + js.add(f); + } + })); + } + } + + b.complete(); + sender.sendMessage("Regenerating " + Form.f(js.size()) + " Sections"); + QueueJob r = new QueueJob<>() { + final KList> futures = new KList<>(); + + @Override + public void execute(Runnable runnable) { + futures.add(J.sfut(runnable)); + + if (futures.size() > 64) { + while (futures.isNotEmpty()) { + try { + futures.remove(0).get(); + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (ExecutionException e) { + e.printStackTrace(); + } + } + } + } + + @Override + public String getName() { + return "Regenerating"; + } + }; + r.queue(js); + r.execute(sender); + } catch (Throwable e) { + sender.sendMessage("Unable to parse view-distance"); + } + }); + } + + return true; + } + + @Override + protected String getArgsUsage() { + return "[view-distance]"; + } +} diff --git a/src/main/java/com/volmit/iris/core/decrees/DecObject.java b/src/main/java/com/volmit/iris/core/decrees/DecObject.java index 89c27cd78..6cfc72a01 100644 --- a/src/main/java/com/volmit/iris/core/decrees/DecObject.java +++ b/src/main/java/com/volmit/iris/core/decrees/DecObject.java @@ -1,9 +1,7 @@ package com.volmit.iris.core.decrees; -import com.volmit.iris.Iris; -import com.volmit.iris.core.project.loader.IrisData; -import com.volmit.iris.core.service.ObjectSVC; -import com.volmit.iris.core.service.StudioSVC; +import com.volmit.iris.core.command.object.CommandIrisObjectUndo; +import com.volmit.iris.core.loader.IrisData; import com.volmit.iris.core.service.WandSVC; import com.volmit.iris.engine.object.common.IObjectPlacer; import com.volmit.iris.engine.object.dimensional.IrisDimension; diff --git a/src/main/java/com/volmit/iris/core/decrees/DecStudio.java b/src/main/java/com/volmit/iris/core/decrees/DecStudio.java index ab33c2f32..00d9505aa 100644 --- a/src/main/java/com/volmit/iris/core/decrees/DecStudio.java +++ b/src/main/java/com/volmit/iris/core/decrees/DecStudio.java @@ -23,7 +23,7 @@ import com.volmit.iris.core.IrisSettings; import com.volmit.iris.core.gui.NoiseExplorerGUI; import com.volmit.iris.core.gui.VisionGUI; import com.volmit.iris.core.project.IrisProject; -import com.volmit.iris.core.project.loader.IrisData; +import com.volmit.iris.core.loader.IrisData; import com.volmit.iris.core.service.ConversionSVC; import com.volmit.iris.core.service.StudioSVC; import com.volmit.iris.core.tools.IrisToolbelt; diff --git a/src/main/java/com/volmit/iris/core/gui/VisionGUI.java b/src/main/java/com/volmit/iris/core/gui/VisionGUI.java index 4cb5c1d04..a416b9930 100644 --- a/src/main/java/com/volmit/iris/core/gui/VisionGUI.java +++ b/src/main/java/com/volmit/iris/core/gui/VisionGUI.java @@ -58,7 +58,17 @@ import java.util.function.BiFunction; public class VisionGUI extends JPanel implements MouseWheelListener, KeyListener, MouseMotionListener, MouseInputListener { private static final long serialVersionUID = 2094606939770332040L; - + private final KList lastEntities = new KList<>(); + private final KMap notifications = new KMap<>(); + private final ChronoLatch centities = new ChronoLatch(1000); + private final RollingSequence rs = new RollingSequence(512); + private final O m = new O<>(); + private final KMap positions = new KMap<>(); + private final KMap fastpositions = new KMap<>(); + private final KSet working = new KSet<>(); + private final KSet workingfast = new KSet<>(); + double tfps = 240D; + int ltc = 3; private RenderType currentType = RenderType.BIOME; private boolean help = true; private boolean helpIgnored = false; @@ -82,7 +92,6 @@ public class VisionGUI extends JPanel implements MouseWheelListener, KeyListener private int h = 0; private double lx = 0; private double lz = 0; - private final KList lastEntities = new KList<>(); private double ox = 0; private double oz = 0; private double hx = 0; @@ -90,17 +99,7 @@ public class VisionGUI extends JPanel implements MouseWheelListener, KeyListener private double oxp = 0; private double ozp = 0; private Engine engine; - private final KMap notifications = new KMap<>(); - double tfps = 240D; - int ltc = 3; - private final ChronoLatch centities = new ChronoLatch(1000); - private final RollingSequence rs = new RollingSequence(512); - private final O m = new O<>(); private int tid = 0; - private final KMap positions = new KMap<>(); - private final KMap fastpositions = new KMap<>(); - private final KSet working = new KSet<>(); - private final KSet workingfast = new KSet<>(); private final ExecutorService e = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors(), r -> { tid++; Thread t = new Thread(r); @@ -153,6 +152,33 @@ public class VisionGUI extends JPanel implements MouseWheelListener, KeyListener }); } + private static void createAndShowGUI(Engine r, int s, IrisWorld world) { + JFrame frame = new JFrame("Vision"); + VisionGUI nv = new VisionGUI(frame); + nv.world = world; + nv.engine = r; + nv.renderer = new IrisRenderer(r); + frame.add(nv); + frame.setSize(1440, 820); + frame.setVisible(true); + File file = Iris.getCached("Iris Icon", "https://raw.githubusercontent.com/VolmitSoftware/Iris/master/icon.png"); + + if (file != null) { + try { + nv.texture = ImageIO.read(file); + frame.setIconImage(ImageIO.read(file)); + } catch (IOException e) { + Iris.reportError(e); + + } + } + } + + public static void launch(Engine g, int i) { + J.a(() -> + createAndShowGUI(g, i, g.getWorld())); + } + public boolean updateEngine() { if (engine.isClosed()) { if (world.hasRealWorld()) { @@ -755,33 +781,6 @@ public class VisionGUI extends JPanel implements MouseWheelListener, KeyListener } } - private static void createAndShowGUI(Engine r, int s, IrisWorld world) { - JFrame frame = new JFrame("Vision"); - VisionGUI nv = new VisionGUI(frame); - nv.world = world; - nv.engine = r; - nv.renderer = new IrisRenderer(r); - frame.add(nv); - frame.setSize(1440, 820); - frame.setVisible(true); - File file = Iris.getCached("Iris Icon", "https://raw.githubusercontent.com/VolmitSoftware/Iris/master/icon.png"); - - if (file != null) { - try { - nv.texture = ImageIO.read(file); - frame.setIconImage(ImageIO.read(file)); - } catch (IOException e) { - Iris.reportError(e); - - } - } - } - - public static void launch(Engine g, int i) { - J.a(() -> - createAndShowGUI(g, i, g.getWorld())); - } - public void mouseWheelMoved(MouseWheelEvent e) { int notches = e.getWheelRotation(); if (e.isControlDown()) { diff --git a/src/main/java/com/volmit/iris/core/project/loader/IrisData.java b/src/main/java/com/volmit/iris/core/loader/IrisData.java similarity index 99% rename from src/main/java/com/volmit/iris/core/project/loader/IrisData.java rename to src/main/java/com/volmit/iris/core/loader/IrisData.java index ec315ead2..99a993a78 100644 --- a/src/main/java/com/volmit/iris/core/project/loader/IrisData.java +++ b/src/main/java/com/volmit/iris/core/loader/IrisData.java @@ -16,13 +16,13 @@ * along with this program. If not, see . */ -package com.volmit.iris.core.project.loader; +package com.volmit.iris.core.loader; import com.volmit.iris.Iris; import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.object.biome.IrisBiome; import com.volmit.iris.engine.object.block.IrisBlockData; -import com.volmit.iris.engine.object.cave.IrisCave; +import com.volmit.iris.engine.object.carving.IrisCave; import com.volmit.iris.engine.object.common.IrisScript; import com.volmit.iris.engine.object.dimensional.IrisDimension; import com.volmit.iris.engine.object.entity.IrisEntity; diff --git a/src/main/java/com/volmit/iris/core/project/loader/IrisRegistrant.java b/src/main/java/com/volmit/iris/core/loader/IrisRegistrant.java similarity index 97% rename from src/main/java/com/volmit/iris/core/project/loader/IrisRegistrant.java rename to src/main/java/com/volmit/iris/core/loader/IrisRegistrant.java index 40072e565..67775dcc2 100644 --- a/src/main/java/com/volmit/iris/core/project/loader/IrisRegistrant.java +++ b/src/main/java/com/volmit/iris/core/loader/IrisRegistrant.java @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package com.volmit.iris.core.project.loader; +package com.volmit.iris.core.loader; import com.volmit.iris.Iris; import com.volmit.iris.engine.object.annotations.ArrayType; diff --git a/src/main/java/com/volmit/iris/core/project/loader/ObjectResourceLoader.java b/src/main/java/com/volmit/iris/core/loader/ObjectResourceLoader.java similarity index 99% rename from src/main/java/com/volmit/iris/core/project/loader/ObjectResourceLoader.java rename to src/main/java/com/volmit/iris/core/loader/ObjectResourceLoader.java index d564af534..92fe42e5c 100644 --- a/src/main/java/com/volmit/iris/core/project/loader/ObjectResourceLoader.java +++ b/src/main/java/com/volmit/iris/core/loader/ObjectResourceLoader.java @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package com.volmit.iris.core.project.loader; +package com.volmit.iris.core.loader; import com.volmit.iris.Iris; import com.volmit.iris.engine.object.objects.IrisObject; diff --git a/src/main/java/com/volmit/iris/core/project/loader/ResourceLoader.java b/src/main/java/com/volmit/iris/core/loader/ResourceLoader.java similarity index 99% rename from src/main/java/com/volmit/iris/core/project/loader/ResourceLoader.java rename to src/main/java/com/volmit/iris/core/loader/ResourceLoader.java index de0f17c77..ec4c10d87 100644 --- a/src/main/java/com/volmit/iris/core/project/loader/ResourceLoader.java +++ b/src/main/java/com/volmit/iris/core/loader/ResourceLoader.java @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package com.volmit.iris.core.project.loader; +package com.volmit.iris.core.loader; import com.google.common.util.concurrent.AtomicDouble; import com.google.gson.Gson; diff --git a/src/main/java/com/volmit/iris/core/project/loader/ScriptResourceLoader.java b/src/main/java/com/volmit/iris/core/loader/ScriptResourceLoader.java similarity index 99% rename from src/main/java/com/volmit/iris/core/project/loader/ScriptResourceLoader.java rename to src/main/java/com/volmit/iris/core/loader/ScriptResourceLoader.java index ac0da6875..2b1117b9e 100644 --- a/src/main/java/com/volmit/iris/core/project/loader/ScriptResourceLoader.java +++ b/src/main/java/com/volmit/iris/core/loader/ScriptResourceLoader.java @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package com.volmit.iris.core.project.loader; +package com.volmit.iris.core.loader; import com.volmit.iris.Iris; import com.volmit.iris.engine.object.common.IrisScript; diff --git a/src/main/java/com/volmit/iris/core/pack/IrisPack.java b/src/main/java/com/volmit/iris/core/pack/IrisPack.java new file mode 100644 index 000000000..b8cbd2fb7 --- /dev/null +++ b/src/main/java/com/volmit/iris/core/pack/IrisPack.java @@ -0,0 +1,383 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.core.pack; + +import com.volmit.iris.Iris; +import com.volmit.iris.core.loader.IrisData; +import com.volmit.iris.core.loader.ResourceLoader; +import com.volmit.iris.core.service.StudioSVC; +import com.volmit.iris.engine.object.common.IrisWorld; +import com.volmit.iris.engine.object.dimensional.IrisDimension; +import com.volmit.iris.util.collection.KList; +import com.volmit.iris.util.exceptions.IrisException; +import com.volmit.iris.util.format.Form; +import com.volmit.iris.util.io.IO; +import com.volmit.iris.util.json.JSONArray; +import com.volmit.iris.util.json.JSONObject; +import com.volmit.iris.util.math.RNG; +import com.volmit.iris.util.plugin.VolmitSender; +import com.volmit.iris.util.scheduling.PrecisionStopwatch; +import lombok.Data; +import org.bukkit.World; +import org.zeroturnaround.zip.commons.FileUtils; + +import java.io.File; +import java.io.IOException; +import java.net.MalformedURLException; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.Future; + +/** + * Represents an Iris pack that exists + */ +@Data +public class IrisPack { + private final File folder; + private final IrisData data; + + /** + * Create an iris pack backed by a data folder + * the data folder is assumed to be in the Iris/packs/NAME folder + * @param name the name + */ + public IrisPack(String name) { + this(packsPack(name)); + } + + /** + * Create an iris pack backed by a data folder + * @param folder the folder of the pack. Must be a directory + */ + public IrisPack(File folder) { + this.folder = folder; + + if(!folder.exists()) + { + throw new RuntimeException("Cannot open Pack " + folder.getPath() + " (directory doesnt exist)"); + } + + if(!folder.isDirectory()) + { + throw new RuntimeException("Cannot open Pack " + folder.getPath() + " (not a directory)"); + } + + this.data = IrisData.get(folder); + } + + /** + * Delete this pack. This invalidates this pack and you should + * probably no longer use this instance after deleting this pack + */ + public void delete() { + IO.delete(folder); + folder.delete(); + } + + /** + * Create a new pack from the input url + * @param sender the sender + * @param url the url, or name, or really anything see IrisPackRepository.from(String) + * @return the iris pack + * @throws IrisException fails + */ + public static Future from(VolmitSender sender, String url) throws IrisException { + IrisPackRepository repo = IrisPackRepository.from(url); + if(repo == null) + { + throw new IrisException("Null Repo"); + } + + try { + return from(sender, repo); + } catch (MalformedURLException e) { + throw new IrisException("Malformed URL " + e.getMessage()); + } + } + + /** + * Get the name of this pack + * @return the pack name + */ + public String getName() + { + return folder.getName(); + } + + /** + * Get the file path of the workspace file + * @return the workspace file path + */ + public File getWorkspaceFile() { + return new File(getFolder(), getName() + ".code-workspace"); + } + + /** + * Update the workspace file + * @return true if it was updated + */ + public boolean updateWorkspace() { + getFolder().mkdirs(); + File ws = getWorkspaceFile(); + + try { + PrecisionStopwatch p = PrecisionStopwatch.start(); + Iris.debug("Building Workspace: " + ws.getPath()); + JSONObject j = generateWorkspaceConfig(); + IO.writeAll(ws, j.toString(4)); + p.end(); + Iris.debug("Building Workspace: " + ws.getPath() + " took " + Form.duration(p.getMilliseconds(), 2)); + return true; + } catch (Throwable e) { + Iris.reportError(e); + Iris.warn("Pack invalid: " + ws.getAbsolutePath() + " Re-creating. You may loose some vs-code workspace settings! But not your actual project!"); + ws.delete(); + try { + IO.writeAll(ws, generateWorkspaceConfig()); + } catch (IOException e1) { + Iris.reportError(e1); + e1.printStackTrace(); + } + } + + return false; + } + + /** + * Install this pack into a world + * @param world the world to install into (world/iris/pack) + * @return the installed pack + */ + public IrisPack install(World world) throws IrisException + { + return install(new File(world.getWorldFolder(), "iris/pack")); + } + + /** + * Install this pack into a world + * @param world the world to install into (world/iris/pack) + * @return the installed pack + */ + public IrisPack install(IrisWorld world) throws IrisException + { + return install(new File(world.worldFolder(), "iris/pack")); + } + + /** + * Install this pack into a world + * @param folder the folder to install this pack into + * @return the installed pack + */ + public IrisPack install(File folder) throws IrisException + { + if(folder.exists()) + { + throw new IrisException("Cannot install new pack because the folder " + folder.getName() + " already exists!"); + } + + folder.mkdirs(); + + try { + FileUtils.copyDirectory(getFolder(), folder); + } catch (IOException e) { + Iris.reportError(e); + } + + return new IrisPack(folder); + } + + /** + * Create a new pack using this pack as a template. The new pack will be renamed & have a renamed dimension + * to match it. + * @param newName the new pack name + * @return the new IrisPack + */ + public IrisPack install(String newName) throws IrisException + { + File newPack = packsPack(newName); + + if(newPack.exists()) + { + throw new IrisException("Cannot install new pack because the folder " + newName + " already exists!"); + } + + try { + FileUtils.copyDirectory(getFolder(), newPack); + } catch (IOException e) { + Iris.reportError(e); + } + + IrisData data = IrisData.get(newPack); + IrisDimension dim = data.getDimensionLoader().load(getDimensionKey()); + data.dump(); + File from = dim.getLoadFile(); + File to = new File(from.getParentFile(), newName + ".json"); + try { + FileUtils.moveFile(from, to); + new File(newPack, getWorkspaceFile().getName()).delete(); + } catch (Throwable e) { + throw new IrisException(e); + } + + IrisPack pack = new IrisPack(newPack); + pack.updateWorkspace(); + + return pack; + } + + /** + * The dimension's assumed loadkey + * @return getName() + */ + public String getDimensionKey() + { + return getName(); + } + + /** + * Get the main dimension object + * @return the dimension (folder name as dim key) + */ + public IrisDimension getDimension() + { + return getData().getDimensionLoader().load(getDimensionKey()); + } + + /** + * Find all files in this pack with the given extension + * @param fileExtension the extension + * @return the list of files + */ + public KList collectFiles(String fileExtension) { + return collectFiles(getFolder(), fileExtension); + } + + private JSONObject generateWorkspaceConfig() { + JSONObject ws = new JSONObject(); + JSONArray folders = new JSONArray(); + JSONObject folder = new JSONObject(); + folder.put("path", "."); + folders.put(folder); + ws.put("folders", folders); + JSONObject settings = new JSONObject(); + settings.put("workbench.colorTheme", "Monokai"); + settings.put("workbench.preferredDarkColorTheme", "Solarized Dark"); + settings.put("workbench.tips.enabled", false); + settings.put("workbench.tree.indent", 24); + settings.put("files.autoSave", "onFocusChange"); + JSONObject jc = new JSONObject(); + jc.put("editor.autoIndent", "brackets"); + jc.put("editor.acceptSuggestionOnEnter", "smart"); + jc.put("editor.cursorSmoothCaretAnimation", true); + jc.put("editor.dragAndDrop", false); + jc.put("files.trimTrailingWhitespace", true); + jc.put("diffEditor.ignoreTrimWhitespace", true); + jc.put("files.trimFinalNewlines", true); + jc.put("editor.suggest.showKeywords", false); + jc.put("editor.suggest.showSnippets", false); + jc.put("editor.suggest.showWords", false); + JSONObject st = new JSONObject(); + st.put("strings", true); + jc.put("editor.quickSuggestions", st); + jc.put("editor.suggest.insertMode", "replace"); + settings.put("[json]", jc); + settings.put("json.maxItemsComputed", 30000); + JSONArray schemas = new JSONArray(); + IrisData dm = IrisData.get(getFolder()); + + for (ResourceLoader r : dm.getLoaders().v()) { + if (r.supportsSchemas()) { + schemas.put(r.buildSchema()); + } + } + + settings.put("json.schemas", schemas); + ws.put("settings", settings); + + return ws; + } + + /** + * Create a pack from a repo + * @param sender the sender + * @param repo the repo + * @return the pack + * @throws MalformedURLException shit happens + */ + public static Future from(VolmitSender sender, IrisPackRepository repo) throws MalformedURLException { + CompletableFuture pack = new CompletableFuture<>(); + repo.install(sender, () -> { + pack.complete(new IrisPack(repo.getRepo())); + }); + return pack; + } + + /** + * Create a blank pack with a given name + * @param name the name of the pack + * @return the pack + * @throws IrisException if the pack already exists or another error + */ + public static IrisPack blank(String name) throws IrisException { + File f = packsPack(name); + + if(f.exists()) + { + throw new IrisException("Already exists"); + } + + File fd = new File(f, "dimensions/" + name + ".json"); + fd.getParentFile().mkdirs(); + try { + IO.writeAll(fd, "{\n" + + " \"name\": \""+Form.capitalize(name)+"\",\n" + + " \"version\": 1\n" + + "}\n"); + } catch (IOException e) { + throw new IrisException(e.getMessage(), e); + } + + IrisPack pack = new IrisPack(f); + pack.updateWorkspace(); + return pack; + } + + /** + * Get a packs pack folder for a name. Such that overworld would resolve as Iris/packs/overworld + * @param name the name + * @return the file path + */ + public static File packsPack(String name) + { + return Iris.instance.getDataFolderNoCreate(StudioSVC.WORKSPACE_NAME, name); + } + + private static KList collectFiles(File f, String fileExtension) { + KList l = new KList<>(); + + if (f.isDirectory()) { + for (File i : f.listFiles()) { + l.addAll(collectFiles(i, fileExtension)); + } + } else if (f.getName().endsWith("." + fileExtension)) { + l.add(f); + } + + return l; + } +} diff --git a/src/main/java/com/volmit/iris/util/data/IrisPackRepository.java b/src/main/java/com/volmit/iris/core/pack/IrisPackRepository.java similarity index 90% rename from src/main/java/com/volmit/iris/util/data/IrisPackRepository.java rename to src/main/java/com/volmit/iris/core/pack/IrisPackRepository.java index 854e68f23..ffe337933 100644 --- a/src/main/java/com/volmit/iris/util/data/IrisPackRepository.java +++ b/src/main/java/com/volmit/iris/core/pack/IrisPackRepository.java @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package com.volmit.iris.util.data; +package com.volmit.iris.core.pack; import com.volmit.iris.Iris; import com.volmit.iris.core.service.StudioSVC; @@ -50,6 +50,11 @@ public class IrisPackRepository { @Builder.Default private String tag = ""; + /** + * + * @param g + * @return + */ public static IrisPackRepository from(String g) { // https://github.com/IrisDimensions/overworld if (g.startsWith("https://github.com/")) { @@ -106,8 +111,8 @@ public class IrisPackRepository { return "https://codeload.github.com/" + user + "/" + repo + "/zip/refs/heads/" + branch; } - public void install(VolmitSender sender) throws MalformedURLException { - File pack = Iris.instance.getDataFolder(StudioSVC.WORKSPACE_NAME, getRepo()); + public void install(VolmitSender sender, Runnable whenComplete) throws MalformedURLException { + File pack = Iris.instance.getDataFolderNoCreate(StudioSVC.WORKSPACE_NAME, getRepo()); if (!pack.exists()) { File dl = new File(Iris.getTemp(), "dltk-" + UUID.randomUUID() + ".zip"); @@ -121,7 +126,12 @@ public class IrisPackRepository { } catch (IOException e) { e.printStackTrace(); } - })).execute(sender); + })).execute(sender, whenComplete); + } + + else + { + sender.sendMessage("Pack already exists!"); } } } diff --git a/src/main/java/com/volmit/iris/core/pregenerator/methods/AsyncPregenMethod.java b/src/main/java/com/volmit/iris/core/pregenerator/methods/AsyncPregenMethod.java index 0c935535c..6ab401be7 100644 --- a/src/main/java/com/volmit/iris/core/pregenerator/methods/AsyncPregenMethod.java +++ b/src/main/java/com/volmit/iris/core/pregenerator/methods/AsyncPregenMethod.java @@ -18,6 +18,7 @@ package com.volmit.iris.core.pregenerator.methods; +import com.volmit.iris.Iris; import com.volmit.iris.core.IrisSettings; import com.volmit.iris.core.pregenerator.PregenListener; import com.volmit.iris.core.pregenerator.PregeneratorMethod; @@ -48,6 +49,11 @@ public class AsyncPregenMethod implements PregeneratorMethod { private void unloadAndSaveAllChunks() { try { J.sfut(() -> { + if (world == null) { + Iris.warn("World was null somehow..."); + return; + } + for (Chunk i : world.getLoadedChunks()) { i.unload(true); } diff --git a/src/main/java/com/volmit/iris/core/project/IrisPack.java b/src/main/java/com/volmit/iris/core/project/IrisPack.java deleted file mode 100644 index 613b654a4..000000000 --- a/src/main/java/com/volmit/iris/core/project/IrisPack.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Iris is a World Generator for Minecraft Bukkit Servers - * Copyright (c) 2021 Arcane Arts (Volmit Software) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.volmit.iris.core.project; - -import com.volmit.iris.Iris; -import com.volmit.iris.core.service.StudioSVC; -import com.volmit.iris.util.data.IrisPackRepository; -import com.volmit.iris.util.io.IO; -import com.volmit.iris.util.plugin.VolmitSender; -import lombok.Data; - -import java.io.File; -import java.net.MalformedURLException; - -@Data -public class IrisPack { - private final File folder; - - public IrisPack(File folder) { - this.folder = folder; - } - - public void delete() { - IO.delete(folder); - folder.delete(); - } - - public static IrisPack from(VolmitSender sender, String url) throws MalformedURLException { - return from(sender, IrisPackRepository.from(url)); - } - - public static IrisPack from(VolmitSender sender, IrisPackRepository repo) throws MalformedURLException { - String name = repo.getRepo(); - String url = repo.toURL(); - repo.install(sender); - - return new IrisPack(Iris.instance.getDataFolder(StudioSVC.WORKSPACE_NAME, repo.getRepo())); - } -} diff --git a/src/main/java/com/volmit/iris/core/project/IrisProject.java b/src/main/java/com/volmit/iris/core/project/IrisProject.java index 35b50adf6..654cbd0bc 100644 --- a/src/main/java/com/volmit/iris/core/project/IrisProject.java +++ b/src/main/java/com/volmit/iris/core/project/IrisProject.java @@ -21,9 +21,9 @@ package com.volmit.iris.core.project; import com.google.gson.Gson; import com.volmit.iris.Iris; import com.volmit.iris.core.IrisSettings; -import com.volmit.iris.core.project.loader.IrisData; -import com.volmit.iris.core.project.loader.IrisRegistrant; -import com.volmit.iris.core.project.loader.ResourceLoader; +import com.volmit.iris.core.loader.IrisData; +import com.volmit.iris.core.loader.IrisRegistrant; +import com.volmit.iris.core.loader.ResourceLoader; import com.volmit.iris.core.tools.IrisToolbelt; import com.volmit.iris.engine.object.biome.IrisBiome; import com.volmit.iris.engine.object.block.IrisBlockData; @@ -56,6 +56,7 @@ import com.volmit.iris.util.scheduling.jobs.ParallelQueueJob; import lombok.Data; import org.bukkit.Bukkit; import org.bukkit.GameMode; +import org.bukkit.World; import org.zeroturnaround.zip.ZipUtil; import java.awt.*; @@ -63,6 +64,7 @@ import java.io.File; import java.io.IOException; import java.util.Objects; import java.util.UUID; +import java.util.function.Consumer; @SuppressWarnings("ALL") @Data @@ -99,12 +101,12 @@ public class IrisProject { } public void open(VolmitSender sender) throws IrisException { - open(sender, 1337, () -> + open(sender, 1337, (w) -> { }); } - public void open(VolmitSender sender, long seed, Runnable onDone) throws IrisException { + public void open(VolmitSender sender, long seed, Consumer onDone) throws IrisException { if (isOpen()) { close(); } @@ -171,13 +173,20 @@ public class IrisProject { }); - J.a(() -> activeProvider = (PlatformChunkGenerator) IrisToolbelt.createWorld() - .seed(seed) - .sender(sender) - .studio(true) - .name("iris/" + UUID.randomUUID()) - .dimension(d.getLoadKey()) - .create().getGenerator()); + J.a(() -> { + try { + activeProvider = (PlatformChunkGenerator) IrisToolbelt.createWorld() + .seed(seed) + .sender(sender) + .studio(true) + .name("iris/" + UUID.randomUUID()) + .dimension(d.getLoadKey()) + .create().getGenerator(); + onDone.accept(activeProvider.getTarget().getWorld().realWorld()); + } catch (IrisException e) { + e.printStackTrace(); + } + }); } public void close() { diff --git a/src/main/java/com/volmit/iris/core/project/SchemaBuilder.java b/src/main/java/com/volmit/iris/core/project/SchemaBuilder.java index 609ca038e..52f854ca0 100644 --- a/src/main/java/com/volmit/iris/core/project/SchemaBuilder.java +++ b/src/main/java/com/volmit/iris/core/project/SchemaBuilder.java @@ -19,9 +19,9 @@ package com.volmit.iris.core.project; import com.volmit.iris.Iris; -import com.volmit.iris.core.project.loader.IrisData; -import com.volmit.iris.core.project.loader.IrisRegistrant; -import com.volmit.iris.core.project.loader.ResourceLoader; +import com.volmit.iris.core.loader.IrisData; +import com.volmit.iris.core.loader.IrisRegistrant; +import com.volmit.iris.core.loader.ResourceLoader; import com.volmit.iris.engine.object.annotations.*; import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.collection.KMap; diff --git a/src/main/java/com/volmit/iris/core/service/BoardSVC.java b/src/main/java/com/volmit/iris/core/service/BoardSVC.java index 192d86753..f8c76991e 100644 --- a/src/main/java/com/volmit/iris/core/service/BoardSVC.java +++ b/src/main/java/com/volmit/iris/core/service/BoardSVC.java @@ -19,7 +19,7 @@ package com.volmit.iris.core.service; import com.volmit.iris.Iris; -import com.volmit.iris.core.project.loader.IrisData; +import com.volmit.iris.core.loader.IrisData; import com.volmit.iris.core.tools.IrisToolbelt; import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.object.feature.IrisFeaturePositional; @@ -149,7 +149,7 @@ public class BoardSVC implements IrisService, BoardProvider { if (Iris.jobCount() > 0) { v.add("&7&m------------------"); - v.add(C.LIGHT_PURPLE + "Tasks" + C.GRAY + ": " + Iris.jobCount()); + v.add(C.LIGHT_PURPLE + "Tasks" + C.GRAY + ": " + Form.f(Iris.jobCount())); } v.add("&7&m------------------"); diff --git a/src/main/java/com/volmit/iris/core/service/PreservationSVC.java b/src/main/java/com/volmit/iris/core/service/PreservationSVC.java index c08eb871b..814104076 100644 --- a/src/main/java/com/volmit/iris/core/service/PreservationSVC.java +++ b/src/main/java/com/volmit/iris/core/service/PreservationSVC.java @@ -19,7 +19,7 @@ package com.volmit.iris.core.service; import com.volmit.iris.Iris; -import com.volmit.iris.core.project.loader.IrisData; +import com.volmit.iris.core.loader.IrisData; import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.context.IrisContext; import com.volmit.iris.util.parallel.MultiBurst; diff --git a/src/main/java/com/volmit/iris/core/service/StudioSVC.java b/src/main/java/com/volmit/iris/core/service/StudioSVC.java index 8b28a45c1..aad2a367e 100644 --- a/src/main/java/com/volmit/iris/core/service/StudioSVC.java +++ b/src/main/java/com/volmit/iris/core/service/StudioSVC.java @@ -21,8 +21,10 @@ package com.volmit.iris.core.service; import com.google.gson.Gson; import com.google.gson.JsonSyntaxException; import com.volmit.iris.Iris; +import com.volmit.iris.core.IrisSettings; +import com.volmit.iris.core.pack.IrisPack; import com.volmit.iris.core.project.IrisProject; -import com.volmit.iris.core.project.loader.IrisData; +import com.volmit.iris.core.loader.IrisData; import com.volmit.iris.core.tools.IrisToolbelt; import com.volmit.iris.engine.data.cache.AtomicCache; import com.volmit.iris.engine.object.dimensional.IrisDimension; @@ -43,6 +45,7 @@ import org.zeroturnaround.zip.commons.FileUtils; import java.io.File; import java.io.IOException; import java.util.UUID; +import java.util.function.Consumer; public class StudioSVC implements IrisService { public static final String LISTING = "https://raw.githubusercontent.com/IrisDimensions/_listing/main/listing-v2.json"; @@ -53,19 +56,14 @@ public class StudioSVC implements IrisService { @Override public void onEnable() { - J.a(() -> - { - File ignore = getWorkspaceFile(".gitignore"); + J.a(() -> { + String pack = IrisSettings.get().getGenerator().getDefaultWorldType(); + File f = IrisPack.packsPack(pack); - if (!ignore.exists()) { - File m = Iris.getCached("Pack Ignore (.gitignore)", "https://raw.githubusercontent.com/VolmitSoftware/Iris/master/packignore.ignore"); - if (m != null) { - try { - IO.copyFile(m, ignore); - } catch (IOException e) { - Iris.reportError(e); - } - } + if(!f.exists()) + { + Iris.info("Downloading Default Pack " + pack); + downloadSearch(Iris.getSender(), pack, false); } }); } @@ -325,7 +323,7 @@ public class StudioSVC implements IrisService { public void open(VolmitSender sender, long seed, String dimm) { try { - open(sender, seed, dimm, () -> { + open(sender, seed, dimm, (w) -> { }); } catch (Exception e) { Iris.reportError(e); @@ -334,7 +332,7 @@ public class StudioSVC implements IrisService { } } - public void open(VolmitSender sender, long seed, String dimm, Runnable onDone) throws IrisException { + public void open(VolmitSender sender, long seed, String dimm, Consumer onDone) throws IrisException { if (isProjectOpen()) { close(); } diff --git a/src/main/java/com/volmit/iris/core/service/TreeSVC.java b/src/main/java/com/volmit/iris/core/service/TreeSVC.java index 3af45a961..d9de6c334 100644 --- a/src/main/java/com/volmit/iris/core/service/TreeSVC.java +++ b/src/main/java/com/volmit/iris/core/service/TreeSVC.java @@ -19,7 +19,7 @@ package com.volmit.iris.core.service; import com.volmit.iris.Iris; -import com.volmit.iris.core.project.loader.IrisData; +import com.volmit.iris.core.loader.IrisData; import com.volmit.iris.core.tools.IrisToolbelt; import com.volmit.iris.engine.object.biome.IrisBiome; import com.volmit.iris.engine.object.common.IObjectPlacer; diff --git a/src/main/java/com/volmit/iris/core/tools/IrisToolbelt.java b/src/main/java/com/volmit/iris/core/tools/IrisToolbelt.java index 72954d893..ca56fa39a 100644 --- a/src/main/java/com/volmit/iris/core/tools/IrisToolbelt.java +++ b/src/main/java/com/volmit/iris/core/tools/IrisToolbelt.java @@ -25,7 +25,7 @@ import com.volmit.iris.core.pregenerator.PregenTask; import com.volmit.iris.core.pregenerator.PregeneratorMethod; import com.volmit.iris.core.pregenerator.methods.HeadlessPregenMethod; import com.volmit.iris.core.pregenerator.methods.HybridPregenMethod; -import com.volmit.iris.core.project.loader.IrisData; +import com.volmit.iris.core.loader.IrisData; import com.volmit.iris.core.service.StudioSVC; import com.volmit.iris.engine.object.dimensional.IrisDimension; import com.volmit.iris.engine.platform.HeadlessGenerator; diff --git a/src/main/java/com/volmit/iris/core/tools/IrisWorldCreator.java b/src/main/java/com/volmit/iris/core/tools/IrisWorldCreator.java index be4e718a4..447cb1ccd 100644 --- a/src/main/java/com/volmit/iris/core/tools/IrisWorldCreator.java +++ b/src/main/java/com/volmit/iris/core/tools/IrisWorldCreator.java @@ -18,7 +18,7 @@ package com.volmit.iris.core.tools; -import com.volmit.iris.core.project.loader.IrisData; +import com.volmit.iris.core.loader.IrisData; import com.volmit.iris.engine.object.common.IrisWorld; import com.volmit.iris.engine.object.dimensional.IrisDimension; import com.volmit.iris.engine.platform.BukkitChunkGenerator; diff --git a/src/main/java/com/volmit/iris/engine/IrisComplex.java b/src/main/java/com/volmit/iris/engine/IrisComplex.java index 6b1a9394b..ef3b9a53a 100644 --- a/src/main/java/com/volmit/iris/engine/IrisComplex.java +++ b/src/main/java/com/volmit/iris/engine/IrisComplex.java @@ -20,10 +20,9 @@ package com.volmit.iris.engine; import com.google.common.util.concurrent.AtomicDouble; import com.volmit.iris.Iris; -import com.volmit.iris.core.project.loader.IrisData; +import com.volmit.iris.core.loader.IrisData; import com.volmit.iris.engine.actuator.IrisTerrainNormalActuator; import com.volmit.iris.engine.framework.Engine; -import com.volmit.iris.engine.modifier.IrisCaveModifier; import com.volmit.iris.engine.object.biome.InferredType; import com.volmit.iris.engine.object.biome.IrisBiome; import com.volmit.iris.engine.object.common.CaveResult; @@ -76,6 +75,7 @@ public class IrisComplex implements DataProvider { private ProceduralStream overlayStream; private ProceduralStream heightFluidStream; private ProceduralStream trueHeightStream; + private ProceduralStream trueHeightStreamNoFeatures; private ProceduralStream slopeStream; private ProceduralStream topSurfaceStream; private ProceduralStream rngStream; @@ -102,8 +102,6 @@ public class IrisComplex implements DataProvider { case SHORE: return shoreBiomeStream; case DEFER: - case LAKE: - case RIVER: default: break; } @@ -217,16 +215,12 @@ public class IrisComplex implements DataProvider { }, Interpolated.DOUBLE).clamp(0, engine.getHeight()).cache2D(cacheSize); slopeStream = heightStream.slope(3).cache2D(cacheSize); objectChanceStream = ProceduralStream.ofDouble((x, z) -> { - if (engine.getDimension().hasFeatures(engine)) { - AtomicDouble str = new AtomicDouble(1D); - for (IrisFeaturePositional i : engine.getMantle().forEachFeature(x, z)) { - str.set(Math.min(str.get(), i.getObjectChanceModifier(x, z, rng, getData()))); - } - - return str.get(); + AtomicDouble str = new AtomicDouble(1D); + for (IrisFeaturePositional i : engine.getMantle().forEachFeature(x, z)) { + str.set(Math.min(str.get(), i.getObjectChanceModifier(x, z, rng, getData()))); } - return 1D; + return str.get(); }); trueBiomeStream = focus != null ? ProceduralStream.of((x, y) -> focus, Interpolated.of(a -> 0D, b -> focus)).convertAware2D((b, x, z) -> { @@ -315,32 +309,16 @@ public class IrisComplex implements DataProvider { trueHeightStream = ProceduralStream.of((x, z) -> { int rx = (int) Math.round(engine.modifyX(x)); int rz = (int) Math.round(engine.modifyZ(z)); - int heightf = (int) Math.round(getHeightStream().get(rx, rz)); +// TODO CAVE STUFF + return (int) Math.round(getHeightStream().get(rx, rz)); + }, Interpolated.INT).cache2D(cacheSize); + + trueHeightStreamNoFeatures = ProceduralStream.of((x, z) -> { + int rx = (int) Math.round(engine.modifyX(x)); + int rz = (int) Math.round(engine.modifyZ(z)); + int heightf = (int) Math.round(getHeightStreamNoFeatures().get(rx, rz)); int m = heightf; - - if (engine.getDimension().isCarved(getData(), rx, m, rz, ((IrisTerrainNormalActuator) engine.getTerrainActuator()).getRng(), heightf)) { - m--; - - while (engine.getDimension().isCarved(getData(), rx, m, rz, ((IrisTerrainNormalActuator) engine.getTerrainActuator()).getRng(), heightf)) { - m--; - } - } - - if (engine.getDimension().isCaves()) { - KList caves = ((IrisCaveModifier) engine.getCaveModifier()).genCaves(rx, rz, 0, 0, null); - boolean again = true; - - while (again) { - again = false; - for (CaveResult i : caves) { - if (i.getCeiling() > m && i.getFloor() < m) { - m = i.getFloor(); - again = true; - } - } - } - } - +// TODO CAVE STUFF return m; }, Interpolated.INT).cache2D(cacheSize); baseBiomeIDStream = trueBiomeStream.convertAware2D((b, x, z) -> { @@ -427,9 +405,7 @@ public class IrisComplex implements DataProvider { AtomicDouble noise = new AtomicDouble(h + fluidHeight + overlayStream.get(x, z)); if (features) { - List p = engine.getMantle().forEachFeature(x, z); - - for (IrisFeaturePositional i : p) { + for (IrisFeaturePositional i : engine.getMantle().forEachFeature(x, z)) { noise.set(i.filter(x, z, noise.get(), rng, getData())); } } diff --git a/src/main/java/com/volmit/iris/engine/IrisEngine.java b/src/main/java/com/volmit/iris/engine/IrisEngine.java index 575fd0fbb..fdc03cff9 100644 --- a/src/main/java/com/volmit/iris/engine/IrisEngine.java +++ b/src/main/java/com/volmit/iris/engine/IrisEngine.java @@ -30,10 +30,9 @@ import com.volmit.iris.engine.actuator.IrisTerrainNormalActuator; import com.volmit.iris.engine.data.cache.AtomicCache; import com.volmit.iris.engine.framework.*; import com.volmit.iris.engine.mantle.EngineMantle; -import com.volmit.iris.engine.modifier.IrisCaveModifier; +import com.volmit.iris.engine.modifier.IrisCarveModifier; import com.volmit.iris.engine.modifier.IrisDepositModifier; import com.volmit.iris.engine.modifier.IrisPostModifier; -import com.volmit.iris.engine.modifier.IrisRavineModifier; import com.volmit.iris.engine.object.biome.IrisBiome; import com.volmit.iris.engine.object.biome.IrisBiomePaletteLayer; import com.volmit.iris.engine.object.decoration.IrisDecorator; @@ -68,7 +67,6 @@ import java.util.concurrent.atomic.AtomicLong; @Data public class IrisEngine implements Engine { - // TODO: Remove block population, stop using bukkit private final AtomicInteger generated; private final AtomicInteger generatedLast; private final AtomicDouble perSecond; @@ -98,7 +96,6 @@ public class IrisEngine implements Engine { private EngineActuator biomeActuator; private EngineModifier depositModifier; private EngineModifier caveModifier; - private EngineModifier ravineModifier; private EngineModifier postModifier; private final AtomicCache engineData = new AtomicCache<>(); private final AtomicBoolean cleaning; @@ -145,7 +142,6 @@ public class IrisEngine implements Engine { decorantActuator.close(); biomeActuator.close(); depositModifier.close(); - ravineModifier.close(); caveModifier.close(); postModifier.close(); effects.close(); @@ -162,9 +158,8 @@ public class IrisEngine implements Engine { decorantActuator = new IrisDecorantActuator(this); biomeActuator = new IrisBiomeActuator(this); depositModifier = new IrisDepositModifier(this); - ravineModifier = new IrisRavineModifier(this); - caveModifier = new IrisCaveModifier(this); postModifier = new IrisPostModifier(this); + caveModifier = new IrisCarveModifier(this); effects = new IrisEngineEffects(this); J.a(this::computeBiomeMaxes); } catch (Throwable e) { @@ -177,12 +172,21 @@ public class IrisEngine implements Engine { @Override public void hotload() { + hotloadSilently(); + Iris.callEvent(new IrisEngineHotloadEvent(this)); + } + + public void hotloadComplex() { + complex.close(); + complex = new IrisComplex(this); + } + + public void hotloadSilently() { getData().dump(); getData().clearLists(); getTarget().setDimension(getData().getDimensionLoader().load(getDimension().getLoadKey())); prehotload(); setupEngine(); - Iris.callEvent(new IrisEngineHotloadEvent(this)); } @Override @@ -332,9 +336,8 @@ public class IrisEngine implements Engine { getDecorantActuator().close(); getBiomeActuator().close(); getDepositModifier().close(); - getRavineModifier().close(); - getCaveModifier().close(); getPostModifier().close(); + getCaveModifier().close(); getMantle().close(); getComplex().close(); getData().dump(); @@ -407,21 +410,14 @@ public class IrisEngine implements Engine { } } } else { - getMantle().generateMatter(x >> 4, z >> 4, true); - burst().burst(multicore, - () -> getTerrainActuator().actuate(x, z, vblocks, multicore), - () -> getBiomeActuator().actuate(x, z, vbiomes, multicore) - ); - burst().burst(multicore, - () -> getCaveModifier().modify(x, z, vblocks, multicore), - () -> getDecorantActuator().actuate(x, z, blocks, multicore), - () -> getRavineModifier().modify(x, z, vblocks, multicore) - ); - getPostModifier().modify(x, z, vblocks, multicore); - burst().burst(multicore, - () -> getMantle().insertMatter(x >> 4, z >> 4, BlockData.class, blocks, true), - () -> getDepositModifier().modify(x, z, vblocks, multicore) - ); + getMantle().generateMatter(x >> 4, z >> 4, multicore); + getTerrainActuator().actuate(x, z, blocks, multicore); + getBiomeActuator().actuate(x, z, vbiomes, multicore); + getDecorantActuator().actuate(x, z, blocks, multicore); + getPostModifier().modify(x, z, blocks, multicore); + getDepositModifier().modify(x, z, blocks, multicore); + getCaveModifier().modify(x >> 4,z >> 4, blocks, multicore); + getMantle().insertMatter(x >> 4, z >> 4, BlockData.class, blocks, multicore); } getMetrics().getTotal().put(p.getMilliseconds()); generated.incrementAndGet(); diff --git a/src/main/java/com/volmit/iris/engine/IrisEngineMantle.java b/src/main/java/com/volmit/iris/engine/IrisEngineMantle.java index 4ae977893..894c9d561 100644 --- a/src/main/java/com/volmit/iris/engine/IrisEngineMantle.java +++ b/src/main/java/com/volmit/iris/engine/IrisEngineMantle.java @@ -23,10 +23,12 @@ import com.volmit.iris.engine.data.cache.AtomicCache; import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.mantle.EngineMantle; import com.volmit.iris.engine.mantle.MantleComponent; +import com.volmit.iris.engine.mantle.components.MantleCarvingComponent; import com.volmit.iris.engine.mantle.components.MantleFeatureComponent; import com.volmit.iris.engine.mantle.components.MantleJigsawComponent; import com.volmit.iris.engine.mantle.components.MantleObjectComponent; import com.volmit.iris.engine.object.biome.IrisBiome; +import com.volmit.iris.engine.object.carving.IrisCarving; import com.volmit.iris.engine.object.deposits.IrisDepositGenerator; import com.volmit.iris.engine.object.feature.IrisFeaturePotential; import com.volmit.iris.engine.object.jigsaw.IrisJigsawStructurePlacement; @@ -61,6 +63,7 @@ public class IrisEngineMantle implements EngineMantle { this.mantle = new Mantle(new File(engine.getWorld().worldFolder(), "mantle"), engine.getTarget().getHeight()); radius = radCache.aquire(this::computeParallaxSize); components = new KList<>(); + registerComponent(new MantleCarvingComponent(this)); registerComponent(new MantleFeatureComponent(this)); registerComponent(new MantleJigsawComponent(this)); registerComponent(new MantleObjectComponent(this)); @@ -174,7 +177,6 @@ public class IrisEngineMantle implements EngineMantle { jig = Math.max(jig, getData().getJigsawStructureLoader().load(getEngine().getDimension().getStronghold()).getMaxDimension()); } catch (Throwable e) { Iris.reportError(e); - Iris.error("THIS IS THE ONE"); e.printStackTrace(); } } @@ -294,15 +296,36 @@ public class IrisEngineMantle implements EngineMantle { x = Math.max(z, x); int u = x; int v = computeFeatureRange(); + int c = computeCarvingRange(); x = Math.max(jig, x); x = Math.max(x, v); + x = Math.max(x, c); x = (Math.max(x, 16) + 16) >> 4; x = x % 2 == 0 ? x + 1 : x; Iris.info("Parallax Size: " + x + " Chunks"); - Iris.info(" Object Parallax Size: " + u + " (" + ((Math.max(u, 16) + 16) >> 4) + ")"); - Iris.info(" Jigsaw Parallax Size: " + jig + " (" + ((Math.max(jig, 16) + 16) >> 4) + ")"); - Iris.info(" Feature Parallax Size: " + v + " (" + ((Math.max(v, 16) + 16) >> 4) + ")"); + Iris.info(" Object Mantle Size: " + u + " (" + ((Math.max(u, 16) + 16) >> 4) + ")"); + Iris.info(" Jigsaw Mantle Size: " + jig + " (" + ((Math.max(jig, 16) + 16) >> 4) + ")"); + Iris.info(" Feature Mantle Size: " + v + " (" + ((Math.max(v, 16) + 16) >> 4) + ")"); + Iris.info(" Carving Mantle Size: " + c + " (" + ((Math.max(c, 16) + 16) >> 4) + ")"); return x; } + + private int computeCarvingRange() { + int m = 0; + + m = Math.max(m, getDimension().getCarving().getMaxRange(getData())); + + for(IrisRegion i : getDimension().getAllRegions(getEngine())) + { + m = Math.max(m, i.getCarving().getMaxRange(getData())); + } + + for(IrisBiome i : getDimension().getAllBiomes(getEngine())) + { + m = Math.max(m, i.getCarving().getMaxRange(getData())); + } + + return m; + } } diff --git a/src/main/java/com/volmit/iris/engine/IrisWorldManager.java b/src/main/java/com/volmit/iris/engine/IrisWorldManager.java index f9d261d46..4bac6040a 100644 --- a/src/main/java/com/volmit/iris/engine/IrisWorldManager.java +++ b/src/main/java/com/volmit/iris/engine/IrisWorldManager.java @@ -34,6 +34,8 @@ import com.volmit.iris.engine.object.spawners.IrisSpawner; import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.collection.KMap; import com.volmit.iris.util.format.Form; +import com.volmit.iris.util.mantle.Mantle; +import com.volmit.iris.util.mantle.MantleFlag; import com.volmit.iris.util.math.M; import com.volmit.iris.util.math.RNG; import com.volmit.iris.util.scheduling.ChronoLatch; @@ -60,6 +62,7 @@ public class IrisWorldManager extends EngineAssignedWorldManager { private final Looper looper; private final int id; private final KMap chunkCooldowns; + private final KList updateQueue = new KList<>(); private double energy = 25; private int entityCount = 0; private final ChronoLatch cl; @@ -140,7 +143,7 @@ public class IrisWorldManager extends EngineAssignedWorldManager { onAsyncTick(); } - return 50; + return 250; } }; looper.setPriority(Thread.MIN_PRIORITY); @@ -150,10 +153,18 @@ public class IrisWorldManager extends EngineAssignedWorldManager { private void updateChunks() { for (Player i : getEngine().getWorld().realWorld().getPlayers()) { - J.s(() -> { - Chunk c = i.getLocation().getChunk(); - J.a(() -> getEngine().updateChunk(c)); - }, RNG.r.i(0, 5)); + int r = 2; + Chunk c = i.getLocation().getChunk(); + for(int x = -r; x <= r; x++) + { + for(int z = -r; z <= r; z++) + { + if(c.getWorld().isChunkLoaded(c.getX() + x, c.getZ() + z)) + { + getEngine().updateChunk(c.getWorld().getChunkAt(c.getX() + x, c.getZ() + z)); + } + } + } } } @@ -221,6 +232,10 @@ public class IrisWorldManager extends EngineAssignedWorldManager { } private void spawnIn(Chunk c, boolean initial) { + if (initial) { + energy += 1.2; + } + IrisBiome biome = getEngine().getSurfaceBiome(c); IrisRegion region = getEngine().getRegion(c); //@builder @@ -362,14 +377,18 @@ public class IrisWorldManager extends EngineAssignedWorldManager { @Override public void onChunkLoad(Chunk e, boolean generated) { - if (generated) { - energy += 1.2; - J.a(() -> spawnIn(e, true), RNG.r.i(5, 50)); - } else { - energy += 0.3; - } - + J.a(() -> getMantle().raiseFlag(e.getX(), e.getZ(), MantleFlag.INITIAL_SPAWNED, + () -> J.a(() -> spawnIn(e, true), RNG.r.i(5, 200)))); + energy += 0.3; fixEnergy(); + if(!getMantle().hasFlag(e.getX(), e.getZ(), MantleFlag.UPDATE)) + { + J.a(() -> getEngine().updateChunk(e),20); + } + } + + public Mantle getMantle() { + return getEngine().getMantle().getMantle(); } @Override @@ -384,36 +403,14 @@ public class IrisWorldManager extends EngineAssignedWorldManager { Runnable drop = () -> J.s(() -> d.forEach((i) -> e.getBlock().getWorld().dropItemNaturally(e.getBlock().getLocation().clone().add(0.5, 0.5, 0.5), i))); IrisBiome b = getEngine().getBiome(e.getBlock().getLocation()); - for (IrisBlockDrops i : b.getBlockDrops()) { - if (i.shouldDropFor(e.getBlock().getBlockData(), getData())) { - if (i.isReplaceVanillaDrops()) { - e.setDropItems(false); - } - - i.fillDrops(false, d); - - if (i.isSkipParents()) { - drop.run(); - return; - } - } + if (dropItems(e, d, drop, b.getBlockDrops(), b)) { + return; } IrisRegion r = getEngine().getRegion(e.getBlock().getLocation()); - for (IrisBlockDrops i : r.getBlockDrops()) { - if (i.shouldDropFor(e.getBlock().getBlockData(), getData())) { - if (i.isReplaceVanillaDrops()) { - e.setDropItems(false); - } - - i.fillDrops(false, d); - - if (i.isSkipParents()) { - drop.run(); - return; - } - } + if (dropItems(e, d, drop, r.getBlockDrops(), b)) { + return; } for (IrisBlockDrops i : getEngine().getDimension().getBlockDrops()) { @@ -433,6 +430,24 @@ public class IrisWorldManager extends EngineAssignedWorldManager { } } + private boolean dropItems(BlockBreakEvent e, KList d, Runnable drop, KList blockDrops, IrisBiome b) { + for (IrisBlockDrops i : blockDrops) { + if (i.shouldDropFor(e.getBlock().getBlockData(), getData())) { + if (i.isReplaceVanillaDrops()) { + e.setDropItems(false); + } + + i.fillDrops(false, d); + + if (i.isSkipParents()) { + drop.run(); + return true; + } + } + } + return false; + } + @Override public void onBlockPlace(BlockPlaceEvent e) { diff --git a/src/main/java/com/volmit/iris/engine/actuator/IrisBiomeActuator.java b/src/main/java/com/volmit/iris/engine/actuator/IrisBiomeActuator.java index 5871fd383..45cd6dc49 100644 --- a/src/main/java/com/volmit/iris/engine/actuator/IrisBiomeActuator.java +++ b/src/main/java/com/volmit/iris/engine/actuator/IrisBiomeActuator.java @@ -55,8 +55,7 @@ public class IrisBiomeActuator extends EngineAssignedActuator { return true; } } catch (Throwable e) { - e.printStackTrace(); - Iris.reportError(e); + } return false; diff --git a/src/main/java/com/volmit/iris/engine/actuator/IrisDecorantActuator.java b/src/main/java/com/volmit/iris/engine/actuator/IrisDecorantActuator.java index b4ce3231b..30b06bd02 100644 --- a/src/main/java/com/volmit/iris/engine/actuator/IrisDecorantActuator.java +++ b/src/main/java/com/volmit/iris/engine/actuator/IrisDecorantActuator.java @@ -23,7 +23,6 @@ import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.framework.EngineAssignedActuator; import com.volmit.iris.engine.framework.EngineDecorator; import com.volmit.iris.engine.object.biome.IrisBiome; -import com.volmit.iris.engine.object.carve.IrisCaveLayer; import com.volmit.iris.util.documentation.BlockCoordinates; import com.volmit.iris.util.hunk.Hunk; import com.volmit.iris.util.math.RNG; @@ -38,7 +37,6 @@ import java.util.function.Predicate; public class IrisDecorantActuator extends EngineAssignedActuator { private static final Predicate PREDICATE_SOLID = (b) -> b != null && !b.getMaterial().isAir() && !b.getMaterial().equals(Material.WATER) && !b.getMaterial().equals(Material.LAVA); - private final BiPredicate PREDICATE_CAVELIQUID; private final RNG rng; @Getter private final EngineDecorator surfaceDecorator; @@ -61,22 +59,6 @@ public class IrisDecorantActuator extends EngineAssignedActuator { seaSurfaceDecorator = new IrisSeaSurfaceDecorator(getEngine()); shoreLineDecorator = new IrisShoreLineDecorator(getEngine()); seaFloorDecorator = new IrisSeaFloorDecorator(getEngine()); - - PREDICATE_CAVELIQUID = (b, y) -> { - for (IrisCaveLayer layer : getEngine().getDimension().getCaveLayers()) { - if (!layer.getFluid().hasFluid(getData())) { - continue; - } - - if (layer.getFluid().isInverseHeight() && y >= layer.getFluid().getFluidHeight()) { - if (b.matches(layer.getFluid().getFluid(getData()))) return true; - } else if (!layer.getFluid().isInverseHeight() && y <= layer.getFluid().getFluidHeight()) { - if (b.matches(layer.getFluid().getFluid(getData()))) return true; - } - } - return false; - }; - } @BlockCoordinates @@ -97,9 +79,8 @@ public class IrisDecorantActuator extends EngineAssignedActuator { int realZ; IrisBiome biome, cave; for (int j = 0; j < output.getDepth(); j++) { - boolean solid, liquid; + boolean solid; int emptyFor = 0; - int liquidFor = 0; int lastSolid = 0; realZ = (int) Math.round(modZ(z + j)); height = (int) Math.round(getComplex().getHeightStream().get(realX, realZ)); @@ -133,24 +114,16 @@ public class IrisDecorantActuator extends EngineAssignedActuator { if (cave != null && cave.getDecorators().isNotEmpty()) { for (int k = height; k > 0; k--) { solid = PREDICATE_SOLID.test(output.get(finalI, k, j)); - liquid = PREDICATE_CAVELIQUID.test(output.get(finalI, k + 1, j), k + 1); if (solid) { if (emptyFor > 0) { - if (liquid) { - getSeaFloorDecorator().decorate(finalI, j, realX, realZ, output, cave, k + 1, liquidFor + lastSolid - emptyFor + 1); - getSeaSurfaceDecorator().decorate(finalI, j, realX, realZ, output, cave, k + liquidFor + 1, emptyFor - liquidFor + lastSolid); - } else { - getSurfaceDecorator().decorate(finalI, j, realX, realZ, output, cave, k, lastSolid); - getCeilingDecorator().decorate(finalI, j, realX, realZ, output, cave, lastSolid - 1, emptyFor); - } + getSurfaceDecorator().decorate(finalI, j, realX, realZ, output, cave, k, lastSolid); + getCeilingDecorator().decorate(finalI, j, realX, realZ, output, cave, lastSolid - 1, emptyFor); emptyFor = 0; - liquidFor = 0; } lastSolid = k; } else { emptyFor++; - if (liquid) liquidFor++; } } } @@ -164,6 +137,6 @@ public class IrisDecorantActuator extends EngineAssignedActuator { } private boolean shouldRayDecorate() { - return getEngine().getDimension().isCarving() || getEngine().getDimension().isCaves() || getEngine().getDimension().isRavines(); + return false; // TODO CAVES } } diff --git a/src/main/java/com/volmit/iris/engine/actuator/IrisTerrainNormalActuator.java b/src/main/java/com/volmit/iris/engine/actuator/IrisTerrainNormalActuator.java index 09dce9310..8a30af604 100644 --- a/src/main/java/com/volmit/iris/engine/actuator/IrisTerrainNormalActuator.java +++ b/src/main/java/com/volmit/iris/engine/actuator/IrisTerrainNormalActuator.java @@ -38,14 +38,12 @@ public class IrisTerrainNormalActuator extends EngineAssignedActuator private static final BlockData CAVE_AIR = Material.CAVE_AIR.createBlockData(); @Getter private final RNG rng; - private final boolean carving; @Getter private int lastBedrock = -1; public IrisTerrainNormalActuator(Engine engine) { super(engine, "Terrain"); rng = new RNG(engine.getWorld().seed()); - carving = getDimension().isCarving() && getDimension().getCarveLayers().isNotEmpty(); } @BlockCoordinates @@ -109,14 +107,6 @@ public class IrisTerrainNormalActuator extends EngineAssignedActuator } } - if (carving && getDimension().isCarved(getData(), realX, i, realZ, rng, he)) { - continue; - } - - if (getDimension().getCaverns() != null && getDimension().getCaverns().isCavern(rng, realX, i, realZ, he, getData())) { - continue; - } - if (i > he && i <= hf) { fdepth = hf - i; diff --git a/src/main/java/com/volmit/iris/engine/data/chunk/LinkedTerrainChunk.java b/src/main/java/com/volmit/iris/engine/data/chunk/LinkedTerrainChunk.java index a3f62ee25..f82dde7f8 100644 --- a/src/main/java/com/volmit/iris/engine/data/chunk/LinkedTerrainChunk.java +++ b/src/main/java/com/volmit/iris/engine/data/chunk/LinkedTerrainChunk.java @@ -21,6 +21,7 @@ package com.volmit.iris.engine.data.chunk; import com.volmit.iris.core.nms.BiomeBaseInjector; import com.volmit.iris.core.nms.INMS; import com.volmit.iris.util.data.IrisBiomeStorage; +import lombok.Setter; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.World; @@ -35,6 +36,8 @@ public class LinkedTerrainChunk implements TerrainChunk { private final IrisBiomeStorage biome3D; private ChunkData rawChunkData; private final BiomeGrid storage; + @Setter + private boolean unsafe = false; public LinkedTerrainChunk(World world) { this(null, Bukkit.createChunkData(world)); @@ -52,6 +55,12 @@ public class LinkedTerrainChunk implements TerrainChunk { @Override public BiomeBaseInjector getBiomeBaseInjector() { + + if (unsafe) { + return (a, b, c, d) -> { + }; + } + return (x, y, z, bb) -> INMS.get().forceBiomeInto(x, y, z, bb, storage); } diff --git a/src/main/java/com/volmit/iris/engine/data/chunk/TerrainChunk.java b/src/main/java/com/volmit/iris/engine/data/chunk/TerrainChunk.java index 8cda901cd..62c64b4e2 100644 --- a/src/main/java/com/volmit/iris/engine/data/chunk/TerrainChunk.java +++ b/src/main/java/com/volmit/iris/engine/data/chunk/TerrainChunk.java @@ -34,6 +34,12 @@ public interface TerrainChunk extends BiomeGrid, ChunkData { return new LinkedTerrainChunk(world, grid); } + static TerrainChunk createUnsafe(World world, BiomeGrid grid) { + LinkedTerrainChunk ltc = new LinkedTerrainChunk(world, grid); + ltc.setUnsafe(true); + return ltc; + } + static TerrainChunk create(ChunkData raw, BiomeGrid grid) { return new LinkedTerrainChunk(grid, raw); } diff --git a/src/main/java/com/volmit/iris/engine/framework/Engine.java b/src/main/java/com/volmit/iris/engine/framework/Engine.java index a10ae8e6d..0b8a01d37 100644 --- a/src/main/java/com/volmit/iris/engine/framework/Engine.java +++ b/src/main/java/com/volmit/iris/engine/framework/Engine.java @@ -21,9 +21,10 @@ package com.volmit.iris.engine.framework; import com.volmit.iris.Iris; import com.volmit.iris.core.gui.components.RenderType; import com.volmit.iris.core.gui.components.Renderer; -import com.volmit.iris.core.project.loader.IrisData; +import com.volmit.iris.core.loader.IrisData; import com.volmit.iris.engine.IrisComplex; import com.volmit.iris.engine.data.cache.Cache; +import com.volmit.iris.engine.data.chunk.TerrainChunk; import com.volmit.iris.engine.mantle.EngineMantle; import com.volmit.iris.engine.object.basic.IrisColor; import com.volmit.iris.engine.object.basic.IrisPosition; @@ -45,12 +46,16 @@ import com.volmit.iris.util.data.B; import com.volmit.iris.util.data.DataProvider; import com.volmit.iris.util.documentation.BlockCoordinates; import com.volmit.iris.util.documentation.ChunkCoordinates; +import com.volmit.iris.util.format.Form; import com.volmit.iris.util.function.Function2; import com.volmit.iris.util.hunk.Hunk; import com.volmit.iris.util.mantle.MantleFlag; import com.volmit.iris.util.math.BlockPosition; import com.volmit.iris.util.math.M; import com.volmit.iris.util.math.RNG; +import com.volmit.iris.util.matter.MatterCavern; +import com.volmit.iris.util.matter.MatterUpdate; +import com.volmit.iris.util.matter.slices.UpdateMatter; import com.volmit.iris.util.parallel.BurstExecutor; import com.volmit.iris.util.parallel.MultiBurst; import com.volmit.iris.util.scheduling.ChronoLatch; @@ -58,19 +63,20 @@ import com.volmit.iris.util.scheduling.J; import com.volmit.iris.util.scheduling.PrecisionStopwatch; import com.volmit.iris.util.stream.ProceduralStream; import io.papermc.lib.PaperLib; -import org.bukkit.Bukkit; -import org.bukkit.Chunk; -import org.bukkit.Location; -import org.bukkit.Material; +import org.bukkit.*; import org.bukkit.block.Biome; import org.bukkit.block.Block; import org.bukkit.block.data.BlockData; import org.bukkit.command.CommandSender; +import org.bukkit.craftbukkit.v1_17_R1.CraftWorld; +import org.bukkit.craftbukkit.v1_17_R1.block.CraftBlock; +import org.bukkit.generator.ChunkGenerator; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.InventoryHolder; import org.bukkit.inventory.ItemStack; import java.awt.*; +import java.awt.Color; import java.util.Arrays; import java.util.UUID; import java.util.concurrent.atomic.AtomicBoolean; @@ -86,22 +92,12 @@ public interface Engine extends DataProvider, Fallible, LootProvider, BlockUpdat EngineMantle getMantle(); + void hotloadSilently(); + + void hotloadComplex(); + void recycle(); - EngineActuator getTerrainActuator(); - - EngineActuator getDecorantActuator(); - - EngineActuator getBiomeActuator(); - - EngineModifier getCaveModifier(); - - EngineModifier getRavineModifier(); - - EngineModifier getDepositModifier(); - - EngineModifier getPostModifier(); - void close(); IrisContext getContext(); @@ -140,6 +136,11 @@ public interface Engine extends DataProvider, Fallible, LootProvider, BlockUpdat @BlockCoordinates double modifyZ(double z); + @BlockCoordinates + default void generate(int x, int z, TerrainChunk tc, boolean multicore) throws WrongEngineBroException { + generate(x, z, Hunk.view((ChunkGenerator.ChunkData) tc), Hunk.view((ChunkGenerator.BiomeGrid) tc), multicore); + } + @BlockCoordinates void generate(int x, int z, Hunk blocks, Hunk biomes, boolean multicore) throws WrongEngineBroException; @@ -234,21 +235,39 @@ public interface Engine extends DataProvider, Fallible, LootProvider, BlockUpdat @ChunkCoordinates @Override default void updateChunk(Chunk c) { - getMantle().getMantle().raiseFlag(c.getX(), c.getZ(), MantleFlag.UPDATE, () -> J.s(() -> { - PrecisionStopwatch p = PrecisionStopwatch.start(); - getMantle().getMantle().iterateChunk(c.getX(), c.getZ(), Boolean.class, (x, y, z, v) -> { - if (v != null && v) { - int vx = x & 15; - int vz = z & 15; - update(x, y, z, c, new RNG(Cache.key(c.getX(), c.getZ()))); + if(c.getWorld().isChunkLoaded(c.getX() + 1, c.getZ() + 1) + && c.getWorld().isChunkLoaded(c.getX(), c.getZ() + 1) + && c.getWorld().isChunkLoaded(c.getX() + 1, c.getZ()) + && c.getWorld().isChunkLoaded(c.getX() - 1, c.getZ() - 1) + && c.getWorld().isChunkLoaded(c.getX(), c.getZ() - 1) + && c.getWorld().isChunkLoaded(c.getX() - 1, c.getZ()) + && c.getWorld().isChunkLoaded(c.getX() + 1, c.getZ() - 1) + && c.getWorld().isChunkLoaded(c.getX() - 1, c.getZ() + 1)) + { + getMantle().getMantle().raiseFlag(c.getX(), c.getZ(), MantleFlag.UPDATE, () -> J.s(() -> { + PrecisionStopwatch p = PrecisionStopwatch.start(); - if (vx > 0 && vx < 15 && vz > 0 && vz < 15) { - updateLighting(x, y, z, c); + getMantle().getMantle().iterateChunk(c.getX(), c.getZ(), MatterCavern.class, (x, y, z, v) -> { + update(x, y, z, c, new RNG(Cache.key(c.getX(), c.getZ()))); + }); + + getMantle().getMantle().iterateChunk(c.getX(), c.getZ(), MatterUpdate.class, (x, y, z, v) -> { + if (v != null && v.isUpdate()) { + int vx = x & 15; + int vz = z & 15; + update(x, y, z, c, new RNG(Cache.key(c.getX(), c.getZ()))); + if (vx > 0 && vx < 15 && vz > 0 && vz < 15) { + updateLighting(x, y, z, c); + } } - } - }); - getMetrics().getUpdates().put(p.getMilliseconds()); - })); + }); + + + getMantle().getMantle().deleteChunkSlice(c.getX(), c.getZ(), MatterCavern.class); + getMantle().getMantle().deleteChunkSlice(c.getX(), c.getZ(), MatterUpdate.class); + getMetrics().getUpdates().put(p.getMilliseconds()); + }, RNG.r.i(0, 20))); + } } @BlockCoordinates @@ -291,6 +310,12 @@ public interface Engine extends DataProvider, Fallible, LootProvider, BlockUpdat } } } + + else + { + block.setType(Material.AIR, false); + block.setBlockData(data, true); + } } @Override diff --git a/src/main/java/com/volmit/iris/engine/framework/EngineComponent.java b/src/main/java/com/volmit/iris/engine/framework/EngineComponent.java index 47b73b49d..08a09ab05 100644 --- a/src/main/java/com/volmit/iris/engine/framework/EngineComponent.java +++ b/src/main/java/com/volmit/iris/engine/framework/EngineComponent.java @@ -19,7 +19,7 @@ package com.volmit.iris.engine.framework; import com.volmit.iris.Iris; -import com.volmit.iris.core.project.loader.IrisData; +import com.volmit.iris.core.loader.IrisData; import com.volmit.iris.engine.IrisComplex; import com.volmit.iris.engine.object.dimensional.IrisDimension; import com.volmit.iris.util.math.RollingSequence; diff --git a/src/main/java/com/volmit/iris/engine/framework/EngineTarget.java b/src/main/java/com/volmit/iris/engine/framework/EngineTarget.java index c644c9e3c..d6b849787 100644 --- a/src/main/java/com/volmit/iris/engine/framework/EngineTarget.java +++ b/src/main/java/com/volmit/iris/engine/framework/EngineTarget.java @@ -18,7 +18,7 @@ package com.volmit.iris.engine.framework; -import com.volmit.iris.core.project.loader.IrisData; +import com.volmit.iris.core.loader.IrisData; import com.volmit.iris.engine.object.common.IrisWorld; import com.volmit.iris.engine.object.dimensional.IrisDimension; import com.volmit.iris.util.parallel.MultiBurst; diff --git a/src/main/java/com/volmit/iris/engine/framework/placer/HeightmapObjectPlacer.java b/src/main/java/com/volmit/iris/engine/framework/placer/HeightmapObjectPlacer.java index 10c614a03..3a7ce0a98 100644 --- a/src/main/java/com/volmit/iris/engine/framework/placer/HeightmapObjectPlacer.java +++ b/src/main/java/com/volmit/iris/engine/framework/placer/HeightmapObjectPlacer.java @@ -18,7 +18,7 @@ package com.volmit.iris.engine.framework.placer; -import com.volmit.iris.core.project.loader.IrisData; +import com.volmit.iris.core.loader.IrisData; import com.volmit.iris.engine.object.common.IObjectPlacer; import com.volmit.iris.engine.object.objects.IrisObjectPlacement; import com.volmit.iris.engine.object.tile.TileData; diff --git a/src/main/java/com/volmit/iris/engine/jigsaw/PlannedPiece.java b/src/main/java/com/volmit/iris/engine/jigsaw/PlannedPiece.java index dbdfca1f4..cb60cc322 100644 --- a/src/main/java/com/volmit/iris/engine/jigsaw/PlannedPiece.java +++ b/src/main/java/com/volmit/iris/engine/jigsaw/PlannedPiece.java @@ -18,7 +18,7 @@ package com.volmit.iris.engine.jigsaw; -import com.volmit.iris.core.project.loader.IrisData; +import com.volmit.iris.core.loader.IrisData; import com.volmit.iris.core.tools.IrisToolbelt; import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.object.basic.IrisPosition; diff --git a/src/main/java/com/volmit/iris/engine/jigsaw/PlannedStructure.java b/src/main/java/com/volmit/iris/engine/jigsaw/PlannedStructure.java index febb334ba..4290072ba 100644 --- a/src/main/java/com/volmit/iris/engine/jigsaw/PlannedStructure.java +++ b/src/main/java/com/volmit/iris/engine/jigsaw/PlannedStructure.java @@ -20,7 +20,7 @@ package com.volmit.iris.engine.jigsaw; import com.googlecode.concurrentlinkedhashmap.ConcurrentLinkedHashMap; import com.volmit.iris.Iris; -import com.volmit.iris.core.project.loader.IrisData; +import com.volmit.iris.core.loader.IrisData; import com.volmit.iris.engine.object.basic.IrisPosition; import com.volmit.iris.engine.object.common.IObjectPlacer; import com.volmit.iris.engine.object.feature.IrisFeature; diff --git a/src/main/java/com/volmit/iris/engine/mantle/EngineMantle.java b/src/main/java/com/volmit/iris/engine/mantle/EngineMantle.java index b644f1c70..253ad5e10 100644 --- a/src/main/java/com/volmit/iris/engine/mantle/EngineMantle.java +++ b/src/main/java/com/volmit/iris/engine/mantle/EngineMantle.java @@ -19,7 +19,7 @@ package com.volmit.iris.engine.mantle; import com.volmit.iris.Iris; -import com.volmit.iris.core.project.loader.IrisData; +import com.volmit.iris.core.loader.IrisData; import com.volmit.iris.engine.IrisComplex; import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.framework.EngineTarget; @@ -33,6 +33,12 @@ import com.volmit.iris.util.documentation.BlockCoordinates; import com.volmit.iris.util.documentation.ChunkCoordinates; import com.volmit.iris.util.hunk.Hunk; import com.volmit.iris.util.mantle.Mantle; +import com.volmit.iris.util.mantle.MantleChunk; +import com.volmit.iris.util.mantle.MantleFlag; +import com.volmit.iris.util.matter.Matter; +import com.volmit.iris.util.matter.MatterCavern; +import com.volmit.iris.util.matter.slices.CavernMatter; +import com.volmit.iris.util.matter.slices.UpdateMatter; import com.volmit.iris.util.parallel.BurstExecutor; import com.volmit.iris.util.parallel.MultiBurst; import org.bukkit.Chunk; @@ -189,7 +195,11 @@ public interface EngineMantle extends IObjectPlacer { int xx = i + x; int zz = j + z; burst.queue(() -> { - getComponents().forEach((f) -> generateMantleComponent(writer, xx, zz, f, c)); + MantleChunk mc = getMantle().getChunk(xx, zz); + + for (MantleComponent k : getComponents()) { + generateMantleComponent(writer, xx, zz, k, c, mc); + } }); } } @@ -201,10 +211,12 @@ public interface EngineMantle extends IObjectPlacer { post.clear(); burst().burst(multicore, px); } + + getMantle().flag(x, z, MantleFlag.REAL, true); } - default void generateMantleComponent(MantleWriter writer, int x, int z, MantleComponent c, Consumer post) { - getMantle().raiseFlag(x, z, c.getFlag(), () -> c.generateLayer(writer, x, z, post)); + default void generateMantleComponent(MantleWriter writer, int x, int z, MantleComponent c, Consumer post, MantleChunk mc) { + mc.raiseFlag(c.getFlag(), () -> c.generateLayer(writer, x, z, post)); } @ChunkCoordinates @@ -218,7 +230,22 @@ public interface EngineMantle extends IObjectPlacer { @BlockCoordinates default void updateBlock(int x, int y, int z) { - getMantle().set(x, y, z, true); + getMantle().set(x, y, z, UpdateMatter.ON); + } + + @BlockCoordinates + default void cavernBlock(int x, int y, int z) { + getMantle().set(x, y, z, CavernMatter.ON); + } + + @BlockCoordinates + default void dropCavernBlock(int x, int y, int z) { + Matter matter = getMantle().getChunk(x & 15, z & 15).get(y & 15); + + if(matter != null) + { + matter.slice(MatterCavern.class).set(x & 15, y & 15, z & 15, null); + } } @ChunkCoordinates @@ -241,10 +268,6 @@ public interface EngineMantle extends IObjectPlacer { default KList forEachFeature(double x, double z) { KList pos = new KList<>(); - if (!getEngine().getDimension().hasFeatures(getEngine())) { - return pos; - } - for (IrisFeaturePositional i : getEngine().getDimension().getSpecificFeatures()) { if (i.shouldFilter(x, z, getEngine().getComplex().getRng(), getData())) { pos.add(i); @@ -274,4 +297,12 @@ public interface EngineMantle extends IObjectPlacer { return pos; } + + default boolean queueRegenerate(int x, int z) { + return false; // TODO: + } + + default boolean dequeueRegenerate(int x, int z) { + return false;// TODO: + } } diff --git a/src/main/java/com/volmit/iris/engine/mantle/MantleComponent.java b/src/main/java/com/volmit/iris/engine/mantle/MantleComponent.java index 7a7444250..a78d91880 100644 --- a/src/main/java/com/volmit/iris/engine/mantle/MantleComponent.java +++ b/src/main/java/com/volmit/iris/engine/mantle/MantleComponent.java @@ -18,7 +18,7 @@ package com.volmit.iris.engine.mantle; -import com.volmit.iris.core.project.loader.IrisData; +import com.volmit.iris.core.loader.IrisData; import com.volmit.iris.engine.IrisComplex; import com.volmit.iris.engine.object.dimensional.IrisDimension; import com.volmit.iris.util.documentation.ChunkCoordinates; diff --git a/src/main/java/com/volmit/iris/engine/mantle/MantleWriter.java b/src/main/java/com/volmit/iris/engine/mantle/MantleWriter.java index 39353eb7a..95780ea38 100644 --- a/src/main/java/com/volmit/iris/engine/mantle/MantleWriter.java +++ b/src/main/java/com/volmit/iris/engine/mantle/MantleWriter.java @@ -18,19 +18,33 @@ package com.volmit.iris.engine.mantle; +import com.google.common.collect.ImmutableList; import com.volmit.iris.Iris; -import com.volmit.iris.core.project.loader.IrisData; +import com.volmit.iris.core.loader.IrisData; import com.volmit.iris.engine.data.cache.Cache; +import com.volmit.iris.engine.object.basic.IrisPosition; import com.volmit.iris.engine.object.common.IObjectPlacer; import com.volmit.iris.engine.object.feature.IrisFeaturePositional; import com.volmit.iris.engine.object.tile.TileData; +import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.collection.KMap; +import com.volmit.iris.util.collection.KSet; import com.volmit.iris.util.mantle.Mantle; import com.volmit.iris.util.mantle.MantleChunk; +import com.volmit.iris.util.math.INode; +import com.volmit.iris.util.math.KochanekBartelsInterpolation; +import com.volmit.iris.util.math.M; +import com.volmit.iris.util.math.PathInterpolation; import com.volmit.iris.util.matter.Matter; import lombok.Data; import org.bukkit.block.TileState; import org.bukkit.block.data.BlockData; +import org.bukkit.util.Vector; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; @Data public class MantleWriter implements IObjectPlacer { @@ -79,8 +93,6 @@ public class MantleWriter implements IObjectPlacer { Matter matter = chunk.getOrCreate(y >> 4); matter.slice(matter.getClass(t)).set(x & 15, y & 15, z & 15, t); } - } else { - Iris.error("Mantle Writer[" + this.x + "," + this.z + ",R" + this.radius + "] Tried to access " + x + "," + y + "," + z + " (Chunk " + cx + "," + cz + ") which is OUT OF BOUNDS!"); } } @@ -133,4 +145,404 @@ public class MantleWriter implements IObjectPlacer { public void setTile(int xx, int yy, int zz, TileData tile) { getEngineMantle().setTile(xx, yy, zz, tile); } + /** + * Set a sphere into the mantle + * + * @param cx the center x + * @param cy the center y + * @param cz the center z + * @param radius the radius of this sphere + * @param fill should it be filled? or just the outer shell? + * @param data the data to set + * @param the type of data to apply to the mantle + */ + public void setSphere(int cx, int cy, int cz, double radius, boolean fill, T data) { + setElipsoid(cx, cy, cz, radius, radius, radius, fill, data); + } + + /** + * Set an elipsoid into the mantle + * + * @param cx the center x + * @param cy the center y + * @param cz the center z + * @param rx the x radius + * @param ry the y radius + * @param rz the z radius + * @param fill should it be filled or just the outer shell? + * @param data the data to set + * @param the type of data to apply to the mantle + */ + public void setElipsoid(int cx, int cy, int cz, double rx, double ry, double rz, boolean fill, T data) { + rx += 0.5; + ry += 0.5; + rz += 0.5; + final double invRadiusX = 1 / rx; + final double invRadiusY = 1 / ry; + final double invRadiusZ = 1 / rz; + final int ceilRadiusX = (int) Math.ceil(rx); + final int ceilRadiusY = (int) Math.ceil(ry); + final int ceilRadiusZ = (int) Math.ceil(rz); + double nextXn = 0; + + forX: + for (int x = 0; x <= ceilRadiusX; ++x) { + final double xn = nextXn; + nextXn = (x + 1) * invRadiusX; + double nextYn = 0; + forY: + for (int y = 0; y <= ceilRadiusY; ++y) { + final double yn = nextYn; + nextYn = (y + 1) * invRadiusY; + double nextZn = 0; + for (int z = 0; z <= ceilRadiusZ; ++z) { + final double zn = nextZn; + nextZn = (z + 1) * invRadiusZ; + + double distanceSq = lengthSq(xn, yn, zn); + if (distanceSq > 1) { + if (z == 0) { + if (y == 0) { + break forX; + } + break forY; + } + break; + } + + if (!fill) { + if (lengthSq(nextXn, yn, zn) <= 1 && lengthSq(xn, nextYn, zn) <= 1 && lengthSq(xn, yn, nextZn) <= 1) { + continue; + } + } + + setData(x + cx, y + cy, z + cz, data); + setData(-x + cx, y + cy, z + cz, data); + setData(x + cx, -y + cy, z + cz, data); + setData(x + cx, y + cy, -z + cz, data); + setData(-x + cx, y + cy, -z + cz, data); + setData(-x + cx, -y + cy, z + cz, data); + setData(x + cx, -y + cy, -z + cz, data); + setData(-x + cx, y + cy, -z + cz, data); + setData(-x + cx, -y + cy, -z + cz, data); + } + } + } + } + + /** + * Set a cuboid of data in the mantle + * + * @param x1 the min x + * @param y1 the min y + * @param z1 the min z + * @param x2 the max x + * @param y2 the max y + * @param z2 the max z + * @param data the data to set + * @param the type of data to apply to the mantle + */ + public void setCuboid(int x1, int y1, int z1, int x2, int y2, int z2, T data) { + int j, k; + + for (int i = x1; i <= x2; i++) { + for (j = x1; j <= x2; j++) { + for (k = x1; k <= x2; k++) { + setData(i, j, k, data); + } + } + } + } + + /** + * Set a pyramid of data in the mantle + * + * @param cx the center x + * @param cy the base y + * @param cz the center z + * @param data the data to set + * @param size the size of the pyramid (width of base & height) + * @param filled should it be filled or hollow + * @param the type of data to apply to the mantle + */ + @SuppressWarnings("ConstantConditions") + public void setPyramid(int cx, int cy, int cz, T data, int size, boolean filled) { + int height = size; + + for (int y = 0; y <= height; ++y) { + size--; + for (int x = 0; x <= size; ++x) { + for (int z = 0; z <= size; ++z) { + if ((filled && z <= size && x <= size) || z == size || x == size) { + setData(x + cx, y + cy, z + cz, data); + setData(-x + cx, y + cy, z + cz, data); + setData(x + cx, y + cy, -z + cz, data); + setData(-x + cx, y + cy, -z + cz, data); + } + } + } + } + } + + /** + * Set a 3d line + * + * @param a the first point + * @param b the second point + * @param radius the radius + * @param filled hollow or filled? + * @param data the data + * @param the type of data to apply to the mantle + */ + public void setLine(IrisPosition a, IrisPosition b, double radius, boolean filled, T data) { + setLine(ImmutableList.of(a, b), radius, filled, data); + } + + /** + * Set lines for points + * + * @param vectors the points + * @param radius the radius + * @param filled hollow or filled? + * @param data the data to set + * @param the type of data to apply to the mantle + */ + public void setLine(List vectors, double radius, boolean filled, T data) { + Set vset = new KSet<>(); + + for (int i = 0; vectors.size() != 0 && i < vectors.size() - 1; i++) { + IrisPosition pos1 = vectors.get(i); + IrisPosition pos2 = vectors.get(i + 1); + int x1 = pos1.getX(); + int y1 = pos1.getY(); + int z1 = pos1.getZ(); + int x2 = pos2.getX(); + int y2 = pos2.getY(); + int z2 = pos2.getZ(); + int tipx = x1; + int tipy = y1; + int tipz = z1; + int dx = Math.abs(x2 - x1); + int dy = Math.abs(y2 - y1); + int dz = Math.abs(z2 - z1); + + if (dx + dy + dz == 0) { + vset.add(new IrisPosition(tipx, tipy, tipz)); + continue; + } + + int dMax = Math.max(Math.max(dx, dy), dz); + if (dMax == dx) { + for (int domstep = 0; domstep <= dx; domstep++) { + tipx = x1 + domstep * (x2 - x1 > 0 ? 1 : -1); + tipy = (int) Math.round(y1 + domstep * ((double) dy) / ((double) dx) * (y2 - y1 > 0 ? 1 : -1)); + tipz = (int) Math.round(z1 + domstep * ((double) dz) / ((double) dx) * (z2 - z1 > 0 ? 1 : -1)); + + vset.add(new IrisPosition(tipx, tipy, tipz)); + } + } else if (dMax == dy) { + for (int domstep = 0; domstep <= dy; domstep++) { + tipy = y1 + domstep * (y2 - y1 > 0 ? 1 : -1); + tipx = (int) Math.round(x1 + domstep * ((double) dx) / ((double) dy) * (x2 - x1 > 0 ? 1 : -1)); + tipz = (int) Math.round(z1 + domstep * ((double) dz) / ((double) dy) * (z2 - z1 > 0 ? 1 : -1)); + + vset.add(new IrisPosition(tipx, tipy, tipz)); + } + } else /* if (dMax == dz) */ { + for (int domstep = 0; domstep <= dz; domstep++) { + tipz = z1 + domstep * (z2 - z1 > 0 ? 1 : -1); + tipy = (int) Math.round(y1 + domstep * ((double) dy) / ((double) dz) * (y2 - y1 > 0 ? 1 : -1)); + tipx = (int) Math.round(x1 + domstep * ((double) dx) / ((double) dz) * (x2 - x1 > 0 ? 1 : -1)); + + vset.add(new IrisPosition(tipx, tipy, tipz)); + } + } + } + + vset = getBallooned(vset, radius); + + if (!filled) { + vset = getHollowed(vset); + } + + set(vset, data); + } + + /** + * Set a cylinder in the mantle + * + * @param cx the center x + * @param cy the base y + * @param cz the center z + * @param data the data to set + * @param radius the radius + * @param height the height of the cyl + * @param filled filled or not + */ + public void setCylinder(int cx, int cy, int cz, T data, double radius, int height, boolean filled) { + setCylinder(cx, cy, cz, data, radius, radius, height, filled); + } + + /** + * Set a cylinder in the mantle + * + * @param cx the center x + * @param cy the base y + * @param cz the center z + * @param data the data to set + * @param radiusX the x radius + * @param radiusZ the z radius + * @param height the height of this cyl + * @param filled filled or hollow? + */ + public void setCylinder(int cx, int cy, int cz, T data, double radiusX, double radiusZ, int height, boolean filled) { + int affected = 0; + radiusX += 0.5; + radiusZ += 0.5; + + if (height == 0) { + return; + } else if (height < 0) { + height = -height; + cy = cy - height; + } + + if (cy < 0) { + cy = 0; + } else if (cy + height - 1 > getMantle().getWorldHeight()) { + height = getMantle().getWorldHeight() - cy + 1; + } + + final double invRadiusX = 1 / radiusX; + final double invRadiusZ = 1 / radiusZ; + final int ceilRadiusX = (int) Math.ceil(radiusX); + final int ceilRadiusZ = (int) Math.ceil(radiusZ); + double nextXn = 0; + + forX: + for (int x = 0; x <= ceilRadiusX; ++x) { + final double xn = nextXn; + nextXn = (x + 1) * invRadiusX; + double nextZn = 0; + for (int z = 0; z <= ceilRadiusZ; ++z) { + final double zn = nextZn; + nextZn = (z + 1) * invRadiusZ; + double distanceSq = lengthSq(xn, zn); + + if (distanceSq > 1) { + if (z == 0) { + break forX; + } + + break; + } + + if (!filled) { + if (lengthSq(nextXn, zn) <= 1 && lengthSq(xn, nextZn) <= 1) { + continue; + } + } + + for (int y = 0; y < height; ++y) { + setData(cx + x, cy + y, cz + z, data); + setData(cx + -x, cy + y, cz + z, data); + setData(cx + x, cy + y, cz + -z, data); + setData(cx + -x, cy + y, cz + -z, data); + } + } + } + } + + public void set(IrisPosition pos, T data) { + setData(pos.getX(), pos.getY(), pos.getZ(), data); + } + + public void set(List positions, T data) { + for (IrisPosition i : positions) { + set(i, data); + } + } + + public void set(Set positions, T data) { + for (IrisPosition i : positions) { + set(i, data); + } + } + + private static Set getBallooned(Set vset, double radius) { + Set returnset = new HashSet<>(); + int ceilrad = (int) Math.ceil(radius); + + for (IrisPosition v : vset) { + int tipx = v.getX(); + int tipy = v.getY(); + int tipz = v.getZ(); + + for (int loopx = tipx - ceilrad; loopx <= tipx + ceilrad; loopx++) { + for (int loopy = tipy - ceilrad; loopy <= tipy + ceilrad; loopy++) { + for (int loopz = tipz - ceilrad; loopz <= tipz + ceilrad; loopz++) { + if (hypot(loopx - tipx, loopy - tipy, loopz - tipz) <= radius) { + returnset.add(new IrisPosition(loopx, loopy, loopz)); + } + } + } + } + } + return returnset; + } + + private static Set getHollowed(Set vset) { + Set returnset = new KSet<>(); + for (IrisPosition v : vset) { + double x = v.getX(); + double y = v.getY(); + double z = v.getZ(); + if (!(vset.contains(new IrisPosition(x + 1, y, z)) + && vset.contains(new IrisPosition(x - 1, y, z)) + && vset.contains(new IrisPosition(x, y + 1, z)) + && vset.contains(new IrisPosition(x, y - 1, z)) + && vset.contains(new IrisPosition(x, y, z + 1)) + && vset.contains(new IrisPosition(x, y, z - 1)))) { + returnset.add(v); + } + } + return returnset; + } + + private static double hypot(double... pars) { + double sum = 0; + for (double d : pars) { + sum += Math.pow(d, 2); + } + return Math.sqrt(sum); + } + + private static double lengthSq(double x, double y, double z) { + return (x * x) + (y * y) + (z * z); + } + + private static double lengthSq(double x, double z) { + return (x * x) + (z * z); + } + + public boolean isWithin(Vector pos) { + return isWithin(pos.getBlockX(), pos.getBlockY(), pos.getBlockZ()); + } + + public boolean isWithin(int x, int y, int z) + { + int cx = x >> 4; + int cz = z >> 4; + + if (y < 0 || y >= mantle.getWorldHeight()) { + return false; + } + + if (cx >= this.x - radius && cx <= this.x + radius + && cz >= this.z - radius && cz <= this.z + radius) { + return true; + } + + return false; + } } diff --git a/src/main/java/com/volmit/iris/engine/mantle/components/MantleCarvingComponent.java b/src/main/java/com/volmit/iris/engine/mantle/components/MantleCarvingComponent.java new file mode 100644 index 000000000..d8b618c2a --- /dev/null +++ b/src/main/java/com/volmit/iris/engine/mantle/components/MantleCarvingComponent.java @@ -0,0 +1,63 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.engine.mantle.components; + +import com.volmit.iris.engine.data.cache.Cache; +import com.volmit.iris.engine.mantle.EngineMantle; +import com.volmit.iris.engine.mantle.IrisMantleComponent; +import com.volmit.iris.engine.mantle.MantleWriter; +import com.volmit.iris.engine.object.biome.IrisBiome; +import com.volmit.iris.engine.object.carving.IrisCarving; +import com.volmit.iris.engine.object.feature.IrisFeaturePositional; +import com.volmit.iris.engine.object.feature.IrisFeaturePotential; +import com.volmit.iris.engine.object.regional.IrisRegion; +import com.volmit.iris.util.collection.KList; +import com.volmit.iris.util.documentation.ChunkCoordinates; +import com.volmit.iris.util.mantle.MantleFlag; +import com.volmit.iris.util.math.RNG; + +import java.util.function.Consumer; + +public class MantleCarvingComponent extends IrisMantleComponent { + public MantleCarvingComponent(EngineMantle engineMantle) { + super(engineMantle, MantleFlag.CARVED); + } + + @Override + public void generateLayer(MantleWriter writer, int x, int z, Consumer post) { + RNG rng = new RNG(Cache.key(x, z) + seed()); + int xxx = 8 + (x << 4); + int zzz = 8 + (z << 4); + IrisRegion region = getComplex().getRegionStream().get(xxx, zzz); + IrisBiome biome = getComplex().getTrueBiomeStreamNoFeatures().get(xxx, zzz); + carve(writer, rng, x, z, region, biome); + } + + @ChunkCoordinates + private void carve(MantleWriter writer, RNG rng, int cx, int cz, IrisRegion region, IrisBiome biome) { + carve(getDimension().getCarving(), writer, new RNG((rng.nextLong() * cx) + 490495 + cz), cx, cz); + carve(biome.getCarving(), writer, new RNG((rng.nextLong() * cx) + 490495 + cz), cx, cz); + carve(region.getCarving(), writer, new RNG((rng.nextLong() * cx) + 490495 + cz), cx, cz); + } + + @ChunkCoordinates + private void carve(IrisCarving carving, MantleWriter writer, RNG rng, int cx, int cz) { + carving.doCarving(writer, rng, getEngineMantle().getEngine(), cx << 4, -1, cz << 4); + } +} diff --git a/src/main/java/com/volmit/iris/engine/mantle/components/MantleFeatureComponent.java b/src/main/java/com/volmit/iris/engine/mantle/components/MantleFeatureComponent.java index eb7f29da5..a94b14bbb 100644 --- a/src/main/java/com/volmit/iris/engine/mantle/components/MantleFeatureComponent.java +++ b/src/main/java/com/volmit/iris/engine/mantle/components/MantleFeatureComponent.java @@ -64,9 +64,12 @@ public class MantleFeatureComponent extends IrisMantleComponent { } private void placeZone(MantleWriter writer, RNG rng, int cx, int cz, IrisFeaturePotential i) { - int x = (cx << 4) + rng.nextInt(16); - int z = (cz << 4) + rng.nextInt(16); - writer.setData(x, 0, z, new IrisFeaturePositional(x, z, i.getZone())); + if(i.hasZone(rng, cx, cz)) + { + int x = (cx << 4) + rng.nextInt(16); + int z = (cz << 4) + rng.nextInt(16); + writer.setData(x, 0, z, new IrisFeaturePositional(x, z, i.getZone())); + } } private KList getFeatures() { diff --git a/src/main/java/com/volmit/iris/engine/mantle/components/MantleJigsawComponent.java b/src/main/java/com/volmit/iris/engine/mantle/components/MantleJigsawComponent.java index 2a946c845..7ffe30a96 100644 --- a/src/main/java/com/volmit/iris/engine/mantle/components/MantleJigsawComponent.java +++ b/src/main/java/com/volmit/iris/engine/mantle/components/MantleJigsawComponent.java @@ -44,7 +44,7 @@ public class MantleJigsawComponent extends IrisMantleComponent { public MantleJigsawComponent(EngineMantle engineMantle) { super(engineMantle, MantleFlag.JIGSAW); - cng = NoiseStyle.STATIC.create(new RNG()); + cng = NoiseStyle.STATIC.create(new RNG(engineMantle.getEngine().getWorld().seed() + 24398848585L)); } @Override @@ -118,6 +118,6 @@ public class MantleJigsawComponent extends IrisMantleComponent { new IrisFeaturePositional(position.getX(), position.getZ(), structure.getFeature())); } - post.accept(() -> new PlannedStructure(structure, position, rng).place(writer, getMantle(), post)); + new PlannedStructure(structure, position, rng).place(writer, getMantle(), post); } } diff --git a/src/main/java/com/volmit/iris/engine/mantle/components/MantleObjectComponent.java b/src/main/java/com/volmit/iris/engine/mantle/components/MantleObjectComponent.java index 13f32ca9b..d73b4c82f 100644 --- a/src/main/java/com/volmit/iris/engine/mantle/components/MantleObjectComponent.java +++ b/src/main/java/com/volmit/iris/engine/mantle/components/MantleObjectComponent.java @@ -90,40 +90,31 @@ public class MantleObjectComponent extends IrisMantleComponent { if (v == null) { return; } - int xx = rng.i(x, x + 16); - int zz = rng.i(z, z + 16); + int xx = rng.i(x, x + 15); + int zz = rng.i(z, z + 15); int id = rng.i(0, Integer.MAX_VALUE); - Runnable r = () -> { - int h = v.place(xx, -1, zz, writer, objectPlacement, rng, - (b) -> writer.setData(b.getX(), b.getY(), b.getZ(), - v.getLoadKey() + "@" + id), null, getData()); - if (objectPlacement.usesFeatures()) { - if (objectPlacement.isVacuum()) { + int h = v.place(xx, -1, zz, writer, objectPlacement, rng, + (b) -> writer.setData(b.getX(), b.getY(), b.getZ(), + v.getLoadKey() + "@" + id), null, getData()); + if (objectPlacement.usesFeatures() && h >= 0) { + if (objectPlacement.isVacuum()) { + double a = Math.max(v.getW(), v.getD()); + IrisFeature f = new IrisFeature(); + f.setConvergeToHeight(h); + f.setBlockRadius(a); + f.setInterpolationRadius(objectPlacement.getVacuumInterpolationRadius()); + f.setInterpolator(objectPlacement.getVacuumInterpolationMethod()); + f.setStrength(1D); + writer.setData(xx, 0, zz, new IrisFeaturePositional(xx, zz, f)); + } - double a = Math.max(v.getW(), v.getD()); - IrisFeature f = new IrisFeature(); - f.setConvergeToHeight(h - (v.getH() >> 1)); - f.setBlockRadius(a); - f.setInterpolationRadius(objectPlacement.getVacuumInterpolationRadius()); - f.setInterpolator(objectPlacement.getVacuumInterpolationMethod()); - f.setStrength(1D); - writer.setData(xx, 0, zz, new IrisFeaturePositional(xx, zz, f)); - } - - for (IrisFeaturePotential j : objectPlacement.getAddFeatures()) { - if (j.hasZone(rng, xx >> 4, zz >> 4)) { - writer.setData(xx, 0, zz, new IrisFeaturePositional(xx, zz, j.getZone())); - } + for (IrisFeaturePotential j : objectPlacement.getAddFeatures()) { + if (j.hasZone(rng, xx >> 4, zz >> 4)) { + writer.setData(xx, 0, zz, new IrisFeaturePositional(xx, zz, j.getZone())); } } - }; - - if (objectPlacement.usesFeatures()) { - r.run(); - } else { - post.accept(r); } } } diff --git a/src/main/java/com/volmit/iris/engine/modifier/IrisCarveModifier.java b/src/main/java/com/volmit/iris/engine/modifier/IrisCarveModifier.java new file mode 100644 index 000000000..9ff7883a3 --- /dev/null +++ b/src/main/java/com/volmit/iris/engine/modifier/IrisCarveModifier.java @@ -0,0 +1,79 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.engine.modifier; + +import com.volmit.iris.engine.data.cache.Cache; +import com.volmit.iris.engine.framework.Engine; +import com.volmit.iris.engine.framework.EngineAssignedModifier; +import com.volmit.iris.engine.object.basic.IrisPosition; +import com.volmit.iris.engine.object.biome.IrisBiome; +import com.volmit.iris.engine.object.deposits.IrisDepositGenerator; +import com.volmit.iris.engine.object.objects.IrisObject; +import com.volmit.iris.engine.object.regional.IrisRegion; +import com.volmit.iris.util.data.B; +import com.volmit.iris.util.data.HeightMap; +import com.volmit.iris.util.hunk.Hunk; +import com.volmit.iris.util.mantle.Mantle; +import com.volmit.iris.util.mantle.MantleChunk; +import com.volmit.iris.util.math.RNG; +import com.volmit.iris.util.matter.MatterCavern; +import com.volmit.iris.util.matter.slices.CavernMatter; +import com.volmit.iris.util.parallel.BurstExecutor; +import com.volmit.iris.util.scheduling.PrecisionStopwatch; +import org.bukkit.Material; +import org.bukkit.block.data.BlockData; +import org.bukkit.util.BlockVector; + +import java.util.Set; + +public class IrisCarveModifier extends EngineAssignedModifier { + private final RNG rng; + private final BlockData AIR = Material.CAVE_AIR.createBlockData(); + + public IrisCarveModifier(Engine engine) { + super(engine, "Carve"); + rng = new RNG(getEngine().getWorld().seed() + 3297778).nextParallelRNG(67648777); + } + + @Override + public void onModify(int x, int z, Hunk output, boolean multicore) { + PrecisionStopwatch p = PrecisionStopwatch.start(); + Mantle mantle = getEngine().getMantle().getMantle(); + MantleChunk mc = getEngine().getMantle().getMantle().getChunk(x, z); + + mc.iterate(MatterCavern.class, (xx, yy, zz, c) -> { + int rx = xx & 15; + int rz = zz & 15; + BlockData current = output.get(rx, yy, rz); + + if(current.getMaterial().isAir()) + { + return; + } + + if(B.isFluid(current)) + { + return; + } + + output.set(rx, yy, rz, AIR); + }); + getEngine().getMetrics().getDeposit().put(p.getMilliseconds()); + } +} diff --git a/src/main/java/com/volmit/iris/engine/modifier/IrisCaveModifier.java b/src/main/java/com/volmit/iris/engine/modifier/IrisCaveModifier.java deleted file mode 100644 index bbee9f959..000000000 --- a/src/main/java/com/volmit/iris/engine/modifier/IrisCaveModifier.java +++ /dev/null @@ -1,254 +0,0 @@ -/* - * Iris is a World Generator for Minecraft Bukkit Servers - * Copyright (c) 2021 Arcane Arts (Volmit Software) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.volmit.iris.engine.modifier; - -import com.volmit.iris.engine.framework.Engine; -import com.volmit.iris.engine.framework.EngineAssignedModifier; -import com.volmit.iris.engine.object.biome.IrisBiome; -import com.volmit.iris.engine.object.carve.IrisCaveLayer; -import com.volmit.iris.engine.object.common.CaveResult; -import com.volmit.iris.util.collection.KList; -import com.volmit.iris.util.data.B; -import com.volmit.iris.util.hunk.Hunk; -import com.volmit.iris.util.math.RNG; -import com.volmit.iris.util.noise.FastNoiseDouble; -import com.volmit.iris.util.parallel.BurstExecutor; -import com.volmit.iris.util.scheduling.PrecisionStopwatch; -import org.bukkit.Material; -import org.bukkit.block.data.BlockData; - -import java.util.function.Function; - -public class IrisCaveModifier extends EngineAssignedModifier { - public static final BlockData CAVE_AIR = B.get("CAVE_AIR"); - public static final BlockData AIR = B.get("AIR"); - private static final KList EMPTY = new KList<>(); - private final FastNoiseDouble gg; - private final RNG rng; - - public IrisCaveModifier(Engine engine) { - super(engine, "Cave"); - rng = new RNG(engine.getWorld().seed() + 28934555); - gg = new FastNoiseDouble(324895L * rng.nextParallelRNG(49678).imax()); - } - - @Override - public void onModify(int x, int z, Hunk a, boolean multicore) { - if (!getDimension().isCaves()) { - return; - } - - PrecisionStopwatch p = PrecisionStopwatch.start(); - BurstExecutor e = burst().burst(multicore); - for (int i = 0; i < a.getWidth(); i++) { - int finalI = i; - e.queue(() -> modifySliver(x, z, finalI, a)); - } - - e.complete(); - getEngine().getMetrics().getCave().put(p.getMilliseconds()); - } - - public void modifySliver(int x, int z, int finalI, Hunk a) { - for (int j = 0; j < a.getDepth(); j++) { - KList caves = genCaves(x + finalI, z + j, finalI, j, a); - int he = (int) Math.round(getComplex().getHeightStream().get(x + finalI, z + j)); - if (caves != null && caves.isNotEmpty()) { - IrisBiome cave = getComplex().getCaveBiomeStream().get(x + finalI, z + j); - - if (cave == null) { - continue; - } - - for (CaveResult cl : caves) { - if (cl.getFloor() < 0 || cl.getFloor() > getEngine().getHeight() || cl.getCeiling() > getEngine().getHeight() || cl.getCeiling() < 0) { - continue; - } - - KList floor = cave.generateLayers(getDimension(), x + finalI, z + j, rng, cl.getFloor(), cl.getFloor(), getData(), getComplex()); - KList ceiling = cave.generateLayers(getDimension(), x + finalI + 656, z + j - 656, rng, - he - cl.getCeiling(), - he - cl.getCeiling(), getData(), getComplex()); - - for (int g = 0; g < floor.size(); g++) { - a.set(finalI, cl.getFloor() - g, j, floor.get(g)); - } - - for (int g = ceiling.size() - 1; g > 0; g--) { - a.set(finalI, cl.getCeiling() + g, j, ceiling.get(g)); - } - } - } - } - } - - public KList genCaves(double wxx, double wzz) { - return genCaves(wxx, wzz, 0, 0, null); - } - - public KList genCaves(double wxx, double wzz, int x, int z, Hunk data) { - if (!getDimension().isCaves()) { - return EMPTY; - } - - KList result = new KList<>(); - gg.setNoiseType(FastNoiseDouble.NoiseType.Cellular); - gg.setCellularReturnType(FastNoiseDouble.CellularReturnType.Distance2Sub); - gg.setCellularDistanceFunction(FastNoiseDouble.CellularDistanceFunction.Natural); - - for (int i = 0; i < getDimension().getCaveLayers().size(); i++) { - IrisCaveLayer layer = getDimension().getCaveLayers().get(i); - generateCave(result, wxx, wzz, x, z, data, layer, i); - } - - return result; - } - - public void generateCave(KList result, double wxx, double wzz, int x, int z, Hunk data, IrisCaveLayer layer, int seed) { - double scale = layer.getCaveZoom(); - Function fluid = (height) -> - { - if (!layer.getFluid().hasFluid(getData())) { - return CAVE_AIR; - } - - if (layer.getFluid().isInverseHeight() && height >= layer.getFluid().getFluidHeight()) { - return layer.getFluid().getFluid(getData()); - } else if (!layer.getFluid().isInverseHeight() && height <= layer.getFluid().getFluidHeight()) { - return layer.getFluid().getFluid(getData()); - } - - return CAVE_AIR; - }; - - int surface = (int) Math.round(getComplex().getHeightStream().get(wxx, wzz)); - double wx = wxx + layer.getHorizontalSlope().get(rng, getData(), wxx, wzz); - double wz = wzz + layer.getHorizontalSlope().get(rng, getData(), -wzz, -wxx); - double baseWidth = (14 * scale); - double distanceCheck = 0.0132 * baseWidth; - double distanceTake = 0.0022 * baseWidth; - double caveHeightNoise = layer.getVerticalSlope().get(rng, getData(), wxx, wzz); - - if (caveHeightNoise > 259 || caveHeightNoise < -1) { - return; - } - - // TODO: WARNING HEIGHT - int ceiling = -256; - int floor = 512; - - for (double tunnelHeight = 1; tunnelHeight <= baseWidth; tunnelHeight++) { - double distance = (gg.GetCellular(((wx + (10000 * seed)) / layer.getCaveZoom()), ((wz - (10000 * seed)) / layer.getCaveZoom())) + 1D) / 2D; - if (distance < distanceCheck - (tunnelHeight * distanceTake)) { - int caveHeight = (int) Math.round(caveHeightNoise); - int pu = (int) (caveHeight + tunnelHeight); - int pd = (int) (caveHeight - tunnelHeight); - - if (pd > surface + 1) { - continue; - } - - if (!layer.isCanBreakSurface() && pu > surface - 3) { - continue; - } - - if ((pu > 255 && pd > 255) || (pu < 0 && pd < 0)) { - continue; - } - - if (data == null) { - ceiling = Math.max(pu, ceiling); - floor = Math.min(pu, floor); - ceiling = Math.max(pd, ceiling); - floor = Math.min(pd, floor); - - if (tunnelHeight == 1) { - ceiling = Math.max(caveHeight, ceiling); - floor = Math.min(caveHeight, floor); - } - } else { - if (dig(x, pu, z, data, fluid)) { - ceiling = Math.max(pu, ceiling); - floor = Math.min(pu, floor); - } - - if (dig(x, pd, z, data, fluid)) { - ceiling = Math.max(pd, ceiling); - floor = Math.min(pd, floor); - } - - if (tunnelHeight == 1) { - if (dig(x, caveHeight, z, data, fluid)) { - ceiling = Math.max(caveHeight, ceiling); - floor = Math.min(caveHeight, floor); - } - } - } - } - } - - if (floor >= 0 && ceiling <= 255) { - result.add(new CaveResult(floor, ceiling)); - } - } - - private Material mat(int x, int y, int z, Hunk data) { - BlockData d = data.get(Math.max(x, 0), Math.max(y, 0), Math.max(z, 0)); - - if (d != null) { - return d.getMaterial(); - } - - return Material.CAVE_AIR; - } - - public boolean dig(int x, int y, int z, Hunk data, Function caveFluid) { - Material a = mat(x, y, z, data); - Material c = mat(x, y + 1, z, data); - Material d = mat(x, y + 2, z, data); - Material e = mat(x, y + 3, z, data); - Material f = mat(x, y - 1, z, data); - BlockData b = caveFluid.apply(y); - BlockData b2 = caveFluid.apply(y + 1); - - if (can(a) && canAir(c, b) && canAir(f, b) && canWater(d) && canWater(e)) { - data.set(x, y, z, b); - data.set(x, y + 1, z, b2); - return true; - } - - return false; - } - - public boolean canAir(Material m, BlockData caveFluid) { - return (m.isSolid() || - (B.isDecorant(m.createBlockData())) || m.equals(Material.AIR) - || m.equals(caveFluid.getMaterial()) || - m.equals(B.getMaterial("CAVE_AIR"))) - && !m.equals(Material.BEDROCK); - } - - public boolean canWater(Material m) { - return !m.equals(Material.WATER); - } - - public boolean can(Material m) { - return m.isSolid() && !m.equals(Material.BEDROCK); - } -} diff --git a/src/main/java/com/volmit/iris/engine/modifier/IrisPostModifier.java b/src/main/java/com/volmit/iris/engine/modifier/IrisPostModifier.java index 52a68a678..936548746 100644 --- a/src/main/java/com/volmit/iris/engine/modifier/IrisPostModifier.java +++ b/src/main/java/com/volmit/iris/engine/modifier/IrisPostModifier.java @@ -231,189 +231,6 @@ public class IrisPostModifier extends EngineAssignedModifier { setPostBlock(x, h + 1, z, AIR, currentPostX, currentPostZ, currentData); } } - - if (getDimension().isPostProcessCaves()) { - IrisBiome cave = getComplex().getCaveBiomeStream().get(x, z); - - if (cave != null) { - for (CaveResult i : ((IrisCaveModifier) getEngine().getCaveModifier()).genCaves(x, z, 0, 0, null)) { - if (i.getCeiling() >= currentData.getMax2DParallelism() || i.getFloor() < 0) { - continue; - } - - int f = i.getFloor(); - int fa = nearestCaveFloor(f, x + 1, z, currentPostX, currentPostZ, currentData); - int fb = nearestCaveFloor(f, x, z + 1, currentPostX, currentPostZ, currentData); - int fc = nearestCaveFloor(f, x - 1, z, currentPostX, currentPostZ, currentData); - int fd = nearestCaveFloor(f, x, z - 1, currentPostX, currentPostZ, currentData); - int c = i.getCeiling(); - int ca = nearestCaveCeiling(c, x + 1, z, currentPostX, currentPostZ, currentData); - int cb = nearestCaveCeiling(c, x, z + 1, currentPostX, currentPostZ, currentData); - int cc = nearestCaveCeiling(c, x - 1, z, currentPostX, currentPostZ, currentData); - int cd = nearestCaveCeiling(c, x, z - 1, currentPostX, currentPostZ, currentData); - - // Cave Nibs - g = 0; - g += fa == f - 1 ? 1 : 0; - g += fb == f - 1 ? 1 : 0; - g += fc == f - 1 ? 1 : 0; - g += fd == f - 1 ? 1 : 0; - - if (g >= 4) { - BlockData bc = getPostBlock(x, f, z, currentPostX, currentPostZ, currentData); - b = getPostBlock(x, f + 1, z, currentPostX, currentPostZ, currentData); - Material m = bc.getMaterial(); - - if (m.isSolid()) { - setPostBlock(x, f, z, b, currentPostX, currentPostZ, currentData); - h--; - } - } else { - // Cave Potholes - g = 0; - g += fa == f + 1 ? 1 : 0; - g += fb == f + 1 ? 1 : 0; - g += fc == f + 1 ? 1 : 0; - g += fd == f + 1 ? 1 : 0; - - if (g >= 4) { - BlockData ba = getPostBlock(x, fa, z, currentPostX, currentPostZ, currentData); - BlockData bb = getPostBlock(x, fb, z, currentPostX, currentPostZ, currentData); - BlockData bc = getPostBlock(x, fc, z, currentPostX, currentPostZ, currentData); - BlockData bd = getPostBlock(x, fd, z, currentPostX, currentPostZ, currentData); - g = 0; - g = B.isSolid(ba) ? g + 1 : g; - g = B.isSolid(bb) ? g + 1 : g; - g = B.isSolid(bc) ? g + 1 : g; - g = B.isSolid(bd) ? g + 1 : g; - - if (g >= 4) { - setPostBlock(x, f + 1, z, getPostBlock(x, f, z, currentPostX, currentPostZ, currentData), currentPostX, currentPostZ, currentData); - h++; - } - } - } - - if (getDimension().isPostProcessingSlabs()) { - //@builder - if ((fa == f + 1 && isSolidNonSlab(x + 1, fa, z, currentPostX, currentPostZ, currentData)) - || (fb == f + 1 && isSolidNonSlab(x, fb, z + 1, currentPostX, currentPostZ, currentData)) - || (fc == f + 1 && isSolidNonSlab(x - 1, fc, z, currentPostX, currentPostZ, currentData)) - || (fd == f + 1 && isSolidNonSlab(x, fd, z - 1, currentPostX, currentPostZ, currentData))) - //@done - { - BlockData d = cave.getSlab().get(rng, x, f, z, getData()); - - if (d != null) { - boolean cancel = B.isAir(d); - - if (d.getMaterial().equals(Material.SNOW) && f + 1 <= getDimension().getFluidHeight()) { - cancel = true; - } - - if (isSnowLayer(x, f, z, currentPostX, currentPostZ, currentData)) { - cancel = true; - } - - if (!cancel && isAirOrWater(x, f + 1, z, currentPostX, currentPostZ, currentData)) { - setPostBlock(x, f + 1, z, d, currentPostX, currentPostZ, currentData); - } - } - } - - //@builder - if ((ca == c - 1 && isSolidNonSlab(x + 1, ca, z, currentPostX, currentPostZ, currentData)) - || (cb == c - 1 && isSolidNonSlab(x, cb, z + 1, currentPostX, currentPostZ, currentData)) - || (cc == c - 1 && isSolidNonSlab(x - 1, cc, z, currentPostX, currentPostZ, currentData)) - || (cd == c - 1 && isSolidNonSlab(x, cd, z - 1, currentPostX, currentPostZ, currentData))) - //@done - { - BlockData d = cave.getSlab().get(rng, x, c, z, getData()); - - if (d != null) { - boolean cancel = B.isAir(d); - - if (!(d instanceof Slab)) { - cancel = true; - } - - if (isSnowLayer(x, c, z, currentPostX, currentPostZ, currentData)) { - cancel = true; - } - - if (!cancel && isAirOrWater(x, c, z, currentPostX, currentPostZ, currentData)) { - try { - Slab slab = (Slab) d.clone(); - slab.setType(Slab.Type.TOP); - setPostBlock(x, c, z, slab, currentPostX, currentPostZ, currentData); - } catch (Throwable e) { - Iris.reportError(e); - try { - Slab slab = (Slab) d.clone(); - - synchronized (slab) { - slab.setType(Slab.Type.TOP); - setPostBlock(x, c, z, slab, currentPostX, currentPostZ, currentData); - } - } catch (Throwable ee) { - Iris.reportError(ee); - } - } - } - } - } - } - } - } - } - } - - private int nearestCaveFloor(int floor, int x, int z, int currentPostX, int currentPostZ, Hunk currentData) { - if (floor >= currentData.getHeight()) { - return currentData.getHeight() - 1; - } - - if (B.isAir(getPostBlock(x, floor, z, currentPostX, currentPostZ, currentData))) { - if (B.isAir(getPostBlock(x, floor - 1, z, currentPostX, currentPostZ, currentData))) { - return floor - 2; - } - - return floor - 1; - } else { - if (!B.isAir(getPostBlock(x, floor + 1, z, currentPostX, currentPostZ, currentData))) { - if (!B.isAir(getPostBlock(x, floor + 2, z, currentPostX, currentPostZ, currentData))) { - return floor + 2; - } - - return floor + 1; - } - - return floor; - } - } - - private int nearestCaveCeiling(int ceiling, int x, int z, int currentPostX, int currentPostZ, Hunk currentData) { - if (ceiling >= currentData.getHeight()) { - return currentData.getHeight() - 1; - } - - if (B.isAir(getPostBlock(x, ceiling, z, currentPostX, currentPostZ, currentData))) { - if (B.isAir(getPostBlock(x, ceiling + 1, z, currentPostX, currentPostZ, currentData))) { - return ceiling + 2; - } - - return ceiling + 1; - } else { - if (!B.isAir(getPostBlock(x, ceiling - 1, z, currentPostX, currentPostZ, currentData))) { - if (!B.isAir(getPostBlock(x, ceiling - 2, z, currentPostX, currentPostZ, currentData))) { - return ceiling - 2; - } - - return ceiling - 1; - } - - return ceiling; - } } public boolean isAir(int x, int y, int z, int currentPostX, int currentPostZ, Hunk currentData) { diff --git a/src/main/java/com/volmit/iris/engine/modifier/IrisRavineModifier.java b/src/main/java/com/volmit/iris/engine/modifier/IrisRavineModifier.java deleted file mode 100644 index 8563d032c..000000000 --- a/src/main/java/com/volmit/iris/engine/modifier/IrisRavineModifier.java +++ /dev/null @@ -1,286 +0,0 @@ -/* - * Iris is a World Generator for Minecraft Bukkit Servers - * Copyright (c) 2021 Arcane Arts (Volmit Software) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.volmit.iris.engine.modifier; - -import com.volmit.iris.engine.framework.Engine; -import com.volmit.iris.engine.framework.EngineAssignedModifier; -import com.volmit.iris.engine.object.noise.NoiseStyle; -import com.volmit.iris.util.data.B; -import com.volmit.iris.util.hunk.Hunk; -import com.volmit.iris.util.math.BlockPosition; -import com.volmit.iris.util.math.MathHelper; -import com.volmit.iris.util.math.Position2; -import com.volmit.iris.util.math.RNG; -import com.volmit.iris.util.noise.CNG; -import com.volmit.iris.util.scheduling.PrecisionStopwatch; -import org.bukkit.Material; -import org.bukkit.block.data.BlockData; - -@SuppressWarnings("ALL") -public class IrisRavineModifier extends EngineAssignedModifier { - private static final BlockData CAVE_AIR = B.get("CAVE_AIR"); - private static final BlockData LAVA = B.get("LAVA"); - private final CNG cng; - private final RNG rng; - - public IrisRavineModifier(Engine engine) { - super(engine, "Ravine"); - rng = new RNG(getEngine().getWorld().seed()).nextParallelRNG(29596878); - cng = NoiseStyle.IRIS_THICK.create(rng); - } - - @Override - public void onModify(int x, int z, Hunk output, boolean multicore) { - if (!getDimension().isRavines()) { - return; - } - - PrecisionStopwatch p = PrecisionStopwatch.start(); - generateRavines(rng, Math.floorDiv(x, 16), Math.floorDiv(z, 16), output); - getEngine().getMetrics().getRavine().put(p.getMilliseconds()); - } - - private void set(Hunk pos, int x, int y, int z, BlockData b) { - pos.set(x, y, z, b); - } - - private BlockData get(Hunk pos, int x, int y, int z) { - BlockData bb = pos.get(x, y, z); - - if (bb == null) { - bb = CAVE_AIR; - } - - return bb; - } - - private BlockData getSurfaceBlock(int n6, int i, RNG rmg) { - return getComplex().getTrueBiomeStream().get(n6, i).getSurfaceBlock(n6, i, rmg, getData()); - } - - private final float[] ravineCache = new float[1024]; - - private void doRavine(long seed, int tx, int tz, Position2 pos, double sx, double sy, double sz, float f, float f2, float f3, @SuppressWarnings("SameParameterValue") int n3, @SuppressWarnings("SameParameterValue") int n4, @SuppressWarnings("SameParameterValue") double d4, RNG bbx, Hunk terrain) { - int n5; - RNG random = new RNG(seed); - double x = tx * 16 + 8; - double z = tz * 16 + 8; - float f4 = 0.0f; - float f5 = 0.0f; - if (n4 <= 0) { - n5 = 8 * 16 - 16; - n4 = n5 - random.nextInt(n5 / 4); - } - n5 = 0; - if (n3 == -1) { - n3 = n4 / 2; - n5 = 1; - } - float f6 = 1.0f; - // TODO: WARNING HEIGHT - for (int i = 0; i < 256; ++i) { - if (i == 0 || random.nextInt(getDimension().getRavineRibRarity()) == 0) { - f6 = 1.0f + random.nextFloat() * random.nextFloat() * 1.0f; - } - this.ravineCache[i] = f6 * f6; - } - while (n3 < n4) { - double d7 = 1.5 + (double) (MathHelper.sin((float) n3 * 3.1415927f / (float) n4) * f * 1.0f); - double d8 = d7 * d4; - d7 *= (double) random.nextFloat() * 0.25 + 0.75; - d8 *= (double) random.nextFloat() * 0.25 + 0.75; - float f7 = MathHelper.cos(f3); - float f8 = MathHelper.sin(f3); - sx = sx + (double) (MathHelper.cos(f2) * f7); - sy += f8; - sz += MathHelper.sin(f2) * f7; - f3 *= 0.7f; - f3 += f5 * 0.05f; - f2 += f4 * 0.05f; - f5 *= 0.8f; - f4 *= 0.5f; - f5 += (random.nextFloat() - random.nextFloat()) * random.nextFloat() * 2.0f; - f4 += (random.nextFloat() - random.nextFloat()) * random.nextFloat() * 4.0f; - if (n5 != 0 || random.nextInt(4) != 0) { - double d9 = sx - x; - double d10 = sz - z; - double d11 = n4 - n3; - double d12 = f + 2.0f + 16.0f; - if (d9 * d9 + d10 * d10 - d11 * d11 > d12 * d12) { - return; - } - if (sx >= x - 16.0 - d7 * 2.0 && sz >= z - 16.0 - d7 * 2.0 && sx <= x + 16.0 + d7 * 2.0 && sz <= z + 16.0 + d7 * 2.0) { - int n6; - int n7 = MathHelper.floor(sx - d7) - tx * 16 - 1; - int n8 = MathHelper.floor(sx + d7) - tx * 16 + 1; - int n9 = MathHelper.floor(sy - d8) - 1; - int n10 = MathHelper.floor(sy + d8) + 1; - int n11 = MathHelper.floor(sz - d7) - tz * 16 - 1; - int n12 = MathHelper.floor(sz + d7) - tz * 16 + 1; - if (n7 < 0) { - n7 = 0; - } - if (n8 > 16) { - n8 = 16; - } - if (n9 < 1) { - n9 = 1; - } - if (n10 > 248) { - n10 = 248; - } - if (n11 < 0) { - n11 = 0; - } - if (n12 > 16) { - n12 = 16; - } - boolean bl = false; - for (int i = n7; !bl && i < n8; ++i) { - for (n6 = n11; !bl && n6 < n12; ++n6) { - for (int j = n10 + 1; !bl && j >= n9 - 1; --j) { - // TODO: WARNING HEIGHT - if (j < 0 || j >= 256) { - continue; - } - - BlockData bb = get(terrain, i, j, n6); - - if (B.isWater(bb)) { - bl = true; - } - - if (j == n9 - 1 || i == n7 || i == n8 - 1 || n6 == n11 || n6 == n12 - 1) { - continue; - } - j = n9; - } - } - } - if (!bl) { - BlockPosition bps = new BlockPosition(0, 0, 0); - for (n6 = n7; n6 < n8; ++n6) { - double d13 = ((double) (n6 + tx * 16) + 0.5 - sx) / d7; - for (int i = n11; i < n12; ++i) { - double d14 = ((double) (i + tz * 16) + 0.5 - sz) / d7; - boolean bl2 = false; - if (d13 * d13 + d14 * d14 >= 1.0) { - continue; - } - for (int j = n10; j > n9; --j) { - double d15 = ((double) (j - 1) + 0.5 - sy) / d8; - if ((d13 * d13 + d14 * d14) * (double) this.ravineCache[j - 1] + d15 * d15 / 6.0 >= 1.0) { - continue; - } - - BlockData blockData = get(terrain, n6, j, i); - - if (isSurface(blockData)) { - bl2 = true; - } - - if (j - 1 < 10) { - set(terrain, n6, j, i, LAVA); - continue; - } - - set(terrain, n6, j, i, CAVE_AIR); - if (!bl2 || !isDirt(get(terrain, n6, j - 1, i))) { - continue; - } - - cSet(bps, n6 + tx * 16, 0, i + tz * 16); - set(terrain, n6, j - 1, i, getSurfaceBlock(n6, i, rng)); - } - } - } - if (n5 != 0) { - break; - } - } - } - } - ++n3; - } - } - - private BlockPosition cSet(BlockPosition bb, double var0, @SuppressWarnings("SameParameterValue") double var2, double var4) { - bb.setX(MathHelper.floor(var0)); - bb.setY(MathHelper.floor(var2)); - bb.setZ(MathHelper.floor(var4)); - - return bb; - } - - private boolean isDirt(BlockData d) { - //@builder - Material m = d.getMaterial(); - return m.equals(Material.DIRT) || - m.equals(Material.COARSE_DIRT) || - m.equals(Material.SAND); - //@done - } - - private boolean isSurface(BlockData d) { - //@builder - Material m = d.getMaterial(); - return m.equals(Material.GRASS_BLOCK) || - m.equals(Material.DIRT) || - m.equals(Material.COARSE_DIRT) || - m.equals(Material.PODZOL) || - m.equals(Material.SAND); - //@done - } - - public void genRavines(int n, int n2, Position2 chunkSnapshot, RNG bbb, Hunk terrain) { - RNG b = this.rng.nextParallelRNG(21949666); - RNG bx = this.rng.nextParallelRNG(6676121); - long l = b.nextLong(); - long l2 = b.nextLong(); - for (int i = n - 8; i <= n + 8; ++i) { - for (int j = n2 - 8; j <= n2 + 8; ++j) { - long l3 = (long) i * l; - long l4 = (long) j * l2; - bx = this.rng.nextParallelRNG((int) (l3 ^ l4 ^ 6676121)); - doRavines(i, j, n, n2, chunkSnapshot, bx, terrain); - } - } - } - - private void doRavines(int tx, int tz, int sx, int sz, Position2 chunkSnapshot, RNG b, Hunk terrain) { - if (b.nextInt(getDimension().getRavineRarity()) != 0) { - return; - } - - double x = tx * 16 + b.nextInt(16); - double d2 = b.nextInt(b.nextInt(40) + 8) + 20; - double z = tz * 16 + b.nextInt(16); - int n5 = 1; - for (int i = 0; i < n5; ++i) { - float f = b.nextFloat() * 3.1415927f * 2.0f; - float f2 = (b.nextFloat() - 0.5f) * 2.0f / 8.0f; - float f3 = (b.nextFloat() * 2.0f + b.nextFloat()) * 2.0f; - this.doRavine(b.nextLong(), sx, sz, chunkSnapshot, x, d2, z, f3, f, f2, 0, 0, 3.0, b, terrain); - } - } - - public void generateRavines(RNG nextParallelRNG, int x, int z, Hunk terrain) { - genRavines(x, z, new Position2(x, z), nextParallelRNG.nextParallelRNG(x).nextParallelRNG(z), terrain); - } -} diff --git a/src/main/java/com/volmit/iris/engine/object/annotations/RegistryListResource.java b/src/main/java/com/volmit/iris/engine/object/annotations/RegistryListResource.java index ea5165f61..5478658b5 100644 --- a/src/main/java/com/volmit/iris/engine/object/annotations/RegistryListResource.java +++ b/src/main/java/com/volmit/iris/engine/object/annotations/RegistryListResource.java @@ -18,7 +18,7 @@ package com.volmit.iris.engine.object.annotations; -import com.volmit.iris.core.project.loader.IrisRegistrant; +import com.volmit.iris.core.loader.IrisRegistrant; import java.lang.annotation.Retention; import java.lang.annotation.Target; diff --git a/src/main/java/com/volmit/iris/engine/object/basic/IrisPosition.java b/src/main/java/com/volmit/iris/engine/object/basic/IrisPosition.java index 6e2d9deea..75d44ce6f 100644 --- a/src/main/java/com/volmit/iris/engine/object/basic/IrisPosition.java +++ b/src/main/java/com/volmit/iris/engine/object/basic/IrisPosition.java @@ -80,4 +80,12 @@ public class IrisPosition { public String toString() { return "[" + getX() + "," + getY() + "," + getZ() + "]"; } + + public boolean isLongerThan(IrisPosition s, int maxLength) { + return Math.abs(Math.pow(s.x - x,2) + Math.pow(s.y - y,2) + Math.pow(s.z - z,2)) > maxLength * maxLength; + } + + public Vector toVector() { + return new Vector(x, y, z); + } } diff --git a/src/main/java/com/volmit/iris/engine/object/biome/InferredType.java b/src/main/java/com/volmit/iris/engine/object/biome/InferredType.java index db9a22215..121ca032e 100644 --- a/src/main/java/com/volmit/iris/engine/object/biome/InferredType.java +++ b/src/main/java/com/volmit/iris/engine/object/biome/InferredType.java @@ -34,12 +34,6 @@ public enum InferredType { @Desc("Represents any cave biome type") CAVE, - @Desc("Represents any river biome type") - RIVER, - - @Desc("Represents any lake biome type") - LAKE, - @Desc("Defers the type to whatever another biome type that already exists is.") DEFER } diff --git a/src/main/java/com/volmit/iris/engine/object/biome/IrisBiome.java b/src/main/java/com/volmit/iris/engine/object/biome/IrisBiome.java index 538475740..a1fd907cc 100644 --- a/src/main/java/com/volmit/iris/engine/object/biome/IrisBiome.java +++ b/src/main/java/com/volmit/iris/engine/object/biome/IrisBiome.java @@ -20,13 +20,14 @@ package com.volmit.iris.engine.object.biome; import com.volmit.iris.Iris; import com.volmit.iris.core.gui.components.RenderType; -import com.volmit.iris.core.project.loader.IrisData; -import com.volmit.iris.core.project.loader.IrisRegistrant; +import com.volmit.iris.core.loader.IrisData; +import com.volmit.iris.core.loader.IrisRegistrant; import com.volmit.iris.engine.IrisComplex; 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.engine.object.block.IrisBlockDrops; +import com.volmit.iris.engine.object.carving.IrisCarving; import com.volmit.iris.engine.object.common.IRare; import com.volmit.iris.engine.object.decoration.IrisDecorator; import com.volmit.iris.engine.object.deposits.IrisDepositGenerator; @@ -115,6 +116,9 @@ public class IrisBiome extends IrisRegistrant implements IRare { @Desc("The max layers to iterate below the surface for locked layer biomes (mesa).") private int lockLayersMax = 7; + @Desc("Carving configuration for the dimension") + private IrisCarving carving = new IrisCarving(); + @MinNumber(1) @MaxNumber(512) @Desc("The rarity of this biome (integer)") @@ -548,22 +552,8 @@ public class IrisBiome extends IrisRegistrant implements IRare { return inferredType.equals(InferredType.SEA); } - public boolean isLake() { - if (inferredType == null) { - return false; - } - return inferredType.equals(InferredType.LAKE); - } - - public boolean isRiver() { - if (inferredType == null) { - return false; - } - return inferredType.equals(InferredType.RIVER); - } - public boolean isAquatic() { - return isSea() || isLake() || isRiver(); + return isSea(); } @SuppressWarnings("BooleanMethodIsAlwaysInverted") diff --git a/src/main/java/com/volmit/iris/engine/object/biome/IrisBiomePaletteLayer.java b/src/main/java/com/volmit/iris/engine/object/biome/IrisBiomePaletteLayer.java index 914ff0d03..44fcf4bb6 100644 --- a/src/main/java/com/volmit/iris/engine/object/biome/IrisBiomePaletteLayer.java +++ b/src/main/java/com/volmit/iris/engine/object/biome/IrisBiomePaletteLayer.java @@ -18,7 +18,7 @@ package com.volmit.iris.engine.object.biome; -import com.volmit.iris.core.project.loader.IrisData; +import com.volmit.iris.core.loader.IrisData; import com.volmit.iris.engine.data.cache.AtomicCache; import com.volmit.iris.engine.object.annotations.*; import com.volmit.iris.engine.object.block.IrisBlockData; diff --git a/src/main/java/com/volmit/iris/engine/object/block/IrisBlockData.java b/src/main/java/com/volmit/iris/engine/object/block/IrisBlockData.java index df29b7a01..9c1bb5477 100644 --- a/src/main/java/com/volmit/iris/engine/object/block/IrisBlockData.java +++ b/src/main/java/com/volmit/iris/engine/object/block/IrisBlockData.java @@ -19,8 +19,8 @@ package com.volmit.iris.engine.object.block; import com.volmit.iris.Iris; -import com.volmit.iris.core.project.loader.IrisData; -import com.volmit.iris.core.project.loader.IrisRegistrant; +import com.volmit.iris.core.loader.IrisData; +import com.volmit.iris.core.loader.IrisRegistrant; import com.volmit.iris.engine.data.cache.AtomicCache; import com.volmit.iris.engine.object.annotations.*; import com.volmit.iris.util.collection.KList; diff --git a/src/main/java/com/volmit/iris/engine/object/block/IrisBlockDrops.java b/src/main/java/com/volmit/iris/engine/object/block/IrisBlockDrops.java index 26d95dbf3..8ad5b7e95 100644 --- a/src/main/java/com/volmit/iris/engine/object/block/IrisBlockDrops.java +++ b/src/main/java/com/volmit/iris/engine/object/block/IrisBlockDrops.java @@ -18,7 +18,7 @@ package com.volmit.iris.engine.object.block; -import com.volmit.iris.core.project.loader.IrisData; +import com.volmit.iris.core.loader.IrisData; import com.volmit.iris.engine.data.cache.AtomicCache; import com.volmit.iris.engine.object.annotations.ArrayType; import com.volmit.iris.engine.object.annotations.Desc; diff --git a/src/main/java/com/volmit/iris/engine/object/block/IrisMaterialPalette.java b/src/main/java/com/volmit/iris/engine/object/block/IrisMaterialPalette.java index 6e85779e7..ef140e345 100644 --- a/src/main/java/com/volmit/iris/engine/object/block/IrisMaterialPalette.java +++ b/src/main/java/com/volmit/iris/engine/object/block/IrisMaterialPalette.java @@ -18,7 +18,7 @@ package com.volmit.iris.engine.object.block; -import com.volmit.iris.core.project.loader.IrisData; +import com.volmit.iris.core.loader.IrisData; import com.volmit.iris.engine.data.cache.AtomicCache; import com.volmit.iris.engine.object.annotations.ArrayType; import com.volmit.iris.engine.object.annotations.Desc; diff --git a/src/main/java/com/volmit/iris/engine/object/carve/IrisCarveLayer.java b/src/main/java/com/volmit/iris/engine/object/carve/IrisCarveLayer.java deleted file mode 100644 index 17df021a5..000000000 --- a/src/main/java/com/volmit/iris/engine/object/carve/IrisCarveLayer.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Iris is a World Generator for Minecraft Bukkit Servers - * Copyright (c) 2021 Arcane Arts (Volmit Software) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.volmit.iris.engine.object.carve; - -import com.volmit.iris.core.project.loader.IrisData; -import com.volmit.iris.engine.data.cache.AtomicCache; -import com.volmit.iris.engine.object.annotations.Desc; -import com.volmit.iris.engine.object.annotations.MaxNumber; -import com.volmit.iris.engine.object.annotations.MinNumber; -import com.volmit.iris.engine.object.annotations.Required; -import com.volmit.iris.engine.object.noise.IrisGeneratorStyle; -import com.volmit.iris.util.interpolation.IrisInterpolation; -import com.volmit.iris.util.math.M; -import com.volmit.iris.util.math.RNG; -import com.volmit.iris.util.noise.CNG; -import com.volmit.iris.util.stream.ProceduralStream; -import com.volmit.iris.util.stream.interpolation.Interpolated; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; -import lombok.experimental.Accessors; - -@Accessors(chain = true) -@NoArgsConstructor -@AllArgsConstructor -@Desc("Translate objects") -@Data -public class IrisCarveLayer { - @Required - @Desc("The 4d slope this carve layer follows") - private IrisGeneratorStyle style = new IrisGeneratorStyle(); - - @MaxNumber(512) - @MinNumber(-128) - @Desc("The max height") - private int maxHeight = 220; - - @MinNumber(0.0) - @MaxNumber(1.0) - @Desc("The full percentage means the 4D opacity of this carver will decay from 100% to 0% at the min & max vertical ranges. Setting the percent to 1.0 will make a very drastic & charp change at the edge of the vertical min & max. Where as 0.15 means only 15% of the vertical range will actually be 100% opacity.") - private double fullPercent = 0.5; - - @MaxNumber(512) - @MinNumber(-128) - @Desc("The min height") - private int minHeight = 147; - - @MaxNumber(1) - @MinNumber(0) - @Desc("The threshold used as: \n\ncarved = noise(x,y,z) > threshold") - private double threshold = 0.5; - - private final transient AtomicCache> streamCache = new AtomicCache<>(); - private final transient AtomicCache> rawStreamCache = new AtomicCache<>(); - private final transient AtomicCache cng = new AtomicCache<>(); - - public boolean isCarved(RNG rng, IrisData data, double x, double y, double z) { - if (y > getMaxHeight() || y < getMinHeight()) { - return false; - } - - double opacity = Math.pow(IrisInterpolation.sinCenter(M.lerpInverse(getMinHeight(), getMaxHeight(), y)), 4); - return getCng(rng, data).fitDouble(0D, 1D, x, y, z) * opacity > getThreshold(); - } - - public ProceduralStream stream(RNG rng, IrisData data) { - return streamCache.aquire(() -> ProceduralStream.of((x, y, z) -> isCarved(rng, data, x, y, z), Interpolated.BOOLEAN)); - } - - public ProceduralStream rawStream(RNG rng, IrisData data) { - return rawStreamCache.aquire(() -> ProceduralStream.of((x, y, z) -> { - return getCng(rng, data).fitDouble(0D, 1D, x, y, z) * Math.pow(IrisInterpolation.sinCenter(M.lerpInverse(getMinHeight(), getMaxHeight(), y)), 4); - }, Interpolated.DOUBLE)); - } - - public CNG getCng(RNG rng, IrisData data) { - return cng.aquire(() -> getStyle().create(rng.nextParallelRNG(-2340 * getMaxHeight() * getMinHeight()), data)); - } - - public boolean isCarved2(RNG rng, IrisData data, double x, double y, double z) { - if (y > getMaxHeight() || y < getMinHeight()) { - return false; - } - - double innerRange = fullPercent * (maxHeight - minHeight); - double opacity = 1D; - - if (y <= minHeight + innerRange) { - opacity = IrisInterpolation.bezier(M.lerpInverse(getMinHeight(), minHeight + innerRange, y)); - } else if (y >= maxHeight - innerRange) { - opacity = IrisInterpolation.bezier(1D - M.lerpInverse(maxHeight - innerRange, getMaxHeight(), y)); - } - - return cng.aquire(() -> getStyle().create(rng.nextParallelRNG(-2340 * getMaxHeight() * getMinHeight()), data)).fitDouble(0D, 1D, x, y, z) * opacity > getThreshold(); - } -} diff --git a/src/main/java/com/volmit/iris/engine/object/carve/IrisCaveFluid.java b/src/main/java/com/volmit/iris/engine/object/carve/IrisCaveFluid.java deleted file mode 100644 index fad1f51c4..000000000 --- a/src/main/java/com/volmit/iris/engine/object/carve/IrisCaveFluid.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Iris is a World Generator for Minecraft Bukkit Servers - * Copyright (c) 2021 Arcane Arts (Volmit Software) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.volmit.iris.engine.object.carve; - -import com.volmit.iris.core.project.loader.IrisData; -import com.volmit.iris.engine.data.cache.AtomicCache; -import com.volmit.iris.engine.object.annotations.Desc; -import com.volmit.iris.engine.object.annotations.MaxNumber; -import com.volmit.iris.engine.object.annotations.MinNumber; -import com.volmit.iris.engine.object.annotations.Required; -import com.volmit.iris.engine.object.block.IrisBlockData; -import com.volmit.iris.util.data.B; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; -import lombok.experimental.Accessors; -import org.bukkit.block.data.BlockData; - -@Accessors(chain = true) -@NoArgsConstructor -@AllArgsConstructor -@Desc("Translate objects") -@Data -public class IrisCaveFluid { - @Required - @MaxNumber(255) - @MinNumber(0) - @Desc("The fluid height of the cave") - private int fluidHeight = 35; - - @Desc("Insead of fluidHeight & below being fluid, turning inverse height on will simply spawn fluid in this cave layer from min(max_height, cave_height) to the fluid height. Basically, fluid will spawn above the fluidHeight value instead of below the fluidHeight.") - private boolean inverseHeight = false; - - @Required - @Desc("The fluid type that should spawn here") - private IrisBlockData fluidType = new IrisBlockData("CAVE_AIR"); - - private final transient AtomicCache fluidData = new AtomicCache<>(); - - public boolean hasFluid(IrisData rdata) { - return !B.isAir(getFluid(rdata)); - } - - public BlockData getFluid(IrisData rdata) { - return fluidData.aquire(() -> - { - BlockData b = getFluidType().getBlockData(rdata); - - if (b != null) { - return b; - } - - return B.get("CAVE_AIR"); - }); - } -} diff --git a/src/main/java/com/volmit/iris/engine/object/carve/IrisCaveLayer.java b/src/main/java/com/volmit/iris/engine/object/carve/IrisCaveLayer.java deleted file mode 100644 index bf282daec..000000000 --- a/src/main/java/com/volmit/iris/engine/object/carve/IrisCaveLayer.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Iris is a World Generator for Minecraft Bukkit Servers - * Copyright (c) 2021 Arcane Arts (Volmit Software) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.volmit.iris.engine.object.carve; - -import com.volmit.iris.engine.object.annotations.Desc; -import com.volmit.iris.engine.object.annotations.MinNumber; -import com.volmit.iris.engine.object.annotations.Required; -import com.volmit.iris.engine.object.noise.IrisShapedGeneratorStyle; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; -import lombok.experimental.Accessors; - -@Accessors(chain = true) -@NoArgsConstructor -@AllArgsConstructor -@Desc("Translate objects") -@Data -public class IrisCaveLayer { - @Required - @Desc("The vertical slope this cave layer follows") - private IrisShapedGeneratorStyle verticalSlope = new IrisShapedGeneratorStyle(); - - @Required - @Desc("The horizontal slope this cave layer follows") - private IrisShapedGeneratorStyle horizontalSlope = new IrisShapedGeneratorStyle(); - - @Desc("If defined, a cave fluid will fill this cave below (or above) the specified fluidHeight in this object.") - private IrisCaveFluid fluid = new IrisCaveFluid(); - - @MinNumber(0.001) - @Desc("The cave zoom. Higher values makes caves spread out further and branch less often, but are thicker.") - private double caveZoom = 1D; - - @MinNumber(0.001) - @Desc("The cave thickness.") - private double caveThickness = 1D; - - @Desc("If set to true, this cave layer can break the surface") - private boolean canBreakSurface = false; - -} diff --git a/src/main/java/com/volmit/iris/engine/object/carve/IrisCavernZone.java b/src/main/java/com/volmit/iris/engine/object/carve/IrisCavernZone.java deleted file mode 100644 index 24e233b81..000000000 --- a/src/main/java/com/volmit/iris/engine/object/carve/IrisCavernZone.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Iris is a World Generator for Minecraft Bukkit Servers - * Copyright (c) 2021 Arcane Arts (Volmit Software) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.volmit.iris.engine.object.carve; - -import com.volmit.iris.core.project.loader.IrisData; -import com.volmit.iris.engine.data.cache.AtomicCache; -import com.volmit.iris.engine.object.annotations.Desc; -import com.volmit.iris.engine.object.annotations.MaxNumber; -import com.volmit.iris.engine.object.annotations.MinNumber; -import com.volmit.iris.engine.object.common.IRare; -import com.volmit.iris.engine.object.noise.IrisGeneratorStyle; -import com.volmit.iris.util.math.RNG; -import com.volmit.iris.util.stream.ProceduralStream; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; -import lombok.experimental.Accessors; - -@Accessors(chain = true) -@NoArgsConstructor -@AllArgsConstructor -@Desc("Represents a cavern zone") -@Data -public class IrisCavernZone implements IRare { - @Desc("Use carving in this zone if defined") - private IrisCarveLayer carver = null; - - @Desc("Use worley styled caves if defined") - private IrisGeneratorStyle worley = null; - - @MinNumber(1) - @MaxNumber(100) - @Desc("The rarity of this zone") - private int rarity = 1; - - private transient AtomicCache> carveCache = new AtomicCache<>(); - - public boolean isCarved(RNG rng, IrisData data, double xx, double yy, double zz) { - if (carver != null) { - return carver.isCarved(rng, data, xx, yy, zz); - } - - return false; - } - - public double getCarved(RNG rng, IrisData data, double xx, double yy, double zz) { - if (carver != null) { - return carver.rawStream(rng, data).get(xx, yy, zz) / (carver.getThreshold() * 2); - } - - return -1; - } -} diff --git a/src/main/java/com/volmit/iris/engine/object/carve/IrisCaverns.java b/src/main/java/com/volmit/iris/engine/object/carve/IrisCaverns.java deleted file mode 100644 index b11c3ab82..000000000 --- a/src/main/java/com/volmit/iris/engine/object/carve/IrisCaverns.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Iris is a World Generator for Minecraft Bukkit Servers - * Copyright (c) 2021 Arcane Arts (Volmit Software) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.volmit.iris.engine.object.carve; - -import com.volmit.iris.core.project.loader.IrisData; -import com.volmit.iris.engine.data.cache.AtomicCache; -import com.volmit.iris.engine.object.annotations.ArrayType; -import com.volmit.iris.engine.object.annotations.Desc; -import com.volmit.iris.engine.object.noise.IrisGeneratorStyle; -import com.volmit.iris.engine.object.noise.IrisInterpolator3D; -import com.volmit.iris.engine.object.noise.NoiseStyle; -import com.volmit.iris.util.collection.KList; -import com.volmit.iris.util.math.RNG; -import com.volmit.iris.util.stream.ProceduralStream; -import com.volmit.iris.util.stream.interpolation.Interpolated; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; -import lombok.experimental.Accessors; - -@Accessors(chain = true) -@NoArgsConstructor -@AllArgsConstructor -@Desc("Represents a cavern system") -@Data -public class IrisCaverns { - @ArrayType(type = IrisCavernZone.class, min = 1) - @Desc("Define different cavern zones") - private KList zones = new KList<>(); - - @Desc("The 3D interpolator to connect caverns") - private IrisInterpolator3D interpolator = new IrisInterpolator3D(); - - @Desc("Defines how cavern zones are placed in the world") - private IrisGeneratorStyle zoneStyle = new IrisGeneratorStyle(NoiseStyle.CELLULAR); - - @Desc("Threshold defined") - private double bottomBleed = 16; - - @Desc("Threshold defined") - private double topBleed = 16; - - @Desc("If set to true (default) iris will interpolate the noise before checking if it meets the threshold.") - private boolean preThresholdInterpolation = true; - - private transient AtomicCache> zonesRarity = new AtomicCache<>(); - private transient AtomicCache> streamCache = new AtomicCache<>(); - - public IrisCavernZone getZone(double x, double y, double z, RNG rng, IrisData data) { - return zonesRarity.aquire(() -> zoneStyle.create(rng, data) - .stream().selectRarity(getZones())).get(x, y, z); - } - - private double threshold(double y) { - return 0.5; - } - - public ProceduralStream stream(RNG rng, IrisData data) { - if (preThresholdInterpolation) { - return streamCache.aquire(() -> ProceduralStream.of((xx, yy, zz) - -> (getZone(xx, yy, zz, rng, data) - .getCarved(rng, data, xx, yy, zz)), Interpolated.DOUBLE) - .cache3D(65535)); - } - - return streamCache.aquire(() -> ProceduralStream.of((xx, yy, zz) - -> (getZone(xx, yy, zz, rng, data) - .isCarved(rng, data, xx, yy, zz) ? 1D : 0D), Interpolated.DOUBLE) - .cache3D(65535)); - } - - public boolean isCavern(RNG rng, double x, double y, double z, double height, IrisData data) { - if (zones.isEmpty()) { - return false; - } - - return getInterpolator().interpolate(x, y, z, (xx, yy, zz) - -> stream(rng, data).get(xx, yy, zz)) > threshold(height); - } -} diff --git a/src/main/java/com/volmit/iris/engine/object/carving/IrisCarving.java b/src/main/java/com/volmit/iris/engine/object/carving/IrisCarving.java new file mode 100644 index 000000000..ba558fa8e --- /dev/null +++ b/src/main/java/com/volmit/iris/engine/object/carving/IrisCarving.java @@ -0,0 +1,127 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.engine.object.carving; + +import com.volmit.iris.core.loader.IrisData; +import com.volmit.iris.engine.framework.Engine; +import com.volmit.iris.engine.mantle.MantleWriter; +import com.volmit.iris.engine.object.annotations.ArrayType; +import com.volmit.iris.engine.object.annotations.Desc; +import com.volmit.iris.util.collection.KList; +import com.volmit.iris.util.documentation.BlockCoordinates; +import com.volmit.iris.util.math.RNG; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; + +@Accessors(chain = true) +@NoArgsConstructor +@AllArgsConstructor +@Desc("Represents a carving configuration") +@Data +public class IrisCarving { + @ArrayType(type = IrisCavePlacer.class, min = 1) + @Desc("Define cave placers") + private KList caves = new KList<>(); + + @ArrayType(type = IrisElipsoid.class, min = 1) + @Desc("Define elipsoids") + private KList elipsoids = new KList<>(); + + @ArrayType(type = IrisSphere.class, min = 1) + @Desc("Define spheres") + private KList spheres = new KList<>(); + + @ArrayType(type = IrisPyramid.class, min = 1) + @Desc("Define pyramids") + private KList pyramids = new KList<>(); + + + + @BlockCoordinates + public void doCarving(MantleWriter writer, RNG rng, Engine engine, int x, int y, int z) { + if(caves.isNotEmpty()) + { + for(IrisCavePlacer i : caves) + { + i.generateCave(writer, rng, engine, x, y, z); + } + } + + if(spheres.isNotEmpty()) + { + for(IrisSphere i : spheres) + { + if(rng.nextInt(i.getRarity()) == 0) + { + i.generate(rng, engine, writer, x, y, z); + } + } + } + + if(elipsoids.isNotEmpty()) + { + for(IrisElipsoid i : elipsoids) + { + if(rng.nextInt(i.getRarity()) == 0) + { + i.generate(rng, engine, writer, x, y, z); + } + } + } + + if(pyramids.isNotEmpty()) + { + for(IrisPyramid i : pyramids) + { + if(rng.nextInt(i.getRarity()) == 0) + { + i.generate(rng, engine, writer, x, y, z); + } + } + } + } + + public int getMaxRange(IrisData data) { + int max = 0; + + for(IrisCavePlacer i : caves) + { + max = Math.max(max, i.getSize(data)); + } + + if(elipsoids.isNotEmpty()) + { + max = (int) Math.max(elipsoids.stream().mapToDouble(IrisElipsoid::maxSize).max().getAsDouble(), max); + } + + if(spheres.isNotEmpty()) + { + max = (int) Math.max(spheres.stream().mapToDouble(IrisSphere::maxSize).max().getAsDouble(), max); + } + + if(pyramids.isNotEmpty()) + { + max = (int) Math.max(pyramids.stream().mapToDouble(IrisPyramid::maxSize).max().getAsDouble(), max); + } + + return max; + } +} diff --git a/src/main/java/com/volmit/iris/engine/object/cave/IrisCave.java b/src/main/java/com/volmit/iris/engine/object/carving/IrisCave.java similarity index 52% rename from src/main/java/com/volmit/iris/engine/object/cave/IrisCave.java rename to src/main/java/com/volmit/iris/engine/object/carving/IrisCave.java index 4abb7bca7..701d075a7 100644 --- a/src/main/java/com/volmit/iris/engine/object/cave/IrisCave.java +++ b/src/main/java/com/volmit/iris/engine/object/carving/IrisCave.java @@ -16,18 +16,33 @@ * along with this program. If not, see . */ -package com.volmit.iris.engine.object.cave; +package com.volmit.iris.engine.object.carving; -import com.volmit.iris.core.project.loader.IrisRegistrant; +import com.volmit.iris.Iris; +import com.volmit.iris.core.loader.IrisData; +import com.volmit.iris.core.loader.IrisRegistrant; +import com.volmit.iris.engine.framework.Engine; +import com.volmit.iris.engine.mantle.MantleWriter; import com.volmit.iris.engine.object.annotations.Desc; +import com.volmit.iris.engine.object.basic.IrisPosition; +import com.volmit.iris.engine.object.basic.IrisRange; +import com.volmit.iris.engine.object.block.IrisBlockData; import com.volmit.iris.engine.object.noise.IrisWorm; +import com.volmit.iris.engine.object.objects.IrisObjectLimit; +import com.volmit.iris.util.collection.KList; +import com.volmit.iris.util.data.B; import com.volmit.iris.util.json.JSONObject; +import com.volmit.iris.util.math.RNG; +import com.volmit.iris.util.matter.slices.CavernMatter; import com.volmit.iris.util.plugin.VolmitSender; import lombok.AllArgsConstructor; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import lombok.experimental.Accessors; +import org.bukkit.block.data.BlockData; + +import java.util.List; @EqualsAndHashCode(callSuper = true) @Accessors(chain = true) @@ -39,6 +54,12 @@ public class IrisCave extends IrisRegistrant { @Desc("Define the shape of this cave") private IrisWorm worm; + @Desc("Define potential forking features") + private IrisCarving fork = new IrisCarving(); + + @Desc("Limit the worm from ever getting higher or lower than this range") + private IrisRange verticalRange = new IrisRange(3, 255); + @Override public String getFolderName() { return "caves"; @@ -49,8 +70,20 @@ public class IrisCave extends IrisRegistrant { return "Cave"; } + public void generate(MantleWriter writer, RNG rng, Engine engine, int x, int y, int z) { + + writer.setLine(getWorm().generate(rng, engine.getData(), writer, verticalRange, x, y, z, + (at) -> fork.doCarving(writer, rng, engine, at.getX(), at.getY(), at.getZ())), + getWorm().getGirth().get(rng, x, z, engine.getData()), true, + CavernMatter.ON); + } + @Override public void scanForErrors(JSONObject p, VolmitSender sender) { } + + public int getMaxSize(IrisData data) { + return getWorm().getMaxDistance() + fork.getMaxRange(data); + } } diff --git a/src/main/java/com/volmit/iris/engine/object/cave/IrisCavePlacer.java b/src/main/java/com/volmit/iris/engine/object/carving/IrisCavePlacer.java similarity index 58% rename from src/main/java/com/volmit/iris/engine/object/cave/IrisCavePlacer.java rename to src/main/java/com/volmit/iris/engine/object/carving/IrisCavePlacer.java index b31aa2389..7adfa0e04 100644 --- a/src/main/java/com/volmit/iris/engine/object/cave/IrisCavePlacer.java +++ b/src/main/java/com/volmit/iris/engine/object/carving/IrisCavePlacer.java @@ -16,29 +16,26 @@ * along with this program. If not, see . */ -package com.volmit.iris.engine.object.cave; +package com.volmit.iris.engine.object.carving; import com.volmit.iris.Iris; -import com.volmit.iris.core.project.loader.IrisData; +import com.volmit.iris.core.loader.IrisData; import com.volmit.iris.engine.data.cache.AtomicCache; +import com.volmit.iris.engine.framework.Engine; +import com.volmit.iris.engine.mantle.MantleWriter; import com.volmit.iris.engine.object.annotations.Desc; import com.volmit.iris.engine.object.annotations.MinNumber; import com.volmit.iris.engine.object.annotations.RegistryListResource; import com.volmit.iris.engine.object.annotations.Required; -import com.volmit.iris.engine.object.basic.IrisPosition; import com.volmit.iris.engine.object.common.IRare; -import com.volmit.iris.util.collection.KList; -import com.volmit.iris.util.data.B; -import com.volmit.iris.util.mantle.Mantle; +import com.volmit.iris.engine.object.noise.IrisGeneratorStyle; +import com.volmit.iris.engine.object.noise.IrisStyledRange; +import com.volmit.iris.engine.object.noise.NoiseStyle; import com.volmit.iris.util.math.RNG; -import com.volmit.iris.util.noise.Worm3; -import com.volmit.iris.util.noise.WormIterator3; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import lombok.experimental.Accessors; -import org.bukkit.block.data.BlockData; -import org.bukkit.util.Vector; import java.util.concurrent.atomic.AtomicBoolean; @@ -48,10 +45,8 @@ import java.util.concurrent.atomic.AtomicBoolean; @Desc("Translate objects") @Data public class IrisCavePlacer implements IRare { - private static final BlockData CAVE_AIR = B.get("CAVE_AIR"); - @Required - @Desc("Typically a 1 in RARITY on a per chunk basis") + @Desc("Typically a 1 in RARITY on a per chunk/fork basis") @MinNumber(1) private int rarity = 15; @@ -61,6 +56,12 @@ public class IrisCavePlacer implements IRare { @RegistryListResource(IrisCave.class) private String cave; + @Desc("If set to true, this cave is allowed to break the surface") + private boolean breakSurface = true; + + @Desc("The height range this cave can spawn at. If breakSurface is false, the output of this range will be clamped by the current world height to prevent surface breaking.") + private IrisStyledRange caveStartHeight = new IrisStyledRange(13, 120, new IrisGeneratorStyle(NoiseStyle.STATIC)); + private transient final AtomicCache caveCache = new AtomicCache<>(); private transient final AtomicBoolean fail = new AtomicBoolean(false); @@ -68,11 +69,17 @@ public class IrisCavePlacer implements IRare { return caveCache.aquire(() -> data.getCaveLoader().load(getCave())); } - public void generateCave(Mantle mantle, RNG rng, IrisData data, int x, int y, int z) { + public void generateCave(MantleWriter mantle, RNG rng, Engine engine, int x, int y, int z) { if (fail.get()) { return; } + if(rng.nextInt(rarity) != 0) + { + return; + } + + IrisData data = engine.getData(); IrisCave cave = getRealCave(data); if (cave == null) { @@ -81,21 +88,26 @@ public class IrisCavePlacer implements IRare { return; } - WormIterator3 w = cave.getWorm().iterate3D(rng, data, x, y, z); - KList points = new KList<>(); - int itr = 0; - while (w.hasNext()) { - itr++; - Worm3 wx = w.next(); - points.add(new Vector(wx.getX().getPosition(), wx.getY().getPosition(), wx.getZ().getPosition())); + if(y == -1) + { + int h = (int) caveStartHeight.get(rng,x, z,data); + int ma = breakSurface ? h : (int) (engine.getComplex().getHeightStream().get(x, z) - 9); + y = Math.min(h, ma); } + try + { + cave.generate(mantle, rng, engine, x + rng.nextInt(15), y, z + rng.nextInt(15)); + } - Iris.info(x + " " + y + " " + z + " /." + " POS: " + points.convert((i) -> "[" + i.getBlockX() + "," + i.getBlockY() + "," + i.getBlockZ() + "]").toString(", ")); + catch(Throwable e) + { + e.printStackTrace(); + fail.set(true); + } + } - mantle.setLine(points.convert(IrisPosition::new), cave.getWorm().getGirth().get(rng, x, z, data), true, CAVE_AIR); - - - // TODO decorate somehow + public int getSize(IrisData data) { + return getRealCave(data).getMaxSize(data); } } diff --git a/src/main/java/com/volmit/iris/engine/object/carving/IrisElipsoid.java b/src/main/java/com/volmit/iris/engine/object/carving/IrisElipsoid.java new file mode 100644 index 000000000..00acea875 --- /dev/null +++ b/src/main/java/com/volmit/iris/engine/object/carving/IrisElipsoid.java @@ -0,0 +1,64 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.engine.object.carving; + +import com.volmit.iris.engine.framework.Engine; +import com.volmit.iris.engine.mantle.MantleWriter; +import com.volmit.iris.engine.object.annotations.Desc; +import com.volmit.iris.engine.object.annotations.MinNumber; +import com.volmit.iris.engine.object.annotations.Required; +import com.volmit.iris.engine.object.block.IrisBlockData; +import com.volmit.iris.engine.object.common.IRare; +import com.volmit.iris.engine.object.noise.IrisGeneratorStyle; +import com.volmit.iris.engine.object.noise.IrisStyledRange; +import com.volmit.iris.engine.object.noise.NoiseStyle; +import com.volmit.iris.util.math.RNG; +import com.volmit.iris.util.matter.slices.CavernMatter; +import lombok.Data; + +@Desc("Represents an procedural eliptical shape") +@Data +public class IrisElipsoid implements IRare +{ + @Required + @Desc("Typically a 1 in RARITY on a per fork basis") + @MinNumber(1) + private int rarity = 1; + + @Desc("The styled random radius for x") + private IrisStyledRange xRadius = new IrisStyledRange(1, 5, new IrisGeneratorStyle(NoiseStyle.STATIC)); + + @Desc("The styled random radius for y") + private IrisStyledRange yRadius = new IrisStyledRange(1, 5, new IrisGeneratorStyle(NoiseStyle.STATIC)); + + @Desc("The styled random radius for z") + private IrisStyledRange zRadius = new IrisStyledRange(1, 5, new IrisGeneratorStyle(NoiseStyle.STATIC)); + + public void generate(RNG rng, Engine engine, MantleWriter writer, int x, int y, int z) + { + writer.setElipsoid(x, y, z, + xRadius.get(rng, z, y, engine.getData()), + yRadius.get(rng, x, z, engine.getData()), + zRadius.get(rng, y, x, engine.getData()), true, CavernMatter.ON); + } + + public double maxSize() { + return Math.max(xRadius.getMax(), Math.max(yRadius.getMax(), zRadius.getMax())); + } +} diff --git a/src/main/java/com/volmit/iris/engine/object/carving/IrisPyramid.java b/src/main/java/com/volmit/iris/engine/object/carving/IrisPyramid.java new file mode 100644 index 000000000..37828cc54 --- /dev/null +++ b/src/main/java/com/volmit/iris/engine/object/carving/IrisPyramid.java @@ -0,0 +1,56 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.engine.object.carving; + +import com.volmit.iris.engine.framework.Engine; +import com.volmit.iris.engine.mantle.MantleWriter; +import com.volmit.iris.engine.object.annotations.Desc; +import com.volmit.iris.engine.object.annotations.MinNumber; +import com.volmit.iris.engine.object.annotations.Required; +import com.volmit.iris.engine.object.block.IrisBlockData; +import com.volmit.iris.engine.object.common.IRare; +import com.volmit.iris.engine.object.noise.IrisGeneratorStyle; +import com.volmit.iris.engine.object.noise.IrisStyledRange; +import com.volmit.iris.engine.object.noise.NoiseStyle; +import com.volmit.iris.util.math.RNG; +import com.volmit.iris.util.matter.slices.CavernMatter; +import lombok.Data; + +@Desc("Represents an procedural eliptical shape") +@Data +public class IrisPyramid implements IRare +{ + @Required + @Desc("Typically a 1 in RARITY on a per fork basis") + @MinNumber(1) + private int rarity = 1; + + @Desc("The styled random radius for x") + private IrisStyledRange baseWidth = new IrisStyledRange(1, 5, new IrisGeneratorStyle(NoiseStyle.STATIC)); + + public void generate(RNG rng, Engine engine, MantleWriter writer, int x, int y, int z) + { + writer.setPyramid(x, y, z, CavernMatter.ON, + (int)baseWidth.get(rng, z, y, engine.getData()), true); + } + + public double maxSize() { + return baseWidth.getMax(); + } +} diff --git a/src/main/java/com/volmit/iris/engine/object/carving/IrisSphere.java b/src/main/java/com/volmit/iris/engine/object/carving/IrisSphere.java new file mode 100644 index 000000000..7e6f9b4b7 --- /dev/null +++ b/src/main/java/com/volmit/iris/engine/object/carving/IrisSphere.java @@ -0,0 +1,55 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.engine.object.carving; + +import com.volmit.iris.engine.framework.Engine; +import com.volmit.iris.engine.mantle.MantleWriter; +import com.volmit.iris.engine.object.annotations.Desc; +import com.volmit.iris.engine.object.annotations.MinNumber; +import com.volmit.iris.engine.object.annotations.Required; +import com.volmit.iris.engine.object.block.IrisBlockData; +import com.volmit.iris.engine.object.common.IRare; +import com.volmit.iris.engine.object.noise.IrisGeneratorStyle; +import com.volmit.iris.engine.object.noise.IrisStyledRange; +import com.volmit.iris.engine.object.noise.NoiseStyle; +import com.volmit.iris.util.math.RNG; +import com.volmit.iris.util.matter.slices.CavernMatter; +import lombok.Data; + +@Desc("Represents an procedural eliptical shape") +@Data +public class IrisSphere implements IRare +{ + @Required + @Desc("Typically a 1 in RARITY on a per fork basis") + @MinNumber(1) + private int rarity = 1; + + @Desc("The styled random radius for x") + private IrisStyledRange radius = new IrisStyledRange(1, 5, new IrisGeneratorStyle(NoiseStyle.STATIC)); + + public void generate(RNG rng, Engine engine, MantleWriter writer, int x, int y, int z) + { + writer.setSphere(x, y, z, radius.get(rng, z, y, engine.getData()),true, CavernMatter.ON); + } + + public double maxSize() { + return radius.getMax(); + } +} diff --git a/src/main/java/com/volmit/iris/engine/object/common/HeadlessWorld.java b/src/main/java/com/volmit/iris/engine/object/common/HeadlessWorld.java index f5e4a52a5..2dc270534 100644 --- a/src/main/java/com/volmit/iris/engine/object/common/HeadlessWorld.java +++ b/src/main/java/com/volmit/iris/engine/object/common/HeadlessWorld.java @@ -19,7 +19,7 @@ package com.volmit.iris.engine.object.common; import com.volmit.iris.Iris; -import com.volmit.iris.core.project.loader.IrisData; +import com.volmit.iris.core.loader.IrisData; import com.volmit.iris.core.service.StudioSVC; import com.volmit.iris.core.tools.IrisToolbelt; import com.volmit.iris.engine.framework.Engine; diff --git a/src/main/java/com/volmit/iris/engine/object/common/IObjectPlacer.java b/src/main/java/com/volmit/iris/engine/object/common/IObjectPlacer.java index 447c472a2..191c81aeb 100644 --- a/src/main/java/com/volmit/iris/engine/object/common/IObjectPlacer.java +++ b/src/main/java/com/volmit/iris/engine/object/common/IObjectPlacer.java @@ -18,7 +18,7 @@ package com.volmit.iris.engine.object.common; -import com.volmit.iris.core.project.loader.IrisData; +import com.volmit.iris.core.loader.IrisData; import com.volmit.iris.engine.object.tile.TileData; import org.bukkit.block.TileState; import org.bukkit.block.data.BlockData; diff --git a/src/main/java/com/volmit/iris/engine/object/common/IrisScript.java b/src/main/java/com/volmit/iris/engine/object/common/IrisScript.java index 0ad77ac6b..ea4947429 100644 --- a/src/main/java/com/volmit/iris/engine/object/common/IrisScript.java +++ b/src/main/java/com/volmit/iris/engine/object/common/IrisScript.java @@ -18,7 +18,7 @@ package com.volmit.iris.engine.object.common; -import com.volmit.iris.core.project.loader.IrisRegistrant; +import com.volmit.iris.core.loader.IrisRegistrant; import com.volmit.iris.util.json.JSONObject; import com.volmit.iris.util.plugin.VolmitSender; import lombok.Data; diff --git a/src/main/java/com/volmit/iris/engine/object/decoration/IrisDecorator.java b/src/main/java/com/volmit/iris/engine/object/decoration/IrisDecorator.java index 99ce1e2d7..e195c1e27 100644 --- a/src/main/java/com/volmit/iris/engine/object/decoration/IrisDecorator.java +++ b/src/main/java/com/volmit/iris/engine/object/decoration/IrisDecorator.java @@ -19,7 +19,7 @@ package com.volmit.iris.engine.object.decoration; import com.volmit.iris.Iris; -import com.volmit.iris.core.project.loader.IrisData; +import com.volmit.iris.core.loader.IrisData; import com.volmit.iris.engine.data.cache.AtomicCache; import com.volmit.iris.engine.object.annotations.*; import com.volmit.iris.engine.object.biome.IrisBiome; diff --git a/src/main/java/com/volmit/iris/engine/object/deposits/IrisDepositGenerator.java b/src/main/java/com/volmit/iris/engine/object/deposits/IrisDepositGenerator.java index 2fb8e4ba8..90e56a125 100644 --- a/src/main/java/com/volmit/iris/engine/object/deposits/IrisDepositGenerator.java +++ b/src/main/java/com/volmit/iris/engine/object/deposits/IrisDepositGenerator.java @@ -18,7 +18,7 @@ package com.volmit.iris.engine.object.deposits; -import com.volmit.iris.core.project.loader.IrisData; +import com.volmit.iris.core.loader.IrisData; import com.volmit.iris.engine.data.cache.AtomicCache; import com.volmit.iris.engine.object.annotations.*; import com.volmit.iris.engine.object.block.IrisBlockData; diff --git a/src/main/java/com/volmit/iris/engine/object/dimensional/IrisDimension.java b/src/main/java/com/volmit/iris/engine/object/dimensional/IrisDimension.java index c11b89f92..545d705e8 100644 --- a/src/main/java/com/volmit/iris/engine/object/dimensional/IrisDimension.java +++ b/src/main/java/com/volmit/iris/engine/object/dimensional/IrisDimension.java @@ -19,8 +19,8 @@ package com.volmit.iris.engine.object.dimensional; import com.volmit.iris.Iris; -import com.volmit.iris.core.project.loader.IrisData; -import com.volmit.iris.core.project.loader.IrisRegistrant; +import com.volmit.iris.core.loader.IrisData; +import com.volmit.iris.core.loader.IrisRegistrant; import com.volmit.iris.engine.data.cache.AtomicCache; import com.volmit.iris.engine.object.annotations.*; import com.volmit.iris.engine.object.biome.InferredType; @@ -28,10 +28,7 @@ import com.volmit.iris.engine.object.biome.IrisBiome; import com.volmit.iris.engine.object.biome.IrisBiomeCustom; import com.volmit.iris.engine.object.block.IrisBlockDrops; import com.volmit.iris.engine.object.block.IrisMaterialPalette; -import com.volmit.iris.engine.object.carve.IrisCarveLayer; -import com.volmit.iris.engine.object.carve.IrisCaveFluid; -import com.volmit.iris.engine.object.carve.IrisCaveLayer; -import com.volmit.iris.engine.object.carve.IrisCaverns; +import com.volmit.iris.engine.object.carving.IrisCarving; import com.volmit.iris.engine.object.deposits.IrisDepositGenerator; import com.volmit.iris.engine.object.feature.IrisFeaturePositional; import com.volmit.iris.engine.object.feature.IrisFeaturePotential; @@ -41,7 +38,6 @@ import com.volmit.iris.engine.object.loot.IrisLootReference; import com.volmit.iris.engine.object.noise.IrisGeneratorStyle; import com.volmit.iris.engine.object.noise.IrisShapedGeneratorStyle; import com.volmit.iris.engine.object.noise.NoiseStyle; -import com.volmit.iris.engine.object.objects.IrisObjectPlacement; import com.volmit.iris.engine.object.regional.IrisRegion; import com.volmit.iris.engine.object.spawners.IrisSpawner; import com.volmit.iris.engine.object.trees.IrisTreeSettings; @@ -92,6 +88,9 @@ public class IrisDimension extends IrisRegistrant { @Desc("Vertically split up the biome palettes with 3 air blocks in between to visualize them") private boolean explodeBiomePalettes = false; + @Desc("Studio Mode for testing different parts of the world") + private StudioMode studioMode = StudioMode.NORMAL; + @MinNumber(1) @MaxNumber(16) @Desc("Customize the palette height explosion") @@ -114,9 +113,6 @@ public class IrisDimension extends IrisRegistrant { @Desc("Tree growth override settings") private IrisTreeSettings treeSettings = new IrisTreeSettings(); - @Desc("Define iris cavern zones") - private IrisCaverns caverns = new IrisCaverns(); - @Desc("Upon joining this world, Iris will send a resource pack request to the client. If they have previously selected yes, it will auto-switch depending on which dimension they go to.") private String resourcePack = ""; @@ -170,47 +166,12 @@ public class IrisDimension extends IrisRegistrant { @Desc("The placement style of biomes") private IrisGeneratorStyle caveBiomeStyle = NoiseStyle.CELLULAR_IRIS_DOUBLE.style(); - @Desc("The placement style of biomes") - private IrisGeneratorStyle riverBiomeStyle = NoiseStyle.CELLULAR_IRIS_DOUBLE.style(); - - @Desc("The placement style of biomes") - private IrisGeneratorStyle lakeBiomeStyle = NoiseStyle.CELLULAR_IRIS_DOUBLE.style(); - - @Desc("The placement style of biomes") - private IrisGeneratorStyle islandBiomeStyle = NoiseStyle.CELLULAR_IRIS_DOUBLE.style(); - - @Desc("The placement style of biomes") - private IrisGeneratorStyle islandBiomeChanceStyle = NoiseStyle.CELLULAR_HEIGHT_IRIS_DOUBLE.style(); - - @Desc("The placement style of biomes") - private IrisGeneratorStyle skylandBiomeStyle = NoiseStyle.CELLULAR_IRIS_DOUBLE.style(); - - @Desc("Generate caves or not.") - private boolean caves = true; - @Desc("Instead of filling objects with air, fills them with cobweb so you can see them") private boolean debugSmartBore = false; - @Desc("Carve terrain or not") - private boolean carving = true; - - @Desc("If defined, If air is defined below the area, this fluid will always place") - private IrisCaveFluid forceFluid = new IrisCaveFluid(); - @Desc("Generate decorations or not") private boolean decorate = true; - @Desc("Generate ravines or not") - private boolean ravines = false; - - @MinNumber(1) - @Desc("The rarity of a ravine layer having a lib (or rib) that sticks in or out by one block. Minecraft's default is 3.") - private int ravineRibRarity = 2; - - @MinNumber(1) - @Desc("The rarity of ravines. Each chunk has a 1 in X chance") - private int ravineRarity = 50; - @Desc("Use post processing or not") private boolean postProcessing = true; @@ -220,8 +181,8 @@ public class IrisDimension extends IrisRegistrant { @Desc("Add painted walls in post processing") private boolean postProcessingWalls = true; - @Desc("Use post processing for caves or not") - private boolean postProcessCaves = true; + @Desc("Carving configuration for the dimension") + private IrisCarving carving = new IrisCarving(); @Desc("The world environment") private Environment environment = Environment.NORMAL; @@ -309,14 +270,6 @@ public class IrisDimension extends IrisRegistrant { @Desc("Overlay additional noise on top of the interoplated terrain.") private KList overlayNoise = new KList<>(); - @ArrayType(min = 1, type = IrisCaveLayer.class) - @Desc("Define cave layers") - private KList caveLayers = new KList<>(); - - @ArrayType(min = 1, type = IrisCarveLayer.class) - @Desc("Define carve layers") - private KList carveLayers = new KList<>(); - @Desc("If true, the spawner system has infinite energy. This is NOT recommended because it would allow for mobs to keep spawning over and over without a rate limit") private boolean infiniteEnergy = false; @@ -375,18 +328,6 @@ public class IrisDimension extends IrisRegistrant { return rad.aquire(() -> Math.toRadians(dimensionAngleDeg)); } - public boolean isCarved(IrisData data, int x, int y, int z, RNG rng, int terrainHeight) { - if (isCarving() && terrainHeight > getFluidHeight() || y < terrainHeight) { - for (IrisCarveLayer j : getCarveLayers()) { - if (j.isCarved(rng, data, x, y, z)) { - return true; - } - } - } - - return false; - } - public Environment getEnvironment() { return environment; } @@ -449,10 +390,6 @@ public class IrisDimension extends IrisRegistrant { switch (type) { case CAVE: return caveBiomeStyle; - case LAKE: - return lakeBiomeStyle; - case RIVER: - return riverBiomeStyle; case LAND: return landBiomeStyle; case SEA: @@ -516,41 +453,6 @@ public class IrisDimension extends IrisRegistrant { return changed; } - public boolean hasFeatures(DataProvider data) { - return featuresUsed.aquire(() -> { - if (getFeatures().isNotEmpty() || getSpecificFeatures().isNotEmpty()) { - return true; - } - - for (IrisRegion i : getAllRegions(data)) { - if (i.getFeatures().isNotEmpty()) { - return true; - } - - for (IrisObjectPlacement j : i.getObjects()) { - if (j.isVacuum()) { - return true; - } - } - - for (IrisBiome j : i.getAllBiomes(data)) { - if (j.getFeatures().isNotEmpty()) { - return true; - } - - for (IrisObjectPlacement k : i.getObjects()) { - if (k.isVacuum()) { - return true; - } - } - } - } - - Iris.verbose("Not using parallax noise features (they arent used in this dimension)"); - return false; - }); - } - @Override public String getFolderName() { return "dimensions"; diff --git a/src/main/java/com/volmit/iris/engine/object/dimensional/StudioMode.java b/src/main/java/com/volmit/iris/engine/object/dimensional/StudioMode.java new file mode 100644 index 000000000..39ac3cf00 --- /dev/null +++ b/src/main/java/com/volmit/iris/engine/object/dimensional/StudioMode.java @@ -0,0 +1,50 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.engine.object.dimensional; + +import com.volmit.iris.engine.object.annotations.Desc; +import com.volmit.iris.engine.platform.BukkitChunkGenerator; +import com.volmit.iris.engine.platform.studio.generators.BiomeBuffetGenerator; + +import java.util.function.Consumer; + +@Desc("Represents a studio mode") +public enum StudioMode { + NORMAL(i -> i.setStudioGenerator(null)), + BIOME_BUFFET_1x1(i -> i.setStudioGenerator(new BiomeBuffetGenerator(i.getEngine(), 1))), + BIOME_BUFFET_3x3(i -> i.setStudioGenerator(new BiomeBuffetGenerator(i.getEngine(), 3))), + BIOME_BUFFET_5x5(i -> i.setStudioGenerator(new BiomeBuffetGenerator(i.getEngine(), 5))), + BIOME_BUFFET_9x9(i -> i.setStudioGenerator(new BiomeBuffetGenerator(i.getEngine(), 9))), + BIOME_BUFFET_18x18(i -> i.setStudioGenerator(new BiomeBuffetGenerator(i.getEngine(), 18))), + BIOME_BUFFET_36x36(i -> i.setStudioGenerator(new BiomeBuffetGenerator(i.getEngine(), 36))), + REGION_BUFFET(i -> i.setStudioGenerator(null)), + OBJECT_BUFFET(i -> i.setStudioGenerator(null)), + + ; + + private final Consumer injector; + + StudioMode(Consumer injector) { + this.injector = injector; + } + + public void inject(BukkitChunkGenerator c) { + injector.accept(c); + } +} diff --git a/src/main/java/com/volmit/iris/engine/object/entity/IrisEntity.java b/src/main/java/com/volmit/iris/engine/object/entity/IrisEntity.java index b78044a1c..9a75b95a5 100644 --- a/src/main/java/com/volmit/iris/engine/object/entity/IrisEntity.java +++ b/src/main/java/com/volmit/iris/engine/object/entity/IrisEntity.java @@ -19,7 +19,7 @@ package com.volmit.iris.engine.object.entity; import com.volmit.iris.Iris; -import com.volmit.iris.core.project.loader.IrisRegistrant; +import com.volmit.iris.core.loader.IrisRegistrant; import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.object.annotations.*; import com.volmit.iris.engine.object.common.IrisScript; @@ -33,6 +33,7 @@ import com.volmit.iris.engine.object.spawners.IrisSurface; import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.format.C; import com.volmit.iris.util.json.JSONObject; +import com.volmit.iris.util.math.M; import com.volmit.iris.util.math.RNG; import com.volmit.iris.util.plugin.VolmitSender; import com.volmit.iris.util.scheduling.J; @@ -42,9 +43,7 @@ import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import lombok.experimental.Accessors; -import org.bukkit.Bukkit; -import org.bukkit.Location; -import org.bukkit.NamespacedKey; +import org.bukkit.*; import org.bukkit.attribute.Attributable; import org.bukkit.entity.*; import org.bukkit.entity.Panda.Gene; @@ -53,9 +52,11 @@ import org.bukkit.inventory.ItemStack; import org.bukkit.loot.LootContext; import org.bukkit.loot.LootTable; import org.bukkit.loot.Lootable; +import org.bukkit.util.Vector; import java.util.Collection; import java.util.Random; +import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicReference; @SuppressWarnings("ALL") @@ -136,6 +137,9 @@ public class IrisEntity extends IrisRegistrant { @Desc("If specified, this entity will spawn with an effect") private IrisEffect spawnEffect = null; + @Desc("Simply moves the entity from below the surface slowly out of the ground as a spawn-in effect") + private boolean spawnEffectRiseOutOfGround = false; + @Desc("The main gene for a panda if the entity type is a panda") private Gene pandaMainGene = Gene.NORMAL; @@ -169,6 +173,13 @@ public class IrisEntity extends IrisRegistrant { } public Entity spawn(Engine gen, Location at, RNG rng) { + if (isSpawnEffectRiseOutOfGround()) { + Location b = at.clone(); + double sy = b.getY() - 5; + Location start = new Location(b.getWorld(), b.getX(), sy, b.getZ()); + at = start; + } + Entity ee = doSpawn(at); if (!spawnerScript.isEmpty() && ee == null) { @@ -216,6 +227,7 @@ public class IrisEntity extends IrisRegistrant { Lootable l = (Lootable) e; if (getLoot().getTables().isNotEmpty()) { + Location finalAt = at; l.setLootTable(new LootTable() { @Override public NamespacedKey getKey() { @@ -228,7 +240,7 @@ public class IrisEntity extends IrisRegistrant { for (String fi : getLoot().getTables()) { IrisLootTable i = gen.getData().getLootLoader().load(fi); - items.addAll(i.getLoot(gen.isStudio(), false, rng.nextParallelRNG(345911), InventorySlotType.STORAGE, at.getBlockX(), at.getBlockY(), at.getBlockZ(), 8, 4)); + items.addAll(i.getLoot(gen.isStudio(), false, rng.nextParallelRNG(345911), InventorySlotType.STORAGE, finalAt.getBlockX(), finalAt.getBlockY(), finalAt.getBlockZ(), 8, 4)); } return items; @@ -319,9 +331,50 @@ public class IrisEntity extends IrisRegistrant { } } + if (isSpawnEffectRiseOutOfGround() && e instanceof LivingEntity) { + Location start = at.clone(); + e.setInvulnerable(true); + ((LivingEntity) e).setAI(false); + ((LivingEntity) e).setCollidable(false); + ((LivingEntity) e).setNoDamageTicks(100000); + + AtomicInteger v = new AtomicInteger(0); + v.set(J.sr(() -> { + if (e.getLocation().getBlock().getType().isSolid() || ((LivingEntity) e).getEyeLocation().getBlock().getType().isSolid()) { + e.teleport(start.add(new Vector(0, 0.1, 0))); + ItemStack itemCrackData = new ItemStack(((LivingEntity) e).getEyeLocation().clone().subtract(0, 2, 0).getBlock().getBlockData().getMaterial()); + e.getWorld().spawnParticle(Particle.ITEM_CRACK, ((LivingEntity) e).getEyeLocation(), 6, 0.2, 0.4, 0.2, 0.06f, itemCrackData); + if (M.r(0.2)) { + e.getWorld().playSound(e.getLocation(), Sound.BLOCK_CHORUS_FLOWER_GROW, 0.8f, 0.1f); + } + } else { + J.csr(v.get()); + ((LivingEntity) e).setNoDamageTicks(0); + ((LivingEntity) e).setCollidable(true); + ((LivingEntity) e).setAI(true); + e.setInvulnerable(false); + } + }, 0)); + } + return e; } + private int surfaceY(Location l) { + int m = l.getBlockY(); + + while (m-- > 0) { + Location ll = l.clone(); + ll.setY(m); + + if (ll.getBlock().getType().isSolid()) { + return m; + } + } + + return 0; + } + private Entity doSpawn(Location at) { if (type.equals(EntityType.UNKNOWN)) { return null; diff --git a/src/main/java/com/volmit/iris/engine/object/entity/IrisEntitySpawn.java b/src/main/java/com/volmit/iris/engine/object/entity/IrisEntitySpawn.java index 2f1a829d3..dcdb0b54e 100644 --- a/src/main/java/com/volmit/iris/engine/object/entity/IrisEntitySpawn.java +++ b/src/main/java/com/volmit/iris/engine/object/entity/IrisEntitySpawn.java @@ -22,7 +22,6 @@ import com.volmit.iris.Iris; import com.volmit.iris.engine.IrisComplex; import com.volmit.iris.engine.data.cache.AtomicCache; import com.volmit.iris.engine.framework.Engine; -import com.volmit.iris.engine.modifier.IrisCaveModifier; import com.volmit.iris.engine.object.annotations.Desc; import com.volmit.iris.engine.object.annotations.MinNumber; import com.volmit.iris.engine.object.annotations.RegistryListResource; @@ -88,15 +87,7 @@ public class IrisEntitySpawn implements IRare { IrisComplex comp = gen.getComplex(); IrisBiome cave = comp.getCaveBiomeStream().get(x, z); KList r = new KList<>(); - if (cave != null) { - for (CaveResult i : ((IrisCaveModifier) gen.getCaveModifier()).genCaves(x, z)) { - if (i.getCeiling() >= gen.getHeight() || i.getFloor() < 0 || i.getCeiling() - 2 <= i.getFloor()) { - continue; - } - - r.add(new Location(c.getWorld(), x, i.getFloor(), z)); - } - } + r.add( new Location(c.getWorld(), x, hf + 1, z)); // TODO CAVE HEIGHT yield r.getRandom(rng); } diff --git a/src/main/java/com/volmit/iris/engine/object/feature/IrisFeaturePositional.java b/src/main/java/com/volmit/iris/engine/object/feature/IrisFeaturePositional.java index a7191cf11..fb3310172 100644 --- a/src/main/java/com/volmit/iris/engine/object/feature/IrisFeaturePositional.java +++ b/src/main/java/com/volmit/iris/engine/object/feature/IrisFeaturePositional.java @@ -20,7 +20,7 @@ package com.volmit.iris.engine.object.feature; import com.google.gson.Gson; import com.volmit.iris.Iris; -import com.volmit.iris.core.project.loader.IrisData; +import com.volmit.iris.core.loader.IrisData; import com.volmit.iris.engine.data.cache.AtomicCache; import com.volmit.iris.engine.object.annotations.Desc; import com.volmit.iris.engine.object.annotations.Required; diff --git a/src/main/java/com/volmit/iris/engine/object/jigsaw/IrisJigsawPiece.java b/src/main/java/com/volmit/iris/engine/object/jigsaw/IrisJigsawPiece.java index 054db8418..ec7c62e7c 100644 --- a/src/main/java/com/volmit/iris/engine/object/jigsaw/IrisJigsawPiece.java +++ b/src/main/java/com/volmit/iris/engine/object/jigsaw/IrisJigsawPiece.java @@ -19,7 +19,7 @@ package com.volmit.iris.engine.object.jigsaw; import com.volmit.iris.Iris; -import com.volmit.iris.core.project.loader.IrisRegistrant; +import com.volmit.iris.core.loader.IrisRegistrant; import com.volmit.iris.engine.data.cache.AtomicCache; import com.volmit.iris.engine.object.annotations.ArrayType; import com.volmit.iris.engine.object.annotations.Desc; diff --git a/src/main/java/com/volmit/iris/engine/object/jigsaw/IrisJigsawPool.java b/src/main/java/com/volmit/iris/engine/object/jigsaw/IrisJigsawPool.java index 8dd1a8aeb..535c76837 100644 --- a/src/main/java/com/volmit/iris/engine/object/jigsaw/IrisJigsawPool.java +++ b/src/main/java/com/volmit/iris/engine/object/jigsaw/IrisJigsawPool.java @@ -18,7 +18,7 @@ package com.volmit.iris.engine.object.jigsaw; -import com.volmit.iris.core.project.loader.IrisRegistrant; +import com.volmit.iris.core.loader.IrisRegistrant; import com.volmit.iris.engine.object.annotations.ArrayType; import com.volmit.iris.engine.object.annotations.Desc; import com.volmit.iris.engine.object.annotations.RegistryListResource; diff --git a/src/main/java/com/volmit/iris/engine/object/jigsaw/IrisJigsawStructure.java b/src/main/java/com/volmit/iris/engine/object/jigsaw/IrisJigsawStructure.java index f643b8567..4abf865a1 100644 --- a/src/main/java/com/volmit/iris/engine/object/jigsaw/IrisJigsawStructure.java +++ b/src/main/java/com/volmit/iris/engine/object/jigsaw/IrisJigsawStructure.java @@ -19,7 +19,7 @@ package com.volmit.iris.engine.object.jigsaw; import com.volmit.iris.Iris; -import com.volmit.iris.core.project.loader.IrisRegistrant; +import com.volmit.iris.core.loader.IrisRegistrant; import com.volmit.iris.engine.data.cache.AtomicCache; import com.volmit.iris.engine.object.annotations.*; import com.volmit.iris.engine.object.feature.IrisFeature; diff --git a/src/main/java/com/volmit/iris/engine/object/loot/IrisLootTable.java b/src/main/java/com/volmit/iris/engine/object/loot/IrisLootTable.java index 221781d44..0cdb3f9da 100644 --- a/src/main/java/com/volmit/iris/engine/object/loot/IrisLootTable.java +++ b/src/main/java/com/volmit/iris/engine/object/loot/IrisLootTable.java @@ -18,7 +18,7 @@ package com.volmit.iris.engine.object.loot; -import com.volmit.iris.core.project.loader.IrisRegistrant; +import com.volmit.iris.core.loader.IrisRegistrant; import com.volmit.iris.engine.object.annotations.ArrayType; import com.volmit.iris.engine.object.annotations.Desc; import com.volmit.iris.engine.object.annotations.MinNumber; diff --git a/src/main/java/com/volmit/iris/engine/object/mods/IrisMod.java b/src/main/java/com/volmit/iris/engine/object/mods/IrisMod.java index 19d4d4476..e04fd0e7f 100644 --- a/src/main/java/com/volmit/iris/engine/object/mods/IrisMod.java +++ b/src/main/java/com/volmit/iris/engine/object/mods/IrisMod.java @@ -18,7 +18,7 @@ package com.volmit.iris.engine.object.mods; -import com.volmit.iris.core.project.loader.IrisRegistrant; +import com.volmit.iris.core.loader.IrisRegistrant; import com.volmit.iris.engine.object.annotations.*; import com.volmit.iris.engine.object.biome.IrisBiome; import com.volmit.iris.engine.object.objects.IrisObject; diff --git a/src/main/java/com/volmit/iris/engine/object/noise/IrisExpression.java b/src/main/java/com/volmit/iris/engine/object/noise/IrisExpression.java index 977cf1e4d..f3c1c5ec1 100644 --- a/src/main/java/com/volmit/iris/engine/object/noise/IrisExpression.java +++ b/src/main/java/com/volmit/iris/engine/object/noise/IrisExpression.java @@ -22,7 +22,7 @@ import com.dfsek.paralithic.Expression; import com.dfsek.paralithic.eval.parser.Parser; import com.dfsek.paralithic.eval.parser.Scope; import com.volmit.iris.Iris; -import com.volmit.iris.core.project.loader.IrisRegistrant; +import com.volmit.iris.core.loader.IrisRegistrant; import com.volmit.iris.engine.data.cache.AtomicCache; import com.volmit.iris.engine.object.annotations.ArrayType; import com.volmit.iris.engine.object.annotations.Desc; diff --git a/src/main/java/com/volmit/iris/engine/object/noise/IrisExpressionLoad.java b/src/main/java/com/volmit/iris/engine/object/noise/IrisExpressionLoad.java index 45c6f6c67..08a3ad9d4 100644 --- a/src/main/java/com/volmit/iris/engine/object/noise/IrisExpressionLoad.java +++ b/src/main/java/com/volmit/iris/engine/object/noise/IrisExpressionLoad.java @@ -18,7 +18,7 @@ package com.volmit.iris.engine.object.noise; -import com.volmit.iris.core.project.loader.IrisData; +import com.volmit.iris.core.loader.IrisData; import com.volmit.iris.engine.data.cache.AtomicCache; import com.volmit.iris.engine.object.annotations.Desc; import com.volmit.iris.engine.object.annotations.Required; diff --git a/src/main/java/com/volmit/iris/engine/object/noise/IrisGenerator.java b/src/main/java/com/volmit/iris/engine/object/noise/IrisGenerator.java index 5df9df69b..c250b9de6 100644 --- a/src/main/java/com/volmit/iris/engine/object/noise/IrisGenerator.java +++ b/src/main/java/com/volmit/iris/engine/object/noise/IrisGenerator.java @@ -19,7 +19,7 @@ package com.volmit.iris.engine.object.noise; import com.volmit.iris.Iris; -import com.volmit.iris.core.project.loader.IrisRegistrant; +import com.volmit.iris.core.loader.IrisRegistrant; import com.volmit.iris.engine.data.cache.AtomicCache; import com.volmit.iris.engine.object.annotations.*; import com.volmit.iris.engine.object.common.IRare; diff --git a/src/main/java/com/volmit/iris/engine/object/noise/IrisGeneratorStyle.java b/src/main/java/com/volmit/iris/engine/object/noise/IrisGeneratorStyle.java index 2bcf60bcc..f8dddb9cc 100644 --- a/src/main/java/com/volmit/iris/engine/object/noise/IrisGeneratorStyle.java +++ b/src/main/java/com/volmit/iris/engine/object/noise/IrisGeneratorStyle.java @@ -18,7 +18,7 @@ package com.volmit.iris.engine.object.noise; -import com.volmit.iris.core.project.loader.IrisData; +import com.volmit.iris.core.loader.IrisData; import com.volmit.iris.engine.data.cache.AtomicCache; import com.volmit.iris.engine.object.annotations.Desc; import com.volmit.iris.engine.object.annotations.MaxNumber; @@ -75,34 +75,36 @@ public class IrisGeneratorStyle { return this; } - public CNG create(RNG rng, IrisData data) { - return cng.aquire(() -> - { - if (getExpression() != null) { - IrisExpression e = data.getExpressionLoader().load(getExpression()); + public CNG createNoCache(RNG rng, IrisData data) + { + if (getExpression() != null) { + IrisExpression e = data.getExpressionLoader().load(getExpression()); - if (e != null) { - CNG cng = new CNG(rng, new ExpressionNoise(rng, e), 1D, 1) - .bake().scale(1D / zoom).pow(exponent).bake(); - cng.setTrueFracturing(axialFracturing); + if (e != null) { + CNG cng = new CNG(rng, new ExpressionNoise(rng, e), 1D, 1) + .bake().scale(1D / zoom).pow(exponent).bake(); + cng.setTrueFracturing(axialFracturing); - if (fracture != null) { - cng.fractureWith(fracture.create(rng.nextParallelRNG(2934), data), fracture.getMultiplier()); - } - - return cng; + if (fracture != null) { + cng.fractureWith(fracture.create(rng.nextParallelRNG(2934), data), fracture.getMultiplier()); } + + return cng; } + } - CNG cng = style.create(rng).bake().scale(1D / zoom).pow(exponent).bake(); - cng.setTrueFracturing(axialFracturing); + CNG cng = style.create(rng).bake().scale(1D / zoom).pow(exponent).bake(); + cng.setTrueFracturing(axialFracturing); - if (fracture != null) { - cng.fractureWith(fracture.create(rng.nextParallelRNG(2934), data), fracture.getMultiplier()); - } + if (fracture != null) { + cng.fractureWith(fracture.create(rng.nextParallelRNG(2934), data), fracture.getMultiplier()); + } - return cng; - }); + return cng; + } + + public CNG create(RNG rng, IrisData data) { + return cng.aquire(() -> createNoCache(rng, data)); } @SuppressWarnings("BooleanMethodIsAlwaysInverted") diff --git a/src/main/java/com/volmit/iris/engine/object/noise/IrisNoiseGenerator.java b/src/main/java/com/volmit/iris/engine/object/noise/IrisNoiseGenerator.java index 7a9118bf5..67111be62 100644 --- a/src/main/java/com/volmit/iris/engine/object/noise/IrisNoiseGenerator.java +++ b/src/main/java/com/volmit/iris/engine/object/noise/IrisNoiseGenerator.java @@ -18,7 +18,7 @@ package com.volmit.iris.engine.object.noise; -import com.volmit.iris.core.project.loader.IrisData; +import com.volmit.iris.core.loader.IrisData; import com.volmit.iris.engine.data.cache.AtomicCache; import com.volmit.iris.engine.object.annotations.*; import com.volmit.iris.util.collection.KList; diff --git a/src/main/java/com/volmit/iris/engine/object/noise/IrisShapedGeneratorStyle.java b/src/main/java/com/volmit/iris/engine/object/noise/IrisShapedGeneratorStyle.java index 1c5273dbc..a61f6ff62 100644 --- a/src/main/java/com/volmit/iris/engine/object/noise/IrisShapedGeneratorStyle.java +++ b/src/main/java/com/volmit/iris/engine/object/noise/IrisShapedGeneratorStyle.java @@ -18,7 +18,7 @@ package com.volmit.iris.engine.object.noise; -import com.volmit.iris.core.project.loader.IrisData; +import com.volmit.iris.core.loader.IrisData; import com.volmit.iris.engine.object.annotations.Desc; import com.volmit.iris.engine.object.annotations.MaxNumber; import com.volmit.iris.engine.object.annotations.MinNumber; diff --git a/src/main/java/com/volmit/iris/engine/object/noise/IrisStyledRange.java b/src/main/java/com/volmit/iris/engine/object/noise/IrisStyledRange.java index a421d15c3..f5a33292f 100644 --- a/src/main/java/com/volmit/iris/engine/object/noise/IrisStyledRange.java +++ b/src/main/java/com/volmit/iris/engine/object/noise/IrisStyledRange.java @@ -18,7 +18,7 @@ package com.volmit.iris.engine.object.noise; -import com.volmit.iris.core.project.loader.IrisData; +import com.volmit.iris.core.loader.IrisData; import com.volmit.iris.engine.object.annotations.Desc; import com.volmit.iris.util.math.M; import com.volmit.iris.util.math.RNG; @@ -59,4 +59,8 @@ public class IrisStyledRange { public ProceduralStream stream(RNG rng, IrisData data) { return ProceduralStream.of((x, z) -> get(rng, x, z, data), Interpolated.DOUBLE); } + + public boolean isFlat() { + return getMax() == getMin() || style.isFlat(); + } } diff --git a/src/main/java/com/volmit/iris/engine/object/noise/IrisWorm.java b/src/main/java/com/volmit/iris/engine/object/noise/IrisWorm.java index 02e85329e..fc7e024e7 100644 --- a/src/main/java/com/volmit/iris/engine/object/noise/IrisWorm.java +++ b/src/main/java/com/volmit/iris/engine/object/noise/IrisWorm.java @@ -18,60 +18,107 @@ package com.volmit.iris.engine.object.noise; -import com.volmit.iris.core.project.loader.IrisData; +import com.volmit.iris.Iris; +import com.volmit.iris.core.loader.IrisData; import com.volmit.iris.engine.data.cache.AtomicCache; +import com.volmit.iris.engine.mantle.MantleWriter; import com.volmit.iris.engine.object.annotations.Desc; +import com.volmit.iris.engine.object.basic.IrisPosition; +import com.volmit.iris.engine.object.basic.IrisRange; +import com.volmit.iris.util.collection.KList; +import com.volmit.iris.util.collection.KSet; import com.volmit.iris.util.function.NoiseProvider; import com.volmit.iris.util.math.RNG; -import com.volmit.iris.util.noise.WormIterator2; -import com.volmit.iris.util.noise.WormIterator3; +import com.volmit.iris.util.noise.CNG; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import lombok.experimental.Accessors; +import java.util.function.Consumer; + @Accessors(chain = true) @NoArgsConstructor @AllArgsConstructor @Desc("Generate worms") @Data public class IrisWorm { - @Desc("The style used to determine the curvature of this worm") - private IrisGeneratorStyle angleStyle = new IrisGeneratorStyle(NoiseStyle.PERLIN); + @Desc("The style used to determine the curvature of this worm's x") + private IrisShapedGeneratorStyle xStyle = new IrisShapedGeneratorStyle(NoiseStyle.PERLIN, -2, 2); + + @Desc("The style used to determine the curvature of this worm's y") + private IrisShapedGeneratorStyle yStyle = new IrisShapedGeneratorStyle(NoiseStyle.PERLIN, -2, 2); + + @Desc("The style used to determine the curvature of this worm's z") + private IrisShapedGeneratorStyle zStyle = new IrisShapedGeneratorStyle(NoiseStyle.PERLIN, -2, 2); @Desc("The max block distance this worm can travel from its start. This can have performance implications at ranges over 1,000 blocks but it's not too serious, test.") private int maxDistance = 128; - @Desc("The max segments, or iterations this worm can execute on. Setting this to -1 will allow it to run up to the maxDistance's value of iterations (default)") - private int maxSegments = -1; + @Desc("The iterations this worm can make") + private int maxIterations = 512; - @Desc("The distance between segments") - private IrisStyledRange segmentDistance = new IrisStyledRange().setMin(4).setMax(7) - .setStyle(new IrisGeneratorStyle(NoiseStyle.PERLIN)); + @Desc("By default if a worm loops back into itself, it stops at that point and does not continue. This is an optimization, to prevent this turn this option on.") + private boolean allowLoops = false; @Desc("The thickness of the worms. Each individual worm has the same thickness while traveling however, each spawned worm will vary in thickness.") private IrisStyledRange girth = new IrisStyledRange().setMin(3).setMax(5) .setStyle(new IrisGeneratorStyle(NoiseStyle.PERLIN)); - private transient final AtomicCache angleProviderCache = new AtomicCache<>(); + public KList generate(RNG rng, IrisData data, MantleWriter writer, IrisRange verticalRange, int x, int y, int z, Consumer fork) + { + int itr = maxIterations; + double jx, jy, jz; + double cx = x; + double cy = y; + double cz = z; + IrisPosition start = new IrisPosition(x, y, z); + KList pos = new KList<>(); + KSet check = allowLoops ? null : new KSet<>(); + CNG gx = xStyle.getGenerator().createNoCache(new RNG(rng.lmax()), data); + CNG gy = xStyle.getGenerator().createNoCache(new RNG(rng.lmax()), data); + CNG gz = xStyle.getGenerator().createNoCache(new RNG(rng.lmax()), data); - public NoiseProvider getAngleProvider(RNG rng, IrisData data) { - return angleProviderCache.aquire(() -> (xx, zz) -> angleStyle.create(rng, data).fitDouble(-0.5, 0.5, xx, zz) * segmentDistance.get(rng, xx, zz, data)); - } + while(itr-- > 0) + { + IrisPosition current = new IrisPosition(Math.round(cx), Math.round(cy), Math.round(cz)); + fork.accept(current); + pos.add(current); - public WormIterator2 iterate2D(RNG rng, IrisData data, int x, int z) { - return WormIterator2.builder() - .maxDistance(maxDistance) - .maxIterations(maxSegments == -1 ? maxDistance : maxSegments) - .noise(getAngleProvider(rng, data)).x(x).z(z) - .build(); - } + if(check != null) + { + check.add(current); + } - public WormIterator3 iterate3D(RNG rng, IrisData data, int x, int y, int z) { - return WormIterator3.builder() - .maxDistance(maxDistance) - .maxIterations(maxSegments == -1 ? maxDistance : maxSegments) - .noise(getAngleProvider(rng, data)).x(x).z(z).y(y) - .build(); + jx = gx.fitDouble(xStyle.getMin(), xStyle.getMax(), cx, cy, cz); + jy = gy.fitDouble(yStyle.getMin(), yStyle.getMax(), cx, cy, cz); + jz = gz.fitDouble(zStyle.getMin(), zStyle.getMax(), cx, cy, cz); + cx += jx; + cy += jy; + cz += jz; + IrisPosition next = new IrisPosition(Math.round(cx), Math.round(cy), Math.round(cz)); + + if(!verticalRange.contains(next.getY())) + { + break; + } + + if(!writer.isWithin((int)Math.round(cx), (int)Math.round(cy), (int)Math.round(cz))) + { + break; + } + + if(next.isLongerThan(start, maxDistance)) + { + break; + } + + if(check != null && check.contains(next)) + { + break; + } + } + + return pos; } } diff --git a/src/main/java/com/volmit/iris/engine/object/objects/IrisObject.java b/src/main/java/com/volmit/iris/engine/object/objects/IrisObject.java index 8c6ade3d5..41b3f53c4 100644 --- a/src/main/java/com/volmit/iris/engine/object/objects/IrisObject.java +++ b/src/main/java/com/volmit/iris/engine/object/objects/IrisObject.java @@ -19,8 +19,8 @@ package com.volmit.iris.engine.object.objects; import com.volmit.iris.Iris; -import com.volmit.iris.core.project.loader.IrisData; -import com.volmit.iris.core.project.loader.IrisRegistrant; +import com.volmit.iris.core.loader.IrisData; +import com.volmit.iris.core.loader.IrisRegistrant; import com.volmit.iris.engine.data.cache.AtomicCache; import com.volmit.iris.engine.framework.placer.HeightmapObjectPlacer; import com.volmit.iris.engine.object.basic.IrisPosition; diff --git a/src/main/java/com/volmit/iris/engine/object/objects/IrisObjectLoot.java b/src/main/java/com/volmit/iris/engine/object/objects/IrisObjectLoot.java index 5382111ca..de94e809d 100644 --- a/src/main/java/com/volmit/iris/engine/object/objects/IrisObjectLoot.java +++ b/src/main/java/com/volmit/iris/engine/object/objects/IrisObjectLoot.java @@ -18,7 +18,7 @@ package com.volmit.iris.engine.object.objects; -import com.volmit.iris.core.project.loader.IrisData; +import com.volmit.iris.core.loader.IrisData; import com.volmit.iris.engine.data.cache.AtomicCache; import com.volmit.iris.engine.object.annotations.ArrayType; import com.volmit.iris.engine.object.annotations.Desc; diff --git a/src/main/java/com/volmit/iris/engine/object/objects/IrisObjectPlacement.java b/src/main/java/com/volmit/iris/engine/object/objects/IrisObjectPlacement.java index c8217d27a..907d4eb65 100644 --- a/src/main/java/com/volmit/iris/engine/object/objects/IrisObjectPlacement.java +++ b/src/main/java/com/volmit/iris/engine/object/objects/IrisObjectPlacement.java @@ -19,7 +19,7 @@ package com.volmit.iris.engine.object.objects; import com.volmit.iris.Iris; -import com.volmit.iris.core.project.loader.IrisData; +import com.volmit.iris.core.loader.IrisData; import com.volmit.iris.engine.data.cache.AtomicCache; import com.volmit.iris.engine.object.annotations.*; import com.volmit.iris.engine.object.feature.IrisFeaturePotential; diff --git a/src/main/java/com/volmit/iris/engine/object/objects/IrisObjectReplace.java b/src/main/java/com/volmit/iris/engine/object/objects/IrisObjectReplace.java index 0176b19ca..fc1baf56a 100644 --- a/src/main/java/com/volmit/iris/engine/object/objects/IrisObjectReplace.java +++ b/src/main/java/com/volmit/iris/engine/object/objects/IrisObjectReplace.java @@ -18,7 +18,7 @@ package com.volmit.iris.engine.object.objects; -import com.volmit.iris.core.project.loader.IrisData; +import com.volmit.iris.core.loader.IrisData; import com.volmit.iris.engine.data.cache.AtomicCache; import com.volmit.iris.engine.object.annotations.*; import com.volmit.iris.engine.object.block.IrisBlockData; diff --git a/src/main/java/com/volmit/iris/engine/object/regional/IrisRegion.java b/src/main/java/com/volmit/iris/engine/object/regional/IrisRegion.java index e263bd2bd..de7660c6a 100644 --- a/src/main/java/com/volmit/iris/engine/object/regional/IrisRegion.java +++ b/src/main/java/com/volmit/iris/engine/object/regional/IrisRegion.java @@ -20,13 +20,14 @@ package com.volmit.iris.engine.object.regional; import com.volmit.iris.Iris; import com.volmit.iris.core.gui.components.RenderType; -import com.volmit.iris.core.project.loader.IrisData; -import com.volmit.iris.core.project.loader.IrisRegistrant; +import com.volmit.iris.core.loader.IrisData; +import com.volmit.iris.core.loader.IrisRegistrant; import com.volmit.iris.engine.data.cache.AtomicCache; import com.volmit.iris.engine.object.annotations.*; import com.volmit.iris.engine.object.biome.InferredType; import com.volmit.iris.engine.object.biome.IrisBiome; import com.volmit.iris.engine.object.block.IrisBlockDrops; +import com.volmit.iris.engine.object.carving.IrisCarving; import com.volmit.iris.engine.object.common.IRare; import com.volmit.iris.engine.object.deposits.IrisDepositGenerator; import com.volmit.iris.engine.object.feature.IrisFeaturePotential; @@ -128,14 +129,6 @@ public class IrisRegion extends IrisRegistrant implements IRare { @Desc("How large shore biomes are in this region") private double shoreBiomeZoom = 1; - @MinNumber(0.0001) - @Desc("How large lake biomes are in this region") - private double lakeBiomeZoom = 1; - - @MinNumber(0.0001) - @Desc("How large river biomes are in this region") - private double riverBiomeZoom = 1; - @MinNumber(0.0001) @Desc("How large sea biomes are in this region") private double seaBiomeZoom = 1; @@ -149,6 +142,9 @@ public class IrisRegion extends IrisRegistrant implements IRare { @Desc("The biome implosion ratio, how much to implode biomes into children (chance)") private double biomeImplosionRatio = 0.4; + @Desc("Carving configuration for the dimension") + private IrisCarving carving = new IrisCarving(); + @RegistryListResource(IrisBiome.class) @Required @ArrayType(min = 1, type = String.class) @@ -167,29 +163,11 @@ public class IrisRegion extends IrisRegistrant implements IRare { @Desc("A list of root-level biomes in this region. Don't specify child biomes of other biomes here. Just the root parents.") private KList shoreBiomes = new KList<>(); - @RegistryListResource(IrisBiome.class) - @ArrayType(min = 1, type = String.class) - @Desc("A list of root-level biomes in this region. Don't specify child biomes of other biomes here. Just the root parents.") - private KList riverBiomes = new KList<>(); - - @RegistryListResource(IrisBiome.class) - @ArrayType(min = 1, type = String.class) - @Desc("A list of root-level biomes in this region. Don't specify child biomes of other biomes here. Just the root parents.") - private KList lakeBiomes = new KList<>(); - @RegistryListResource(IrisBiome.class) @ArrayType(min = 1, type = String.class) @Desc("A list of root-level biomes in this region. Don't specify child biomes of other biomes here. Just the root parents.") private KList caveBiomes = new KList<>(); - @ArrayType(min = 1, type = IrisRegionRidge.class) - @Desc("Ridge biomes create a vein-like network like rivers through this region") - private KList ridgeBiomes = new KList<>(); - - @ArrayType(min = 1, type = IrisRegionSpot.class) - @Desc("Spot biomes splotch themselves across this region like lakes") - private KList spotBiomes = new KList<>(); - @ArrayType(min = 1, type = IrisDepositGenerator.class) @Desc("Define regional deposit generators that add onto the global deposit generators") private KList deposits = new KList<>(); @@ -275,42 +253,10 @@ public class IrisRegion extends IrisRegistrant implements IRare { }); } - public boolean isRiver(RNG rng, double x, double z) { - if (!isRivers()) { - return false; - } - - if (getRiverBiomes().isEmpty()) { - return false; - } - - if (getRiverChanceGen().aquire(() -> getRiverChanceStyle().create(rng, getLoader())).fit(1, getRiverRarity(), x, z) != 1) { - return false; - } - - return getRiverGen().aquire(() -> getRiverStyle().create(rng, getLoader())).fitDouble(0, 1, x, z) < getRiverThickness(); - } - - public boolean isLake(RNG rng, double x, double z) { - if (!isLakes()) { - return false; - } - - if (getLakeBiomes().isEmpty()) { - return false; - } - - return getLakeGen().aquire(() -> getLakeStyle().create(rng, getLoader())).fit(1, getLakeRarity(), x, z) == 1; - } - public double getBiomeZoom(InferredType t) { switch (t) { case CAVE: return caveBiomeZoom; - case LAKE: - return lakeBiomeZoom; - case RIVER: - return riverBiomeZoom; case LAND: return landBiomeZoom; case SEA: @@ -324,25 +270,6 @@ public class IrisRegion extends IrisRegistrant implements IRare { return 1; } - public KList getRidgeBiomeKeys() { - return cacheRidge.aquire(() -> - { - KList cacheRidge = new KList<>(); - ridgeBiomes.forEach((i) -> cacheRidge.add(i.getBiome())); - - return cacheRidge; - }); - } - - public KList getSpotBiomeKeys() { - return cacheSpot.aquire(() -> - { - KList cacheSpot = new KList<>(); - spotBiomes.forEach((i) -> cacheSpot.add(i.getBiome())); - return cacheSpot; - }); - } - public CNG getShoreHeightGenerator() { return shoreHeightGenerator.aquire(() -> CNG.signature(new RNG((long) (getName().length() + getLandBiomeZoom() + getLandBiomes().size() + 3458612)))); @@ -358,10 +285,6 @@ public class IrisRegion extends IrisRegistrant implements IRare { names.addAll(caveBiomes); names.addAll(seaBiomes); names.addAll(shoreBiomes); - names.addAll(riverBiomes); - names.addAll(lakeBiomes); - spotBiomes.forEach((i) -> names.add(i.getBiome())); - ridgeBiomes.forEach((i) -> names.add(i.getBiome())); return names; } @@ -402,10 +325,6 @@ public class IrisRegion extends IrisRegistrant implements IRare { return getRealShoreBiomes(g); } else if (type.equals(InferredType.CAVE)) { return getRealCaveBiomes(g); - } else if (type.equals(InferredType.LAKE)) { - return getRealLakeBiomes(g); - } else if (type.equals(InferredType.RIVER)) { - return getRealRiverBiomes(g); } return new KList<>(); @@ -424,32 +343,6 @@ public class IrisRegion extends IrisRegistrant implements IRare { }); } - public KList getRealLakeBiomes(DataProvider g) { - return realLakeBiomes.aquire(() -> - { - KList realLakeBiomes = new KList<>(); - - for (String i : getLakeBiomes()) { - realLakeBiomes.add(g.getData().getBiomeLoader().load(i)); - } - - return realLakeBiomes; - }); - } - - public KList getRealRiverBiomes(DataProvider g) { - return realRiverBiomes.aquire(() -> - { - KList realRiverBiomes = new KList<>(); - - for (String i : getRiverBiomes()) { - realRiverBiomes.add(g.getData().getBiomeLoader().load(i)); - } - - return realRiverBiomes; - }); - } - public KList getRealShoreBiomes(DataProvider g) { return realShoreBiomes.aquire(() -> { @@ -496,10 +389,6 @@ public class IrisRegion extends IrisRegistrant implements IRare { names.addAll(caveBiomes); names.addAll(seaBiomes); names.addAll(shoreBiomes); - names.addAll(riverBiomes); - names.addAll(lakeBiomes); - spotBiomes.forEach((i) -> names.add(i.getBiome())); - ridgeBiomes.forEach((i) -> names.add(i.getBiome())); while (!names.isEmpty()) { for (String i : new KList<>(names)) { diff --git a/src/main/java/com/volmit/iris/engine/object/regional/IrisRegionRidge.java b/src/main/java/com/volmit/iris/engine/object/regional/IrisRegionRidge.java deleted file mode 100644 index 91d04e104..000000000 --- a/src/main/java/com/volmit/iris/engine/object/regional/IrisRegionRidge.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Iris is a World Generator for Minecraft Bukkit Servers - * Copyright (c) 2021 Arcane Arts (Volmit Software) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.volmit.iris.engine.object.regional; - -import com.volmit.iris.engine.data.cache.AtomicCache; -import com.volmit.iris.engine.object.annotations.*; -import com.volmit.iris.engine.object.biome.InferredType; -import com.volmit.iris.engine.object.biome.IrisBiome; -import com.volmit.iris.engine.object.biome.IrisBiomePaletteLayer; -import com.volmit.iris.util.math.RNG; -import com.volmit.iris.util.noise.CellGenerator; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; -import lombok.experimental.Accessors; - -@Accessors(chain = true) -@NoArgsConstructor -@AllArgsConstructor -@Desc("A ridge config") -@Data -public class IrisRegionRidge { - @RegistryListResource(IrisBiome.class) - @Required - @Desc("The biome name") - private String biome = ""; - - @Required - @Desc("The type this biome should override (land sea or shore)") - private InferredType type = InferredType.LAND; - - @Desc("What type this spot is (i.e. target SEA but as LAND) like an island. Default matches the target type") - private InferredType as = InferredType.DEFER; - - @Desc("Use the distance from cell value to add or remove noise value. (Forces depth or height)") - private double noiseMultiplier = 0; - - @Required - @MinNumber(0) - @MaxNumber(1) - @Desc("The chance this biome will be placed in a given spot") - private double chance = 0.75; - - @MinNumber(0) - @Desc("The scale of the biome ridge. Higher values = wider veins & bigger connected cells") - private double scale = 5; - - @Desc("The chance scale (cell chances)") - private double chanceScale = 4; - - @MinNumber(0) - @Desc("The shuffle, how 'natural' this looks. Compared to pure polygons") - private double shuffle = 16; - - @MinNumber(0) - @Desc("The chance shuffle (polygon cell chances)") - private double chanceShuffle = 128; - - @MinNumber(0) - @Desc("The thickness of the vein") - private double thickness = 0.125; - - @Desc("If the noise multiplier is below zero, what should the air be filled with?") - private IrisBiomePaletteLayer air = new IrisBiomePaletteLayer().zero(); - private final transient AtomicCache spot = new AtomicCache<>(); - private final transient AtomicCache ridge = new AtomicCache<>(); - - public CellGenerator getSpotGenerator(RNG rng) { - return spot.aquire(() -> - { - CellGenerator spot = new CellGenerator(rng.nextParallelRNG((int) (198523 * getChance()))); - spot.setCellScale(chanceScale); - spot.setShuffle(shuffle); - return spot; - }); - } - - public CellGenerator getRidgeGenerator(RNG rng) { - return spot.aquire(() -> - { - CellGenerator ridge = new CellGenerator(rng.nextParallelRNG((int) (465583 * getChance()))); - ridge.setCellScale(scale); - ridge.setShuffle(shuffle); - return ridge; - }); - } - - public double getRidgeHeight(RNG rng, double x, double z) { - if (getNoiseMultiplier() == 0) { - return 0; - } - - return getSpotGenerator(rng).getDistance(x, z) * getRidgeGenerator(rng).getDistance(x, z) * getNoiseMultiplier(); - } - - public boolean isRidge(RNG rng, double x, double z) { - if (chance < 1) { - if (getSpotGenerator(rng).getIndex(x, z, 1000) > chance * 1000) { - return false; - } - } - - return getRidgeGenerator(rng).getDistance(x, z) <= thickness; - } -} diff --git a/src/main/java/com/volmit/iris/engine/object/regional/IrisRegionSpot.java b/src/main/java/com/volmit/iris/engine/object/regional/IrisRegionSpot.java deleted file mode 100644 index 12b15dad3..000000000 --- a/src/main/java/com/volmit/iris/engine/object/regional/IrisRegionSpot.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Iris is a World Generator for Minecraft Bukkit Servers - * Copyright (c) 2021 Arcane Arts (Volmit Software) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.volmit.iris.engine.object.regional; - -import com.volmit.iris.engine.data.cache.AtomicCache; -import com.volmit.iris.engine.object.annotations.Desc; -import com.volmit.iris.engine.object.annotations.MinNumber; -import com.volmit.iris.engine.object.annotations.RegistryListResource; -import com.volmit.iris.engine.object.annotations.Required; -import com.volmit.iris.engine.object.biome.InferredType; -import com.volmit.iris.engine.object.biome.IrisBiome; -import com.volmit.iris.engine.object.biome.IrisBiomePaletteLayer; -import com.volmit.iris.util.math.RNG; -import com.volmit.iris.util.noise.CellGenerator; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; -import lombok.experimental.Accessors; - -@Accessors(chain = true) -@NoArgsConstructor -@AllArgsConstructor -@Desc("A spot config") -@Data -public class IrisRegionSpot { - @RegistryListResource(IrisBiome.class) - @Required - @Desc("The biome to be placed") - private String biome = ""; - - @Required - @Desc("Where this spot overrides. Land sea or shore") - private InferredType type = InferredType.LAND; - - @Desc("What type this spot is (i.e. target SEA but as LAND) like an island. Default matches the target type") - private InferredType as = InferredType.DEFER; - - @Desc("Use the distance from cell value to add or remove noise value. (Forces depth or height)") - private double noiseMultiplier = 0; - - @MinNumber(0) - @Desc("The scale of splotches") - private double scale = 1; - - @Required - @MinNumber(1) - @Desc("Rarity is how often this splotch appears. higher = less often") - private double rarity = 1; - - @MinNumber(0) - @Desc("The shuffle or how natural the splotch looks like (anti-polygon)") - private double shuffle = 128; - - @Desc("If the noise multiplier is below zero, what should the air be filled with?") - private IrisBiomePaletteLayer air = new IrisBiomePaletteLayer().zero(); - - private final transient AtomicCache spot = new AtomicCache<>(); - - public CellGenerator getSpotGenerator(RNG rng) { - return spot.aquire(() -> - { - CellGenerator spot = new CellGenerator(rng.nextParallelRNG((int) (168583 * (shuffle + 102) + rarity + (scale * 10465) + biome.length() + type.ordinal() + as.ordinal()))); - spot.setCellScale(scale); - spot.setShuffle(shuffle); - return spot; - }); - } - - public double getSpotHeight(RNG rng, double x, double z) { - if (getNoiseMultiplier() == 0) { - return 0; - } - - return getSpotGenerator(rng).getDistance(x, z) * getNoiseMultiplier(); - } - - public boolean isSpot(RNG rng, double x, double z) { - return getSpotGenerator(rng).getIndex(x, z, (int) (Math.round(rarity) + 8)) == (int) ((Math.round(rarity) + 8) / 2); - } -} diff --git a/src/main/java/com/volmit/iris/engine/object/spawners/IrisSpawner.java b/src/main/java/com/volmit/iris/engine/object/spawners/IrisSpawner.java index 5a0b08279..999a5b349 100644 --- a/src/main/java/com/volmit/iris/engine/object/spawners/IrisSpawner.java +++ b/src/main/java/com/volmit/iris/engine/object/spawners/IrisSpawner.java @@ -18,7 +18,7 @@ package com.volmit.iris.engine.object.spawners; -import com.volmit.iris.core.project.loader.IrisRegistrant; +import com.volmit.iris.core.loader.IrisRegistrant; import com.volmit.iris.engine.object.annotations.ArrayType; import com.volmit.iris.engine.object.annotations.Desc; import com.volmit.iris.engine.object.basic.IrisRange; @@ -79,17 +79,17 @@ public class IrisSpawner extends IrisRegistrant { public boolean isValid(IrisBiome biome) { return switch (group) { case NORMAL -> switch (biome.getInferredType()) { - case SHORE, SEA, CAVE, RIVER, LAKE, DEFER -> false; + case SHORE, SEA, CAVE, DEFER -> false; case LAND -> true; }; case CAVE -> true; case UNDERWATER -> switch (biome.getInferredType()) { - case SHORE, LAND, CAVE, RIVER, LAKE, DEFER -> false; + case SHORE, LAND, CAVE, DEFER -> false; case SEA -> true; }; case BEACH -> switch (biome.getInferredType()) { case SHORE -> true; - case LAND, CAVE, RIVER, LAKE, SEA, DEFER -> false; + case LAND, CAVE, SEA, DEFER -> false; }; }; } diff --git a/src/main/java/com/volmit/iris/engine/platform/BukkitChunkGenerator.java b/src/main/java/com/volmit/iris/engine/platform/BukkitChunkGenerator.java index 11ec5f9a0..9b908617d 100644 --- a/src/main/java/com/volmit/iris/engine/platform/BukkitChunkGenerator.java +++ b/src/main/java/com/volmit/iris/engine/platform/BukkitChunkGenerator.java @@ -19,7 +19,7 @@ package com.volmit.iris.engine.platform; import com.volmit.iris.Iris; -import com.volmit.iris.core.project.loader.IrisData; +import com.volmit.iris.core.loader.IrisData; import com.volmit.iris.core.service.StudioSVC; import com.volmit.iris.engine.IrisEngine; import com.volmit.iris.engine.data.chunk.TerrainChunk; @@ -28,7 +28,10 @@ import com.volmit.iris.engine.framework.EngineTarget; import com.volmit.iris.engine.framework.WrongEngineBroException; import com.volmit.iris.engine.object.common.IrisWorld; import com.volmit.iris.engine.object.dimensional.IrisDimension; +import com.volmit.iris.engine.object.dimensional.StudioMode; +import com.volmit.iris.engine.platform.studio.StudioGenerator; import com.volmit.iris.util.collection.KList; +import com.volmit.iris.util.data.IrisBiomeStorage; import com.volmit.iris.util.hunk.Hunk; import com.volmit.iris.util.io.ReactiveFolder; import com.volmit.iris.util.scheduling.ChronoLatch; @@ -36,19 +39,27 @@ import com.volmit.iris.util.scheduling.J; import com.volmit.iris.util.scheduling.Looper; import lombok.Data; import lombok.EqualsAndHashCode; +import lombok.Setter; import org.bukkit.Bukkit; +import org.bukkit.Chunk; import org.bukkit.Material; import org.bukkit.World; import org.bukkit.block.Biome; import org.bukkit.block.data.BlockData; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; +import org.bukkit.generator.BiomeProvider; import org.bukkit.generator.BlockPopulator; import org.bukkit.generator.ChunkGenerator; +import org.bukkit.generator.WorldInfo; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.io.File; import java.util.List; import java.util.Random; import java.util.concurrent.Semaphore; +import java.util.function.Consumer; @EqualsAndHashCode(callSuper = true) @Data @@ -63,10 +74,15 @@ public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChun private final KList populators; private final ChronoLatch hotloadChecker; private final Looper hotloader; + private StudioMode lastMode; + + @Setter + private StudioGenerator studioGenerator; private final boolean studio; private long lastSeed; public BukkitChunkGenerator(IrisWorld world, boolean studio, File dataLocation, String dimensionKey) { + studioGenerator = null; populators = new KList<>(); lastSeed = world.seed(); loadLock = new Semaphore(LOAD_LOCKS); @@ -121,6 +137,7 @@ public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChun } } + lastMode = StudioMode.NORMAL; engine = new IrisEngine(new EngineTarget(world, dimension, data), studio); populators.clear(); } @@ -130,6 +147,88 @@ public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChun return false; } + @Override + public void injectChunkReplacement(World world, int x, int z, Consumer jobs) { + try { + if (lastSeed != world.getSeed()) { + Iris.debug("Seed for engine " + lastSeed + " does not match world seed if " + world.getSeed()); + lastSeed = world.getSeed(); + engine.getTarget().getWorld().seed(lastSeed); + engine.hotload(); + Iris.debug("Updated Engine seed to " + lastSeed); + } + + loadLock.acquire(); + IrisBiomeStorage st = new IrisBiomeStorage(); + TerrainChunk tc = TerrainChunk.createUnsafe(world, st); + Hunk blocks = Hunk.view((ChunkData) tc); + Hunk biomes = Hunk.view((BiomeGrid) tc); + this.world.bind(world); + getEngine().generate(x << 4, z << 4, blocks, biomes, true); + Iris.debug("Regenerated " + x + " " + z); + int t = 0; + for (int i = getEngine().getHeight() >> 4; i >= 0; i--) { + if (!world.isChunkLoaded(x, z)) { + continue; + } + + Chunk c = world.getChunkAt(x, z); + for (Entity ee : c.getEntities()) { + if (ee instanceof Player) { + continue; + } + + J.s(ee::remove); + } + + J.s(() -> engine.getWorldManager().onChunkLoad(c, false)); + + int finalI = i; + jobs.accept(() -> { + + for (int xx = 0; xx < 16; xx++) { + for (int yy = 0; yy < 16; yy++) { + for (int zz = 0; zz < 16; zz++) { + if (yy + (finalI << 4) >= engine.getHeight() || yy + (finalI << 4) < 0) { + continue; + } + + c.getBlock(xx, yy + (finalI << 4), zz).setBlockData(tc.getBlockData(xx, yy + (finalI << 4), zz), false); + } + } + } + }); + } + + loadLock.release(); + } catch (WrongEngineBroException e) { + Iris.warn("Trying to generate with a shut-down engine! Did you reload? Attempting to resolve this..."); + + try { + setupEngine(); + Iris.success("Resolved! Should generate now!"); + } catch (Throwable fe) { + Iris.error("FATAL! Iris cannot generate in this world since it was reloaded! This will cause a crash, with missing chunks, so we're crashing right now!"); + Bukkit.shutdown(); + throw new RuntimeException(); + } + } catch (Throwable e) { + loadLock.release(); + Iris.error("======================================"); + e.printStackTrace(); + Iris.reportErrorChunk(x, z, e, "CHUNK"); + Iris.error("======================================"); + + ChunkData d = Bukkit.createChunkData(world); + + for (int i = 0; i < 16; i++) { + for (int j = 0; j < 16; j++) { + d.setBlock(i, 0, j, Material.RED_GLAZED_TERRACOTTA.createBlockData()); + } + } + } + } + @Override public void close() { withExclusiveControl(() -> { @@ -162,23 +261,28 @@ public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChun @Override public @NotNull ChunkData generateChunkData(@NotNull World world, @NotNull Random ignored, int x, int z, @NotNull BiomeGrid biome) { - - try { if (lastSeed != world.getSeed()) { - Iris.warn("Seed for engine " + lastSeed + " does not match world seed if " + world.getSeed()); + Iris.debug("Seed for engine " + lastSeed + " does not match world seed if " + world.getSeed()); lastSeed = world.getSeed(); engine.getTarget().getWorld().seed(lastSeed); engine.hotload(); - Iris.success("Updated Engine seed to " + lastSeed); + Iris.debug("Updated Engine seed to " + lastSeed); } loadLock.acquire(); + computeStudioGenerator(); TerrainChunk tc = TerrainChunk.create(world, biome); - Hunk blocks = Hunk.view((ChunkData) tc); - Hunk biomes = Hunk.view((BiomeGrid) tc); this.world.bind(world); - getEngine().generate(x * 16, z * 16, blocks, biomes, true); + + if (studioGenerator != null) { + studioGenerator.generateChunk(getEngine(), tc, x, z); + } else { + Hunk blocks = Hunk.view((ChunkData) tc); + Hunk biomes = Hunk.view((BiomeGrid) tc); + getEngine().generate(x << 4, z << 4, blocks, biomes, true); + } + ChunkData c = tc.getRaw(); Iris.debug("Generated " + x + " " + z); loadLock.release(); @@ -215,6 +319,13 @@ public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChun } } + private void computeStudioGenerator() { + if (!getEngine().getDimension().getStudioMode().equals(lastMode)) { + lastMode = getEngine().getDimension().getStudioMode(); + getEngine().getDimension().getStudioMode().inject(this); + } + } + @NotNull @Override public List getDefaultPopulators(@NotNull World world) { @@ -245,4 +356,25 @@ public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChun public boolean shouldGenerateStructures() { return false; } + + @Override + public boolean shouldGenerateNoise() { + return false; + } + + @Override + public boolean shouldGenerateSurface() { + return false; + } + + @Override + public boolean shouldGenerateBedrock() { + return false; + } + + @Nullable + @Override + public BiomeProvider getDefaultBiomeProvider(@NotNull WorldInfo worldInfo) { + return null; + } } diff --git a/src/main/java/com/volmit/iris/engine/platform/HeadlessGenerator.java b/src/main/java/com/volmit/iris/engine/platform/HeadlessGenerator.java index 9aea5b8f2..e5f13fcb1 100644 --- a/src/main/java/com/volmit/iris/engine/platform/HeadlessGenerator.java +++ b/src/main/java/com/volmit/iris/engine/platform/HeadlessGenerator.java @@ -42,11 +42,13 @@ import com.volmit.iris.util.parallel.BurstExecutor; import com.volmit.iris.util.parallel.MultiBurst; import lombok.Data; import org.bukkit.Material; +import org.bukkit.World; import org.bukkit.block.data.BlockData; import org.bukkit.generator.ChunkGenerator; import java.io.File; import java.io.IOException; +import java.util.function.Consumer; @Data public class HeadlessGenerator implements PlatformChunkGenerator { @@ -100,6 +102,11 @@ public class HeadlessGenerator implements PlatformChunkGenerator { } } + @Override + public void injectChunkReplacement(World world, int x, int z, Consumer jobs) { + + } + @RegionCoordinates public void generateRegion(int x, int z) { generateRegion(x, z, null); diff --git a/src/main/java/com/volmit/iris/engine/platform/PlatformChunkGenerator.java b/src/main/java/com/volmit/iris/engine/platform/PlatformChunkGenerator.java index a11d6d348..12461060f 100644 --- a/src/main/java/com/volmit/iris/engine/platform/PlatformChunkGenerator.java +++ b/src/main/java/com/volmit/iris/engine/platform/PlatformChunkGenerator.java @@ -18,11 +18,14 @@ package com.volmit.iris.engine.platform; -import com.volmit.iris.core.project.loader.IrisData; +import com.volmit.iris.core.loader.IrisData; import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.framework.EngineTarget; import com.volmit.iris.engine.framework.Hotloadable; import com.volmit.iris.util.data.DataProvider; +import org.bukkit.World; + +import java.util.function.Consumer; public interface PlatformChunkGenerator extends Hotloadable, DataProvider { Engine getEngine(); @@ -38,6 +41,8 @@ public interface PlatformChunkGenerator extends Hotloadable, DataProvider { return getEngine().getTarget(); } + void injectChunkReplacement(World world, int x, int z, Consumer jobs); + void close(); boolean isStudio(); diff --git a/src/main/java/com/volmit/iris/util/noise/Worm3.java b/src/main/java/com/volmit/iris/engine/platform/studio/EnginedStudioGenerator.java similarity index 56% rename from src/main/java/com/volmit/iris/util/noise/Worm3.java rename to src/main/java/com/volmit/iris/engine/platform/studio/EnginedStudioGenerator.java index e173af29f..201f996ab 100644 --- a/src/main/java/com/volmit/iris/util/noise/Worm3.java +++ b/src/main/java/com/volmit/iris/engine/platform/studio/EnginedStudioGenerator.java @@ -16,35 +16,17 @@ * along with this program. If not, see . */ -package com.volmit.iris.util.noise; +package com.volmit.iris.engine.platform.studio; -import lombok.Data; +import com.volmit.iris.engine.data.chunk.TerrainChunk; +import com.volmit.iris.engine.framework.Engine; +import com.volmit.iris.engine.framework.WrongEngineBroException; +import lombok.RequiredArgsConstructor; -@Data -public class Worm3 { - private final Worm x; - private final Worm y; - private final Worm z; +@RequiredArgsConstructor +public abstract class EnginedStudioGenerator implements StudioGenerator { + private final Engine engine; - public Worm3(Worm x, Worm y, Worm z) { - this.x = x; - this.y = y; - this.z = z; - } - - public Worm3(int x, int y, int z, int vx, int vy, int vz) { - this(new Worm(x, vx), new Worm(y, vy), new Worm(z, vz)); - } - - public void step() { - x.step(); - y.step(); - z.step(); - } - - public void unstep() { - x.unstep(); - y.unstep(); - z.unstep(); - } + @Override + public abstract void generateChunk(Engine engine, TerrainChunk tc, int x, int z) throws WrongEngineBroException; } diff --git a/src/main/java/com/volmit/iris/engine/platform/studio/StudioGenerator.java b/src/main/java/com/volmit/iris/engine/platform/studio/StudioGenerator.java new file mode 100644 index 000000000..8cd6b3ae4 --- /dev/null +++ b/src/main/java/com/volmit/iris/engine/platform/studio/StudioGenerator.java @@ -0,0 +1,27 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.engine.platform.studio; + +import com.volmit.iris.engine.data.chunk.TerrainChunk; +import com.volmit.iris.engine.framework.Engine; +import com.volmit.iris.engine.framework.WrongEngineBroException; + +public interface StudioGenerator { + void generateChunk(Engine engine, TerrainChunk tc, int x, int z) throws WrongEngineBroException; +} diff --git a/src/main/java/com/volmit/iris/engine/platform/studio/generators/BiomeBuffetGenerator.java b/src/main/java/com/volmit/iris/engine/platform/studio/generators/BiomeBuffetGenerator.java new file mode 100644 index 000000000..16c591cc6 --- /dev/null +++ b/src/main/java/com/volmit/iris/engine/platform/studio/generators/BiomeBuffetGenerator.java @@ -0,0 +1,63 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.engine.platform.studio.generators; + +import com.volmit.iris.engine.data.cache.Cache; +import com.volmit.iris.engine.data.chunk.TerrainChunk; +import com.volmit.iris.engine.framework.Engine; +import com.volmit.iris.engine.framework.WrongEngineBroException; +import com.volmit.iris.engine.object.biome.IrisBiome; +import com.volmit.iris.engine.platform.studio.EnginedStudioGenerator; +import org.bukkit.Material; +import org.bukkit.block.data.BlockData; + +import java.util.Objects; + +public class BiomeBuffetGenerator extends EnginedStudioGenerator { + private static final BlockData FLOOR = Material.BARRIER.createBlockData(); + private final IrisBiome[] biomes; + private final int width; + private final int biomeSize; + + public BiomeBuffetGenerator(Engine engine, int biomeSize) { + super(engine); + this.biomeSize = biomeSize; + biomes = engine.getDimension().getAllBiomes(engine).toArray(new IrisBiome[0]); + width = Math.max((int) Math.sqrt(biomes.length), 1); + } + + @Override + public void generateChunk(Engine engine, TerrainChunk tc, int x, int z) throws WrongEngineBroException { + int id = Cache.to1D(x / biomeSize, 0, z / biomeSize, width, 1); + + if (id >= 0 && id < biomes.length) { + IrisBiome biome = biomes[id]; + String foc = engine.getDimension().getFocus(); + + if (!Objects.equals(foc, biome.getLoadKey())) { + engine.getDimension().setFocus(biome.getLoadKey()); + engine.hotloadComplex(); + } + + engine.generate(x << 4, z << 4, tc, true); + } else { + tc.setRegion(0, 0, 0, 16, 1, 16, FLOOR); + } + } +} diff --git a/src/main/java/com/volmit/iris/engine/scripting/IrisScriptingAPI.java b/src/main/java/com/volmit/iris/engine/scripting/IrisScriptingAPI.java index 9c19a7bb5..d1423fae9 100644 --- a/src/main/java/com/volmit/iris/engine/scripting/IrisScriptingAPI.java +++ b/src/main/java/com/volmit/iris/engine/scripting/IrisScriptingAPI.java @@ -19,8 +19,8 @@ package com.volmit.iris.engine.scripting; import com.volmit.iris.Iris; -import com.volmit.iris.core.project.loader.IrisData; -import com.volmit.iris.core.project.loader.IrisRegistrant; +import com.volmit.iris.core.loader.IrisData; +import com.volmit.iris.core.loader.IrisRegistrant; import com.volmit.iris.engine.IrisComplex; import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.object.biome.IrisBiome; diff --git a/src/main/java/com/volmit/iris/util/context/IrisContext.java b/src/main/java/com/volmit/iris/util/context/IrisContext.java index 155db0832..799530d13 100644 --- a/src/main/java/com/volmit/iris/util/context/IrisContext.java +++ b/src/main/java/com/volmit/iris/util/context/IrisContext.java @@ -19,7 +19,7 @@ package com.volmit.iris.util.context; import com.volmit.iris.Iris; -import com.volmit.iris.core.project.loader.IrisData; +import com.volmit.iris.core.loader.IrisData; import com.volmit.iris.engine.IrisComplex; import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.util.collection.KMap; diff --git a/src/main/java/com/volmit/iris/util/data/B.java b/src/main/java/com/volmit/iris/util/data/B.java index ecb14eca4..a112b4c28 100644 --- a/src/main/java/com/volmit/iris/util/data/B.java +++ b/src/main/java/com/volmit/iris/util/data/B.java @@ -28,6 +28,7 @@ import it.unimi.dsi.fastutil.ints.IntSets; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.block.data.BlockData; +import org.bukkit.block.data.Waterlogged; import org.bukkit.block.data.type.Leaves; import java.util.Arrays; @@ -510,4 +511,8 @@ public class B { return bt.toArray(new String[0]); } + + public static boolean isWaterLogged(BlockData b) { + return (b instanceof Waterlogged) && ((Waterlogged)b).isWaterlogged(); + } } diff --git a/src/main/java/com/volmit/iris/util/data/DataProvider.java b/src/main/java/com/volmit/iris/util/data/DataProvider.java index 9fa3adb1b..4847ce047 100644 --- a/src/main/java/com/volmit/iris/util/data/DataProvider.java +++ b/src/main/java/com/volmit/iris/util/data/DataProvider.java @@ -18,7 +18,7 @@ package com.volmit.iris.util.data; -import com.volmit.iris.core.project.loader.IrisData; +import com.volmit.iris.core.loader.IrisData; public interface DataProvider { IrisData getData(); diff --git a/src/main/java/com/volmit/iris/util/data/IrisBiomeStorage.java b/src/main/java/com/volmit/iris/util/data/IrisBiomeStorage.java index 63c2c4ac3..6fc24fa7f 100644 --- a/src/main/java/com/volmit/iris/util/data/IrisBiomeStorage.java +++ b/src/main/java/com/volmit/iris/util/data/IrisBiomeStorage.java @@ -21,8 +21,9 @@ package com.volmit.iris.util.data; import com.volmit.iris.util.math.IrisMathHelper; import org.bukkit.block.Biome; import org.bukkit.generator.ChunkGenerator.BiomeGrid; +import org.jetbrains.annotations.NotNull; -public class IrisBiomeStorage { +public class IrisBiomeStorage implements BiomeGrid { private static final int e; private static final int f; public static final int a; @@ -67,6 +68,12 @@ public class IrisBiomeStorage { } } + @NotNull + @Override + public Biome getBiome(int x, int z) { + return null; + } + public Biome getBiome(final int x, final int y, final int z) { final int l = x & IrisBiomeStorage.b; final int i2 = IrisMathHelper.clamp(y, 0, IrisBiomeStorage.c); @@ -74,6 +81,11 @@ public class IrisBiomeStorage { return this.g[i2 << IrisBiomeStorage.e + IrisBiomeStorage.e | j2 << IrisBiomeStorage.e | l]; } + @Override + public void setBiome(int x, int z, @NotNull Biome bio) { + + } + public void setBiome(final int x, final int y, final int z, final Biome biome) { final int l = x & IrisBiomeStorage.b; final int i2 = IrisMathHelper.clamp(y, 0, IrisBiomeStorage.c); diff --git a/src/main/java/com/volmit/iris/util/decree/handlers/BiomeHandler.java b/src/main/java/com/volmit/iris/util/decree/handlers/BiomeHandler.java index 5f6c9ec42..d142cea4d 100644 --- a/src/main/java/com/volmit/iris/util/decree/handlers/BiomeHandler.java +++ b/src/main/java/com/volmit/iris/util/decree/handlers/BiomeHandler.java @@ -19,7 +19,7 @@ package com.volmit.iris.util.decree.handlers; import com.volmit.iris.Iris; -import com.volmit.iris.core.project.loader.IrisData; +import com.volmit.iris.core.loader.IrisData; import com.volmit.iris.engine.object.biome.IrisBiome; import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.collection.KMap; diff --git a/src/main/java/com/volmit/iris/util/decree/handlers/DimensionHandler.java b/src/main/java/com/volmit/iris/util/decree/handlers/DimensionHandler.java index 3e4f43fbd..1d93ee01d 100644 --- a/src/main/java/com/volmit/iris/util/decree/handlers/DimensionHandler.java +++ b/src/main/java/com/volmit/iris/util/decree/handlers/DimensionHandler.java @@ -19,7 +19,7 @@ package com.volmit.iris.util.decree.handlers; import com.volmit.iris.Iris; -import com.volmit.iris.core.project.loader.IrisData; +import com.volmit.iris.core.loader.IrisData; import com.volmit.iris.engine.object.dimensional.IrisDimension; import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.collection.KMap; diff --git a/src/main/java/com/volmit/iris/util/decree/handlers/EntityHandler.java b/src/main/java/com/volmit/iris/util/decree/handlers/EntityHandler.java index ab364b18e..f28d61f4e 100644 --- a/src/main/java/com/volmit/iris/util/decree/handlers/EntityHandler.java +++ b/src/main/java/com/volmit/iris/util/decree/handlers/EntityHandler.java @@ -19,7 +19,7 @@ package com.volmit.iris.util.decree.handlers; import com.volmit.iris.Iris; -import com.volmit.iris.core.project.loader.IrisData; +import com.volmit.iris.core.loader.IrisData; import com.volmit.iris.engine.object.entity.IrisEntity; import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.collection.KMap; diff --git a/src/main/java/com/volmit/iris/util/decree/handlers/GeneratorHandler.java b/src/main/java/com/volmit/iris/util/decree/handlers/GeneratorHandler.java index c31390629..104809a20 100644 --- a/src/main/java/com/volmit/iris/util/decree/handlers/GeneratorHandler.java +++ b/src/main/java/com/volmit/iris/util/decree/handlers/GeneratorHandler.java @@ -19,7 +19,7 @@ package com.volmit.iris.util.decree.handlers; import com.volmit.iris.Iris; -import com.volmit.iris.core.project.loader.IrisData; +import com.volmit.iris.core.loader.IrisData; import com.volmit.iris.engine.object.noise.IrisGenerator; import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.collection.KMap; diff --git a/src/main/java/com/volmit/iris/util/decree/handlers/RegionHandler.java b/src/main/java/com/volmit/iris/util/decree/handlers/RegionHandler.java index 12d6064c3..8f205af9a 100644 --- a/src/main/java/com/volmit/iris/util/decree/handlers/RegionHandler.java +++ b/src/main/java/com/volmit/iris/util/decree/handlers/RegionHandler.java @@ -19,7 +19,7 @@ package com.volmit.iris.util.decree.handlers; import com.volmit.iris.Iris; -import com.volmit.iris.core.project.loader.IrisData; +import com.volmit.iris.core.loader.IrisData; import com.volmit.iris.engine.object.regional.IrisRegion; import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.collection.KMap; diff --git a/src/main/java/com/volmit/iris/util/decree/handlers/ScriptHandler.java b/src/main/java/com/volmit/iris/util/decree/handlers/ScriptHandler.java index 3120a7aa0..895fe8e52 100644 --- a/src/main/java/com/volmit/iris/util/decree/handlers/ScriptHandler.java +++ b/src/main/java/com/volmit/iris/util/decree/handlers/ScriptHandler.java @@ -19,7 +19,7 @@ package com.volmit.iris.util.decree.handlers; import com.volmit.iris.Iris; -import com.volmit.iris.core.project.loader.IrisData; +import com.volmit.iris.core.loader.IrisData; import com.volmit.iris.engine.object.common.IrisScript; import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.collection.KMap; diff --git a/src/main/java/com/volmit/iris/util/decree/specialhandlers/ObjectHandler.java b/src/main/java/com/volmit/iris/util/decree/specialhandlers/ObjectHandler.java index 7d7af67fe..a88ca4e2c 100644 --- a/src/main/java/com/volmit/iris/util/decree/specialhandlers/ObjectHandler.java +++ b/src/main/java/com/volmit/iris/util/decree/specialhandlers/ObjectHandler.java @@ -19,7 +19,7 @@ package com.volmit.iris.util.decree.specialhandlers; import com.volmit.iris.Iris; -import com.volmit.iris.core.project.loader.IrisData; +import com.volmit.iris.core.loader.IrisData; import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.decree.DecreeParameterHandler; import com.volmit.iris.util.decree.exceptions.DecreeParsingException; diff --git a/src/main/java/com/volmit/iris/util/exceptions/IrisException.java b/src/main/java/com/volmit/iris/util/exceptions/IrisException.java index b6a70e696..7768caa9a 100644 --- a/src/main/java/com/volmit/iris/util/exceptions/IrisException.java +++ b/src/main/java/com/volmit/iris/util/exceptions/IrisException.java @@ -26,4 +26,12 @@ public class IrisException extends Exception { public IrisException(String message) { super(message); } + + public IrisException(Throwable message) { + super(message); + } + + public IrisException(String message, Throwable e) { + super(message, e); + } } diff --git a/src/main/java/com/volmit/iris/util/mantle/Mantle.java b/src/main/java/com/volmit/iris/util/mantle/Mantle.java index bac9f0d8f..5f0ea90f8 100644 --- a/src/main/java/com/volmit/iris/util/mantle/Mantle.java +++ b/src/main/java/com/volmit/iris/util/mantle/Mantle.java @@ -38,9 +38,11 @@ import com.volmit.iris.util.math.KochanekBartelsInterpolation; import com.volmit.iris.util.math.M; import com.volmit.iris.util.math.PathInterpolation; import com.volmit.iris.util.matter.Matter; +import com.volmit.iris.util.matter.MatterCavern; import com.volmit.iris.util.parallel.BurstExecutor; import com.volmit.iris.util.parallel.HyperLock; import com.volmit.iris.util.parallel.MultiBurst; +import org.bukkit.Chunk; import org.bukkit.util.Vector; import java.io.File; @@ -151,6 +153,10 @@ public class Mantle { get(x >> 5, z >> 5).getOrCreate(x & 31, z & 31).flag(flag, flagged); } + public void deleteChunk(int x, int z) { + get(x >> 5, z >> 5).delete(x & 31, z & 31); + } + /** * Check very quickly if a tectonic plate exists via cached or the file system * @@ -426,13 +432,18 @@ public class Mantle { if (file.exists()) { try { region = TectonicPlate.read(worldHeight, file); + + if (region.getX() != x || region.getZ() != z) { + Iris.warn("Loaded Tectonic Plate " + x + "," + z + " but read it as " + region.getX() + "," + region.getZ() + "... Assuming " + x + "," + z); + } + loadedRegions.put(k, region); Iris.debug("Loaded Tectonic Plate " + C.DARK_GREEN + x + " " + z + C.DARK_AQUA + " " + file.getName()); } catch (Throwable e) { Iris.error("Failed to read Tectonic Plate " + file.getAbsolutePath() + " creating a new chunk instead."); Iris.reportError(e); e.printStackTrace(); - region = new TectonicPlate(worldHeight); + region = new TectonicPlate(worldHeight, x, z); loadedRegions.put(k, region); Iris.debug("Created new Tectonic Plate (Due to Load Failure) " + C.DARK_GREEN + x + " " + z); } @@ -440,7 +451,7 @@ public class Mantle { return region; } - region = new TectonicPlate(worldHeight); + region = new TectonicPlate(worldHeight, x, z); loadedRegions.put(k, region); Iris.debug("Created new Tectonic Plate " + C.DARK_GREEN + x + " " + z); return region; @@ -489,440 +500,15 @@ public class Mantle { } - /** - * Set a sphere into the mantle - * - * @param cx the center x - * @param cy the center y - * @param cz the center z - * @param radius the radius of this sphere - * @param fill should it be filled? or just the outer shell? - * @param data the data to set - * @param the type of data to apply to the mantle - */ - public void setSphere(int cx, int cy, int cz, double radius, boolean fill, T data) { - setElipsoid(cx, cy, cz, radius, radius, radius, fill, data); - } - - /** - * Set an elipsoid into the mantle - * - * @param cx the center x - * @param cy the center y - * @param cz the center z - * @param rx the x radius - * @param ry the y radius - * @param rz the z radius - * @param fill should it be filled or just the outer shell? - * @param data the data to set - * @param the type of data to apply to the mantle - */ - public void setElipsoid(int cx, int cy, int cz, double rx, double ry, double rz, boolean fill, T data) { - rx += 0.5; - ry += 0.5; - rz += 0.5; - final double invRadiusX = 1 / rx; - final double invRadiusY = 1 / ry; - final double invRadiusZ = 1 / rz; - final int ceilRadiusX = (int) Math.ceil(rx); - final int ceilRadiusY = (int) Math.ceil(ry); - final int ceilRadiusZ = (int) Math.ceil(rz); - double nextXn = 0; - - forX: - for (int x = 0; x <= ceilRadiusX; ++x) { - final double xn = nextXn; - nextXn = (x + 1) * invRadiusX; - double nextYn = 0; - forY: - for (int y = 0; y <= ceilRadiusY; ++y) { - final double yn = nextYn; - nextYn = (y + 1) * invRadiusY; - double nextZn = 0; - for (int z = 0; z <= ceilRadiusZ; ++z) { - final double zn = nextZn; - nextZn = (z + 1) * invRadiusZ; - - double distanceSq = lengthSq(xn, yn, zn); - if (distanceSq > 1) { - if (z == 0) { - if (y == 0) { - break forX; - } - break forY; - } - break; - } - - if (!fill) { - if (lengthSq(nextXn, yn, zn) <= 1 && lengthSq(xn, nextYn, zn) <= 1 && lengthSq(xn, yn, nextZn) <= 1) { - continue; - } - } - - set(x + cx, y + cy, z + cz, data); - set(-x + cx, y + cy, z + cz, data); - set(x + cx, -y + cy, z + cz, data); - set(x + cx, y + cy, -z + cz, data); - set(-x + cx, y + cy, -z + cz, data); - set(-x + cx, -y + cy, z + cz, data); - set(x + cx, -y + cy, -z + cz, data); - set(-x + cx, y + cy, -z + cz, data); - set(-x + cx, -y + cy, -z + cz, data); - } - } - } - } - - /** - * Set a cuboid of data in the mantle - * - * @param x1 the min x - * @param y1 the min y - * @param z1 the min z - * @param x2 the max x - * @param y2 the max y - * @param z2 the max z - * @param data the data to set - * @param the type of data to apply to the mantle - */ - public void setCuboid(int x1, int y1, int z1, int x2, int y2, int z2, T data) { - int j, k; - - for (int i = x1; i <= x2; i++) { - for (j = x1; j <= x2; j++) { - for (k = x1; k <= x2; k++) { - set(i, j, k, data); - } - } - } - } - - /** - * Set a pyramid of data in the mantle - * - * @param cx the center x - * @param cy the base y - * @param cz the center z - * @param data the data to set - * @param size the size of the pyramid (width of base & height) - * @param filled should it be filled or hollow - * @param the type of data to apply to the mantle - */ - @SuppressWarnings("ConstantConditions") - public void setPyramid(int cx, int cy, int cz, T data, int size, boolean filled) { - int height = size; - - for (int y = 0; y <= height; ++y) { - size--; - for (int x = 0; x <= size; ++x) { - for (int z = 0; z <= size; ++z) { - if ((filled && z <= size && x <= size) || z == size || x == size) { - set(x + cx, y + cy, z + cz, data); - set(-x + cx, y + cy, z + cz, data); - set(x + cx, y + cy, -z + cz, data); - set(-x + cx, y + cy, -z + cz, data); - } - } - } - } - } - - /** - * Set a 3d tube spline interpolated with Kochanek Bartels - * - * @param nodevectors the vector points - * @param radius the radius - * @param filled if it should be filled or hollow - * @param data the data to set - */ - public void setSpline(List nodevectors, double radius, boolean filled, T data) { - setSpline(nodevectors, 0, 0, 0, 10, radius, filled, data); - } - - /** - * Set a 3d tube spline interpolated with Kochanek Bartels - * - * @param nodevectors the spline points - * @param tension the tension 0 - * @param bias the bias 0 - * @param continuity the continuity 0 - * @param quality the quality 10 - * @param radius the radius - * @param filled filled or hollow - * @param data the data to set - * @param the type of data to apply to the mantle - */ - public void setSpline(List nodevectors, double tension, double bias, double continuity, double quality, double radius, boolean filled, T data) { - Set vset = new KSet<>(); - List nodes = new ArrayList<>(nodevectors.size()); - PathInterpolation interpol = new KochanekBartelsInterpolation(); - - for (Vector nodevector : nodevectors) { - INode n = new INode(nodevector); - n.setTension(tension); - n.setBias(bias); - n.setContinuity(continuity); - nodes.add(n); - } - - interpol.setNodes(nodes); - double splinelength = interpol.arcLength(0, 1); - for (double loop = 0; loop <= 1; loop += 1D / splinelength / quality) { - Vector tipv = interpol.getPosition(loop); - vset.add(new IrisPosition(tipv.toBlockVector())); - } - - vset = getBallooned(vset, radius); - if (!filled) { - vset = getHollowed(vset); - } - - set(vset, data); - } - - /** - * Set a 3d line - * - * @param a the first point - * @param b the second point - * @param radius the radius - * @param filled hollow or filled? - * @param data the data - * @param the type of data to apply to the mantle - */ - public void setLine(IrisPosition a, IrisPosition b, double radius, boolean filled, T data) { - setLine(ImmutableList.of(a, b), radius, filled, data); - } - - /** - * Set lines for points - * - * @param vectors the points - * @param radius the radius - * @param filled hollow or filled? - * @param data the data to set - * @param the type of data to apply to the mantle - */ - public void setLine(List vectors, double radius, boolean filled, T data) { - Set vset = new KSet<>(); - - for (int i = 0; vectors.size() != 0 && i < vectors.size() - 1; i++) { - IrisPosition pos1 = vectors.get(i); - IrisPosition pos2 = vectors.get(i + 1); - int x1 = pos1.getX(); - int y1 = pos1.getY(); - int z1 = pos1.getZ(); - int x2 = pos2.getX(); - int y2 = pos2.getY(); - int z2 = pos2.getZ(); - int tipx = x1; - int tipy = y1; - int tipz = z1; - int dx = Math.abs(x2 - x1); - int dy = Math.abs(y2 - y1); - int dz = Math.abs(z2 - z1); - - if (dx + dy + dz == 0) { - vset.add(new IrisPosition(tipx, tipy, tipz)); - continue; - } - - int dMax = Math.max(Math.max(dx, dy), dz); - if (dMax == dx) { - for (int domstep = 0; domstep <= dx; domstep++) { - tipx = x1 + domstep * (x2 - x1 > 0 ? 1 : -1); - tipy = (int) Math.round(y1 + domstep * ((double) dy) / ((double) dx) * (y2 - y1 > 0 ? 1 : -1)); - tipz = (int) Math.round(z1 + domstep * ((double) dz) / ((double) dx) * (z2 - z1 > 0 ? 1 : -1)); - - vset.add(new IrisPosition(tipx, tipy, tipz)); - } - } else if (dMax == dy) { - for (int domstep = 0; domstep <= dy; domstep++) { - tipy = y1 + domstep * (y2 - y1 > 0 ? 1 : -1); - tipx = (int) Math.round(x1 + domstep * ((double) dx) / ((double) dy) * (x2 - x1 > 0 ? 1 : -1)); - tipz = (int) Math.round(z1 + domstep * ((double) dz) / ((double) dy) * (z2 - z1 > 0 ? 1 : -1)); - - vset.add(new IrisPosition(tipx, tipy, tipz)); - } - } else /* if (dMax == dz) */ { - for (int domstep = 0; domstep <= dz; domstep++) { - tipz = z1 + domstep * (z2 - z1 > 0 ? 1 : -1); - tipy = (int) Math.round(y1 + domstep * ((double) dy) / ((double) dz) * (y2 - y1 > 0 ? 1 : -1)); - tipx = (int) Math.round(x1 + domstep * ((double) dx) / ((double) dz) * (x2 - x1 > 0 ? 1 : -1)); - - vset.add(new IrisPosition(tipx, tipy, tipz)); - } - } - } - - vset = getBallooned(vset, radius); - - if (!filled) { - vset = getHollowed(vset); - } - - set(vset, data); - } - - /** - * Set a cylinder in the mantle - * - * @param cx the center x - * @param cy the base y - * @param cz the center z - * @param data the data to set - * @param radius the radius - * @param height the height of the cyl - * @param filled filled or not - */ - public void setCylinder(int cx, int cy, int cz, T data, double radius, int height, boolean filled) { - setCylinder(cx, cy, cz, data, radius, radius, height, filled); - } - - /** - * Set a cylinder in the mantle - * - * @param cx the center x - * @param cy the base y - * @param cz the center z - * @param data the data to set - * @param radiusX the x radius - * @param radiusZ the z radius - * @param height the height of this cyl - * @param filled filled or hollow? - */ - public void setCylinder(int cx, int cy, int cz, T data, double radiusX, double radiusZ, int height, boolean filled) { - int affected = 0; - radiusX += 0.5; - radiusZ += 0.5; - - if (height == 0) { - return; - } else if (height < 0) { - height = -height; - cy = cy - height; - } - - if (cy < 0) { - cy = 0; - } else if (cy + height - 1 > worldHeight) { - height = worldHeight - cy + 1; - } - - final double invRadiusX = 1 / radiusX; - final double invRadiusZ = 1 / radiusZ; - final int ceilRadiusX = (int) Math.ceil(radiusX); - final int ceilRadiusZ = (int) Math.ceil(radiusZ); - double nextXn = 0; - - forX: - for (int x = 0; x <= ceilRadiusX; ++x) { - final double xn = nextXn; - nextXn = (x + 1) * invRadiusX; - double nextZn = 0; - for (int z = 0; z <= ceilRadiusZ; ++z) { - final double zn = nextZn; - nextZn = (z + 1) * invRadiusZ; - double distanceSq = lengthSq(xn, zn); - - if (distanceSq > 1) { - if (z == 0) { - break forX; - } - - break; - } - - if (!filled) { - if (lengthSq(nextXn, zn) <= 1 && lengthSq(xn, nextZn) <= 1) { - continue; - } - } - - for (int y = 0; y < height; ++y) { - set(cx + x, cy + y, cz + z, data); - set(cx + -x, cy + y, cz + z, data); - set(cx + x, cy + y, cz + -z, data); - set(cx + -x, cy + y, cz + -z, data); - } - } - } - } - - public void set(IrisPosition pos, T data) { - set(pos.getX(), pos.getY(), pos.getZ(), data); - } - - public void set(List positions, T data) { - for (IrisPosition i : positions) { - set(i, data); - } - } - - public void set(Set positions, T data) { - for (IrisPosition i : positions) { - set(i, data); - } - } - - private static Set getBallooned(Set vset, double radius) { - Set returnset = new HashSet<>(); - int ceilrad = (int) Math.ceil(radius); - - for (IrisPosition v : vset) { - int tipx = v.getX(); - int tipy = v.getY(); - int tipz = v.getZ(); - - for (int loopx = tipx - ceilrad; loopx <= tipx + ceilrad; loopx++) { - for (int loopy = tipy - ceilrad; loopy <= tipy + ceilrad; loopy++) { - for (int loopz = tipz - ceilrad; loopz <= tipz + ceilrad; loopz++) { - if (hypot(loopx - tipx, loopy - tipy, loopz - tipz) <= radius) { - returnset.add(new IrisPosition(loopx, loopy, loopz)); - } - } - } - } - } - return returnset; - } - - private static Set getHollowed(Set vset) { - Set returnset = new KSet<>(); - for (IrisPosition v : vset) { - double x = v.getX(); - double y = v.getY(); - double z = v.getZ(); - if (!(vset.contains(new IrisPosition(x + 1, y, z)) - && vset.contains(new IrisPosition(x - 1, y, z)) - && vset.contains(new IrisPosition(x, y + 1, z)) - && vset.contains(new IrisPosition(x, y - 1, z)) - && vset.contains(new IrisPosition(x, y, z + 1)) - && vset.contains(new IrisPosition(x, y, z - 1)))) { - returnset.add(v); - } - } - return returnset; - } - - private static double hypot(double... pars) { - double sum = 0; - for (double d : pars) { - sum += Math.pow(d, 2); - } - return Math.sqrt(sum); - } - - private static double lengthSq(double x, double y, double z) { - return (x * x) + (y * y) + (z * z); - } - - private static double lengthSq(double x, double z) { - return (x * x) + (z * z); - } - public int getWorldHeight() { return worldHeight; } + + public MantleChunk getChunk(Chunk e) { + return getChunk(e.getX(), e.getZ()); + } + + public void deleteChunkSlice(int x, int z, Class c) { + getChunk(x, z).deleteSlices(c); + } } diff --git a/src/main/java/com/volmit/iris/util/mantle/MantleChunk.java b/src/main/java/com/volmit/iris/util/mantle/MantleChunk.java index 162d514c6..46b57ec2b 100644 --- a/src/main/java/com/volmit/iris/util/mantle/MantleChunk.java +++ b/src/main/java/com/volmit/iris/util/mantle/MantleChunk.java @@ -25,6 +25,7 @@ import com.volmit.iris.util.matter.IrisMatter; import com.volmit.iris.util.matter.Matter; import com.volmit.iris.util.matter.MatterSlice; import com.volmit.iris.util.matter.slices.ZoneMatter; +import lombok.Getter; import java.io.DataInputStream; import java.io.DataOutputStream; @@ -39,6 +40,10 @@ import java.util.concurrent.atomic.AtomicReferenceArray; * Mantle Chunks are fully atomic & thread safe */ public class MantleChunk { + @Getter + private final int x; + @Getter + private final int z; private static final ZoneMatter zm = new ZoneMatter(); private final AtomicIntegerArray flags; private final AtomicReferenceArray sections; @@ -50,10 +55,12 @@ public class MantleChunk { * @param sectionHeight the height of the world in sections (blocks >> 4) */ @ChunkCoordinates - public MantleChunk(int sectionHeight) { + public MantleChunk(int sectionHeight, int x, int z) { sections = new AtomicReferenceArray<>(sectionHeight); flags = new AtomicIntegerArray(MantleFlag.values().length); features = new CopyOnWriteArrayList<>(); + this.x = x; + this.z = z; for (int i = 0; i < flags.length(); i++) { flags.set(i, 0); @@ -69,7 +76,7 @@ public class MantleChunk { * @throws ClassNotFoundException shit happens */ public MantleChunk(int sectionHeight, DataInputStream din) throws IOException, ClassNotFoundException { - this(sectionHeight); + this(sectionHeight, din.readByte(), din.readByte()); int s = din.readByte(); for (int i = 0; i < flags.length(); i++) { @@ -93,6 +100,13 @@ public class MantleChunk { flags.set(flag.ordinal(), f ? 1 : 0); } + public void raiseFlag(MantleFlag flag, Runnable r) { + if (!isFlagged(flag)) { + flag(flag, true); + r.run(); + } + } + public boolean isFlagged(MantleFlag flag) { return flags.get(flag.ordinal()) == 1; } @@ -163,6 +177,8 @@ public class MantleChunk { * @throws IOException shit happens */ public void write(DataOutputStream dos) throws IOException { + dos.writeByte(x); + dos.writeByte(z); dos.writeByte(sections.length()); for (int i = 0; i < flags.length(); i++) { @@ -225,4 +241,15 @@ public class MantleChunk { public List getFeatures() { return features; } + + public void deleteSlices(Class c) { + for(int i = 0; i < sections.length(); i++) + { + Matter m = sections.get(i); + if(m != null && m.hasSlice(c)) + { + m.deleteSlice(c); + } + } + } } diff --git a/src/main/java/com/volmit/iris/util/mantle/MantleFlag.java b/src/main/java/com/volmit/iris/util/mantle/MantleFlag.java index 351882140..d4b812a0b 100644 --- a/src/main/java/com/volmit/iris/util/mantle/MantleFlag.java +++ b/src/main/java/com/volmit/iris/util/mantle/MantleFlag.java @@ -24,7 +24,10 @@ public enum MantleFlag { OBJECT, UPDATE, JIGSAW, - FEATURE; + FEATURE, + INITIAL_SPAWNED, + REAL, + CARVED; static StateList getStateList() { return new StateList(MantleFlag.values()); diff --git a/src/main/java/com/volmit/iris/util/mantle/TectonicPlate.java b/src/main/java/com/volmit/iris/util/mantle/TectonicPlate.java index b25d5ef14..e5532774b 100644 --- a/src/main/java/com/volmit/iris/util/mantle/TectonicPlate.java +++ b/src/main/java/com/volmit/iris/util/mantle/TectonicPlate.java @@ -24,6 +24,7 @@ import com.volmit.iris.util.documentation.ChunkCoordinates; import com.volmit.iris.util.format.C; import com.volmit.iris.util.format.Form; import com.volmit.iris.util.scheduling.PrecisionStopwatch; +import lombok.Getter; import java.io.*; import java.util.concurrent.atomic.AtomicReferenceArray; @@ -38,14 +39,22 @@ public class TectonicPlate { private final int sectionHeight; private final AtomicReferenceArray chunks; + @Getter + private final int x; + + @Getter + private final int z; + /** * Create a new tectonic plate * * @param worldHeight the height of the world */ - public TectonicPlate(int worldHeight) { + public TectonicPlate(int worldHeight, int x, int z) { this.sectionHeight = worldHeight >> 4; this.chunks = new AtomicReferenceArray<>(1024); + this.x = x; + this.z = z; } /** @@ -57,8 +66,7 @@ public class TectonicPlate { * @throws ClassNotFoundException real shit bro */ public TectonicPlate(int worldHeight, DataInputStream din) throws IOException, ClassNotFoundException { - this(worldHeight); - + this(worldHeight, din.readInt(), din.readInt()); for (int i = 0; i < chunks.length(); i++) { if (din.readBoolean()) { chunks.set(i, new MantleChunk(sectionHeight, din)); @@ -132,7 +140,7 @@ public class TectonicPlate { MantleChunk chunk = get(x, z); if (chunk == null) { - chunk = new MantleChunk(sectionHeight); + chunk = new MantleChunk(sectionHeight, x & 31, z & 31); chunks.set(index(x, z), chunk); } @@ -167,6 +175,9 @@ public class TectonicPlate { * @throws IOException shit happens */ public void write(DataOutputStream dos) throws IOException { + dos.writeInt(x); + dos.writeInt(z); + for (int i = 0; i < chunks.length(); i++) { MantleChunk chunk = chunks.get(i); diff --git a/src/main/java/com/volmit/iris/util/noise/Worm.java b/src/main/java/com/volmit/iris/util/matter/MatterCavern.java similarity index 67% rename from src/main/java/com/volmit/iris/util/noise/Worm.java rename to src/main/java/com/volmit/iris/util/matter/MatterCavern.java index 02ef9449a..a06df01ef 100644 --- a/src/main/java/com/volmit/iris/util/noise/Worm.java +++ b/src/main/java/com/volmit/iris/util/matter/MatterCavern.java @@ -16,25 +16,13 @@ * along with this program. If not, see . */ -package com.volmit.iris.util.noise; +package com.volmit.iris.util.matter; +import lombok.AllArgsConstructor; import lombok.Data; @Data -public class Worm { - private double position; - private double velocity; - - public Worm(double startPosition, double startVelocity) { - this.position = startPosition; - this.velocity = startVelocity; - } - - public void unstep() { - position -= velocity; - } - - public void step() { - position += velocity; - } +@AllArgsConstructor +public class MatterCavern { + private final boolean cavern; } diff --git a/src/main/java/com/volmit/iris/util/noise/Worm2.java b/src/main/java/com/volmit/iris/util/matter/MatterUpdate.java similarity index 64% rename from src/main/java/com/volmit/iris/util/noise/Worm2.java rename to src/main/java/com/volmit/iris/util/matter/MatterUpdate.java index 7f72a9881..e675741d1 100644 --- a/src/main/java/com/volmit/iris/util/noise/Worm2.java +++ b/src/main/java/com/volmit/iris/util/matter/MatterUpdate.java @@ -16,31 +16,13 @@ * along with this program. If not, see . */ -package com.volmit.iris.util.noise; +package com.volmit.iris.util.matter; +import lombok.AllArgsConstructor; import lombok.Data; @Data -public class Worm2 { - private final Worm x; - private final Worm z; - - public Worm2(Worm x, Worm z) { - this.x = x; - this.z = z; - } - - public Worm2(int x, int z, int vx, int vz) { - this(new Worm(x, vx), new Worm(z, vz)); - } - - public void step() { - x.step(); - z.step(); - } - - public void unstep() { - x.unstep(); - z.unstep(); - } -} +@AllArgsConstructor +public class MatterUpdate { + private final boolean update; +} \ No newline at end of file diff --git a/src/main/java/com/volmit/iris/util/matter/slices/CavernMatter.java b/src/main/java/com/volmit/iris/util/matter/slices/CavernMatter.java new file mode 100644 index 000000000..636cd5605 --- /dev/null +++ b/src/main/java/com/volmit/iris/util/matter/slices/CavernMatter.java @@ -0,0 +1,52 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.util.matter.slices; + +import com.volmit.iris.util.matter.MatterCavern; +import com.volmit.iris.util.matter.Sliced; +import lombok.AllArgsConstructor; +import lombok.Data; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +@Sliced +public class CavernMatter extends RawMatter { + public static final MatterCavern ON = new MatterCavern(true); + public static final MatterCavern OFF = new MatterCavern(false); + + public CavernMatter() { + this(1, 1, 1); + } + + public CavernMatter(int width, int height, int depth) { + super(width, height, depth, MatterCavern.class); + } + + @Override + public void writeNode(MatterCavern b, DataOutputStream dos) throws IOException { + dos.writeBoolean(b.isCavern()); + } + + @Override + public MatterCavern readNode(DataInputStream din) throws IOException { + return din.readBoolean() ? ON : OFF; + } +} diff --git a/src/main/java/com/volmit/iris/util/matter/slices/RegionMatter.java b/src/main/java/com/volmit/iris/util/matter/slices/RegionMatter.java index 840dc6e77..ae89607ca 100644 --- a/src/main/java/com/volmit/iris/util/matter/slices/RegionMatter.java +++ b/src/main/java/com/volmit/iris/util/matter/slices/RegionMatter.java @@ -18,7 +18,7 @@ package com.volmit.iris.util.matter.slices; -import com.volmit.iris.core.project.loader.IrisRegistrant; +import com.volmit.iris.core.loader.IrisRegistrant; import com.volmit.iris.util.matter.Sliced; @Sliced diff --git a/src/main/java/com/volmit/iris/util/matter/slices/RegistryMatter.java b/src/main/java/com/volmit/iris/util/matter/slices/RegistryMatter.java index 7938df3f6..8a343b2af 100644 --- a/src/main/java/com/volmit/iris/util/matter/slices/RegistryMatter.java +++ b/src/main/java/com/volmit/iris/util/matter/slices/RegistryMatter.java @@ -18,7 +18,7 @@ package com.volmit.iris.util.matter.slices; -import com.volmit.iris.core.project.loader.IrisRegistrant; +import com.volmit.iris.core.loader.IrisRegistrant; import com.volmit.iris.util.context.IrisContext; import java.io.DataInputStream; diff --git a/src/main/java/com/volmit/iris/util/matter/slices/UpdateMatter.java b/src/main/java/com/volmit/iris/util/matter/slices/UpdateMatter.java new file mode 100644 index 000000000..65f487210 --- /dev/null +++ b/src/main/java/com/volmit/iris/util/matter/slices/UpdateMatter.java @@ -0,0 +1,52 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.util.matter.slices; + +import com.volmit.iris.util.matter.MatterUpdate; +import com.volmit.iris.util.matter.Sliced; +import lombok.AllArgsConstructor; +import lombok.Data; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +@Sliced +public class UpdateMatter extends RawMatter { + public static final MatterUpdate ON = new MatterUpdate(true); + public static final MatterUpdate OFF = new MatterUpdate(false); + + public UpdateMatter() { + this(1, 1, 1); + } + + public UpdateMatter(int width, int height, int depth) { + super(width, height, depth, MatterUpdate.class); + } + + @Override + public void writeNode(MatterUpdate b, DataOutputStream dos) throws IOException { + dos.writeBoolean(b.isUpdate()); + } + + @Override + public MatterUpdate readNode(DataInputStream din) throws IOException { + return din.readBoolean() ? ON : OFF; + } +} diff --git a/src/main/java/com/volmit/iris/util/noise/CNG.java b/src/main/java/com/volmit/iris/util/noise/CNG.java index fe8c39c7f..9d9253626 100644 --- a/src/main/java/com/volmit/iris/util/noise/CNG.java +++ b/src/main/java/com/volmit/iris/util/noise/CNG.java @@ -388,6 +388,11 @@ public class CNG { return noise(dim); } + public double noiseSym(double... dim) + { + return (noise(dim) * 2) - 1; + } + public double noise(double... dim) { double n = getNoise(dim); n = power != 1D ? (n < 0 ? -Math.pow(Math.abs(n), power) : Math.pow(n, power)) : n; diff --git a/src/main/java/com/volmit/iris/util/noise/WormIterator2.java b/src/main/java/com/volmit/iris/util/noise/WormIterator2.java deleted file mode 100644 index f3363e7e7..000000000 --- a/src/main/java/com/volmit/iris/util/noise/WormIterator2.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Iris is a World Generator for Minecraft Bukkit Servers - * Copyright (c) 2021 Arcane Arts (Volmit Software) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.volmit.iris.util.noise; - -import com.volmit.iris.util.function.NoiseProvider; -import lombok.Builder; -import lombok.Data; - -@Builder -@Data -public class WormIterator2 { - private transient Worm2 worm; - private transient NoiseProvider noise; - private int x; - private int z; - private int maxDistance; - private int maxIterations; - - public boolean hasNext() { - double dist = maxDistance - (Math.max(Math.abs(worm.getX().getVelocity()), Math.abs(worm.getZ().getVelocity())) + 1); - return maxIterations > 0 && - ((x * x) - (worm.getX().getPosition() * worm.getX().getPosition())) - + ((z * z) - (worm.getZ().getPosition() * worm.getZ().getPosition())) < dist * dist; - } - - public Worm2 next() { - if (worm == null) { - worm = new Worm2(x, z, 0, 0); - return worm; - } - - worm.getX().setVelocity(noise.noise(worm.getX().getPosition(), 0)); - worm.getZ().setVelocity(noise.noise(worm.getZ().getPosition(), 0)); - worm.step(); - - return worm; - } -} diff --git a/src/main/java/com/volmit/iris/util/noise/WormIterator3.java b/src/main/java/com/volmit/iris/util/noise/WormIterator3.java deleted file mode 100644 index 8b1083884..000000000 --- a/src/main/java/com/volmit/iris/util/noise/WormIterator3.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Iris is a World Generator for Minecraft Bukkit Servers - * Copyright (c) 2021 Arcane Arts (Volmit Software) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.volmit.iris.util.noise; - -import com.volmit.iris.util.function.NoiseProvider; -import lombok.Builder; -import lombok.Data; - -@Builder -@Data -public class WormIterator3 { - private transient Worm3 worm; - private int x; - private int y; - private int z; - private transient NoiseProvider noise; - private int maxDistance; - private int maxIterations; - - public boolean hasNext() { - if (worm == null) { - return true; - } - - double dist = maxDistance - (Math.max(Math.max(Math.abs(worm.getX().getVelocity()), - Math.abs(worm.getZ().getVelocity())), - Math.abs(worm.getY().getVelocity())) + 1); - - return maxIterations > 0 && - ((x * x) - (worm.getX().getPosition() * worm.getX().getPosition())) - + ((y * y) - (worm.getY().getPosition() * worm.getY().getPosition())) - + ((z * z) - (worm.getZ().getPosition() * worm.getZ().getPosition())) < dist * dist; - } - - public Worm3 next() { - maxIterations--; - if (worm == null) { - worm = new Worm3(x, y, z, 0, 0, 0); - return worm; - } - - worm.getX().setVelocity(worm.getX().getVelocity() + noise.noise(worm.getX().getPosition() + 10000, 0)); - worm.getY().setVelocity(worm.getY().getVelocity() + noise.noise(worm.getY().getPosition() + 1000, 0)); - worm.getZ().setVelocity(worm.getZ().getVelocity() + noise.noise(worm.getZ().getPosition() - 10000, 0)); - worm.step(); - - return worm; - } -} diff --git a/src/main/java/com/volmit/iris/util/parallel/BurstExecutor.java b/src/main/java/com/volmit/iris/util/parallel/BurstExecutor.java index 83aa394c4..301e00616 100644 --- a/src/main/java/com/volmit/iris/util/parallel/BurstExecutor.java +++ b/src/main/java/com/volmit/iris/util/parallel/BurstExecutor.java @@ -23,6 +23,7 @@ import com.volmit.iris.util.collection.KList; import lombok.Setter; import java.util.List; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Future; @@ -41,6 +42,11 @@ public class BurstExecutor { @SuppressWarnings("UnusedReturnValue") public Future queue(Runnable r) { + if (!multicore) { + r.run(); + return CompletableFuture.completedFuture(null); + } + synchronized (futures) { Future c = executor.submit(r); diff --git a/src/main/java/com/volmit/iris/util/scheduling/J.java b/src/main/java/com/volmit/iris/util/scheduling/J.java index e52475bd7..de0fc28fc 100644 --- a/src/main/java/com/volmit/iris/util/scheduling/J.java +++ b/src/main/java/com/volmit/iris/util/scheduling/J.java @@ -231,6 +231,15 @@ public class J { return f; } + public static CompletableFuture sfut(Runnable r, int delay) { + CompletableFuture f = new CompletableFuture(); + Bukkit.getScheduler().scheduleSyncDelayedTask(Iris.instance, () -> { + r.run(); + f.complete(null); + }, delay); + return f; + } + public static CompletableFuture afut(Runnable r) { CompletableFuture f = new CompletableFuture(); J.a(() -> { @@ -247,7 +256,11 @@ public class J { * @param delay the delay to wait in ticks before running */ public static void s(Runnable r, int delay) { - Bukkit.getScheduler().scheduleSyncDelayedTask(Iris.instance, r, delay); + try { + Bukkit.getScheduler().scheduleSyncDelayedTask(Iris.instance, r, delay); + } catch (Throwable e) { + Iris.reportError(e); + } } /** diff --git a/src/main/java/com/volmit/iris/util/scheduling/jobs/Job.java b/src/main/java/com/volmit/iris/util/scheduling/jobs/Job.java index 33864d86b..2e0331fe8 100644 --- a/src/main/java/com/volmit/iris/util/scheduling/jobs/Job.java +++ b/src/main/java/com/volmit/iris/util/scheduling/jobs/Job.java @@ -48,7 +48,12 @@ public interface Job { return (double) getWorkCompleted() / (double) getTotalWork(); } + default void execute(VolmitSender sender) { + execute(sender, () -> {}); + } + + default void execute(VolmitSender sender, Runnable whenComplete) { PrecisionStopwatch p = PrecisionStopwatch.start(); CompletableFuture f = J.afut(this::execute); int c = J.ar(() -> { @@ -61,6 +66,7 @@ public interface Job { f.whenComplete((fs, ff) -> { J.car(c); sender.sendMessage("Completed " + getName() + " in " + Form.duration(p.getMilliseconds(), 1)); + whenComplete.run(); }); } } diff --git a/src/main/java/com/volmit/iris/util/stream/ProceduralStream.java b/src/main/java/com/volmit/iris/util/stream/ProceduralStream.java index 1b22dc511..3ba8ebb41 100644 --- a/src/main/java/com/volmit/iris/util/stream/ProceduralStream.java +++ b/src/main/java/com/volmit/iris/util/stream/ProceduralStream.java @@ -19,7 +19,7 @@ package com.volmit.iris.util.stream; import com.volmit.iris.Iris; -import com.volmit.iris.core.project.loader.IrisData; +import com.volmit.iris.core.loader.IrisData; import com.volmit.iris.engine.object.common.IRare; import com.volmit.iris.engine.object.noise.IrisStyledRange; import com.volmit.iris.util.collection.KList; diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 0d540b7b7..e59e41bf3 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -11,7 +11,7 @@ libraries: - org.apache.commons:commons-lang3:3.12.0 - io.timeandspace:smoothie-map:2.0.2 - com.google.guava:guava:30.1.1-jre - - com.google.code.gson:gson:2.8.7 + - com.google.code.gson:gson:2.8.8 - org.zeroturnaround:zt-zip:1.14 - it.unimi.dsi:fastutil:8.5.4 - org.ow2.asm:asm:9.2