mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2025-07-18 10:12:53 +00:00
Engine fixes
This commit is contained in:
parent
69cbb262ba
commit
b081bbb444
@ -30,9 +30,10 @@ import com.volmit.iris.core.link.OraxenLink;
|
||||
import com.volmit.iris.core.nms.INMS;
|
||||
import com.volmit.iris.core.project.loader.IrisData;
|
||||
import com.volmit.iris.core.tools.IrisToolbelt;
|
||||
import com.volmit.iris.engine.framework.EngineCompositeGenerator;
|
||||
import com.volmit.iris.engine.platform.BukkitChunkGenerator;
|
||||
import com.volmit.iris.engine.object.biome.IrisBiome;
|
||||
import com.volmit.iris.engine.object.biome.IrisBiomeCustom;
|
||||
import com.volmit.iris.engine.object.common.IrisWorld;
|
||||
import com.volmit.iris.engine.object.compat.IrisCompat;
|
||||
import com.volmit.iris.engine.object.dimensional.IrisDimension;
|
||||
import com.volmit.iris.util.collection.KList;
|
||||
@ -435,7 +436,23 @@ public class Iris extends VolmitPlugin implements Listener {
|
||||
Iris.info("Generator ID: " + id + " requested by bukkit/plugin. Assuming IrisDimension: " + id);
|
||||
}
|
||||
|
||||
return new EngineCompositeGenerator(dimension, true);
|
||||
IrisDimension d = IrisData.loadAnyDimension(dimension);
|
||||
|
||||
if(d == null)
|
||||
{
|
||||
throw new RuntimeException("Can't find dimension " + dimension + "!");
|
||||
}
|
||||
|
||||
IrisWorld w = IrisWorld.builder()
|
||||
.name(worldName)
|
||||
.seed(RNG.r.lmax())
|
||||
.environment(d.getEnvironment())
|
||||
.worldFolder(new File(worldName))
|
||||
.minHeight(0)
|
||||
.maxHeight(256)
|
||||
.build();
|
||||
|
||||
return new BukkitChunkGenerator(w, false, new File(w.worldFolder(), "iris"), dimension);
|
||||
}
|
||||
|
||||
public static void msg(String string) {
|
||||
|
@ -38,9 +38,14 @@ import com.volmit.iris.engine.object.decoration.IrisDecorator;
|
||||
import com.volmit.iris.engine.object.engine.IrisEngineData;
|
||||
import com.volmit.iris.engine.object.objects.IrisObjectPlacement;
|
||||
import com.volmit.iris.engine.scripting.EngineExecutionEnvironment;
|
||||
import com.volmit.iris.util.atomics.AtomicRollingSequence;
|
||||
import com.volmit.iris.util.collection.KList;
|
||||
import com.volmit.iris.util.collection.KMap;
|
||||
import com.volmit.iris.util.context.IrisContext;
|
||||
import com.volmit.iris.util.documentation.BlockCoordinates;
|
||||
import com.volmit.iris.util.documentation.ChunkCoordinates;
|
||||
import com.volmit.iris.util.format.C;
|
||||
import com.volmit.iris.util.format.Form;
|
||||
import com.volmit.iris.util.hunk.Hunk;
|
||||
import com.volmit.iris.util.io.IO;
|
||||
import com.volmit.iris.util.math.RNG;
|
||||
@ -49,10 +54,12 @@ import com.volmit.iris.util.scheduling.J;
|
||||
import com.volmit.iris.util.scheduling.PrecisionStopwatch;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Biome;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.generator.BlockPopulator;
|
||||
|
||||
import java.io.File;
|
||||
@ -63,19 +70,19 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
public class IrisEngine extends BlockPopulator implements Engine {
|
||||
private final EngineCompound compound;
|
||||
// TODO: Remove block population, stop using bukkit
|
||||
private final EngineTarget target;
|
||||
private final IrisContext context;
|
||||
private final EngineEffects effects;
|
||||
private final EngineExecutionEnvironment execution;
|
||||
private final EngineWorldManager worldManager;
|
||||
private volatile int parallelism;
|
||||
private final int index;
|
||||
private final EngineMetrics metrics;
|
||||
private volatile int minHeight;
|
||||
private boolean failing;
|
||||
private boolean closed;
|
||||
private int cacheId;
|
||||
private final AtomicRollingSequence wallClock;
|
||||
private final int art;
|
||||
private double maxBiomeObjectDensity;
|
||||
private double maxBiomeLayerDensity;
|
||||
@ -94,19 +101,19 @@ public class IrisEngine extends BlockPopulator implements Engine {
|
||||
private final AtomicBoolean cleaning;
|
||||
private final ChronoLatch cleanLatch;
|
||||
|
||||
public IrisEngine(EngineTarget target, EngineCompound compound, int index) {
|
||||
public IrisEngine(EngineTarget target) {
|
||||
wallClock = new AtomicRollingSequence(32);
|
||||
execution = new IrisExecutionEnvironment(this);
|
||||
Iris.info("Initializing Engine: " + target.getWorld().name() + "/" + target.getDimension().getLoadKey() + " (" + target.getHeight() + " height)");
|
||||
// TODO: HEIGHT ------------------------------------------------------------------------------------------------------>
|
||||
Iris.info("Initializing Engine: " + target.getWorld().name() + "/" + target.getDimension().getLoadKey() + " (" + 256+ " height)");
|
||||
metrics = new EngineMetrics(32);
|
||||
this.target = target;
|
||||
getData().setEngine(this);
|
||||
getEngineData();
|
||||
worldManager = new IrisWorldManager(this);
|
||||
this.compound = compound;
|
||||
minHeight = 0;
|
||||
failing = false;
|
||||
closed = false;
|
||||
this.index = index;
|
||||
cacheId = RNG.r.nextInt();
|
||||
effects = new IrisEngineEffects(this);
|
||||
art = J.ar(effects::tickRandomPlayer, 0);
|
||||
@ -135,7 +142,8 @@ public class IrisEngine extends BlockPopulator implements Engine {
|
||||
World w = null;
|
||||
|
||||
return engineData.aquire(() -> {
|
||||
File f = new File(getWorld().worldFolder(), "iris/engine-data/" + getDimension().getLoadKey() + "-" + getIndex() + ".json");
|
||||
//TODO: Method this file
|
||||
File f = new File(getWorld().worldFolder(), "iris/engine-data/" + getDimension().getLoadKey() + ".json");
|
||||
|
||||
if (!f.exists()) {
|
||||
try {
|
||||
@ -182,6 +190,63 @@ public class IrisEngine extends BlockPopulator implements Engine {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void printMetrics(CommandSender sender) {
|
||||
KMap<String, Double> totals = new KMap<>();
|
||||
KMap<String, Double> weights = new KMap<>();
|
||||
double masterWallClock = wallClock.getAverage();
|
||||
KMap<String, Double> timings = getMetrics().pull();
|
||||
double totalWeight = 0;
|
||||
double wallClock = getMetrics().getTotal().getAverage();
|
||||
|
||||
for (double j : timings.values()) {
|
||||
totalWeight += j;
|
||||
}
|
||||
|
||||
for (String j : timings.k()) {
|
||||
weights.put(getName() + "." + j, (wallClock / totalWeight) * timings.get(j));
|
||||
}
|
||||
|
||||
totals.put(getName(), wallClock);
|
||||
|
||||
double mtotals = 0;
|
||||
|
||||
for (double i : totals.values()) {
|
||||
mtotals += i;
|
||||
}
|
||||
|
||||
for (String i : totals.k()) {
|
||||
totals.put(i, (masterWallClock / mtotals) * totals.get(i));
|
||||
}
|
||||
|
||||
double v = 0;
|
||||
|
||||
for (double i : weights.values()) {
|
||||
v += i;
|
||||
}
|
||||
|
||||
for (String i : weights.k()) {
|
||||
weights.put(i, weights.get(i) / v);
|
||||
}
|
||||
|
||||
sender.sendMessage("Total: " + C.BOLD + C.WHITE + Form.duration(masterWallClock, 0));
|
||||
|
||||
for (String i : totals.k()) {
|
||||
sender.sendMessage(" Engine " + C.UNDERLINE + C.GREEN + i + C.RESET + ": " + C.BOLD + C.WHITE + Form.duration(totals.get(i), 0));
|
||||
}
|
||||
|
||||
sender.sendMessage("Details: ");
|
||||
|
||||
for (String i : weights.sortKNumber().reverse()) {
|
||||
String befb = C.UNDERLINE + "" + C.GREEN + "" + i.split("\\Q[\\E")[0] + C.RESET + C.GRAY + "[";
|
||||
String num = C.GOLD + i.split("\\Q[\\E")[1].split("]")[0] + C.RESET + C.GRAY + "].";
|
||||
String afb = C.ITALIC + "" + C.AQUA + i.split("\\Q]\\E")[1].substring(1) + C.RESET + C.GRAY;
|
||||
|
||||
sender.sendMessage(" " + befb + num + afb + ": " + C.BOLD + C.WHITE + Form.pc(weights.get(i), 0));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
J.car(art);
|
||||
@ -249,7 +314,7 @@ public class IrisEngine extends BlockPopulator implements Engine {
|
||||
return z / getDimension().getTerrainZoom();
|
||||
}
|
||||
|
||||
@ChunkCoordinates
|
||||
@BlockCoordinates
|
||||
@Override
|
||||
public void generate(int x, int z, Hunk<BlockData> vblocks, Hunk<Biome> vbiomes, boolean multicore) {
|
||||
context.touch();
|
||||
@ -284,7 +349,8 @@ public class IrisEngine extends BlockPopulator implements Engine {
|
||||
|
||||
@Override
|
||||
public void saveEngineData() {
|
||||
File f = new File(getWorld().worldFolder(), "iris/engine-data/" + getDimension().getLoadKey() + "-" + getIndex() + ".json");
|
||||
//TODO: Method this file
|
||||
File f = new File(getWorld().worldFolder(), "iris/engine-data/" + getDimension().getLoadKey() + ".json");
|
||||
f.getParentFile().mkdirs();
|
||||
try {
|
||||
IO.writeAll(f, new Gson().toJson(getEngineData()));
|
||||
@ -304,6 +370,7 @@ public class IrisEngine extends BlockPopulator implements Engine {
|
||||
return getData().getBiomeLoader().load(getDimension().getFocus());
|
||||
}
|
||||
|
||||
// TODO: Remove block population
|
||||
@ChunkCoordinates
|
||||
@Override
|
||||
public void populate(World world, Random random, Chunk c) {
|
||||
|
@ -25,6 +25,7 @@ import com.volmit.iris.core.project.loader.IrisData;
|
||||
import com.volmit.iris.engine.IrisComplex;
|
||||
import com.volmit.iris.engine.data.cache.Cache;
|
||||
import com.volmit.iris.engine.object.basic.IrisColor;
|
||||
import com.volmit.iris.engine.object.basic.IrisPosition;
|
||||
import com.volmit.iris.engine.object.biome.IrisBiome;
|
||||
import com.volmit.iris.engine.object.common.IrisWorld;
|
||||
import com.volmit.iris.engine.object.dimensional.IrisDimension;
|
||||
@ -37,6 +38,7 @@ import com.volmit.iris.engine.object.regional.IrisRegion;
|
||||
import com.volmit.iris.engine.parallax.ParallaxAccess;
|
||||
import com.volmit.iris.engine.scripting.EngineExecutionEnvironment;
|
||||
import com.volmit.iris.util.collection.KList;
|
||||
import com.volmit.iris.util.collection.KMap;
|
||||
import com.volmit.iris.util.context.IrisContext;
|
||||
import com.volmit.iris.util.data.B;
|
||||
import com.volmit.iris.util.data.DataProvider;
|
||||
@ -54,6 +56,7 @@ import org.bukkit.Material;
|
||||
import org.bukkit.block.Biome;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.InventoryHolder;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
@ -61,10 +64,13 @@ import org.bukkit.inventory.ItemStack;
|
||||
import java.awt.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.UUID;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public interface Engine extends DataProvider, Fallible, GeneratorAccess, LootProvider, BlockUpdater, Renderer, Hotloadable {
|
||||
public interface Engine extends DataProvider, Fallible, GeneratorAccess, LootProvider, BlockUpdater, Renderer {
|
||||
IrisComplex getComplex();
|
||||
|
||||
void printMetrics(CommandSender sender);
|
||||
|
||||
void recycle();
|
||||
|
||||
EngineParallaxManager getEngineParallax();
|
||||
@ -111,9 +117,10 @@ public interface Engine extends DataProvider, Fallible, GeneratorAccess, LootPro
|
||||
|
||||
void setMinHeight(int min);
|
||||
|
||||
int getIndex();
|
||||
|
||||
int getMinHeight();
|
||||
default int getMinHeight()
|
||||
{
|
||||
return getTarget().getWorld().minHeight();
|
||||
}
|
||||
|
||||
@BlockCoordinates
|
||||
double modifyX(double x);
|
||||
@ -121,7 +128,7 @@ public interface Engine extends DataProvider, Fallible, GeneratorAccess, LootPro
|
||||
@BlockCoordinates
|
||||
double modifyZ(double z);
|
||||
|
||||
@ChunkCoordinates
|
||||
@BlockCoordinates
|
||||
void generate(int x, int z, Hunk<BlockData> blocks, Hunk<Biome> biomes, boolean multicore);
|
||||
|
||||
EngineMetrics getMetrics();
|
||||
@ -143,10 +150,6 @@ public interface Engine extends DataProvider, Fallible, GeneratorAccess, LootPro
|
||||
return getDimension().getName();
|
||||
}
|
||||
|
||||
default int getHeight() {
|
||||
return getTarget().getHeight();
|
||||
}
|
||||
|
||||
default IrisData getData() {
|
||||
return getTarget().getData();
|
||||
}
|
||||
@ -168,7 +171,7 @@ public interface Engine extends DataProvider, Fallible, GeneratorAccess, LootPro
|
||||
IrisRegion region = getRegion((int) x, (int) z);
|
||||
IrisBiome biome = getSurfaceBiome((int) x, (int) z);
|
||||
int height = getHeight((int) x, (int) z);
|
||||
double heightFactor = M.lerpInverse(0, getHeight(), height);
|
||||
double heightFactor = M.lerpInverse(0, getTarget().getHeight(), height);
|
||||
Color irc = region.getColor(this.getComplex(), RenderType.BIOME);
|
||||
Color ibc = biome.getColor(this, RenderType.BIOME);
|
||||
Color rc = irc != null ? irc : Color.GREEN.darker();
|
||||
@ -404,18 +407,8 @@ public interface Engine extends DataProvider, Fallible, GeneratorAccess, LootPro
|
||||
scramble(inv, rng);
|
||||
}
|
||||
|
||||
default int getMaxHeight() {
|
||||
return getHeight() + getMinHeight();
|
||||
}
|
||||
|
||||
EngineEffects getEffects();
|
||||
|
||||
EngineCompound getCompound();
|
||||
|
||||
default boolean isStudio() {
|
||||
return getCompound().isStudio();
|
||||
}
|
||||
|
||||
default MultiBurst burst() {
|
||||
return getTarget().getBurster();
|
||||
}
|
||||
@ -434,11 +427,6 @@ public interface Engine extends DataProvider, Fallible, GeneratorAccess, LootPro
|
||||
return getRegion(l.getBlockX(), l.getBlockZ());
|
||||
}
|
||||
|
||||
@BlockCoordinates
|
||||
default boolean contains(Location l) {
|
||||
return l.getBlockY() >= getMinHeight() && l.getBlockY() <= getMaxHeight();
|
||||
}
|
||||
|
||||
IrisBiome getFocus();
|
||||
|
||||
IrisEngineData getEngineData();
|
||||
@ -450,4 +438,34 @@ public interface Engine extends DataProvider, Fallible, GeneratorAccess, LootPro
|
||||
default IrisRegion getRegion(Chunk c) {
|
||||
return getRegion((c.getX() << 4) + 8, (c.getZ() << 4) + 8);
|
||||
}
|
||||
|
||||
default KList<IrisBiome> getAllBiomes() {
|
||||
KMap<String, IrisBiome> v = new KMap<>();
|
||||
|
||||
IrisDimension dim = getDimension();
|
||||
dim.getAllBiomes(this).forEach((i) -> v.put(i.getLoadKey(), i));
|
||||
|
||||
try {
|
||||
dim.getDimensionalComposite().forEach((m) -> getData().getDimensionLoader().load(m.getDimension()).getAllBiomes(this).forEach((i) -> v.put(i.getLoadKey(), i)));
|
||||
} catch (Throwable ignored) {
|
||||
Iris.reportError(ignored);
|
||||
|
||||
}
|
||||
|
||||
return v.v();
|
||||
}
|
||||
|
||||
int getGenerated();
|
||||
|
||||
default IrisPosition lookForBiome(IrisBiome biome, int checks, Consumer<Integer> progress)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
default IrisPosition lookForRegion(IrisRegion biome, int checks, Consumer<Integer> progress)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
double getGeneratedPerSecond();
|
||||
}
|
||||
|
@ -24,6 +24,7 @@ import com.volmit.iris.engine.object.common.IrisWorld;
|
||||
import com.volmit.iris.engine.object.dimensional.IrisDimension;
|
||||
import com.volmit.iris.engine.parallax.ParallaxWorld;
|
||||
import com.volmit.iris.util.parallel.MultiBurst;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.File;
|
||||
@ -34,24 +35,24 @@ public class EngineTarget {
|
||||
private final MultiBurst burster;
|
||||
private final IrisDimension dimension;
|
||||
private IrisWorld world;
|
||||
private final int height;
|
||||
private final IrisData data;
|
||||
private final ParallaxWorld parallaxWorld;
|
||||
private final boolean inverted;
|
||||
|
||||
public EngineTarget(IrisWorld world, IrisDimension dimension, IrisData data, int height, boolean inverted, int threads) {
|
||||
public EngineTarget(IrisWorld world, IrisDimension dimension, IrisData data) {
|
||||
this.world = world;
|
||||
this.height = height;
|
||||
this.dimension = dimension;
|
||||
this.data = data;
|
||||
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(),
|
||||
IrisSettings.getThreadCount(IrisSettings.get().getConcurrency().getEngineThreadCount()));
|
||||
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"));
|
||||
this.parallaxWorld = new ParallaxWorld(parallaxBurster, 256, new File(world.worldFolder(),
|
||||
"iris/" + dimension.getLoadKey() + "/parallax"));
|
||||
}
|
||||
|
||||
public EngineTarget(IrisWorld world, IrisDimension dimension, IrisData data, int height, int threads) {
|
||||
this(world, dimension, data, height, false, threads);
|
||||
public int getHeight()
|
||||
{
|
||||
return world.maxHeight() - world.minHeight();
|
||||
}
|
||||
|
||||
public void close() {
|
||||
|
@ -19,9 +19,8 @@
|
||||
package com.volmit.iris.engine.jigsaw;
|
||||
|
||||
import com.volmit.iris.core.project.loader.IrisData;
|
||||
import com.volmit.iris.core.tools.IrisWorlds;
|
||||
import com.volmit.iris.core.tools.IrisToolbelt;
|
||||
import com.volmit.iris.engine.framework.Engine;
|
||||
import com.volmit.iris.engine.framework.IrisAccess;
|
||||
import com.volmit.iris.engine.object.basic.IrisPosition;
|
||||
import com.volmit.iris.engine.object.common.IObjectPlacer;
|
||||
import com.volmit.iris.engine.object.jigsaw.IrisJigsawPiece;
|
||||
@ -32,6 +31,7 @@ import com.volmit.iris.engine.object.objects.IrisObject;
|
||||
import com.volmit.iris.engine.object.objects.IrisObjectRotation;
|
||||
import com.volmit.iris.engine.object.objects.IrisObjectTranslate;
|
||||
import com.volmit.iris.engine.object.tile.TileData;
|
||||
import com.volmit.iris.engine.platform.PlatformChunkGenerator;
|
||||
import com.volmit.iris.util.collection.KList;
|
||||
import com.volmit.iris.util.math.AxisAlignedBB;
|
||||
import com.volmit.iris.util.math.BlockPosition;
|
||||
@ -150,13 +150,13 @@ public class PlannedPiece {
|
||||
}
|
||||
|
||||
public void place(World world) {
|
||||
IrisAccess a = IrisWorlds.access(world);
|
||||
PlatformChunkGenerator a = IrisToolbelt.access(world);
|
||||
|
||||
int minY = 0;
|
||||
if (a != null) {
|
||||
minY = a.getCompound().getDefaultEngine().getMinHeight();
|
||||
minY = a.getEngine().getMinHeight();
|
||||
|
||||
if (!a.getCompound().getRootDimension().isBedrock())
|
||||
if (!a.getEngine().getDimension().isBedrock())
|
||||
minY--; //If the dimension has no bedrock, allow it to go a block lower
|
||||
}
|
||||
|
||||
@ -191,7 +191,7 @@ public class PlannedPiece {
|
||||
|
||||
IrisLootTable table = getPiece().getPlacementOptions().getTable(block.getBlockData(), getData());
|
||||
if (table == null) return;
|
||||
Engine engine = a.getCompound().getEngineForHeight(y);
|
||||
Engine engine = a.getEngine();
|
||||
engine.addItems(false, ((InventoryHolder) block.getState()).getInventory(),
|
||||
rng.nextParallelRNG(BlockPosition.toLong(x, y, z)),
|
||||
new KList<>(table), InventorySlotType.STORAGE, x, y, z, 15);
|
||||
|
@ -21,9 +21,9 @@ package com.volmit.iris.engine.jigsaw;
|
||||
import com.googlecode.concurrentlinkedhashmap.ConcurrentLinkedHashMap;
|
||||
import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.core.project.loader.IrisData;
|
||||
import com.volmit.iris.core.tools.IrisWorlds;
|
||||
import com.volmit.iris.core.tools.IrisToolbelt;
|
||||
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.object.basic.IrisPosition;
|
||||
import com.volmit.iris.engine.object.common.IObjectPlacer;
|
||||
import com.volmit.iris.engine.object.entity.IrisEntity;
|
||||
@ -174,7 +174,7 @@ public class PlannedStructure {
|
||||
Iris.sq(() -> {
|
||||
for (IrisJigsawPieceConnector j : i.getAvailableConnectors()) {
|
||||
if (j.getSpawnEntity() != null) {
|
||||
IrisAccess a = IrisWorlds.access(world);
|
||||
Engine a = IrisToolbelt.access(world).getEngine();
|
||||
if (a == null) {
|
||||
Iris.warn("Cannot spawn entities from jigsaw in non Iris world!");
|
||||
break;
|
||||
@ -183,7 +183,7 @@ public class PlannedStructure {
|
||||
IrisEntity e = getData().getEntityLoader().load(j.getSpawnEntity());
|
||||
|
||||
if (a != null) {
|
||||
Entity entity = e.spawn(a.getCompound().getEngineForHeight(p.getY()), new Location(world, p.getX() + 0.5, p.getY(), p.getZ() + 0.5), rng);
|
||||
Entity entity = e.spawn(a, new Location(world, p.getX() + 0.5, p.getY(), p.getZ() + 0.5), rng);
|
||||
if (j.isKeepEntity()) {
|
||||
entity.setPersistent(true);
|
||||
}
|
||||
|
@ -22,10 +22,10 @@ import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.core.gui.components.RenderType;
|
||||
import com.volmit.iris.core.project.loader.IrisData;
|
||||
import com.volmit.iris.core.project.loader.IrisRegistrant;
|
||||
import com.volmit.iris.core.tools.IrisToolbelt;
|
||||
import com.volmit.iris.engine.IrisComplex;
|
||||
import com.volmit.iris.engine.data.cache.AtomicCache;
|
||||
import com.volmit.iris.engine.framework.Engine;
|
||||
import com.volmit.iris.engine.framework.IrisAccess;
|
||||
import com.volmit.iris.engine.object.annotations.*;
|
||||
import com.volmit.iris.engine.object.block.IrisBlockDrops;
|
||||
import com.volmit.iris.engine.object.common.IRare;
|
||||
@ -306,7 +306,7 @@ public class IrisBiome extends IrisRegistrant implements IRare {
|
||||
});
|
||||
}
|
||||
|
||||
public double getHeight(IrisAccess xg, double x, double z, long seed) {
|
||||
public double getHeight(Engine xg, double x, double z, long seed) {
|
||||
double height = 0;
|
||||
|
||||
for (IrisBiomeGeneratorLink i : generators) {
|
||||
|
@ -0,0 +1,89 @@
|
||||
/*
|
||||
* 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.common;
|
||||
|
||||
import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.core.project.loader.IrisData;
|
||||
import com.volmit.iris.core.tools.IrisToolbelt;
|
||||
import com.volmit.iris.engine.platform.HeadlessGenerator;
|
||||
import com.volmit.iris.engine.platform.BukkitChunkGenerator;
|
||||
import com.volmit.iris.engine.object.dimensional.IrisDimension;
|
||||
import com.volmit.iris.util.plugin.VolmitSender;
|
||||
import lombok.Data;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.WorldCreator;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
@Data
|
||||
@SuppressWarnings("ResultOfMethodCallIgnored")
|
||||
public class HeadlessWorld {
|
||||
private final IrisDimension dimension;
|
||||
private final String worldName;
|
||||
private final IrisWorld world;
|
||||
private boolean studio;
|
||||
|
||||
public HeadlessWorld(String worldName, IrisDimension dimension, long seed) {
|
||||
this(worldName, dimension, seed, false);
|
||||
}
|
||||
|
||||
public HeadlessWorld(String worldName, IrisDimension dimension, long seed, boolean studio) {
|
||||
this.worldName = worldName;
|
||||
this.dimension = dimension;
|
||||
this.studio = studio;
|
||||
world = IrisWorld.builder()
|
||||
.environment(dimension.getEnvironment())
|
||||
.worldFolder(new File(worldName))
|
||||
.seed(seed)
|
||||
.maxHeight(256)
|
||||
.minHeight(0)
|
||||
.name(worldName)
|
||||
.build();
|
||||
world.worldFolder().mkdirs();
|
||||
new File(world.worldFolder(), "region").mkdirs();
|
||||
|
||||
if (!studio && !new File(world.worldFolder(), "iris").exists()) {
|
||||
Iris.proj.installIntoWorld(new VolmitSender(Bukkit.getConsoleSender(), Iris.instance.getTag("Headless")), dimension.getLoadKey(), world.worldFolder());
|
||||
}
|
||||
}
|
||||
|
||||
public HeadlessGenerator generate() {
|
||||
return new HeadlessGenerator(this);
|
||||
}
|
||||
|
||||
public World load() {
|
||||
World w = new WorldCreator(worldName)
|
||||
.environment(dimension.getEnvironment())
|
||||
.seed(world.seed())
|
||||
.generator(new BukkitChunkGenerator(world, studio, dimension.getLoader().getDataFolder(),
|
||||
dimension.getLoadKey()))
|
||||
.createWorld();
|
||||
world.realWorld(w);
|
||||
return w;
|
||||
}
|
||||
|
||||
public static HeadlessWorld from(World world) {
|
||||
return new HeadlessWorld(world.getName(), IrisToolbelt.access(world).getEngine().getTarget().getDimension(), world.getSeed());
|
||||
}
|
||||
|
||||
public static HeadlessWorld from(String name, String dimension, long seed) {
|
||||
return new HeadlessWorld(name, IrisData.loadAnyDimension(dimension), seed);
|
||||
}
|
||||
}
|
@ -19,7 +19,7 @@
|
||||
package com.volmit.iris.engine.object.common;
|
||||
|
||||
import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.core.tools.IrisWorlds;
|
||||
import com.volmit.iris.core.tools.IrisToolbelt;
|
||||
import com.volmit.iris.util.collection.KList;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
@ -76,11 +76,16 @@ public class IrisWorld {
|
||||
|
||||
public void evacuate() {
|
||||
if (hasRealWorld()) {
|
||||
IrisWorlds.evacuate(realWorld());
|
||||
IrisToolbelt.evacuate(realWorld());
|
||||
}
|
||||
}
|
||||
|
||||
public void bind(World world) {
|
||||
if(hasRealWorld())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
bindWorld(this, world);
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,177 @@
|
||||
/*
|
||||
* 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.platform;
|
||||
|
||||
import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.core.project.loader.IrisData;
|
||||
import com.volmit.iris.engine.IrisEngine;
|
||||
import com.volmit.iris.engine.data.chunk.TerrainChunk;
|
||||
import com.volmit.iris.engine.framework.Engine;
|
||||
import com.volmit.iris.engine.framework.EngineTarget;
|
||||
import com.volmit.iris.engine.object.common.IrisWorld;
|
||||
import com.volmit.iris.engine.object.dimensional.IrisDimension;
|
||||
import com.volmit.iris.util.collection.KList;
|
||||
import com.volmit.iris.util.hunk.Hunk;
|
||||
import com.volmit.iris.util.io.ReactiveFolder;
|
||||
import com.volmit.iris.util.parallel.MultiBurst;
|
||||
import com.volmit.iris.util.scheduling.PrecisionStopwatch;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Biome;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.generator.BlockPopulator;
|
||||
import org.bukkit.generator.ChunkGenerator;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChunkGenerator {
|
||||
private static final BlockData ERROR_BLOCK = Material.RED_GLAZED_TERRACOTTA.createBlockData();
|
||||
private final AtomicReference<CompletableFuture<Engine>> engine = new AtomicReference<>();
|
||||
private final AtomicBoolean busy = new AtomicBoolean(false);
|
||||
private final IrisWorld world;
|
||||
private final File dataLocation;
|
||||
private final String dimensionKey;
|
||||
private final ReactiveFolder folder;
|
||||
private final KList<BlockPopulator> populators;
|
||||
private final boolean studio;
|
||||
|
||||
public BukkitChunkGenerator(IrisWorld world, boolean studio, File dataLocation, String dimensionKey)
|
||||
{
|
||||
populators = new KList<>();
|
||||
this.world = world;
|
||||
this.studio = studio;
|
||||
this.dataLocation = dataLocation;
|
||||
this.dimensionKey = dimensionKey;
|
||||
this.folder = new ReactiveFolder(dataLocation, (_a, _b, _c) -> initialize());
|
||||
initialize();
|
||||
}
|
||||
|
||||
public Engine getEngine()
|
||||
{
|
||||
try {
|
||||
return engine.get().get();
|
||||
} catch (InterruptedException | ExecutionException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isHeadless() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
getEngine().close();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void hotload() {
|
||||
initialize();
|
||||
}
|
||||
|
||||
private void initialize()
|
||||
{
|
||||
engine.set(MultiBurst.burst.completeValue(() -> createEngine(world, dimensionKey, dataLocation)));
|
||||
}
|
||||
|
||||
private Engine createEngine(IrisWorld world, String dimension, File dataLocation) {
|
||||
IrisData data = new IrisData(dataLocation);
|
||||
IrisDimension realDimension = data.getDimensionLoader().load(dimension);
|
||||
EngineTarget target = new EngineTarget(world, realDimension, data);
|
||||
Engine engine = new IrisEngine(target);
|
||||
populators.clear();
|
||||
populators.add((BlockPopulator) engine);
|
||||
return engine;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ChunkData generateChunkData(@NotNull World world, @NotNull Random ignored, int x, int z, @NotNull BiomeGrid biome) {
|
||||
try
|
||||
{
|
||||
PrecisionStopwatch ps = PrecisionStopwatch.start();
|
||||
TerrainChunk tc = TerrainChunk.create(world, biome);
|
||||
Hunk<BlockData> blocks = Hunk.view((ChunkData) tc);
|
||||
Hunk<Biome> biomes = Hunk.view((BiomeGrid) tc);
|
||||
this.world.bind(world);
|
||||
engine.get().get().generate(x * 16, z * 16, blocks, biomes, true);
|
||||
return tc.getRaw();
|
||||
}
|
||||
|
||||
catch(Throwable e)
|
||||
{
|
||||
Iris.error("======================================");
|
||||
e.printStackTrace();
|
||||
Iris.reportErrorChunk(x, z, e, "CHUNK");
|
||||
Iris.error("======================================");
|
||||
|
||||
ChunkData d = Bukkit.createChunkData(world);
|
||||
|
||||
for (int i = 0; i < 16; i++) {
|
||||
for (int j = 0; j < 16; j++) {
|
||||
d.setBlock(i, 0, j, ERROR_BLOCK);
|
||||
}
|
||||
}
|
||||
|
||||
return d;
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<BlockPopulator> getDefaultPopulators(@NotNull World world) {
|
||||
return populators;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isParallelCapable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldGenerateCaves() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldGenerateDecorations() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldGenerateMobs() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldGenerateStructures() {
|
||||
return false;
|
||||
}
|
||||
}
|
@ -0,0 +1,158 @@
|
||||
/*
|
||||
* 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.platform;
|
||||
|
||||
import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.core.IrisSettings;
|
||||
import com.volmit.iris.core.nms.INMS;
|
||||
import com.volmit.iris.core.pregenerator.PregenListener;
|
||||
import com.volmit.iris.core.pregenerator.PregenTask;
|
||||
import com.volmit.iris.engine.IrisEngine;
|
||||
import com.volmit.iris.engine.data.chunk.MCATerrainChunk;
|
||||
import com.volmit.iris.engine.data.chunk.TerrainChunk;
|
||||
import com.volmit.iris.engine.framework.Engine;
|
||||
import com.volmit.iris.engine.framework.EngineTarget;
|
||||
import com.volmit.iris.engine.object.common.HeadlessWorld;
|
||||
import com.volmit.iris.util.collection.KList;
|
||||
import com.volmit.iris.util.documentation.ChunkCoordinates;
|
||||
import com.volmit.iris.util.documentation.RegionCoordinates;
|
||||
import com.volmit.iris.util.hunk.Hunk;
|
||||
import com.volmit.iris.util.math.Position2;
|
||||
import com.volmit.iris.util.nbt.mca.MCAUtil;
|
||||
import com.volmit.iris.util.nbt.mca.NBTWorld;
|
||||
import com.volmit.iris.util.nbt.tag.CompoundTag;
|
||||
import com.volmit.iris.util.parallel.BurstExecutor;
|
||||
import com.volmit.iris.util.parallel.MultiBurst;
|
||||
import lombok.Data;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.generator.ChunkGenerator;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
@Data
|
||||
public class HeadlessGenerator implements PlatformChunkGenerator {
|
||||
private static final BlockData ERROR_BLOCK = Material.RED_GLAZED_TERRACOTTA.createBlockData();
|
||||
private static KList<Position2> EMPTYPOINTS = new KList<>();
|
||||
private final HeadlessWorld world;
|
||||
private final NBTWorld writer;
|
||||
private final MultiBurst burst;
|
||||
private final Engine engine;
|
||||
|
||||
public HeadlessGenerator(HeadlessWorld world) {
|
||||
this.world = world;
|
||||
burst = new MultiBurst("Iris Headless Generator", 9, IrisSettings.getThreadCount(IrisSettings.get().getConcurrency().getPregenThreadCount()));
|
||||
writer = new NBTWorld(world.getWorld().worldFolder());
|
||||
engine = new IrisEngine(new EngineTarget(world.getWorld(),world.getDimension(), world.getDimension().getLoader()));
|
||||
}
|
||||
|
||||
@ChunkCoordinates
|
||||
public void generateChunk(int x, int z) {
|
||||
try {
|
||||
int ox = x << 4;
|
||||
int oz = z << 4;
|
||||
com.volmit.iris.util.nbt.mca.Chunk chunk = writer.getChunk(x, z);
|
||||
|
||||
TerrainChunk tc = MCATerrainChunk.builder()
|
||||
.writer(writer).ox(ox).oz(oz).mcaChunk(chunk)
|
||||
.minHeight(world.getWorld().minHeight()).maxHeight(world.getWorld().maxHeight())
|
||||
.injector((xx, yy, zz, biomeBase) -> chunk.setBiomeAt(ox + xx, yy, oz + zz,
|
||||
INMS.get().getTrueBiomeBaseId(biomeBase)))
|
||||
.build();
|
||||
engine.generate(x * 16, z * 16,
|
||||
Hunk.view((ChunkGenerator.ChunkData) tc), Hunk.view((ChunkGenerator.BiomeGrid) tc),
|
||||
false);
|
||||
} catch (Throwable e) {
|
||||
Iris.error("======================================");
|
||||
e.printStackTrace();
|
||||
Iris.reportErrorChunk(x, z, e, "MCA");
|
||||
Iris.error("======================================");
|
||||
com.volmit.iris.util.nbt.mca.Chunk chunk = writer.getChunk(x, z);
|
||||
CompoundTag c = NBTWorld.getCompound(ERROR_BLOCK);
|
||||
for (int i = 0; i < 16; i++) {
|
||||
for (int j = 0; j < 16; j++) {
|
||||
chunk.setBlockStateAt(i, 0, j, c, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@RegionCoordinates
|
||||
public void generateRegion(int x, int z) {
|
||||
generateRegion(x, z, null);
|
||||
}
|
||||
|
||||
@RegionCoordinates
|
||||
public void generateRegion(int x, int z, PregenListener listener) {
|
||||
BurstExecutor e = burst.burst(1024);
|
||||
PregenTask.iterateRegion(x, z, (ii, jj) -> e.queue(() -> {
|
||||
if (listener != null) {
|
||||
listener.onChunkGenerating(ii, jj);
|
||||
}
|
||||
generateChunk(ii, jj);
|
||||
if (listener != null) {
|
||||
listener.onChunkGenerated(ii, jj);
|
||||
}
|
||||
}));
|
||||
|
||||
e.complete();
|
||||
}
|
||||
|
||||
@RegionCoordinates
|
||||
public File generateRegionToFile(int x, int z, PregenListener listener) {
|
||||
generateRegion(x, z, listener);
|
||||
flush();
|
||||
return writer.getRegionFile(x, z);
|
||||
}
|
||||
|
||||
public void flush() {
|
||||
writer.flushNow();
|
||||
}
|
||||
|
||||
public void save() {
|
||||
writer.save();
|
||||
}
|
||||
|
||||
public void close() {
|
||||
burst.shutdownAndAwait();
|
||||
engine.close();
|
||||
writer.close();
|
||||
}
|
||||
|
||||
public KList<Position2> getChunksInRegion(int x, int z) {
|
||||
try {
|
||||
return MCAUtil.sampleChunkPositions(writer.getRegionFile(x, z));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return EMPTYPOINTS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isHeadless() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hotload() {
|
||||
|
||||
}
|
||||
}
|
@ -16,8 +16,31 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.engine.framework;
|
||||
package com.volmit.iris.engine.platform;
|
||||
|
||||
public interface IrisAccessProvider {
|
||||
IrisAccess getAccess();
|
||||
import com.volmit.iris.core.project.loader.IrisData;
|
||||
import com.volmit.iris.engine.framework.Engine;
|
||||
import com.volmit.iris.engine.framework.EngineTarget;
|
||||
import com.volmit.iris.engine.framework.Hotloadable;
|
||||
import com.volmit.iris.util.data.DataProvider;
|
||||
|
||||
public interface PlatformChunkGenerator extends Hotloadable, DataProvider {
|
||||
Engine getEngine();
|
||||
|
||||
boolean isHeadless();
|
||||
|
||||
@Override
|
||||
default IrisData getData()
|
||||
{
|
||||
return getEngine().getData();
|
||||
}
|
||||
|
||||
default EngineTarget getTarget()
|
||||
{
|
||||
return getEngine().getTarget();
|
||||
}
|
||||
|
||||
void close();
|
||||
|
||||
boolean isStudio();
|
||||
}
|
@ -18,6 +18,7 @@
|
||||
|
||||
package com.volmit.iris.util.plugin;
|
||||
|
||||
import com.google.common.collect.Comparators;
|
||||
import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.core.IrisSettings;
|
||||
import com.volmit.iris.util.collection.KList;
|
||||
@ -26,6 +27,9 @@ import org.bukkit.Sound;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
|
||||
/**
|
||||
* Represents a pawn command
|
||||
@ -197,6 +201,8 @@ public abstract class MortarCommand implements ICommand {
|
||||
}
|
||||
}
|
||||
|
||||
p.sort(Comparator.comparing(MortarCommand::getNode));
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user