mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2025-07-18 18:23:06 +00:00
Merge remote-tracking branch 'upstream/master' into Fixes
This commit is contained in:
commit
a060c01f58
19
.github/ISSUE_TEMPLATE/bug.yml
vendored
19
.github/ISSUE_TEMPLATE/bug.yml
vendored
@ -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:
|
||||||
|
@ -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'
|
||||||
|
@ -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)
|
||||||
|
@ -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();
|
||||||
|
@ -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
|
||||||
|
@ -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") + ".");
|
||||||
|
@ -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");
|
||||||
|
@ -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) {
|
||||||
|
@ -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
|
||||||
|
@ -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)) {
|
||||||
|
@ -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());
|
||||||
|
@ -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
|
||||||
|
@ -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());
|
||||||
|
@ -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
|
||||||
|
@ -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() {
|
||||||
|
@ -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;
|
||||||
|
@ -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() {
|
||||||
|
107
src/main/java/com/volmit/iris/engine/framework/SeedManager.java
Normal file
107
src/main/java/com/volmit/iris/engine/framework/SeedManager.java
Normal 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())));
|
||||||
|
}
|
||||||
|
}
|
@ -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() {
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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();
|
||||||
|
@ -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);
|
||||||
|
@ -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());
|
||||||
}
|
}
|
||||||
|
@ -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()));
|
|
||||||
}
|
|
||||||
}
|
|
@ -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) {
|
||||||
|
@ -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;
|
||||||
|
@ -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("======================================");
|
||||||
|
@ -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) {
|
||||||
|
@ -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();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user