Merge remote-tracking branch 'upstream/master' into DecreeCommands

This commit is contained in:
CocoTheOwner 2021-08-28 16:19:29 +02:00
commit 49385a08ad
154 changed files with 2709 additions and 2771 deletions

View File

@ -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'

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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 <https://www.gnu.org/licenses/>.
*/
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<String> 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 "<number> [|,&,^,>>,<<,%] <other>";
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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 {

View File

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

View File

@ -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 {

View File

@ -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 <https://www.gnu.org/licenses/>.
*/
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<String> 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<Runnable> 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<Runnable> r = new QueueJob<>() {
final KList<Future<?>> 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]";
}
}

View File

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

View File

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

View File

@ -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<LivingEntity> lastEntities = new KList<>();
private final KMap<String, Long> notifications = new KMap<>();
private final ChronoLatch centities = new ChronoLatch(1000);
private final RollingSequence rs = new RollingSequence(512);
private final O<Integer> m = new O<>();
private final KMap<BlockPosition, BufferedImage> positions = new KMap<>();
private final KMap<BlockPosition, BufferedImage> fastpositions = new KMap<>();
private final KSet<BlockPosition> working = new KSet<>();
private final KSet<BlockPosition> 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<LivingEntity> 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<String, Long> 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<Integer> m = new O<>();
private int tid = 0;
private final KMap<BlockPosition, BufferedImage> positions = new KMap<>();
private final KMap<BlockPosition, BufferedImage> fastpositions = new KMap<>();
private final KSet<BlockPosition> working = new KSet<>();
private final KSet<BlockPosition> 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()) {

View File

@ -16,13 +16,13 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
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;

View File

@ -16,7 +16,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
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;

View File

@ -16,7 +16,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
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;

View File

@ -16,7 +16,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
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;

View File

@ -16,7 +16,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
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;

View File

@ -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 <https://www.gnu.org/licenses/>.
*/
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<IrisPack> 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<File> 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<IrisPack> from(VolmitSender sender, IrisPackRepository repo) throws MalformedURLException {
CompletableFuture<IrisPack> 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<File> collectFiles(File f, String fileExtension) {
KList<File> 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;
}
}

View File

@ -16,7 +16,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
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!");
}
}
}

View File

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

View File

@ -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 <https://www.gnu.org/licenses/>.
*/
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()));
}
}

View File

@ -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<World> 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() {

View File

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

View File

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

View File

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

View File

@ -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<World> onDone) throws IrisException {
if (isProjectOpen()) {
close();
}

View File

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

View File

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

View File

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

View File

@ -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<Double> overlayStream;
private ProceduralStream<Double> heightFluidStream;
private ProceduralStream<Integer> trueHeightStream;
private ProceduralStream<Integer> trueHeightStreamNoFeatures;
private ProceduralStream<Double> slopeStream;
private ProceduralStream<Integer> topSurfaceStream;
private ProceduralStream<RNG> 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<CaveResult> 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<IrisFeaturePositional> 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()));
}
}

View File

@ -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<Biome> biomeActuator;
private EngineModifier<BlockData> depositModifier;
private EngineModifier<BlockData> caveModifier;
private EngineModifier<BlockData> ravineModifier;
private EngineModifier<BlockData> postModifier;
private final AtomicCache<IrisEngineData> 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();

View File

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

View File

@ -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<Long, Long> chunkCooldowns;
private final KList<Runnable> 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<ItemStack> d, Runnable drop, KList<IrisBlockDrops> 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) {

View File

@ -55,8 +55,7 @@ public class IrisBiomeActuator extends EngineAssignedActuator<Biome> {
return true;
}
} catch (Throwable e) {
e.printStackTrace();
Iris.reportError(e);
}
return false;

View File

@ -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<BlockData> {
private static final Predicate<BlockData> PREDICATE_SOLID = (b) -> b != null && !b.getMaterial().isAir() && !b.getMaterial().equals(Material.WATER) && !b.getMaterial().equals(Material.LAVA);
private final BiPredicate<BlockData, Integer> PREDICATE_CAVELIQUID;
private final RNG rng;
@Getter
private final EngineDecorator surfaceDecorator;
@ -61,22 +59,6 @@ public class IrisDecorantActuator extends EngineAssignedActuator<BlockData> {
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<BlockData> {
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<BlockData> {
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<BlockData> {
}
private boolean shouldRayDecorate() {
return getEngine().getDimension().isCarving() || getEngine().getDimension().isCaves() || getEngine().getDimension().isRavines();
return false; // TODO CAVES
}
}

View File

@ -38,14 +38,12 @@ public class IrisTerrainNormalActuator extends EngineAssignedActuator<BlockData>
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<BlockData>
}
}
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;

View File

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

View File

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

View File

@ -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<BlockData> getTerrainActuator();
EngineActuator<BlockData> getDecorantActuator();
EngineActuator<Biome> getBiomeActuator();
EngineModifier<BlockData> getCaveModifier();
EngineModifier<BlockData> getRavineModifier();
EngineModifier<BlockData> getDepositModifier();
EngineModifier<BlockData> 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<BlockData> blocks, Hunk<Biome> 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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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<Runnable> 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<Runnable> 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<IrisFeaturePositional> forEachFeature(double x, double z) {
KList<IrisFeaturePositional> 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:
}
}

View File

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

View File

@ -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<? extends TileState> 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 <T> the type of data to apply to the mantle
*/
public <T> 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 <T> the type of data to apply to the mantle
*/
public <T> 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 <T> the type of data to apply to the mantle
*/
public <T> 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 <T> the type of data to apply to the mantle
*/
@SuppressWarnings("ConstantConditions")
public <T> 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 <T> the type of data to apply to the mantle
*/
public <T> 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 <T> the type of data to apply to the mantle
*/
public <T> void setLine(List<IrisPosition> vectors, double radius, boolean filled, T data) {
Set<IrisPosition> 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 <T> 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 <T> 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 <T> void set(IrisPosition pos, T data) {
setData(pos.getX(), pos.getY(), pos.getZ(), data);
}
public <T> void set(List<IrisPosition> positions, T data) {
for (IrisPosition i : positions) {
set(i, data);
}
}
public <T> void set(Set<IrisPosition> positions, T data) {
for (IrisPosition i : positions) {
set(i, data);
}
}
private static Set<IrisPosition> getBallooned(Set<IrisPosition> vset, double radius) {
Set<IrisPosition> 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<IrisPosition> getHollowed(Set<IrisPosition> vset) {
Set<IrisPosition> 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;
}
}

View File

@ -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 <https://www.gnu.org/licenses/>.
*/
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<Runnable> 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);
}
}

View File

@ -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<IrisFeaturePotential> getFeatures() {

View File

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

View File

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

View File

@ -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 <https://www.gnu.org/licenses/>.
*/
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<BlockData> {
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<BlockData> 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());
}
}

View File

@ -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 <https://www.gnu.org/licenses/>.
*/
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<BlockData> {
public static final BlockData CAVE_AIR = B.get("CAVE_AIR");
public static final BlockData AIR = B.get("AIR");
private static final KList<CaveResult> EMPTY = new KList<>();
private final FastNoiseDouble gg;
private final RNG rng;
public IrisCaveModifier(Engine engine) {
super(engine, "Cave");
rng = new RNG(engine.getWorld().seed() + 28934555);
gg = new FastNoiseDouble(324895L * rng.nextParallelRNG(49678).imax());
}
@Override
public void onModify(int x, int z, Hunk<BlockData> 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<BlockData> a) {
for (int j = 0; j < a.getDepth(); j++) {
KList<CaveResult> 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<BlockData> floor = cave.generateLayers(getDimension(), x + finalI, z + j, rng, cl.getFloor(), cl.getFloor(), getData(), getComplex());
KList<BlockData> 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<CaveResult> genCaves(double wxx, double wzz) {
return genCaves(wxx, wzz, 0, 0, null);
}
public KList<CaveResult> genCaves(double wxx, double wzz, int x, int z, Hunk<BlockData> data) {
if (!getDimension().isCaves()) {
return EMPTY;
}
KList<CaveResult> result = new KList<>();
gg.setNoiseType(FastNoiseDouble.NoiseType.Cellular);
gg.setCellularReturnType(FastNoiseDouble.CellularReturnType.Distance2Sub);
gg.setCellularDistanceFunction(FastNoiseDouble.CellularDistanceFunction.Natural);
for (int i = 0; i < getDimension().getCaveLayers().size(); i++) {
IrisCaveLayer layer = getDimension().getCaveLayers().get(i);
generateCave(result, wxx, wzz, x, z, data, layer, i);
}
return result;
}
public void generateCave(KList<CaveResult> result, double wxx, double wzz, int x, int z, Hunk<BlockData> data, IrisCaveLayer layer, int seed) {
double scale = layer.getCaveZoom();
Function<Integer, BlockData> fluid = (height) ->
{
if (!layer.getFluid().hasFluid(getData())) {
return CAVE_AIR;
}
if (layer.getFluid().isInverseHeight() && height >= layer.getFluid().getFluidHeight()) {
return layer.getFluid().getFluid(getData());
} else if (!layer.getFluid().isInverseHeight() && height <= layer.getFluid().getFluidHeight()) {
return layer.getFluid().getFluid(getData());
}
return CAVE_AIR;
};
int surface = (int) Math.round(getComplex().getHeightStream().get(wxx, wzz));
double wx = wxx + layer.getHorizontalSlope().get(rng, 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<BlockData> data) {
BlockData d = data.get(Math.max(x, 0), Math.max(y, 0), Math.max(z, 0));
if (d != null) {
return d.getMaterial();
}
return Material.CAVE_AIR;
}
public boolean dig(int x, int y, int z, Hunk<BlockData> data, Function<Integer, BlockData> caveFluid) {
Material a = mat(x, y, z, data);
Material c = mat(x, y + 1, z, data);
Material d = mat(x, y + 2, z, data);
Material e = mat(x, y + 3, z, data);
Material f = mat(x, y - 1, z, data);
BlockData b = caveFluid.apply(y);
BlockData b2 = caveFluid.apply(y + 1);
if (can(a) && canAir(c, b) && canAir(f, b) && canWater(d) && canWater(e)) {
data.set(x, y, z, b);
data.set(x, y + 1, z, b2);
return true;
}
return false;
}
public boolean canAir(Material m, BlockData caveFluid) {
return (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);
}
}

View File

@ -231,189 +231,6 @@ public class IrisPostModifier extends EngineAssignedModifier<BlockData> {
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<BlockData> currentData) {
if (floor >= currentData.getHeight()) {
return currentData.getHeight() - 1;
}
if (B.isAir(getPostBlock(x, floor, z, currentPostX, currentPostZ, currentData))) {
if (B.isAir(getPostBlock(x, floor - 1, z, currentPostX, currentPostZ, currentData))) {
return floor - 2;
}
return floor - 1;
} else {
if (!B.isAir(getPostBlock(x, floor + 1, z, currentPostX, currentPostZ, currentData))) {
if (!B.isAir(getPostBlock(x, floor + 2, z, currentPostX, currentPostZ, currentData))) {
return floor + 2;
}
return floor + 1;
}
return floor;
}
}
private int nearestCaveCeiling(int ceiling, int x, int z, int currentPostX, int currentPostZ, Hunk<BlockData> currentData) {
if (ceiling >= currentData.getHeight()) {
return currentData.getHeight() - 1;
}
if (B.isAir(getPostBlock(x, ceiling, z, currentPostX, currentPostZ, currentData))) {
if (B.isAir(getPostBlock(x, ceiling + 1, z, currentPostX, currentPostZ, currentData))) {
return ceiling + 2;
}
return ceiling + 1;
} else {
if (!B.isAir(getPostBlock(x, ceiling - 1, z, currentPostX, currentPostZ, currentData))) {
if (!B.isAir(getPostBlock(x, ceiling - 2, z, currentPostX, currentPostZ, currentData))) {
return ceiling - 2;
}
return ceiling - 1;
}
return ceiling;
}
}
public boolean isAir(int x, int y, int z, int currentPostX, int currentPostZ, Hunk<BlockData> currentData) {

View File

@ -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 <https://www.gnu.org/licenses/>.
*/
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<BlockData> {
private static final BlockData CAVE_AIR = B.get("CAVE_AIR");
private static final BlockData LAVA = B.get("LAVA");
private final CNG cng;
private final RNG rng;
public IrisRavineModifier(Engine engine) {
super(engine, "Ravine");
rng = new RNG(getEngine().getWorld().seed()).nextParallelRNG(29596878);
cng = NoiseStyle.IRIS_THICK.create(rng);
}
@Override
public void onModify(int x, int z, Hunk<BlockData> 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<BlockData> pos, int x, int y, int z, BlockData b) {
pos.set(x, y, z, b);
}
private BlockData get(Hunk<BlockData> pos, int x, int y, int z) {
BlockData bb = pos.get(x, y, z);
if (bb == null) {
bb = CAVE_AIR;
}
return bb;
}
private BlockData getSurfaceBlock(int n6, int i, RNG rmg) {
return getComplex().getTrueBiomeStream().get(n6, i).getSurfaceBlock(n6, i, rmg, getData());
}
private final float[] ravineCache = new float[1024];
private void doRavine(long seed, int tx, int tz, 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<BlockData> terrain) {
int n5;
RNG random = new RNG(seed);
double x = tx * 16 + 8;
double z = tz * 16 + 8;
float f4 = 0.0f;
float f5 = 0.0f;
if (n4 <= 0) {
n5 = 8 * 16 - 16;
n4 = n5 - random.nextInt(n5 / 4);
}
n5 = 0;
if (n3 == -1) {
n3 = n4 / 2;
n5 = 1;
}
float f6 = 1.0f;
// TODO: WARNING HEIGHT
for (int i = 0; i < 256; ++i) {
if (i == 0 || random.nextInt(getDimension().getRavineRibRarity()) == 0) {
f6 = 1.0f + random.nextFloat() * random.nextFloat() * 1.0f;
}
this.ravineCache[i] = f6 * f6;
}
while (n3 < n4) {
double d7 = 1.5 + (double) (MathHelper.sin((float) n3 * 3.1415927f / (float) n4) * f * 1.0f);
double d8 = d7 * d4;
d7 *= (double) random.nextFloat() * 0.25 + 0.75;
d8 *= (double) random.nextFloat() * 0.25 + 0.75;
float f7 = MathHelper.cos(f3);
float f8 = MathHelper.sin(f3);
sx = sx + (double) (MathHelper.cos(f2) * f7);
sy += f8;
sz += MathHelper.sin(f2) * f7;
f3 *= 0.7f;
f3 += f5 * 0.05f;
f2 += f4 * 0.05f;
f5 *= 0.8f;
f4 *= 0.5f;
f5 += (random.nextFloat() - random.nextFloat()) * random.nextFloat() * 2.0f;
f4 += (random.nextFloat() - random.nextFloat()) * random.nextFloat() * 4.0f;
if (n5 != 0 || random.nextInt(4) != 0) {
double d9 = sx - x;
double d10 = sz - z;
double d11 = n4 - n3;
double d12 = f + 2.0f + 16.0f;
if (d9 * d9 + d10 * d10 - d11 * d11 > d12 * d12) {
return;
}
if (sx >= x - 16.0 - d7 * 2.0 && sz >= z - 16.0 - d7 * 2.0 && sx <= x + 16.0 + d7 * 2.0 && sz <= z + 16.0 + d7 * 2.0) {
int n6;
int n7 = MathHelper.floor(sx - d7) - tx * 16 - 1;
int n8 = MathHelper.floor(sx + d7) - tx * 16 + 1;
int n9 = MathHelper.floor(sy - d8) - 1;
int n10 = MathHelper.floor(sy + d8) + 1;
int n11 = MathHelper.floor(sz - d7) - tz * 16 - 1;
int n12 = MathHelper.floor(sz + d7) - tz * 16 + 1;
if (n7 < 0) {
n7 = 0;
}
if (n8 > 16) {
n8 = 16;
}
if (n9 < 1) {
n9 = 1;
}
if (n10 > 248) {
n10 = 248;
}
if (n11 < 0) {
n11 = 0;
}
if (n12 > 16) {
n12 = 16;
}
boolean bl = false;
for (int i = n7; !bl && i < n8; ++i) {
for (n6 = n11; !bl && n6 < n12; ++n6) {
for (int j = n10 + 1; !bl && j >= n9 - 1; --j) {
// TODO: WARNING HEIGHT
if (j < 0 || j >= 256) {
continue;
}
BlockData bb = get(terrain, i, j, n6);
if (B.isWater(bb)) {
bl = true;
}
if (j == n9 - 1 || i == n7 || i == n8 - 1 || n6 == n11 || n6 == n12 - 1) {
continue;
}
j = n9;
}
}
}
if (!bl) {
BlockPosition bps = new BlockPosition(0, 0, 0);
for (n6 = n7; n6 < n8; ++n6) {
double d13 = ((double) (n6 + tx * 16) + 0.5 - sx) / d7;
for (int i = n11; i < n12; ++i) {
double d14 = ((double) (i + tz * 16) + 0.5 - sz) / d7;
boolean bl2 = false;
if (d13 * d13 + d14 * d14 >= 1.0) {
continue;
}
for (int j = n10; j > n9; --j) {
double d15 = ((double) (j - 1) + 0.5 - sy) / d8;
if ((d13 * d13 + d14 * d14) * (double) this.ravineCache[j - 1] + d15 * d15 / 6.0 >= 1.0) {
continue;
}
BlockData blockData = get(terrain, n6, j, i);
if (isSurface(blockData)) {
bl2 = true;
}
if (j - 1 < 10) {
set(terrain, n6, j, i, LAVA);
continue;
}
set(terrain, n6, j, i, CAVE_AIR);
if (!bl2 || !isDirt(get(terrain, n6, j - 1, i))) {
continue;
}
cSet(bps, n6 + tx * 16, 0, i + tz * 16);
set(terrain, n6, j - 1, i, getSurfaceBlock(n6, i, rng));
}
}
}
if (n5 != 0) {
break;
}
}
}
}
++n3;
}
}
private BlockPosition cSet(BlockPosition bb, double var0, @SuppressWarnings("SameParameterValue") double var2, double var4) {
bb.setX(MathHelper.floor(var0));
bb.setY(MathHelper.floor(var2));
bb.setZ(MathHelper.floor(var4));
return bb;
}
private boolean isDirt(BlockData d) {
//@builder
Material m = d.getMaterial();
return m.equals(Material.DIRT) ||
m.equals(Material.COARSE_DIRT) ||
m.equals(Material.SAND);
//@done
}
private boolean isSurface(BlockData d) {
//@builder
Material m = d.getMaterial();
return m.equals(Material.GRASS_BLOCK) ||
m.equals(Material.DIRT) ||
m.equals(Material.COARSE_DIRT) ||
m.equals(Material.PODZOL) ||
m.equals(Material.SAND);
//@done
}
public void genRavines(int n, int n2, Position2 chunkSnapshot, RNG bbb, Hunk<BlockData> terrain) {
RNG b = this.rng.nextParallelRNG(21949666);
RNG bx = this.rng.nextParallelRNG(6676121);
long l = b.nextLong();
long l2 = b.nextLong();
for (int i = n - 8; i <= n + 8; ++i) {
for (int j = n2 - 8; j <= n2 + 8; ++j) {
long l3 = (long) i * l;
long l4 = (long) j * l2;
bx = this.rng.nextParallelRNG((int) (l3 ^ l4 ^ 6676121));
doRavines(i, j, n, n2, chunkSnapshot, bx, terrain);
}
}
}
private void doRavines(int tx, int tz, int sx, int sz, Position2 chunkSnapshot, RNG b, Hunk<BlockData> terrain) {
if (b.nextInt(getDimension().getRavineRarity()) != 0) {
return;
}
double x = tx * 16 + b.nextInt(16);
double d2 = b.nextInt(b.nextInt(40) + 8) + 20;
double z = tz * 16 + b.nextInt(16);
int n5 = 1;
for (int i = 0; i < n5; ++i) {
float f = b.nextFloat() * 3.1415927f * 2.0f;
float f2 = (b.nextFloat() - 0.5f) * 2.0f / 8.0f;
float f3 = (b.nextFloat() * 2.0f + b.nextFloat()) * 2.0f;
this.doRavine(b.nextLong(), sx, sz, chunkSnapshot, x, d2, z, f3, f, f2, 0, 0, 3.0, b, terrain);
}
}
public void generateRavines(RNG nextParallelRNG, int x, int z, Hunk<BlockData> terrain) {
genRavines(x, z, new Position2(x, z), nextParallelRNG.nextParallelRNG(x).nextParallelRNG(z), terrain);
}
}

View File

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

View File

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

View File

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

View File

@ -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")

View File

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

View File

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

View File

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

View File

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

View File

@ -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 <https://www.gnu.org/licenses/>.
*/
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<ProceduralStream<Boolean>> streamCache = new AtomicCache<>();
private final transient AtomicCache<ProceduralStream<Double>> rawStreamCache = new AtomicCache<>();
private final transient AtomicCache<CNG> 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<Boolean> stream(RNG rng, IrisData data) {
return streamCache.aquire(() -> ProceduralStream.of((x, y, z) -> isCarved(rng, data, x, y, z), Interpolated.BOOLEAN));
}
public ProceduralStream<Double> 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();
}
}

View File

@ -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 <https://www.gnu.org/licenses/>.
*/
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<BlockData> 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");
});
}
}

View File

@ -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 <https://www.gnu.org/licenses/>.
*/
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;
}

View File

@ -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 <https://www.gnu.org/licenses/>.
*/
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<ProceduralStream<Boolean>> 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;
}
}

View File

@ -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 <https://www.gnu.org/licenses/>.
*/
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<IrisCavernZone> 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<ProceduralStream<IrisCavernZone>> zonesRarity = new AtomicCache<>();
private transient AtomicCache<ProceduralStream<Double>> 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<Double> 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);
}
}

View File

@ -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 <https://www.gnu.org/licenses/>.
*/
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<IrisCavePlacer> caves = new KList<>();
@ArrayType(type = IrisElipsoid.class, min = 1)
@Desc("Define elipsoids")
private KList<IrisElipsoid> elipsoids = new KList<>();
@ArrayType(type = IrisSphere.class, min = 1)
@Desc("Define spheres")
private KList<IrisSphere> spheres = new KList<>();
@ArrayType(type = IrisPyramid.class, min = 1)
@Desc("Define pyramids")
private KList<IrisPyramid> 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;
}
}

View File

@ -16,18 +16,33 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
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);
}
}

View File

@ -16,29 +16,26 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
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<IrisCave> 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<Vector> 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);
}
}

View File

@ -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 <https://www.gnu.org/licenses/>.
*/
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()));
}
}

View File

@ -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 <https://www.gnu.org/licenses/>.
*/
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();
}
}

View File

@ -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 <https://www.gnu.org/licenses/>.
*/
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();
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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<IrisShapedGeneratorStyle> overlayNoise = new KList<>();
@ArrayType(min = 1, type = IrisCaveLayer.class)
@Desc("Define cave layers")
private KList<IrisCaveLayer> caveLayers = new KList<>();
@ArrayType(min = 1, type = IrisCarveLayer.class)
@Desc("Define carve layers")
private KList<IrisCarveLayer> 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";

View File

@ -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 <https://www.gnu.org/licenses/>.
*/
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<BukkitChunkGenerator> injector;
StudioMode(Consumer<BukkitChunkGenerator> injector) {
this.injector = injector;
}
public void inject(BukkitChunkGenerator c) {
injector.accept(c);
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

Some files were not shown because too many files have changed in this diff Show More