mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2025-12-30 20:39:21 +00:00
sync
This commit is contained in:
@@ -397,6 +397,10 @@ public class SchemaBuilder {
|
||||
description.add(SYMBOL_LIMIT__N + " Requires at least " + t.min() + " entries.");
|
||||
}
|
||||
}
|
||||
if (t.max() > 0) {
|
||||
prop.put("maxItems", t.max());
|
||||
description.add(SYMBOL_LIMIT__N + " Maximum allowed entries are " + t.max() + ".");
|
||||
}
|
||||
|
||||
String arrayType = getType(t.type());
|
||||
|
||||
|
||||
@@ -21,10 +21,11 @@ package com.volmit.iris.engine;
|
||||
import com.google.common.util.concurrent.AtomicDouble;
|
||||
import com.google.gson.Gson;
|
||||
import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.core.IrisSettings;
|
||||
import com.volmit.iris.core.ServerConfigurator;
|
||||
import com.volmit.iris.core.events.IrisEngineHotloadEvent;
|
||||
import com.volmit.iris.core.gui.PregeneratorJob;
|
||||
import com.volmit.iris.core.nms.IMemoryWorld;
|
||||
import com.volmit.iris.core.nms.INMS;
|
||||
import com.volmit.iris.core.nms.container.BlockPos;
|
||||
import com.volmit.iris.core.nms.container.Pair;
|
||||
import com.volmit.iris.core.project.IrisProject;
|
||||
@@ -53,21 +54,24 @@ import com.volmit.iris.util.scheduling.PrecisionStopwatch;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.apache.commons.lang3.function.Failable;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.WorldCreator;
|
||||
import org.bukkit.block.Biome;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.persistence.PersistentDataType;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.HashSet;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
@Data
|
||||
@EqualsAndHashCode(exclude = "context")
|
||||
@@ -96,6 +100,8 @@ public class IrisEngine implements Engine {
|
||||
private EngineEffects effects;
|
||||
private EngineExecutionEnvironment execution;
|
||||
private EngineWorldManager worldManager;
|
||||
private IMemoryWorld memoryWorld;
|
||||
private IrisMerger merger;
|
||||
private volatile int parallelism;
|
||||
private volatile int minHeight;
|
||||
private boolean failing;
|
||||
@@ -127,6 +133,7 @@ public class IrisEngine implements Engine {
|
||||
context = new IrisContext(this);
|
||||
cleaning = new AtomicBoolean(false);
|
||||
context.touch();
|
||||
merger = new IrisMerger();
|
||||
getData().setEngine(this);
|
||||
getData().loadPrefetch(this);
|
||||
Iris.info("Initializing Engine: " + target.getWorld().name() + "/" + target.getDimension().getLoadKey() + " (" + target.getDimension().getDimensionHeight() + " height) Seed: " + getSeedManager().getSeed());
|
||||
@@ -192,6 +199,20 @@ public class IrisEngine implements Engine {
|
||||
mode = getDimension().getMode().getType().create(this);
|
||||
}
|
||||
|
||||
private void setupMemoryWorld(@Nullable NamespacedKey key, WorldCreator creator) {
|
||||
try {
|
||||
NamespacedKey dk = NamespacedKey.minecraft("memory_current_creator");
|
||||
var per = memoryWorld.getBukkit().getPersistentDataContainer();
|
||||
if (Objects.equals(per.get(dk, PersistentDataType.STRING), creator.toString())) return;
|
||||
if (memoryWorld != null)
|
||||
memoryWorld.close();
|
||||
memoryWorld = getDimension().isEnableExperimentalMerger() ? Failable.get(() -> key == null ? INMS.get().createMemoryWorld(creator) : INMS.get().createMemoryWorld(key, creator)) : null; // todo: experimental
|
||||
per.set(dk, PersistentDataType.STRING, creator.toString());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generateMatter(int x, int z, boolean multicore, ChunkContext context) {
|
||||
getMantle().generateMatter(x, z, multicore, context);
|
||||
|
||||
@@ -25,6 +25,7 @@ import com.volmit.iris.core.gui.components.Renderer;
|
||||
import com.volmit.iris.core.link.Identifier;
|
||||
import com.volmit.iris.core.loader.IrisData;
|
||||
import com.volmit.iris.core.loader.IrisRegistrant;
|
||||
import com.volmit.iris.core.nms.IMemoryWorld;
|
||||
import com.volmit.iris.core.nms.container.BlockPos;
|
||||
import com.volmit.iris.core.nms.container.Pair;
|
||||
import com.volmit.iris.core.service.ExternalDataSVC;
|
||||
@@ -108,6 +109,10 @@ public interface Engine extends DataProvider, Fallible, LootProvider, BlockUpdat
|
||||
|
||||
EngineExecutionEnvironment getExecution();
|
||||
|
||||
IMemoryWorld getMemoryWorld();
|
||||
|
||||
IrisMerger getMerger();
|
||||
|
||||
double getMaxBiomeObjectDensity();
|
||||
|
||||
double getMaxBiomeDecoratorDensity();
|
||||
|
||||
@@ -144,10 +144,11 @@ public class IrisDimension extends IrisRegistrant {
|
||||
@RegistryListResource(IrisJigsawStructure.class)
|
||||
@Desc("If defined, Iris will place the given jigsaw structure where minecraft should place the overworld stronghold.")
|
||||
private String stronghold;
|
||||
// @Desc("Iris merger") V4 Feature
|
||||
// private IrisMerger merger = new IrisMerger();
|
||||
@Desc("Cheap temp solution till v4 arrives")
|
||||
private boolean vanillaUnderground = true;
|
||||
@ArrayType(max = 1, type = IrisMerger.class)
|
||||
@Desc("Iris merger [Experimental] ( Deprecated for v3 )")
|
||||
private IrisMerger merger;
|
||||
@Desc("Cheap temp solution till v4 arrives [ Enables the experimental merger ] Requires studio restart to take effect!")
|
||||
private boolean EnableExperimentalMerger = true;
|
||||
@Desc("If set to true, Iris will remove chunks to allow visualizing cross sections of chunks easily")
|
||||
private boolean debugChunkCrossSections = false;
|
||||
@Desc("Vertically split up the biome palettes with 3 air blocks in between to visualize them")
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.volmit.iris.engine.object;
|
||||
|
||||
import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.core.nms.INMS;
|
||||
import com.volmit.iris.engine.framework.Engine;
|
||||
import com.volmit.iris.engine.object.annotations.ArrayType;
|
||||
import com.volmit.iris.engine.object.annotations.Desc;
|
||||
@@ -7,7 +9,10 @@ import com.volmit.iris.engine.platform.BukkitChunkGenerator;
|
||||
import com.volmit.iris.util.collection.KList;
|
||||
import com.volmit.iris.util.context.ChunkContext;
|
||||
import com.volmit.iris.util.documentation.BlockCoordinates;
|
||||
import com.volmit.iris.util.format.Form;
|
||||
import com.volmit.iris.util.hunk.Hunk;
|
||||
import com.volmit.iris.util.math.RollingSequence;
|
||||
import com.volmit.iris.util.scheduling.PrecisionStopwatch;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
@@ -15,46 +20,71 @@ import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.Accessors;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.generator.ChunkGenerator;
|
||||
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Desc("Dimension Merging only supports 1 for now.")
|
||||
@Data
|
||||
public class IrisMerger {
|
||||
|
||||
private RollingSequence mergeDuration;
|
||||
private Engine engine;
|
||||
|
||||
@Desc("Selected Generator")
|
||||
private String generator;
|
||||
|
||||
//
|
||||
@Desc("Uses the generator as a datapack key")
|
||||
private boolean datapackMode;
|
||||
//
|
||||
// @Desc("Merging strategy")
|
||||
// private IrisMergeStrategies mode;
|
||||
|
||||
@Desc("Merging strategy")
|
||||
private IrisMergeStrategies mode;
|
||||
@Desc("How deep till it should use vanilla terrain")
|
||||
private int depth = 10;
|
||||
|
||||
/**
|
||||
* Merges caves from a selected chunk into the corresponding chunk in the outcome world.
|
||||
* This is calling 1/16th of a chunk x/z slice. It is a plane from sky to bedrock 1 thick in the x direction.
|
||||
*
|
||||
* @param x the chunk x in blocks
|
||||
* @param z the chunk z in blocks
|
||||
* @param xf the current x slice
|
||||
* @param h the blockdata
|
||||
* Merges underground from a selected chunk into the corresponding chunk in the outcome world.
|
||||
*/
|
||||
@BlockCoordinates
|
||||
private void terrainMergeSliver(int x, int z, int xf, Hunk<BlockData> h, Engine engine) {
|
||||
int zf, realX, realZ, hf, he;
|
||||
|
||||
for (zf = 0; zf < h.getDepth(); zf++) {
|
||||
realX = xf + x;
|
||||
realZ = zf + z;
|
||||
|
||||
for (int i = h.getHeight(); i >= 0; i--) {
|
||||
|
||||
|
||||
@Deprecated
|
||||
public void generateVanillaUnderground(int x, int z, Engine engine) {
|
||||
if (engine.getMemoryWorld() == null || engine.getWorld() == null)
|
||||
throw new NullPointerException();
|
||||
PrecisionStopwatch p = PrecisionStopwatch.start();
|
||||
Hunk<BlockData> vh = memoryWorldToHunk(engine.getMemoryWorld().getChunkData(x, z), engine);
|
||||
int totalHeight = engine.getMemoryWorld().getBukkit().getMaxHeight() - engine.getMemoryWorld().getBukkit().getMinHeight();
|
||||
int minHeight = Math.abs(engine.getMemoryWorld().getBukkit().getMinHeight());
|
||||
|
||||
ChunkContext context = new ChunkContext(x << 4, z << 4, engine.getComplex());
|
||||
for (int xx = 0; xx < 16; xx++) {
|
||||
for (int zz = 0; zz < 16; zz++) {
|
||||
for (int y = 0; y < totalHeight; y++) {
|
||||
//int height = engine.getHeight(x * 16 + xx, z * 16 + zz, true) - 10;
|
||||
int height = (int) Math.ceil(context.getHeight().get(xx,zz));
|
||||
if (y < height) {
|
||||
BlockData blockData = vh.get(xx, y, zz);
|
||||
if (blockData != null) {
|
||||
|
||||
INMS.get().setBlock(engine.getWorld().realWorld(), x * 16 + xx, y - minHeight , z * 16 + zz, blockData, 1042, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
mergeDuration.put(p.getMilliseconds());
|
||||
Iris.info("Vanilla merge average in: " + Form.duration(mergeDuration.getAverage(), 8));
|
||||
}
|
||||
|
||||
private Hunk<BlockData> memoryWorldToHunk(ChunkGenerator.ChunkData data, Engine engine) {
|
||||
Hunk<BlockData> h = Hunk.newArrayHunk(16, engine.getMemoryWorld().getBukkit().getMaxHeight() - engine.getMemoryWorld().getBukkit().getMinHeight(), 16);
|
||||
for (int x = 0; x < 16; x++) {
|
||||
for (int z = 0; z < 16; z++) {
|
||||
for (int y = 0; y < engine.getMemoryWorld().getBukkit().getMaxHeight() - engine.getMemoryWorld().getBukkit().getMinHeight(); y++) {
|
||||
BlockData block = data.getBlockData(x, y, z);
|
||||
h.set(x, y, z, block);
|
||||
}
|
||||
}
|
||||
}
|
||||
return h;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,4 +30,6 @@ public @interface ArrayType {
|
||||
Class<?> type();
|
||||
|
||||
int min() default 0;
|
||||
|
||||
int max() default Integer.MAX_VALUE;
|
||||
}
|
||||
|
||||
@@ -20,7 +20,6 @@ package com.volmit.iris.engine.platform;
|
||||
|
||||
import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.core.loader.IrisData;
|
||||
import com.volmit.iris.core.nms.IMemoryWorld;
|
||||
import com.volmit.iris.core.nms.INMS;
|
||||
import com.volmit.iris.core.service.StudioSVC;
|
||||
import com.volmit.iris.engine.IrisEngine;
|
||||
@@ -33,29 +32,23 @@ import com.volmit.iris.engine.object.StudioMode;
|
||||
import com.volmit.iris.engine.platform.studio.StudioGenerator;
|
||||
import com.volmit.iris.util.collection.KList;
|
||||
import com.volmit.iris.util.data.IrisBiomeStorage;
|
||||
import com.volmit.iris.util.format.Form;
|
||||
import com.volmit.iris.util.hunk.Hunk;
|
||||
import com.volmit.iris.util.hunk.view.BiomeGridHunkHolder;
|
||||
import com.volmit.iris.util.hunk.view.ChunkDataHunkHolder;
|
||||
import com.volmit.iris.util.io.ReactiveFolder;
|
||||
import com.volmit.iris.util.math.RollingSequence;
|
||||
import com.volmit.iris.util.misc.E;
|
||||
import com.volmit.iris.util.scheduling.ChronoLatch;
|
||||
import com.volmit.iris.util.scheduling.J;
|
||||
import com.volmit.iris.util.scheduling.Looper;
|
||||
import com.volmit.iris.util.scheduling.PrecisionStopwatch;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Setter;
|
||||
import org.apache.commons.lang3.Functions;
|
||||
import org.apache.commons.lang3.function.Failable;
|
||||
import org.bukkit.*;
|
||||
import org.bukkit.block.Biome;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.world.ChunkLoadEvent;
|
||||
import org.bukkit.event.world.WorldInitEvent;
|
||||
@@ -92,7 +85,6 @@ public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChun
|
||||
private final KList<BlockPopulator> populators;
|
||||
private final ChronoLatch hotloadChecker;
|
||||
private final AtomicBoolean setup;
|
||||
private IMemoryWorld memoryWorld;
|
||||
private final boolean studio;
|
||||
private final AtomicInteger a = new AtomicInteger(0);
|
||||
private final CompletableFuture<Integer> spawnChunks = new CompletableFuture<>();
|
||||
@@ -115,13 +107,6 @@ public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChun
|
||||
loadLock = new Semaphore(LOAD_LOCKS);
|
||||
this.world = world;
|
||||
this.mergeDuration = new RollingSequence(20);
|
||||
try {
|
||||
this.memoryWorld = INMS.get().createMemoryWorld(NamespacedKey.minecraft("overworld"), new WorldCreator("terrain"));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
//this.memoryWorld = engine.getDimension().isVanillaUnderground() ? Failable.get(() -> INMS.get().createMemoryWorld(NamespacedKey.minecraft("overworld"), new WorldCreator("terrain"))) : null;
|
||||
this.hotloadChecker = new ChronoLatch(1000, false);
|
||||
this.studio = studio;
|
||||
this.dataLocation = dataLocation;
|
||||
@@ -404,46 +389,8 @@ public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChun
|
||||
|
||||
@EventHandler
|
||||
private void onChunkGeneration(ChunkLoadEvent event) {
|
||||
if(!event.isNewChunk() || !engine.getWorld().realWorld().equals(event.getWorld()) || !engine.getDimension().isVanillaUnderground()) return;
|
||||
generateVanillaUnderground(event.getChunk().getX(), event.getChunk().getZ());
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
private void generateVanillaUnderground(int x, int z) {
|
||||
if (memoryWorld == null || engine.getWorld() == null)
|
||||
throw new NullPointerException();
|
||||
PrecisionStopwatch p = PrecisionStopwatch.start();
|
||||
Hunk<BlockData> vh = toHunk(memoryWorld.getChunkData(x, z));
|
||||
int totalHeight = memoryWorld.getBukkit().getMaxHeight() - memoryWorld.getBukkit().getMinHeight();
|
||||
int minHeight = memoryWorld.getBukkit().getMinHeight();
|
||||
|
||||
for (int xx = 0; xx < 16; xx++) {
|
||||
for (int zz = 0; zz < 16; zz++) {
|
||||
for (int y = 0; y < totalHeight; y++) {
|
||||
if (y < engine.getHeight(x * 16 + xx, z * 16 + zz, false) - 10) {
|
||||
BlockData blockData = vh.get(xx, y, zz);
|
||||
if (blockData != null) {
|
||||
INMS.get().setBlock(world.realWorld(), x * 16 + xx, y - minHeight , z * 16 + zz, blockData, 1042, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
mergeDuration.put(p.getMilliseconds());
|
||||
Iris.info("Vanilla merge average in: " + Form.duration(mergeDuration.getAverage(), 8));
|
||||
}
|
||||
|
||||
private Hunk<BlockData> toHunk(ChunkGenerator.ChunkData data) {
|
||||
Hunk<BlockData> h = Hunk.newArrayHunk(16, memoryWorld.getBukkit().getMaxHeight() - memoryWorld.getBukkit().getMinHeight(), 16);
|
||||
for (int x = 0; x < 16; x++) {
|
||||
for (int z = 0; z < 16; z++) {
|
||||
for (int y = 0; y < memoryWorld.getBukkit().getMaxHeight() - memoryWorld.getBukkit().getMinHeight(); y++) {
|
||||
BlockData block = data.getBlockData(x, y, z);
|
||||
h.set(x, y, z, block);
|
||||
}
|
||||
}
|
||||
}
|
||||
return h;
|
||||
if(!event.isNewChunk() || !engine.getWorld().realWorld().equals(event.getWorld()) || !engine.getDimension().isEnableExperimentalMerger() || engine.getMemoryWorld() != null) return;
|
||||
engine.getMerger().generateVanillaUnderground(event.getChunk().getX(), event.getChunk().getZ(), engine);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user