Merge branch 'master' into saplingOverrides

This commit is contained in:
CocoTheOwner 2021-07-25 15:28:54 +02:00
commit 7fb87ad67f
129 changed files with 2266 additions and 885 deletions

View File

@ -17,7 +17,6 @@ body:
2. Do this... 2. Do this...
3. Do that... 3. Do that...
4. Observe the error... 4. Observe the error...
render: txt
validations: validations:
required: true required: true
- type: textarea - type: textarea

View File

@ -5,7 +5,7 @@ plugins {
} }
group 'com.volmit.iris' group 'com.volmit.iris'
version '1.5.6' version '1.5.10'
def apiVersion = '1.17' def apiVersion = '1.17'
def name = 'Iris' def name = 'Iris'
def main = 'com.volmit.iris.Iris' def main = 'com.volmit.iris.Iris'
@ -76,8 +76,8 @@ shadowJar
minimize() minimize()
dependencies { dependencies {
include(dependency('org.zeroturnaround:zt-zip:1.14')) include(dependency('org.zeroturnaround:zt-zip:1.14'))
include(dependency('io.papermc:paperlib:1.0.5'))
include(dependency('com.googlecode.concurrentlinkedhashmap:concurrentlinkedhashmap-lru:1.4.2')) include(dependency('com.googlecode.concurrentlinkedhashmap:concurrentlinkedhashmap-lru:1.4.2'))
include(dependency('io.papermc:paperlib:1.0.5'))
} }
} }
@ -92,6 +92,9 @@ dependencies {
implementation 'org.spigotmc:spigot-api:1.17-R0.1-SNAPSHOT' implementation 'org.spigotmc:spigot-api:1.17-R0.1-SNAPSHOT'
implementation 'org.bukkit.craftbukkit:1.17:1.17' implementation 'org.bukkit.craftbukkit:1.17:1.17'
implementation 'org.bukkit.craftbukkit:1.17.1:1.17.1' implementation 'org.bukkit.craftbukkit:1.17.1:1.17.1'
implementation 'org.bukkit.craftbukkit:1.16.5:1.16.5'
implementation 'org.bukkit.craftbukkit:1.16.3:1.16.3'
implementation 'org.bukkit.craftbukkit:1.16.1:1.16.1'
implementation 'com.bergerkiller.bukkit:BKCommonLib:1.16.4-v2' implementation 'com.bergerkiller.bukkit:BKCommonLib:1.16.4-v2'
implementation 'com.sk89q.worldedit:worldedit-bukkit:7.2.0-SNAPSHOT' implementation 'com.sk89q.worldedit:worldedit-bukkit:7.2.0-SNAPSHOT'
implementation 'io.lumine.xikage:MythicMobs:4.9.1' implementation 'io.lumine.xikage:MythicMobs:4.9.1'

View File

@ -560,7 +560,25 @@ public class Iris extends VolmitPlugin implements Listener {
} }
public boolean isMCA() { public boolean isMCA() {
return IrisSettings.get().getGenerator().isMcaPregenerator(); return !IrisSettings.get().getGenerator().isDisableMCA();
}
public static void reportErrorChunk(int x, int z, Throwable e, String extra) {
if (IrisSettings.get().getGeneral().isDebug()) {
File f = instance.getDataFile("debug", "chunk-errors", "chunk."+ x + "." + z + ".txt");
if (!f.exists()) {
J.attempt(() -> {
PrintWriter pw = new PrintWriter(f);
pw.println("Thread: " + Thread.currentThread().getName());
pw.println("First: " + new Date(M.ms()));
e.printStackTrace(pw);
pw.close();
});
}
Iris.debug("Chunk " + x + "," + z + " Exception Logged: " + e.getClass().getSimpleName() + ": " + C.RESET + "" + C.LIGHT_PURPLE + e.getMessage());
}
} }
public static synchronized void reportError(Throwable e) { public static synchronized void reportError(Throwable e) {

View File

@ -21,7 +21,9 @@ package com.volmit.iris.core;
import com.volmit.iris.Iris; import com.volmit.iris.Iris;
import com.volmit.iris.core.tools.IrisWorlds; import com.volmit.iris.core.tools.IrisWorlds;
import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.framework.Engine;
import com.volmit.iris.engine.framework.EngineParallaxManager;
import com.volmit.iris.engine.framework.IrisAccess; import com.volmit.iris.engine.framework.IrisAccess;
import com.volmit.iris.engine.object.IrisFeaturePositional;
import com.volmit.iris.util.board.BoardManager; import com.volmit.iris.util.board.BoardManager;
import com.volmit.iris.util.board.BoardProvider; import com.volmit.iris.util.board.BoardProvider;
import com.volmit.iris.util.board.BoardSettings; import com.volmit.iris.util.board.BoardSettings;
@ -29,6 +31,7 @@ import com.volmit.iris.util.board.ScoreDirection;
import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.format.C; import com.volmit.iris.util.format.C;
import com.volmit.iris.util.format.Form; import com.volmit.iris.util.format.Form;
import com.volmit.iris.util.math.Position2;
import com.volmit.iris.util.math.RollingSequence; import com.volmit.iris.util.math.RollingSequence;
import com.volmit.iris.util.scheduling.ChronoLatch; import com.volmit.iris.util.scheduling.ChronoLatch;
import com.volmit.iris.util.scheduling.J; import com.volmit.iris.util.scheduling.J;
@ -103,6 +106,12 @@ public class IrisBoardManager implements BoardProvider, Listener {
int y = player.getLocation().getBlockY(); int y = player.getLocation().getBlockY();
int z = player.getLocation().getBlockZ(); int z = player.getLocation().getBlockZ();
if(g.getCompound() == null)
{
v.add("Loading...");
return v;
}
Engine engine = g.getCompound().getEngineForHeight(y); Engine engine = g.getCompound().getEngineForHeight(y);
int parallaxChunks = 0; int parallaxChunks = 0;
@ -128,11 +137,15 @@ public class IrisBoardManager implements BoardProvider, Listener {
if (engine != null) { if (engine != null) {
v.add("&7&m------------------"); v.add("&7&m------------------");
KList<IrisFeaturePositional> f = new KList<>();
engine.getFramework().getEngineParallax().forEachFeature(x, z, f::add);
v.add(C.AQUA + "Engine" + C.GRAY + ": " + engine.getName() + " " + engine.getMinHeight() + "-" + engine.getMaxHeight()); v.add(C.AQUA + "Engine" + C.GRAY + ": " + engine.getName() + " " + engine.getMinHeight() + "-" + engine.getMaxHeight());
v.add(C.AQUA + "Region" + C.GRAY + ": " + engine.getRegion(x, z).getName()); v.add(C.AQUA + "Region" + C.GRAY + ": " + engine.getRegion(x, z).getName());
v.add(C.AQUA + "Biome" + C.GRAY + ": " + engine.getBiome(x, y, z).getName()); v.add(C.AQUA + "Biome" + C.GRAY + ": " + engine.getBiome(x, y, z).getName());
v.add(C.AQUA + "Height" + C.GRAY + ": " + Math.round(engine.getHeight(x, z))); v.add(C.AQUA + "Height" + C.GRAY + ": " + Math.round(engine.getHeight(x, z)));
v.add(C.AQUA + "Slope" + C.GRAY + ": " + Form.f(engine.getFramework().getComplex().getSlopeStream().get(x, z), 2)); v.add(C.AQUA + "Slope" + C.GRAY + ": " + Form.f(engine.getFramework().getComplex().getSlopeStream().get(x, z), 2));
v.add(C.AQUA + "Features " + C.GRAY + ": " + Form.f(f.size()));
} }
if (Iris.jobCount() > 0) { if (Iris.jobCount() > 0) {

View File

@ -40,6 +40,7 @@ public class IrisDataManager {
private ResourceLoader<IrisJigsawPool> jigsawPoolLoader; private ResourceLoader<IrisJigsawPool> jigsawPoolLoader;
private ResourceLoader<IrisJigsawStructure> jigsawStructureLoader; private ResourceLoader<IrisJigsawStructure> jigsawStructureLoader;
private ResourceLoader<IrisEntity> entityLoader; private ResourceLoader<IrisEntity> entityLoader;
private ResourceLoader<IrisMod> modLoader;
private ResourceLoader<IrisBlockData> blockLoader; private ResourceLoader<IrisBlockData> blockLoader;
private ObjectResourceLoader objectLoader; private ObjectResourceLoader objectLoader;
private boolean closed; private boolean closed;
@ -64,6 +65,7 @@ public class IrisDataManager {
this.entityLoader = null; this.entityLoader = null;
this.regionLoader = null; this.regionLoader = null;
this.biomeLoader = null; this.biomeLoader = null;
this.modLoader = null;
this.dimensionLoader = null; this.dimensionLoader = null;
this.jigsawPoolLoader = null; this.jigsawPoolLoader = null;
this.jigsawPieceLoader = null; this.jigsawPieceLoader = null;
@ -92,6 +94,7 @@ public class IrisDataManager {
this.entityLoader = new ResourceLoader<>(packs, this, "entities", "Entity", IrisEntity.class); this.entityLoader = new ResourceLoader<>(packs, this, "entities", "Entity", IrisEntity.class);
this.regionLoader = new ResourceLoader<>(packs, this, "regions", "Region", IrisRegion.class); this.regionLoader = new ResourceLoader<>(packs, this, "regions", "Region", IrisRegion.class);
this.biomeLoader = new ResourceLoader<>(packs, this, "biomes", "Biome", IrisBiome.class); this.biomeLoader = new ResourceLoader<>(packs, this, "biomes", "Biome", IrisBiome.class);
this.modLoader = new ResourceLoader<>(packs, this, "mods", "Mod", IrisMod.class);
this.dimensionLoader = new ResourceLoader<>(packs, this, "dimensions", "Dimension", IrisDimension.class); this.dimensionLoader = new ResourceLoader<>(packs, this, "dimensions", "Dimension", IrisDimension.class);
this.jigsawPoolLoader = new ResourceLoader<>(packs, this, "jigsaw-pools", "Jigsaw Pool", IrisJigsawPool.class); this.jigsawPoolLoader = new ResourceLoader<>(packs, this, "jigsaw-pools", "Jigsaw Pool", IrisJigsawPool.class);
this.jigsawStructureLoader = new ResourceLoader<>(packs, this, "jigsaw-structures", "Jigsaw Structure", IrisJigsawStructure.class); this.jigsawStructureLoader = new ResourceLoader<>(packs, this, "jigsaw-structures", "Jigsaw Structure", IrisJigsawStructure.class);
@ -111,6 +114,7 @@ public class IrisDataManager {
objectLoader.clearCache(); objectLoader.clearCache();
jigsawPieceLoader.clearCache(); jigsawPieceLoader.clearCache();
jigsawPoolLoader.clearCache(); jigsawPoolLoader.clearCache();
modLoader.clearCache();
jigsawStructureLoader.clearCache(); jigsawStructureLoader.clearCache();
regionLoader.clearCache(); regionLoader.clearCache();
dimensionLoader.clearCache(); dimensionLoader.clearCache();
@ -127,6 +131,7 @@ public class IrisDataManager {
blockLoader.clearList(); blockLoader.clearList();
entityLoader.clearList(); entityLoader.clearList();
biomeLoader.clearList(); biomeLoader.clearList();
modLoader.clearList();
regionLoader.clearList(); regionLoader.clearList();
dimensionLoader.clearList(); dimensionLoader.clearList();
generatorLoader.clearList(); generatorLoader.clearList();
@ -144,6 +149,10 @@ public class IrisDataManager {
return loadAny(key, (dm) -> dm.getBiomeLoader().load(key, false)); return loadAny(key, (dm) -> dm.getBiomeLoader().load(key, false));
} }
public static IrisMod loadAnyMod(String key) {
return loadAny(key, (dm) -> dm.getModLoader().load(key, false));
}
public static IrisJigsawPiece loadAnyJigsawPiece(String key) { public static IrisJigsawPiece loadAnyJigsawPiece(String key) {
return loadAny(key, (dm) -> dm.getJigsawPieceLoader().load(key, false)); return loadAny(key, (dm) -> dm.getJigsawPieceLoader().load(key, false));
} }

View File

@ -21,15 +21,19 @@ package com.volmit.iris.core;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.volmit.iris.Iris; import com.volmit.iris.Iris;
import com.volmit.iris.core.nms.INMS; import com.volmit.iris.core.nms.INMS;
import com.volmit.iris.core.pregenerator.PregenTask;
import com.volmit.iris.core.report.Report; import com.volmit.iris.core.report.Report;
import com.volmit.iris.core.report.ReportType; import com.volmit.iris.core.report.ReportType;
import com.volmit.iris.core.tools.IrisToolbelt;
import com.volmit.iris.core.tools.IrisWorldCreator; import com.volmit.iris.core.tools.IrisWorldCreator;
import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.framework.Engine;
import com.volmit.iris.engine.framework.IrisAccess; import com.volmit.iris.engine.framework.IrisAccess;
import com.volmit.iris.engine.object.*; import com.volmit.iris.engine.object.*;
import com.volmit.iris.engine.parallel.MultiBurst;
import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.collection.KMap; import com.volmit.iris.util.collection.KMap;
import com.volmit.iris.util.collection.KSet; 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.C;
import com.volmit.iris.util.format.Form; import com.volmit.iris.util.format.Form;
import com.volmit.iris.util.io.IO; import com.volmit.iris.util.io.IO;
@ -171,13 +175,13 @@ public class IrisProject {
return collectFiles(path, json); return collectFiles(path, json);
} }
public void open(VolmitSender sender) { public void open(VolmitSender sender) throws IrisException {
open(sender, () -> open(sender, () ->
{ {
}); });
} }
public void open(VolmitSender sender, Runnable onDone) { public void open(VolmitSender sender, Runnable onDone) throws IrisException {
if (isOpen()) { if (isOpen()) {
close(); close();
} }
@ -381,6 +385,7 @@ public class IrisProject {
schemas.put(getSchemaEntry(IrisDimension.class, dm, "/dimensions/*.json", "/dimensions/*/*.json", "/dimensions/*/*/*.json")); schemas.put(getSchemaEntry(IrisDimension.class, dm, "/dimensions/*.json", "/dimensions/*/*.json", "/dimensions/*/*/*.json"));
schemas.put(getSchemaEntry(IrisEntity.class, dm, "/entities/*.json", "/entities/*/*.json", "/entities/*/*/*.json")); schemas.put(getSchemaEntry(IrisEntity.class, dm, "/entities/*.json", "/entities/*/*.json", "/entities/*/*/*.json"));
schemas.put(getSchemaEntry(IrisBiome.class, dm, "/biomes/*.json", "/biomes/*/*.json", "/biomes/*/*/*.json")); schemas.put(getSchemaEntry(IrisBiome.class, dm, "/biomes/*.json", "/biomes/*/*.json", "/biomes/*/*/*.json"));
schemas.put(getSchemaEntry(IrisMod.class, dm, "/mods/*.json", "/mods/*/*.json", "/mods/*/*/*.json"));
schemas.put(getSchemaEntry(IrisRegion.class, dm, "/regions/*.json", "/regions/*/*.json", "/regions/*/*/*.json")); schemas.put(getSchemaEntry(IrisRegion.class, dm, "/regions/*.json", "/regions/*/*.json", "/regions/*/*/*.json"));
schemas.put(getSchemaEntry(IrisGenerator.class, dm, "/generators/*.json", "/generators/*/*.json", "/generators/*/*/*.json")); schemas.put(getSchemaEntry(IrisGenerator.class, dm, "/generators/*.json", "/generators/*/*.json", "/generators/*/*/*.json"));
schemas.put(getSchemaEntry(IrisJigsawPiece.class, dm, "/jigsaw-pieces/*.json", "/jigsaw-pieces/*/*.json", "/jigsaw-pieces/*/*/*.json")); schemas.put(getSchemaEntry(IrisJigsawPiece.class, dm, "/jigsaw-pieces/*.json", "/jigsaw-pieces/*/*.json", "/jigsaw-pieces/*/*/*.json"));
@ -422,7 +427,27 @@ public class IrisProject {
} }
//TODO: EXPORT JIGSAW PIECES FROM STRUCTURES //TODO: EXPORT JIGSAW PIECES FROM STRUCTURES
dimension.getFeatures().forEach((i) -> {
if (i.getZone().getCustomBiome() != null)
{
biomes.add(dm.getBiomeLoader().load(i.getZone().getCustomBiome()));
}
});
dimension.getSpecificFeatures().forEach((i) -> {
if (i.getFeature().getCustomBiome() != null)
{
biomes.add(dm.getBiomeLoader().load(i.getFeature().getCustomBiome()));
}
});
dimension.getRegions().forEach((i) -> regions.add(dm.getRegionLoader().load(i))); dimension.getRegions().forEach((i) -> regions.add(dm.getRegionLoader().load(i)));
regions.forEach((r) -> {
r.getFeatures().forEach((i) -> {
if (i.getZone().getCustomBiome() != null)
{
biomes.add(dm.getBiomeLoader().load(i.getZone().getCustomBiome()));
}
});
});
dimension.getLoot().getTables().forEach((i) -> loot.add(dm.getLootLoader().load(i))); dimension.getLoot().getTables().forEach((i) -> loot.add(dm.getLootLoader().load(i)));
regions.forEach((i) -> biomes.addAll(i.getAllBiomes(null))); regions.forEach((i) -> biomes.addAll(i.getAllBiomes(null)));
biomes.forEach((i) -> i.getGenerators().forEach((j) -> generators.add(j.getCachedGenerator(null)))); biomes.forEach((i) -> i.getGenerators().forEach((j) -> generators.add(j.getCachedGenerator(null))));
@ -432,6 +457,19 @@ public class IrisProject {
regions.forEach((r) -> r.getEntitySpawnOverrides().forEach((sp) -> entities.add(dm.getEntityLoader().load(sp.getEntity())))); regions.forEach((r) -> r.getEntitySpawnOverrides().forEach((sp) -> entities.add(dm.getEntityLoader().load(sp.getEntity()))));
dimension.getEntitySpawnOverrides().forEach((sp) -> entities.add(dm.getEntityLoader().load(sp.getEntity()))); dimension.getEntitySpawnOverrides().forEach((sp) -> entities.add(dm.getEntityLoader().load(sp.getEntity())));
biomes.forEach((r) -> r.getEntityInitialSpawns().forEach((sp) -> entities.add(dm.getEntityLoader().load(sp.getEntity())))); biomes.forEach((r) -> r.getEntityInitialSpawns().forEach((sp) -> entities.add(dm.getEntityLoader().load(sp.getEntity()))));
for(int f = 0; f < IrisSettings.get().getGenerator().getMaxBiomeChildDepth(); f++)
{
biomes.copy().forEach((r) -> {
r.getFeatures().forEach((i) -> {
if (i.getZone().getCustomBiome() != null)
{
biomes.add(dm.getBiomeLoader().load(i.getZone().getCustomBiome()));
}
});
});
}
regions.forEach((r) -> r.getEntityInitialSpawns().forEach((sp) -> entities.add(dm.getEntityLoader().load(sp.getEntity())))); regions.forEach((r) -> r.getEntityInitialSpawns().forEach((sp) -> entities.add(dm.getEntityLoader().load(sp.getEntity()))));
dimension.getEntityInitialSpawns().forEach((sp) -> entities.add(dm.getEntityLoader().load(sp.getEntity()))); dimension.getEntityInitialSpawns().forEach((sp) -> entities.add(dm.getEntityLoader().load(sp.getEntity())));
KMap<String, String> renameObjects = new KMap<>(); KMap<String, String> renameObjects = new KMap<>();

View File

@ -64,6 +64,17 @@ public class IrisSettings {
return Math.max(2, c < 0 ? Runtime.getRuntime().availableProcessors() / -c : c); return Math.max(2, c < 0 ? Runtime.getRuntime().availableProcessors() / -c : c);
} }
public void forceSave() {
File s = Iris.instance.getDataFile("settings.json");
try {
IO.writeAll(s, new JSONObject(new Gson().toJson(settings)).toString(4));
} catch (JSONException | IOException e) {
e.printStackTrace();
Iris.reportError(e);
}
}
@Data @Data
public static class IrisSettingsCache { public static class IrisSettingsCache {
public int complexCacheSize = 131072; public int complexCacheSize = 131072;
@ -108,7 +119,7 @@ public class IrisSettings {
public static class IrisSettingsGenerator { public static class IrisSettingsGenerator {
public String defaultWorldType = "overworld"; public String defaultWorldType = "overworld";
public boolean mcaPregenerator = false; public boolean disableMCA = false;
public boolean systemEffects = true; public boolean systemEffects = true;
public boolean systemEntitySpawnOverrides = true; public boolean systemEntitySpawnOverrides = true;
public boolean systemEntityInitialSpawns = true; public boolean systemEntityInitialSpawns = true;

View File

@ -24,6 +24,7 @@ import com.volmit.iris.Iris;
import com.volmit.iris.engine.cache.AtomicCache; import com.volmit.iris.engine.cache.AtomicCache;
import com.volmit.iris.engine.object.IrisDimension; import com.volmit.iris.engine.object.IrisDimension;
import com.volmit.iris.util.collection.KMap; import com.volmit.iris.util.collection.KMap;
import com.volmit.iris.util.exceptions.IrisException;
import com.volmit.iris.util.format.Form; import com.volmit.iris.util.format.Form;
import com.volmit.iris.util.io.IO; import com.volmit.iris.util.io.IO;
import com.volmit.iris.util.json.JSONException; import com.volmit.iris.util.json.JSONException;
@ -171,7 +172,7 @@ public class ProjectManager {
Iris.info("Assuming URL " + url); Iris.info("Assuming URL " + url);
String branch = "master"; String branch = "master";
String[] nodes = url.split("\\Q/\\E"); String[] nodes = url.split("\\Q/\\E");
String repo = nodes[0] + "/" + nodes[1]; String repo = nodes.length == 1 ? "IrisDimensions/" + nodes[0] : nodes[0] + "/" + nodes[1];
branch = nodes.length > 2 ? nodes[2] : branch; branch = nodes.length > 2 ? nodes[2] : branch;
download(sender, repo, branch, trim, forceOverwrite); download(sender, repo, branch, trim, forceOverwrite);
} catch (Throwable e) { } catch (Throwable e) {
@ -192,6 +193,13 @@ public class ProjectManager {
File temp = Iris.getTemp(); File temp = Iris.getTemp();
File work = new File(temp, "dl-" + UUID.randomUUID()); File work = new File(temp, "dl-" + UUID.randomUUID());
File packs = getWorkspaceFolder(); File packs = getWorkspaceFolder();
if (zip == null || !zip.exists()) {
sender.sendMessage("Failed to find pack at " + url);
sender.sendMessage("Make sure you specified the correct repo and branch!");
sender.sendMessage("For example: /iris download IrisDimensions/overworld branch=master");
return;
}
sender.sendMessage("Unpacking " + repo); sender.sendMessage("Unpacking " + repo);
try { try {
ZipUtil.unpack(zip, work); ZipUtil.unpack(zip, work);
@ -326,7 +334,7 @@ public class ProjectManager {
} }
} }
public void open(VolmitSender sender, String dimm, Runnable onDone) { public void open(VolmitSender sender, String dimm, Runnable onDone) throws IrisException {
if (isProjectOpen()) { if (isProjectOpen()) {
close(); close();
} }

View File

@ -36,6 +36,9 @@ public class CommandIris extends MortarCommand {
@Command @Command
private CommandIrisVerify verify; private CommandIrisVerify verify;
@Command
private CommandIrisDebug debug;
@Command @Command
private CommandIrisFix fix; private CommandIrisFix fix;
@ -48,9 +51,6 @@ public class CommandIris extends MortarCommand {
@Command @Command
private CommandIrisObject object; private CommandIrisObject object;
@Command
private CommandIrisRegen regen;
@Command @Command
private CommandIrisDownload download; private CommandIrisDownload download;
@ -60,6 +60,9 @@ public class CommandIris extends MortarCommand {
@Command @Command
private CommandIrisUpdateWorld updateWorld; private CommandIrisUpdateWorld updateWorld;
@Command
private CommandIrisBitwise bitwise;
@Command @Command
private CommandIrisWhat what; private CommandIrisWhat what;

View File

@ -0,0 +1,124 @@
/*
* 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.util.collection.KList;
import com.volmit.iris.util.format.C;
import com.volmit.iris.util.plugin.MortarCommand;
import com.volmit.iris.util.plugin.VolmitSender;
import com.volmit.iris.util.scheduling.J;
import java.util.Arrays;
public class CommandIrisBitwise extends MortarCommand {
public CommandIrisBitwise() {
super("bitwise", "bits", "bw");
requiresPermission(Iris.perm.studio);
setDescription("Run bitwise calculations");
setCategory("Studio");
}
@Override
public void addTabOptions(VolmitSender sender, String[] args, KList<String> list) {
}
@Override
public boolean handle(VolmitSender sender, String[] args) {
if(args.length != 3)
{
sender.sendMessage("/iris bw " + getArgsUsage());
}
try
{
if(args[0].contains(","))
{
KList<Integer> r = new KList<>();
for(String i : args[0].split("\\Q,\\E"))
{
int a = Integer.parseInt(i);
String op = args[1];
int b = Integer.parseInt(args[2]);
int v = 0;
switch (op) {
case "|" -> v = a | b;
case "&" -> v = a & b;
case "^" -> v = a ^ b;
case "%" -> v = a % b;
case ">>" -> v = a >> b;
case "<<" -> v = a << b;
default -> {
{
sender.sendMessage("Error Invalid operation");
return true;
}
}
}
;
r.add(v);
sender.sendMessage("Result: " + r.toString(","));
}
}
else
{
int a = Integer.parseInt(args[0]);
String op = args[1];
int b = Integer.parseInt(args[2]);
int v = 0;
switch (op) {
case "|" -> v = a | b;
case "&" -> v = a & b;
case "^" -> v = a ^ b;
case "%" -> v = a % b;
case ">>" -> v = a >> b;
case "<<" -> v = a << b;
default -> {
{
sender.sendMessage("Error Invalid operation");
return true;
}
}
}
;
sender.sendMessage("Result: " + v);
}
}
catch(Throwable ignored)
{
}
return true;
}
@Override
protected String getArgsUsage() {
return "<number> [|,&,^,>>,<<,%] <other>";
}
}

View File

@ -0,0 +1,54 @@
/*
* 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.IrisSettings;
import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.plugin.MortarCommand;
import com.volmit.iris.util.plugin.VolmitSender;
public class CommandIrisDebug extends MortarCommand {
public CommandIrisDebug() {
super("debug", "dbg");
requiresPermission(Iris.perm.studio);
setDescription("Toggle debug mode");
setCategory("Studio");
}
@Override
public void addTabOptions(VolmitSender sender, String[] args, KList<String> list) {
}
@Override
public boolean handle(VolmitSender sender, String[] args) {
IrisSettings.get().getGeneral().setDebug(!IrisSettings.get().getGeneral().isDebug());
IrisSettings.get().forceSave();
sender.sendMessage("Debug Mode: " + (IrisSettings.get().getGeneral().isDebug() ? "Enabled" : "Disabled"));
return true;
}
@Override
protected String getArgsUsage() {
return "<number> [|,&,^,>>,<<,%] <other>";
}
}

View File

@ -25,6 +25,8 @@ import com.volmit.iris.util.plugin.MortarCommand;
import com.volmit.iris.util.plugin.VolmitSender; import com.volmit.iris.util.plugin.VolmitSender;
import com.volmit.iris.util.scheduling.J; import com.volmit.iris.util.scheduling.J;
import java.util.Arrays;
public class CommandIrisDownload extends MortarCommand { public class CommandIrisDownload extends MortarCommand {
public CommandIrisDownload() { public CommandIrisDownload() {
super("download", "down", "dl"); super("download", "down", "dl");
@ -42,28 +44,44 @@ public class CommandIrisDownload extends MortarCommand {
@Override @Override
public boolean handle(VolmitSender sender, String[] args) { public boolean handle(VolmitSender sender, String[] args) {
if (args.length < 1) { if (args.length < 1) {
sender.sendMessage("/iris dl " + C.BOLD + "<NAME>"); sender.sendMessage("/iris dl " + C.BOLD + "<NAME> [BRANCH=master]");
return true; return true;
} }
boolean trim = false; boolean trim = false;
String branch = "master";
for (String i : args) { for (String i : Arrays.copyOfRange(args, 1, args.length)) {
if (i.equals("-t") || i.equals("--trim")) { if (i.equals("-t") || i.equals("--trim")) {
trim = true; trim = true;
break; break;
} else if (i.startsWith("-")) {
sender.sendMessage("Invalid parameter.");
sender.sendMessage("/iris dl " + C.BOLD + "<NAME> [BRANCH=master]");
return true;
} else {
branch = i;
if (branch.toLowerCase().startsWith("branch=")) branch = branch.substring(7);
} }
} }
boolean btrim = trim; boolean btrim = trim;
J.a(() -> Iris.proj.downloadSearch(sender, args[0], btrim)); String pack = args[0];
if (!pack.contains("/")) {
pack = "IrisDimensions/" + pack;
}
final String finalPack = pack + "/" + branch;
J.a(() -> Iris.proj.downloadSearch(sender, finalPack, btrim));
return true; return true;
} }
@Override @Override
protected String getArgsUsage() { protected String getArgsUsage() {
return "<name> [-t/--trim]"; return "<name> [branch=master] [-t/--trim]";
} }
} }

View File

@ -21,6 +21,7 @@ package com.volmit.iris.core.command.jigsaw;
import com.volmit.iris.Iris; import com.volmit.iris.Iris;
import com.volmit.iris.core.IrisDataManager; import com.volmit.iris.core.IrisDataManager;
import com.volmit.iris.core.IrisSettings; import com.volmit.iris.core.IrisSettings;
import com.volmit.iris.core.tools.IrisWorlds;
import com.volmit.iris.engine.jigsaw.PlannedStructure; import com.volmit.iris.engine.jigsaw.PlannedStructure;
import com.volmit.iris.engine.object.IrisJigsawStructure; import com.volmit.iris.engine.object.IrisJigsawStructure;
import com.volmit.iris.engine.object.IrisPosition; import com.volmit.iris.engine.object.IrisPosition;
@ -41,7 +42,16 @@ public class CommandIrisJigsawPlace extends MortarCommand {
@Override @Override
public void addTabOptions(VolmitSender sender, String[] args, KList<String> list) { public void addTabOptions(VolmitSender sender, String[] args, KList<String> list) {
if ((args.length == 0 || args.length == 1) && sender.isPlayer() && IrisWorlds.isIrisWorld(sender.player().getWorld())) {
IrisDataManager data = IrisWorlds.access(sender.player().getWorld()).getData();
if (data == null) {
sender.sendMessage("Tab complete options only work for jigsaw structures while in an Iris world.");
} else if(args.length == 0) {
list.add(data.getJigsawStructureLoader().getPossibleKeys());
}else if(args.length == 1) {
list.add(data.getJigsawStructureLoader().getPossibleKeys(args[0]));
}
}
} }
@Override @Override

View File

@ -23,6 +23,7 @@ import com.volmit.iris.core.IrisDataManager;
import com.volmit.iris.core.IrisSettings; import com.volmit.iris.core.IrisSettings;
import com.volmit.iris.core.ProjectManager; import com.volmit.iris.core.ProjectManager;
import com.volmit.iris.core.WandManager; import com.volmit.iris.core.WandManager;
import com.volmit.iris.core.tools.IrisWorlds;
import com.volmit.iris.engine.object.IrisObject; import com.volmit.iris.engine.object.IrisObject;
import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.plugin.MortarCommand; import com.volmit.iris.util.plugin.MortarCommand;
@ -44,7 +45,16 @@ public class CommandIrisObjectPaste extends MortarCommand {
@Override @Override
public void addTabOptions(VolmitSender sender, String[] args, KList<String> list) { public void addTabOptions(VolmitSender sender, String[] args, KList<String> list) {
if ((args.length == 0 || args.length == 1) && sender.isPlayer() && IrisWorlds.isIrisWorld(sender.player().getWorld())) {
IrisDataManager data = IrisWorlds.access(sender.player().getWorld()).getData();
if (data == null) {
sender.sendMessage("Tab complete options only work for objects while in an Iris world.");
} else if(args.length == 0) {
list.add(data.getObjectLoader().getPossibleKeys());
}else if(args.length == 1) {
list.add(data.getObjectLoader().getPossibleKeys(args[0]));
}
}
} }
@Override @Override

View File

@ -19,8 +19,10 @@
package com.volmit.iris.core.command.studio; package com.volmit.iris.core.command.studio;
import com.volmit.iris.Iris; import com.volmit.iris.Iris;
import com.volmit.iris.core.IrisDataManager;
import com.volmit.iris.core.IrisSettings; import com.volmit.iris.core.IrisSettings;
import com.volmit.iris.core.gui.NoiseExplorerGUI; import com.volmit.iris.core.gui.NoiseExplorerGUI;
import com.volmit.iris.core.tools.IrisWorlds;
import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.plugin.Command; import com.volmit.iris.util.plugin.Command;
import com.volmit.iris.util.plugin.MortarCommand; import com.volmit.iris.util.plugin.MortarCommand;

View File

@ -22,6 +22,7 @@ import com.volmit.iris.Iris;
import com.volmit.iris.core.IrisDataManager; import com.volmit.iris.core.IrisDataManager;
import com.volmit.iris.core.IrisSettings; import com.volmit.iris.core.IrisSettings;
import com.volmit.iris.core.gui.NoiseExplorerGUI; import com.volmit.iris.core.gui.NoiseExplorerGUI;
import com.volmit.iris.core.tools.IrisWorlds;
import com.volmit.iris.engine.object.IrisGenerator; import com.volmit.iris.engine.object.IrisGenerator;
import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.math.RNG; import com.volmit.iris.util.math.RNG;
@ -38,7 +39,16 @@ public class CommandIrisStudioExplorerGenerator extends MortarCommand {
@Override @Override
public void addTabOptions(VolmitSender sender, String[] args, KList<String> list) { public void addTabOptions(VolmitSender sender, String[] args, KList<String> list) {
if ((args.length == 0 || args.length == 1) && sender.isPlayer() && IrisWorlds.isIrisWorld(sender.player().getWorld())) {
IrisDataManager data = IrisWorlds.access(sender.player().getWorld()).getData();
if (data == null) {
sender.sendMessage("Issue when loading tab completions. No data found (?)");
} else if(args.length == 0) {
list.add(data.getGeneratorLoader().getPossibleKeys());
}else if(args.length == 1) {
list.add(data.getGeneratorLoader().getPossibleKeys(args[0]));
}
}
} }
@Override @Override

View File

@ -40,8 +40,6 @@ import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
public class CommandIrisStudioGoto extends MortarCommand { public class CommandIrisStudioGoto extends MortarCommand {
private static final AtomicBoolean looking = new AtomicBoolean(false);
public CommandIrisStudioGoto() { public CommandIrisStudioGoto() {
super("goto", "find", "g"); super("goto", "find", "g");
setDescription("Find any region or biome"); setDescription("Find any region or biome");
@ -51,14 +49,16 @@ public class CommandIrisStudioGoto extends MortarCommand {
@Override @Override
public void addTabOptions(VolmitSender sender, String[] args, KList<String> list) { public void addTabOptions(VolmitSender sender, String[] args, KList<String> list) {
if (args.length == 0 && sender.isPlayer() && IrisWorlds.isIrisWorld(sender.player().getWorld())) { if ((args.length == 0 || args.length == 1) && sender.isPlayer() && IrisWorlds.isIrisWorld(sender.player().getWorld())) {
IrisDataManager data = IrisWorlds.access(sender.player().getWorld()).getData(); IrisDataManager data = IrisWorlds.access(sender.player().getWorld()).getData();
if (data == null) { if (data == null) {
sender.sendMessage("Issue when loading tab completions. No data found (?)"); sender.sendMessage("Issue when loading tab completions. No data found (?)");
} else { } else if(args.length == 0) {
list.add(data.getBiomeLoader().getPossibleKeys()); list.add(data.getBiomeLoader().getPossibleKeys());
list.add(data.getRegionLoader().getPossibleKeys()); list.add(data.getRegionLoader().getPossibleKeys());
//TODO: Remove comment here -> list.add(data.getObjectLoader().getPossibleKeys()); }else if(args.length == 1) {
list.add(data.getBiomeLoader().getPossibleKeys(args[0]));
list.add(data.getRegionLoader().getPossibleKeys(args[0]));
} }
} }
} }
@ -72,10 +72,6 @@ public class CommandIrisStudioGoto extends MortarCommand {
} }
if (sender.isPlayer()) { if (sender.isPlayer()) {
if (looking.get()) {
sender.sendMessage("A Search is already running, please wait!");
}
Player p = sender.player(); Player p = sender.player();
World world = p.getWorld(); World world = p.getWorld();
@ -88,12 +84,10 @@ public class CommandIrisStudioGoto extends MortarCommand {
IrisBiome b = IrisDataManager.loadAnyBiome(args[0]); IrisBiome b = IrisDataManager.loadAnyBiome(args[0]);
IrisRegion r = IrisDataManager.loadAnyRegion(args[0]); IrisRegion r = IrisDataManager.loadAnyRegion(args[0]);
looking.set(true);
if (b != null) { if (b != null) {
J.a(() -> { J.a(() -> {
Location l = g.lookForBiome(b, 10000, (v) -> sender.sendMessage("Looking for " + C.BOLD + C.WHITE + b.getName() + C.RESET + C.GRAY + ": Checked " + Form.f(v) + " Places")); Location l = g.lookForBiome(b, 10000, (v) -> sender.sendMessage("Looking for " + C.BOLD + C.WHITE + b.getName() + C.RESET + C.GRAY + ": Checked " + Form.f(v) + " Places"));
looking.set(false);
if (l == null) { if (l == null) {
sender.sendMessage("Couldn't find " + b.getName() + "."); sender.sendMessage("Couldn't find " + b.getName() + ".");
} else { } else {
@ -105,7 +99,6 @@ public class CommandIrisStudioGoto extends MortarCommand {
J.a(() -> { J.a(() -> {
Location l = g.lookForRegion(r, 60000, (v) -> sender.sendMessage(C.BOLD + "" + C.WHITE + r.getName() + C.RESET + C.GRAY + ": Checked " + Form.f(v) + " Places")); Location l = g.lookForRegion(r, 60000, (v) -> sender.sendMessage(C.BOLD + "" + C.WHITE + r.getName() + C.RESET + C.GRAY + ": Checked " + Form.f(v) + " Places"));
looking.set(false);
if (l == null) { if (l == null) {
sender.sendMessage("Couldn't find " + r.getName() + "."); sender.sendMessage("Couldn't find " + r.getName() + ".");
} else { } else {

View File

@ -27,13 +27,8 @@ import com.volmit.iris.engine.framework.IrisAccess;
import com.volmit.iris.engine.parallel.BurstExecutor; import com.volmit.iris.engine.parallel.BurstExecutor;
import com.volmit.iris.engine.parallel.MultiBurst; import com.volmit.iris.engine.parallel.MultiBurst;
import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.collection.KSet;
import com.volmit.iris.util.format.Form;
import com.volmit.iris.util.math.Position2;
import com.volmit.iris.util.math.Spiraler;
import com.volmit.iris.util.plugin.MortarCommand; import com.volmit.iris.util.plugin.MortarCommand;
import com.volmit.iris.util.plugin.VolmitSender; import com.volmit.iris.util.plugin.VolmitSender;
import com.volmit.iris.util.scheduling.J;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
@ -78,6 +73,11 @@ public class CommandIrisVerify extends MortarCommand {
{ {
sender.sendMessage("Found Missing Chunk " + i.getName() + ", chunk #" + j + "," + k + " (see " + (((rx << 5)<<4)+(j<<4)) + "," + (((rz << 5)<<4)+(k<<4))); sender.sendMessage("Found Missing Chunk " + i.getName() + ", chunk #" + j + "," + k + " (see " + (((rx << 5)<<4)+(j<<4)) + "," + (((rz << 5)<<4)+(k<<4)));
} }
else if(c.sectionCount() == 0)
{
sender.sendMessage("Found Missing Chunk (valid, but 0 sections) " + i.getName() + ", chunk #" + j + "," + k + " (see " + (((rx << 5)<<4)+(j<<4)) + "," + (((rz << 5)<<4)+(k<<4)));
}
} }
} }
} catch (IOException ioException) { } catch (IOException ioException) {

View File

@ -19,8 +19,12 @@
package com.volmit.iris.core.gui; package com.volmit.iris.core.gui;
import com.volmit.iris.Iris; import com.volmit.iris.Iris;
import com.volmit.iris.engine.hunk.Hunk;
import com.volmit.iris.engine.hunk.storage.ArrayHunk;
import com.volmit.iris.engine.noise.CNG; import com.volmit.iris.engine.noise.CNG;
import com.volmit.iris.engine.object.NoiseStyle; import com.volmit.iris.engine.object.NoiseStyle;
import com.volmit.iris.engine.parallel.BurstExecutor;
import com.volmit.iris.engine.parallel.MultiBurst;
import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.function.Function2; import com.volmit.iris.util.function.Function2;
import com.volmit.iris.util.math.M; import com.volmit.iris.util.math.M;
@ -34,6 +38,7 @@ import javax.imageio.ImageIO;
import javax.swing.*; import javax.swing.*;
import java.awt.*; import java.awt.*;
import java.awt.event.*; import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.locks.ReentrantLock;
@ -44,7 +49,7 @@ public class NoiseExplorerGUI extends JPanel implements MouseWheelListener {
static JComboBox<String> combo; static JComboBox<String> combo;
@SuppressWarnings("CanBeFinal") @SuppressWarnings("CanBeFinal")
RollingSequence r = new RollingSequence(90); RollingSequence r = new RollingSequence(290);
@SuppressWarnings("CanBeFinal") @SuppressWarnings("CanBeFinal")
boolean colorMode = true; boolean colorMode = true;
double scale = 1; double scale = 1;
@ -53,9 +58,9 @@ public class NoiseExplorerGUI extends JPanel implements MouseWheelListener {
static double ascale = 10; static double ascale = 10;
CNG cng = NoiseStyle.STATIC.create(new RNG(RNG.r.nextLong())); CNG cng = NoiseStyle.STATIC.create(new RNG(RNG.r.nextLong()));
@SuppressWarnings("CanBeFinal") @SuppressWarnings("CanBeFinal")
GroupedExecutor gx = new GroupedExecutor(Runtime.getRuntime().availableProcessors(), Thread.MAX_PRIORITY, "Iris Renderer"); MultiBurst gx = new MultiBurst("Iris Noise Renderer", Thread.MAX_PRIORITY, Runtime.getRuntime().availableProcessors());
ReentrantLock l = new ReentrantLock(); ReentrantLock l = new ReentrantLock();
int[][] co; BufferedImage img;
int w = 0; int w = 0;
int h = 0; int h = 0;
Function2<Double, Double, Double> generator; Function2<Double, Double, Double> generator;
@ -161,7 +166,7 @@ public class NoiseExplorerGUI extends JPanel implements MouseWheelListener {
} }
PrecisionStopwatch p = PrecisionStopwatch.start(); PrecisionStopwatch p = PrecisionStopwatch.start();
int accuracy = hd ? 1 : M.clip((r.getAverage() / 6D), 1D, 128D).intValue(); int accuracy = hd ? 1 : M.clip((r.getAverage() / 12D), 2D, 128D).intValue();
accuracy = down ? accuracy * 4 : accuracy; accuracy = down ? accuracy * 4 : accuracy;
int v = 1000; int v = 1000;
@ -170,45 +175,41 @@ public class NoiseExplorerGUI extends JPanel implements MouseWheelListener {
if (getParent().getWidth() != w || getParent().getHeight() != h) { if (getParent().getWidth() != w || getParent().getHeight() != h) {
w = getParent().getWidth(); w = getParent().getWidth();
h = getParent().getHeight(); h = getParent().getHeight();
co = null; img = null;
} }
if (co == null) { if (img == null) {
co = new int[w][h]; img = new BufferedImage(w/accuracy, h/accuracy, BufferedImage.TYPE_INT_RGB);
} }
for (int x = 0; x < w; x += accuracy) { BurstExecutor e = gx.burst(w);
for (int x = 0; x < w/accuracy; x ++) {
int xx = x; int xx = x;
for (int z = 0; z < h; z += accuracy) { int finalAccuracy = accuracy;
int zz = z; e.queue(() -> {
gx.queue("a", () -> for (int z = 0; z < h/finalAccuracy; z++) {
{ double n = generator != null ? generator.apply(((xx*finalAccuracy) * ascale) + oxp, ((z*finalAccuracy) * ascale) + ozp) : cng.noise(((xx*finalAccuracy) * ascale) + oxp, tz, ((z*finalAccuracy) * ascale) + ozp);
double n = generator != null ? generator.apply((xx * ascale) + oxp, (zz * ascale) + ozp) : cng.noise((xx * ascale) + oxp, tz, (zz * ascale) + ozp); n = n > 1 ? 1 : n < 0 ? 0 : n;
if (n > 1 || n < 0) { try
return; {
Color color = colorMode ? Color.getHSBColor((float) (n), 1f - (float) (n * n * n * n * n * n), 1f - (float) n) : Color.getHSBColor(0f, 0f, (float) n);
int rgb = color.getRGB();
img.setRGB(xx, z, rgb);
} }
Color color = colorMode ? Color.getHSBColor((float) (n), 1f - (float) (n * n * n * n * n * n), 1f - (float) n) : Color.getHSBColor(0f, 0f, (float) n); catch(Throwable xxx)
int rgb = color.getRGB(); {
co[xx][zz] = rgb;
});
}
gx.waitFor("a"); }
}
if (hd && p.getMilliseconds() > v) { });
break;
}
} }
for (int x = 0; x < getParent().getWidth(); x += accuracy) { e.complete();
for (int z = 0; z < getParent().getHeight(); z += accuracy) { gg.drawImage(img, 0, 0, getParent().getWidth()*accuracy, getParent().getHeight()*accuracy, (img, infoflags, x, y, width, height) -> true);
gg.setColor(new Color(co[x][z]));
gg.fillRect(x, z, accuracy, accuracy);
}
}
} }
p.end(); p.end();

View File

@ -20,6 +20,9 @@ package com.volmit.iris.core.nms;
import com.volmit.iris.Iris; import com.volmit.iris.Iris;
import com.volmit.iris.core.IrisSettings; import com.volmit.iris.core.IrisSettings;
import com.volmit.iris.core.nms.v16_1.NMSBinding16_1;
import com.volmit.iris.core.nms.v16_2.NMSBinding16_2;
import com.volmit.iris.core.nms.v16_3.NMSBinding16_3;
import com.volmit.iris.core.nms.v17_1.NMSBinding17_1; import com.volmit.iris.core.nms.v17_1.NMSBinding17_1;
import com.volmit.iris.core.nms.v1X.NMSBinding1X; import com.volmit.iris.core.nms.v1X.NMSBinding1X;
import com.volmit.iris.util.collection.KMap; import com.volmit.iris.util.collection.KMap;
@ -28,7 +31,11 @@ import org.bukkit.Bukkit;
public class INMS { public class INMS {
//@builder //@builder
private static final KMap<String, Class<? extends INMSBinding>> bindings = new KMap<String, Class<? extends INMSBinding>>() private static final KMap<String, Class<? extends INMSBinding>> bindings = new KMap<String, Class<? extends INMSBinding>>()
.qput("v1_17_R1", NMSBinding17_1.class); .qput("v1_17_R1", NMSBinding17_1.class)
.qput("v1_16_R3", NMSBinding16_3 .class)
.qput("v1_16_R2", NMSBinding16_2.class)
.qput("v1_16_R1", NMSBinding16_1.class)
;
//@done //@done
private static final INMSBinding binding = bind(); private static final INMSBinding binding = bind();

View File

@ -25,8 +25,14 @@ import org.bukkit.block.Biome;
import org.bukkit.generator.ChunkGenerator; import org.bukkit.generator.ChunkGenerator;
public interface INMSBinding { public interface INMSBinding {
boolean supportsCustomHeight();
Object getBiomeBaseFromId(int id); Object getBiomeBaseFromId(int id);
int getMinHeight(World world);
boolean supportsCustomBiomes();
int getTrueBiomeBaseId(Object biomeBase); int getTrueBiomeBaseId(Object biomeBase);
Object getTrueBiomeBase(Location location); Object getTrueBiomeBase(Location location);

View File

@ -0,0 +1,161 @@
/*
* 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.nms.v16_1;
import com.volmit.iris.Iris;
import com.volmit.iris.core.nms.INMSBinding;
import com.volmit.iris.util.collection.KMap;
import net.minecraft.server.v1_16_R1.*;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.block.Biome;
import org.bukkit.craftbukkit.v1_16_R1.CraftWorld;
import org.bukkit.generator.ChunkGenerator;
import java.lang.reflect.Field;
public class NMSBinding16_1 implements INMSBinding {
private final KMap<Biome, Object> baseBiomeCache = new KMap<>();
private Field biomeStorageCache = null;
public boolean supportsDataPacks() {
return true;
}
private Field getFieldForBiomeStorage(Object storage) {
Field f = biomeStorageCache;
if (f != null) {
return f;
}
try {
f = storage.getClass().getDeclaredField("biome");
f.setAccessible(true);
return f;
} catch (Throwable e) {
Iris.reportError(e);
e.printStackTrace();
Iris.error(storage.getClass().getCanonicalName());
}
biomeStorageCache = f;
return null;
}
private IRegistryWritable<BiomeBase> getCustomBiomeRegistry() {
return null;
}
@Override
public Object getBiomeBaseFromId(int id) {
return null;
}
@Override
public int getMinHeight(World world) {
return 0;
}
@Override
public boolean supportsCustomHeight() {
return false;
}
@Override
public boolean supportsCustomBiomes() {
return false;
}
@Override
public int getTrueBiomeBaseId(Object biomeBase) {
return -1;
}
@Override
public Object getTrueBiomeBase(Location location) {
return ((CraftWorld) location.getWorld()).getHandle().getBiome(location.getBlockX(), location.getBlockY(), location.getBlockZ());
}
@Override
public String getTrueBiomeBaseKey(Location location) {
return getKeyForBiomeBase(getTrueBiomeBase(location));
}
@Override
public Object getCustomBiomeBaseFor(String mckey) {
try {
return null;
} catch (Throwable e) {
Iris.reportError(e);
}
return null;
}
@SuppressWarnings("OptionalGetWithoutIsPresent")
@Override
public String getKeyForBiomeBase(Object biomeBase) {
return getCustomBiomeRegistry().c((BiomeBase) biomeBase).get().a().toString();
}
@Override
public Object getBiomeBase(World world, Biome biome) {
return null; // Can't find IRegistryCustom in 16_R1
}
@Override
public Object getBiomeBase(Object registry, Biome biome) {
Object v = baseBiomeCache.get(biome);
if (v != null) {
return v;
}
//noinspection unchecked
v = org.bukkit.craftbukkit.v1_16_R1.block.CraftBlock.biomeToBiomeBase(biome);
if (v == null) {
// Ok so there is this new biome name called "CUSTOM" in Paper's new releases.
// But, this does NOT exist within CraftBukkit which makes it return an error.
// So, we will just return the ID that the plains biome returns instead.
return org.bukkit.craftbukkit.v1_16_R1.block.CraftBlock.biomeToBiomeBase(Biome.PLAINS);
}
baseBiomeCache.put(biome, v);
return v;
}
@Override
public int getBiomeId(Biome biome) {
return -1;
}
@Override
public int countCustomBiomes() {
return 0;
}
@Override
public void forceBiomeInto(int x, int y, int z, Object somethingVeryDirty, ChunkGenerator.BiomeGrid chunk) {
}
@Override
public boolean isBukkit() {
return false;
}
}

View File

@ -0,0 +1,267 @@
/*
* 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.nms.v16_2;
import com.volmit.iris.Iris;
import com.volmit.iris.core.nms.INMSBinding;
import com.volmit.iris.util.collection.KMap;
import net.minecraft.server.v1_16_R2.*;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.block.Biome;
import org.bukkit.craftbukkit.v1_16_R2.CraftServer;
import org.bukkit.craftbukkit.v1_16_R2.CraftWorld;
import org.bukkit.generator.ChunkGenerator;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.concurrent.atomic.AtomicInteger;
public class NMSBinding16_2 implements INMSBinding {
private final KMap<Biome, Object> baseBiomeCache = new KMap<>();
private Field biomeStorageCache = null;
public boolean supportsDataPacks() {
return true;
}
private Object getBiomeStorage(ChunkGenerator.BiomeGrid g) {
try {
return getFieldForBiomeStorage(g).get(g);
} catch (IllegalAccessException e) {
Iris.reportError(e);
e.printStackTrace();
}
return null;
}
private Field getFieldForBiomeStorage(Object storage) {
Field f = biomeStorageCache;
if (f != null) {
return f;
}
try {
f = storage.getClass().getDeclaredField("biome");
f.setAccessible(true);
return f;
} catch (Throwable e) {
Iris.reportError(e);
e.printStackTrace();
Iris.error(storage.getClass().getCanonicalName());
}
biomeStorageCache = f;
return null;
}
private IRegistryWritable<BiomeBase> getCustomBiomeRegistry() {
return ((CraftServer) Bukkit.getServer()).getHandle().getServer().getCustomRegistry().b(IRegistry.ay);
}
@Override
public Object getBiomeBaseFromId(int id) {
return getCustomBiomeRegistry().fromId(id);
}
@Override
public int getTrueBiomeBaseId(Object biomeBase) {
return getCustomBiomeRegistry().a((BiomeBase) biomeBase);
}
@Override
public Object getTrueBiomeBase(Location location) {
return ((CraftWorld) location.getWorld()).getHandle().getBiome(location.getBlockX(), location.getBlockY(), location.getBlockZ());
}
@Override
public String getTrueBiomeBaseKey(Location location) {
return getKeyForBiomeBase(getTrueBiomeBase(location));
}
@Override
public Object getCustomBiomeBaseFor(String mckey) {
try {
return getCustomBiomeRegistry().d(ResourceKey.a(IRegistry.ay, new MinecraftKey(mckey)));
} catch (Throwable e) {
Iris.reportError(e);
}
return null;
}
@SuppressWarnings("OptionalGetWithoutIsPresent")
@Override
public String getKeyForBiomeBase(Object biomeBase) {
return getCustomBiomeRegistry().c((BiomeBase) biomeBase).get().a().toString();
}
@Override
public Object getBiomeBase(World world, Biome biome) {
return getBiomeBase(((CraftWorld) world).getHandle().r().b(IRegistry.ay), biome);
}
@Override
public boolean supportsCustomBiomes() {
return false;
}
@Override
public int getMinHeight(World world) {
return 0;
}
@Override
public boolean supportsCustomHeight() {
return false;
}
private Class<?>[] classify(Object... par) {
Class<?>[] g = new Class<?>[par.length];
for (int i = 0; i < g.length; i++) {
g[i] = par[i].getClass();
}
return g;
}
private <T> T invoke(Object from, String name, Object... par) {
try {
Method f = from.getClass().getDeclaredMethod(name, classify(par));
f.setAccessible(true);
//noinspection unchecked
return (T) f.invoke(from, par);
} catch (Throwable e) {
Iris.reportError(e);
e.printStackTrace();
}
return null;
}
private <T> T invokeStatic(Class<?> from, String name, Object... par) {
try {
Method f = from.getDeclaredMethod(name, classify(par));
f.setAccessible(true);
//noinspection unchecked
return (T) f.invoke(null, par);
} catch (Throwable e) {
Iris.reportError(e);
e.printStackTrace();
}
return null;
}
private <T> T getField(Object from, String name) {
try {
Field f = from.getClass().getDeclaredField(name);
f.setAccessible(true);
//noinspection unchecked
return (T) f.get(from);
} catch (Throwable e) {
Iris.reportError(e);
e.printStackTrace();
}
return null;
}
private <T> T getStaticField(Class<?> t, String name) {
try {
Field f = t.getDeclaredField(name);
f.setAccessible(true);
//noinspection unchecked
return (T) f.get(null);
} catch (Throwable e) {
Iris.reportError(e);
e.printStackTrace();
}
return null;
}
@Override
public Object getBiomeBase(Object registry, Biome biome) {
Object v = baseBiomeCache.get(biome);
if (v != null) {
return v;
}
//noinspection unchecked
v = org.bukkit.craftbukkit.v1_16_R2.block.CraftBlock.biomeToBiomeBase((IRegistry<BiomeBase>) registry, biome);
if (v == null) {
// Ok so there is this new biome name called "CUSTOM" in Paper's new releases.
// But, this does NOT exist within CraftBukkit which makes it return an error.
// So, we will just return the ID that the plains biome returns instead.
//noinspection unchecked
return org.bukkit.craftbukkit.v1_16_R2.block.CraftBlock.biomeToBiomeBase((IRegistry<BiomeBase>) registry, Biome.PLAINS);
}
baseBiomeCache.put(biome, v);
return v;
}
@Override
public int getBiomeId(Biome biome) {
for (World i : Bukkit.getWorlds()) {
if (i.getEnvironment().equals(World.Environment.NORMAL)) {
IRegistry<BiomeBase> registry = ((CraftWorld) i).getHandle().r().b(IRegistry.ay);
return registry.a((BiomeBase) getBiomeBase(registry, biome));
}
}
return biome.ordinal();
}
@Override
public int countCustomBiomes() {
AtomicInteger a = new AtomicInteger(0);
getCustomBiomeRegistry().d().forEach((i) -> {
MinecraftKey k = i.getKey().a();
if (k.getNamespace().equals("minecraft")) {
return;
}
a.incrementAndGet();
Iris.debug("Custom Biome: " + k);
});
return a.get();
}
@Override
public void forceBiomeInto(int x, int y, int z, Object somethingVeryDirty, ChunkGenerator.BiomeGrid chunk) {
try {
BiomeStorage s = (BiomeStorage) getFieldForBiomeStorage(chunk).get(chunk);
s.setBiome(x, y, z, (BiomeBase) somethingVeryDirty);
} catch (IllegalAccessException e) {
Iris.reportError(e);
e.printStackTrace();
}
}
@Override
public boolean isBukkit() {
return false;
}
}

View File

@ -0,0 +1,267 @@
/*
* 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.nms.v16_3;
import com.volmit.iris.Iris;
import com.volmit.iris.core.nms.INMSBinding;
import com.volmit.iris.util.collection.KMap;
import net.minecraft.server.v1_16_R3.*;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.block.Biome;
import org.bukkit.craftbukkit.v1_16_R3.CraftServer;
import org.bukkit.craftbukkit.v1_16_R3.CraftWorld;
import org.bukkit.generator.ChunkGenerator;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.concurrent.atomic.AtomicInteger;
public class NMSBinding16_3 implements INMSBinding {
private final KMap<Biome, Object> baseBiomeCache = new KMap<>();
private Field biomeStorageCache = null;
public boolean supportsDataPacks() {
return true;
}
private Object getBiomeStorage(ChunkGenerator.BiomeGrid g) {
try {
return getFieldForBiomeStorage(g).get(g);
} catch (IllegalAccessException e) {
Iris.reportError(e);
e.printStackTrace();
}
return null;
}
@Override
public boolean supportsCustomHeight() {
return false;
}
@Override
public int getMinHeight(World world) {
return 0;
}
@Override
public boolean supportsCustomBiomes() {
return false;
}
private Field getFieldForBiomeStorage(Object storage) {
Field f = biomeStorageCache;
if (f != null) {
return f;
}
try {
f = storage.getClass().getDeclaredField("biome");
f.setAccessible(true);
return f;
} catch (Throwable e) {
Iris.reportError(e);
e.printStackTrace();
Iris.error(storage.getClass().getCanonicalName());
}
biomeStorageCache = f;
return null;
}
private IRegistryWritable<BiomeBase> getCustomBiomeRegistry() {
return ((CraftServer) Bukkit.getServer()).getHandle().getServer().getCustomRegistry().b(IRegistry.ay);
}
@Override
public Object getBiomeBaseFromId(int id) {
return getCustomBiomeRegistry().fromId(id);
}
@Override
public int getTrueBiomeBaseId(Object biomeBase) {
return getCustomBiomeRegistry().a((BiomeBase) biomeBase);
}
@Override
public Object getTrueBiomeBase(Location location) {
return ((CraftWorld) location.getWorld()).getHandle().getBiome(location.getBlockX(), location.getBlockY(), location.getBlockZ());
}
@Override
public String getTrueBiomeBaseKey(Location location) {
return getKeyForBiomeBase(getTrueBiomeBase(location));
}
@Override
public Object getCustomBiomeBaseFor(String mckey) {
try {
return getCustomBiomeRegistry().d(ResourceKey.a(IRegistry.ay, new MinecraftKey(mckey)));
} catch (Throwable e) {
Iris.reportError(e);
}
return null;
}
@SuppressWarnings("OptionalGetWithoutIsPresent")
@Override
public String getKeyForBiomeBase(Object biomeBase) {
return getCustomBiomeRegistry().c((BiomeBase) biomeBase).get().a().toString();
}
@Override
public Object getBiomeBase(World world, Biome biome) {
return getBiomeBase(((CraftWorld) world).getHandle().r().b(IRegistry.ay), biome);
}
private Class<?>[] classify(Object... par) {
Class<?>[] g = new Class<?>[par.length];
for (int i = 0; i < g.length; i++) {
g[i] = par[i].getClass();
}
return g;
}
private <T> T invoke(Object from, String name, Object... par) {
try {
Method f = from.getClass().getDeclaredMethod(name, classify(par));
f.setAccessible(true);
//noinspection unchecked
return (T) f.invoke(from, par);
} catch (Throwable e) {
Iris.reportError(e);
e.printStackTrace();
}
return null;
}
private <T> T invokeStatic(Class<?> from, String name, Object... par) {
try {
Method f = from.getDeclaredMethod(name, classify(par));
f.setAccessible(true);
//noinspection unchecked
return (T) f.invoke(null, par);
} catch (Throwable e) {
Iris.reportError(e);
e.printStackTrace();
}
return null;
}
private <T> T getField(Object from, String name) {
try {
Field f = from.getClass().getDeclaredField(name);
f.setAccessible(true);
//noinspection unchecked
return (T) f.get(from);
} catch (Throwable e) {
Iris.reportError(e);
e.printStackTrace();
}
return null;
}
private <T> T getStaticField(Class<?> t, String name) {
try {
Field f = t.getDeclaredField(name);
f.setAccessible(true);
//noinspection unchecked
return (T) f.get(null);
} catch (Throwable e) {
Iris.reportError(e);
e.printStackTrace();
}
return null;
}
@Override
public Object getBiomeBase(Object registry, Biome biome) {
Object v = baseBiomeCache.get(biome);
if (v != null) {
return v;
}
//noinspection unchecked
v = org.bukkit.craftbukkit.v1_16_R3.block.CraftBlock.biomeToBiomeBase((IRegistry<BiomeBase>) registry, biome);
if (v == null) {
// Ok so there is this new biome name called "CUSTOM" in Paper's new releases.
// But, this does NOT exist within CraftBukkit which makes it return an error.
// So, we will just return the ID that the plains biome returns instead.
//noinspection unchecked
return org.bukkit.craftbukkit.v1_16_R3.block.CraftBlock.biomeToBiomeBase((IRegistry<BiomeBase>) registry, Biome.PLAINS);
}
baseBiomeCache.put(biome, v);
return v;
}
@Override
public int getBiomeId(Biome biome) {
for (World i : Bukkit.getWorlds()) {
if (i.getEnvironment().equals(World.Environment.NORMAL)) {
IRegistry<BiomeBase> registry = ((CraftWorld) i).getHandle().r().b(IRegistry.ay);
return registry.a((BiomeBase) getBiomeBase(registry, biome));
}
}
return biome.ordinal();
}
@Override
public int countCustomBiomes() {
AtomicInteger a = new AtomicInteger(0);
getCustomBiomeRegistry().d().forEach((i) -> {
MinecraftKey k = i.getKey().a();
if (k.getNamespace().equals("minecraft")) {
return;
}
a.incrementAndGet();
Iris.debug("Custom Biome: " + k);
});
return a.get();
}
@Override
public void forceBiomeInto(int x, int y, int z, Object somethingVeryDirty, ChunkGenerator.BiomeGrid chunk) {
try {
BiomeStorage s = (BiomeStorage) getFieldForBiomeStorage(chunk).get(chunk);
s.setBiome(x, y, z, (BiomeBase) somethingVeryDirty);
} catch (IllegalAccessException e) {
Iris.reportError(e);
e.printStackTrace();
}
}
@Override
public boolean isBukkit() {
return false;
}
}

View File

@ -58,6 +58,11 @@ public class NMSBinding17_1 implements INMSBinding {
return null; return null;
} }
@Override
public boolean supportsCustomHeight() {
return false;
}
private Field getFieldForBiomeStorage(Object storage) { private Field getFieldForBiomeStorage(Object storage) {
Field f = biomeStorageCache; Field f = biomeStorageCache;
@ -103,6 +108,16 @@ public class NMSBinding17_1 implements INMSBinding {
return getKeyForBiomeBase(getTrueBiomeBase(location)); return getKeyForBiomeBase(getTrueBiomeBase(location));
} }
@Override
public boolean supportsCustomBiomes() {
return true;
}
@Override
public int getMinHeight(World world) {
return world.getMinHeight();
}
@Override @Override
public Object getCustomBiomeBaseFor(String mckey) { public Object getCustomBiomeBaseFor(String mckey) {
try { try {

View File

@ -24,12 +24,49 @@ import org.bukkit.World;
import org.bukkit.block.Biome; import org.bukkit.block.Biome;
import org.bukkit.generator.ChunkGenerator; import org.bukkit.generator.ChunkGenerator;
import java.lang.reflect.Method;
public class NMSBinding1X implements INMSBinding { public class NMSBinding1X implements INMSBinding {
private static final boolean supportsCustomHeight = testCustomHeight();
@SuppressWarnings("ConstantConditions")
private static boolean testCustomHeight() {
try
{
if(World.class.getDeclaredMethod("getMaxHeight") != null && World.class.getDeclaredMethod("getMinHeight") != null);
{
return true;
}
}
catch(Throwable ignored)
{
}
return false;
}
@Override
public boolean supportsCustomHeight() {
return supportsCustomHeight;
}
@Override @Override
public Object getBiomeBaseFromId(int id) { public Object getBiomeBaseFromId(int id) {
return null; return null;
} }
@Override
public int getMinHeight(World world) {
return supportsCustomHeight ? world.getMinHeight() : 0;
}
@Override
public boolean supportsCustomBiomes() {
return false;
}
@Override @Override
public int getTrueBiomeBaseId(Object biomeBase) { public int getTrueBiomeBaseId(Object biomeBase) {
return 0; return 0;

View File

@ -63,20 +63,20 @@ public class AsyncPregenMethod implements PregeneratorMethod {
PaperLib.getChunkAtAsync(world, x, z, true).get(); PaperLib.getChunkAtAsync(world, x, z, true).get();
listener.onChunkGenerated(x, z); listener.onChunkGenerated(x, z);
} catch (Throwable e) { } catch (Throwable e) {
e.printStackTrace(); J.sleep(5);
future.add(burst.complete(() -> completeChunk(x, z, listener)));
} }
} }
private void waitForChunks() { private void waitForChunks() {
for (CompletableFuture<?> i : future) { for (CompletableFuture<?> i : future.copy()) {
try { try {
i.get(); i.get();
future.remove(i);
} catch (Throwable e) { } catch (Throwable e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
future.clear();
} }
@Override @Override

View File

@ -42,7 +42,7 @@ public class HybridPregenMethod implements PregeneratorMethod {
} }
private boolean supportsHeadless(World world) { private boolean supportsHeadless(World world) {
return IrisWorlds.access(world) != null && IrisSettings.get().getGenerator().isMcaPregenerator(); return IrisWorlds.access(world) != null && !IrisSettings.get().getGenerator().isDisableMCA();
} }
@Override @Override

View File

@ -37,6 +37,8 @@ import net.md_5.bungee.api.ChatMessageType;
import net.md_5.bungee.api.chat.TextComponent; import net.md_5.bungee.api.chat.TextComponent;
import org.bukkit.WorldCreator; import org.bukkit.WorldCreator;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.function.Consumer; import java.util.function.Consumer;
/** /**
@ -95,7 +97,7 @@ public class IrisCreator {
IrisDimension d = IrisToolbelt.getDimension(dimension()); IrisDimension d = IrisToolbelt.getDimension(dimension());
IrisAccess access = null; IrisAccess access = null;
Consumer<Double> prog = (pxx) -> { Consumer<Double> prog = (pxx) -> {
double px = (headless && pregen != null) ? pxx / 2 : pxx; double px = pxx;
if (pregen != null && !headless) { if (pregen != null && !headless) {
px = (px / 2) + 0.5; px = (px / 2) + 0.5;
@ -158,61 +160,72 @@ public class IrisCreator {
sender.player().spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText(C.WHITE + "Generation Complete")); sender.player().spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText(C.WHITE + "Generation Complete"));
}); });
wc.createWorld(); try {
done.set(true); J.sfut(wc::createWorld).get();
} catch (Throwable e) {
e.printStackTrace();
}
} }
if (access == null) { if (access == null) {
throw new IrisException("Access is null. Something bad happened."); throw new IrisException("Access is null. Something bad happened.");
} }
IrisAccess finalAccess = access; CompletableFuture<Boolean> ff = new CompletableFuture<>();
Runnable loadup = () -> {
if (pregen != null) {
IrisToolbelt.pregenerate(pregen, access)
.onProgress(prog)
.whenDone(() -> ff.complete(true));
try { try {
J.sfut(() -> { ff.get();
if (headless) {
O<Boolean> done = new O<>();
done.set(false);
J.a(() ->
{
int req = 400;
while (finalAccess.getGenerated() < req && !done.get()) {
double v = (double) finalAccess.getGenerated() / (double) req;
v = (v / 2) + 0.5;
if (sender.isPlayer()) {
sender.player().spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText(C.WHITE + "Generating " + Form.pc(v) + ((C.GRAY + " (" + (req - finalAccess.getGenerated()) + " Left)"))));
J.sleep(50);
} else {
sender.sendMessage(C.WHITE + "Generating " + Form.pc(v) + ((C.GRAY + " (" + (req - finalAccess.getGenerated()) + " Left)")));
J.sleep(1000);
}
if (finalAccess.isFailing()) {
sender.sendMessage("Generation Failed!");
break;
}
}
sender.player().spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText(C.WHITE + "Generation Complete"));
});
finalAccess.getHeadlessGenerator().getWorld().load();
done.set(true);
}
}).get();
} catch (Throwable e) { } catch (Throwable e) {
e.printStackTrace(); e.printStackTrace();
} }
}; }
if (pregen != null) { try {
IrisToolbelt.pregenerate(pregen, access).onProgress(prog).whenDone(loadup);
} else { IrisAccess finalAccess = access;
loadup.run(); J.sfut(() -> {
if (headless) {
O<Boolean> done = new O<>();
done.set(false);
J.a(() ->
{
int req = 400;
while (finalAccess.getGenerated() < req && !done.get()) {
double v = (double) finalAccess.getGenerated() / (double) req;
v = (v / 2) + 0.5;
if (sender.isPlayer()) {
sender.player().spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText(C.WHITE + "Generating " + Form.pc(v) + ((C.GRAY + " (" + (req - finalAccess.getGenerated()) + " Left)"))));
J.sleep(50);
} else {
sender.sendMessage(C.WHITE + "Generating " + Form.pc(v) + ((C.GRAY + " (" + (req - finalAccess.getGenerated()) + " Left)")));
J.sleep(1000);
}
if (finalAccess.isFailing()) {
sender.sendMessage("Generation Failed!");
break;
}
}
sender.player().spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText(C.WHITE + "Generation Complete"));
});
finalAccess.getHeadlessGenerator().getWorld().load();
done.set(true);
}
}).get();
} catch (Throwable e) {
e.printStackTrace();
} }
return access; return access;

View File

@ -39,6 +39,7 @@ import org.bukkit.block.Biome;
import org.bukkit.block.data.BlockData; import org.bukkit.block.data.BlockData;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
@Data @Data
public class IrisComplex implements DataProvider { public class IrisComplex implements DataProvider {
@ -115,6 +116,12 @@ public class IrisComplex implements DataProvider {
fluidHeight = engine.getDimension().getFluidHeight(); fluidHeight = engine.getDimension().getFluidHeight();
generators = new KList<>(); generators = new KList<>();
focus = engine.getFocus(); focus = engine.getFocus();
if(focus != null)
{
focus.setInferredType(InferredType.LAND);
}
IrisRegion focusRegion = focus != null ? findRegion(focus, engine) : null; IrisRegion focusRegion = focus != null ? findRegion(focus, engine) : null;
RNG rng = new RNG(engine.getWorld().seed()); RNG rng = new RNG(engine.getWorld().seed());
//@builder //@builder
@ -195,13 +202,13 @@ public class IrisComplex implements DataProvider {
heightStream = ProceduralStream.of((x, z) -> { heightStream = ProceduralStream.of((x, z) -> {
IrisBiome b = focus != null ? focus : baseBiomeStream.get(x, z); IrisBiome b = focus != null ? focus : baseBiomeStream.get(x, z);
return getHeight(engine, b, x, z, engine.getWorld().seed()); return getHeight(engine, b, x, z, engine.getWorld().seed());
}, Interpolated.DOUBLE).cache2D(cacheSize); }, Interpolated.DOUBLE).clamp(0, engine.getHeight()).cache2D(cacheSize);
slopeStream = heightStream.slope(3).cache2D(cacheSize); slopeStream = heightStream.slope(3).cache2D(cacheSize);
objectChanceStream = ProceduralStream.ofDouble((x, z) -> { objectChanceStream = ProceduralStream.ofDouble((x, z) -> {
if (engine.getDimension().hasFeatures(engine)) { if (engine.getDimension().hasFeatures(engine)) {
AtomicDouble str = new AtomicDouble(1D); AtomicDouble str = new AtomicDouble(1D);
engine.getFramework().getEngineParallax().forEachFeature(x, z, (i) engine.getFramework().getEngineParallax().forEachFeature(x, z, (i)
-> str.set(Math.min(str.get(), i.getObjectChanceModifier(x, z)))); -> str.set(Math.min(str.get(), i.getObjectChanceModifier(x, z, rng))));
return str.get(); return str.get();
} }
@ -209,10 +216,39 @@ public class IrisComplex implements DataProvider {
}); });
trueBiomeStream = focus != null ? ProceduralStream.of((x, y) -> focus, Interpolated.of(a -> 0D, trueBiomeStream = focus != null ? ProceduralStream.of((x, y) -> focus, Interpolated.of(a -> 0D,
b -> focus)) : heightStream b -> focus)).convertAware2D((b, x,z) -> {
for(IrisFeaturePositional i : engine.getFramework().getEngineParallax().forEachFeature(x, z))
{
IrisBiome bx = i.filter(x, z, b, rng);
if(bx != null)
{
bx.setInferredType(b.getInferredType());
return bx;
}
}
return b;
})
.cache2D(cacheSize) : heightStream
.convertAware2D((h, x, z) -> .convertAware2D((h, x, z) ->
fixBiomeType(h, baseBiomeStream.get(x, z), fixBiomeType(h, baseBiomeStream.get(x, z),
regionStream.get(x, z), x, z, fluidHeight)).cache2D(cacheSize); regionStream.get(x, z), x, z, fluidHeight))
.convertAware2D((b, x,z) -> {
for(IrisFeaturePositional i : engine.getFramework().getEngineParallax().forEachFeature(x, z))
{
IrisBiome bx = i.filter(x, z, b, rng);
if(bx != null)
{
bx.setInferredType(b.getInferredType());
return bx;
}
}
return b;
})
.cache2D(cacheSize);
trueBiomeDerivativeStream = trueBiomeStream.convert(IrisBiome::getDerivative).cache2D(cacheSize); trueBiomeDerivativeStream = trueBiomeStream.convert(IrisBiome::getDerivative).cache2D(cacheSize);
heightFluidStream = heightStream.max(fluidHeight).cache2D(cacheSize); heightFluidStream = heightStream.max(fluidHeight).cache2D(cacheSize);
maxHeightStream = ProceduralStream.ofDouble((x, z) -> height); maxHeightStream = ProceduralStream.ofDouble((x, z) -> height);
@ -380,7 +416,7 @@ public class IrisComplex implements DataProvider {
AtomicDouble noise = new AtomicDouble(h + fluidHeight + overlayStream.get(x, z)); AtomicDouble noise = new AtomicDouble(h + fluidHeight + overlayStream.get(x, z));
engine.getFramework().getEngineParallax().forEachFeature(x, z, (i) engine.getFramework().getEngineParallax().forEachFeature(x, z, (i)
-> noise.set(i.filter(x, z, noise.get()))); -> noise.set(i.filter(x, z, noise.get(), rng)));
return Math.min(engine.getHeight(), Math.max(noise.get(), 0)); return Math.min(engine.getHeight(), Math.max(noise.get(), 0));
} }

View File

@ -163,6 +163,7 @@ public class IrisEngine extends BlockPopulator implements Engine {
try { try {
PrecisionStopwatch p = PrecisionStopwatch.start(); PrecisionStopwatch p = PrecisionStopwatch.start();
BurstExecutor b = burst().burst(16); BurstExecutor b = burst().burst(16);
Hunk<BlockData> blocks = vblocks.listen((xx, y, zz, t) -> catchBlockUpdates(x + xx, y + getMinHeight(), z + zz, t));
// This is a very weird optimization, but it works // This is a very weird optimization, but it works
// Basically we precache multicore the biome stream which effectivley // Basically we precache multicore the biome stream which effectivley
@ -188,9 +189,9 @@ public class IrisEngine extends BlockPopulator implements Engine {
getFramework().getCaveModifier().modify(x, z, vblocks); getFramework().getCaveModifier().modify(x, z, vblocks);
getFramework().getRavineModifier().modify(x, z, vblocks); getFramework().getRavineModifier().modify(x, z, vblocks);
getFramework().getPostModifier().modify(x, z, vblocks); getFramework().getPostModifier().modify(x, z, vblocks);
getFramework().getDecorantActuator().actuate(x, z, vblocks); getFramework().getDecorantActuator().actuate(x, z, blocks);
getFramework().getEngineParallax().insertParallax(x >> 4, z >> 4, vblocks); getFramework().getEngineParallax().insertParallax(x >> 4, z >> 4, blocks);
getFramework().getDepositModifier().modify(x, z, vblocks); getFramework().getDepositModifier().modify(x, z, blocks);
} }
case ISLANDS -> { case ISLANDS -> {
getFramework().getTerrainActuator().actuate(x, z, vblocks); getFramework().getTerrainActuator().actuate(x, z, vblocks);

View File

@ -74,13 +74,11 @@ public class IrisWorldManager extends EngineAssignedWorldManager {
trySpawn(above.getEntityInitialSpawns(), c, rng); trySpawn(above.getEntityInitialSpawns(), c, rng);
trySpawn(region.getEntityInitialSpawns(), c, rng); trySpawn(region.getEntityInitialSpawns(), c, rng);
trySpawn(dim.getEntityInitialSpawns(), c, rng); trySpawn(dim.getEntityInitialSpawns(), c, rng);
} }
@Override @Override
public void onEntitySpawn(EntitySpawnEvent e) { public void onEntitySpawn(EntitySpawnEvent e) {
if (getTarget().getWorld() == null || !getTarget().getWorld().equals(e.getEntity().getWorld())) { if (getTarget().getWorld() == null || !e.getEntity().getWorld().equals(getTarget().getWorld().realWorld())) {
return; return;
} }

View File

@ -70,7 +70,6 @@ public class IrisBiomeActuator extends EngineAssignedActuator<Biome> {
for (int xf = 0; xf < h.getWidth(); xf++) { for (int xf = 0; xf < h.getWidth(); xf++) {
for (zf = 0; zf < h.getDepth(); zf++) { for (zf = 0; zf < h.getDepth(); zf++) {
ib = getComplex().getTrueBiomeStream().get(modX(xf + x), modZ(zf + z)); ib = getComplex().getTrueBiomeStream().get(modX(xf + x), modZ(zf + z));
maxHeight = (int) (getComplex().getFluidHeight() + ib.getMaxWithObjectHeight(getData())); maxHeight = (int) (getComplex().getFluidHeight() + ib.getMaxWithObjectHeight(getData()));
if (ib.isCustom()) { if (ib.isCustom()) {
@ -78,7 +77,7 @@ public class IrisBiomeActuator extends EngineAssignedActuator<Biome> {
IrisBiomeCustom custom = ib.getCustomBiome(rng, x, 0, z); IrisBiomeCustom custom = ib.getCustomBiome(rng, x, 0, z);
Object biomeBase = INMS.get().getCustomBiomeBaseFor(getDimension().getLoadKey() + ":" + custom.getId()); Object biomeBase = INMS.get().getCustomBiomeBaseFor(getDimension().getLoadKey() + ":" + custom.getId());
if (!injectBiome(h, x, 0, z, biomeBase)) { if (biomeBase == null || !injectBiome(h, x, 0, z, biomeBase)) {
throw new RuntimeException("Cant inject biome!"); throw new RuntimeException("Cant inject biome!");
} }
@ -87,7 +86,6 @@ public class IrisBiomeActuator extends EngineAssignedActuator<Biome> {
} }
} catch (Throwable e) { } catch (Throwable e) {
Iris.reportError(e); Iris.reportError(e);
e.printStackTrace();
Biome v = ib.getSkyBiome(rng, x, 0, z); Biome v = ib.getSkyBiome(rng, x, 0, z);
for (int i = 0; i < maxHeight; i++) { for (int i = 0; i < maxHeight; i++) {
h.set(xf, i, zf, v); h.set(xf, i, zf, v);

View File

@ -0,0 +1,163 @@
/*
* 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.data.chunk;
import com.volmit.iris.core.nms.BiomeBaseInjector;
import com.volmit.iris.engine.data.mca.Chunk;
import com.volmit.iris.engine.data.mca.NBTWorld;
import lombok.AllArgsConstructor;
import lombok.Builder;
import org.bukkit.Material;
import org.bukkit.block.Biome;
import org.bukkit.block.data.BlockData;
import org.bukkit.generator.ChunkGenerator;
import org.bukkit.material.MaterialData;
import org.jetbrains.annotations.NotNull;
@Builder
@AllArgsConstructor
public class MCATerrainChunk implements TerrainChunk {
private NBTWorld writer;
private BiomeBaseInjector injector;
private int ox;
private int oz;
private int minHeight;
private int maxHeight;
private Chunk mcaChunk;
@Override
public BiomeBaseInjector getBiomeBaseInjector() {
return injector;
}
@Override
public void setRaw(ChunkGenerator.ChunkData data) {
}
@NotNull
@Override
public Biome getBiome(int x, int z) {
return Biome.THE_VOID;
}
@NotNull
@Override
public Biome getBiome(int x, int y, int z) {
return Biome.THE_VOID;
}
@Override
public void setBiome(int x, int z, Biome bio) {
setBiome(ox + x, 0, oz + z, bio);
}
@Override
public void setBiome(int x, int y, int z, Biome bio) {
writer.setBiome(ox + x, y, oz + z, bio);
}
@Override
public int getMinHeight() {
return minHeight;
}
@Override
public int getMaxHeight() {
return maxHeight;
}
@Override
public void setBlock(int x, int y, int z, BlockData blockData) {
int xx = (x + ox) & 15;
int zz = (z + oz) & 15;
if (y > 255 || y < 0) {
return;
}
mcaChunk.setBlockStateAt(xx, y, zz, NBTWorld.getCompound(blockData), false);
}
@NotNull
@Override
public org.bukkit.block.data.BlockData getBlockData(int x, int y, int z) {
if (y > getMaxHeight()) {
y = getMaxHeight();
}
if (y < 0) {
y = 0;
}
return NBTWorld.getBlockData(mcaChunk.getBlockStateAt((x + ox) & 15, y, (z + oz) & 15));
}
@Override
public ChunkGenerator.ChunkData getRaw() {
return null;
}
@Override
public void inject(ChunkGenerator.BiomeGrid biome) {
}
@Override
public void setBlock(int x, int y, int z, @NotNull Material material) {
}
@Override
public void setBlock(int x, int y, int z, @NotNull MaterialData material) {
}
@Override
public void setRegion(int xMin, int yMin, int zMin, int xMax, int yMax, int zMax, @NotNull Material material) {
}
@Override
public void setRegion(int xMin, int yMin, int zMin, int xMax, int yMax, int zMax, @NotNull MaterialData material) {
}
@Override
public void setRegion(int xMin, int yMin, int zMin, int xMax, int yMax, int zMax, @NotNull BlockData blockData) {
}
@NotNull
@Override
public Material getType(int x, int y, int z) {
return null;
}
@NotNull
@Override
public MaterialData getTypeAndData(int x, int y, int z) {
return null;
}
@Override
public byte getData(int x, int y, int z) {
return 0;
}
}

View File

@ -36,7 +36,9 @@ import com.volmit.iris.util.scheduling.PrecisionStopwatch;
import lombok.Data; import lombok.Data;
import java.io.File; import java.io.File;
import java.util.Locale;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Predicate;
@Data @Data
public class ResourceLoader<T extends IrisRegistrant> { public class ResourceLoader<T extends IrisRegistrant> {
@ -91,6 +93,32 @@ public class ResourceLoader<T extends IrisRegistrant> {
J.a(() -> Iris.warn("Couldn't Load " + resourceTypeName + " file: " + path.getPath() + ": " + e.getMessage())); J.a(() -> Iris.warn("Couldn't Load " + resourceTypeName + " file: " + path.getPath() + ": " + e.getMessage()));
} }
private KList<File> matchAllFiles(File root, Predicate<File> f)
{
KList<File> fx = new KList<>();
matchFiles(root, fx, f);
return fx;
}
private void matchFiles(File at, KList<File> files, Predicate<File> f)
{
if(at.isDirectory())
{
for(File i : at.listFiles())
{
matchFiles(i, files, f);
}
}
else
{
if(f.test(at))
{
files.add(at);
}
}
}
public String[] getPossibleKeys() { public String[] getPossibleKeys() {
if (possibleKeys != null) { if (possibleKeys != null) {
return possibleKeys; return possibleKeys;
@ -99,17 +127,11 @@ public class ResourceLoader<T extends IrisRegistrant> {
Iris.info("Building " + resourceTypeName + " Registry Lists"); Iris.info("Building " + resourceTypeName + " Registry Lists");
KSet<String> m = new KSet<>(); KSet<String> m = new KSet<>();
for (File i : getFolders()) { for(File i : getFolders())
for (File j : i.listFiles()) { {
if (j.isFile() && j.getName().endsWith(".json")) { for(File j : matchAllFiles(i, (f) -> f.getName().endsWith(".json")))
m.add(j.getName().replaceAll("\\Q.json\\E", "")); {
} else if (j.isDirectory()) { m.add(i.toURI().relativize(j.toURI()).getPath().replaceAll("\\Q.json\\E", ""));
for (File k : j.listFiles()) {
if (k.isFile() && k.getName().endsWith(".json")) {
m.add(j.getName() + "/" + k.getName().replaceAll("\\Q.json\\E", ""));
}
}
}
} }
} }
@ -156,6 +178,20 @@ public class ResourceLoader<T extends IrisRegistrant> {
return m; return m;
} }
public KList<T> loadAll(String[] s) {
KList<T> m = new KList<>();
for (String i : s) {
T t = load(i);
if (t != null) {
m.add(t);
}
}
return m;
}
public T load(String name) { public T load(String name) {
return load(name, true); return load(name, true);
} }
@ -268,4 +304,18 @@ public class ResourceLoader<T extends IrisRegistrant> {
possibleKeys = null; possibleKeys = null;
lock.unlock(); lock.unlock();
} }
public KList<String> getPossibleKeys(String arg) {
KList<String> f = new KList<>();
for(String i : getPossibleKeys())
{
if(i.equalsIgnoreCase(arg) || i.toLowerCase(Locale.ROOT).startsWith(arg.toLowerCase(Locale.ROOT)) || i.toLowerCase(Locale.ROOT).contains(arg.toLowerCase(Locale.ROOT)) || arg.toLowerCase(Locale.ROOT).contains(i.toLowerCase(Locale.ROOT)))
{
f.add(i);
}
}
return f;
}
} }

View File

@ -26,6 +26,7 @@ import com.volmit.iris.engine.data.nbt.tag.ListTag;
import java.io.*; import java.io.*;
import java.util.Arrays; import java.util.Arrays;
import java.util.concurrent.atomic.AtomicReferenceArray;
import static com.volmit.iris.engine.data.mca.LoadFlags.*; import static com.volmit.iris.engine.data.mca.LoadFlags.*;
@ -45,7 +46,7 @@ public class Chunk {
private int[] biomes; private int[] biomes;
private CompoundTag heightMaps; private CompoundTag heightMaps;
private CompoundTag carvingMasks; private CompoundTag carvingMasks;
private final Section[] sections = new Section[16]; private final AtomicReferenceArray<Section> sections = new AtomicReferenceArray<>(16);
private ListTag<CompoundTag> entities; private ListTag<CompoundTag> entities;
private ListTag<CompoundTag> tileEntities; private ListTag<CompoundTag> tileEntities;
private ListTag<CompoundTag> tileTicks; private ListTag<CompoundTag> tileTicks;
@ -129,7 +130,7 @@ public class Chunk {
if (newSection.isEmpty()) { if (newSection.isEmpty()) {
continue; continue;
} }
sections[sectionIndex] = newSection; sections.set(sectionIndex, newSection);
} }
} }
@ -299,7 +300,7 @@ public class Chunk {
} }
public CompoundTag getBlockStateAt(int blockX, int blockY, int blockZ) { public CompoundTag getBlockStateAt(int blockX, int blockY, int blockZ) {
Section section = sections[MCAUtil.blockToChunk(blockY)]; Section section = sections.get(MCAUtil.blockToChunk(blockY));
if (section == null) { if (section == null) {
return null; return null;
} }
@ -320,9 +321,10 @@ public class Chunk {
*/ */
public void setBlockStateAt(int blockX, int blockY, int blockZ, CompoundTag state, boolean cleanup) { public void setBlockStateAt(int blockX, int blockY, int blockZ, CompoundTag state, boolean cleanup) {
int sectionIndex = MCAUtil.blockToChunk(blockY); int sectionIndex = MCAUtil.blockToChunk(blockY);
Section section = sections[sectionIndex]; Section section = sections.get(sectionIndex);
if (section == null) { if (section == null) {
section = sections[sectionIndex] = Section.newSection(); section = Section.newSection();
sections.set(sectionIndex, section);
} }
section.setBlockStateAt(blockX, blockY, blockZ, state, cleanup); section.setBlockStateAt(blockX, blockY, blockZ, state, cleanup);
} }
@ -383,7 +385,7 @@ public class Chunk {
* @return The Section. * @return The Section.
*/ */
public Section getSection(int sectionY) { public Section getSection(int sectionY) {
return sections[sectionY]; return sections.get(sectionY);
} }
/** /**
@ -393,7 +395,7 @@ public class Chunk {
* @param section The section to be set. * @param section The section to be set.
*/ */
public void setSection(int sectionY, Section section) { public void setSection(int sectionY, Section section) {
sections[sectionY] = section; sections.set(sectionY, section);
} }
/** /**
@ -632,7 +634,9 @@ public class Chunk {
} }
public void cleanupPalettesAndBlockStates() { public void cleanupPalettesAndBlockStates() {
for (Section section : sections) { for (int i = 0; i < sections.length(); i++)
{
Section section = sections.get(i);
if (section != null) { if (section != null) {
section.cleanupPaletteAndBlockStates(); section.cleanupPaletteAndBlockStates();
} }
@ -673,12 +677,28 @@ public class Chunk {
level.putString("Status", status); level.putString("Status", status);
if (structures != null) level.put("Structures", structures); if (structures != null) level.put("Structures", structures);
ListTag<CompoundTag> sections = new ListTag<>(CompoundTag.class); ListTag<CompoundTag> sections = new ListTag<>(CompoundTag.class);
for (int i = 0; i < this.sections.length; i++) { for (int i = 0; i < this.sections.length(); i++) {
if (this.sections[i] != null) { if (this.sections.get(i) != null) {
sections.add(this.sections[i].updateHandle(i)); sections.add(this.sections.get(i).updateHandle(i));
} }
} }
level.put("Sections", sections); level.put("Sections", sections);
return data; return data;
} }
public int sectionCount() {
return sections.length();
}
public void runLighting() {
for(int s = 15; s >= 0; s--)
{
Section section = getSection(s);
if(section != null)
{
section.runLighting();
}
}
}
} }

View File

@ -160,6 +160,7 @@ public final class MCAUtil {
if (chunks > 0 && to != file) { if (chunks > 0 && to != file) {
Files.move(to.toPath(), file.toPath(), StandardCopyOption.REPLACE_EXISTING); Files.move(to.toPath(), file.toPath(), StandardCopyOption.REPLACE_EXISTING);
} }
return chunks; return chunks;
} }

View File

@ -265,7 +265,7 @@ public class NBTWorld {
return s; return s;
} }
public Chunk getChunk(int x, int z) { public synchronized Chunk getChunk(int x, int z) {
MCAFile mca = getMCA(x >> 5, z >> 5); MCAFile mca = getMCA(x >> 5, z >> 5);
Chunk c = mca.getChunk(x & 31, z & 31); Chunk c = mca.getChunk(x & 31, z & 31);

View File

@ -25,18 +25,19 @@ import com.volmit.iris.engine.data.nbt.tag.ListTag;
import com.volmit.iris.engine.data.nbt.tag.LongArrayTag; import com.volmit.iris.engine.data.nbt.tag.LongArrayTag;
import com.volmit.iris.util.collection.KMap; import com.volmit.iris.util.collection.KMap;
import java.lang.reflect.Field;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.atomic.AtomicLongArray;
public class Section { public class Section {
private CompoundTag data; private CompoundTag data;
private Map<String, List<PaletteIndex>> valueIndexedPalette = new KMap<>(); private Map<String, List<PaletteIndex>> valueIndexedPalette = new KMap<>();
private ListTag<CompoundTag> palette; private ListTag<CompoundTag> palette;
private byte[] blockLight; private byte[] blockLight;
private long[] blockStates; private AtomicLongArray blockStates;
private byte[] skyLight; private byte[] skyLight;
private int dataVersion; private int dataVersion;
@ -65,7 +66,7 @@ public class Section {
this.blockLight = blockLight != null ? blockLight.getValue() : null; this.blockLight = blockLight != null ? blockLight.getValue() : null;
} }
if ((loadFlags & LoadFlags.BLOCK_STATES) != 0) { if ((loadFlags & LoadFlags.BLOCK_STATES) != 0) {
this.blockStates = blockStates != null ? blockStates.getValue() : null; this.blockStates = blockStates != null ? new AtomicLongArray(blockStates.getValue()) : null;
} }
if ((loadFlags & LoadFlags.SKY_LIGHT) != 0) { if ((loadFlags & LoadFlags.SKY_LIGHT) != 0) {
this.skyLight = skyLight != null ? skyLight.getValue() : null; this.skyLight = skyLight != null ? skyLight.getValue() : null;
@ -106,6 +107,19 @@ public class Section {
return null; return null;
} }
public void runLighting() {
for(int x = 1; x < 14; x++)
{
for(int z = 1; z < 14; z++)
{
for(int y = 0; y < 16; y++)
{
}
}
}
}
@SuppressWarnings("ClassCanBeRecord") @SuppressWarnings("ClassCanBeRecord")
private static class PaletteIndex { private static class PaletteIndex {
@ -185,24 +199,24 @@ public class Section {
* @return The index of the block data in the palette. * @return The index of the block data in the palette.
*/ */
public int getPaletteIndex(int blockStateIndex) { public int getPaletteIndex(int blockStateIndex) {
int bits = blockStates.length >> 6; int bits = blockStates.length() >> 6;
if (dataVersion < 2527) { if (dataVersion < 2527) {
double blockStatesIndex = blockStateIndex / (4096D / blockStates.length); double blockStatesIndex = blockStateIndex / (4096D / blockStates.length());
int longIndex = (int) blockStatesIndex; int longIndex = (int) blockStatesIndex;
int startBit = (int) ((blockStatesIndex - Math.floor(blockStatesIndex)) * 64D); int startBit = (int) ((blockStatesIndex - Math.floor(blockStatesIndex)) * 64D);
if (startBit + bits > 64) { if (startBit + bits > 64) {
long prev = bitRange(blockStates[longIndex], startBit, 64); long prev = bitRange(blockStates.get(longIndex), startBit, 64);
long next = bitRange(blockStates[longIndex + 1], 0, startBit + bits - 64); long next = bitRange(blockStates.get(longIndex + 1), 0, startBit + bits - 64);
return (int) ((next << 64 - startBit) + prev); return (int) ((next << 64 - startBit) + prev);
} else { } else {
return (int) bitRange(blockStates[longIndex], startBit, startBit + bits); return (int) bitRange(blockStates.get(longIndex), startBit, startBit + bits);
} }
} else { } else {
int indicesPerLong = (int) (64D / bits); int indicesPerLong = (int) (64D / bits);
int blockStatesIndex = blockStateIndex / indicesPerLong; int blockStatesIndex = blockStateIndex / indicesPerLong;
int startBit = (blockStateIndex % indicesPerLong) * bits; int startBit = (blockStateIndex % indicesPerLong) * bits;
return (int) bitRange(blockStates[blockStatesIndex], startBit, startBit + bits); return (int) bitRange(blockStates.get(blockStatesIndex), startBit, startBit + bits);
} }
} }
@ -213,24 +227,24 @@ public class Section {
* @param paletteIndex The block state to be set (index of block data in the palette). * @param paletteIndex The block state to be set (index of block data in the palette).
* @param blockStates The block states to be updated. * @param blockStates The block states to be updated.
*/ */
public void setPaletteIndex(int blockIndex, int paletteIndex, long[] blockStates) { public void setPaletteIndex(int blockIndex, int paletteIndex, AtomicLongArray blockStates) {
int bits = blockStates.length >> 6; int bits = blockStates.length() >> 6;
if (dataVersion < 2527) { if (dataVersion < 2527) {
double blockStatesIndex = blockIndex / (4096D / blockStates.length); double blockStatesIndex = blockIndex / (4096D / blockStates.length());
int longIndex = (int) blockStatesIndex; int longIndex = (int) blockStatesIndex;
int startBit = (int) ((blockStatesIndex - Math.floor(longIndex)) * 64D); int startBit = (int) ((blockStatesIndex - Math.floor(longIndex)) * 64D);
if (startBit + bits > 64) { if (startBit + bits > 64) {
blockStates[longIndex] = updateBits(blockStates[longIndex], paletteIndex, startBit, 64); blockStates.set(longIndex, updateBits(blockStates.get(longIndex), paletteIndex, startBit, 64));
blockStates[longIndex + 1] = updateBits(blockStates[longIndex + 1], paletteIndex, startBit - 64, startBit + bits - 64); blockStates.set(longIndex + 1, updateBits(blockStates.get(longIndex + 1), paletteIndex, startBit - 64, startBit + bits - 64));
} else { } else {
blockStates[longIndex] = updateBits(blockStates[longIndex], paletteIndex, startBit, startBit + bits); blockStates.set(longIndex, updateBits(blockStates.get(longIndex), paletteIndex, startBit, startBit + bits));
} }
} else { } else {
int indicesPerLong = (int) (64D / bits); int indicesPerLong = (int) (64D / bits);
int blockStatesIndex = blockIndex / indicesPerLong; int blockStatesIndex = blockIndex / indicesPerLong;
int startBit = (blockIndex % indicesPerLong) * bits; int startBit = (blockIndex % indicesPerLong) * bits;
blockStates[blockStatesIndex] = updateBits(blockStates[blockStatesIndex], paletteIndex, startBit, startBit + bits); blockStates.set(blockStatesIndex, updateBits(blockStates.get(blockStatesIndex), paletteIndex, startBit, startBit + bits));
} }
} }
@ -304,7 +318,7 @@ public class Section {
return allIndices; return allIndices;
} }
void adjustBlockStateBits(Map<Integer, Integer> oldToNewMapping, long[] blockStates) { void adjustBlockStateBits(Map<Integer, Integer> oldToNewMapping, AtomicLongArray blockStates) {
//increases or decreases the amount of bits used per BlockState //increases or decreases the amount of bits used per BlockState
//based on the size of the palette. oldToNewMapping can be used to update indices //based on the size of the palette. oldToNewMapping can be used to update indices
//if the palette had been cleaned up before using MCAFile#cleanupPalette(). //if the palette had been cleaned up before using MCAFile#cleanupPalette().
@ -312,13 +326,13 @@ public class Section {
int newBits = 32 - Integer.numberOfLeadingZeros(palette.size() - 1); int newBits = 32 - Integer.numberOfLeadingZeros(palette.size() - 1);
newBits = Math.max(newBits, 4); newBits = Math.max(newBits, 4);
long[] newBlockStates; AtomicLongArray newBlockStates;
if (dataVersion < 2527) { if (dataVersion < 2527) {
newBlockStates = newBits == blockStates.length / 64 ? blockStates : new long[newBits * 64]; newBlockStates = newBits == blockStates.length() / 64 ? blockStates : new AtomicLongArray(newBits * 64);
} else { } else {
int newLength = (int) Math.ceil(4096D / (64D / newBits)); int newLength = (int) Math.ceil(4096D / (64D / newBits));
newBlockStates = newBits == blockStates.length / 64 ? blockStates : new long[newLength]; newBlockStates = newBits == blockStates.length() / 64 ? blockStates : new AtomicLongArray(newLength);
} }
if (oldToNewMapping != null) { if (oldToNewMapping != null) {
for (int i = 0; i < 4096; i++) { for (int i = 0; i < 4096; i++) {
@ -355,7 +369,7 @@ public class Section {
/** /**
* @return The indices of the block states of this Section. * @return The indices of the block states of this Section.
*/ */
public long[] getBlockStates() { public AtomicLongArray getBlockStates() {
return blockStates; return blockStates;
} }
@ -366,10 +380,10 @@ public class Section {
* @throws NullPointerException If <code>blockStates</code> is <code>null</code> * @throws NullPointerException If <code>blockStates</code> is <code>null</code>
* @throws IllegalArgumentException When <code>blockStates</code>' length is &lt; 256 or &gt; 4096 and is not a multiple of 64 * @throws IllegalArgumentException When <code>blockStates</code>' length is &lt; 256 or &gt; 4096 and is not a multiple of 64
*/ */
public void setBlockStates(long[] blockStates) { public void setBlockStates(AtomicLongArray blockStates) {
if (blockStates == null) { if (blockStates == null) {
throw new NullPointerException("BlockStates cannot be null"); throw new NullPointerException("BlockStates cannot be null");
} else if (blockStates.length % 64 != 0 || blockStates.length < 256 || blockStates.length > 4096) { } else if (blockStates.length() % 64 != 0 || blockStates.length() < 256 || blockStates.length() > 4096) {
throw new IllegalArgumentException("BlockStates must have a length > 255 and < 4097 and must be divisible by 64"); throw new IllegalArgumentException("BlockStates must have a length > 255 and < 4097 and must be divisible by 64");
} }
this.blockStates = blockStates; this.blockStates = blockStates;
@ -402,7 +416,7 @@ public class Section {
*/ */
public static Section newSection() { public static Section newSection() {
Section s = new Section(); Section s = new Section();
s.blockStates = new long[256]; s.blockStates = new AtomicLongArray(256);
s.palette = new ListTag<>(CompoundTag.class); s.palette = new ListTag<>(CompoundTag.class);
CompoundTag air = new CompoundTag(); CompoundTag air = new CompoundTag();
air.putString("Name", "minecraft:air"); air.putString("Name", "minecraft:air");
@ -428,7 +442,14 @@ public class Section {
data.putByteArray("BlockLight", blockLight); data.putByteArray("BlockLight", blockLight);
} }
if (blockStates != null) { if (blockStates != null) {
data.putLongArray("BlockStates", blockStates); long[] c = new long[blockStates.length()];
for(int i = 0; i < c.length; i++)
{
c[i] = blockStates.get(i);
}
data.putLongArray("BlockStates", c);
} }
if (skyLight != null) { if (skyLight != null) {
data.putByteArray("SkyLight", skyLight); data.putByteArray("SkyLight", skyLight);

View File

@ -38,15 +38,23 @@ import com.volmit.iris.util.scheduling.PrecisionStopwatch;
import org.bukkit.Chunk; import org.bukkit.Chunk;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.block.Biome; import org.bukkit.block.Biome;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.block.Chest;
import org.bukkit.block.data.BlockData; import org.bukkit.block.data.BlockData;
import org.bukkit.inventory.Inventory; import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder; import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.loot.LootContext;
import org.bukkit.loot.LootTable;
import org.bukkit.loot.Lootable;
import org.jetbrains.annotations.NotNull;
import java.awt.*; import java.awt.*;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection;
import java.util.Random;
public interface Engine extends DataProvider, Fallible, GeneratorAccess, LootProvider, BlockUpdater, Renderer, Hotloadable { public interface Engine extends DataProvider, Fallible, GeneratorAccess, LootProvider, BlockUpdater, Renderer, Hotloadable {
void close(); void close();
@ -163,10 +171,8 @@ public interface Engine extends DataProvider, Fallible, GeneratorAccess, LootPro
} }
if (B.isUpdatable(data)) { if (B.isUpdatable(data)) {
synchronized (getParallax()) { getParallax().updateBlock(x, y, z);
getParallax().updateBlock(x, y, z); getParallax().getMetaRW(x >> 4, z >> 4).setUpdates(true);
getParallax().getMetaRW(x >> 4, z >> 4).setUpdates(true);
}
} }
} }
@ -233,7 +239,6 @@ public interface Engine extends DataProvider, Fallible, GeneratorAccess, LootPro
addItems(false, m.getInventory(), rx, tables, slot, x, y, z, 15); addItems(false, m.getInventory(), rx, tables, slot, x, y, z, 15);
} catch (Throwable e) { } catch (Throwable e) {
Iris.reportError(e); Iris.reportError(e);
} }
} }
} }

View File

@ -39,35 +39,35 @@ public abstract class EngineAssignedWorldManager extends EngineAssignedComponent
@EventHandler @EventHandler
public void on(WorldSaveEvent e) { public void on(WorldSaveEvent e) {
if (e.getWorld().equals(getTarget().getWorld())) { if (e.getWorld().equals(getTarget().getWorld().realWorld())) {
onSave(); onSave();
} }
} }
@EventHandler @EventHandler
public void on(WorldUnloadEvent e) { public void on(WorldUnloadEvent e) {
if (e.getWorld().equals(getTarget().getWorld())) { if (e.getWorld().equals(getTarget().getWorld().realWorld())) {
getEngine().close(); getEngine().close();
} }
} }
@EventHandler @EventHandler
public void on(EntitySpawnEvent e) { public void on(EntitySpawnEvent e) {
if (e.getEntity().getWorld().equals(getTarget().getWorld())) { if (e.getEntity().getWorld().equals(getTarget().getWorld().realWorld())) {
onEntitySpawn(e); onEntitySpawn(e);
} }
} }
@EventHandler @EventHandler
public void on(BlockBreakEvent e) { public void on(BlockBreakEvent e) {
if (e.getPlayer().getWorld().equals(getTarget().getWorld())) { if (e.getPlayer().getWorld().equals(getTarget().getWorld().realWorld())) {
onBlockBreak(e); onBlockBreak(e);
} }
} }
@EventHandler @EventHandler
public void on(BlockPlaceEvent e) { public void on(BlockPlaceEvent e) {
if (e.getPlayer().getWorld().equals(getTarget().getWorld())) { if (e.getPlayer().getWorld().equals(getTarget().getWorld().realWorld())) {
onBlockPlace(e); onBlockPlace(e);
} }
} }

View File

@ -27,10 +27,14 @@ import com.volmit.iris.core.pregenerator.PregenListener;
import com.volmit.iris.core.pregenerator.PregenTask; import com.volmit.iris.core.pregenerator.PregenTask;
import com.volmit.iris.engine.IrisEngineCompound; import com.volmit.iris.engine.IrisEngineCompound;
import com.volmit.iris.engine.data.B; import com.volmit.iris.engine.data.B;
import com.volmit.iris.engine.data.chunk.MCATerrainChunk;
import com.volmit.iris.engine.data.chunk.TerrainChunk; import com.volmit.iris.engine.data.chunk.TerrainChunk;
import com.volmit.iris.engine.data.mca.MCAUtil;
import com.volmit.iris.engine.data.mca.NBTWorld; import com.volmit.iris.engine.data.mca.NBTWorld;
import com.volmit.iris.engine.data.nbt.tag.CompoundTag;
import com.volmit.iris.engine.headless.HeadlessGenerator; import com.volmit.iris.engine.headless.HeadlessGenerator;
import com.volmit.iris.engine.hunk.Hunk; import com.volmit.iris.engine.hunk.Hunk;
import com.volmit.iris.engine.lighting.LightingChunk;
import com.volmit.iris.engine.object.IrisBiome; import com.volmit.iris.engine.object.IrisBiome;
import com.volmit.iris.engine.object.IrisDimension; import com.volmit.iris.engine.object.IrisDimension;
import com.volmit.iris.engine.object.IrisPosition; import com.volmit.iris.engine.object.IrisPosition;
@ -71,6 +75,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReference;
public class EngineCompositeGenerator extends ChunkGenerator implements IrisAccess { public class EngineCompositeGenerator extends ChunkGenerator implements IrisAccess {
private static final BlockData ERROR_BLOCK = Material.RED_GLAZED_TERRACOTTA.createBlockData();
private final AtomicReference<EngineCompound> compound = new AtomicReference<>(); private final AtomicReference<EngineCompound> compound = new AtomicReference<>();
private final AtomicBoolean initialized; private final AtomicBoolean initialized;
private final String dimensionQuery; private final String dimensionQuery;
@ -310,6 +315,11 @@ public class EngineCompositeGenerator extends ChunkGenerator implements IrisAcce
populators.addAll(compound.get().getPopulators()); populators.addAll(compound.get().getPopulators());
hotloader = new ReactiveFolder(data.getDataFolder(), (a, c, d) -> hotload()); hotloader = new ReactiveFolder(data.getDataFolder(), (a, c, d) -> hotload());
// if(world.hasRealWorld())
// {
// placeStrongholds(world.realWorld());
// }
if(isStudio()) if(isStudio())
{ {
dim.installDataPack(() -> data, Iris.instance.getDatapacksFolder()); dim.installDataPack(() -> data, Iris.instance.getDatapacksFolder());
@ -448,23 +458,46 @@ public class EngineCompositeGenerator extends ChunkGenerator implements IrisAcce
@NotNull @NotNull
@Override @Override
public ChunkData generateChunkData(@NotNull World world, @NotNull Random ignored, int x, int z, @NotNull BiomeGrid biome) { public ChunkData generateChunkData(@NotNull World world, @NotNull Random ignored, int x, int z, @NotNull BiomeGrid biome) {
PrecisionStopwatch ps = PrecisionStopwatch.start(); try
TerrainChunk tc = TerrainChunk.create(world, biome); {
IrisWorld ww = (getComposite() == null || getComposite().getWorld() == null) ? IrisWorld.fromWorld(world) : getComposite().getWorld(); PrecisionStopwatch ps = PrecisionStopwatch.start();
generateChunkRawData(ww, x, z, tc).run(); TerrainChunk tc = TerrainChunk.create(world, biome);
IrisWorld ww = (getComposite() == null || getComposite().getWorld() == null) ? IrisWorld.fromWorld(world) : getComposite().getWorld();
generateChunkRawData(ww, x, z, tc).run();
if (!getComposite().getWorld().hasRealWorld()) { if (!getComposite().getWorld().hasRealWorld()) {
getComposite().getWorld().bind(world); getComposite().getWorld().bind(world);
}
generated++;
ps.end();
if (IrisSettings.get().getGeneral().isDebug()) {
Iris.debug("Chunk " + C.GREEN + x + "," + z + C.LIGHT_PURPLE + " in " + C.YELLOW + Form.duration(ps.getMillis(), 2) + C.LIGHT_PURPLE + " Rate: " + C.BLUE + Form.f(getGeneratedPerSecond(), 0) + "/s");
}
return tc.getRaw();
} }
generated++; catch(Throwable e)
ps.end(); {
Iris.error("======================================");
e.printStackTrace();
Iris.reportErrorChunk(x, z, e, "CHUNK");
Iris.error("======================================");
if (IrisSettings.get().getGeneral().isDebug()) { ChunkData d = Bukkit.createChunkData(world);
Iris.debug("Chunk " + C.GREEN + x + "," + z + C.LIGHT_PURPLE + " in " + C.YELLOW + Form.duration(ps.getMillis(), 2) + C.LIGHT_PURPLE + " Rate: " + C.BLUE + Form.f(getGeneratedPerSecond(), 0) + "/s");
for(int i = 0; i < 16; i++)
{
for(int j = 0; j < 16; j++)
{
d.setBlock(i, 0, j, ERROR_BLOCK);
}
}
return d;
} }
return tc.getRaw();
} }
public void assignHeadlessGenerator(HeadlessGenerator headlessGenerator) { public void assignHeadlessGenerator(HeadlessGenerator headlessGenerator) {
@ -509,132 +542,34 @@ public class EngineCompositeGenerator extends ChunkGenerator implements IrisAcce
@Override @Override
public void directWriteChunk(IrisWorld w, int x, int z, NBTWorld writer) { public void directWriteChunk(IrisWorld w, int x, int z, NBTWorld writer) {
int ox = x << 4; try
int oz = z << 4; {int ox = x << 4;
com.volmit.iris.engine.data.mca.Chunk cc = writer.getChunk(x, z); int oz = z << 4;
BiomeBaseInjector injector = (xx, yy, zz, biomeBase) -> cc.setBiomeAt(ox + xx, yy, oz + zz, INMS.get().getTrueBiomeBaseId(biomeBase)); com.volmit.iris.engine.data.mca.Chunk chunk = writer.getChunk(x, z);
//noinspection deprecation generateChunkRawData(w, x, z, MCATerrainChunk.builder()
generateChunkRawData(w, x, z, new TerrainChunk() { .writer(writer).ox(ox).oz(oz).mcaChunk(chunk)
@Override .minHeight(w.minHeight()).maxHeight(w.maxHeight())
public BiomeBaseInjector getBiomeBaseInjector() { .injector((xx, yy, zz, biomeBase) -> chunk.setBiomeAt(ox + xx, yy, oz + zz,
return injector; INMS.get().getTrueBiomeBaseId(biomeBase)))
} .build()).run();
}
@Override catch(Throwable e)
public void setRaw(ChunkData data) { {
Iris.error("======================================");
} e.printStackTrace();
Iris.reportErrorChunk(x, z, e, "MCA");
@NotNull Iris.error("======================================");
@Override com.volmit.iris.engine.data.mca.Chunk chunk = writer.getChunk(x, z);
public Biome getBiome(int x, int z) { CompoundTag c = NBTWorld.getCompound(ERROR_BLOCK);
return Biome.THE_VOID; for(int i = 0; i < 16; i++)
} {
for(int j = 0; j < 16; j++)
@NotNull {
@Override chunk.setBlockStateAt(i, 0, j, c, false);
public Biome getBiome(int x, int y, int z) {
return Biome.THE_VOID;
}
@Override
public void setBiome(int x, int z, Biome bio) {
setBiome(ox + x, 0, oz + z, bio);
}
@Override
public void setBiome(int x, int y, int z, Biome bio) {
writer.setBiome(ox + x, y, oz + z, bio);
}
@Override
public int getMinHeight() {
return w.minHeight();
}
@Override
public int getMaxHeight() {
return w.maxHeight();
}
@Override
public void setBlock(int x, int y, int z, BlockData blockData) {
int xx = (x + ox) & 15;
int zz = (z + oz) & 15;
if (y > 255 || y < 0) {
return;
} }
cc.setBlockStateAt(xx, y, zz, NBTWorld.getCompound(blockData), false);
} }
}
@NotNull
@Override
public BlockData getBlockData(int x, int y, int z) {
if (y > getMaxHeight()) {
y = getMaxHeight();
}
if (y < 0) {
y = 0;
}
return NBTWorld.getBlockData(cc.getBlockStateAt((x + ox) & 15, y, (z + oz) & 15));
}
@Override
public ChunkData getRaw() {
return null;
}
@Override
public void inject(BiomeGrid biome) {
}
@Override
public void setBlock(int x, int y, int z, @NotNull Material material) {
}
@Override
public void setBlock(int x, int y, int z, @NotNull MaterialData material) {
}
@Override
public void setRegion(int xMin, int yMin, int zMin, int xMax, int yMax, int zMax, @NotNull Material material) {
}
@Override
public void setRegion(int xMin, int yMin, int zMin, int xMax, int yMax, int zMax, @NotNull MaterialData material) {
}
@Override
public void setRegion(int xMin, int yMin, int zMin, int xMax, int yMax, int zMax, @NotNull BlockData blockData) {
}
@NotNull
@Override
public Material getType(int x, int y, int z) {
return null;
}
@NotNull
@Override
public MaterialData getTypeAndData(int x, int y, int z) {
return null;
}
@Override
public byte getData(int x, int y, int z) {
return 0;
}
}).run();
} }
public Runnable generateChunkRawData(IrisWorld world, int x, int z, TerrainChunk tc) { public Runnable generateChunkRawData(IrisWorld world, int x, int z, TerrainChunk tc) {

View File

@ -37,13 +37,16 @@ import com.volmit.iris.engine.parallel.BurstExecutor;
import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.collection.KMap; import com.volmit.iris.util.collection.KMap;
import com.volmit.iris.util.collection.KSet; import com.volmit.iris.util.collection.KSet;
import com.volmit.iris.util.documentation.BlockCoordinates;
import com.volmit.iris.util.documentation.ChunkCoordinates; import com.volmit.iris.util.documentation.ChunkCoordinates;
import com.volmit.iris.util.format.Form; import com.volmit.iris.util.format.Form;
import com.volmit.iris.util.function.Consumer4; import com.volmit.iris.util.function.Consumer4;
import com.volmit.iris.util.math.Position2;
import com.volmit.iris.util.math.RNG; import com.volmit.iris.util.math.RNG;
import com.volmit.iris.util.scheduling.IrisLock; import com.volmit.iris.util.scheduling.IrisLock;
import com.volmit.iris.util.scheduling.J; import com.volmit.iris.util.scheduling.J;
import com.volmit.iris.util.scheduling.PrecisionStopwatch; import com.volmit.iris.util.scheduling.PrecisionStopwatch;
import io.lumine.xikage.mythicmobs.utils.serialize.ChunkPosition;
import org.bukkit.Chunk; import org.bukkit.Chunk;
import org.bukkit.ChunkSnapshot; import org.bukkit.ChunkSnapshot;
import org.bukkit.block.TileState; import org.bukkit.block.TileState;
@ -203,59 +206,57 @@ public interface EngineParallaxManager extends DataProvider, IObjectPlacer {
IrisLock getFeatureLock(); IrisLock getFeatureLock();
@BlockCoordinates
default void forEachFeature(double x, double z, Consumer<IrisFeaturePositional> f) { default void forEachFeature(double x, double z, Consumer<IrisFeaturePositional> f) {
if (!getEngine().getDimension().hasFeatures(getEngine())) { if (!getEngine().getDimension().hasFeatures(getEngine())) {
return; return;
} }
long key = Cache.key(((int) x) >> 4, ((int) z) >> 4); for (IrisFeaturePositional ipf : forEachFeature(x, z)) {
for (IrisFeaturePositional ipf : getFeatureCache().compute(key, (ke, v) -> {
if (v != null) {
return v;
}
getFeatureLock().lock();
KList<IrisFeaturePositional> pos = new KList<>();
for (IrisFeaturePositional i : getEngine().getDimension().getSpecificFeatures()) {
if (i.shouldFilter(x, z)) {
pos.add(i);
}
}
int s = (int) Math.ceil(getParallaxSize() / 2D);
int i, j;
int cx = (int) x >> 4;
int cz = (int) z >> 4;
for (i = -s; i <= s; i++) {
for (j = -s; j <= s; j++) {
ParallaxChunkMeta m = getParallaxAccess().getMetaR(i + cx, j + cz);
synchronized (m) {
try {
for (IrisFeaturePositional k : m.getFeatures()) {
if (k.shouldFilter(x, z)) {
pos.add(k);
}
}
} catch (Throwable e) {
Iris.error("FILTER ERROR" + " AT " + (cx + i) + " " + (j + cz));
e.printStackTrace();
Iris.reportError(e);
}
}
}
}
getFeatureLock().unlock();
return pos;
})) {
f.accept(ipf); f.accept(ipf);
} }
} }
@BlockCoordinates
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().getFramework().getComplex().getRng())) {
pos.add(i);
}
}
int s = (int) Math.ceil(getParallaxSize() / 2D);
int i, j;
int cx = (int) x >> 4;
int cz = (int) z >> 4;
for (i = -s; i <= s; i++) {
for (j = -s; j <= s; j++) {
ParallaxChunkMeta m = getParallaxAccess().getMetaR(i + cx, j + cz);
try {
for (IrisFeaturePositional k : m.getFeatures()) {
if (k.shouldFilter(x, z, getEngine().getFramework().getComplex().getRng())) {
pos.add(k);
}
}
} catch (Throwable e) {
Iris.error("FILTER ERROR" + " AT " + (cx + i) + " " + (j + cz));
e.printStackTrace();
Iris.reportError(e);
}
}
}
return pos;
}
@SuppressWarnings("SynchronizationOnLocalVariableOrMethodParameter") @SuppressWarnings("SynchronizationOnLocalVariableOrMethodParameter")
default void generateParallaxArea(int x, int z) { default void generateParallaxArea(int x, int z) {
if (!getEngine().getDimension().isPlaceObjects()) { if (!getEngine().getDimension().isPlaceObjects()) {
@ -277,8 +278,8 @@ public interface EngineParallaxManager extends DataProvider, IObjectPlacer {
int xxx = xx << 4; int xxx = xx << 4;
int zzz = zz << 4; int zzz = zz << 4;
if (!getParallaxAccess().isFeatureGenerated(xx, zz)) { if (!getParallaxAccess().isFeatureGenerated(xx, zz)) {
getParallaxAccess().setFeatureGenerated(xx, zz);
burst.queue(() -> { burst.queue(() -> {
getParallaxAccess().setFeatureGenerated(xx, zz);
RNG rng = new RNG(Cache.key(xx, zz)).nextParallelRNG(getEngine().getTarget().getWorld().seed()); RNG rng = new RNG(Cache.key(xx, zz)).nextParallelRNG(getEngine().getTarget().getWorld().seed());
IrisRegion region = getComplex().getRegionStream().get(xxx, zzz); IrisRegion region = getComplex().getRegionStream().get(xxx, zzz);
IrisBiome biome = getComplex().getTrueBiomeStream().get(xxx, zzz); IrisBiome biome = getComplex().getTrueBiomeStream().get(xxx, zzz);
@ -497,7 +498,7 @@ public interface EngineParallaxManager extends DataProvider, IObjectPlacer {
place(rng, x << 4, z << 4, i); place(rng, x << 4, z << 4, i);
} catch (Throwable e) { } catch (Throwable e) {
Iris.reportError(e); Iris.reportError(e);
Iris.error("Failed to place objects in the following biome: " + biome.getName()); Iris.error("Failed to place objects in the following region: " + region.getName());
Iris.error("Object(s) " + i.getPlace().toString(", ") + " (" + e.getClass().getSimpleName() + ")."); Iris.error("Object(s) " + i.getPlace().toString(", ") + " (" + e.getClass().getSimpleName() + ").");
Iris.error("Are these objects missing?"); Iris.error("Are these objects missing?");
e.printStackTrace(); e.printStackTrace();

View File

@ -30,6 +30,7 @@ import java.io.File;
@Data @Data
public class EngineTarget { public class EngineTarget {
private final MultiBurst parallaxBurster;
private final MultiBurst burster; private final MultiBurst burster;
private final IrisDimension dimension; private final IrisDimension dimension;
private IrisWorld world; private IrisWorld world;
@ -45,7 +46,8 @@ public class EngineTarget {
this.data = data; this.data = data;
this.inverted = inverted; this.inverted = inverted;
this.burster = new MultiBurst("Iris Engine " + dimension.getName(), IrisSettings.get().getConcurrency().getEngineThreadPriority(), threads); this.burster = new MultiBurst("Iris Engine " + dimension.getName(), IrisSettings.get().getConcurrency().getEngineThreadPriority(), threads);
this.parallaxWorld = new ParallaxWorld(burster, 256, new File(world.worldFolder(), "iris/" + dimension.getLoadKey() + "/parallax")); this.parallaxBurster = new MultiBurst("Iris Parallax Engine " + dimension.getName(), 3, 4);
this.parallaxWorld = new ParallaxWorld(parallaxBurster, 256, new File(world.worldFolder(), "iris/" + dimension.getLoadKey() + "/parallax"));
} }
public EngineTarget(IrisWorld world, IrisDimension dimension, IrisDataManager data, int height, int threads) { public EngineTarget(IrisWorld world, IrisDimension dimension, IrisDataManager data, int height, int threads) {
@ -53,6 +55,7 @@ public class EngineTarget {
} }
public void close() { public void close() {
parallaxBurster.shutdownAndAwait();
burster.shutdownAndAwait(); burster.shutdownAndAwait();
} }
} }

View File

@ -69,11 +69,13 @@ public class HeadlessWorld {
} }
public World load() { public World load() {
return new WorldCreator(worldName) World w = new WorldCreator(worldName)
.environment(dimension.getEnvironment()) .environment(dimension.getEnvironment())
.seed(world.seed()) .seed(world.seed())
.generator(new EngineCompositeGenerator(dimension.getLoadKey(), !studio)) .generator(new EngineCompositeGenerator(dimension.getLoadKey(), !studio))
.createWorld(); .createWorld();
world.realWorld(w);
return w;
} }
public static HeadlessWorld from(World world) { public static HeadlessWorld from(World world) {

View File

@ -377,7 +377,7 @@ public class PlannedStructure {
return false; return false;
} }
public synchronized IrisObject rotated(IrisJigsawPiece piece, IrisObjectRotation rotation) { public IrisObject rotated(IrisJigsawPiece piece, IrisObjectRotation rotation) {
String key = piece.getObject() + "-" + rotation.hashCode(); String key = piece.getObject() + "-" + rotation.hashCode();
if (objectRotationCache.containsKey(key)) { if (objectRotationCache.containsKey(key)) {

View File

@ -24,6 +24,7 @@ import com.bergerkiller.bukkit.common.wrappers.BlockData;
import com.bergerkiller.bukkit.common.wrappers.ChunkSection; import com.bergerkiller.bukkit.common.wrappers.ChunkSection;
import com.bergerkiller.generated.net.minecraft.server.NibbleArrayHandle; import com.bergerkiller.generated.net.minecraft.server.NibbleArrayHandle;
import com.volmit.iris.Iris; import com.volmit.iris.Iris;
import com.volmit.iris.util.data.NibbleArray;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;

View File

@ -23,15 +23,12 @@ import com.volmit.iris.engine.object.annotations.Desc;
@Desc("Defines if an object is allowed to place in carvings, surfaces or both.") @Desc("Defines if an object is allowed to place in carvings, surfaces or both.")
public enum CarvingMode { public enum CarvingMode {
@Desc("Only place this object on surfaces (NOT under carvings)") @Desc("Only place this object on surfaces (NOT under carvings)")
SURFACE_ONLY, SURFACE_ONLY,
@Desc("Only place this object under carvings (NOT on the surface)") @Desc("Only place this object under carvings (NOT on the surface)")
CARVING_ONLY, CARVING_ONLY,
@Desc("This object can place anywhere") @Desc("This object can place anywhere")
ANYWHERE; ANYWHERE;
@SuppressWarnings("BooleanMethodIsAlwaysInverted") @SuppressWarnings("BooleanMethodIsAlwaysInverted")

View File

@ -23,22 +23,17 @@ import com.volmit.iris.engine.object.annotations.Desc;
@Desc("Represents a location where decorations should go") @Desc("Represents a location where decorations should go")
public enum DecorationPart { public enum DecorationPart {
@Desc("The default, decorate anywhere") @Desc("The default, decorate anywhere")
NONE, NONE,
@Desc("Targets shore lines (typically for sugar cane)") @Desc("Targets shore lines (typically for sugar cane)")
SHORE_LINE, SHORE_LINE,
@Desc("Target sea surfaces (typically for lilypads)") @Desc("Target sea surfaces (typically for lilypads)")
SEA_SURFACE, SEA_SURFACE,
@Desc("Targets the sea floor (entire placement must be bellow sea level)") @Desc("Targets the sea floor (entire placement must be bellow sea level)")
SEA_FLOOR, SEA_FLOOR,
@Desc("Decorates on cave & carving ceilings or underside of overhangs") @Desc("Decorates on cave & carving ceilings or underside of overhangs")
CEILING, CEILING,
} }

View File

@ -23,14 +23,11 @@ import com.volmit.iris.engine.object.annotations.Desc;
@Desc("Represents a basic font style to apply to a font family") @Desc("Represents a basic font style to apply to a font family")
public enum FontStyle { public enum FontStyle {
@Desc("Plain old text") @Desc("Plain old text")
PLAIN, PLAIN,
@Desc("Italicized Text") @Desc("Italicized Text")
ITALIC, ITALIC,
@Desc("Bold Text") @Desc("Bold Text")
BOLD, BOLD,
} }

View File

@ -23,23 +23,18 @@ import com.volmit.iris.engine.object.annotations.Desc;
@Desc("Represents a biome type") @Desc("Represents a biome type")
public enum InferredType { public enum InferredType {
@Desc("Represents any shore biome type") @Desc("Represents any shore biome type")
SHORE, SHORE,
@Desc("Represents any land biome type") @Desc("Represents any land biome type")
LAND, LAND,
@Desc("Represents any sea biome type") @Desc("Represents any sea biome type")
SEA, SEA,
@Desc("Represents any cave biome type") @Desc("Represents any cave biome type")
CAVE, CAVE,
@Desc("Represents any river biome type") @Desc("Represents any river biome type")
RIVER, RIVER,
@Desc("Represents any lake biome type") @Desc("Represents any lake biome type")

View File

@ -23,22 +23,16 @@ import com.volmit.iris.engine.object.annotations.Desc;
@Desc("An inventory slot type is used to represent a type of slot for items to fit into in any given inventory.") @Desc("An inventory slot type is used to represent a type of slot for items to fit into in any given inventory.")
public enum InventorySlotType { public enum InventorySlotType {
@Desc("Typically the one you want to go with. Storage represnents most slots in inventories.") @Desc("Typically the one you want to go with. Storage represnents most slots in inventories.")
STORAGE, STORAGE,
@Desc("Used for the fuel slot in Furnaces, Blast furnaces, smokers etc.") @Desc("Used for the fuel slot in Furnaces, Blast furnaces, smokers etc.")
FUEL, FUEL,
@Desc("Used for the cook slot in furnaces") @Desc("Used for the cook slot in furnaces")
FURNACE, FURNACE,
@Desc("Used for the cook slot in blast furnaces") @Desc("Used for the cook slot in blast furnaces")
BLAST_FURNACE, BLAST_FURNACE,
@Desc("Used for the cook slot in smokers") @Desc("Used for the cook slot in smokers")
SMOKER, SMOKER,
} }

View File

@ -40,14 +40,11 @@ import org.bukkit.inventory.meta.ItemMeta;
@Data @Data
public class IrisAttributeModifier { public class IrisAttributeModifier {
@Required @Required
@Desc("The Attribute type. This type is pulled from the game attributes. Zombie & Horse attributes will not work on non-zombie/horse entities.\nUsing an attribute on an item will have affects when held, or worn. There is no way to specify further granularity as the game picks this depending on the item type.") @Desc("The Attribute type. This type is pulled from the game attributes. Zombie & Horse attributes will not work on non-zombie/horse entities.\nUsing an attribute on an item will have affects when held, or worn. There is no way to specify further granularity as the game picks this depending on the item type.")
private Attribute attribute = null; private Attribute attribute = null;
@MinNumber(2) @MinNumber(2)
@Required @Required
@Desc("The Attribute Name is used internally only for the game. This value should be unique to all other attributes applied to this item/entity. It is not shown in game.") @Desc("The Attribute Name is used internally only for the game. This value should be unique to all other attributes applied to this item/entity. It is not shown in game.")
private String name = ""; private String name = "";

View File

@ -31,7 +31,6 @@ import lombok.experimental.Accessors;
@Desc("Represents a rotation axis with intervals and maxes. The x and z axis values are defaulted to disabled. The Y axis defaults to on, rotating by 90 degree increments.") @Desc("Represents a rotation axis with intervals and maxes. The x and z axis values are defaulted to disabled. The Y axis defaults to on, rotating by 90 degree increments.")
@Data @Data
public class IrisAxisRotationClamp { public class IrisAxisRotationClamp {
@Desc("Should this axis be rotated at all?") @Desc("Should this axis be rotated at all?")
private boolean enabled = false; private boolean enabled = false;
private transient boolean forceLock = false; private transient boolean forceLock = false;

View File

@ -57,26 +57,21 @@ import java.awt.*;
public class IrisBiome extends IrisRegistrant implements IRare { public class IrisBiome extends IrisRegistrant implements IRare {
@MinNumber(2) @MinNumber(2)
@Required @Required
@Desc("This is the human readable name for this biome. This can and should be different than the file name. This is not used for loading biomes in other objects.") @Desc("This is the human readable name for this biome. This can and should be different than the file name. This is not used for loading biomes in other objects.")
private String name = "A Biome"; private String name = "A Biome";
@ArrayType(min = 1, type = IrisBiomeCustom.class) @ArrayType(min = 1, type = IrisBiomeCustom.class)
@Desc("If the biome type custom is defined, specify this") @Desc("If the biome type custom is defined, specify this")
private KList<IrisBiomeCustom> customDerivitives; private KList<IrisBiomeCustom> customDerivitives;
@Desc("Entity spawns to override or add to this biome. Anytime an entity spawns, it has a chance to be replaced as one of these overrides.") @Desc("Entity spawns to override or add to this biome. Anytime an entity spawns, it has a chance to be replaced as one of these overrides.")
@ArrayType(min = 1, type = IrisEntitySpawnOverride.class) @ArrayType(min = 1, type = IrisEntitySpawnOverride.class)
private KList<IrisEntitySpawnOverride> entitySpawnOverrides = new KList<>(); private KList<IrisEntitySpawnOverride> entitySpawnOverrides = new KList<>();
@Desc("Add random chances for terrain features") @Desc("Add random chances for terrain features")
@ArrayType(min = 1, type = IrisFeaturePotential.class) @ArrayType(min = 1, type = IrisFeaturePotential.class)
private KList<IrisFeaturePotential> features = new KList<>(); private KList<IrisFeaturePotential> features = new KList<>();
@Desc("Entity spawns during generation") @Desc("Entity spawns during generation")
@ArrayType(min = 1, type = IrisEntityInitialSpawn.class) @ArrayType(min = 1, type = IrisEntityInitialSpawn.class)
private KList<IrisEntityInitialSpawn> entityInitialSpawns = new KList<>(); private KList<IrisEntityInitialSpawn> entityInitialSpawns = new KList<>();
@ -85,7 +80,6 @@ public class IrisBiome extends IrisRegistrant implements IRare {
@Desc("Effects are ambient effects such as potion effects, random sounds, or even particles around each player. All of these effects are played via packets so two players won't see/hear each others effects.\nDue to performance reasons, effects will play around the player even if where the effect was played is no longer in the biome the player is in.") @Desc("Effects are ambient effects such as potion effects, random sounds, or even particles around each player. All of these effects are played via packets so two players won't see/hear each others effects.\nDue to performance reasons, effects will play around the player even if where the effect was played is no longer in the biome the player is in.")
private KList<IrisEffect> effects = new KList<>(); private KList<IrisEffect> effects = new KList<>();
@DependsOn({"biomeStyle", "biomeZoom", "biomeScatter"}) @DependsOn({"biomeStyle", "biomeZoom", "biomeScatter"})
@Desc("This changes the dispersion of the biome colors if multiple derivatives are chosen.") @Desc("This changes the dispersion of the biome colors if multiple derivatives are chosen.")
private IrisGeneratorStyle biomeStyle = NoiseStyle.SIMPLEX.style(); private IrisGeneratorStyle biomeStyle = NoiseStyle.SIMPLEX.style();
@ -94,21 +88,17 @@ public class IrisBiome extends IrisRegistrant implements IRare {
@Desc("Define custom block drops for this biome") @Desc("Define custom block drops for this biome")
private KList<IrisBlockDrops> blockDrops = new KList<>(); private KList<IrisBlockDrops> blockDrops = new KList<>();
@Desc("Reference loot tables in this area") @Desc("Reference loot tables in this area")
private IrisLootReference loot = new IrisLootReference(); private IrisLootReference loot = new IrisLootReference();
@MinNumber(0.0001) @MinNumber(0.0001)
@DependsOn({"biomeStyle", "biomeZoom", "biomeScatter"}) @DependsOn({"biomeStyle", "biomeZoom", "biomeScatter"})
@Desc("This zooms in the biome colors if multiple derivatives are chosen") @Desc("This zooms in the biome colors if multiple derivatives are chosen")
private double biomeZoom = 1; private double biomeZoom = 1;
@Desc("Layers no longer descend from the surface block, they descend from the max possible height the biome can produce (constant) creating mesa like layers.") @Desc("Layers no longer descend from the surface block, they descend from the max possible height the biome can produce (constant) creating mesa like layers.")
private boolean lockLayers = false; private boolean lockLayers = false;
@Desc("The max layers to iterate below the surface for locked layer biomes (mesa).") @Desc("The max layers to iterate below the surface for locked layer biomes (mesa).")
private int lockLayersMax = 7; private int lockLayersMax = 7;
@ -117,17 +107,14 @@ public class IrisBiome extends IrisRegistrant implements IRare {
@Desc("The rarity of this biome (integer)") @Desc("The rarity of this biome (integer)")
private int rarity = 1; private int rarity = 1;
@Desc("A color for visualizing this biome with a color. I.e. #F13AF5. This will show up on the map.") @Desc("A color for visualizing this biome with a color. I.e. #F13AF5. This will show up on the map.")
private String color = null; private String color = null;
@Required @Required
@Desc("The raw derivative of this biome. This is required or the terrain will not properly generate. Use any vanilla biome type. Look in examples/biome-list.txt") @Desc("The raw derivative of this biome. This is required or the terrain will not properly generate. Use any vanilla biome type. Look in examples/biome-list.txt")
private Biome derivative = Biome.THE_VOID; private Biome derivative = Biome.THE_VOID;
@Required @Required
@Desc("Override the derivative when vanilla places structures to this derivative. This is useful for example if you have an ocean biome, but you have set the derivative to desert to get a brown-ish color. To prevent desert structures from spawning on top of your ocean, you can set your vanillaDerivative to ocean, to allow for vanilla structures. Not defining this value will simply select the derivative.") @Desc("Override the derivative when vanilla places structures to this derivative. This is useful for example if you have an ocean biome, but you have set the derivative to desert to get a brown-ish color. To prevent desert structures from spawning on top of your ocean, you can set your vanillaDerivative to ocean, to allow for vanilla structures. Not defining this value will simply select the derivative.")
private Biome vanillaDerivative = null; private Biome vanillaDerivative = null;
@ -139,12 +126,10 @@ public class IrisBiome extends IrisRegistrant implements IRare {
@Desc("Since 1.13 supports 3D biomes, you can add different derivative colors for anything above the terrain. (Think swampy tree leaves with a desert looking grass surface)") @Desc("Since 1.13 supports 3D biomes, you can add different derivative colors for anything above the terrain. (Think swampy tree leaves with a desert looking grass surface)")
private KList<Biome> biomeSkyScatter = new KList<>(); private KList<Biome> biomeSkyScatter = new KList<>();
@DependsOn({"children"}) @DependsOn({"children"})
@Desc("If this biome has children biomes, and the gen layer chooses one of this biomes children, how much smaller will it be (inside of this biome). Higher values means a smaller biome relative to this biome's size. Set higher than 1.0 and below 3.0 for best results.") @Desc("If this biome has children biomes, and the gen layer chooses one of this biomes children, how much smaller will it be (inside of this biome). Higher values means a smaller biome relative to this biome's size. Set higher than 1.0 and below 3.0 for best results.")
private double childShrinkFactor = 1.5; private double childShrinkFactor = 1.5;
@DependsOn({"children"}) @DependsOn({"children"})
@Desc("If this biome has children biomes, and the gen layer chooses one of this biomes children, How will it be shaped?") @Desc("If this biome has children biomes, and the gen layer chooses one of this biomes children, How will it be shaped?")
private IrisGeneratorStyle childStyle = NoiseStyle.CELLULAR_IRIS_DOUBLE.style(); private IrisGeneratorStyle childStyle = NoiseStyle.CELLULAR_IRIS_DOUBLE.style();
@ -159,15 +144,12 @@ public class IrisBiome extends IrisRegistrant implements IRare {
private KList<IrisJigsawStructurePlacement> jigsawStructures = new KList<>(); private KList<IrisJigsawStructurePlacement> jigsawStructures = new KList<>();
@RegistryListBiome @RegistryListBiome
@Desc("The carving biome. If specified the biome will be used when under a carving instead of this current biome.") @Desc("The carving biome. If specified the biome will be used when under a carving instead of this current biome.")
private String carvingBiome = ""; private String carvingBiome = "";
@Desc("The default slab if iris decides to place a slab in this biome. Default is no slab.") @Desc("The default slab if iris decides to place a slab in this biome. Default is no slab.")
private IrisBiomePaletteLayer slab = new IrisBiomePaletteLayer().zero(); private IrisBiomePaletteLayer slab = new IrisBiomePaletteLayer().zero();
@Desc("The default wall if iris decides to place a wall higher than 2 blocks (steep hills or possibly cliffs)") @Desc("The default wall if iris decides to place a wall higher than 2 blocks (steep hills or possibly cliffs)")
private IrisBiomePaletteLayer wall = new IrisBiomePaletteLayer().zero(); private IrisBiomePaletteLayer wall = new IrisBiomePaletteLayer().zero();

View File

@ -63,6 +63,7 @@ public class IrisBiomeCustom {
@Desc("Define an ambient particle to be rendered clientside (no server cost!)") @Desc("Define an ambient particle to be rendered clientside (no server cost!)")
private IrisBiomeCustomParticle ambientParticle = null; private IrisBiomeCustomParticle ambientParticle = null;
@Required
@Desc("The biome's category type") @Desc("The biome's category type")
private IrisBiomeCustomCategory category = IrisBiomeCustomCategory.plains; private IrisBiomeCustomCategory category = IrisBiomeCustomCategory.plains;

View File

@ -23,14 +23,11 @@ import com.volmit.iris.engine.object.annotations.Desc;
@Desc("Snow, rain, or nothing") @Desc("Snow, rain, or nothing")
public enum IrisBiomeCustomPrecipType { public enum IrisBiomeCustomPrecipType {
@Desc("No downfall") @Desc("No downfall")
none, none,
@Desc("Rain downfall") @Desc("Rain downfall")
rain, rain,
@Desc("Snow downfall") @Desc("Snow downfall")
snow snow
} }

View File

@ -22,11 +22,24 @@ import com.volmit.iris.engine.object.annotations.Desc;
@Desc("The mob spawn group") @Desc("The mob spawn group")
public enum IrisBiomeCustomSpawnType { public enum IrisBiomeCustomSpawnType {
@Desc("Typical monsters that spawn at night, like zombies and skeletons")
MONSTER, MONSTER,
@Desc("Typical creatures like sheep, pigs, cows")
CREATURE, CREATURE,
@Desc("Eg bats")
AMBIENT, AMBIENT,
@Desc("Odd spawn group but ok")
UNDERGROUND_WATER_CREATURE, UNDERGROUND_WATER_CREATURE,
@Desc("Water mobs like squid, dolphins")
WATER_CREATURE, WATER_CREATURE,
@Desc("Fish")
WATER_AMBIENT, WATER_AMBIENT,
@Desc("Unknown")
MISC MISC
} }

View File

@ -35,7 +35,6 @@ import lombok.experimental.Accessors;
public class IrisBiomeGeneratorLink { public class IrisBiomeGeneratorLink {
@RegistryListGenerator @RegistryListGenerator
@Desc("The generator id") @Desc("The generator id")
private String generator = "default"; private String generator = "default";
@ -43,7 +42,6 @@ public class IrisBiomeGeneratorLink {
@Required @Required
@MinNumber(-256) // TODO: WARNING HEIGHT @MinNumber(-256) // TODO: WARNING HEIGHT
@MaxNumber(256) // TODO: WARNING HEIGHT @MaxNumber(256) // TODO: WARNING HEIGHT
@Desc("The min block value (value + fluidHeight)") @Desc("The min block value (value + fluidHeight)")
private int min = 0; private int min = 0;
@ -51,7 +49,6 @@ public class IrisBiomeGeneratorLink {
@Required @Required
@MinNumber(-256) // TODO: WARNING HEIGHT @MinNumber(-256) // TODO: WARNING HEIGHT
@MaxNumber(256) // TODO: WARNING HEIGHT @MaxNumber(256) // TODO: WARNING HEIGHT
@Desc("The max block value (value + fluidHeight)") @Desc("The max block value (value + fluidHeight)")
private int max = 0; private int max = 0;

View File

@ -34,7 +34,6 @@ import lombok.experimental.Accessors;
@Desc("A biome mutation if a condition is met") @Desc("A biome mutation if a condition is met")
@Data @Data
public class IrisBiomeMutation { public class IrisBiomeMutation {
@RegistryListBiome @RegistryListBiome
@Required @Required
@ArrayType(min = 1, type = String.class) @ArrayType(min = 1, type = String.class)

View File

@ -36,7 +36,6 @@ import org.bukkit.block.data.BlockData;
@Desc("A layer of surface / subsurface material in biomes") @Desc("A layer of surface / subsurface material in biomes")
@Data @Data
public class IrisBiomePaletteLayer { public class IrisBiomePaletteLayer {
@Desc("The style of noise") @Desc("The style of noise")
private IrisGeneratorStyle style = NoiseStyle.STATIC.style(); private IrisGeneratorStyle style = NoiseStyle.STATIC.style();

View File

@ -44,15 +44,12 @@ import java.util.Map;
public class IrisBlockData extends IrisRegistrant { public class IrisBlockData extends IrisRegistrant {
@RegistryListBlockType @RegistryListBlockType
@Required @Required
@Desc("The block to use") @Desc("The block to use")
private String block = "air"; private String block = "air";
@Desc("Debug this block by printing it to the console when it's used") @Desc("Debug this block by printing it to the console when it's used. Must have debug turned on in settings.")
private boolean debug = false; private boolean debug = false;
@Desc("The resource key. Typically Minecraft") @Desc("The resource key. Typically Minecraft")
private String key = "minecraft"; private String key = "minecraft";
@ -61,11 +58,9 @@ public class IrisBlockData extends IrisRegistrant {
@Desc("The weight is used when this block data is inside of a list of blockdata. A weight of two is just as if you placed two of the same block data values in the same list making it more common when randomly picked.") @Desc("The weight is used when this block data is inside of a list of blockdata. A weight of two is just as if you placed two of the same block data values in the same list making it more common when randomly picked.")
private int weight = 1; private int weight = 1;
@Desc("If the block cannot be created on this version, Iris will attempt to use this backup block data instead.") @Desc("If the block cannot be created on this version, Iris will attempt to use this backup block data instead.")
private IrisBlockData backup = null; private IrisBlockData backup = null;
@Desc("Optional properties for this block data such as 'waterlogged': true") @Desc("Optional properties for this block data such as 'waterlogged': true")
private KMap<String, Object> data = new KMap<>(); private KMap<String, Object> data = new KMap<>();
@ -122,7 +117,7 @@ public class IrisBlockData extends IrisRegistrant {
String sx = getKey() + ":" + st.split("\\Q:\\E")[1] + computeProperties(cdata); String sx = getKey() + ":" + st.split("\\Q:\\E")[1] + computeProperties(cdata);
if (debug) { if (debug) {
Iris.warn("Debug block data " + sx + " (CUSTOM)"); Iris.debug("Block Data used " + sx + " (CUSTOM)");
} }
BlockData bx = B.get(sx); BlockData bx = B.get(sx);
@ -141,7 +136,7 @@ public class IrisBlockData extends IrisRegistrant {
b = B.get(ss); b = B.get(ss);
if (debug) { if (debug) {
Iris.warn("Debug block data " + ss); Iris.debug("Block Data used " + ss);
} }
if (b != null) { if (b != null) {

View File

@ -43,20 +43,16 @@ public class IrisBlockDrops {
@Desc("The blocks that drop loot") @Desc("The blocks that drop loot")
private KList<IrisBlockData> blocks = new KList<>(); private KList<IrisBlockData> blocks = new KList<>();
@Desc("If exact blocks is set to true, minecraft:barrel[axis=x] will only drop for that axis. When exact is false (default) any barrel will drop the defined drops.") @Desc("If exact blocks is set to true, minecraft:barrel[axis=x] will only drop for that axis. When exact is false (default) any barrel will drop the defined drops.")
private boolean exactBlocks = false; private boolean exactBlocks = false;
@Desc("Add in specific items to drop") @Desc("Add in specific items to drop")
@ArrayType(min = 1, type = IrisLoot.class) @ArrayType(min = 1, type = IrisLoot.class)
private KList<IrisLoot> drops = new KList<>(); private KList<IrisLoot> drops = new KList<>();
@Desc("If this is in a biome, setting skipParents to true will ignore the drops in the region and dimension for this block type. The default (false) will allow all three nodes to fire and add to a list of drops.") @Desc("If this is in a biome, setting skipParents to true will ignore the drops in the region and dimension for this block type. The default (false) will allow all three nodes to fire and add to a list of drops.")
private boolean skipParents = false; private boolean skipParents = false;
@Desc("Removes the default vanilla block drops and only drops the given items & any parent loot tables specified for this block type.") @Desc("Removes the default vanilla block drops and only drops the given items & any parent loot tables specified for this block type.")
private boolean replaceVanillaDrops = false; private boolean replaceVanillaDrops = false;

View File

@ -39,7 +39,6 @@ import lombok.experimental.Accessors;
@Data @Data
public class IrisCarveLayer { public class IrisCarveLayer {
@Required @Required
@Desc("The 4d slope this carve layer follows") @Desc("The 4d slope this carve layer follows")
private IrisGeneratorStyle style = new IrisGeneratorStyle(); private IrisGeneratorStyle style = new IrisGeneratorStyle();

View File

@ -43,12 +43,10 @@ public class IrisCaveFluid {
@Desc("The fluid height of the cave") @Desc("The fluid height of the cave")
private int fluidHeight = 35; 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.") @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; private boolean inverseHeight = false;
@Required @Required
@Desc("The fluid type that should spawn here") @Desc("The fluid type that should spawn here")
private IrisBlockData fluidType = new IrisBlockData("CAVE_AIR"); private IrisBlockData fluidType = new IrisBlockData("CAVE_AIR");

View File

@ -33,16 +33,13 @@ import lombok.experimental.Accessors;
@Data @Data
public class IrisCaveLayer { public class IrisCaveLayer {
@Required @Required
@Desc("The vertical slope this cave layer follows") @Desc("The vertical slope this cave layer follows")
private IrisShapedGeneratorStyle verticalSlope = new IrisShapedGeneratorStyle(); private IrisShapedGeneratorStyle verticalSlope = new IrisShapedGeneratorStyle();
@Required @Required
@Desc("The horizontal slope this cave layer follows") @Desc("The horizontal slope this cave layer follows")
private IrisShapedGeneratorStyle horizontalSlope = new IrisShapedGeneratorStyle(); private IrisShapedGeneratorStyle horizontalSlope = new IrisShapedGeneratorStyle();
@Desc("If defined, a cave fluid will fill this cave below (or above) the specified fluidHeight in this object.") @Desc("If defined, a cave fluid will fill this cave below (or above) the specified fluidHeight in this object.")
private IrisCaveFluid fluid = new IrisCaveFluid(); private IrisCaveFluid fluid = new IrisCaveFluid();
@ -54,7 +51,6 @@ public class IrisCaveLayer {
@Desc("The cave thickness.") @Desc("The cave thickness.")
private double caveThickness = 1D; private double caveThickness = 1D;
@Desc("If set to true, this cave layer can break the surface") @Desc("If set to true, this cave layer can break the surface")
private boolean canBreakSurface = false; private boolean canBreakSurface = false;

View File

@ -29,31 +29,26 @@ import lombok.experimental.Accessors;
import java.awt.*; import java.awt.*;
@Deprecated()
@Accessors(chain = true) @Accessors(chain = true)
@NoArgsConstructor @NoArgsConstructor
@Desc("Represents a color") @Desc("Represents a color")
@Data @Data
public class IrisColor { public class IrisColor {
@MaxNumber(7) @MaxNumber(7)
@MinNumber(6) @MinNumber(6)
@Desc("Pass in a 6 digit hexadecimal color to fill R G and B values. You can also include the # symbol, but it's not required.") @Desc("Pass in a 6 digit hexadecimal color to fill R G and B values. You can also include the # symbol, but it's not required.")
private String hex = null; private String hex = null;
@MaxNumber(255) @MaxNumber(255)
@MinNumber(0) @MinNumber(0)
@Desc("Represents the red channel. Only define this if you are not defining the hex value.") @Desc("Represents the red channel. Only define this if you are not defining the hex value.")
private int red = 0; private int red = 0;
@MaxNumber(255) @MaxNumber(255)
@MinNumber(0) @MinNumber(0)
@Desc("Represents the green channel. Only define this if you are not defining the hex value.") @Desc("Represents the green channel. Only define this if you are not defining the hex value.")
private int green = 0; private int green = 0;
@MaxNumber(255) @MaxNumber(255)
@MinNumber(0) @MinNumber(0)
@Desc("Represents the blue channel. Only define this if you are not defining the hex value.") @Desc("Represents the blue channel. Only define this if you are not defining the hex value.")

View File

@ -36,16 +36,13 @@ import org.bukkit.block.data.BlockData;
@Data @Data
public class IrisCompatabilityBlockFilter { public class IrisCompatabilityBlockFilter {
@Required @Required
@Desc("When iris sees this block, and it's not reconized") @Desc("When iris sees this block, and it's not reconized")
private String when = ""; private String when = "";
@Required @Required
@Desc("Replace it with this block. Dont worry if this block is also not reconized, iris repeat this compat check.") @Desc("Replace it with this block. Dont worry if this block is also not reconized, iris repeat this compat check.")
private String supplement = ""; private String supplement = "";
@Desc("If exact is true, it compares block data for example minecraft:some_log[axis=x]") @Desc("If exact is true, it compares block data for example minecraft:some_log[axis=x]")
private boolean exact = false; private boolean exact = false;

View File

@ -34,12 +34,10 @@ import org.bukkit.Material;
@Data @Data
public class IrisCompatabilityItemFilter { public class IrisCompatabilityItemFilter {
@Required @Required
@Desc("When iris sees this block, and it's not reconized") @Desc("When iris sees this block, and it's not reconized")
private String when = ""; private String when = "";
@Required @Required
@Desc("Replace it with this block. Dont worry if this block is also not reconized, iris repeat this compat check.") @Desc("Replace it with this block. Dont worry if this block is also not reconized, iris repeat this compat check.")
private String supplement = ""; private String supplement = "";

View File

@ -37,15 +37,12 @@ import org.bukkit.block.data.BlockData;
@Desc("A biome decorator is used for placing flowers, grass, cacti and so on") @Desc("A biome decorator is used for placing flowers, grass, cacti and so on")
@Data @Data
public class IrisDecorator { public class IrisDecorator {
@Desc("The varience dispersion is used when multiple blocks are put in the palette. Scatter scrambles them, Wispy shows streak-looking varience") @Desc("The varience dispersion is used when multiple blocks are put in the palette. Scatter scrambles them, Wispy shows streak-looking varience")
private IrisGeneratorStyle variance = NoiseStyle.STATIC.style(); private IrisGeneratorStyle variance = NoiseStyle.STATIC.style();
@Desc("Forcefully place this decorant anywhere it is supposed to go even if it should not go on a specific surface block. For example, you could force tallgrass to place on top of stone by using this.") @Desc("Forcefully place this decorant anywhere it is supposed to go even if it should not go on a specific surface block. For example, you could force tallgrass to place on top of stone by using this.")
private boolean forcePlace = false; private boolean forcePlace = false;
@Desc("Dispersion is used to pick places to spawn. Scatter randomly places them (vanilla) or Wispy for a streak like patch system.") @Desc("Dispersion is used to pick places to spawn. Scatter randomly places them (vanilla) or Wispy for a streak like patch system.")
private IrisGeneratorStyle style = NoiseStyle.STATIC.style(); private IrisGeneratorStyle style = NoiseStyle.STATIC.style();
@ -53,7 +50,6 @@ public class IrisDecorator {
@Desc("If this decorator has a height more than 1 this changes how it picks the height between your maxes. Scatter = random, Wispy = wavy heights") @Desc("If this decorator has a height more than 1 this changes how it picks the height between your maxes. Scatter = random, Wispy = wavy heights")
private IrisGeneratorStyle heightVariance = NoiseStyle.STATIC.style(); private IrisGeneratorStyle heightVariance = NoiseStyle.STATIC.style();
@Desc("Tells iris where this decoration is a part of. I.e. SHORE_LINE or SEA_SURFACE") @Desc("Tells iris where this decoration is a part of. I.e. SHORE_LINE or SEA_SURFACE")
private DecorationPart partOf = DecorationPart.NONE; private DecorationPart partOf = DecorationPart.NONE;

View File

@ -39,14 +39,12 @@ public class IrisDepositGenerator {
@Required @Required
@MinNumber(0) @MinNumber(0)
@MaxNumber(256) // TODO: WARNING HEIGHT @MaxNumber(256) // TODO: WARNING HEIGHT
@Desc("The minimum height this deposit can generate at") @Desc("The minimum height this deposit can generate at")
private int minHeight = 7; private int minHeight = 7;
@Required @Required
@MinNumber(0) @MinNumber(0)
@MaxNumber(256) // TODO: WARNING HEIGHT @MaxNumber(256) // TODO: WARNING HEIGHT
@Desc("The maximum height this deposit can generate at") @Desc("The maximum height this deposit can generate at")
private int maxHeight = 55; private int maxHeight = 55;

View File

@ -53,7 +53,6 @@ public class IrisDimension extends IrisRegistrant {
@MinNumber(2) @MinNumber(2)
@Required @Required
@Desc("The human readable name of this dimension") @Desc("The human readable name of this dimension")
private String name = "A Dimension"; private String name = "A Dimension";
@ -61,10 +60,6 @@ public class IrisDimension extends IrisRegistrant {
@ArrayType(min = 1, type = IrisDimensionIndex.class) @ArrayType(min = 1, type = IrisDimensionIndex.class)
private KList<IrisDimensionIndex> dimensionalComposite = new KList<>(); private KList<IrisDimensionIndex> dimensionalComposite = new KList<>();
@ArrayType(min = 1, type = IrisObjectPlacement.class)
@Desc("Objects define what schematics (iob files) iris will place in this biome. ONLY FOR SAPLINGS UNTIL FURTHER NOTICE!")
private KList<IrisObjectPlacement> objects = new KList<>();
@Desc("Create an inverted dimension in the sky (like the nether)") @Desc("Create an inverted dimension in the sky (like the nether)")
private IrisDimension sky = null; private IrisDimension sky = null;
@ -72,7 +67,6 @@ public class IrisDimension extends IrisRegistrant {
@Desc("If defined, Iris will place the given jigsaw structure where minecraft should place the overworld stronghold.") @Desc("If defined, Iris will place the given jigsaw structure where minecraft should place the overworld stronghold.")
private String stronghold; private String stronghold;
@Desc("Improves the biome grid variation by shuffling the cell grid more depending on the seed. This makes biomes across multiple seeds look far different than before.") @Desc("Improves the biome grid variation by shuffling the cell grid more depending on the seed. This makes biomes across multiple seeds look far different than before.")
private boolean aggressiveBiomeReshuffle = false; private boolean aggressiveBiomeReshuffle = false;
@ -83,31 +77,25 @@ public class IrisDimension extends IrisRegistrant {
@Desc("Instead of a flat bottom, applies a clamp (using this noise style) to the bottom instead of a flat bottom. Useful for carving out center-dimensions in a dimension composite world.") @Desc("Instead of a flat bottom, applies a clamp (using this noise style) to the bottom instead of a flat bottom. Useful for carving out center-dimensions in a dimension composite world.")
private IrisShapedGeneratorStyle undercarriage = null; private IrisShapedGeneratorStyle undercarriage = null;
@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.") @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 = ""; private String resourcePack = "";
@Desc("Entity spawns to override or add to this dimension") @Desc("Entity spawns to override or add to this dimension")
@ArrayType(min = 1, type = IrisEntitySpawnOverride.class) @ArrayType(min = 1, type = IrisEntitySpawnOverride.class)
private KList<IrisEntitySpawnOverride> entitySpawnOverrides = new KList<>(); private KList<IrisEntitySpawnOverride> entitySpawnOverrides = new KList<>();
@Desc("Add specific features in exact positions") @Desc("Add specific features in exact positions")
@ArrayType(min = 1, type = IrisFeaturePositional.class) @ArrayType(min = 1, type = IrisFeaturePositional.class)
private KList<IrisFeaturePositional> specificFeatures = new KList<>(); private KList<IrisFeaturePositional> specificFeatures = new KList<>();
@Desc("Entity spawns during generation") @Desc("Entity spawns during generation")
@ArrayType(min = 1, type = IrisEntityInitialSpawn.class) @ArrayType(min = 1, type = IrisEntityInitialSpawn.class)
private KList<IrisEntityInitialSpawn> entityInitialSpawns = new KList<>(); private KList<IrisEntityInitialSpawn> entityInitialSpawns = new KList<>();
@Desc("Add random chances for terrain features") @Desc("Add random chances for terrain features")
@ArrayType(min = 1, type = IrisFeaturePotential.class) @ArrayType(min = 1, type = IrisFeaturePotential.class)
private KList<IrisFeaturePotential> features = new KList<>(); private KList<IrisFeaturePotential> features = new KList<>();
@Desc("Reference loot tables in this area") @Desc("Reference loot tables in this area")
private IrisLootReference loot = new IrisLootReference(); private IrisLootReference loot = new IrisLootReference();
@ -119,7 +107,6 @@ public class IrisDimension extends IrisRegistrant {
@Desc("Define custom block drops for this dimension") @Desc("Define custom block drops for this dimension")
private KList<IrisBlockDrops> blockDrops = new KList<>(); private KList<IrisBlockDrops> blockDrops = new KList<>();
@Desc("Should bedrock be generated or not.") @Desc("Should bedrock be generated or not.")
private boolean bedrock = true; private boolean bedrock = true;
@ -128,71 +115,54 @@ public class IrisDimension extends IrisRegistrant {
@Desc("The land chance. Up to 1.0 for total land or 0.0 for total sea") @Desc("The land chance. Up to 1.0 for total land or 0.0 for total sea")
private double landChance = 0.625; private double landChance = 0.625;
@Desc("The placement style of regions") @Desc("The placement style of regions")
private IrisGeneratorStyle regionStyle = NoiseStyle.CELLULAR_IRIS_DOUBLE.style(); private IrisGeneratorStyle regionStyle = NoiseStyle.CELLULAR_IRIS_DOUBLE.style();
@Desc("The placement style of land/sea") @Desc("The placement style of land/sea")
private IrisGeneratorStyle continentalStyle = NoiseStyle.CELLULAR_IRIS_DOUBLE.style(); private IrisGeneratorStyle continentalStyle = NoiseStyle.CELLULAR_IRIS_DOUBLE.style();
@Desc("The placement style of biomes") @Desc("The placement style of biomes")
private IrisGeneratorStyle landBiomeStyle = NoiseStyle.CELLULAR_IRIS_DOUBLE.style(); private IrisGeneratorStyle landBiomeStyle = NoiseStyle.CELLULAR_IRIS_DOUBLE.style();
@Desc("The placement style of biomes") @Desc("The placement style of biomes")
private IrisGeneratorStyle shoreBiomeStyle = NoiseStyle.CELLULAR_IRIS_DOUBLE.style(); private IrisGeneratorStyle shoreBiomeStyle = NoiseStyle.CELLULAR_IRIS_DOUBLE.style();
@Desc("The placement style of biomes") @Desc("The placement style of biomes")
private IrisGeneratorStyle seaBiomeStyle = NoiseStyle.CELLULAR_IRIS_DOUBLE.style(); private IrisGeneratorStyle seaBiomeStyle = NoiseStyle.CELLULAR_IRIS_DOUBLE.style();
@Desc("The placement style of biomes") @Desc("The placement style of biomes")
private IrisGeneratorStyle caveBiomeStyle = NoiseStyle.CELLULAR_IRIS_DOUBLE.style(); private IrisGeneratorStyle caveBiomeStyle = NoiseStyle.CELLULAR_IRIS_DOUBLE.style();
@Desc("The placement style of biomes") @Desc("The placement style of biomes")
private IrisGeneratorStyle riverBiomeStyle = NoiseStyle.CELLULAR_IRIS_DOUBLE.style(); private IrisGeneratorStyle riverBiomeStyle = NoiseStyle.CELLULAR_IRIS_DOUBLE.style();
@Desc("The placement style of biomes") @Desc("The placement style of biomes")
private IrisGeneratorStyle lakeBiomeStyle = NoiseStyle.CELLULAR_IRIS_DOUBLE.style(); private IrisGeneratorStyle lakeBiomeStyle = NoiseStyle.CELLULAR_IRIS_DOUBLE.style();
@Desc("The placement style of biomes") @Desc("The placement style of biomes")
private IrisGeneratorStyle islandBiomeStyle = NoiseStyle.CELLULAR_IRIS_DOUBLE.style(); private IrisGeneratorStyle islandBiomeStyle = NoiseStyle.CELLULAR_IRIS_DOUBLE.style();
@Desc("The placement style of biomes") @Desc("The placement style of biomes")
private IrisGeneratorStyle islandBiomeChanceStyle = NoiseStyle.CELLULAR_HEIGHT_IRIS_DOUBLE.style(); private IrisGeneratorStyle islandBiomeChanceStyle = NoiseStyle.CELLULAR_HEIGHT_IRIS_DOUBLE.style();
@Desc("The placement style of biomes") @Desc("The placement style of biomes")
private IrisGeneratorStyle skylandBiomeStyle = NoiseStyle.CELLULAR_IRIS_DOUBLE.style(); private IrisGeneratorStyle skylandBiomeStyle = NoiseStyle.CELLULAR_IRIS_DOUBLE.style();
@Desc("Generate caves or not.") @Desc("Generate caves or not.")
private boolean caves = true; private boolean caves = true;
@Desc("Instead of filling objects with air, fills them with cobweb so you can see them") @Desc("Instead of filling objects with air, fills them with cobweb so you can see them")
private boolean debugSmartBore = false; private boolean debugSmartBore = false;
@Desc("Carve terrain or not") @Desc("Carve terrain or not")
private boolean carving = true; private boolean carving = true;
@Desc("If defined, If air is defined below the area, this fluid will always place") @Desc("If defined, If air is defined below the area, this fluid will always place")
private IrisCaveFluid forceFluid = new IrisCaveFluid(); private IrisCaveFluid forceFluid = new IrisCaveFluid();
@Desc("Generate decorations or not") @Desc("Generate decorations or not")
private boolean decorate = true; private boolean decorate = true;
@Desc("Generate ravines or not") @Desc("Generate ravines or not")
private boolean ravines = false; private boolean ravines = false;
@ -204,23 +174,18 @@ public class IrisDimension extends IrisRegistrant {
@Desc("The rarity of ravines. Each chunk has a 1 in X chance") @Desc("The rarity of ravines. Each chunk has a 1 in X chance")
private int ravineRarity = 50; private int ravineRarity = 50;
@Desc("Use post processing or not") @Desc("Use post processing or not")
private boolean postProcessing = true; private boolean postProcessing = true;
@Desc("Add slabs in post processing") @Desc("Add slabs in post processing")
private boolean postProcessingSlabs = true; private boolean postProcessingSlabs = true;
@Desc("Add painted walls in post processing") @Desc("Add painted walls in post processing")
private boolean postProcessingWalls = true; private boolean postProcessingWalls = true;
@Desc("Use post processing for caves or not") @Desc("Use post processing for caves or not")
private boolean postProcessCaves = true; private boolean postProcessCaves = true;
@Desc("The world environment") @Desc("The world environment")
private Environment environment = Environment.NORMAL; private Environment environment = Environment.NORMAL;
@ -241,12 +206,10 @@ public class IrisDimension extends IrisRegistrant {
private int fluidHeight = 63; private int fluidHeight = 63;
@RegistryListBiome @RegistryListBiome
@Desc("Keep this either undefined or empty. Setting any biome name into this will force iris to only generate the specified biome. Great for testing.") @Desc("Keep this either undefined or empty. Setting any biome name into this will force iris to only generate the specified biome. Great for testing.")
private String focus = ""; private String focus = "";
@RegistryListBiome @RegistryListBiome
@Desc("Keep this either undefined or empty. Setting any region name into this will force iris to only generate the specified region. Great for testing.") @Desc("Keep this either undefined or empty. Setting any region name into this will force iris to only generate the specified region. Great for testing.")
private String focusRegion = ""; private String focusRegion = "";
@ -304,7 +267,6 @@ public class IrisDimension extends IrisRegistrant {
@Desc("Disable this to stop placing schematics in biomes") @Desc("Disable this to stop placing schematics in biomes")
private boolean placeObjects = true; private boolean placeObjects = true;
@Desc("Prevent Leaf decay as if placed in creative mode") @Desc("Prevent Leaf decay as if placed in creative mode")
private boolean preventLeafDecay = false; private boolean preventLeafDecay = false;
@ -329,11 +291,9 @@ public class IrisDimension extends IrisRegistrant {
@Desc("The rock zoom mostly for zooming in on a wispy palette") @Desc("The rock zoom mostly for zooming in on a wispy palette")
private double rockZoom = 5; private double rockZoom = 5;
@Desc("The palette of blocks for 'stone'") @Desc("The palette of blocks for 'stone'")
private IrisMaterialPalette rockPalette = new IrisMaterialPalette().qclear().qadd("stone"); private IrisMaterialPalette rockPalette = new IrisMaterialPalette().qclear().qadd("stone");
@Desc("The palette of blocks for 'water'") @Desc("The palette of blocks for 'water'")
private IrisMaterialPalette fluidPalette = new IrisMaterialPalette().qclear().qadd("water"); private IrisMaterialPalette fluidPalette = new IrisMaterialPalette().qclear().qadd("water");
@ -420,17 +380,7 @@ public class IrisDimension extends IrisRegistrant {
} }
public KList<IrisBiome> getAllBiomes(DataProvider g) { public KList<IrisBiome> getAllBiomes(DataProvider g) {
KList<IrisBiome> r = new KList<>(); return g.getData().getBiomeLoader().loadAll(g.getData().getBiomeLoader().getPossibleKeys());
for (IrisRegion i : getAllRegions(g)) {
if (i == null) {
continue;
}
r.addAll(i.getAllBiomes(g));
}
return r;
} }
public KList<IrisBiome> getAllAnyBiomes() { public KList<IrisBiome> getAllAnyBiomes() {

View File

@ -37,19 +37,15 @@ import lombok.experimental.Accessors;
@EqualsAndHashCode(callSuper = false) @EqualsAndHashCode(callSuper = false)
public class IrisDimensionIndex { public class IrisDimensionIndex {
@Required @Required
@Desc("The weight of this dimension. If there are 2 dimensions, if the weight is the same on both, both dimensions will take up 128 blocks of height.") @Desc("The weight of this dimension. If there are 2 dimensions, if the weight is the same on both, both dimensions will take up 128 blocks of height.")
private double weight = 1D; private double weight = 1D;
@Desc("If inverted is set to true, the dimension will be updide down in the world") @Desc("If inverted is set to true, the dimension will be updide down in the world")
private boolean inverted = false; private boolean inverted = false;
@Desc("Only one dimension layer should be set to primary. The primary dimension layer is where players spawn, and the biomes that the vanilla structure system uses to figure out what structures to place.") @Desc("Only one dimension layer should be set to primary. The primary dimension layer is where players spawn, and the biomes that the vanilla structure system uses to figure out what structures to place.")
private boolean primary = false; private boolean primary = false;
@Required @Required
@RegistryListDimension @RegistryListDimension
@MinNumber(1) @MinNumber(1)

View File

@ -39,11 +39,17 @@ import java.util.Map;
*/ */
@Desc("A direction object") @Desc("A direction object")
public enum IrisDirection { public enum IrisDirection {
@Desc("0, 1, 0")
UP_POSITIVE_Y(0, 1, 0, CuboidDirection.Up), UP_POSITIVE_Y(0, 1, 0, CuboidDirection.Up),
@Desc("0, -1, 0")
DOWN_NEGATIVE_Y(0, -1, 0, CuboidDirection.Down), DOWN_NEGATIVE_Y(0, -1, 0, CuboidDirection.Down),
@Desc("0, 0, -1")
NORTH_NEGATIVE_Z(0, 0, -1, CuboidDirection.North), NORTH_NEGATIVE_Z(0, 0, -1, CuboidDirection.North),
@Desc("0, 0, 1")
SOUTH_POSITIVE_Z(0, 0, 1, CuboidDirection.South), SOUTH_POSITIVE_Z(0, 0, 1, CuboidDirection.South),
@Desc("1, 0, 0")
EAST_POSITIVE_X(1, 0, 0, CuboidDirection.East), EAST_POSITIVE_X(1, 0, 0, CuboidDirection.East),
@Desc("-1, 0, 0")
WEST_NEGATIVE_X(-1, 0, 0, CuboidDirection.West); WEST_NEGATIVE_X(-1, 0, 0, CuboidDirection.West);
private static KMap<GBiset<IrisDirection, IrisDirection>, DOP> permute = null; private static KMap<GBiset<IrisDirection, IrisDirection>, DOP> permute = null;

View File

@ -42,12 +42,9 @@ import org.bukkit.potion.PotionEffectType;
@Desc("An iris effect") @Desc("An iris effect")
@Data @Data
public class IrisEffect { public class IrisEffect {
@Desc("The potion effect to apply in this area") @Desc("The potion effect to apply in this area")
private String potionEffect = ""; private String potionEffect = "";
@Desc("The particle effect to apply in the area") @Desc("The particle effect to apply in the area")
private Particle particleEffect = null; private Particle particleEffect = null;
@ -87,7 +84,6 @@ public class IrisEffect {
@Desc("Randomize the altZ by -altZ to altZ") @Desc("Randomize the altZ by -altZ to altZ")
private boolean randomAltZ = true; private boolean randomAltZ = true;
@Desc("The sound to play") @Desc("The sound to play")
private Sound sound = null; private Sound sound = null;

View File

@ -40,9 +40,7 @@ import java.lang.reflect.Field;
@Desc("Represents an enchantment & level") @Desc("Represents an enchantment & level")
@Data @Data
public class IrisEnchantment { public class IrisEnchantment {
@Required @Required
@Desc("The enchantment") @Desc("The enchantment")
private String enchantment = ""; private String enchantment = "";

View File

@ -60,106 +60,81 @@ import java.util.concurrent.atomic.AtomicReference;
@EqualsAndHashCode(callSuper = false) @EqualsAndHashCode(callSuper = false)
public class IrisEntity extends IrisRegistrant { public class IrisEntity extends IrisRegistrant {
@Required @Required
@Desc("The type of entity to spawn. To spawn a mythic mob, set this type to unknown and define mythic type.") @Desc("The type of entity to spawn. To spawn a mythic mob, set this type to unknown and define mythic type.")
private EntityType type = EntityType.UNKNOWN; private EntityType type = EntityType.UNKNOWN;
@RegistryListMythical @RegistryListMythical
@Desc("The type of mythic mob (if mythic mobs is installed). If this is set, make sure to set 'type' to UNKNOWN") @Desc("The type of mythic mob (if mythic mobs is installed). If this is set, make sure to set 'type' to UNKNOWN")
private String mythicalType = ""; private String mythicalType = "";
@Desc("The custom name of this entity") @Desc("The custom name of this entity")
private String customName = ""; private String customName = "";
@Desc("Should the name on this entity be visible even if you arent looking at it.") @Desc("Should the name on this entity be visible even if you arent looking at it.")
private boolean customNameVisible = false; private boolean customNameVisible = false;
@Desc("If this entity type is a mob, should it be aware of it's surroundings & interact with the world.") @Desc("If this entity type is a mob, should it be aware of it's surroundings & interact with the world.")
private boolean aware = true; private boolean aware = true;
@Desc("If this entity type is a creature, should it have ai goals.") @Desc("If this entity type is a creature, should it have ai goals.")
private boolean ai = true; private boolean ai = true;
@Desc("Should this entity be glowing") @Desc("Should this entity be glowing")
private boolean glowing = false; private boolean glowing = false;
@Desc("Should gravity apply to this entity") @Desc("Should gravity apply to this entity")
private boolean gravity = true; private boolean gravity = true;
@Desc("When an entity is invulnerable it can only be damaged by players increative mode.") @Desc("When an entity is invulnerable it can only be damaged by players increative mode.")
private boolean invulnerable = false; private boolean invulnerable = false;
@Desc("When an entity is silent it will not produce any sound.") @Desc("When an entity is silent it will not produce any sound.")
private boolean silent = false; private boolean silent = false;
@Desc("Should this entity be allowed to pickup items") @Desc("Should this entity be allowed to pickup items")
private boolean pickupItems = false; private boolean pickupItems = false;
@Desc("Should this entity be removed when far away") @Desc("Should this entity be removed when far away")
private boolean removable = true; private boolean removable = true;
@Desc("Entity helmet equipment") @Desc("Entity helmet equipment")
private IrisLoot helmet = null; private IrisLoot helmet = null;
@Desc("Entity chestplate equipment") @Desc("Entity chestplate equipment")
private IrisLoot chestplate = null; private IrisLoot chestplate = null;
@Desc("Entity boots equipment") @Desc("Entity boots equipment")
private IrisLoot boots = null; private IrisLoot boots = null;
@Desc("Entity leggings equipment") @Desc("Entity leggings equipment")
private IrisLoot leggings = null; private IrisLoot leggings = null;
@Desc("Entity main hand equipment") @Desc("Entity main hand equipment")
private IrisLoot mainHand = null; private IrisLoot mainHand = null;
@Desc("Entity off hand equipment") @Desc("Entity off hand equipment")
private IrisLoot offHand = null; private IrisLoot offHand = null;
@Desc("Make other entities ride this entity") @Desc("Make other entities ride this entity")
@ArrayType(min = 1, type = IrisEntity.class) @ArrayType(min = 1, type = IrisEntity.class)
private KList<IrisEntity> passengers = new KList<>(); private KList<IrisEntity> passengers = new KList<>();
@Desc("Attribute modifiers for this entity") @Desc("Attribute modifiers for this entity")
@ArrayType(min = 1, type = IrisAttributeModifier.class) @ArrayType(min = 1, type = IrisAttributeModifier.class)
private KList<IrisAttributeModifier> attributes = new KList<>(); private KList<IrisAttributeModifier> attributes = new KList<>();
@Desc("Loot tables for drops") @Desc("Loot tables for drops")
private IrisLootReference loot = new IrisLootReference(); private IrisLootReference loot = new IrisLootReference();
@Desc("If specified, this entity will be leashed by this entity. I.e. THIS ENTITY Leashed by SPECIFIED. This has no effect on EnderDragons, Withers, Players, or Bats.Non-living entities excluding leashes will not persist as leashholders.") @Desc("If specified, this entity will be leashed by this entity. I.e. THIS ENTITY Leashed by SPECIFIED. This has no effect on EnderDragons, Withers, Players, or Bats.Non-living entities excluding leashes will not persist as leashholders.")
private IrisEntity leashHolder = null; private IrisEntity leashHolder = null;
@Desc("The main gene for a panda if the entity type is a panda") @Desc("The main gene for a panda if the entity type is a panda")
private Gene pandaMainGene = Gene.NORMAL; private Gene pandaMainGene = Gene.NORMAL;
@Desc("The hidden gene for a panda if the entity type is a panda") @Desc("The hidden gene for a panda if the entity type is a panda")
private Gene pandaHiddenGene = Gene.NORMAL; private Gene pandaHiddenGene = Gene.NORMAL;
@Desc("The this entity is ageable, set it's baby status") @Desc("The this entity is ageable, set it's baby status")
private boolean baby = false; private boolean baby = false;

View File

@ -41,7 +41,6 @@ import org.bukkit.entity.Entity;
public class IrisEntityInitialSpawn { public class IrisEntityInitialSpawn {
@RegistryListEntity @RegistryListEntity
@Required @Required
@Desc("The entity") @Desc("The entity")
private String entity = ""; private String entity = "";

View File

@ -40,24 +40,18 @@ import org.bukkit.event.entity.EntitySpawnEvent;
@Desc("Represents an entity spawn") @Desc("Represents an entity spawn")
@Data @Data
public class IrisEntitySpawnOverride { public class IrisEntitySpawnOverride {
@RegistryListEntity @RegistryListEntity
@Required @Required
@Desc("The entity") @Desc("The entity")
private String entity = ""; private String entity = "";
@Required @Required
@Desc("If the following entity type spawns, spawn this entity. Set to unknown for any entity spawn") @Desc("If the following entity type spawns, spawn this entity. Set to unknown for any entity spawn")
private EntityType trigger = EntityType.UNKNOWN; private EntityType trigger = EntityType.UNKNOWN;
@Desc("If the source is triggered, cancel spawning the original entity instead of ADDING a new entity.") @Desc("If the source is triggered, cancel spawning the original entity instead of ADDING a new entity.")
private boolean cancelSourceSpawn = false; private boolean cancelSourceSpawn = false;
@MinNumber(1) @MinNumber(1)
@Desc("The 1 in RARITY chance for this entity to spawn") @Desc("The 1 in RARITY chance for this entity to spawn")
private int rarity = 1; private int rarity = 1;

View File

@ -22,10 +22,7 @@ import com.google.gson.Gson;
import com.volmit.iris.engine.cache.AtomicCache; import com.volmit.iris.engine.cache.AtomicCache;
import com.volmit.iris.engine.interpolation.InterpolationMethod; import com.volmit.iris.engine.interpolation.InterpolationMethod;
import com.volmit.iris.engine.interpolation.IrisInterpolation; import com.volmit.iris.engine.interpolation.IrisInterpolation;
import com.volmit.iris.engine.object.annotations.Desc; import com.volmit.iris.engine.object.annotations.*;
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 lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
@ -41,64 +38,62 @@ import java.io.IOException;
@Desc("Represents an Iris zone") @Desc("Represents an Iris zone")
public class IrisFeature { public class IrisFeature {
@Required @Required
@Desc("The block radius of this zone") @Desc("The block radius of this zone")
private double blockRadius = 32; private double blockRadius = 32;
@MinNumber(0) @MinNumber(0)
@MaxNumber(1) @MaxNumber(1)
@Required
@Desc("The chance an object that should be place actually will place. Set to below 1 to affect objects in this zone") @Desc("The chance an object that should be place actually will place. Set to below 1 to affect objects in this zone")
private double objectChance = 1; private double objectChance = 1;
@Required @RegistryListBiome
@Desc("Apply a custom biome here")
private String customBiome = null;
@MinNumber(0)
@MaxNumber(1)
@Desc("How much strength before the biome is applied.")
private double biomeStrengthThreshold = 0.75;
@Desc("The interpolation radius of this zone") @Desc("The interpolation radius of this zone")
private double interpolationRadius = 7; private double interpolationRadius = 7;
@Required
@MaxNumber(1) @MaxNumber(1)
@MinNumber(0) @MinNumber(0)
@Desc("The strength of this effect") @Desc("The strength of this effect")
private double strength = 0.75; private double strength = 1;
@Required
@Desc("The interpolator to use for smoothing the strength") @Desc("The interpolator to use for smoothing the strength")
private InterpolationMethod interpolator = InterpolationMethod.BILINEAR_STARCAST_9; private InterpolationMethod interpolator = InterpolationMethod.BILINEAR_STARCAST_9;
@Required
@Desc("If set, this will shift the terrain height in blocks (up or down)") @Desc("If set, this will shift the terrain height in blocks (up or down)")
private double shiftHeight = 0; private double shiftHeight = 0;
@Required
@Desc("If set, this will force the terrain closer to the specified height.") @Desc("If set, this will force the terrain closer to the specified height.")
private double convergeToHeight = -1; private double convergeToHeight = -1;
@Required
@Desc("Multiplies the input noise") @Desc("Multiplies the input noise")
private double multiplyHeight = 1; private double multiplyHeight = 1;
@Required
@Desc("Invert the zone so that anything outside this zone is affected.") @Desc("Invert the zone so that anything outside this zone is affected.")
private boolean invertZone = false; private boolean invertZone = false;
@Required @Desc("Fracture the radius ring with additional noise")
private IrisGeneratorStyle fractureRadius = null;
@Desc("Add additional noise to this spot")
private IrisGeneratorStyle addNoise = NoiseStyle.FLAT.style();
private transient AtomicCache<Double> actualRadius = new AtomicCache<>(); private transient AtomicCache<Double> actualRadius = new AtomicCache<>();
public double getActualRadius() { public double getActualRadius() {
return actualRadius.aquire(() -> IrisInterpolation.getRealRadius(getInterpolator(), getInterpolationRadius())); return actualRadius.aquire(() -> {
double o = 0;
if(fractureRadius != null)
{
o+=fractureRadius.getMaxFractureDistance();
}
return o + IrisInterpolation.getRealRadius(getInterpolator(), getInterpolationRadius());
});
} }
public static IrisFeature read(DataInputStream s) throws IOException { public static IrisFeature read(DataInputStream s) throws IOException {

View File

@ -22,9 +22,12 @@ import com.google.gson.Gson;
import com.volmit.iris.engine.cache.AtomicCache; import com.volmit.iris.engine.cache.AtomicCache;
import com.volmit.iris.engine.interpolation.IrisInterpolation; import com.volmit.iris.engine.interpolation.IrisInterpolation;
import com.volmit.iris.engine.object.annotations.Desc; 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.annotations.Required;
import com.volmit.iris.util.function.NoiseProvider; import com.volmit.iris.util.function.NoiseProvider;
import com.volmit.iris.util.math.M; import com.volmit.iris.util.math.M;
import com.volmit.iris.util.math.RNG;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
@ -44,17 +47,14 @@ public class IrisFeaturePositional {
} }
@Required @Required
@Desc("The x coordinate of this zone") @Desc("The x coordinate of this zone")
private int x; private int x;
@Required @Required
@Desc("The z coordinate of this zone") @Desc("The z coordinate of this zone")
private int z; private int z;
@Required @Required
@Desc("The Terrain Feature to apply") @Desc("The Terrain Feature to apply")
private IrisFeature feature; private IrisFeature feature;
@ -69,9 +69,9 @@ public class IrisFeaturePositional {
s.writeUTF(new Gson().toJson(this)); s.writeUTF(new Gson().toJson(this));
} }
public boolean shouldFilter(double x, double z) { public boolean shouldFilter(double x, double z, RNG rng) {
double actualRadius = getFeature().getActualRadius(); double actualRadius = getFeature().getActualRadius();
double dist2 = distance2(x, z); double dist2 = distance2(x, z, rng);
if (getFeature().isInvertZone()) { if (getFeature().isInvertZone()) {
if (dist2 < Math.pow(getFeature().getBlockRadius() - actualRadius, 2)) { if (dist2 < Math.pow(getFeature().getBlockRadius() - actualRadius, 2)) {
@ -82,16 +82,16 @@ public class IrisFeaturePositional {
return !(dist2 > Math.pow(getFeature().getBlockRadius() + actualRadius, 2)); return !(dist2 > Math.pow(getFeature().getBlockRadius() + actualRadius, 2));
} }
public double getStrength(double x, double z) { public double getStrength(double x, double z, RNG rng) {
double actualRadius = getFeature().getActualRadius(); double actualRadius = getFeature().getActualRadius();
double dist2 = distance2(x, z); double dist2 = distance2(x, z, rng);
if (getFeature().isInvertZone()) { if (getFeature().isInvertZone()) {
if (dist2 < Math.pow(getFeature().getBlockRadius() - actualRadius, 2)) { if (dist2 < Math.pow(getFeature().getBlockRadius() - actualRadius, 2)) {
return 0; return 0;
} }
NoiseProvider d = provider.aquire(this::getNoiseProvider); NoiseProvider d = provider.aquire(() -> getNoiseProvider(rng));
double s = IrisInterpolation.getNoise(getFeature().getInterpolator(), (int) x, (int) z, getFeature().getInterpolationRadius(), d); double s = IrisInterpolation.getNoise(getFeature().getInterpolator(), (int) x, (int) z, getFeature().getInterpolationRadius(), d);
if (s <= 0) { if (s <= 0) {
@ -104,7 +104,7 @@ public class IrisFeaturePositional {
return 0; return 0;
} }
NoiseProvider d = provider.aquire(this::getNoiseProvider); NoiseProvider d = provider.aquire(() -> getNoiseProvider(rng));
double s = IrisInterpolation.getNoise(getFeature().getInterpolator(), (int) x, (int) z, getFeature().getInterpolationRadius(), d); double s = IrisInterpolation.getNoise(getFeature().getInterpolator(), (int) x, (int) z, getFeature().getInterpolationRadius(), d);
if (s <= 0) { if (s <= 0) {
@ -115,16 +115,31 @@ public class IrisFeaturePositional {
} }
} }
public double getObjectChanceModifier(double x, double z) { public double getObjectChanceModifier(double x, double z, RNG rng) {
if (getFeature().getObjectChance() >= 1) { if (getFeature().getObjectChance() >= 1) {
return getFeature().getObjectChance(); return getFeature().getObjectChance();
} }
return M.lerp(1, getFeature().getObjectChance(), getStrength(x, z)); return M.lerp(1, getFeature().getObjectChance(), getStrength(x, z, rng));
} }
public double filter(double x, double z, double noise) { public IrisBiome filter(double x, double z, IrisBiome biome, RNG rng)
double s = getStrength(x, z); {
if(getFeature().getCustomBiome() != null)
{
if(getStrength(x, z, rng) >= getFeature().getBiomeStrengthThreshold())
{
IrisBiome b = biome.getLoader().getBiomeLoader().load(getFeature().getCustomBiome());
b.setInferredType(biome.getInferredType());
return b;
}
}
return null;
}
public double filter(double x, double z, double noise, RNG rng) {
double s = getStrength(x, z, rng);
if (s <= 0) { if (s <= 0) {
return noise; return noise;
@ -142,19 +157,24 @@ public class IrisFeaturePositional {
return M.lerp(noise, fx, s); return M.lerp(noise, fx, s);
} }
public double distance(double x, double z) { public double distance(double x, double z, RNG rng) {
return Math.sqrt(Math.pow(this.x - x, 2) + Math.pow(this.z - z, 2)); double mul = getFeature().getFractureRadius() != null ? getFeature().getFractureRadius().getMultiplier()/2 : 1;
double mod = getFeature().getFractureRadius() != null ? getFeature().getFractureRadius().create(rng).fitDouble(-mul, mul, x, z) : 0;
return Math.sqrt(Math.pow(this.x - (x + mod), 2) + Math.pow(this.z - (z + mod), 2));
} }
public double distance2(double x, double z) { public double distance2(double x, double z, RNG rng) {
return Math.pow(this.x - x, 2) + Math.pow(this.z - z, 2); double mul = getFeature().getFractureRadius() != null ? getFeature().getFractureRadius().getMultiplier()/2 : 1;
double mod = getFeature().getFractureRadius() != null ? getFeature().getFractureRadius().create(rng).fitDouble(-mul, mul, x, z) : 0;
return Math.pow(this.x - (x+mod), 2) + Math.pow(this.z - (z+mod), 2);
} }
private NoiseProvider getNoiseProvider() { private NoiseProvider getNoiseProvider(RNG rng) {
if (getFeature().isInvertZone()) { if (getFeature().isInvertZone()) {
return (x, z) -> distance(x, z) > getFeature().getBlockRadius() ? 1D : 0D; return (x, z) -> distance(x, z, rng) > getFeature().getBlockRadius() ? 1D : 0D;
} else { } else {
return (x, z) -> distance(x, z) < getFeature().getBlockRadius() ? 1D : 0D; return (x, z) -> distance(x, z, rng) < getFeature().getBlockRadius() ? 1D : 0D;
} }
} }
} }

View File

@ -28,15 +28,12 @@ import lombok.Data;
@Desc("Represents a potential Iris zone") @Desc("Represents a potential Iris zone")
public class IrisFeaturePotential { public class IrisFeaturePotential {
@MinNumber(0) @MinNumber(0)
@Required @Required
@Desc("The rarity is 1 in X chance per chunk") @Desc("The rarity is 1 in X chance per chunk")
private int rarity = 100; private int rarity = 100;
@Required @Required
@Desc("") @Desc("")
private IrisFeature zone = new IrisFeature(); private IrisFeature zone = new IrisFeature();

View File

@ -50,7 +50,6 @@ public class IrisGenerator extends IrisRegistrant {
@Desc("The opacity, essentially a multiplier on the output.") @Desc("The opacity, essentially a multiplier on the output.")
private double opacity = 1; private double opacity = 1;
@Desc("Multiply the compsites instead of adding them") @Desc("Multiply the compsites instead of adding them")
private boolean multiplicitive = false; private boolean multiplicitive = false;
@ -62,7 +61,6 @@ public class IrisGenerator extends IrisRegistrant {
@Desc("Cell Fracture Coordinate Shuffling") @Desc("Cell Fracture Coordinate Shuffling")
private double cellFractureShuffle = 12D; private double cellFractureShuffle = 12D;
@Desc("The height of fracture cells. Set to 0 to disable") @Desc("The height of fracture cells. Set to 0 to disable")
private double cellFractureHeight = 0D; private double cellFractureHeight = 0D;
@ -71,21 +69,17 @@ public class IrisGenerator extends IrisRegistrant {
@Desc("How big are the cells (X,Z) relative to the veins that touch them. Between 0 and 1. 0.1 means thick veins, small cells.") @Desc("How big are the cells (X,Z) relative to the veins that touch them. Between 0 and 1. 0.1 means thick veins, small cells.")
private double cellPercentSize = 0.75D; private double cellPercentSize = 0.75D;
@Desc("The offset to shift this noise x") @Desc("The offset to shift this noise x")
private double offsetX = 0; private double offsetX = 0;
@Desc("The offset to shift this noise z") @Desc("The offset to shift this noise z")
private double offsetZ = 0; private double offsetZ = 0;
@Required @Required
@Desc("The seed for this generator") @Desc("The seed for this generator")
private long seed = 1; private long seed = 1;
@Required @Required
@Desc("The interpolator to use when smoothing this generator into other regions & generators") @Desc("The interpolator to use when smoothing this generator into other regions & generators")
private IrisInterpolator interpolator = new IrisInterpolator(); private IrisInterpolator interpolator = new IrisInterpolator();
@ -103,7 +97,6 @@ public class IrisGenerator extends IrisRegistrant {
@Desc("The list of noise gens this gen contains.") @Desc("The list of noise gens this gen contains.")
private KList<IrisNoiseGenerator> composite = new KList<>(); private KList<IrisNoiseGenerator> composite = new KList<>();
@Desc("The noise gen for cliff height.") @Desc("The noise gen for cliff height.")
private IrisNoiseGenerator cliffHeightGenerator = new IrisNoiseGenerator(); private IrisNoiseGenerator cliffHeightGenerator = new IrisNoiseGenerator();
@ -227,12 +220,11 @@ public class IrisGenerator extends IrisRegistrant {
} }
int hc = (int) ((cliffHeightMin * 10) + 10 + cliffHeightMax * seed + offsetX + offsetZ); int hc = (int) ((cliffHeightMin * 10) + 10 + cliffHeightMax * seed + offsetX + offsetZ);
double h = 0; double h = multiplicitive ? 1 : 0;
double tp = multiplicitive ? 1 : 0; double tp = 0;
for (IrisNoiseGenerator i : composite) { for (IrisNoiseGenerator i : composite) {
if (multiplicitive) { if (multiplicitive) {
tp *= i.getOpacity();
h *= i.getNoise(seed + superSeed + hc, (rx + offsetX) / zoom, (rz + offsetZ) / zoom); h *= i.getNoise(seed + superSeed + hc, (rx + offsetX) / zoom, (rz + offsetZ) / zoom);
} else { } else {
tp += i.getOpacity(); tp += i.getOpacity();

View File

@ -36,7 +36,6 @@ import lombok.experimental.Accessors;
@Desc("A gen style") @Desc("A gen style")
@Data @Data
public class IrisGeneratorStyle { public class IrisGeneratorStyle {
@Required @Required
@Desc("The chance is 1 in CHANCE per interval") @Desc("The chance is 1 in CHANCE per interval")
private NoiseStyle style = NoiseStyle.IRIS; private NoiseStyle style = NoiseStyle.IRIS;
@ -89,4 +88,8 @@ public class IrisGeneratorStyle {
public boolean isFlat() { public boolean isFlat() {
return style.equals(NoiseStyle.FLAT); return style.equals(NoiseStyle.FLAT);
} }
public double getMaxFractureDistance() {
return multiplier;
}
} }

View File

@ -36,9 +36,7 @@ import lombok.experimental.Accessors;
@Desc("Configures rotation for iris") @Desc("Configures rotation for iris")
@Data @Data
public class IrisInterpolator { public class IrisInterpolator {
@Required @Required
@Desc("The interpolation method when two biomes use different heights but this same generator") @Desc("The interpolation method when two biomes use different heights but this same generator")
private InterpolationMethod function = InterpolationMethod.BICUBIC; private InterpolationMethod function = InterpolationMethod.BICUBIC;

View File

@ -45,18 +45,15 @@ import java.io.IOException;
public class IrisJigsawPiece extends IrisRegistrant { public class IrisJigsawPiece extends IrisRegistrant {
@RegistryListObject @RegistryListObject
@Required @Required
@Desc("The object this piece represents") @Desc("The object this piece represents")
private String object = ""; private String object = "";
@Required @Required
@ArrayType(type = IrisJigsawPieceConnector.class, min = 1) @ArrayType(type = IrisJigsawPieceConnector.class, min = 1)
@Desc("The connectors this object contains") @Desc("The connectors this object contains")
private KList<IrisJigsawPieceConnector> connectors = new KList<>(); private KList<IrisJigsawPieceConnector> connectors = new KList<>();
@Desc("Configure everything about the object placement. Please don't define this unless you actually need it as using this option will slow down the jigsaw deign stage. Use this where you need it, just avoid using it everywhere to keep things fast.") @Desc("Configure everything about the object placement. Please don't define this unless you actually need it as using this option will slow down the jigsaw deign stage. Use this where you need it, just avoid using it everywhere to keep things fast.")
private IrisObjectPlacement placementOptions = new IrisObjectPlacement().setMode(ObjectPlaceMode.FAST_MAX_HEIGHT); private IrisObjectPlacement placementOptions = new IrisObjectPlacement().setMode(ObjectPlaceMode.FAST_MAX_HEIGHT);
private transient AtomicCache<Integer> max2dDim = new AtomicCache<>(); private transient AtomicCache<Integer> max2dDim = new AtomicCache<>();

View File

@ -36,20 +36,16 @@ import lombok.experimental.Accessors;
@EqualsAndHashCode(callSuper = false) @EqualsAndHashCode(callSuper = false)
public class IrisJigsawPieceConnector { public class IrisJigsawPieceConnector {
@Required @Required
@Desc("The name of this connector, such as entry, or table node. This is a name for organization. Other connectors can specifically use targetName to target a specific connector type. Multiple connectors can use the same name.") @Desc("The name of this connector, such as entry, or table node. This is a name for organization. Other connectors can specifically use targetName to target a specific connector type. Multiple connectors can use the same name.")
private String name = ""; private String name = "";
@Required @Required
@Desc("Target a piece's connector with the specified name. For any piece's connector, define * or don't define it.") @Desc("Target a piece's connector with the specified name. For any piece's connector, define * or don't define it.")
private String targetName = "*"; private String targetName = "*";
@Desc("Rotates the placed piece on this connector. If rotation is enabled, this connector will effectivley rotate, if this connector is facing the Z direction, then the connected piece would rotate in the X,Y direction in 90 degree segments.") @Desc("Rotates the placed piece on this connector. If rotation is enabled, this connector will effectivley rotate, if this connector is facing the Z direction, then the connected piece would rotate in the X,Y direction in 90 degree segments.")
private boolean rotateConnector = false; private boolean rotateConnector = false;
@Desc("If set to true, this connector is allowed to place pieces inside of it's own piece. For example if you are adding a light post, or house on top of a path piece, you would set this to true to allow the piece to collide with the path bounding box.") @Desc("If set to true, this connector is allowed to place pieces inside of it's own piece. For example if you are adding a light post, or house on top of a path piece, you would set this to true to allow the piece to collide with the path bounding box.")
private boolean innerConnector = false; private boolean innerConnector = false;
@ -60,31 +56,25 @@ public class IrisJigsawPieceConnector {
private KList<String> pools = new KList<>(); private KList<String> pools = new KList<>();
@RegistryListEntity @RegistryListEntity
@Desc("Pick an entity to spawn on this connector") @Desc("Pick an entity to spawn on this connector")
private String spawnEntity; private String spawnEntity;
@Desc("Stop the entity from despawning") @Desc("Stop the entity from despawning")
private boolean keepEntity; private boolean keepEntity;
@MaxNumber(50) @MaxNumber(50)
@MinNumber(1) @MinNumber(1)
@Desc("The amount of entities to spawn (must be a whole number)") @Desc("The amount of entities to spawn (must be a whole number)")
private int entityCount = 1; private int entityCount = 1;
@Desc("The relative position this connector is located at for connecting to other pieces") @Desc("The relative position this connector is located at for connecting to other pieces")
@Required @Required
private IrisPosition position = new IrisPosition(0, 0, 0); private IrisPosition position = new IrisPosition(0, 0, 0);
@Desc("The relative position to this connector to place entities at") @Desc("The relative position to this connector to place entities at")
@DependsOn({"spawnEntity"}) @DependsOn({"spawnEntity"})
private IrisPosition entityPosition = null; private IrisPosition entityPosition = null;
@Desc("The direction this connector is facing. If the direction is set to UP, then pieces will place ABOVE the connector.") @Desc("The direction this connector is facing. If the direction is set to UP, then pieces will place ABOVE the connector.")
@Required @Required
private IrisDirection direction = IrisDirection.UP_POSITIVE_Y; private IrisDirection direction = IrisDirection.UP_POSITIVE_Y;

View File

@ -35,7 +35,6 @@ import lombok.experimental.Accessors;
public class IrisJigsawPlacement { public class IrisJigsawPlacement {
@RegistryListJigsaw @RegistryListJigsaw
@Required @Required
@Desc("The jigsaw structure to use") @Desc("The jigsaw structure to use")
private String structure = ""; private String structure = "";

View File

@ -40,7 +40,6 @@ import lombok.experimental.Accessors;
public class IrisJigsawPool extends IrisRegistrant { public class IrisJigsawPool extends IrisRegistrant {
@RegistryListJigsawPiece @RegistryListJigsawPiece
@Required @Required
@ArrayType(min = 1, type = String.class) @ArrayType(min = 1, type = String.class)
@Desc("A list of structure piece pools") @Desc("A list of structure piece pools")
private KList<String> pieces = new KList<>(); private KList<String> pieces = new KList<>();

View File

@ -39,7 +39,6 @@ import lombok.experimental.Accessors;
public class IrisJigsawStructure extends IrisRegistrant { public class IrisJigsawStructure extends IrisRegistrant {
@RegistryListJigsawPiece @RegistryListJigsawPiece
@Required @Required
@ArrayType(min = 1, type = String.class) @ArrayType(min = 1, type = String.class)
@Desc("The starting pieces. Randomly chooses a starting piece, then connects pieces using the pools define in the starting piece.") @Desc("The starting pieces. Randomly chooses a starting piece, then connects pieces using the pools define in the starting piece.")
private KList<String> pieces = new KList<>(); private KList<String> pieces = new KList<>();
@ -49,15 +48,12 @@ public class IrisJigsawStructure extends IrisRegistrant {
@Desc("The maximum pieces that can step out from the center piece") @Desc("The maximum pieces that can step out from the center piece")
private int maxDepth = 9; private int maxDepth = 9;
@Desc("Jigsaw grows the parallax layer which slows iris down a bit. Since there are so many pieces, Iris takes the avg piece size and calculates the parallax radius from that. Unless your structures are using only the biggest pieces, your structure should fit in the chosen size fine. If you are seeing cut-off parts of your structures or broken terrain, turn this option on. This option will pick the biggest piece dimensions and multiply it by your (maxDepth+1) * 2 as the size to grow the parallax layer by. But typically keep this off.") @Desc("Jigsaw grows the parallax layer which slows iris down a bit. Since there are so many pieces, Iris takes the avg piece size and calculates the parallax radius from that. Unless your structures are using only the biggest pieces, your structure should fit in the chosen size fine. If you are seeing cut-off parts of your structures or broken terrain, turn this option on. This option will pick the biggest piece dimensions and multiply it by your (maxDepth+1) * 2 as the size to grow the parallax layer by. But typically keep this off.")
private boolean useMaxPieceSizeForParallaxRadius = false; private boolean useMaxPieceSizeForParallaxRadius = false;
@Desc("Add a noise feature to this village") @Desc("Add a noise feature to this village")
private IrisFeature feature = null; private IrisFeature feature = null;
@Desc("If set to true, iris will look for any pieces with only one connector in valid pools for edge connectors and attach them to 'terminate' the paths/piece connectors. Essentially it caps off ends. For example in a village, Iris would add houses to the ends of roads where possible. For terminators to be selected, they can only have one connector or they wont be chosen.") @Desc("If set to true, iris will look for any pieces with only one connector in valid pools for edge connectors and attach them to 'terminate' the paths/piece connectors. Essentially it caps off ends. For example in a village, Iris would add houses to the ends of roads where possible. For terminators to be selected, they can only have one connector or they wont be chosen.")
private boolean terminate = true; private boolean terminate = true;

View File

@ -38,11 +38,9 @@ import lombok.experimental.Accessors;
public class IrisJigsawStructurePlacement extends IrisRegistrant { public class IrisJigsawStructurePlacement extends IrisRegistrant {
@RegistryListJigsaw @RegistryListJigsaw
@Required @Required
@Desc("The structure to place") @Desc("The structure to place")
private String structure; private String structure;
@Required @Required
@Desc("The 1 in X chance rarity") @Desc("The 1 in X chance rarity")
private int rarity = 100; private int rarity = 100;

View File

@ -48,7 +48,6 @@ import java.awt.*;
@Desc("Represents a loot entry") @Desc("Represents a loot entry")
@Data @Data
public class IrisLoot { public class IrisLoot {
@Desc("The target inventory slot types to fill this loot with") @Desc("The target inventory slot types to fill this loot with")
private InventorySlotType slotTypes = InventorySlotType.STORAGE; private InventorySlotType slotTypes = InventorySlotType.STORAGE;
@ -78,11 +77,9 @@ public class IrisLoot {
@Desc("Maximum durability percent") @Desc("Maximum durability percent")
private double maxDurability = 1; private double maxDurability = 1;
@Desc("Define a custom model identifier 1.14+ only") @Desc("Define a custom model identifier 1.14+ only")
private Integer customModel = null; private Integer customModel = null;
@Desc("Set this to true to prevent it from being broken") @Desc("Set this to true to prevent it from being broken")
private boolean unbreakable = false; private boolean unbreakable = false;
@ -90,12 +87,10 @@ public class IrisLoot {
@Desc("The item flags to add") @Desc("The item flags to add")
private KList<ItemFlag> itemFlags = new KList<>(); private KList<ItemFlag> itemFlags = new KList<>();
@Desc("Apply enchantments to this item") @Desc("Apply enchantments to this item")
@ArrayType(min = 1, type = IrisEnchantment.class) @ArrayType(min = 1, type = IrisEnchantment.class)
private KList<IrisEnchantment> enchantments = new KList<>(); private KList<IrisEnchantment> enchantments = new KList<>();
@Desc("Apply attribute modifiers to this item") @Desc("Apply attribute modifiers to this item")
@ArrayType(min = 1, type = IrisAttributeModifier.class) @ArrayType(min = 1, type = IrisAttributeModifier.class)
private KList<IrisAttributeModifier> attributes = new KList<>(); private KList<IrisAttributeModifier> attributes = new KList<>();
@ -106,15 +101,12 @@ public class IrisLoot {
@RegistryListItemType @RegistryListItemType
@Required @Required
@Desc("This is the item or block type. Does not accept minecraft:*. Only materials such as DIAMOND_SWORD or DIRT.") @Desc("This is the item or block type. Does not accept minecraft:*. Only materials such as DIAMOND_SWORD or DIRT.")
private String type = ""; private String type = "";
@Desc("The dye color") @Desc("The dye color")
private DyeColor dyeColor = null; private DyeColor dyeColor = null;
@Desc("The leather armor color") @Desc("The leather armor color")
private String leatherColor = null; private String leatherColor = null;

View File

@ -36,12 +36,9 @@ import lombok.experimental.Accessors;
@Desc("Represents a loot entry") @Desc("Represents a loot entry")
@Data @Data
public class IrisLootReference { public class IrisLootReference {
@Desc("Add = add on top of parent tables, Replace = clear first then add these. Clear = Remove all and dont add loot from this or parent.") @Desc("Add = add on top of parent tables, Replace = clear first then add these. Clear = Remove all and dont add loot from this or parent.")
private LootMode mode = LootMode.ADD; private LootMode mode = LootMode.ADD;
@RegistryListLoot @RegistryListLoot
@ArrayType(min = 1, type = String.class) @ArrayType(min = 1, type = String.class)
@Desc("Add loot table registries here") @Desc("Add loot table registries here")

View File

@ -41,9 +41,7 @@ import org.bukkit.inventory.ItemStack;
@EqualsAndHashCode(callSuper = false) @EqualsAndHashCode(callSuper = false)
public class IrisLootTable extends IrisRegistrant { public class IrisLootTable extends IrisRegistrant {
@Required @Required
@Desc("The name of this loot table") @Desc("The name of this loot table")
@MinNumber(2) @MinNumber(2)
private String name = ""; private String name = "";
@ -59,7 +57,6 @@ public class IrisLootTable extends IrisRegistrant {
@Desc("The minimum amount of loot that can be picked in this table at a time.") @Desc("The minimum amount of loot that can be picked in this table at a time.")
private int minPicked = 1; private int minPicked = 1;
@Desc("The loot in this table") @Desc("The loot in this table")
@ArrayType(min = 1, type = IrisLoot.class) @ArrayType(min = 1, type = IrisLoot.class)
private KList<IrisLoot> loot = new KList<>(); private KList<IrisLoot> loot = new KList<>();

View File

@ -39,7 +39,6 @@ import org.bukkit.block.data.BlockData;
@Desc("A palette of materials") @Desc("A palette of materials")
@Data @Data
public class IrisMaterialPalette { public class IrisMaterialPalette {
@Desc("The style of noise") @Desc("The style of noise")
private IrisGeneratorStyle style = NoiseStyle.STATIC.style(); private IrisGeneratorStyle style = NoiseStyle.STATIC.style();

View File

@ -0,0 +1,115 @@
/*
* 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;
import com.volmit.iris.Iris;
import com.volmit.iris.core.IrisDataManager;
import com.volmit.iris.engine.cache.AtomicCache;
import com.volmit.iris.engine.data.DataProvider;
import com.volmit.iris.engine.noise.CNG;
import com.volmit.iris.engine.object.annotations.*;
import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.io.IO;
import com.volmit.iris.util.math.Position2;
import com.volmit.iris.util.math.RNG;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import org.bukkit.Material;
import org.bukkit.World.Environment;
import org.bukkit.block.data.BlockData;
import java.io.File;
import java.io.IOException;
@SuppressWarnings("DefaultAnnotationParam")
@Accessors(chain = true)
@AllArgsConstructor
@NoArgsConstructor
@Desc("Represents a dimension")
@Data
@EqualsAndHashCode(callSuper = false)
public class IrisMod extends IrisRegistrant {
@MinNumber(2)
@Required
@Desc("The human readable name of this dimension")
private String name = "A Dimension Mod";
@Desc("If this mod only works with a specific dimension, define it's load key here. Such as overworld, or flat. Otherwise iris will assume this mod works with anything.")
private String forDimension = "";
@MinNumber(-1)
@MaxNumber(512)
@Desc("Override the fluid height. Otherwise set it to -1")
private int overrideFluidHeight = -1;
@Desc("A list of biomes to remove")
@RegistryListBiome
@ArrayType(type = String.class, min = 1)
private KList<String> removeBiomes = new KList<>();
@Desc("A list of objects to remove")
@RegistryListObject
@ArrayType(type = String.class, min = 1)
private KList<String> removeObjects = new KList<>();
@Desc("A list of regions to remove")
@RegistryListRegion
@ArrayType(type = String.class, min = 1)
private KList<String> removeRegions = new KList<>();
@Desc("A list of regions to inject")
@RegistryListRegion
@ArrayType(type = String.class, min = 1)
private KList<String> injectRegions = new KList<>();
@ArrayType(min = 1, type = IrisModBiomeInjector.class)
@Desc("Inject biomes into existing regions")
private KList<IrisModBiomeInjector> biomeInjectors = new KList<>();
@ArrayType(min = 1, type = IrisModBiomeReplacer.class)
@Desc("Replace biomes with other biomes")
private KList<IrisModBiomeReplacer> biomeReplacers = new KList<>();
@ArrayType(min = 1, type = IrisModObjectReplacer.class)
@Desc("Replace objects with other objects")
private KList<IrisModObjectReplacer> objectReplacers = new KList<>();
@ArrayType(min = 1, type = IrisModObjectPlacementBiomeInjector.class)
@Desc("Inject placers into existing biomes")
private KList<IrisModObjectPlacementBiomeInjector> biomeObjectPlacementInjectors = new KList<>();
@ArrayType(min = 1, type = IrisModObjectPlacementRegionInjector.class)
@Desc("Inject placers into existing regions")
private KList<IrisModObjectPlacementRegionInjector> regionObjectPlacementInjectors = new KList<>();
@ArrayType(min = 1, type = IrisModRegionReplacer.class)
@Desc("Replace biomes with other biomes")
private KList<IrisModRegionReplacer> regionReplacers = new KList<>();
@ArrayType(min = 1, type = IrisObjectReplace.class)
@Desc("Replace blocks with other blocks")
private KList<IrisObjectReplace> blockReplacers = new KList<>();
@ArrayType(min = 1, type = IrisModNoiseStyleReplacer.class)
@Desc("Replace noise styles with other styles")
private KList<IrisModNoiseStyleReplacer> styleReplacers = new KList<>();
}

View File

@ -0,0 +1,44 @@
/*
* 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;
import com.volmit.iris.engine.object.annotations.*;
import com.volmit.iris.util.collection.KList;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
@Accessors(chain = true)
@NoArgsConstructor
@AllArgsConstructor
@Desc("A biome injector")
@Data
public class IrisModBiomeInjector {
@Required
@Desc("The region to find")
@RegistryListRegion
private String region = "";
@Required
@Desc("A biome to inject into the region")
@RegistryListBiome
@ArrayType(type = String.class, min = 1)
private KList<String> inject = new KList<>();
}

View File

@ -0,0 +1,48 @@
/*
* 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;
import com.volmit.iris.engine.cache.AtomicCache;
import com.volmit.iris.engine.interpolation.IrisInterpolation;
import com.volmit.iris.engine.noise.CNG;
import com.volmit.iris.engine.object.annotations.*;
import com.volmit.iris.util.collection.KList;
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("A biome replacer")
@Data
public class IrisModBiomeReplacer {
@Required
@Desc("A list of biomes to find")
@RegistryListBiome
@ArrayType(type = String.class, min = 1)
private KList<String> find = new KList<>();
@Required
@Desc("A biome to replace it with")
@RegistryListBiome
private String replace = "";
}

View File

@ -0,0 +1,47 @@
/*
* 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;
import com.volmit.iris.engine.object.annotations.*;
import com.volmit.iris.util.collection.KList;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
@Accessors(chain = true)
@NoArgsConstructor
@AllArgsConstructor
@Desc("A noise style replacer")
@Data
public class IrisModNoiseStyleReplacer {
@Required
@Desc("A noise style to find")
@ArrayType(type = String.class, min = 1)
private NoiseStyle find = NoiseStyle.IRIS;
@Required
@Desc("If replaceTypeOnly is set to true, Iris will keep the existing generator style and only replace the type itself. Otherwise it will use the replace tag for every style using the find type.")
private boolean replaceTypeOnly = false;
@Required
@Desc("A noise style to replace it with")
@RegistryListBiome
private IrisGeneratorStyle replace = new IrisGeneratorStyle();
}

View File

@ -0,0 +1,46 @@
/*
* 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;
import com.volmit.iris.engine.object.annotations.ArrayType;
import com.volmit.iris.engine.object.annotations.Desc;
import com.volmit.iris.engine.object.annotations.RegistryListBiome;
import com.volmit.iris.engine.object.annotations.Required;
import com.volmit.iris.util.collection.KList;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
@Accessors(chain = true)
@NoArgsConstructor
@AllArgsConstructor
@Desc("An object placement injector")
@Data
public class IrisModObjectPlacementBiomeInjector {
@Required
@Desc("The biome to find")
@RegistryListBiome
private String biome = "";
@Required
@Desc("A biome to inject into the region")
@ArrayType(type = IrisObjectPlacement.class, min = 1)
private KList<IrisObjectPlacement> place = new KList<>();
}

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