diff --git a/src/main/java/com/volmit/iris/Iris.java b/src/main/java/com/volmit/iris/Iris.java index dbd8b5657..c14a75d2e 100644 --- a/src/main/java/com/volmit/iris/Iris.java +++ b/src/main/java/com/volmit/iris/Iris.java @@ -501,7 +501,7 @@ public class Iris extends VolmitPlugin implements Listener { IrisWorld w = IrisWorld.builder() .name(worldName) - .seed(RNG.r.lmax()) + .seed(1337) .environment(dim.getEnvironment()) .worldFolder(new File(worldName)) .minHeight(0) diff --git a/src/main/java/com/volmit/iris/core/link/IrisPapiExpansion.java b/src/main/java/com/volmit/iris/core/link/IrisPapiExpansion.java index c7159483e..519e18d5f 100644 --- a/src/main/java/com/volmit/iris/core/link/IrisPapiExpansion.java +++ b/src/main/java/com/volmit/iris/core/link/IrisPapiExpansion.java @@ -97,7 +97,7 @@ public class IrisPapiExpansion extends PlaceholderExpansion { } } else if (p.equalsIgnoreCase("world_seed")) { if (a != null) { - return a.getTarget().getWorld().seed() + ""; + return a.getEngine().getSeedManager().getSeed() + ""; } } else if (p.equalsIgnoreCase("world_speed")) { if (a != null) { diff --git a/src/main/java/com/volmit/iris/core/tools/IrisCreator.java b/src/main/java/com/volmit/iris/core/tools/IrisCreator.java index ffc4c29d4..6cc5e0aea 100644 --- a/src/main/java/com/volmit/iris/core/tools/IrisCreator.java +++ b/src/main/java/com/volmit/iris/core/tools/IrisCreator.java @@ -60,7 +60,7 @@ public class IrisCreator { /** * 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 diff --git a/src/main/java/com/volmit/iris/engine/IrisComplex.java b/src/main/java/com/volmit/iris/engine/IrisComplex.java index 4731b4bda..5a3643b8d 100644 --- a/src/main/java/com/volmit/iris/engine/IrisComplex.java +++ b/src/main/java/com/volmit/iris/engine/IrisComplex.java @@ -21,6 +21,7 @@ package com.volmit.iris.engine; import com.google.common.util.concurrent.AtomicDouble; import com.volmit.iris.Iris; 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.object.*; import com.volmit.iris.util.collection.KList; @@ -69,8 +70,6 @@ public class IrisComplex implements DataProvider { private ProceduralStream trueHeightStreamNoFeatures; private ProceduralStream slopeStream; private ProceduralStream topSurfaceStream; - private ProceduralStream rngStream; - private ProceduralStream chunkRngStream; private ProceduralStream terrainSurfaceDecoration; private ProceduralStream terrainCeilingDecoration; private ProceduralStream terrainCaveSurfaceDecoration; @@ -108,7 +107,7 @@ public class IrisComplex implements DataProvider { int cacheSize = 131072; IrisBiome emptyBiome = new IrisBiome(); UUID focusUUID = UUID.nameUUIDFromBytes("focus".getBytes()); - this.rng = new RNG(engine.getWorld().seed()); + this.rng = new RNG(engine.getSeedManager().getComplex()); this.data = engine.getData(); double height = engine.getHeight(); fluidHeight = engine.getDimension().getFluidHeight(); @@ -121,7 +120,6 @@ public class IrisComplex implements DataProvider { } IrisRegion focusRegion = focus != null ? findRegion(focus, engine) : null; - RNG rng = new RNG(engine.getWorld().seed()); //@builder engine.getDimension().getRegions().forEach((i) -> data.getRegionLoader().load(i) .getAllBiomes(this).forEach((b) -> b @@ -129,9 +127,6 @@ public class IrisComplex implements DataProvider { .forEach((c) -> registerGenerator(c.getCachedGenerator(this))))); overlayStream = ProceduralStream.ofDouble((x, z) -> 0D); 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() .select(engine.getDimension().getRockPalette().getBlockData(data)); fluidStream = engine.getDimension().getFluidPalette().getLayerGenerator(rng.nextParallelRNG(78), data).stream() @@ -198,11 +193,11 @@ public class IrisComplex implements DataProvider { .convertAware2D(this::implode).cache2D(cacheSize); heightStream = ProceduralStream.of((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); heightStreamNoFeatures = ProceduralStream.of((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); slopeStream = heightStream.slope(3).cache2D(cacheSize); 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) { - RNG rngc = chunkRngStream.get(x, z); + RNG rngc = new RNG(Cache.key(((int)x), ((int)z))); for (IrisDecorator i : b.getDecorators()) { if (!i.getPartOf().equals(part)) { diff --git a/src/main/java/com/volmit/iris/engine/IrisEngine.java b/src/main/java/com/volmit/iris/engine/IrisEngine.java index ca721aa71..96a686191 100644 --- a/src/main/java/com/volmit/iris/engine/IrisEngine.java +++ b/src/main/java/com/volmit/iris/engine/IrisEngine.java @@ -100,10 +100,14 @@ public class IrisEngine implements Engine { private final AtomicCache engineData = new AtomicCache<>(); private final AtomicBoolean cleaning; private final ChronoLatch cleanLatch; + private final SeedManager seedManager; public IrisEngine(EngineTarget target, boolean studio) { this.studio = studio; this.target = target; + getEngineData(); + verifySeed(); + this.seedManager = new SeedManager(target.getWorld().getRawWorldSeed()); bud = new AtomicInteger(0); buds = new AtomicInteger(0); metrics = new EngineMetrics(32); @@ -120,9 +124,8 @@ public class IrisEngine implements Engine { context = new IrisContext(this); cleaning = new AtomicBoolean(false); 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); - getEngineData(); minHeight = 0; failing = false; closed = false; @@ -131,6 +134,13 @@ public class IrisEngine implements Engine { 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() { if (perSecondBudLatch.flip()) { buds.set(bud.get()); diff --git a/src/main/java/com/volmit/iris/engine/actuator/IrisBiomeActuator.java b/src/main/java/com/volmit/iris/engine/actuator/IrisBiomeActuator.java index ca889e854..15f39b1e5 100644 --- a/src/main/java/com/volmit/iris/engine/actuator/IrisBiomeActuator.java +++ b/src/main/java/com/volmit/iris/engine/actuator/IrisBiomeActuator.java @@ -39,7 +39,7 @@ public class IrisBiomeActuator extends EngineAssignedActuator { public IrisBiomeActuator(Engine engine) { super(engine, "Biome"); - rng = new RNG(engine.getWorld().seed() + 243995); + rng = new RNG(engine.getSeedManager().getBiome()); } @BlockCoordinates diff --git a/src/main/java/com/volmit/iris/engine/actuator/IrisDecorantActuator.java b/src/main/java/com/volmit/iris/engine/actuator/IrisDecorantActuator.java index 4c0b7b102..c94f96588 100644 --- a/src/main/java/com/volmit/iris/engine/actuator/IrisDecorantActuator.java +++ b/src/main/java/com/volmit/iris/engine/actuator/IrisDecorantActuator.java @@ -52,7 +52,7 @@ public class IrisDecorantActuator extends EngineAssignedActuator { public IrisDecorantActuator(Engine engine) { super(engine, "Decorant"); shouldRay = shouldRayDecorate(); - this.rng = new RNG(engine.getTarget().getWorld().seed()); + this.rng = new RNG(engine.getSeedManager().getDecorator()); surfaceDecorator = new IrisSurfaceDecorator(getEngine()); ceilingDecorator = new IrisCeilingDecorator(getEngine()); seaSurfaceDecorator = new IrisSeaSurfaceDecorator(getEngine()); diff --git a/src/main/java/com/volmit/iris/engine/actuator/IrisTerrainNormalActuator.java b/src/main/java/com/volmit/iris/engine/actuator/IrisTerrainNormalActuator.java index 38f5d8c09..e06a6bffe 100644 --- a/src/main/java/com/volmit/iris/engine/actuator/IrisTerrainNormalActuator.java +++ b/src/main/java/com/volmit/iris/engine/actuator/IrisTerrainNormalActuator.java @@ -43,7 +43,7 @@ public class IrisTerrainNormalActuator extends EngineAssignedActuator public IrisTerrainNormalActuator(Engine engine) { super(engine, "Terrain"); - rng = new RNG(engine.getWorld().seed()); + rng = new RNG(engine.getSeedManager().getTerrain()); } @BlockCoordinates diff --git a/src/main/java/com/volmit/iris/engine/framework/Engine.java b/src/main/java/com/volmit/iris/engine/framework/Engine.java index 4185dff3e..cddb4e4a7 100644 --- a/src/main/java/com/volmit/iris/engine/framework/Engine.java +++ b/src/main/java/com/volmit/iris/engine/framework/Engine.java @@ -146,6 +146,8 @@ public interface Engine extends DataProvider, Fallible, LootProvider, BlockUpdat saveEngineData(); } + SeedManager getSeedManager(); + void saveEngineData(); default String getName() { diff --git a/src/main/java/com/volmit/iris/engine/framework/EngineAssignedWorldManager.java b/src/main/java/com/volmit/iris/engine/framework/EngineAssignedWorldManager.java index c8b56ef7c..07cf3bd08 100644 --- a/src/main/java/com/volmit/iris/engine/framework/EngineAssignedWorldManager.java +++ b/src/main/java/com/volmit/iris/engine/framework/EngineAssignedWorldManager.java @@ -73,7 +73,7 @@ public abstract class EngineAssignedWorldManager extends EngineAssignedComponent public void on(EntitySpawnEvent e) { if (e.getEntity().getWorld().equals(getTarget().getWorld().realWorld())) { if (e.getEntityType().equals(EntityType.ENDER_SIGNAL)) { - KList p = getEngine().getDimension().getStrongholds(getEngine().getWorld().seed()); + KList p = getEngine().getDimension().getStrongholds(getEngine().getSeedManager().getSpawn()); Position2 px = new Position2(e.getEntity().getLocation().getBlockX(), e.getEntity().getLocation().getBlockZ()); Position2 pr = null; double d = Double.MAX_VALUE; diff --git a/src/main/java/com/volmit/iris/engine/framework/EngineComponent.java b/src/main/java/com/volmit/iris/engine/framework/EngineComponent.java index ead01825d..15ad8b86f 100644 --- a/src/main/java/com/volmit/iris/engine/framework/EngineComponent.java +++ b/src/main/java/com/volmit/iris/engine/framework/EngineComponent.java @@ -69,7 +69,7 @@ public interface EngineComponent { } default long getSeed() { - return getTarget().getWorld().seed(); + return getEngine().getSeedManager().getComponent(); } default int getParallelism() { diff --git a/src/main/java/com/volmit/iris/engine/framework/SeedManager.java b/src/main/java/com/volmit/iris/engine/framework/SeedManager.java new file mode 100644 index 000000000..a42b95b50 --- /dev/null +++ b/src/main/java/com/volmit/iris/engine/framework/SeedManager.java @@ -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 . + */ + +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()))); + } +} diff --git a/src/main/java/com/volmit/iris/engine/mantle/MantleComponent.java b/src/main/java/com/volmit/iris/engine/mantle/MantleComponent.java index a4426ee94..15bba4f76 100644 --- a/src/main/java/com/volmit/iris/engine/mantle/MantleComponent.java +++ b/src/main/java/com/volmit/iris/engine/mantle/MantleComponent.java @@ -46,7 +46,7 @@ public interface MantleComponent { } default long seed() { - return getEngineMantle().getEngine().getTarget().getWorld().seed(); + return getEngineMantle().getEngine().getSeedManager().getMantle(); } default BurstExecutor burst() { diff --git a/src/main/java/com/volmit/iris/engine/mantle/components/MantleJigsawComponent.java b/src/main/java/com/volmit/iris/engine/mantle/components/MantleJigsawComponent.java index 96a7178e7..44675c836 100644 --- a/src/main/java/com/volmit/iris/engine/mantle/components/MantleJigsawComponent.java +++ b/src/main/java/com/volmit/iris/engine/mantle/components/MantleJigsawComponent.java @@ -38,7 +38,7 @@ public class MantleJigsawComponent extends IrisMantleComponent { public MantleJigsawComponent(EngineMantle engineMantle) { 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 diff --git a/src/main/java/com/volmit/iris/engine/modifier/IrisCarveModifier.java b/src/main/java/com/volmit/iris/engine/modifier/IrisCarveModifier.java index 79efaa79a..cd2eb9346 100644 --- a/src/main/java/com/volmit/iris/engine/modifier/IrisCarveModifier.java +++ b/src/main/java/com/volmit/iris/engine/modifier/IrisCarveModifier.java @@ -51,7 +51,7 @@ public class IrisCarveModifier extends EngineAssignedModifier { public IrisCarveModifier(Engine engine) { super(engine, "Carve"); - rng = new RNG(getEngine().getWorld().seed() + 3297778).nextParallelRNG(67648777); + rng = new RNG(getEngine().getSeedManager().getCarve()); } @Override diff --git a/src/main/java/com/volmit/iris/engine/modifier/IrisDepositModifier.java b/src/main/java/com/volmit/iris/engine/modifier/IrisDepositModifier.java index bc4106e77..60b8e8015 100644 --- a/src/main/java/com/volmit/iris/engine/modifier/IrisDepositModifier.java +++ b/src/main/java/com/volmit/iris/engine/modifier/IrisDepositModifier.java @@ -38,7 +38,7 @@ public class IrisDepositModifier extends EngineAssignedModifier { public IrisDepositModifier(Engine engine) { super(engine, "Deposit"); - rng = new RNG(getEngine().getWorld().seed() + 12938).nextParallelRNG(28348777); + rng = new RNG(getEngine().getSeedManager().getDeposit()); } @Override diff --git a/src/main/java/com/volmit/iris/engine/modifier/IrisPostModifier.java b/src/main/java/com/volmit/iris/engine/modifier/IrisPostModifier.java index 04f55e54f..a54a67be6 100644 --- a/src/main/java/com/volmit/iris/engine/modifier/IrisPostModifier.java +++ b/src/main/java/com/volmit/iris/engine/modifier/IrisPostModifier.java @@ -40,7 +40,7 @@ public class IrisPostModifier extends EngineAssignedModifier { public IrisPostModifier(Engine engine) { super(engine, "Post"); - rng = new RNG(getEngine().getWorld().seed() + 12938).nextParallelRNG(28348777); + rng = new RNG(getEngine().getSeedManager().getPost()); } @Override diff --git a/src/main/java/com/volmit/iris/engine/object/HeadlessWorld.java b/src/main/java/com/volmit/iris/engine/object/HeadlessWorld.java index 421a23c91..01a552e71 100644 --- a/src/main/java/com/volmit/iris/engine/object/HeadlessWorld.java +++ b/src/main/java/com/volmit/iris/engine/object/HeadlessWorld.java @@ -85,7 +85,7 @@ public class HeadlessWorld { public World load() { World w = new WorldCreator(worldName) .environment(dimension.getEnvironment()) - .seed(world.seed()) + .seed(world.getRawWorldSeed()) .generator(new BukkitChunkGenerator(world, studio, dimension.getLoader().getDataFolder(), dimension.getLoadKey())) .createWorld(); diff --git a/src/main/java/com/volmit/iris/engine/object/IrisEngineData.java b/src/main/java/com/volmit/iris/engine/object/IrisEngineData.java index 3acf21ea4..9b58040d4 100644 --- a/src/main/java/com/volmit/iris/engine/object/IrisEngineData.java +++ b/src/main/java/com/volmit/iris/engine/object/IrisEngineData.java @@ -28,6 +28,7 @@ public class IrisEngineData { private IrisEngineStatistics statistics = new IrisEngineStatistics(); private KList spawnerCooldowns = new KList<>(); private KList chunks = new KList<>(); + private Long seed = null; public void removeChunk(int x, int z) { long k = Cache.key(x, z); diff --git a/src/main/java/com/volmit/iris/engine/object/IrisEntitySpawn.java b/src/main/java/com/volmit/iris/engine/object/IrisEntitySpawn.java index 4c35fb1e0..a348eb5cd 100644 --- a/src/main/java/com/volmit/iris/engine/object/IrisEntitySpawn.java +++ b/src/main/java/com/volmit/iris/engine/object/IrisEntitySpawn.java @@ -109,7 +109,7 @@ public class IrisEntitySpawn implements IRare { 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); } @@ -123,7 +123,7 @@ public class IrisEntitySpawn implements IRare { if (!irisEntity.getSurface().matches(at.clone().subtract(0, 1, 0).getBlock())) 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) { 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()); } diff --git a/src/main/java/com/volmit/iris/engine/object/IrisEntitySpawnOverride.java b/src/main/java/com/volmit/iris/engine/object/IrisEntitySpawnOverride.java deleted file mode 100644 index cc80c6094..000000000 --- a/src/main/java/com/volmit/iris/engine/object/IrisEntitySpawnOverride.java +++ /dev/null @@ -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 . - */ - -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 = new AtomicCache<>(); - private final transient AtomicCache 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())); - } -} diff --git a/src/main/java/com/volmit/iris/engine/object/IrisWorld.java b/src/main/java/com/volmit/iris/engine/object/IrisWorld.java index d78fe79d2..bb5e16876 100644 --- a/src/main/java/com/volmit/iris/engine/object/IrisWorld.java +++ b/src/main/java/com/volmit/iris/engine/object/IrisWorld.java @@ -21,8 +21,7 @@ package com.volmit.iris.engine.object; import com.volmit.iris.Iris; import com.volmit.iris.core.tools.IrisToolbelt; import com.volmit.iris.util.collection.KList; -import lombok.Builder; -import lombok.Data; +import lombok.*; import lombok.experimental.Accessors; import org.bukkit.Bukkit; import org.bukkit.Location; @@ -42,6 +41,9 @@ public class IrisWorld { private static final KList NO_ENTITIES = new KList<>(); private String name; private File worldFolder; + + @Getter(AccessLevel.NONE) + @Setter(AccessLevel.NONE) private long seed; private World.Environment environment; private World realWorld; @@ -55,13 +57,22 @@ public class IrisWorld { private static IrisWorld bindWorld(IrisWorld iw, World world) { return iw.name(world.getName()) .worldFolder(world.getWorldFolder()) - .seed(world.getSeed()) .minHeight(world.getMinHeight()) .maxHeight(world.getMaxHeight()) .realWorld(world) .environment(world.getEnvironment()); } + public long getRawWorldSeed() + { + return seed; + } + + public void setRawWorldSeed(long seed) + { + this.seed = seed; + } + public boolean tryGetRealWorld() { if (hasRealWorld()) { return true; diff --git a/src/main/java/com/volmit/iris/engine/platform/BukkitChunkGenerator.java b/src/main/java/com/volmit/iris/engine/platform/BukkitChunkGenerator.java index d478118b2..80b093c51 100644 --- a/src/main/java/com/volmit/iris/engine/platform/BukkitChunkGenerator.java +++ b/src/main/java/com/volmit/iris/engine/platform/BukkitChunkGenerator.java @@ -59,6 +59,7 @@ import java.io.File; import java.util.List; import java.util.Random; import java.util.concurrent.Semaphore; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Consumer; @EqualsAndHashCode(callSuper = true) @@ -73,18 +74,18 @@ public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChun private final ReactiveFolder folder; private final KList populators; private final ChronoLatch hotloadChecker; - private final Looper hotloader; + private Looper hotloader; + private final AtomicBoolean setup; private StudioMode lastMode; @Setter private StudioGenerator studioGenerator; private final boolean studio; - private long lastSeed; public BukkitChunkGenerator(IrisWorld world, boolean studio, File dataLocation, String dimensionKey) { + setup = new AtomicBoolean(false); studioGenerator = null; populators = new KList<>(); - lastSeed = world.seed(); loadLock = new Semaphore(LOAD_LOCKS); this.world = world; this.hotloadChecker = new ChronoLatch(1000, false); @@ -92,23 +93,6 @@ public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChun this.dataLocation = dataLocation; this.dimensionKey = dimensionKey; 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() { @@ -153,14 +137,6 @@ public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChun @Override public void injectChunkReplacement(World world, int x, int z, Consumer jobs) { 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(); IrisBiomeStorage st = new IrisBiomeStorage(); TerrainChunk tc = TerrainChunk.createUnsafe(world, st); @@ -204,17 +180,6 @@ public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChun } 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) { loadLock.release(); 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 public void close() { withExclusiveControl(() -> { @@ -272,14 +271,7 @@ public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChun @Override public @NotNull ChunkData generateChunkData(@NotNull World world, @NotNull Random ignored, int x, int z, @NotNull BiomeGrid biome) { 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); - } - + getEngine(world); loadLock.acquire(); computeStudioGenerator(); TerrainChunk tc = TerrainChunk.create(world, biome); @@ -297,19 +289,6 @@ public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChun Iris.debug("Generated " + x + " " + z); loadLock.release(); 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) { loadLock.release(); Iris.error("======================================"); diff --git a/src/main/java/com/volmit/iris/engine/scripting/IrisScriptingAPI.java b/src/main/java/com/volmit/iris/engine/scripting/IrisScriptingAPI.java index baa8a8bd2..409d5f48a 100644 --- a/src/main/java/com/volmit/iris/engine/scripting/IrisScriptingAPI.java +++ b/src/main/java/com/volmit/iris/engine/scripting/IrisScriptingAPI.java @@ -53,7 +53,7 @@ public class IrisScriptingAPI { } public long getSeed() { - return getEngine().getTarget().getWorld().seed(); + return getEngine().getSeedManager().getScript(); } public double expression(String expressionName, double x, double y, double z) {