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

This commit is contained in:
CocoTheOwner 2021-09-07 17:41:41 +02:00
commit a060c01f58
32 changed files with 239 additions and 224 deletions

View File

@ -33,9 +33,12 @@ body:
label: Minecraft Version label: Minecraft Version
description: What version of Minecraft is the server on? description: What version of Minecraft is the server on?
options: options:
- 1.14 to 1.16.5 - 1.14.X
- 1.17.x - 1.15.X
- 1.18.x - 1.16.X
- 1.17
- 1.17.1
- 1.18
validations: validations:
required: true required: true
- type: input - type: input
@ -54,16 +57,6 @@ body:
placeholder: https://mslog.gs/... placeholder: https://mslog.gs/...
validations: validations:
required: true required: true
- type: checkboxes
id: checksum
attributes:
label: Checklist
description: Please ensure you meet each of the requirements below
options:
- label: I am using an unmodified version of Iris. (If you modified the plugin and see an issue, make sure it is reproducable on the latest spigot version or contact [support](https://discord.gg/volmit))
required: true
- label: I am using Spigot, Paper, Tuinity, or Purpur. (If you are not, and still think it is a valid issue, contact [support](https://discord.gg/volmit))
required: true
- type: markdown - type: markdown
id: thanks id: thanks
attributes: attributes:

View File

@ -22,7 +22,7 @@ plugins {
} }
group 'com.volmit.iris' group 'com.volmit.iris'
version '1.8.4' version '1.8.6'
def apiVersion = '1.17' def apiVersion = '1.17'
def name = getRootProject().getName() // Defined in settings.gradle def name = getRootProject().getName() // Defined in settings.gradle
def main = 'com.volmit.iris.Iris' def main = 'com.volmit.iris.Iris'

View File

@ -501,7 +501,7 @@ public class Iris extends VolmitPlugin implements Listener {
IrisWorld w = IrisWorld.builder() IrisWorld w = IrisWorld.builder()
.name(worldName) .name(worldName)
.seed(RNG.r.lmax()) .seed(1337)
.environment(dim.getEnvironment()) .environment(dim.getEnvironment())
.worldFolder(new File(worldName)) .worldFolder(new File(worldName))
.minHeight(0) .minHeight(0)

View File

@ -162,6 +162,16 @@ public class CommandIris implements DecreeExecutor {
Iris.service(StudioSVC.class).downloadSearch(sender(), "IrisDimensions/" + pack + "/" + branch, trim, overwrite); Iris.service(StudioSVC.class).downloadSearch(sender(), "IrisDimensions/" + pack + "/" + branch, trim, overwrite);
} }
@Decree(description = "Get metrics for your world", aliases = "measure", origin = DecreeOrigin.PLAYER)
public void metrics() {
if (!IrisToolbelt.isIrisWorld(world())) {
sender().sendMessage(C.RED + "You must be in an Iris world");
return;
}
sender().sendMessage(C.GREEN + "Sending metrics...");
engine().printMetrics(sender());
}
@Decree(description = "Reload configuration file (this is also done automatically)") @Decree(description = "Reload configuration file (this is also done automatically)")
public void reload() { public void reload() {
IrisSettings.invalidate(); IrisSettings.invalidate();

View File

@ -107,7 +107,7 @@ public class CommandObject implements DecreeExecutor {
sender().playSound(Sound.AMBIENT_SOUL_SAND_VALLEY_ADDITIONS, 1f, 1.5f); sender().playSound(Sound.AMBIENT_SOUL_SAND_VALLEY_ADDITIONS, 1f, 1.5f);
} }
@Decree(description = "Contract a selection based on your looking direction") @Decree(description = "Contract a selection based on your looking direction", aliases = "-")
public void contract( public void contract(
@Param(description = "The amount to inset by", defaultValue = "1") @Param(description = "The amount to inset by", defaultValue = "1")
int amount int amount
@ -345,7 +345,7 @@ public class CommandObject implements DecreeExecutor {
sender().sendMessage(C.GREEN + "Successfully object to saved: " + dimension.getLoadKey() + "/objects/" + name); sender().sendMessage(C.GREEN + "Successfully object to saved: " + dimension.getLoadKey() + "/objects/" + name);
} }
@Decree(description = "Shift a selection in your looking direction") @Decree(description = "Shift a selection in your looking direction", aliases = "-")
public void shift( public void shift(
@Param(description = "The amount to shift by", defaultValue = "1") @Param(description = "The amount to shift by", defaultValue = "1")
int amount int amount
@ -369,7 +369,7 @@ public class CommandObject implements DecreeExecutor {
sender().playSound(Sound.ENTITY_ITEM_FRAME_ROTATE_ITEM, 1f, 0.55f); sender().playSound(Sound.ENTITY_ITEM_FRAME_ROTATE_ITEM, 1f, 0.55f);
} }
@Decree(description = "Undo a number of pastes") @Decree(description = "Undo a number of pastes", aliases = "-")
public void undo( public void undo(
@Param(description = "The amount of pastes to undo", defaultValue = "1") @Param(description = "The amount of pastes to undo", defaultValue = "1")
int amount int amount

View File

@ -65,7 +65,7 @@ public class CommandPregen implements DecreeExecutor {
} }
} }
@Decree(description = "Pause / continue the active pregeneration task", aliases = {"resume", "unpause"}) @Decree(description = "Pause / continue the active pregeneration task", aliases = {"t", "resume", "unpause"})
public void pause() { public void pause() {
if (PregeneratorJob.pauseResume()) { if (PregeneratorJob.pauseResume()) {
sender().sendMessage(C.GREEN + "Paused/unpaused pregeneration task, now: " + (PregeneratorJob.isPaused() ? "Paused" : "Running") + "."); sender().sendMessage(C.GREEN + "Paused/unpaused pregeneration task, now: " + (PregeneratorJob.isPaused() ? "Paused" : "Running") + ".");

View File

@ -79,9 +79,9 @@ import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future; import java.util.concurrent.Future;
import java.util.function.Supplier; import java.util.function.Supplier;
@Decree(name = "studio", aliases = {"std"}, description = "Studio Commands", studio = true) @Decree(name = "studio", aliases = {"std", "s"}, description = "Studio Commands", studio = true)
public class CommandStudio implements DecreeExecutor { public class CommandStudio implements DecreeExecutor {
@Decree(description = "Open a new studio world", sync = true) @Decree(description = "Open a new studio world", aliases = "o", sync = true)
public void open( public void open(
@Param(defaultValue = "overworld", description = "The dimension to open a studio for", aliases = "dim") @Param(defaultValue = "overworld", description = "The dimension to open a studio for", aliases = "dim")
IrisDimension dimension, IrisDimension dimension,
@ -91,7 +91,7 @@ public class CommandStudio implements DecreeExecutor {
Iris.service(StudioSVC.class).open(sender(), seed, dimension.getLoadKey()); Iris.service(StudioSVC.class).open(sender(), seed, dimension.getLoadKey());
} }
@Decree(description = "Open VSCode for a dimension", aliases = {"edit"}) @Decree(description = "Open VSCode for a dimension", aliases = {"vsc", "edit"})
public void vscode( public void vscode(
@Param(defaultValue = "overworld", description = "The dimension to open VSCode for", aliases = "dim") @Param(defaultValue = "overworld", description = "The dimension to open VSCode for", aliases = "dim")
IrisDimension dimension IrisDimension dimension
@ -100,7 +100,7 @@ public class CommandStudio implements DecreeExecutor {
Iris.service(StudioSVC.class).openVSCode(sender(), dimension.getLoadKey()); Iris.service(StudioSVC.class).openVSCode(sender(), dimension.getLoadKey());
} }
@Decree(description = "Close an open studio project", aliases = {"x"}, sync = true) @Decree(description = "Close an open studio project", aliases = {"x", "c"}, sync = true)
public void close() { public void close() {
if (!Iris.service(StudioSVC.class).isProjectOpen()) { if (!Iris.service(StudioSVC.class).isProjectOpen()) {
sender().sendMessage(C.RED + "No open studio projects."); sender().sendMessage(C.RED + "No open studio projects.");
@ -111,7 +111,7 @@ public class CommandStudio implements DecreeExecutor {
sender().sendMessage(C.GREEN + "Project Closed."); sender().sendMessage(C.GREEN + "Project Closed.");
} }
@Decree(description = "Create a new studio project", sync = true) @Decree(description = "Create a new studio project", aliases = "+", sync = true)
public void create( public void create(
@Param(description = "The name of this new Iris Project.") @Param(description = "The name of this new Iris Project.")
String name, String name,
@ -262,7 +262,7 @@ public class CommandStudio implements DecreeExecutor {
} }
@Decree(description = "Edit the biome you are currently in", aliases = {"eb"}, origin = DecreeOrigin.PLAYER) @Decree(description = "Edit the biome you are currently in", aliases = {"ebiome", "eb"}, origin = DecreeOrigin.PLAYER)
public void editbiome( public void editbiome(
@Param(contextual = true, description = "The biome to edit") @Param(contextual = true, description = "The biome to edit")
IrisBiome biome IrisBiome biome
@ -309,7 +309,7 @@ public class CommandStudio implements DecreeExecutor {
engine().getWorldManager().chargeEnergy(); engine().getWorldManager().chargeEnergy();
} }
@Decree(description = "Preview noise gens (External GUI)", aliases = {"generator"}) @Decree(description = "Preview noise gens (External GUI)", aliases = {"generator", "gen"})
public void explore( public void explore(
@Param(description = "The generator to explore", contextual = true) @Param(description = "The generator to explore", contextual = true)
IrisGenerator generator, IrisGenerator generator,
@ -330,7 +330,7 @@ public class CommandStudio implements DecreeExecutor {
NoiseExplorerGUI.launch(l, "Custom Generator"); NoiseExplorerGUI.launch(l, "Custom Generator");
} }
@Decree(description = "Find any biome or region", aliases = {"goto"}, origin = DecreeOrigin.PLAYER) @Decree(description = "Find any biome or region", aliases = {"goto", "g"}, origin = DecreeOrigin.PLAYER)
public void find( public void find(
@Param(description = "The biome or region to find", defaultValue = "null") @Param(description = "The biome or region to find", defaultValue = "null")
IrisBiome biome, IrisBiome biome,
@ -446,7 +446,7 @@ public class CommandStudio implements DecreeExecutor {
sender().sendMessage(C.GREEN + "Opening map!"); sender().sendMessage(C.GREEN + "Opening map!");
} }
@Decree(name = "package", description = "Package a dimension into a compressed format") @Decree(description = "Package a dimension into a compressed format", aliases = "package")
public void pkg( public void pkg(
@Param(name = "dimension", description = "The dimension pack to compress", contextual = true, defaultValue = "overworld") @Param(name = "dimension", description = "The dimension pack to compress", contextual = true, defaultValue = "overworld")
IrisDimension dimension, IrisDimension dimension,
@ -662,7 +662,7 @@ public class CommandStudio implements DecreeExecutor {
entity.spawn(engine(), new Location(world(), location.getX(), location.getY(), location.getZ())); entity.spawn(engine(), new Location(world(), location.getX(), location.getY(), location.getZ()));
} }
@Decree(description = "Teleport to the active studio world", aliases = {"tp"}, origin = DecreeOrigin.PLAYER, sync = true) @Decree(description = "Teleport to the active studio world", aliases = "stp", origin = DecreeOrigin.PLAYER, sync = true)
public void tpstudio() { public void tpstudio() {
if (!Iris.service(StudioSVC.class).isProjectOpen()) { if (!Iris.service(StudioSVC.class).isProjectOpen()) {
sender().sendMessage(C.RED + "No studio world is open!"); sender().sendMessage(C.RED + "No studio world is open!");
@ -691,7 +691,7 @@ public class CommandStudio implements DecreeExecutor {
} }
} }
@Decree(aliases = "nf", description = "Get the noise feature data in your chunk") @Decree(aliases = {"find-features", "nf"}, description = "Get the noise feature data in your chunk")
public void features() { public void features() {
if (!IrisToolbelt.isIrisWorld(player().getWorld())) { if (!IrisToolbelt.isIrisWorld(player().getWorld())) {
@ -706,7 +706,7 @@ public class CommandStudio implements DecreeExecutor {
} }
} }
@Decree(description = "Get information about nearby structures") @Decree(aliases = "find-objects", description = "Get information about nearby structures")
public void objects() { public void objects() {
if (!IrisToolbelt.isIrisWorld(player().getWorld())) { if (!IrisToolbelt.isIrisWorld(player().getWorld())) {
sender().sendMessage(C.RED + "You must be in an Iris world"); sender().sendMessage(C.RED + "You must be in an Iris world");

View File

@ -97,7 +97,7 @@ public class IrisPapiExpansion extends PlaceholderExpansion {
} }
} else if (p.equalsIgnoreCase("world_seed")) { } else if (p.equalsIgnoreCase("world_seed")) {
if (a != null) { if (a != null) {
return a.getTarget().getWorld().seed() + ""; return a.getEngine().getSeedManager().getSeed() + "";
} }
} else if (p.equalsIgnoreCase("world_speed")) { } else if (p.equalsIgnoreCase("world_speed")) {
if (a != null) { if (a != null) {

View File

@ -60,7 +60,7 @@ public class IrisCreator {
/** /**
* The seed to use for this generator * The seed to use for this generator
*/ */
private long seed = RNG.r.nextLong(); private long seed = 1337;
/** /**
* The dimension to use. This can be any online dimension, or a dimension in the * The dimension to use. This can be any online dimension, or a dimension in the

View File

@ -21,6 +21,7 @@ package com.volmit.iris.engine;
import com.google.common.util.concurrent.AtomicDouble; import com.google.common.util.concurrent.AtomicDouble;
import com.volmit.iris.Iris; import com.volmit.iris.Iris;
import com.volmit.iris.core.loader.IrisData; import com.volmit.iris.core.loader.IrisData;
import com.volmit.iris.engine.data.cache.Cache;
import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.framework.Engine;
import com.volmit.iris.engine.object.*; import com.volmit.iris.engine.object.*;
import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.collection.KList;
@ -69,8 +70,6 @@ public class IrisComplex implements DataProvider {
private ProceduralStream<Integer> trueHeightStreamNoFeatures; private ProceduralStream<Integer> trueHeightStreamNoFeatures;
private ProceduralStream<Double> slopeStream; private ProceduralStream<Double> slopeStream;
private ProceduralStream<Integer> topSurfaceStream; private ProceduralStream<Integer> topSurfaceStream;
private ProceduralStream<RNG> rngStream;
private ProceduralStream<RNG> chunkRngStream;
private ProceduralStream<IrisDecorator> terrainSurfaceDecoration; private ProceduralStream<IrisDecorator> terrainSurfaceDecoration;
private ProceduralStream<IrisDecorator> terrainCeilingDecoration; private ProceduralStream<IrisDecorator> terrainCeilingDecoration;
private ProceduralStream<IrisDecorator> terrainCaveSurfaceDecoration; private ProceduralStream<IrisDecorator> terrainCaveSurfaceDecoration;
@ -108,7 +107,7 @@ public class IrisComplex implements DataProvider {
int cacheSize = 131072; int cacheSize = 131072;
IrisBiome emptyBiome = new IrisBiome(); IrisBiome emptyBiome = new IrisBiome();
UUID focusUUID = UUID.nameUUIDFromBytes("focus".getBytes()); UUID focusUUID = UUID.nameUUIDFromBytes("focus".getBytes());
this.rng = new RNG(engine.getWorld().seed()); this.rng = new RNG(engine.getSeedManager().getComplex());
this.data = engine.getData(); this.data = engine.getData();
double height = engine.getHeight(); double height = engine.getHeight();
fluidHeight = engine.getDimension().getFluidHeight(); fluidHeight = engine.getDimension().getFluidHeight();
@ -121,7 +120,6 @@ public class IrisComplex implements DataProvider {
} }
IrisRegion focusRegion = focus != null ? findRegion(focus, engine) : null; IrisRegion focusRegion = focus != null ? findRegion(focus, engine) : null;
RNG rng = new RNG(engine.getWorld().seed());
//@builder //@builder
engine.getDimension().getRegions().forEach((i) -> data.getRegionLoader().load(i) engine.getDimension().getRegions().forEach((i) -> data.getRegionLoader().load(i)
.getAllBiomes(this).forEach((b) -> b .getAllBiomes(this).forEach((b) -> b
@ -129,9 +127,6 @@ public class IrisComplex implements DataProvider {
.forEach((c) -> registerGenerator(c.getCachedGenerator(this))))); .forEach((c) -> registerGenerator(c.getCachedGenerator(this)))));
overlayStream = ProceduralStream.ofDouble((x, z) -> 0D); overlayStream = ProceduralStream.ofDouble((x, z) -> 0D);
engine.getDimension().getOverlayNoise().forEach((i) -> overlayStream.add((x, z) -> i.get(rng, getData(), x, z))); engine.getDimension().getOverlayNoise().forEach((i) -> overlayStream.add((x, z) -> i.get(rng, getData(), x, z)));
rngStream = ProceduralStream.of((x, z) -> new RNG(((x.longValue()) << 32) | (z.longValue() & 0xffffffffL))
.nextParallelRNG(engine.getWorld().seed()), Interpolated.RNG);
chunkRngStream = rngStream.blockToChunkCoords();
rockStream = engine.getDimension().getRockPalette().getLayerGenerator(rng.nextParallelRNG(45), data).stream() rockStream = engine.getDimension().getRockPalette().getLayerGenerator(rng.nextParallelRNG(45), data).stream()
.select(engine.getDimension().getRockPalette().getBlockData(data)); .select(engine.getDimension().getRockPalette().getBlockData(data));
fluidStream = engine.getDimension().getFluidPalette().getLayerGenerator(rng.nextParallelRNG(78), data).stream() fluidStream = engine.getDimension().getFluidPalette().getLayerGenerator(rng.nextParallelRNG(78), data).stream()
@ -198,11 +193,11 @@ public class IrisComplex implements DataProvider {
.convertAware2D(this::implode).cache2D(cacheSize); .convertAware2D(this::implode).cache2D(cacheSize);
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(), true); return getHeight(engine, b, x, z, engine.getSeedManager().getHeight(), true);
}, Interpolated.DOUBLE).clamp(0, engine.getHeight()).cache2D(cacheSize); }, Interpolated.DOUBLE).clamp(0, engine.getHeight()).cache2D(cacheSize);
heightStreamNoFeatures = ProceduralStream.of((x, z) -> { heightStreamNoFeatures = 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(), false); return getHeight(engine, b, x, z, engine.getSeedManager().getHeight(), false);
}, Interpolated.DOUBLE).clamp(0, engine.getHeight()).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) -> {
@ -332,7 +327,7 @@ public class IrisComplex implements DataProvider {
} }
private IrisDecorator decorateFor(IrisBiome b, double x, double z, IrisDecorationPart part) { private IrisDecorator decorateFor(IrisBiome b, double x, double z, IrisDecorationPart part) {
RNG rngc = chunkRngStream.get(x, z); RNG rngc = new RNG(Cache.key(((int)x), ((int)z)));
for (IrisDecorator i : b.getDecorators()) { for (IrisDecorator i : b.getDecorators()) {
if (!i.getPartOf().equals(part)) { if (!i.getPartOf().equals(part)) {

View File

@ -100,10 +100,14 @@ public class IrisEngine implements Engine {
private final AtomicCache<IrisEngineData> engineData = new AtomicCache<>(); private final AtomicCache<IrisEngineData> engineData = new AtomicCache<>();
private final AtomicBoolean cleaning; private final AtomicBoolean cleaning;
private final ChronoLatch cleanLatch; private final ChronoLatch cleanLatch;
private final SeedManager seedManager;
public IrisEngine(EngineTarget target, boolean studio) { public IrisEngine(EngineTarget target, boolean studio) {
this.studio = studio; this.studio = studio;
this.target = target; this.target = target;
getEngineData();
verifySeed();
this.seedManager = new SeedManager(target.getWorld().getRawWorldSeed());
bud = new AtomicInteger(0); bud = new AtomicInteger(0);
buds = new AtomicInteger(0); buds = new AtomicInteger(0);
metrics = new EngineMetrics(32); metrics = new EngineMetrics(32);
@ -120,9 +124,8 @@ public class IrisEngine implements Engine {
context = new IrisContext(this); context = new IrisContext(this);
cleaning = new AtomicBoolean(false); cleaning = new AtomicBoolean(false);
context.touch(); context.touch();
Iris.info("Initializing Engine: " + target.getWorld().name() + "/" + target.getDimension().getLoadKey() + " (" + 256 + " height)"); Iris.info("Initializing Engine: " + target.getWorld().name() + "/" + target.getDimension().getLoadKey() + " (" + 256 + " height) Seed: " + getSeedManager().toString());
getData().setEngine(this); getData().setEngine(this);
getEngineData();
minHeight = 0; minHeight = 0;
failing = false; failing = false;
closed = false; closed = false;
@ -131,6 +134,13 @@ public class IrisEngine implements Engine {
Iris.debug("Engine Initialized " + getCacheID()); Iris.debug("Engine Initialized " + getCacheID());
} }
private void verifySeed() {
if(getEngineData().getSeed() != null && getEngineData().getSeed() != target.getWorld().getRawWorldSeed())
{
target.getWorld().setRawWorldSeed(getEngineData().getSeed());
}
}
private void tickRandomPlayer() { private void tickRandomPlayer() {
if (perSecondBudLatch.flip()) { if (perSecondBudLatch.flip()) {
buds.set(bud.get()); buds.set(bud.get());

View File

@ -39,7 +39,7 @@ public class IrisBiomeActuator extends EngineAssignedActuator<Biome> {
public IrisBiomeActuator(Engine engine) { public IrisBiomeActuator(Engine engine) {
super(engine, "Biome"); super(engine, "Biome");
rng = new RNG(engine.getWorld().seed() + 243995); rng = new RNG(engine.getSeedManager().getBiome());
} }
@BlockCoordinates @BlockCoordinates

View File

@ -52,7 +52,7 @@ public class IrisDecorantActuator extends EngineAssignedActuator<BlockData> {
public IrisDecorantActuator(Engine engine) { public IrisDecorantActuator(Engine engine) {
super(engine, "Decorant"); super(engine, "Decorant");
shouldRay = shouldRayDecorate(); shouldRay = shouldRayDecorate();
this.rng = new RNG(engine.getTarget().getWorld().seed()); this.rng = new RNG(engine.getSeedManager().getDecorator());
surfaceDecorator = new IrisSurfaceDecorator(getEngine()); surfaceDecorator = new IrisSurfaceDecorator(getEngine());
ceilingDecorator = new IrisCeilingDecorator(getEngine()); ceilingDecorator = new IrisCeilingDecorator(getEngine());
seaSurfaceDecorator = new IrisSeaSurfaceDecorator(getEngine()); seaSurfaceDecorator = new IrisSeaSurfaceDecorator(getEngine());

View File

@ -43,7 +43,7 @@ public class IrisTerrainNormalActuator extends EngineAssignedActuator<BlockData>
public IrisTerrainNormalActuator(Engine engine) { public IrisTerrainNormalActuator(Engine engine) {
super(engine, "Terrain"); super(engine, "Terrain");
rng = new RNG(engine.getWorld().seed()); rng = new RNG(engine.getSeedManager().getTerrain());
} }
@BlockCoordinates @BlockCoordinates

View File

@ -146,6 +146,8 @@ public interface Engine extends DataProvider, Fallible, LootProvider, BlockUpdat
saveEngineData(); saveEngineData();
} }
SeedManager getSeedManager();
void saveEngineData(); void saveEngineData();
default String getName() { default String getName() {

View File

@ -73,7 +73,7 @@ public abstract class EngineAssignedWorldManager extends EngineAssignedComponent
public void on(EntitySpawnEvent e) { public void on(EntitySpawnEvent e) {
if (e.getEntity().getWorld().equals(getTarget().getWorld().realWorld())) { if (e.getEntity().getWorld().equals(getTarget().getWorld().realWorld())) {
if (e.getEntityType().equals(EntityType.ENDER_SIGNAL)) { if (e.getEntityType().equals(EntityType.ENDER_SIGNAL)) {
KList<Position2> p = getEngine().getDimension().getStrongholds(getEngine().getWorld().seed()); KList<Position2> p = getEngine().getDimension().getStrongholds(getEngine().getSeedManager().getSpawn());
Position2 px = new Position2(e.getEntity().getLocation().getBlockX(), e.getEntity().getLocation().getBlockZ()); Position2 px = new Position2(e.getEntity().getLocation().getBlockX(), e.getEntity().getLocation().getBlockZ());
Position2 pr = null; Position2 pr = null;
double d = Double.MAX_VALUE; double d = Double.MAX_VALUE;

View File

@ -69,7 +69,7 @@ public interface EngineComponent {
} }
default long getSeed() { default long getSeed() {
return getTarget().getWorld().seed(); return getEngine().getSeedManager().getComponent();
} }
default int getParallelism() { default int getParallelism() {

View File

@ -0,0 +1,107 @@
/*
* 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.framework;
import com.volmit.iris.engine.object.NoiseStyle;
import com.volmit.iris.util.math.RNG;
import com.volmit.iris.util.noise.CNG;
import lombok.AccessLevel;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
@Data
public class SeedManager
{
////////////////////////////////////////////////////////////////////
private static final String IRIS_SIGNATURE = "Iris World Generator";
private static final long IRIS_TERRAIN_VERSION = 1;
////////////////////////////////////////////////////////////////////
@Setter(AccessLevel.NONE)
private long fullMixedSeed;
private final RNG rlock;
private final CNG soup;
private final long seed;
private final long complex;
private final long complexStreams;
private final long basic;
private final long height;
private final long component;
private final long script;
private final long mantle;
private final long entity;
private final long biome;
private final long decorator;
private final long terrain;
private final long spawn;
private final long jigsaw;
private final long carve;
private final long deposit;
private final long post;
public SeedManager(long seed)
{
soup = createSoup(seed);
rlock = new RNG(Double.doubleToLongBits(soup.fitDouble(Double.MIN_VALUE, Double.MAX_VALUE, seed + 1337, seed * 69, seed)));
this.seed = seed;
complex = of("complex");
complexStreams = of("complex_streams");
basic = of("basic");
height = of("height");
component = of("component");
script = of("script");
mantle = of("mantle");
entity = of("entity");
biome = of("biome");
decorator = of("decorator");
terrain = of("terrain");
spawn = of("spawn");
jigsaw = of("jigsaw");
carve = of("carve");
deposit = of("deposit");
post = of("post");
}
private long of(String name)
{
RNG rng = new RNG(name + IRIS_SIGNATURE + "::" + IRIS_TERRAIN_VERSION + ((seed + rlock.imax()) * rlock.lmax()));
long f = rlock.imax() * ((rlock.chance(0.5) ? 1 : -1) * (name.hashCode() + Double.doubleToLongBits(soup.fitDouble(Double.MIN_VALUE, Double.MAX_VALUE, rng.imax(), rng.imax(), rng.imax()))));
fullMixedSeed += (f * rlock.imax());
return f;
}
private CNG createSoup(long seed) {
RNG a = new RNG((seed - 2043905) * 4_385_677_888L);
RNG b = new RNG((seed * -305) + 45_858_458_555L);
RNG c = new RNG((seed * (a.lmax() - b.lmax())) + IRIS_SIGNATURE.hashCode());
RNG d = new RNG((seed - (c.lmax() * -IRIS_TERRAIN_VERSION)) + IRIS_TERRAIN_VERSION);
RNG e = new RNG((IRIS_TERRAIN_VERSION * 42) + IRIS_SIGNATURE);
double gsoup = 0;
int gk = a.i(1_000, 10_000);
for(char i : (a.s(4) + b.s(4) + c.s(4) + d.s(4) + e.s(4)).toCharArray())
{
gsoup += ((gk * b.d(3, Math.PI)) / c.d(10, 18 * Math.E)) + 6_549;
gsoup *= d.d(90.5, 1_234_567);
gsoup += e.d(39.95, 99.25);
}
return NoiseStyle.STATIC.create(new RNG(4_966_866 * Double.doubleToLongBits((gsoup * a.imax() + b.imax() + c.lmax() + d.lmax()) * e.lmax())));
}
}

View File

@ -46,7 +46,7 @@ public interface MantleComponent {
} }
default long seed() { default long seed() {
return getEngineMantle().getEngine().getTarget().getWorld().seed(); return getEngineMantle().getEngine().getSeedManager().getMantle();
} }
default BurstExecutor burst() { default BurstExecutor burst() {

View File

@ -38,7 +38,7 @@ public class MantleJigsawComponent extends IrisMantleComponent {
public MantleJigsawComponent(EngineMantle engineMantle) { public MantleJigsawComponent(EngineMantle engineMantle) {
super(engineMantle, MantleFlag.JIGSAW); super(engineMantle, MantleFlag.JIGSAW);
cng = NoiseStyle.STATIC.create(new RNG(engineMantle.getEngine().getWorld().seed() + 24398848585L)); cng = NoiseStyle.STATIC.create(new RNG(engineMantle.getEngine().getSeedManager().getJigsaw()));
} }
@Override @Override

View File

@ -51,7 +51,7 @@ public class IrisCarveModifier extends EngineAssignedModifier<BlockData> {
public IrisCarveModifier(Engine engine) { public IrisCarveModifier(Engine engine) {
super(engine, "Carve"); super(engine, "Carve");
rng = new RNG(getEngine().getWorld().seed() + 3297778).nextParallelRNG(67648777); rng = new RNG(getEngine().getSeedManager().getCarve());
} }
@Override @Override

View File

@ -38,7 +38,7 @@ public class IrisDepositModifier extends EngineAssignedModifier<BlockData> {
public IrisDepositModifier(Engine engine) { public IrisDepositModifier(Engine engine) {
super(engine, "Deposit"); super(engine, "Deposit");
rng = new RNG(getEngine().getWorld().seed() + 12938).nextParallelRNG(28348777); rng = new RNG(getEngine().getSeedManager().getDeposit());
} }
@Override @Override

View File

@ -40,7 +40,7 @@ public class IrisPostModifier extends EngineAssignedModifier<BlockData> {
public IrisPostModifier(Engine engine) { public IrisPostModifier(Engine engine) {
super(engine, "Post"); super(engine, "Post");
rng = new RNG(getEngine().getWorld().seed() + 12938).nextParallelRNG(28348777); rng = new RNG(getEngine().getSeedManager().getPost());
} }
@Override @Override

View File

@ -85,7 +85,7 @@ public class HeadlessWorld {
public World load() { public World load() {
World w = new WorldCreator(worldName) World w = new WorldCreator(worldName)
.environment(dimension.getEnvironment()) .environment(dimension.getEnvironment())
.seed(world.seed()) .seed(world.getRawWorldSeed())
.generator(new BukkitChunkGenerator(world, studio, dimension.getLoader().getDataFolder(), .generator(new BukkitChunkGenerator(world, studio, dimension.getLoader().getDataFolder(),
dimension.getLoadKey())) dimension.getLoadKey()))
.createWorld(); .createWorld();

View File

@ -28,6 +28,7 @@ public class IrisEngineData {
private IrisEngineStatistics statistics = new IrisEngineStatistics(); private IrisEngineStatistics statistics = new IrisEngineStatistics();
private KList<IrisEngineSpawnerCooldown> spawnerCooldowns = new KList<>(); private KList<IrisEngineSpawnerCooldown> spawnerCooldowns = new KList<>();
private KList<IrisEngineChunkData> chunks = new KList<>(); private KList<IrisEngineChunkData> chunks = new KList<>();
private Long seed = null;
public void removeChunk(int x, int z) { public void removeChunk(int x, int z) {
long k = Cache.key(x, z); long k = Cache.key(x, z);

View File

@ -109,7 +109,7 @@ public class IrisEntitySpawn implements IRare {
return null; return null;
} }
if (rng.aquire(() -> new RNG(g.getTarget().getWorld().seed() + 4)).i(1, getRarity()) == 1) { if (rng.aquire(() -> new RNG(g.getSeedManager().getEntity())).i(1, getRarity()) == 1) {
return spawn100(g, at); return spawn100(g, at);
} }
@ -123,7 +123,7 @@ public class IrisEntitySpawn implements IRare {
if (!irisEntity.getSurface().matches(at.clone().subtract(0, 1, 0).getBlock())) if (!irisEntity.getSurface().matches(at.clone().subtract(0, 1, 0).getBlock()))
return null; //Make sure it can spawn on the block return null; //Make sure it can spawn on the block
Entity e = irisEntity.spawn(g, at.add(0.5, 0, 0.5), rng.aquire(() -> new RNG(g.getTarget().getWorld().seed() + 4))); Entity e = irisEntity.spawn(g, at.add(0.5, 0, 0.5), rng.aquire(() -> new RNG(g.getSeedManager().getEntity())));
if (e != null) { if (e != null) {
Iris.debug("Spawned " + C.DARK_AQUA + "Entity<" + getEntity() + "> " + C.GREEN + e.getType() + C.LIGHT_PURPLE + " @ " + C.GRAY + e.getLocation().getX() + ", " + e.getLocation().getY() + ", " + e.getLocation().getZ()); Iris.debug("Spawned " + C.DARK_AQUA + "Entity<" + getEntity() + "> " + C.GREEN + e.getType() + C.LIGHT_PURPLE + " @ " + C.GRAY + e.getLocation().getX() + ", " + e.getLocation().getY() + ", " + e.getLocation().getZ());
} }

View File

@ -1,93 +0,0 @@
/*
* Iris is a World Generator for Minecraft Bukkit Servers
* Copyright (c) 2021 Arcane Arts (Volmit Software)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.volmit.iris.engine.object;
import com.volmit.iris.engine.data.cache.AtomicCache;
import com.volmit.iris.engine.framework.Engine;
import com.volmit.iris.engine.object.annotations.*;
import com.volmit.iris.util.math.RNG;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import org.bukkit.Location;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.event.entity.EntitySpawnEvent;
@Snippet("entity-spawn-override")
@Accessors(chain = true)
@NoArgsConstructor
@AllArgsConstructor
@Desc("Represents an entity spawn")
@Data
public class IrisEntitySpawnOverride {
@RegistryListResource(IrisEntity.class)
@Required
@Desc("The entity")
private String entity = "";
@Required
@Desc("If the following entity type spawns, spawn this entity. Set to unknown for any entity spawn")
private EntityType trigger = EntityType.UNKNOWN;
@Desc("If the source is triggered, cancel spawning the original entity instead of ADDING a new entity.")
private boolean cancelSourceSpawn = false;
@MinNumber(1)
@Desc("The 1 in RARITY chance for this entity to spawn")
private int rarity = 1;
private final transient AtomicCache<RNG> rng = new AtomicCache<>();
private final transient AtomicCache<IrisEntity> ent = new AtomicCache<>();
public Entity on(Engine g, Location at, EntityType t, EntitySpawnEvent ee) {
if (!trigger.equals(EntityType.UNKNOWN)) {
if (!trigger.equals(t)) {
return null;
}
}
Entity e = spawn(g, at);
if (e != null && isCancelSourceSpawn()) {
ee.setCancelled(true);
ee.getEntity().remove();
}
return e;
}
public Entity spawn(Engine g, Location at) {
if (getRealEntity(g) == null) {
return null;
}
if (rng.aquire(() -> new RNG(g.getTarget().getWorld().seed() + 4)).i(1, getRarity()) == 1) {
return getRealEntity(g).spawn(g, at, rng.aquire(() -> new RNG(g.getTarget().getWorld().seed() + 4)));
}
return null;
}
public IrisEntity getRealEntity(Engine g) {
return ent.aquire(() -> g.getData().getEntityLoader().load(getEntity()));
}
}

View File

@ -460,7 +460,7 @@ public class IrisObject extends IrisRegistrant {
if (yv < 0) { if (yv < 0) {
if (config.getMode().equals(ObjectPlaceMode.CENTER_HEIGHT)) { if (config.getMode().equals(ObjectPlaceMode.CENTER_HEIGHT)) {
y = (c != null ? c.getSurface() : placer.getHighest(x, z, getLoader(), config.isUnderwater())) + rty; y = (c != null ? c.getSurface() : placer.getHighest(x, z, getLoader(), config.isUnderwater())) + rty;
if (placer.isCarved(x, y, z) || placer.isCarved(x, y - 1, z)) { if (placer.isCarved(x, y, z) || placer.isCarved(x, y - 1, z) || placer.isCarved(x, y - 2, z) || placer.isCarved(x, y - 3, z)) {
bail = true; bail = true;
} }
} else if (config.getMode().equals(ObjectPlaceMode.MAX_HEIGHT) || config.getMode().equals(ObjectPlaceMode.STILT)) { } else if (config.getMode().equals(ObjectPlaceMode.MAX_HEIGHT) || config.getMode().equals(ObjectPlaceMode.STILT)) {
@ -471,7 +471,7 @@ public class IrisObject extends IrisRegistrant {
for (int j = z - (rotatedDimensions.getBlockZ() / 2) + offset.getBlockZ(); j <= z + (rotatedDimensions.getBlockZ() / 2) + offset.getBlockZ(); j++) { for (int j = z - (rotatedDimensions.getBlockZ() / 2) + offset.getBlockZ(); j <= z + (rotatedDimensions.getBlockZ() / 2) + offset.getBlockZ(); j++) {
int h = placer.getHighest(i, j, getLoader(), config.isUnderwater()) + rty; int h = placer.getHighest(i, j, getLoader(), config.isUnderwater()) + rty;
if (placer.isCarved(i, h, j)) { if (placer.isCarved(i, h, j) || placer.isCarved(i, h-1, j) || placer.isCarved(i, h-2, j) || placer.isCarved(i, h-3, j)) {
bail = true; bail = true;
break; break;
} }
@ -489,7 +489,7 @@ public class IrisObject extends IrisRegistrant {
for (int j = z - (rotatedDimensions.getBlockZ() / 2) + offset.getBlockZ(); j <= z + (rotatedDimensions.getBlockZ() / 2) + offset.getBlockZ(); j += (rotatedDimensions.getBlockZ() / 2) + 1) { for (int j = z - (rotatedDimensions.getBlockZ() / 2) + offset.getBlockZ(); j <= z + (rotatedDimensions.getBlockZ() / 2) + offset.getBlockZ(); j += (rotatedDimensions.getBlockZ() / 2) + 1) {
int h = placer.getHighest(i, j, getLoader(), config.isUnderwater()) + rty; int h = placer.getHighest(i, j, getLoader(), config.isUnderwater()) + rty;
if (placer.isCarved(i, h, j)) { if (placer.isCarved(i, h, j) || placer.isCarved(i, h-1, j) || placer.isCarved(i, h-2, j) || placer.isCarved(i, h-3, j)) {
bail = true; bail = true;
break; break;
} }
@ -507,7 +507,7 @@ public class IrisObject extends IrisRegistrant {
for (int i = x - (rotatedDimensions.getBlockX() / 2) + offset.getBlockX(); i <= x + (rotatedDimensions.getBlockX() / 2) + offset.getBlockX(); i++) { for (int i = x - (rotatedDimensions.getBlockX() / 2) + offset.getBlockX(); i <= x + (rotatedDimensions.getBlockX() / 2) + offset.getBlockX(); i++) {
for (int j = z - (rotatedDimensions.getBlockZ() / 2) + offset.getBlockZ(); j <= z + (rotatedDimensions.getBlockZ() / 2) + offset.getBlockZ(); j++) { for (int j = z - (rotatedDimensions.getBlockZ() / 2) + offset.getBlockZ(); j <= z + (rotatedDimensions.getBlockZ() / 2) + offset.getBlockZ(); j++) {
int h = placer.getHighest(i, j, getLoader(), config.isUnderwater()) + rty; int h = placer.getHighest(i, j, getLoader(), config.isUnderwater()) + rty;
if (placer.isCarved(i, h, j)) { if (placer.isCarved(i, h, j) || placer.isCarved(i, h-1, j) || placer.isCarved(i, h-2, j) || placer.isCarved(i, h-3, j)) {
bail = true; bail = true;
break; break;
} }
@ -524,7 +524,7 @@ public class IrisObject extends IrisRegistrant {
for (int i = x - (rotatedDimensions.getBlockX() / 2) + offset.getBlockX(); i <= x + (rotatedDimensions.getBlockX() / 2) + offset.getBlockX(); i += (rotatedDimensions.getBlockX() / 2) + 1) { for (int i = x - (rotatedDimensions.getBlockX() / 2) + offset.getBlockX(); i <= x + (rotatedDimensions.getBlockX() / 2) + offset.getBlockX(); i += (rotatedDimensions.getBlockX() / 2) + 1) {
for (int j = z - (rotatedDimensions.getBlockZ() / 2) + offset.getBlockZ(); j <= z + (rotatedDimensions.getBlockZ() / 2) + offset.getBlockZ(); j += (rotatedDimensions.getBlockZ() / 2) + 1) { for (int j = z - (rotatedDimensions.getBlockZ() / 2) + offset.getBlockZ(); j <= z + (rotatedDimensions.getBlockZ() / 2) + offset.getBlockZ(); j += (rotatedDimensions.getBlockZ() / 2) + 1) {
int h = placer.getHighest(i, j, getLoader(), config.isUnderwater()) + rty; int h = placer.getHighest(i, j, getLoader(), config.isUnderwater()) + rty;
if (placer.isCarved(i, h, j)) { if (placer.isCarved(i, h, j) || placer.isCarved(i, h-1, j) || placer.isCarved(i, h-2, j) || placer.isCarved(i, h-3, j)) {
bail = true; bail = true;
break; break;
} }
@ -535,20 +535,20 @@ public class IrisObject extends IrisRegistrant {
} }
} else if (config.getMode().equals(ObjectPlaceMode.PAINT)) { } else if (config.getMode().equals(ObjectPlaceMode.PAINT)) {
y = placer.getHighest(x, z, getLoader(), config.isUnderwater()) + rty; y = placer.getHighest(x, z, getLoader(), config.isUnderwater()) + rty;
if (placer.isCarved(x, y, z)) { if (placer.isCarved(x, y, z) || placer.isCarved(x, y-1, z)|| placer.isCarved(x, y-2, z)|| placer.isCarved(x, y-3, z)) {
bail = true; bail = true;
} }
} }
} else { } else {
y = yv; y = yv;
if (placer.isCarved(x, y, z)) { if (placer.isCarved(x, y, z) || placer.isCarved(x, y-1, z)|| placer.isCarved(x, y-2, z)|| placer.isCarved(x, y-3, z)) {
bail = true; bail = true;
} }
} }
if (yv >= 0 && config.isBottom()) { if (yv >= 0 && config.isBottom()) {
y += Math.floorDiv(h, 2); y += Math.floorDiv(h, 2);
bail = placer.isCarved(x, y, z); bail = placer.isCarved(x, y, z) || placer.isCarved(x, y-1, z)|| placer.isCarved(x, y-2, z)|| placer.isCarved(x, y-3, z);
} }
if (bail) { if (bail) {

View File

@ -21,8 +21,7 @@ package com.volmit.iris.engine.object;
import com.volmit.iris.Iris; import com.volmit.iris.Iris;
import com.volmit.iris.core.tools.IrisToolbelt; import com.volmit.iris.core.tools.IrisToolbelt;
import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.collection.KList;
import lombok.Builder; import lombok.*;
import lombok.Data;
import lombok.experimental.Accessors; import lombok.experimental.Accessors;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Location; import org.bukkit.Location;
@ -42,6 +41,9 @@ public class IrisWorld {
private static final KList<? extends Entity> NO_ENTITIES = new KList<>(); private static final KList<? extends Entity> NO_ENTITIES = new KList<>();
private String name; private String name;
private File worldFolder; private File worldFolder;
@Getter(AccessLevel.NONE)
@Setter(AccessLevel.NONE)
private long seed; private long seed;
private World.Environment environment; private World.Environment environment;
private World realWorld; private World realWorld;
@ -55,13 +57,22 @@ public class IrisWorld {
private static IrisWorld bindWorld(IrisWorld iw, World world) { private static IrisWorld bindWorld(IrisWorld iw, World world) {
return iw.name(world.getName()) return iw.name(world.getName())
.worldFolder(world.getWorldFolder()) .worldFolder(world.getWorldFolder())
.seed(world.getSeed())
.minHeight(world.getMinHeight()) .minHeight(world.getMinHeight())
.maxHeight(world.getMaxHeight()) .maxHeight(world.getMaxHeight())
.realWorld(world) .realWorld(world)
.environment(world.getEnvironment()); .environment(world.getEnvironment());
} }
public long getRawWorldSeed()
{
return seed;
}
public void setRawWorldSeed(long seed)
{
this.seed = seed;
}
public boolean tryGetRealWorld() { public boolean tryGetRealWorld() {
if (hasRealWorld()) { if (hasRealWorld()) {
return true; return true;

View File

@ -59,6 +59,7 @@ import java.io.File;
import java.util.List; import java.util.List;
import java.util.Random; import java.util.Random;
import java.util.concurrent.Semaphore; import java.util.concurrent.Semaphore;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Consumer; import java.util.function.Consumer;
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@ -73,18 +74,18 @@ public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChun
private final ReactiveFolder folder; private final ReactiveFolder folder;
private final KList<BlockPopulator> populators; private final KList<BlockPopulator> populators;
private final ChronoLatch hotloadChecker; private final ChronoLatch hotloadChecker;
private final Looper hotloader; private Looper hotloader;
private final AtomicBoolean setup;
private StudioMode lastMode; private StudioMode lastMode;
@Setter @Setter
private StudioGenerator studioGenerator; private StudioGenerator studioGenerator;
private final boolean studio; private final boolean studio;
private long lastSeed;
public BukkitChunkGenerator(IrisWorld world, boolean studio, File dataLocation, String dimensionKey) { public BukkitChunkGenerator(IrisWorld world, boolean studio, File dataLocation, String dimensionKey) {
setup = new AtomicBoolean(false);
studioGenerator = null; studioGenerator = null;
populators = new KList<>(); populators = new KList<>();
lastSeed = world.seed();
loadLock = new Semaphore(LOAD_LOCKS); loadLock = new Semaphore(LOAD_LOCKS);
this.world = world; this.world = world;
this.hotloadChecker = new ChronoLatch(1000, false); this.hotloadChecker = new ChronoLatch(1000, false);
@ -92,23 +93,6 @@ public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChun
this.dataLocation = dataLocation; this.dataLocation = dataLocation;
this.dimensionKey = dimensionKey; this.dimensionKey = dimensionKey;
this.folder = new ReactiveFolder(dataLocation, (_a, _b, _c) -> hotload()); this.folder = new ReactiveFolder(dataLocation, (_a, _b, _c) -> hotload());
setupEngine();
this.hotloader = studio ? new Looper() {
@Override
protected long loop() {
if (hotloadChecker.flip()) {
folder.check();
}
return 250;
}
} : null;
if (studio) {
hotloader.setPriority(Thread.MIN_PRIORITY);
hotloader.start();
hotloader.setName(getTarget().getWorld().name() + " Hotloader");
}
} }
private void setupEngine() { private void setupEngine() {
@ -153,14 +137,6 @@ public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChun
@Override @Override
public void injectChunkReplacement(World world, int x, int z, Consumer<Runnable> jobs) { public void injectChunkReplacement(World world, int x, int z, Consumer<Runnable> jobs) {
try { try {
if (lastSeed != world.getSeed()) {
Iris.debug("Seed for engine " + lastSeed + " does not match world seed if " + world.getSeed());
lastSeed = world.getSeed();
engine.getTarget().getWorld().seed(lastSeed);
engine.hotload();
Iris.debug("Updated Engine seed to " + lastSeed);
}
loadLock.acquire(); loadLock.acquire();
IrisBiomeStorage st = new IrisBiomeStorage(); IrisBiomeStorage st = new IrisBiomeStorage();
TerrainChunk tc = TerrainChunk.createUnsafe(world, st); TerrainChunk tc = TerrainChunk.createUnsafe(world, st);
@ -204,17 +180,6 @@ public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChun
} }
loadLock.release(); loadLock.release();
} catch (WrongEngineBroException e) {
Iris.warn("Trying to generate with a shut-down engine! Did you reload? Attempting to resolve this...");
try {
setupEngine();
Iris.success("Resolved! Should generate now!");
} catch (Throwable fe) {
Iris.error("FATAL! Iris cannot generate in this world since it was reloaded! This will cause a crash, with missing chunks, so we're crashing right now!");
Bukkit.shutdown();
throw new RuntimeException();
}
} catch (Throwable e) { } catch (Throwable e) {
loadLock.release(); loadLock.release();
Iris.error("======================================"); Iris.error("======================================");
@ -232,6 +197,40 @@ public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChun
} }
} }
private Engine getEngine(World world)
{
if(setup.get())
{
return getEngine();
}
synchronized (this)
{
getWorld().setRawWorldSeed(world.getSeed());
setupEngine();
this.hotloader = studio ? new Looper() {
@Override
protected long loop() {
if (hotloadChecker.flip()) {
folder.check();
}
return 250;
}
} : null;
if (studio) {
hotloader.setPriority(Thread.MIN_PRIORITY);
hotloader.start();
hotloader.setName(getTarget().getWorld().name() + " Hotloader");
}
setup.set(true);
}
return engine;
}
@Override @Override
public void close() { public void close() {
withExclusiveControl(() -> { withExclusiveControl(() -> {
@ -272,14 +271,7 @@ public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChun
@Override @Override
public @NotNull ChunkData generateChunkData(@NotNull World world, @NotNull Random ignored, int x, int z, @NotNull BiomeGrid biome) { public @NotNull ChunkData generateChunkData(@NotNull World world, @NotNull Random ignored, int x, int z, @NotNull BiomeGrid biome) {
try { try {
if (lastSeed != world.getSeed()) { getEngine(world);
Iris.debug("Seed for engine " + lastSeed + " does not match world seed if " + world.getSeed());
lastSeed = world.getSeed();
engine.getTarget().getWorld().seed(lastSeed);
engine.hotload();
Iris.debug("Updated Engine seed to " + lastSeed);
}
loadLock.acquire(); loadLock.acquire();
computeStudioGenerator(); computeStudioGenerator();
TerrainChunk tc = TerrainChunk.create(world, biome); TerrainChunk tc = TerrainChunk.create(world, biome);
@ -297,19 +289,6 @@ public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChun
Iris.debug("Generated " + x + " " + z); Iris.debug("Generated " + x + " " + z);
loadLock.release(); loadLock.release();
return c; return c;
} catch (WrongEngineBroException e) {
Iris.warn("Trying to generate with a shut-down engine! Did you reload? Attempting to resolve this...");
try {
setupEngine();
Iris.success("Resolved! Should generate now!");
} catch (Throwable fe) {
Iris.error("FATAL! Iris cannot generate in this world since it was reloaded! This will cause a crash, with missing chunks, so we're crashing right now!");
Bukkit.shutdown();
throw new RuntimeException();
}
return generateChunkData(world, ignored, x, z, biome);
} catch (Throwable e) { } catch (Throwable e) {
loadLock.release(); loadLock.release();
Iris.error("======================================"); Iris.error("======================================");

View File

@ -53,7 +53,7 @@ public class IrisScriptingAPI {
} }
public long getSeed() { public long getSeed() {
return getEngine().getTarget().getWorld().seed(); return getEngine().getSeedManager().getScript();
} }
public double expression(String expressionName, double x, double y, double z) { public double expression(String expressionName, double x, double y, double z) {

View File

@ -43,7 +43,7 @@ public class B {
private static final IntSet foliageCache = buildFoliageCache(); private static final IntSet foliageCache = buildFoliageCache();
private static final IntSet deepslateCache = buildDeepslateCache(); private static final IntSet deepslateCache = buildDeepslateCache();
private static final Int2IntMap normal2DeepslateCache = buildNormal2DeepslateCache(); private static final Int2IntMap normal2DeepslateCache = buildNormal2DeepslateCache();
private static final Int2IntMap deepslate2NormalCache = buildNormal2DeepslateCache(); private static final Int2IntMap deepslate2NormalCache = buildDeepslate2NormalCache();
private static final IntSet decorantCache = buildDecorantCache(); private static final IntSet decorantCache = buildDecorantCache();
private static final IntSet storageCache = buildStorageCache(); private static final IntSet storageCache = buildStorageCache();
private static final IntSet storageChestCache = buildStorageChestCache(); private static final IntSet storageChestCache = buildStorageChestCache();