mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2025-07-18 18:23:06 +00:00
commit
342e689825
@ -48,7 +48,6 @@ import com.volmit.iris.util.io.InstanceState;
|
|||||||
import com.volmit.iris.util.io.JarScanner;
|
import com.volmit.iris.util.io.JarScanner;
|
||||||
import com.volmit.iris.util.math.M;
|
import com.volmit.iris.util.math.M;
|
||||||
import com.volmit.iris.util.math.RNG;
|
import com.volmit.iris.util.math.RNG;
|
||||||
import com.volmit.iris.util.noise.CNG;
|
|
||||||
import com.volmit.iris.util.parallel.MultiBurst;
|
import com.volmit.iris.util.parallel.MultiBurst;
|
||||||
import com.volmit.iris.util.plugin.Metrics;
|
import com.volmit.iris.util.plugin.Metrics;
|
||||||
import com.volmit.iris.util.plugin.Permission;
|
import com.volmit.iris.util.plugin.Permission;
|
||||||
|
@ -122,8 +122,6 @@ public class IrisBoardManager implements BoardProvider, Listener {
|
|||||||
long memoryGuess = 0;
|
long memoryGuess = 0;
|
||||||
int loadedObjects = 0;
|
int loadedObjects = 0;
|
||||||
|
|
||||||
parallaxRegions +=engine.getParallax().getRegionCount();
|
|
||||||
parallaxChunks += engine.getParallax().getChunkCount();
|
|
||||||
loadedObjects += engine.getData().getObjectLoader().getSize();
|
loadedObjects += engine.getData().getObjectLoader().getSize();
|
||||||
memoryGuess += engine.getData().getObjectLoader().getTotalStorage() * 225L;
|
memoryGuess += engine.getData().getObjectLoader().getTotalStorage() * 225L;
|
||||||
memoryGuess += parallaxChunks * 3500L;
|
memoryGuess += parallaxChunks * 3500L;
|
||||||
@ -139,7 +137,7 @@ public class IrisBoardManager implements BoardProvider, Listener {
|
|||||||
if (engine != null) {
|
if (engine != null) {
|
||||||
v.add("&7&m------------------");
|
v.add("&7&m------------------");
|
||||||
KList<IrisFeaturePositional> f = new KList<>();
|
KList<IrisFeaturePositional> f = new KList<>();
|
||||||
f.add(engine.getEngineParallax().forEachFeature(x, z));
|
f.add(engine.getMantle().forEachFeature(x, z));
|
||||||
v.add(C.AQUA + "Region" + C.GRAY + ": " + engine.getRegion(x, z).getName());
|
v.add(C.AQUA + "Region" + C.GRAY + ": " + engine.getRegion(x, z).getName());
|
||||||
v.add(C.AQUA + "Biome" + C.GRAY + ": " + engine.getBiome(x, y, z).getName());
|
v.add(C.AQUA + "Biome" + C.GRAY + ": " + engine.getBiome(x, y, z).getName());
|
||||||
v.add(C.AQUA + "Height" + C.GRAY + ": " + Math.round(engine.getHeight(x, z)));
|
v.add(C.AQUA + "Height" + C.GRAY + ": " + Math.round(engine.getHeight(x, z)));
|
||||||
|
@ -25,7 +25,6 @@ import com.volmit.iris.core.command.pregen.CommandIrisPregen;
|
|||||||
import com.volmit.iris.core.command.studio.CommandIrisStudio;
|
import com.volmit.iris.core.command.studio.CommandIrisStudio;
|
||||||
import com.volmit.iris.core.command.what.CommandIrisWhat;
|
import com.volmit.iris.core.command.what.CommandIrisWhat;
|
||||||
import com.volmit.iris.core.command.world.CommandIrisCreate;
|
import com.volmit.iris.core.command.world.CommandIrisCreate;
|
||||||
import com.volmit.iris.core.command.world.CommandIrisFix;
|
|
||||||
import com.volmit.iris.core.command.world.CommandIrisUpdateWorld;
|
import com.volmit.iris.core.command.world.CommandIrisUpdateWorld;
|
||||||
import com.volmit.iris.core.command.world.CommandIrisVerify;
|
import com.volmit.iris.core.command.world.CommandIrisVerify;
|
||||||
import com.volmit.iris.util.collection.KList;
|
import com.volmit.iris.util.collection.KList;
|
||||||
@ -43,9 +42,6 @@ public class CommandIris extends MortarCommand {
|
|||||||
@Command
|
@Command
|
||||||
private CommandIrisDebug debug;
|
private CommandIrisDebug debug;
|
||||||
|
|
||||||
@Command
|
|
||||||
private CommandIrisFix fix;
|
|
||||||
|
|
||||||
@Command
|
@Command
|
||||||
private CommandIrisStudio studio;
|
private CommandIrisStudio studio;
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@ public class CommandIrisWhatFeatures extends MortarCommand {
|
|||||||
|
|
||||||
if (IrisToolbelt.isIrisWorld(c.getWorld())) {
|
if (IrisToolbelt.isIrisWorld(c.getWorld())) {
|
||||||
int m = 1;
|
int m = 1;
|
||||||
for (IrisFeaturePositional i : ((Engine) IrisToolbelt.access(c.getWorld()).getEngine()).getEngineParallax().getFeaturesInChunk(c)) {
|
for (IrisFeaturePositional i : ((Engine) IrisToolbelt.access(c.getWorld()).getEngine()).getMantle().getFeaturesInChunk(c)) {
|
||||||
sender.sendMessage("#" + m++ + " " + new JSONObject(new Gson().toJson(i)).toString(4));
|
sender.sendMessage("#" + m++ + " " + new JSONObject(new Gson().toJson(i)).toString(4));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -1,76 +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.core.command.world;
|
|
||||||
|
|
||||||
import com.volmit.iris.Iris;
|
|
||||||
import com.volmit.iris.core.tools.IrisToolbelt;
|
|
||||||
import com.volmit.iris.engine.framework.Engine;
|
|
||||||
import com.volmit.iris.util.collection.KList;
|
|
||||||
import com.volmit.iris.util.format.Form;
|
|
||||||
import com.volmit.iris.util.math.Spiraler;
|
|
||||||
import com.volmit.iris.util.plugin.MortarCommand;
|
|
||||||
import com.volmit.iris.util.plugin.VolmitSender;
|
|
||||||
import com.volmit.iris.util.scheduling.J;
|
|
||||||
|
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
|
||||||
|
|
||||||
public class CommandIrisFix extends MortarCommand {
|
|
||||||
public CommandIrisFix() {
|
|
||||||
super("fix");
|
|
||||||
requiresPermission(Iris.perm.studio);
|
|
||||||
setDescription("Fix nearby chunks");
|
|
||||||
setCategory("Studio");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void addTabOptions(VolmitSender sender, String[] args, KList<String> list) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean handle(VolmitSender sender, String[] args) {
|
|
||||||
try {
|
|
||||||
Engine a = IrisToolbelt.access(sender.player().getWorld()).getEngine();
|
|
||||||
|
|
||||||
int viewDistance = args.length > 0 ? Integer.parseInt(args[0]) : -1;
|
|
||||||
if (viewDistance <= 1) {
|
|
||||||
J.a(() -> {
|
|
||||||
int fixed = a.getEngineParallax().repairChunk(sender.player().getLocation().getChunk());
|
|
||||||
sender.sendMessage("Fixed " + Form.f(fixed) + " blocks!");
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
AtomicInteger v = new AtomicInteger();
|
|
||||||
J.a(() -> {
|
|
||||||
new Spiraler(viewDistance, viewDistance, (x, z) -> v.set(v.get() + a.getEngineParallax().repairChunk(sender.player().getWorld().getChunkAt(x, z)))).drain();
|
|
||||||
sender.sendMessage("Fixed " + Form.f(v.get()) + " blocks in " + (viewDistance * viewDistance) + " chunks!");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} catch (Throwable e) {
|
|
||||||
Iris.reportError(e);
|
|
||||||
sender.sendMessage("Not a valid Iris World (or bad argument)");
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected String getArgsUsage() {
|
|
||||||
return "[view-distance]";
|
|
||||||
}
|
|
||||||
}
|
|
@ -21,7 +21,9 @@ package com.volmit.iris.core.edit;
|
|||||||
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.engine.framework.Engine;
|
import com.volmit.iris.engine.framework.Engine;
|
||||||
import com.volmit.iris.engine.parallax.ParallaxAccess;
|
import com.volmit.iris.engine.framework.PlacedObject;
|
||||||
|
import com.volmit.iris.engine.mantle.EngineMantle;
|
||||||
|
import com.volmit.iris.engine.object.objects.IrisObjectPlacement;
|
||||||
import com.volmit.iris.util.collection.KList;
|
import com.volmit.iris.util.collection.KList;
|
||||||
import com.volmit.iris.util.math.BlockPosition;
|
import com.volmit.iris.util.math.BlockPosition;
|
||||||
import com.volmit.iris.util.math.RNG;
|
import com.volmit.iris.util.math.RNG;
|
||||||
@ -34,7 +36,7 @@ import org.bukkit.block.Block;
|
|||||||
@SuppressWarnings("ALL")
|
@SuppressWarnings("ALL")
|
||||||
@Data
|
@Data
|
||||||
public class DustRevealer {
|
public class DustRevealer {
|
||||||
private final ParallaxAccess parallax;
|
private final Engine engine;
|
||||||
private final World world;
|
private final World world;
|
||||||
private final BlockPosition block;
|
private final BlockPosition block;
|
||||||
private final String key;
|
private final String key;
|
||||||
@ -45,20 +47,19 @@ public class DustRevealer {
|
|||||||
Engine access = IrisToolbelt.access(world).getEngine();
|
Engine access = IrisToolbelt.access(world).getEngine();
|
||||||
|
|
||||||
if (access != null) {
|
if (access != null) {
|
||||||
ParallaxAccess a = access.getParallaxAccess();
|
String a = access.getObjectPlacementKey(block.getX(), block.getY(), block.getZ());
|
||||||
|
|
||||||
if (a.getObject(block.getX(), block.getY(), block.getZ()) != null) {
|
if (a != null) {
|
||||||
sender.sendMessage("Found object " + a.getObject(block.getX(), block.getY(), block.getZ()));
|
sender.sendMessage("Found object " + a);
|
||||||
Iris.info(sender.getName() + " found object " + a.getObject(block.getX(), block.getY(), block.getZ()));
|
|
||||||
J.a(() -> {
|
J.a(() -> {
|
||||||
new DustRevealer(a, world, new BlockPosition(block.getX(), block.getY(), block.getZ()), a.getObject(block.getX(), block.getY(), block.getZ()), new KList<>());
|
new DustRevealer(access, world, new BlockPosition(block.getX(), block.getY(), block.getZ()), a, new KList<>());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public DustRevealer(ParallaxAccess parallax, World world, BlockPosition block, String key, KList<BlockPosition> hits) {
|
public DustRevealer(Engine engine, World world, BlockPosition block, String key, KList<BlockPosition> hits) {
|
||||||
this.parallax = parallax;
|
this.engine = engine;
|
||||||
this.world = world;
|
this.world = world;
|
||||||
this.block = block;
|
this.block = block;
|
||||||
this.key = key;
|
this.key = key;
|
||||||
@ -103,9 +104,9 @@ public class DustRevealer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean is(BlockPosition a) {
|
private boolean is(BlockPosition a) {
|
||||||
if (isValidTry(a) && parallax.getObject(a.getX(), a.getY(), a.getZ()) != null && parallax.getObject(a.getX(), a.getY(), a.getZ()).equals(key)) {
|
if (isValidTry(a) && engine.getObjectPlacementKey(a.getX(), a.getY(), a.getZ()) != null && engine.getObjectPlacementKey(a.getX(), a.getY(), a.getZ()).equals(key)) {
|
||||||
hits.add(a);
|
hits.add(a);
|
||||||
new DustRevealer(parallax, world, a, key, hits);
|
new DustRevealer(engine, world, a, key, hits);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,7 +30,6 @@ import com.volmit.iris.core.tools.IrisToolbelt;
|
|||||||
import com.volmit.iris.core.tools.IrisWorldCreator;
|
import com.volmit.iris.core.tools.IrisWorldCreator;
|
||||||
import com.volmit.iris.engine.framework.Engine;
|
import com.volmit.iris.engine.framework.Engine;
|
||||||
import com.volmit.iris.engine.object.biome.IrisBiome;
|
import com.volmit.iris.engine.object.biome.IrisBiome;
|
||||||
import com.volmit.iris.engine.object.biome.IrisBiomeMutation;
|
|
||||||
import com.volmit.iris.engine.object.biome.IrisBiomePaletteLayer;
|
import com.volmit.iris.engine.object.biome.IrisBiomePaletteLayer;
|
||||||
import com.volmit.iris.engine.object.block.IrisBlockData;
|
import com.volmit.iris.engine.object.block.IrisBlockData;
|
||||||
import com.volmit.iris.engine.object.dimensional.IrisDimension;
|
import com.volmit.iris.engine.object.dimensional.IrisDimension;
|
||||||
@ -411,27 +410,6 @@ public class IrisProject {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (IrisBiomeMutation i : dimension.getMutations()) {
|
|
||||||
for (IrisObjectPlacement j : i.getObjects()) {
|
|
||||||
b.append(j.hashCode());
|
|
||||||
KList<String> newNames = new KList<>();
|
|
||||||
|
|
||||||
for (String k : j.getPlace()) {
|
|
||||||
if (renameObjects.containsKey(k)) {
|
|
||||||
newNames.add(renameObjects.get(k));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
String name = !obfuscate ? k : UUID.randomUUID().toString().replaceAll("-", "");
|
|
||||||
b.append(name);
|
|
||||||
newNames.add(name);
|
|
||||||
renameObjects.put(k, name);
|
|
||||||
}
|
|
||||||
|
|
||||||
j.setPlace(newNames);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
KMap<String, KList<String>> lookupObjects = renameObjects.flip();
|
KMap<String, KList<String>> lookupObjects = renameObjects.flip();
|
||||||
StringBuilder gb = new StringBuilder();
|
StringBuilder gb = new StringBuilder();
|
||||||
ChronoLatch cl = new ChronoLatch(1000);
|
ChronoLatch cl = new ChronoLatch(1000);
|
||||||
@ -455,24 +433,6 @@ public class IrisProject {
|
|||||||
}
|
}
|
||||||
})));
|
})));
|
||||||
|
|
||||||
dimension.getMutations().forEach((i) -> i.getObjects().forEach((j) -> j.getPlace().forEach((k) ->
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
File f = dm.getObjectLoader().findFile(lookupObjects.get(k).get(0));
|
|
||||||
IO.copyFile(f, new File(folder, "objects/" + k + ".iob"));
|
|
||||||
gb.append(IO.hash(f));
|
|
||||||
ggg.set(ggg.get() + 1);
|
|
||||||
|
|
||||||
if (cl.flip()) {
|
|
||||||
int g = ggg.get();
|
|
||||||
ggg.set(0);
|
|
||||||
sender.sendMessage("Wrote another " + g + " Objects");
|
|
||||||
}
|
|
||||||
} catch (Throwable e) {
|
|
||||||
Iris.reportError(e);
|
|
||||||
}
|
|
||||||
})));
|
|
||||||
|
|
||||||
b.append(IO.hash(gb.toString()));
|
b.append(IO.hash(gb.toString()));
|
||||||
c.append(IO.hash(b.toString()));
|
c.append(IO.hash(b.toString()));
|
||||||
b = new StringBuilder();
|
b = new StringBuilder();
|
||||||
|
@ -230,7 +230,7 @@ public class IrisComplex implements DataProvider {
|
|||||||
objectChanceStream = ProceduralStream.ofDouble((x, z) -> {
|
objectChanceStream = ProceduralStream.ofDouble((x, z) -> {
|
||||||
if (engine.getDimension().hasFeatures(engine)) {
|
if (engine.getDimension().hasFeatures(engine)) {
|
||||||
AtomicDouble str = new AtomicDouble(1D);
|
AtomicDouble str = new AtomicDouble(1D);
|
||||||
for (IrisFeaturePositional i : engine.getEngineParallax().forEachFeature(x, z)) {
|
for (IrisFeaturePositional i : engine.getMantle().forEachFeature(x, z)) {
|
||||||
str.set(Math.min(str.get(), i.getObjectChanceModifier(x, z, rng, getData())));
|
str.set(Math.min(str.get(), i.getObjectChanceModifier(x, z, rng, getData())));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -241,7 +241,7 @@ public class IrisComplex implements DataProvider {
|
|||||||
});
|
});
|
||||||
trueBiomeStream = focus != null ? ProceduralStream.of((x, y) -> focus, Interpolated.of(a -> 0D,
|
trueBiomeStream = focus != null ? ProceduralStream.of((x, y) -> focus, Interpolated.of(a -> 0D,
|
||||||
b -> focus)).convertAware2D((b, x, z) -> {
|
b -> focus)).convertAware2D((b, x, z) -> {
|
||||||
for (IrisFeaturePositional i : engine.getEngineParallax().forEachFeature(x, z)) {
|
for (IrisFeaturePositional i : engine.getMantle().forEachFeature(x, z)) {
|
||||||
IrisBiome bx = i.filter(x, z, b, rng);
|
IrisBiome bx = i.filter(x, z, b, rng);
|
||||||
|
|
||||||
if (bx != null) {
|
if (bx != null) {
|
||||||
@ -257,7 +257,7 @@ public class IrisComplex implements DataProvider {
|
|||||||
fixBiomeType(h, baseBiomeStream.get(x, z),
|
fixBiomeType(h, baseBiomeStream.get(x, z),
|
||||||
regionStream.get(x, z), x, z, fluidHeight))
|
regionStream.get(x, z), x, z, fluidHeight))
|
||||||
.convertAware2D((b, x, z) -> {
|
.convertAware2D((b, x, z) -> {
|
||||||
for (IrisFeaturePositional i : engine.getEngineParallax().forEachFeature(x, z)) {
|
for (IrisFeaturePositional i : engine.getMantle().forEachFeature(x, z)) {
|
||||||
IrisBiome bx = i.filter(x, z, b, rng);
|
IrisBiome bx = i.filter(x, z, b, rng);
|
||||||
|
|
||||||
if (bx != null) {
|
if (bx != null) {
|
||||||
@ -271,7 +271,7 @@ public class IrisComplex implements DataProvider {
|
|||||||
.cache2D(cacheSize);
|
.cache2D(cacheSize);
|
||||||
trueBiomeStream = focus != null ? ProceduralStream.of((x, y) -> focus, Interpolated.of(a -> 0D,
|
trueBiomeStream = focus != null ? ProceduralStream.of((x, y) -> focus, Interpolated.of(a -> 0D,
|
||||||
b -> focus)).convertAware2D((b, x, z) -> {
|
b -> focus)).convertAware2D((b, x, z) -> {
|
||||||
for (IrisFeaturePositional i : engine.getEngineParallax().forEachFeature(x, z)) {
|
for (IrisFeaturePositional i : engine.getMantle().forEachFeature(x, z)) {
|
||||||
IrisBiome bx = i.filter(x, z, b, rng);
|
IrisBiome bx = i.filter(x, z, b, rng);
|
||||||
|
|
||||||
if (bx != null) {
|
if (bx != null) {
|
||||||
@ -287,7 +287,7 @@ public class IrisComplex implements DataProvider {
|
|||||||
fixBiomeType(h, baseBiomeStream.get(x, z),
|
fixBiomeType(h, baseBiomeStream.get(x, z),
|
||||||
regionStream.get(x, z), x, z, fluidHeight))
|
regionStream.get(x, z), x, z, fluidHeight))
|
||||||
.convertAware2D((b, x, z) -> {
|
.convertAware2D((b, x, z) -> {
|
||||||
for (IrisFeaturePositional i : engine.getEngineParallax().forEachFeature(x, z)) {
|
for (IrisFeaturePositional i : engine.getMantle().forEachFeature(x, z)) {
|
||||||
IrisBiome bx = i.filter(x, z, b, rng);
|
IrisBiome bx = i.filter(x, z, b, rng);
|
||||||
|
|
||||||
if (bx != null) {
|
if (bx != null) {
|
||||||
@ -458,7 +458,7 @@ public class IrisComplex implements DataProvider {
|
|||||||
AtomicDouble noise = new AtomicDouble(h + fluidHeight + overlayStream.get(x, z));
|
AtomicDouble noise = new AtomicDouble(h + fluidHeight + overlayStream.get(x, z));
|
||||||
|
|
||||||
if (features) {
|
if (features) {
|
||||||
List<IrisFeaturePositional> p = engine.getEngineParallax().forEachFeature(x, z);
|
List<IrisFeaturePositional> p = engine.getMantle().forEachFeature(x, z);
|
||||||
|
|
||||||
for (IrisFeaturePositional i : p) {
|
for (IrisFeaturePositional i : p) {
|
||||||
noise.set(i.filter(x, z, noise.get(), rng, getData()));
|
noise.set(i.filter(x, z, noise.get(), rng, getData()));
|
||||||
|
@ -29,6 +29,7 @@ import com.volmit.iris.engine.actuator.IrisTerrainIslandActuator;
|
|||||||
import com.volmit.iris.engine.actuator.IrisTerrainNormalActuator;
|
import com.volmit.iris.engine.actuator.IrisTerrainNormalActuator;
|
||||||
import com.volmit.iris.engine.data.cache.AtomicCache;
|
import com.volmit.iris.engine.data.cache.AtomicCache;
|
||||||
import com.volmit.iris.engine.framework.*;
|
import com.volmit.iris.engine.framework.*;
|
||||||
|
import com.volmit.iris.engine.mantle.EngineMantle;
|
||||||
import com.volmit.iris.engine.modifier.IrisCaveModifier;
|
import com.volmit.iris.engine.modifier.IrisCaveModifier;
|
||||||
import com.volmit.iris.engine.modifier.IrisDepositModifier;
|
import com.volmit.iris.engine.modifier.IrisDepositModifier;
|
||||||
import com.volmit.iris.engine.modifier.IrisPostModifier;
|
import com.volmit.iris.engine.modifier.IrisPostModifier;
|
||||||
@ -83,6 +84,7 @@ public class IrisEngine extends BlockPopulator implements Engine {
|
|||||||
private final EngineTarget target;
|
private final EngineTarget target;
|
||||||
private final IrisContext context;
|
private final IrisContext context;
|
||||||
private final EngineEffects effects;
|
private final EngineEffects effects;
|
||||||
|
private final EngineMantle mantle;
|
||||||
private final ChronoLatch perSecondLatch;
|
private final ChronoLatch perSecondLatch;
|
||||||
private final EngineExecutionEnvironment execution;
|
private final EngineExecutionEnvironment execution;
|
||||||
private final EngineWorldManager worldManager;
|
private final EngineWorldManager worldManager;
|
||||||
@ -99,7 +101,6 @@ public class IrisEngine extends BlockPopulator implements Engine {
|
|||||||
private double maxBiomeLayerDensity;
|
private double maxBiomeLayerDensity;
|
||||||
private double maxBiomeDecoratorDensity;
|
private double maxBiomeDecoratorDensity;
|
||||||
private final IrisComplex complex;
|
private final IrisComplex complex;
|
||||||
private final EngineParallaxManager engineParallax;
|
|
||||||
private final EngineActuator<BlockData> terrainNormalActuator;
|
private final EngineActuator<BlockData> terrainNormalActuator;
|
||||||
private final EngineActuator<BlockData> terrainIslandActuator;
|
private final EngineActuator<BlockData> terrainIslandActuator;
|
||||||
private final EngineActuator<BlockData> decorantActuator;
|
private final EngineActuator<BlockData> decorantActuator;
|
||||||
@ -138,7 +139,6 @@ public class IrisEngine extends BlockPopulator implements Engine {
|
|||||||
context = new IrisContext(this);
|
context = new IrisContext(this);
|
||||||
context.touch();
|
context.touch();
|
||||||
this.complex = new IrisComplex(this);
|
this.complex = new IrisComplex(this);
|
||||||
this.engineParallax = new IrisEngineParallax(this);
|
|
||||||
this.terrainNormalActuator = new IrisTerrainNormalActuator(this);
|
this.terrainNormalActuator = new IrisTerrainNormalActuator(this);
|
||||||
this.terrainIslandActuator = new IrisTerrainIslandActuator(this);
|
this.terrainIslandActuator = new IrisTerrainIslandActuator(this);
|
||||||
this.decorantActuator = new IrisDecorantActuator(this);
|
this.decorantActuator = new IrisDecorantActuator(this);
|
||||||
@ -150,7 +150,7 @@ public class IrisEngine extends BlockPopulator implements Engine {
|
|||||||
cleaning = new AtomicBoolean(false);
|
cleaning = new AtomicBoolean(false);
|
||||||
cleanLatch = new ChronoLatch(Math.max(10000, Math.min(IrisSettings.get().getParallax()
|
cleanLatch = new ChronoLatch(Math.max(10000, Math.min(IrisSettings.get().getParallax()
|
||||||
.getParallaxChunkEvictionMS(), IrisSettings.get().getParallax().getParallaxRegionEvictionMS())));
|
.getParallaxChunkEvictionMS(), IrisSettings.get().getParallax().getParallaxRegionEvictionMS())));
|
||||||
|
mantle = new IrisEngineMantle(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -300,7 +300,7 @@ public class IrisEngine extends BlockPopulator implements Engine {
|
|||||||
getWorldManager().close();
|
getWorldManager().close();
|
||||||
getTarget().close();
|
getTarget().close();
|
||||||
saveEngineData();
|
saveEngineData();
|
||||||
getEngineParallax().close();
|
getMantle().close();
|
||||||
getTerrainActuator().close();
|
getTerrainActuator().close();
|
||||||
getDecorantActuator().close();
|
getDecorantActuator().close();
|
||||||
getBiomeActuator().close();
|
getBiomeActuator().close();
|
||||||
@ -328,8 +328,9 @@ public class IrisEngine extends BlockPopulator implements Engine {
|
|||||||
|
|
||||||
cleaning.set(true);
|
cleaning.set(true);
|
||||||
|
|
||||||
|
J.a(() -> {
|
||||||
try {
|
try {
|
||||||
getParallax().cleanup();
|
getMantle().trim();
|
||||||
getData().getObjectLoader().clean();
|
getData().getObjectLoader().clean();
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
Iris.reportError(e);
|
Iris.reportError(e);
|
||||||
@ -338,9 +339,9 @@ public class IrisEngine extends BlockPopulator implements Engine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
cleaning.lazySet(false);
|
cleaning.lazySet(false);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public EngineActuator<BlockData> getTerrainActuator() {
|
public EngineActuator<BlockData> getTerrainActuator() {
|
||||||
return switch (getDimension().getTerrainMode()) {
|
return switch (getDimension().getTerrainMode()) {
|
||||||
case NORMAL -> getTerrainNormalActuator();
|
case NORMAL -> getTerrainNormalActuator();
|
||||||
@ -371,14 +372,14 @@ public class IrisEngine extends BlockPopulator implements Engine {
|
|||||||
|
|
||||||
switch (getDimension().getTerrainMode()) {
|
switch (getDimension().getTerrainMode()) {
|
||||||
case NORMAL -> {
|
case NORMAL -> {
|
||||||
getEngineParallax().generateParallaxArea(x >> 4, z >> 4);
|
getMantle().generateMatter(x>>4, z>>4);
|
||||||
getTerrainActuator().actuate(x, z, vblocks, multicore);
|
getTerrainActuator().actuate(x, z, vblocks, multicore);
|
||||||
getBiomeActuator().actuate(x, z, vbiomes, multicore);
|
getBiomeActuator().actuate(x, z, vbiomes, multicore);
|
||||||
getCaveModifier().modify(x, z, vblocks, multicore);
|
getCaveModifier().modify(x, z, vblocks, multicore);
|
||||||
getRavineModifier().modify(x, z, vblocks, multicore);
|
getRavineModifier().modify(x, z, vblocks, multicore);
|
||||||
getPostModifier().modify(x, z, vblocks, multicore);
|
getPostModifier().modify(x, z, vblocks, multicore);
|
||||||
getDecorantActuator().actuate(x, z, blocks, multicore);
|
getDecorantActuator().actuate(x, z, blocks, multicore);
|
||||||
getEngineParallax().insertParallax(x >> 4, z >> 4, blocks);
|
getMantle().insertMatter(x>>4, z>>4, BlockData.class, blocks);
|
||||||
getDepositModifier().modify(x, z, blocks, multicore);
|
getDepositModifier().modify(x, z, blocks, multicore);
|
||||||
}
|
}
|
||||||
case ISLANDS -> {
|
case ISLANDS -> {
|
||||||
@ -388,6 +389,7 @@ public class IrisEngine extends BlockPopulator implements Engine {
|
|||||||
|
|
||||||
getMetrics().getTotal().put(p.getMilliseconds());
|
getMetrics().getTotal().put(p.getMilliseconds());
|
||||||
generated.incrementAndGet();
|
generated.incrementAndGet();
|
||||||
|
recycle();
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
Iris.reportError(e);
|
Iris.reportError(e);
|
||||||
fail("Failed to generate " + x + ", " + z, e);
|
fail("Failed to generate " + x + ", " + z, e);
|
||||||
|
@ -18,20 +18,294 @@
|
|||||||
|
|
||||||
package com.volmit.iris.engine;
|
package com.volmit.iris.engine;
|
||||||
|
|
||||||
|
import com.volmit.iris.Iris;
|
||||||
import com.volmit.iris.engine.framework.Engine;
|
import com.volmit.iris.engine.framework.Engine;
|
||||||
import com.volmit.iris.engine.mantle.EngineMantle;
|
import com.volmit.iris.engine.mantle.EngineMantle;
|
||||||
|
import com.volmit.iris.engine.mantle.IrisMantleComponent;
|
||||||
|
import com.volmit.iris.engine.mantle.MantleComponent;
|
||||||
|
import com.volmit.iris.engine.mantle.components.MantleFeatureComponent;
|
||||||
|
import com.volmit.iris.engine.mantle.components.MantleJigsawComponent;
|
||||||
|
import com.volmit.iris.engine.mantle.components.MantleObjectComponent;
|
||||||
|
import com.volmit.iris.engine.object.biome.IrisBiome;
|
||||||
|
import com.volmit.iris.engine.object.deposits.IrisDepositGenerator;
|
||||||
|
import com.volmit.iris.engine.object.feature.IrisFeaturePotential;
|
||||||
|
import com.volmit.iris.engine.object.jigsaw.IrisJigsawStructurePlacement;
|
||||||
|
import com.volmit.iris.engine.object.objects.IrisObject;
|
||||||
|
import com.volmit.iris.engine.object.objects.IrisObjectPlacement;
|
||||||
|
import com.volmit.iris.engine.object.objects.IrisObjectScale;
|
||||||
|
import com.volmit.iris.engine.object.regional.IrisRegion;
|
||||||
|
import com.volmit.iris.util.collection.KList;
|
||||||
|
import com.volmit.iris.util.collection.KMap;
|
||||||
|
import com.volmit.iris.util.collection.KSet;
|
||||||
|
import com.volmit.iris.util.format.Form;
|
||||||
import com.volmit.iris.util.mantle.Mantle;
|
import com.volmit.iris.util.mantle.Mantle;
|
||||||
|
import com.volmit.iris.util.parallel.BurstExecutor;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
import org.bukkit.util.BlockVector;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
public class IrisEngineMantle implements EngineMantle {
|
public class IrisEngineMantle implements EngineMantle {
|
||||||
private final Engine engine;
|
private final Engine engine;
|
||||||
private final Mantle mantle;
|
private final Mantle mantle;
|
||||||
|
private final KList<MantleComponent> components;
|
||||||
|
private final CompletableFuture<Integer> radius;
|
||||||
|
|
||||||
public IrisEngineMantle(Engine engine) {
|
public IrisEngineMantle(Engine engine) {
|
||||||
this.engine = engine;
|
this.engine = engine;
|
||||||
this.mantle = new Mantle(new File(engine.getWorld().worldFolder(), "mantle"), engine.getTarget().getHeight());
|
this.mantle = new Mantle(new File(engine.getWorld().worldFolder(), "mantle"), engine.getTarget().getHeight());
|
||||||
|
radius = burst().completeValue(this::computeParallaxSize);
|
||||||
|
components = new KList<>();
|
||||||
|
registerComponent(new MantleFeatureComponent(this));
|
||||||
|
registerComponent(new MantleJigsawComponent(this));
|
||||||
|
registerComponent(new MantleObjectComponent(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void registerComponent(MantleComponent c) {
|
||||||
|
components.add(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
private KList<IrisRegion> getAllRegions() {
|
||||||
|
KList<IrisRegion> r = new KList<>();
|
||||||
|
|
||||||
|
for (String i : getEngine().getDimension().getRegions()) {
|
||||||
|
r.add(getEngine().getData().getRegionLoader().load(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
private KList<IrisFeaturePotential> getAllFeatures() {
|
||||||
|
KList<IrisFeaturePotential> r = new KList<>();
|
||||||
|
r.addAll(getEngine().getDimension().getFeatures());
|
||||||
|
getAllRegions().forEach((i) -> r.addAll(i.getFeatures()));
|
||||||
|
getAllBiomes().forEach((i) -> r.addAll(i.getFeatures()));
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
private KList<IrisBiome> getAllBiomes() {
|
||||||
|
KList<IrisBiome> r = new KList<>();
|
||||||
|
|
||||||
|
for (IrisRegion i : getAllRegions()) {
|
||||||
|
r.addAll(i.getAllBiomes(getEngine()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void warn(String ob, BlockVector bv) {
|
||||||
|
if (Math.max(bv.getBlockX(), bv.getBlockZ()) > 128) {
|
||||||
|
Iris.warn("Object " + ob + " has a large size (" + bv + ") and may increase memory usage!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void warnScaled(String ob, BlockVector bv, double ms) {
|
||||||
|
if (Math.max(bv.getBlockX(), bv.getBlockZ()) > 128) {
|
||||||
|
Iris.warn("Object " + ob + " has a large size (" + bv + ") and may increase memory usage! (Object scaled up to " + Form.pc(ms, 2) + ")");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int computeFeatureRange() {
|
||||||
|
int m = 0;
|
||||||
|
|
||||||
|
for (IrisFeaturePotential i : getAllFeatures()) {
|
||||||
|
m = Math.max(m, i.getZone().getRealSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int computeParallaxSize() {
|
||||||
|
Iris.verbose("Calculating the Parallax Size in Parallel");
|
||||||
|
AtomicInteger xg = new AtomicInteger(0);
|
||||||
|
AtomicInteger zg = new AtomicInteger();
|
||||||
|
xg.set(0);
|
||||||
|
zg.set(0);
|
||||||
|
int jig = 0;
|
||||||
|
KSet<String> objects = new KSet<>();
|
||||||
|
KMap<IrisObjectScale, KList<String>> scalars = new KMap<>();
|
||||||
|
int x = xg.get();
|
||||||
|
int z = zg.get();
|
||||||
|
|
||||||
|
if (getEngine().getDimension().isUseMantle()) {
|
||||||
|
KList<IrisRegion> r = getAllRegions();
|
||||||
|
KList<IrisBiome> b = getAllBiomes();
|
||||||
|
|
||||||
|
for (IrisBiome i : b) {
|
||||||
|
for (IrisObjectPlacement j : i.getObjects()) {
|
||||||
|
if (j.getScale().canScaleBeyond()) {
|
||||||
|
scalars.put(j.getScale(), j.getPlace());
|
||||||
|
} else {
|
||||||
|
objects.addAll(j.getPlace());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (IrisJigsawStructurePlacement j : i.getJigsawStructures()) {
|
||||||
|
jig = Math.max(jig, getData().getJigsawStructureLoader().load(j.getStructure()).getMaxDimension());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (IrisRegion i : r) {
|
||||||
|
for (IrisObjectPlacement j : i.getObjects()) {
|
||||||
|
if (j.getScale().canScaleBeyond()) {
|
||||||
|
scalars.put(j.getScale(), j.getPlace());
|
||||||
|
} else {
|
||||||
|
objects.addAll(j.getPlace());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (IrisJigsawStructurePlacement j : i.getJigsawStructures()) {
|
||||||
|
jig = Math.max(jig, getData().getJigsawStructureLoader().load(j.getStructure()).getMaxDimension());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (IrisJigsawStructurePlacement j : getEngine().getDimension().getJigsawStructures()) {
|
||||||
|
jig = Math.max(jig, getData().getJigsawStructureLoader().load(j.getStructure()).getMaxDimension());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getEngine().getDimension().getStronghold() != null) {
|
||||||
|
try {
|
||||||
|
jig = Math.max(jig, getData().getJigsawStructureLoader().load(getEngine().getDimension().getStronghold()).getMaxDimension());
|
||||||
|
} catch (Throwable e) {
|
||||||
|
Iris.reportError(e);
|
||||||
|
Iris.error("THIS IS THE ONE");
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Iris.verbose("Checking sizes for " + Form.f(objects.size()) + " referenced objects.");
|
||||||
|
BurstExecutor e = getEngine().getTarget().getBurster().burst(objects.size());
|
||||||
|
KMap<String, BlockVector> sizeCache = new KMap<>();
|
||||||
|
for (String i : objects) {
|
||||||
|
e.queue(() -> {
|
||||||
|
try {
|
||||||
|
BlockVector bv = sizeCache.compute(i, (k, v) -> {
|
||||||
|
if (v != null) {
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return IrisObject.sampleSize(getData().getObjectLoader().findFile(i));
|
||||||
|
} catch (IOException ex) {
|
||||||
|
Iris.reportError(ex);
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (bv == null) {
|
||||||
|
throw new RuntimeException();
|
||||||
|
}
|
||||||
|
|
||||||
|
warn(i, bv);
|
||||||
|
|
||||||
|
synchronized (xg) {
|
||||||
|
xg.getAndSet(Math.max(bv.getBlockX(), xg.get()));
|
||||||
|
}
|
||||||
|
|
||||||
|
synchronized (zg) {
|
||||||
|
zg.getAndSet(Math.max(bv.getBlockZ(), zg.get()));
|
||||||
|
}
|
||||||
|
} catch (Throwable ed) {
|
||||||
|
Iris.reportError(ed);
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Map.Entry<IrisObjectScale, KList<String>> entry : scalars.entrySet()) {
|
||||||
|
double ms = entry.getKey().getMaximumScale();
|
||||||
|
for (String j : entry.getValue()) {
|
||||||
|
e.queue(() -> {
|
||||||
|
try {
|
||||||
|
BlockVector bv = sizeCache.compute(j, (k, v) -> {
|
||||||
|
if (v != null) {
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return IrisObject.sampleSize(getData().getObjectLoader().findFile(j));
|
||||||
|
} catch (IOException ioException) {
|
||||||
|
Iris.reportError(ioException);
|
||||||
|
ioException.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (bv == null) {
|
||||||
|
throw new RuntimeException();
|
||||||
|
}
|
||||||
|
|
||||||
|
warnScaled(j, bv, ms);
|
||||||
|
|
||||||
|
synchronized (xg) {
|
||||||
|
xg.getAndSet((int) Math.max(Math.ceil(bv.getBlockX() * ms), xg.get()));
|
||||||
|
}
|
||||||
|
|
||||||
|
synchronized (zg) {
|
||||||
|
zg.getAndSet((int) Math.max(Math.ceil(bv.getBlockZ() * ms), zg.get()));
|
||||||
|
}
|
||||||
|
} catch (Throwable ee) {
|
||||||
|
Iris.reportError(ee);
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
e.complete();
|
||||||
|
|
||||||
|
x = xg.get();
|
||||||
|
z = zg.get();
|
||||||
|
|
||||||
|
for (IrisDepositGenerator i : getEngine().getDimension().getDeposits()) {
|
||||||
|
int max = i.getMaxDimension();
|
||||||
|
x = Math.max(max, x);
|
||||||
|
z = Math.max(max, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (IrisRegion v : r) {
|
||||||
|
for (IrisDepositGenerator i : v.getDeposits()) {
|
||||||
|
int max = i.getMaxDimension();
|
||||||
|
x = Math.max(max, x);
|
||||||
|
z = Math.max(max, z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (IrisBiome v : b) {
|
||||||
|
for (IrisDepositGenerator i : v.getDeposits()) {
|
||||||
|
int max = i.getMaxDimension();
|
||||||
|
x = Math.max(max, x);
|
||||||
|
z = Math.max(max, z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
x = Math.max(z, x);
|
||||||
|
int u = x;
|
||||||
|
int v = computeFeatureRange();
|
||||||
|
x = Math.max(jig, x);
|
||||||
|
x = Math.max(x, v);
|
||||||
|
x = (Math.max(x, 16) + 16) >> 4;
|
||||||
|
x = x % 2 == 0 ? x + 1 : x;
|
||||||
|
Iris.info("Parallax Size: " + x + " Chunks");
|
||||||
|
Iris.info(" Object Parallax Size: " + u + " (" + ((Math.max(u, 16) + 16) >> 4) + ")");
|
||||||
|
Iris.info(" Jigsaw Parallax Size: " + jig + " (" + ((Math.max(jig, 16) + 16) >> 4) + ")");
|
||||||
|
Iris.info(" Feature Parallax Size: " + v + " (" + ((Math.max(v, 16) + 16) >> 4) + ")");
|
||||||
|
|
||||||
|
return x;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -206,7 +206,7 @@ public class IrisWorldManager extends EngineAssignedWorldManager {
|
|||||||
getData().getSpawnerLoader()
|
getData().getSpawnerLoader()
|
||||||
.loadAll(getDimension().getEntitySpawners())
|
.loadAll(getDimension().getEntitySpawners())
|
||||||
.shuffleCopy(RNG.r).stream().filter(this::canSpawn),
|
.shuffleCopy(RNG.r).stream().filter(this::canSpawn),
|
||||||
getData().getSpawnerLoader().streamAll(getEngine().getEngineParallax()
|
getData().getSpawnerLoader().streamAll(getEngine().getMantle()
|
||||||
.getFeaturesInChunk(c).stream()
|
.getFeaturesInChunk(c).stream()
|
||||||
.flatMap((o) -> o.getFeature().getEntitySpawners().stream()))
|
.flatMap((o) -> o.getFeature().getEntitySpawners().stream()))
|
||||||
.filter(this::canSpawn))
|
.filter(this::canSpawn))
|
||||||
@ -333,7 +333,7 @@ public class IrisWorldManager extends EngineAssignedWorldManager {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSave() {
|
public void onSave() {
|
||||||
getEngine().getParallax().saveAll();
|
getEngine().getMantle().save();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -24,6 +24,7 @@ import com.volmit.iris.core.gui.components.Renderer;
|
|||||||
import com.volmit.iris.core.project.loader.IrisData;
|
import com.volmit.iris.core.project.loader.IrisData;
|
||||||
import com.volmit.iris.engine.IrisComplex;
|
import com.volmit.iris.engine.IrisComplex;
|
||||||
import com.volmit.iris.engine.data.cache.Cache;
|
import com.volmit.iris.engine.data.cache.Cache;
|
||||||
|
import com.volmit.iris.engine.mantle.EngineMantle;
|
||||||
import com.volmit.iris.engine.object.basic.IrisColor;
|
import com.volmit.iris.engine.object.basic.IrisColor;
|
||||||
import com.volmit.iris.engine.object.basic.IrisPosition;
|
import com.volmit.iris.engine.object.basic.IrisPosition;
|
||||||
import com.volmit.iris.engine.object.biome.IrisBiome;
|
import com.volmit.iris.engine.object.biome.IrisBiome;
|
||||||
@ -34,8 +35,8 @@ import com.volmit.iris.engine.object.loot.IrisLootMode;
|
|||||||
import com.volmit.iris.engine.object.loot.IrisLootReference;
|
import com.volmit.iris.engine.object.loot.IrisLootReference;
|
||||||
import com.volmit.iris.engine.object.loot.IrisLootTable;
|
import com.volmit.iris.engine.object.loot.IrisLootTable;
|
||||||
import com.volmit.iris.engine.object.meta.InventorySlotType;
|
import com.volmit.iris.engine.object.meta.InventorySlotType;
|
||||||
|
import com.volmit.iris.engine.object.objects.IrisObjectPlacement;
|
||||||
import com.volmit.iris.engine.object.regional.IrisRegion;
|
import com.volmit.iris.engine.object.regional.IrisRegion;
|
||||||
import com.volmit.iris.engine.parallax.ParallaxAccess;
|
|
||||||
import com.volmit.iris.engine.scripting.EngineExecutionEnvironment;
|
import com.volmit.iris.engine.scripting.EngineExecutionEnvironment;
|
||||||
import com.volmit.iris.util.collection.KList;
|
import com.volmit.iris.util.collection.KList;
|
||||||
import com.volmit.iris.util.collection.KMap;
|
import com.volmit.iris.util.collection.KMap;
|
||||||
@ -46,6 +47,8 @@ import com.volmit.iris.util.documentation.BlockCoordinates;
|
|||||||
import com.volmit.iris.util.documentation.ChunkCoordinates;
|
import com.volmit.iris.util.documentation.ChunkCoordinates;
|
||||||
import com.volmit.iris.util.function.Function2;
|
import com.volmit.iris.util.function.Function2;
|
||||||
import com.volmit.iris.util.hunk.Hunk;
|
import com.volmit.iris.util.hunk.Hunk;
|
||||||
|
import com.volmit.iris.util.mantle.Mantle;
|
||||||
|
import com.volmit.iris.util.mantle.MantleFlag;
|
||||||
import com.volmit.iris.util.math.BlockPosition;
|
import com.volmit.iris.util.math.BlockPosition;
|
||||||
import com.volmit.iris.util.math.M;
|
import com.volmit.iris.util.math.M;
|
||||||
import com.volmit.iris.util.math.RNG;
|
import com.volmit.iris.util.math.RNG;
|
||||||
@ -75,14 +78,14 @@ import java.util.concurrent.atomic.AtomicLong;
|
|||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
public interface Engine extends DataProvider, Fallible, GeneratorAccess, LootProvider, BlockUpdater, Renderer {
|
public interface Engine extends DataProvider, Fallible, LootProvider, BlockUpdater, Renderer {
|
||||||
IrisComplex getComplex();
|
IrisComplex getComplex();
|
||||||
|
|
||||||
void printMetrics(CommandSender sender);
|
void printMetrics(CommandSender sender);
|
||||||
|
|
||||||
void recycle();
|
EngineMantle getMantle();
|
||||||
|
|
||||||
EngineParallaxManager getEngineParallax();
|
void recycle();
|
||||||
|
|
||||||
EngineActuator<BlockData> getTerrainActuator();
|
EngineActuator<BlockData> getTerrainActuator();
|
||||||
|
|
||||||
@ -143,13 +146,13 @@ public interface Engine extends DataProvider, Fallible, GeneratorAccess, LootPro
|
|||||||
EngineMetrics getMetrics();
|
EngineMetrics getMetrics();
|
||||||
|
|
||||||
default void save() {
|
default void save() {
|
||||||
getParallax().saveAll();
|
getMantle().save();
|
||||||
getWorldManager().onSave();
|
getWorldManager().onSave();
|
||||||
saveEngineData();
|
saveEngineData();
|
||||||
}
|
}
|
||||||
|
|
||||||
default void saveNow() {
|
default void saveNow() {
|
||||||
getParallax().saveAllNOW();
|
getMantle().saveAllNow();
|
||||||
saveEngineData();
|
saveEngineData();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -171,10 +174,6 @@ public interface Engine extends DataProvider, Fallible, GeneratorAccess, LootPro
|
|||||||
return getTarget().getDimension();
|
return getTarget().getDimension();
|
||||||
}
|
}
|
||||||
|
|
||||||
default ParallaxAccess getParallax() {
|
|
||||||
return getTarget().getParallaxWorld();
|
|
||||||
}
|
|
||||||
|
|
||||||
@BlockCoordinates
|
@BlockCoordinates
|
||||||
default Color draw(double x, double z) {
|
default Color draw(double x, double z) {
|
||||||
IrisRegion region = getRegion((int) x, (int) z);
|
IrisRegion region = getRegion((int) x, (int) z);
|
||||||
@ -191,37 +190,28 @@ public interface Engine extends DataProvider, Fallible, GeneratorAccess, LootPro
|
|||||||
}
|
}
|
||||||
|
|
||||||
@BlockCoordinates
|
@BlockCoordinates
|
||||||
@Override
|
|
||||||
default IrisRegion getRegion(int x, int z) {
|
default IrisRegion getRegion(int x, int z) {
|
||||||
return getComplex().getRegionStream().get(x, z);
|
return getComplex().getRegionStream().get(x, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
default ParallaxAccess getParallaxAccess() {
|
|
||||||
return getParallax();
|
|
||||||
}
|
|
||||||
|
|
||||||
@BlockCoordinates
|
@BlockCoordinates
|
||||||
@Override
|
|
||||||
default IrisBiome getCaveBiome(int x, int z) {
|
default IrisBiome getCaveBiome(int x, int z) {
|
||||||
return getComplex().getCaveBiomeStream().get(x, z);
|
return getComplex().getCaveBiomeStream().get(x, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
@BlockCoordinates
|
@BlockCoordinates
|
||||||
@Override
|
|
||||||
default IrisBiome getSurfaceBiome(int x, int z) {
|
default IrisBiome getSurfaceBiome(int x, int z) {
|
||||||
return getComplex().getTrueBiomeStream().get(x, z);
|
return getComplex().getTrueBiomeStream().get(x, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
@BlockCoordinates
|
@BlockCoordinates
|
||||||
@Override
|
|
||||||
default int getHeight(int x, int z) {
|
default int getHeight(int x, int z) {
|
||||||
return getHeight(x, z, true);
|
return getHeight(x, z, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@BlockCoordinates
|
@BlockCoordinates
|
||||||
default int getHeight(int x, int z, boolean ignoreFluid) {
|
default int getHeight(int x, int z, boolean ignoreFluid) {
|
||||||
return getEngineParallax().getHighest(x, z, getData(), ignoreFluid);
|
return getMantle().getHighest(x, z, getData(), ignoreFluid);
|
||||||
}
|
}
|
||||||
|
|
||||||
@BlockCoordinates
|
@BlockCoordinates
|
||||||
@ -232,8 +222,7 @@ public interface Engine extends DataProvider, Fallible, GeneratorAccess, LootPro
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (B.isUpdatable(data)) {
|
if (B.isUpdatable(data)) {
|
||||||
getParallax().updateBlock(x, y, z);
|
getMantle().updateBlock(x, y, z);
|
||||||
getParallax().getMetaRW(x >> 4, z >> 4).setUpdates(true);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -246,11 +235,7 @@ public interface Engine extends DataProvider, Fallible, GeneratorAccess, LootPro
|
|||||||
@Override
|
@Override
|
||||||
default void updateChunk(Chunk c) {
|
default void updateChunk(Chunk c) {
|
||||||
PrecisionStopwatch p = PrecisionStopwatch.start();
|
PrecisionStopwatch p = PrecisionStopwatch.start();
|
||||||
if (getParallax().getMetaR(c.getX(), c.getZ()).isUpdates()) {
|
getMantle().getMantle().iterateChunk(c.getX(), c.getZ(), Boolean.class, (x, y, z, v) -> {
|
||||||
Hunk<Boolean> b = getParallax().getUpdatesR(c.getX(), c.getZ());
|
|
||||||
|
|
||||||
b.iterateSync((x, y, z, v) -> {
|
|
||||||
|
|
||||||
if (v != null && v) {
|
if (v != null && v) {
|
||||||
int vx = x & 15;
|
int vx = x & 15;
|
||||||
int vz = z & 15;
|
int vz = z & 15;
|
||||||
@ -260,9 +245,7 @@ public interface Engine extends DataProvider, Fallible, GeneratorAccess, LootPro
|
|||||||
updateLighting(x, y, z, c);
|
updateLighting(x, y, z, c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
}, MantleFlag.UPDATE);
|
||||||
}
|
|
||||||
|
|
||||||
getMetrics().getUpdates().put(p.getMilliseconds());
|
getMetrics().getUpdates().put(p.getMilliseconds());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -277,7 +260,6 @@ public interface Engine extends DataProvider, Fallible, GeneratorAccess, LootPro
|
|||||||
block.setBlockData(data, true);
|
block.setBlockData(data, true);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Iris.reportError(e);
|
Iris.reportError(e);
|
||||||
// Issue when adding block data. Suppress massive warnings and stack-traces to console.
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -423,7 +405,7 @@ public interface Engine extends DataProvider, Fallible, GeneratorAccess, LootPro
|
|||||||
}
|
}
|
||||||
|
|
||||||
default void clean() {
|
default void clean() {
|
||||||
burst().lazy(() -> getParallax().cleanup());
|
burst().lazy(() -> getMantle().trim());
|
||||||
}
|
}
|
||||||
|
|
||||||
@BlockCoordinates
|
@BlockCoordinates
|
||||||
@ -642,4 +624,55 @@ public interface Engine extends DataProvider, Fallible, GeneratorAccess, LootPro
|
|||||||
}
|
}
|
||||||
|
|
||||||
boolean isStudio();
|
boolean isStudio();
|
||||||
|
|
||||||
|
default IrisBiome getBiome(int x, int y, int z) {
|
||||||
|
if (y <= getHeight(x, z) - 2) {
|
||||||
|
return getCaveBiome(x, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
return getSurfaceBiome(x, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
default String getObjectPlacementKey(int x, int y, int z)
|
||||||
|
{
|
||||||
|
PlacedObject o = getObjectPlacement(x,y,z);
|
||||||
|
|
||||||
|
if(o != null && o.getObject() != null)
|
||||||
|
{
|
||||||
|
return o.getObject().getLoadKey() + "@" + o.getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
default PlacedObject getObjectPlacement(int x, int y, int z) {
|
||||||
|
String objectAt = getMantle().getMantle().get(x,y,z, String.class);
|
||||||
|
|
||||||
|
if (objectAt == null || objectAt.isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
String[] v = objectAt.split("\\Q@\\E");
|
||||||
|
String object = v[0];
|
||||||
|
int id = Integer.parseInt(v[1]);
|
||||||
|
IrisRegion region = getRegion(x, z);
|
||||||
|
|
||||||
|
for (IrisObjectPlacement i : region.getObjects()) {
|
||||||
|
if (i.getPlace().contains(object)) {
|
||||||
|
return new PlacedObject(i, getData().getObjectLoader().load(object), id, x, z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
IrisBiome biome = getBiome(x, y, z);
|
||||||
|
|
||||||
|
for (IrisObjectPlacement i : biome.getObjects()) {
|
||||||
|
if (i.getPlace().contains(object)) {
|
||||||
|
return new PlacedObject(i, getData().getObjectLoader().load(object), id, x, z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new PlacedObject(null, getData().getObjectLoader().load(object), id, x, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
int getCacheID();
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,6 @@ import com.volmit.iris.Iris;
|
|||||||
import com.volmit.iris.core.project.loader.IrisData;
|
import com.volmit.iris.core.project.loader.IrisData;
|
||||||
import com.volmit.iris.engine.IrisComplex;
|
import com.volmit.iris.engine.IrisComplex;
|
||||||
import com.volmit.iris.engine.object.dimensional.IrisDimension;
|
import com.volmit.iris.engine.object.dimensional.IrisDimension;
|
||||||
import com.volmit.iris.engine.parallax.ParallaxAccess;
|
|
||||||
import com.volmit.iris.util.math.RollingSequence;
|
import com.volmit.iris.util.math.RollingSequence;
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
|
|
||||||
@ -56,10 +55,6 @@ public interface EngineComponent {
|
|||||||
return getEngine().getData();
|
return getEngine().getData();
|
||||||
}
|
}
|
||||||
|
|
||||||
default ParallaxAccess getParallax() {
|
|
||||||
return getEngine().getParallax();
|
|
||||||
}
|
|
||||||
|
|
||||||
default EngineTarget getTarget() {
|
default EngineTarget getTarget() {
|
||||||
return getEngine().getTarget();
|
return getEngine().getTarget();
|
||||||
}
|
}
|
||||||
|
@ -1,941 +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.framework;
|
|
||||||
|
|
||||||
import com.volmit.iris.Iris;
|
|
||||||
import com.volmit.iris.core.project.loader.IrisData;
|
|
||||||
import com.volmit.iris.engine.IrisComplex;
|
|
||||||
import com.volmit.iris.engine.data.cache.Cache;
|
|
||||||
import com.volmit.iris.engine.jigsaw.PlannedStructure;
|
|
||||||
import com.volmit.iris.engine.object.basic.IrisPosition;
|
|
||||||
import com.volmit.iris.engine.object.biome.IrisBiome;
|
|
||||||
import com.volmit.iris.engine.object.biome.IrisBiomeMutation;
|
|
||||||
import com.volmit.iris.engine.object.common.IObjectPlacer;
|
|
||||||
import com.volmit.iris.engine.object.deposits.IrisDepositGenerator;
|
|
||||||
import com.volmit.iris.engine.object.feature.IrisFeature;
|
|
||||||
import com.volmit.iris.engine.object.feature.IrisFeaturePositional;
|
|
||||||
import com.volmit.iris.engine.object.feature.IrisFeaturePotential;
|
|
||||||
import com.volmit.iris.engine.object.jigsaw.IrisJigsawStructure;
|
|
||||||
import com.volmit.iris.engine.object.jigsaw.IrisJigsawStructurePlacement;
|
|
||||||
import com.volmit.iris.engine.object.objects.IrisObject;
|
|
||||||
import com.volmit.iris.engine.object.objects.IrisObjectPlacement;
|
|
||||||
import com.volmit.iris.engine.object.objects.IrisObjectScale;
|
|
||||||
import com.volmit.iris.engine.object.regional.IrisRegion;
|
|
||||||
import com.volmit.iris.engine.object.tile.TileData;
|
|
||||||
import com.volmit.iris.engine.parallax.ParallaxAccess;
|
|
||||||
import com.volmit.iris.engine.parallax.ParallaxChunkMeta;
|
|
||||||
import com.volmit.iris.util.collection.KList;
|
|
||||||
import com.volmit.iris.util.collection.KMap;
|
|
||||||
import com.volmit.iris.util.collection.KSet;
|
|
||||||
import com.volmit.iris.util.data.B;
|
|
||||||
import com.volmit.iris.util.data.DataProvider;
|
|
||||||
import com.volmit.iris.util.documentation.BlockCoordinates;
|
|
||||||
import com.volmit.iris.util.documentation.ChunkCoordinates;
|
|
||||||
import com.volmit.iris.util.format.Form;
|
|
||||||
import com.volmit.iris.util.function.Consumer4;
|
|
||||||
import com.volmit.iris.util.hunk.Hunk;
|
|
||||||
import com.volmit.iris.util.math.Position2;
|
|
||||||
import com.volmit.iris.util.math.RNG;
|
|
||||||
import com.volmit.iris.util.parallel.BurstExecutor;
|
|
||||||
import com.volmit.iris.util.scheduling.J;
|
|
||||||
import com.volmit.iris.util.scheduling.PrecisionStopwatch;
|
|
||||||
import org.bukkit.Chunk;
|
|
||||||
import org.bukkit.ChunkSnapshot;
|
|
||||||
import org.bukkit.block.TileState;
|
|
||||||
import org.bukkit.block.data.BlockData;
|
|
||||||
import org.bukkit.util.BlockVector;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
|
||||||
|
|
||||||
public interface EngineParallaxManager extends DataProvider, IObjectPlacer {
|
|
||||||
BlockData AIR = B.get("AIR");
|
|
||||||
|
|
||||||
Engine getEngine();
|
|
||||||
|
|
||||||
int getParallaxSize();
|
|
||||||
|
|
||||||
default ParallaxAccess getParallaxAccess() {
|
|
||||||
return getEngine().getParallax();
|
|
||||||
}
|
|
||||||
|
|
||||||
default IrisData getData() {
|
|
||||||
return getEngine().getData();
|
|
||||||
}
|
|
||||||
|
|
||||||
default IrisComplex getComplex() {
|
|
||||||
return getEngine().getComplex();
|
|
||||||
}
|
|
||||||
|
|
||||||
default KList<IrisRegion> getAllRegions() {
|
|
||||||
KList<IrisRegion> r = new KList<>();
|
|
||||||
|
|
||||||
for (String i : getEngine().getDimension().getRegions()) {
|
|
||||||
r.add(getEngine().getData().getRegionLoader().load(i));
|
|
||||||
}
|
|
||||||
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
default KList<IrisFeaturePotential> getAllFeatures() {
|
|
||||||
KList<IrisFeaturePotential> r = new KList<>();
|
|
||||||
r.addAll(getEngine().getDimension().getFeatures());
|
|
||||||
getAllRegions().forEach((i) -> r.addAll(i.getFeatures()));
|
|
||||||
getAllBiomes().forEach((i) -> r.addAll(i.getFeatures()));
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
default KList<IrisBiome> getAllBiomes() {
|
|
||||||
KList<IrisBiome> r = new KList<>();
|
|
||||||
|
|
||||||
for (IrisRegion i : getAllRegions()) {
|
|
||||||
r.addAll(i.getAllBiomes(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Verifies the chunk correctly has all the parallax objects it should.
|
|
||||||
* This method should not have to be written but why not.
|
|
||||||
* Thread Safe, Designed to run async
|
|
||||||
*
|
|
||||||
* @param c the bukkit chunk
|
|
||||||
*/
|
|
||||||
default int repairChunk(Chunk c) {
|
|
||||||
ParallaxChunkMeta m = getParallaxAccess().getMetaR(c.getX(), c.getZ());
|
|
||||||
Hunk<String> o = getParallaxAccess().getObjectsR(c.getX(), c.getZ());
|
|
||||||
Hunk<BlockData> b = getParallaxAccess().getBlocksR(c.getX(), c.getZ());
|
|
||||||
ChunkSnapshot snapshot = c.getChunkSnapshot(false, false, false);
|
|
||||||
KList<Runnable> queue = new KList<>();
|
|
||||||
|
|
||||||
o.iterateSync((x, y, z, s) -> {
|
|
||||||
if (s != null) {
|
|
||||||
|
|
||||||
BlockData bd = b.get(x, y, z);
|
|
||||||
if (bd != null) {
|
|
||||||
BlockData bdx = snapshot.getBlockData(x, y, z);
|
|
||||||
|
|
||||||
if (!bdx.getMaterial().equals(bd.getMaterial())) {
|
|
||||||
queue.add(() -> c.getBlock(x, y, z).setBlockData(bd, false));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
AtomicBoolean bx = new AtomicBoolean(false);
|
|
||||||
J.s(() -> {
|
|
||||||
queue.forEach(Runnable::run);
|
|
||||||
bx.set(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
while (!bx.get()) {
|
|
||||||
J.sleep(50);
|
|
||||||
}
|
|
||||||
|
|
||||||
return queue.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
default void insertTileEntities(int x, int z, Consumer4<Integer, Integer, Integer, TileData<? extends TileState>> consumer) {
|
|
||||||
ParallaxChunkMeta meta = getParallaxAccess().getMetaRW(x >> 4, z >> 4);
|
|
||||||
|
|
||||||
if (meta.isTilesGenerated()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
meta.setTilesGenerated(true);
|
|
||||||
|
|
||||||
getParallaxAccess().getTilesRW(x >> 4, z >> 4).iterateSync((a, b, c, d) -> {
|
|
||||||
if (d != null) {
|
|
||||||
consumer.accept(a, b, c, d);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@ChunkCoordinates
|
|
||||||
default void insertParallax(int x, int z, Hunk<BlockData> data) {
|
|
||||||
if (!getEngine().getDimension().isPlaceObjects()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
PrecisionStopwatch p = PrecisionStopwatch.start();
|
|
||||||
ParallaxChunkMeta meta = getParallaxAccess().getMetaR(x, z);
|
|
||||||
|
|
||||||
if (!meta.isParallaxGenerated()) {
|
|
||||||
generateParallaxLayer(x, z, true);
|
|
||||||
meta = getParallaxAccess().getMetaR(x, z);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!meta.isObjects()) {
|
|
||||||
getEngine().getMetrics().getParallaxInsert().put(p.getMilliseconds());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
getParallaxAccess().getBlocksR(x, z).iterateSync((a, b, c, d) -> {
|
|
||||||
if (d != null) {
|
|
||||||
data.set(a, b, c, d);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
getEngine().getMetrics().getParallaxInsert().put(p.getMilliseconds());
|
|
||||||
} catch (Throwable e) {
|
|
||||||
Iris.reportError(e);
|
|
||||||
Iris.error("Failed to insert parallax at chunk " + x + " " + z);
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@ChunkCoordinates
|
|
||||||
default KList<IrisFeaturePositional> getFeaturesInChunk(int x, int z) {
|
|
||||||
KList<IrisFeaturePositional> pos = new KList<>();
|
|
||||||
|
|
||||||
for (IrisFeaturePositional i : getEngine().getDimension().getSpecificFeatures()) {
|
|
||||||
if (i.shouldFilter((x << 4) + 8, (z << 4) + 8, getEngine().getComplex().getRng(), getData())) {
|
|
||||||
pos.add(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (IrisFeaturePositional i : getParallaxAccess().getMetaR(x, z).getFeatures()) {
|
|
||||||
if (i.shouldFilter((x << 4) + 8, (z << 4) + 8, getEngine().getComplex().getRng(), getData())) {
|
|
||||||
pos.add(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pos.add(forEachFeature(x << 4, z << 4));
|
|
||||||
pos.add(forEachFeature(((x + 1) << 4) - 1, z << 4));
|
|
||||||
pos.add(forEachFeature(x << 4, ((z + 1) << 4) - 1));
|
|
||||||
pos.add(forEachFeature(((x + 1) << 4) - 1, ((z + 1) << 4) - 1));
|
|
||||||
pos.removeDuplicates();
|
|
||||||
return pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
@BlockCoordinates
|
|
||||||
default KList<IrisFeaturePositional> forEachFeature(double x, double z) {
|
|
||||||
KList<IrisFeaturePositional> pos = new KList<>();
|
|
||||||
|
|
||||||
if (!getEngine().getDimension().hasFeatures(getEngine())) {
|
|
||||||
return pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (IrisFeaturePositional i : getEngine().getDimension().getSpecificFeatures()) {
|
|
||||||
if (i.shouldFilter(x, z, getEngine().getComplex().getRng(), getData())) {
|
|
||||||
pos.add(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int s = (int) Math.ceil(getParallaxSize() / 2D);
|
|
||||||
|
|
||||||
int i, j;
|
|
||||||
int cx = (int) x >> 4;
|
|
||||||
int cz = (int) z >> 4;
|
|
||||||
|
|
||||||
for (i = -s; i <= s; i++) {
|
|
||||||
for (j = -s; j <= s; j++) {
|
|
||||||
ParallaxChunkMeta m = getParallaxAccess().getMetaR(i + cx, j + cz);
|
|
||||||
|
|
||||||
try {
|
|
||||||
for (IrisFeaturePositional k : m.getFeatures()) {
|
|
||||||
if (k.shouldFilter(x, z, getEngine().getComplex().getRng(), getData())) {
|
|
||||||
pos.add(k);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Throwable e) {
|
|
||||||
Iris.error("FILTER ERROR" + " AT " + (cx + i) + " " + (j + cz));
|
|
||||||
e.printStackTrace();
|
|
||||||
Iris.reportError(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
@ChunkCoordinates
|
|
||||||
@SuppressWarnings("SynchronizationOnLocalVariableOrMethodParameter")
|
|
||||||
default void generateParallaxArea(int x, int z) {
|
|
||||||
if (!getEngine().getDimension().isPlaceObjects()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
PrecisionStopwatch p = PrecisionStopwatch.start();
|
|
||||||
|
|
||||||
int s = (int) Math.ceil(getParallaxSize() / 2D);
|
|
||||||
int i, j;
|
|
||||||
KList<Runnable> after = new KList<>();
|
|
||||||
int bs = (int) Math.pow((s * 2) + 1, 2);
|
|
||||||
BurstExecutor burst = getEngine().getTarget().getBurster().burst(bs);
|
|
||||||
for (i = -s; i <= s; i++) {
|
|
||||||
for (j = -s; j <= s; j++) {
|
|
||||||
int xx = i + x;
|
|
||||||
int zz = j + z;
|
|
||||||
int xxx = xx << 4;
|
|
||||||
int zzz = zz << 4;
|
|
||||||
if (!getParallaxAccess().isFeatureGenerated(xx, zz)) {
|
|
||||||
getParallaxAccess().setFeatureGenerated(xx, zz);
|
|
||||||
burst.queue(() -> {
|
|
||||||
RNG rng = new RNG(Cache.key(xx, zz) + getEngine().getTarget().getWorld().seed());
|
|
||||||
IrisRegion region = getComplex().getRegionStream().get(xxx, zzz);
|
|
||||||
IrisBiome biome = getComplex().getTrueBiomeStreamNoFeatures().get(xxx, zzz);
|
|
||||||
generateParallaxFeatures(rng, xx, zz, region, biome);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
burst.complete();
|
|
||||||
|
|
||||||
if (getEngine().getDimension().isPlaceObjects()) {
|
|
||||||
burst = getEngine().getTarget().getBurster().burst(bs);
|
|
||||||
|
|
||||||
for (i = -s; i <= s; i++) {
|
|
||||||
int ii = i;
|
|
||||||
for (j = -s; j <= s; j++) {
|
|
||||||
int jj = j;
|
|
||||||
burst.queue(() -> {
|
|
||||||
KList<Runnable> a = generateParallaxVacuumLayer(ii + x, jj + z);
|
|
||||||
synchronized (a) {
|
|
||||||
after.addAll(a);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
burst.complete();
|
|
||||||
burst = getEngine().getTarget().getBurster().burst(bs);
|
|
||||||
|
|
||||||
for (i = -s; i <= s; i++) {
|
|
||||||
int ii = i;
|
|
||||||
for (j = -s; j <= s; j++) {
|
|
||||||
int jj = j;
|
|
||||||
burst.queue(() -> generateParallaxLayer(ii + x, jj + z));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
burst.complete();
|
|
||||||
}
|
|
||||||
|
|
||||||
getEngine().getTarget().getBurster().burst(after);
|
|
||||||
getParallaxAccess().setChunkGenerated(x, z);
|
|
||||||
p.end();
|
|
||||||
getEngine().getMetrics().getParallax().put(p.getMilliseconds());
|
|
||||||
} catch (Throwable e) {
|
|
||||||
Iris.reportError(e);
|
|
||||||
Iris.error("Failed to generate parallax in " + x + " " + z);
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@ChunkCoordinates
|
|
||||||
default KList<Runnable> generateParallaxVacuumLayer(int x, int z) {
|
|
||||||
KList<Runnable> after = new KList<>();
|
|
||||||
if (getParallaxAccess().isParallaxGenerated(x, z)) {
|
|
||||||
return after;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (getEngine().getDimension().isPlaceObjects()) {
|
|
||||||
int xx = x << 4;
|
|
||||||
int zz = z << 4;
|
|
||||||
RNG rng = new RNG(Cache.key(x, z)).nextParallelRNG(getEngine().getTarget().getWorld().seed());
|
|
||||||
IrisRegion region = getComplex().getRegionStream().get(xx + 8, zz + 8);
|
|
||||||
IrisBiome biome = getComplex().getTrueBiomeStreamNoFeatures().get(xx + 8, zz + 8);
|
|
||||||
after.addAll(generateParallaxJigsaw(rng, x, z, biome, region));
|
|
||||||
generateParallaxSurface(rng, x, z, biome, region, true);
|
|
||||||
generateParallaxMutations(rng, x, z, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
return after;
|
|
||||||
}
|
|
||||||
|
|
||||||
default void generateParallaxLayer(int x, int z, boolean force) {
|
|
||||||
if (!force && getParallaxAccess().isParallaxGenerated(x, z)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int xx = x << 4;
|
|
||||||
int zz = z << 4;
|
|
||||||
getParallaxAccess().setParallaxGenerated(x, z);
|
|
||||||
RNG rng = new RNG(Cache.key(x, z)).nextParallelRNG(getEngine().getTarget().getWorld().seed());
|
|
||||||
IrisBiome biome = getComplex().getTrueBiomeStreamNoFeatures().get(xx + 8, zz + 8);
|
|
||||||
IrisRegion region = getComplex().getRegionStream().get(xx + 8, zz + 8);
|
|
||||||
generateParallaxSurface(rng, x, z, biome, region, false);
|
|
||||||
generateParallaxMutations(rng, x, z, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@ChunkCoordinates
|
|
||||||
default void generateParallaxFeatures(RNG rng, int cx, int cz, IrisRegion region, IrisBiome biome) {
|
|
||||||
for (IrisFeaturePotential i : getEngine().getDimension().getFeatures()) {
|
|
||||||
placeZone(rng, cx, cz, i);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (IrisFeaturePotential i : region.getFeatures()) {
|
|
||||||
placeZone(rng, cx, cz, i);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (IrisFeaturePotential i : biome.getFeatures()) {
|
|
||||||
placeZone(rng, cx, cz, i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
default void placeZone(RNG rng, int cx, int cz, IrisFeaturePotential i) {
|
|
||||||
if (i.hasZone(rng, cx, cz)) {
|
|
||||||
getParallaxAccess().getMetaRW(cx, cz).getFeatures()
|
|
||||||
.add(new IrisFeaturePositional(
|
|
||||||
(cx << 4) + rng.nextInt(16),
|
|
||||||
(cz << 4) + rng.nextInt(16),
|
|
||||||
i.getZone()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
default void generateParallaxLayer(int x, int z) {
|
|
||||||
generateParallaxLayer(x, z, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
default KList<Runnable> placeStructure(IrisPosition position, IrisJigsawStructure structure, RNG rng) {
|
|
||||||
KList<Runnable> placeAfter = new KList<>();
|
|
||||||
|
|
||||||
if (structure == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (structure.getFeature() != null) {
|
|
||||||
if (structure.getFeature().getBlockRadius() == 32) {
|
|
||||||
structure.getFeature().setBlockRadius((double) structure.getMaxDimension() / 3);
|
|
||||||
}
|
|
||||||
|
|
||||||
getParallaxAccess().getMetaRW(position.getX() >> 4, position.getZ() >> 4).getFeatures()
|
|
||||||
.add(new IrisFeaturePositional(position.getX(), position.getZ(), structure.getFeature()));
|
|
||||||
}
|
|
||||||
|
|
||||||
placeAfter.addAll(new PlannedStructure(structure, position, rng).place(this, this));
|
|
||||||
return placeAfter;
|
|
||||||
}
|
|
||||||
|
|
||||||
default KList<Runnable> generateParallaxJigsaw(RNG rng, int x, int z, IrisBiome biome, IrisRegion region) {
|
|
||||||
KList<Runnable> placeAfter = new KList<>();
|
|
||||||
|
|
||||||
if (getEngine().getDimension().isPlaceObjects()) {
|
|
||||||
boolean placed = false;
|
|
||||||
|
|
||||||
if (getEngine().getDimension().getStronghold() != null) {
|
|
||||||
List<Position2> poss = getEngine().getDimension().getStrongholds(getEngine().getWorld().seed());
|
|
||||||
|
|
||||||
if (poss != null) {
|
|
||||||
for (Position2 pos : poss) {
|
|
||||||
if (x == pos.getX() >> 4 && z == pos.getZ() >> 4) {
|
|
||||||
IrisJigsawStructure structure = getData().getJigsawStructureLoader().load(getEngine().getDimension().getStronghold());
|
|
||||||
placeAfter.addAll(placeStructure(pos.toIris(), structure, rng));
|
|
||||||
placed = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!placed) {
|
|
||||||
for (IrisJigsawStructurePlacement i : biome.getJigsawStructures()) {
|
|
||||||
if (rng.nextInt(i.getRarity()) == 0) {
|
|
||||||
IrisPosition position = new IrisPosition((x << 4) + rng.nextInt(15), 0, (z << 4) + rng.nextInt(15));
|
|
||||||
IrisJigsawStructure structure = getData().getJigsawStructureLoader().load(i.getStructure());
|
|
||||||
placeAfter.addAll(placeStructure(position, structure, rng));
|
|
||||||
placed = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!placed) {
|
|
||||||
for (IrisJigsawStructurePlacement i : region.getJigsawStructures()) {
|
|
||||||
if (rng.nextInt(i.getRarity()) == 0) {
|
|
||||||
IrisPosition position = new IrisPosition((x << 4) + rng.nextInt(15), 0, (z << 4) + rng.nextInt(15));
|
|
||||||
IrisJigsawStructure structure = getData().getJigsawStructureLoader().load(i.getStructure());
|
|
||||||
placeAfter.addAll(placeStructure(position, structure, rng));
|
|
||||||
placed = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!placed) {
|
|
||||||
for (IrisJigsawStructurePlacement i : getEngine().getDimension().getJigsawStructures()) {
|
|
||||||
if (rng.nextInt(i.getRarity()) == 0) {
|
|
||||||
IrisPosition position = new IrisPosition((x << 4) + rng.nextInt(15), 0, (z << 4) + rng.nextInt(15));
|
|
||||||
IrisJigsawStructure structure = getData().getJigsawStructureLoader().load(i.getStructure());
|
|
||||||
placeAfter.addAll(placeStructure(position, structure, rng));
|
|
||||||
placed = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return placeAfter;
|
|
||||||
}
|
|
||||||
|
|
||||||
default void generateParallaxSurface(RNG rng, int x, int z, IrisBiome biome, IrisRegion region, boolean useFeatures) {
|
|
||||||
|
|
||||||
for (IrisObjectPlacement i : biome.getSurfaceObjects()) {
|
|
||||||
if (i.usesFeatures() != useFeatures) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rng.chance(i.getChance() + rng.d(-0.005, 0.005)) && rng.chance(getComplex().getObjectChanceStream().get(x << 4, z << 4))) {
|
|
||||||
try {
|
|
||||||
place(rng, x << 4, z << 4, i);
|
|
||||||
} catch (Throwable e) {
|
|
||||||
Iris.reportError(e);
|
|
||||||
Iris.error("Failed to place objects in the following biome: " + biome.getName());
|
|
||||||
Iris.error("Object(s) " + i.getPlace().toString(", ") + " (" + e.getClass().getSimpleName() + ").");
|
|
||||||
Iris.error("Are these objects missing?");
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (IrisObjectPlacement i : region.getSurfaceObjects()) {
|
|
||||||
if (i.usesFeatures() != useFeatures) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rng.chance(i.getChance() + rng.d(-0.005, 0.005)) && rng.chance(getComplex().getObjectChanceStream().get(x << 4, z << 4))) {
|
|
||||||
try {
|
|
||||||
place(rng, x << 4, z << 4, i);
|
|
||||||
} catch (Throwable e) {
|
|
||||||
Iris.reportError(e);
|
|
||||||
Iris.error("Failed to place objects in the following region: " + region.getName());
|
|
||||||
Iris.error("Object(s) " + i.getPlace().toString(", ") + " (" + e.getClass().getSimpleName() + ").");
|
|
||||||
Iris.error("Are these objects missing?");
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
default void generateParallaxMutations(RNG rng, int x, int z, boolean useFeatures) {
|
|
||||||
if (getEngine().getDimension().getMutations().isEmpty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
searching:
|
|
||||||
for (IrisBiomeMutation k : getEngine().getDimension().getMutations()) {
|
|
||||||
for (int l = 0; l < k.getChecks(); l++) {
|
|
||||||
IrisBiome sa = getComplex().getTrueBiomeStreamNoFeatures().get(((x * 16) + rng.nextInt(16)) + rng.i(-k.getRadius(), k.getRadius()), ((z * 16) + rng.nextInt(16)) + rng.i(-k.getRadius(), k.getRadius()));
|
|
||||||
IrisBiome sb = getComplex().getTrueBiomeStreamNoFeatures().get(((x * 16) + rng.nextInt(16)) + rng.i(-k.getRadius(), k.getRadius()), ((z * 16) + rng.nextInt(16)) + rng.i(-k.getRadius(), k.getRadius()));
|
|
||||||
|
|
||||||
if (sa.getLoadKey().equals(sb.getLoadKey())) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (k.getRealSideA(this).contains(sa.getLoadKey()) && k.getRealSideB(this).contains(sb.getLoadKey())) {
|
|
||||||
for (IrisObjectPlacement m : k.getObjects()) {
|
|
||||||
if (m.usesFeatures() != useFeatures) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
place(rng.nextParallelRNG((34 * ((x * 30) + (z * 30)) * x * z) + x - z + 1569962), x, z, m);
|
|
||||||
}
|
|
||||||
|
|
||||||
continue searching;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
default void place(RNG rng, int x, int z, IrisObjectPlacement objectPlacement) {
|
|
||||||
place(rng, x, -1, z, objectPlacement);
|
|
||||||
}
|
|
||||||
|
|
||||||
default void placePiece(RNG rng, int xx, int forceY, int zz, IrisObject v, IrisObjectPlacement p) {
|
|
||||||
int id = rng.i(0, Integer.MAX_VALUE);
|
|
||||||
int maxf = 10000;
|
|
||||||
AtomicBoolean pl = new AtomicBoolean(false);
|
|
||||||
AtomicInteger max = new AtomicInteger(-1);
|
|
||||||
AtomicInteger min = new AtomicInteger(maxf);
|
|
||||||
int h = v.place(xx, forceY, zz, this, p, rng, (b) -> {
|
|
||||||
int xf = b.getX();
|
|
||||||
int yf = b.getY();
|
|
||||||
int zf = b.getZ();
|
|
||||||
getParallaxAccess().setObject(xf, yf, zf, v.getLoadKey() + "@" + id);
|
|
||||||
ParallaxChunkMeta meta = getParallaxAccess().getMetaRW(xf >> 4, zf >> 4);
|
|
||||||
meta.setObjects(true);
|
|
||||||
meta.setMinObject(Math.min(Math.max(meta.getMinObject(), 0), yf));
|
|
||||||
meta.setMaxObject(Math.max(Math.max(meta.getMaxObject(), 0), yf));
|
|
||||||
|
|
||||||
}, null, getData());
|
|
||||||
|
|
||||||
if (p.usesFeatures()) {
|
|
||||||
if (p.isVacuum()) {
|
|
||||||
ParallaxChunkMeta rw = getParallaxAccess().getMetaRW(xx >> 4, zz >> 4);
|
|
||||||
double a = Math.max(v.getW(), v.getD());
|
|
||||||
IrisFeature f = new IrisFeature();
|
|
||||||
f.setConvergeToHeight(h - (v.getH() >> 1));
|
|
||||||
f.setBlockRadius(a);
|
|
||||||
f.setInterpolationRadius(p.getVacuumInterpolationRadius());
|
|
||||||
f.setInterpolator(p.getVacuumInterpolationMethod());
|
|
||||||
f.setStrength(1D);
|
|
||||||
|
|
||||||
rw.getFeatures().add(new IrisFeaturePositional(xx, zz, f));
|
|
||||||
}
|
|
||||||
|
|
||||||
for (IrisFeaturePotential j : p.getAddFeatures()) {
|
|
||||||
if (j.hasZone(rng, xx >> 4, zz >> 4)) {
|
|
||||||
ParallaxChunkMeta rw = getParallaxAccess().getMetaRW(xx >> 4, zz >> 4);
|
|
||||||
rw.getFeatures().add(new IrisFeaturePositional(xx + 1, zz - 1, j.getZone()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
default void place(RNG rng, int x, int forceY, int z, IrisObjectPlacement objectPlacement) {
|
|
||||||
placing:
|
|
||||||
for (int i = 0; i < objectPlacement.getDensity(); i++) {
|
|
||||||
IrisObject v = objectPlacement.getScale().get(rng, objectPlacement.getObject(getComplex(), rng));
|
|
||||||
if (v == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
int xx = rng.i(x, x + 16);
|
|
||||||
int zz = rng.i(z, z + 16);
|
|
||||||
int id = rng.i(0, Integer.MAX_VALUE);
|
|
||||||
|
|
||||||
int h = v.place(xx, forceY, zz, this, objectPlacement, rng, (b) -> {
|
|
||||||
int xf = b.getX();
|
|
||||||
int yf = b.getY();
|
|
||||||
int zf = b.getZ();
|
|
||||||
getParallaxAccess().setObject(xf, yf, zf, v.getLoadKey() + "@" + id);
|
|
||||||
ParallaxChunkMeta meta = getParallaxAccess().getMetaRW(xf >> 4, zf >> 4);
|
|
||||||
meta.setObjects(true);
|
|
||||||
meta.setMinObject(Math.min(Math.max(meta.getMinObject(), 0), yf));
|
|
||||||
meta.setMaxObject(Math.max(Math.max(meta.getMaxObject(), 0), yf));
|
|
||||||
|
|
||||||
}, null, getData());
|
|
||||||
|
|
||||||
if (objectPlacement.usesFeatures()) {
|
|
||||||
if (objectPlacement.isVacuum()) {
|
|
||||||
ParallaxChunkMeta rw = getParallaxAccess().getMetaRW(xx >> 4, zz >> 4);
|
|
||||||
double a = Math.max(v.getW(), v.getD());
|
|
||||||
IrisFeature f = new IrisFeature();
|
|
||||||
f.setConvergeToHeight(h - (v.getH() >> 1));
|
|
||||||
f.setBlockRadius(a);
|
|
||||||
f.setInterpolationRadius(objectPlacement.getVacuumInterpolationRadius());
|
|
||||||
f.setInterpolator(objectPlacement.getVacuumInterpolationMethod());
|
|
||||||
f.setStrength(1D);
|
|
||||||
rw.getFeatures().add(new IrisFeaturePositional(xx, zz, f));
|
|
||||||
}
|
|
||||||
|
|
||||||
for (IrisFeaturePotential j : objectPlacement.getAddFeatures()) {
|
|
||||||
if (j.hasZone(rng, xx >> 4, zz >> 4)) {
|
|
||||||
ParallaxChunkMeta rw = getParallaxAccess().getMetaRW(xx >> 4, zz >> 4);
|
|
||||||
rw.getFeatures().add(new IrisFeaturePositional(xx + 1, zz - 1, j.getZone()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
default void updateParallaxChunkObjectData(int minY, int maxY, int x, int z, IrisObject v) {
|
|
||||||
ParallaxChunkMeta meta = getParallaxAccess().getMetaRW(x >> 4, z >> 4);
|
|
||||||
meta.setObjects(true);
|
|
||||||
meta.setMaxObject(Math.max(maxY, meta.getMaxObject()));
|
|
||||||
meta.setMinObject(Math.min(minY, Math.max(meta.getMinObject(), 0)));
|
|
||||||
}
|
|
||||||
|
|
||||||
default int computeParallaxSize() {
|
|
||||||
Iris.verbose("Calculating the Parallax Size in Parallel");
|
|
||||||
AtomicInteger xg = new AtomicInteger(0);
|
|
||||||
AtomicInteger zg = new AtomicInteger();
|
|
||||||
xg.set(0);
|
|
||||||
zg.set(0);
|
|
||||||
int jig = 0;
|
|
||||||
KSet<String> objects = new KSet<>();
|
|
||||||
KMap<IrisObjectScale, KList<String>> scalars = new KMap<>();
|
|
||||||
int x = xg.get();
|
|
||||||
int z = zg.get();
|
|
||||||
|
|
||||||
if (getEngine().getDimension().isPlaceObjects()) {
|
|
||||||
KList<IrisRegion> r = getAllRegions();
|
|
||||||
KList<IrisBiome> b = getAllBiomes();
|
|
||||||
|
|
||||||
for (IrisBiome i : b) {
|
|
||||||
for (IrisObjectPlacement j : i.getObjects()) {
|
|
||||||
if (j.getScale().canScaleBeyond()) {
|
|
||||||
scalars.put(j.getScale(), j.getPlace());
|
|
||||||
} else {
|
|
||||||
objects.addAll(j.getPlace());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (IrisJigsawStructurePlacement j : i.getJigsawStructures()) {
|
|
||||||
jig = Math.max(jig, getData().getJigsawStructureLoader().load(j.getStructure()).getMaxDimension());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (IrisRegion i : r) {
|
|
||||||
for (IrisObjectPlacement j : i.getObjects()) {
|
|
||||||
if (j.getScale().canScaleBeyond()) {
|
|
||||||
scalars.put(j.getScale(), j.getPlace());
|
|
||||||
} else {
|
|
||||||
objects.addAll(j.getPlace());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (IrisJigsawStructurePlacement j : i.getJigsawStructures()) {
|
|
||||||
jig = Math.max(jig, getData().getJigsawStructureLoader().load(j.getStructure()).getMaxDimension());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (IrisJigsawStructurePlacement j : getEngine().getDimension().getJigsawStructures()) {
|
|
||||||
jig = Math.max(jig, getData().getJigsawStructureLoader().load(j.getStructure()).getMaxDimension());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (getEngine().getDimension().getStronghold() != null) {
|
|
||||||
try {
|
|
||||||
jig = Math.max(jig, getData().getJigsawStructureLoader().load(getEngine().getDimension().getStronghold()).getMaxDimension());
|
|
||||||
} catch (Throwable e) {
|
|
||||||
Iris.reportError(e);
|
|
||||||
Iris.error("THIS IS THE ONE");
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Iris.verbose("Checking sizes for " + Form.f(objects.size()) + " referenced objects.");
|
|
||||||
BurstExecutor e = getEngine().getTarget().getBurster().burst(objects.size());
|
|
||||||
KMap<String, BlockVector> sizeCache = new KMap<>();
|
|
||||||
for (String i : objects) {
|
|
||||||
e.queue(() -> {
|
|
||||||
try {
|
|
||||||
BlockVector bv = sizeCache.compute(i, (k, v) -> {
|
|
||||||
if (v != null) {
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
return IrisObject.sampleSize(getData().getObjectLoader().findFile(i));
|
|
||||||
} catch (IOException ex) {
|
|
||||||
Iris.reportError(ex);
|
|
||||||
ex.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
});
|
|
||||||
|
|
||||||
if (bv == null) {
|
|
||||||
throw new RuntimeException();
|
|
||||||
}
|
|
||||||
|
|
||||||
warn(i, bv);
|
|
||||||
|
|
||||||
synchronized (xg) {
|
|
||||||
xg.getAndSet(Math.max(bv.getBlockX(), xg.get()));
|
|
||||||
}
|
|
||||||
|
|
||||||
synchronized (zg) {
|
|
||||||
zg.getAndSet(Math.max(bv.getBlockZ(), zg.get()));
|
|
||||||
}
|
|
||||||
} catch (Throwable ed) {
|
|
||||||
Iris.reportError(ed);
|
|
||||||
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Map.Entry<IrisObjectScale, KList<String>> entry : scalars.entrySet()) {
|
|
||||||
double ms = entry.getKey().getMaximumScale();
|
|
||||||
for (String j : entry.getValue()) {
|
|
||||||
e.queue(() -> {
|
|
||||||
try {
|
|
||||||
BlockVector bv = sizeCache.compute(j, (k, v) -> {
|
|
||||||
if (v != null) {
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
return IrisObject.sampleSize(getData().getObjectLoader().findFile(j));
|
|
||||||
} catch (IOException ioException) {
|
|
||||||
Iris.reportError(ioException);
|
|
||||||
ioException.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
});
|
|
||||||
|
|
||||||
if (bv == null) {
|
|
||||||
throw new RuntimeException();
|
|
||||||
}
|
|
||||||
|
|
||||||
warnScaled(j, bv, ms);
|
|
||||||
|
|
||||||
synchronized (xg) {
|
|
||||||
xg.getAndSet((int) Math.max(Math.ceil(bv.getBlockX() * ms), xg.get()));
|
|
||||||
}
|
|
||||||
|
|
||||||
synchronized (zg) {
|
|
||||||
zg.getAndSet((int) Math.max(Math.ceil(bv.getBlockZ() * ms), zg.get()));
|
|
||||||
}
|
|
||||||
} catch (Throwable ee) {
|
|
||||||
Iris.reportError(ee);
|
|
||||||
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
e.complete();
|
|
||||||
|
|
||||||
x = xg.get();
|
|
||||||
z = zg.get();
|
|
||||||
|
|
||||||
for (IrisDepositGenerator i : getEngine().getDimension().getDeposits()) {
|
|
||||||
int max = i.getMaxDimension();
|
|
||||||
x = Math.max(max, x);
|
|
||||||
z = Math.max(max, z);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (IrisRegion v : r) {
|
|
||||||
for (IrisDepositGenerator i : v.getDeposits()) {
|
|
||||||
int max = i.getMaxDimension();
|
|
||||||
x = Math.max(max, x);
|
|
||||||
z = Math.max(max, z);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (IrisBiome v : b) {
|
|
||||||
for (IrisDepositGenerator i : v.getDeposits()) {
|
|
||||||
int max = i.getMaxDimension();
|
|
||||||
x = Math.max(max, x);
|
|
||||||
z = Math.max(max, z);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
x = Math.max(z, x);
|
|
||||||
int u = x;
|
|
||||||
int v = computeFeatureRange();
|
|
||||||
x = Math.max(jig, x);
|
|
||||||
x = Math.max(x, v);
|
|
||||||
x = (Math.max(x, 16) + 16) >> 4;
|
|
||||||
x = x % 2 == 0 ? x + 1 : x;
|
|
||||||
Iris.info("Parallax Size: " + x + " Chunks");
|
|
||||||
Iris.info(" Object Parallax Size: " + u + " (" + ((Math.max(u, 16) + 16) >> 4) + ")");
|
|
||||||
Iris.info(" Jigsaw Parallax Size: " + jig + " (" + ((Math.max(jig, 16) + 16) >> 4) + ")");
|
|
||||||
Iris.info(" Feature Parallax Size: " + v + " (" + ((Math.max(v, 16) + 16) >> 4) + ")");
|
|
||||||
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
|
|
||||||
default int computeFeatureRange() {
|
|
||||||
int m = 0;
|
|
||||||
|
|
||||||
for (IrisFeaturePotential i : getAllFeatures()) {
|
|
||||||
m = Math.max(m, i.getZone().getRealSize());
|
|
||||||
}
|
|
||||||
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
|
|
||||||
default void warn(String ob, BlockVector bv) {
|
|
||||||
if (Math.max(bv.getBlockX(), bv.getBlockZ()) > 128) {
|
|
||||||
Iris.warn("Object " + ob + " has a large size (" + bv + ") and may increase memory usage!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
default void warnScaled(String ob, BlockVector bv, double ms) {
|
|
||||||
if (Math.max(bv.getBlockX(), bv.getBlockZ()) > 128) {
|
|
||||||
Iris.warn("Object " + ob + " has a large size (" + bv + ") and may increase memory usage! (Object scaled up to " + Form.pc(ms, 2) + ")");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
default int getHighest(int x, int z) {
|
|
||||||
return getHighest(x, z, getData());
|
|
||||||
}
|
|
||||||
|
|
||||||
default int getHighest(int x, int z, boolean ignoreFluid) {
|
|
||||||
return getHighest(x, z, getData(), ignoreFluid);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
default int getHighest(int x, int z, IrisData data) {
|
|
||||||
return getHighest(x, z, data, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
default int getHighest(int x, int z, IrisData data, boolean ignoreFluid) {
|
|
||||||
return ignoreFluid ? trueHeight(x, z) : Math.max(trueHeight(x, z), getEngine().getDimension().getFluidHeight());
|
|
||||||
}
|
|
||||||
|
|
||||||
default int trueHeight(int x, int z) {
|
|
||||||
return getComplex().getTrueHeightStream().get(x, z);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
default void set(int x, int y, int z, BlockData d) {
|
|
||||||
getParallaxAccess().setBlock(x, y, z, d);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
default void setTile(int x, int y, int z, TileData<? extends TileState> d) {
|
|
||||||
getParallaxAccess().setTile(x, y, z, d);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
default BlockData get(int x, int y, int z) {
|
|
||||||
BlockData block = getParallaxAccess().getBlock(x, y, z);
|
|
||||||
|
|
||||||
if (block == null) {
|
|
||||||
return AIR;
|
|
||||||
}
|
|
||||||
|
|
||||||
return block;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
default boolean isPreventingDecay() {
|
|
||||||
return getEngine().getDimension().isPreventLeafDecay();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
default boolean isSolid(int x, int y, int z) {
|
|
||||||
return B.isSolid(get(x, y, z));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
default boolean isUnderwater(int x, int z) {
|
|
||||||
return getHighest(x, z, true) <= getFluidHeight();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
default int getFluidHeight() {
|
|
||||||
return getEngine().getDimension().getFluidHeight();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
default boolean isDebugSmartBore() {
|
|
||||||
return getEngine().getDimension().isDebugSmartBore();
|
|
||||||
}
|
|
||||||
|
|
||||||
default void close() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@ChunkCoordinates
|
|
||||||
default KList<IrisFeaturePositional> getFeaturesInChunk(Chunk c) {
|
|
||||||
return getFeaturesInChunk(c.getX(), c.getZ());
|
|
||||||
}
|
|
||||||
}
|
|
@ -22,21 +22,15 @@ import com.volmit.iris.core.IrisSettings;
|
|||||||
import com.volmit.iris.core.project.loader.IrisData;
|
import com.volmit.iris.core.project.loader.IrisData;
|
||||||
import com.volmit.iris.engine.object.common.IrisWorld;
|
import com.volmit.iris.engine.object.common.IrisWorld;
|
||||||
import com.volmit.iris.engine.object.dimensional.IrisDimension;
|
import com.volmit.iris.engine.object.dimensional.IrisDimension;
|
||||||
import com.volmit.iris.engine.parallax.ParallaxWorld;
|
|
||||||
import com.volmit.iris.util.parallel.MultiBurst;
|
import com.volmit.iris.util.parallel.MultiBurst;
|
||||||
import lombok.Builder;
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
public class EngineTarget {
|
public class EngineTarget {
|
||||||
private final MultiBurst parallaxBurster;
|
|
||||||
private final MultiBurst burster;
|
private final MultiBurst burster;
|
||||||
private final IrisDimension dimension;
|
private final IrisDimension dimension;
|
||||||
private IrisWorld world;
|
private IrisWorld world;
|
||||||
private final IrisData data;
|
private final IrisData data;
|
||||||
private final ParallaxWorld parallaxWorld;
|
|
||||||
|
|
||||||
public EngineTarget(IrisWorld world, IrisDimension dimension, IrisData data) {
|
public EngineTarget(IrisWorld world, IrisDimension dimension, IrisData data) {
|
||||||
this.world = world;
|
this.world = world;
|
||||||
@ -45,9 +39,6 @@ public class EngineTarget {
|
|||||||
this.burster = new MultiBurst("Iris Engine " + dimension.getName(),
|
this.burster = new MultiBurst("Iris Engine " + dimension.getName(),
|
||||||
IrisSettings.get().getConcurrency().getEngineThreadPriority(),
|
IrisSettings.get().getConcurrency().getEngineThreadPriority(),
|
||||||
IrisSettings.getThreadCount(IrisSettings.get().getConcurrency().getEngineThreadCount()));
|
IrisSettings.getThreadCount(IrisSettings.get().getConcurrency().getEngineThreadCount()));
|
||||||
this.parallaxBurster = new MultiBurst("Iris Parallax Engine " + dimension.getName(), 3, 4);
|
|
||||||
this.parallaxWorld = new ParallaxWorld(parallaxBurster, 256, new File(world.worldFolder(),
|
|
||||||
"iris/" + dimension.getLoadKey() + "/parallax"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getHeight()
|
public int getHeight()
|
||||||
@ -56,7 +47,6 @@ public class EngineTarget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void close() {
|
public void close() {
|
||||||
parallaxBurster.shutdownLater();
|
|
||||||
burster.shutdownLater();
|
burster.shutdownLater();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,80 +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.framework;
|
|
||||||
|
|
||||||
import com.volmit.iris.core.gui.components.Renderer;
|
|
||||||
import com.volmit.iris.core.project.loader.IrisData;
|
|
||||||
import com.volmit.iris.engine.object.biome.IrisBiome;
|
|
||||||
import com.volmit.iris.engine.object.objects.IrisObjectPlacement;
|
|
||||||
import com.volmit.iris.engine.object.regional.IrisRegion;
|
|
||||||
import com.volmit.iris.engine.parallax.ParallaxAccess;
|
|
||||||
import com.volmit.iris.util.data.DataProvider;
|
|
||||||
|
|
||||||
public interface GeneratorAccess extends DataProvider, Renderer {
|
|
||||||
IrisRegion getRegion(int x, int z);
|
|
||||||
|
|
||||||
ParallaxAccess getParallaxAccess();
|
|
||||||
|
|
||||||
IrisData getData();
|
|
||||||
|
|
||||||
IrisBiome getCaveBiome(int x, int z);
|
|
||||||
|
|
||||||
IrisBiome getSurfaceBiome(int x, int z);
|
|
||||||
|
|
||||||
int getHeight(int x, int z);
|
|
||||||
|
|
||||||
default IrisBiome getBiome(int x, int y, int z) {
|
|
||||||
if (y <= getHeight(x, z) - 2) {
|
|
||||||
return getCaveBiome(x, z);
|
|
||||||
}
|
|
||||||
|
|
||||||
return getSurfaceBiome(x, z);
|
|
||||||
}
|
|
||||||
|
|
||||||
default PlacedObject getObjectPlacement(int x, int y, int z) {
|
|
||||||
String objectAt = getParallaxAccess().getObject(x, y, z);
|
|
||||||
|
|
||||||
if (objectAt == null || objectAt.isEmpty()) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
String[] v = objectAt.split("\\Q@\\E");
|
|
||||||
String object = v[0];
|
|
||||||
int id = Integer.parseInt(v[1]);
|
|
||||||
IrisRegion region = getRegion(x, z);
|
|
||||||
|
|
||||||
for (IrisObjectPlacement i : region.getObjects()) {
|
|
||||||
if (i.getPlace().contains(object)) {
|
|
||||||
return new PlacedObject(i, getData().getObjectLoader().load(object), id, x, z);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
IrisBiome biome = getBiome(x, y, z);
|
|
||||||
|
|
||||||
for (IrisObjectPlacement i : biome.getObjects()) {
|
|
||||||
if (i.getPlace().contains(object)) {
|
|
||||||
return new PlacedObject(i, getData().getObjectLoader().load(object), id, x, z);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return new PlacedObject(null, getData().getObjectLoader().load(object), id, x, z);
|
|
||||||
}
|
|
||||||
|
|
||||||
int getCacheID();
|
|
||||||
}
|
|
@ -23,7 +23,6 @@ import com.volmit.iris.Iris;
|
|||||||
import com.volmit.iris.core.project.loader.IrisData;
|
import com.volmit.iris.core.project.loader.IrisData;
|
||||||
import com.volmit.iris.core.tools.IrisToolbelt;
|
import com.volmit.iris.core.tools.IrisToolbelt;
|
||||||
import com.volmit.iris.engine.framework.Engine;
|
import com.volmit.iris.engine.framework.Engine;
|
||||||
import com.volmit.iris.engine.framework.EngineParallaxManager;
|
|
||||||
import com.volmit.iris.engine.object.basic.IrisPosition;
|
import com.volmit.iris.engine.object.basic.IrisPosition;
|
||||||
import com.volmit.iris.engine.object.common.IObjectPlacer;
|
import com.volmit.iris.engine.object.common.IObjectPlacer;
|
||||||
import com.volmit.iris.engine.object.entity.IrisEntity;
|
import com.volmit.iris.engine.object.entity.IrisEntity;
|
||||||
@ -33,9 +32,9 @@ import com.volmit.iris.engine.object.jigsaw.IrisJigsawPiece;
|
|||||||
import com.volmit.iris.engine.object.jigsaw.IrisJigsawPieceConnector;
|
import com.volmit.iris.engine.object.jigsaw.IrisJigsawPieceConnector;
|
||||||
import com.volmit.iris.engine.object.jigsaw.IrisJigsawStructure;
|
import com.volmit.iris.engine.object.jigsaw.IrisJigsawStructure;
|
||||||
import com.volmit.iris.engine.object.objects.*;
|
import com.volmit.iris.engine.object.objects.*;
|
||||||
import com.volmit.iris.engine.parallax.ParallaxChunkMeta;
|
|
||||||
import com.volmit.iris.util.collection.KList;
|
import com.volmit.iris.util.collection.KList;
|
||||||
import com.volmit.iris.util.interpolation.InterpolationMethod;
|
import com.volmit.iris.util.interpolation.InterpolationMethod;
|
||||||
|
import com.volmit.iris.util.mantle.Mantle;
|
||||||
import com.volmit.iris.util.math.RNG;
|
import com.volmit.iris.util.math.RNG;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import org.bukkit.Axis;
|
import org.bukkit.Axis;
|
||||||
@ -43,6 +42,8 @@ import org.bukkit.Location;
|
|||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.entity.Entity;
|
import org.bukkit.entity.Entity;
|
||||||
|
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
public class PlannedStructure {
|
public class PlannedStructure {
|
||||||
private KList<PlannedPiece> pieces;
|
private KList<PlannedPiece> pieces;
|
||||||
@ -80,24 +81,21 @@ public class PlannedStructure {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public KList<Runnable> place(IObjectPlacer placer, EngineParallaxManager e) {
|
public void place(IObjectPlacer placer, Mantle e, Consumer<Runnable> post) {
|
||||||
KList<Runnable> after = new KList<>();
|
|
||||||
IrisObjectPlacement options = new IrisObjectPlacement();
|
IrisObjectPlacement options = new IrisObjectPlacement();
|
||||||
options.getRotation().setEnabled(false);
|
options.getRotation().setEnabled(false);
|
||||||
int startHeight = pieces.get(0).getPosition().getY();
|
int startHeight = pieces.get(0).getPosition().getY();
|
||||||
|
|
||||||
for (PlannedPiece i : pieces) {
|
for (PlannedPiece i : pieces) {
|
||||||
if (i.getPiece().getPlaceMode().equals(ObjectPlaceMode.VACUUM)) {
|
if (i.getPiece().getPlacementOptions().usesFeatures()) {
|
||||||
place(i, startHeight, options, placer, e);
|
place(i, startHeight, options, placer, e);
|
||||||
} else {
|
} else {
|
||||||
after.add(() -> place(i, startHeight, options, placer, e));
|
post.accept(() -> place(i, startHeight, options, placer, e));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return after;
|
public void place(PlannedPiece i, int startHeight, IrisObjectPlacement o, IObjectPlacer placer, Mantle e) {
|
||||||
}
|
|
||||||
|
|
||||||
public void place(PlannedPiece i, int startHeight, IrisObjectPlacement o, IObjectPlacer placer, EngineParallaxManager e) {
|
|
||||||
IrisObjectPlacement options = o;
|
IrisObjectPlacement options = o;
|
||||||
|
|
||||||
if (i.getPiece().getPlacementOptions() != null) {
|
if (i.getPiece().getPlacementOptions() != null) {
|
||||||
@ -121,17 +119,8 @@ public class PlannedStructure {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int id = rng.i(0, Integer.MAX_VALUE);
|
int id = rng.i(0, Integer.MAX_VALUE);
|
||||||
|
int h = vo.place(xx, height, zz, placer, options, rng, (b)
|
||||||
int h = vo.place(xx, height, zz, placer, options, rng, (b) -> {
|
-> e.set(b.getX(), b.getY(), b.getZ(), v.getLoadKey() + "@" + id), null, getData());
|
||||||
int xf = b.getX();
|
|
||||||
int yf = b.getY();
|
|
||||||
int zf = b.getZ();
|
|
||||||
e.getParallaxAccess().setObject(xf, yf, zf, v.getLoadKey() + "@" + id);
|
|
||||||
ParallaxChunkMeta meta = e.getParallaxAccess().getMetaRW(xf >> 4, zf >> 4);
|
|
||||||
meta.setObjects(true);
|
|
||||||
meta.setMinObject(Math.min(Math.max(meta.getMinObject(), 0), yf));
|
|
||||||
meta.setMaxObject(Math.max(Math.max(meta.getMaxObject(), 0), yf));
|
|
||||||
}, null, getData());
|
|
||||||
|
|
||||||
|
|
||||||
for (IrisJigsawPieceConnector j : i.getAvailableConnectors()) {
|
for (IrisJigsawPieceConnector j : i.getAvailableConnectors()) {
|
||||||
@ -149,13 +138,10 @@ public class PlannedStructure {
|
|||||||
} else {
|
} else {
|
||||||
p.setY(height);
|
p.setY(height);
|
||||||
}
|
}
|
||||||
for (int k = 0; k < j.getEntityCount(); k++) {
|
|
||||||
e.getParallaxAccess().setEntity(p.getX(), p.getY(), p.getZ(), j.getSpawnEntity());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.isVacuum()) {
|
if (options.usesFeatures()) {
|
||||||
double a = Math.max(v.getW(), v.getD());
|
double a = Math.max(v.getW(), v.getD());
|
||||||
IrisFeature f = new IrisFeature();
|
IrisFeature f = new IrisFeature();
|
||||||
f.setConvergeToHeight(h - (v.getH() >> 1) - 1);
|
f.setConvergeToHeight(h - (v.getH() >> 1) - 1);
|
||||||
@ -163,9 +149,7 @@ public class PlannedStructure {
|
|||||||
f.setInterpolationRadius(a / 4);
|
f.setInterpolationRadius(a / 4);
|
||||||
f.setInterpolator(InterpolationMethod.BILINEAR_STARCAST_9);
|
f.setInterpolator(InterpolationMethod.BILINEAR_STARCAST_9);
|
||||||
f.setStrength(1D);
|
f.setStrength(1D);
|
||||||
e.getParallaxAccess().getMetaRW(xx >> 4, zz >> 4)
|
e.set(xx, 0, zz, new IrisFeaturePositional(xx, zz, f));
|
||||||
.getFeatures()
|
|
||||||
.add(new IrisFeaturePositional(xx, zz, f));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,13 +25,31 @@ import com.volmit.iris.engine.framework.Engine;
|
|||||||
import com.volmit.iris.engine.framework.EngineTarget;
|
import com.volmit.iris.engine.framework.EngineTarget;
|
||||||
import com.volmit.iris.engine.object.common.IObjectPlacer;
|
import com.volmit.iris.engine.object.common.IObjectPlacer;
|
||||||
import com.volmit.iris.engine.object.dimensional.IrisDimension;
|
import com.volmit.iris.engine.object.dimensional.IrisDimension;
|
||||||
|
import com.volmit.iris.engine.object.feature.IrisFeaturePositional;
|
||||||
import com.volmit.iris.engine.object.tile.TileData;
|
import com.volmit.iris.engine.object.tile.TileData;
|
||||||
import com.volmit.iris.engine.parallax.ParallaxAccess;
|
import com.volmit.iris.util.collection.KList;
|
||||||
import com.volmit.iris.util.data.B;
|
import com.volmit.iris.util.data.B;
|
||||||
|
import com.volmit.iris.util.documentation.BlockCoordinates;
|
||||||
|
import com.volmit.iris.util.documentation.ChunkCoordinates;
|
||||||
|
import com.volmit.iris.util.format.Form;
|
||||||
|
import com.volmit.iris.util.hunk.Hunk;
|
||||||
import com.volmit.iris.util.mantle.Mantle;
|
import com.volmit.iris.util.mantle.Mantle;
|
||||||
|
import com.volmit.iris.util.mantle.MantleFlag;
|
||||||
|
import com.volmit.iris.util.parallel.BurstExecutor;
|
||||||
|
import com.volmit.iris.util.parallel.MultiBurst;
|
||||||
|
import com.volmit.iris.util.scheduling.PrecisionStopwatch;
|
||||||
|
import org.bukkit.Chunk;
|
||||||
import org.bukkit.block.TileState;
|
import org.bukkit.block.TileState;
|
||||||
import org.bukkit.block.data.BlockData;
|
import org.bukkit.block.data.BlockData;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
// TODO: MOVE PLACER OUT OF MATTER INTO ITS OWN THING
|
||||||
public interface EngineMantle extends IObjectPlacer {
|
public interface EngineMantle extends IObjectPlacer {
|
||||||
BlockData AIR = B.get("AIR");
|
BlockData AIR = B.get("AIR");
|
||||||
|
|
||||||
@ -39,6 +57,12 @@ public interface EngineMantle extends IObjectPlacer {
|
|||||||
|
|
||||||
Engine getEngine();
|
Engine getEngine();
|
||||||
|
|
||||||
|
CompletableFuture<Integer> getRadius();
|
||||||
|
|
||||||
|
KList<MantleComponent> getComponents();
|
||||||
|
|
||||||
|
void registerComponent(MantleComponent c);
|
||||||
|
|
||||||
default int getHighest(int x, int z) {
|
default int getHighest(int x, int z) {
|
||||||
return getHighest(x, z, getData());
|
return getHighest(x, z, getData());
|
||||||
}
|
}
|
||||||
@ -116,10 +140,6 @@ public interface EngineMantle extends IObjectPlacer {
|
|||||||
return getEngine().getData();
|
return getEngine().getData();
|
||||||
}
|
}
|
||||||
|
|
||||||
default ParallaxAccess getParallax() {
|
|
||||||
return getEngine().getParallax();
|
|
||||||
}
|
|
||||||
|
|
||||||
default EngineTarget getTarget() {
|
default EngineTarget getTarget() {
|
||||||
return getEngine().getTarget();
|
return getEngine().getTarget();
|
||||||
}
|
}
|
||||||
@ -135,4 +155,139 @@ public interface EngineMantle extends IObjectPlacer {
|
|||||||
default void close() {
|
default void close() {
|
||||||
getMantle().close();
|
getMantle().close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
default void saveAllNow()
|
||||||
|
{
|
||||||
|
getMantle().saveAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
default void save()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
default void trim()
|
||||||
|
{
|
||||||
|
getMantle().trim(60000);
|
||||||
|
}
|
||||||
|
|
||||||
|
default MultiBurst burst()
|
||||||
|
{
|
||||||
|
return getEngine().burst();
|
||||||
|
}
|
||||||
|
|
||||||
|
default int getRealRadius()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
return (int) Math.ceil(getRadius().get() / 2D);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (ExecutionException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ChunkCoordinates
|
||||||
|
default void generateMatter(int x, int z)
|
||||||
|
{
|
||||||
|
if (!getEngine().getDimension().isUseMantle()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
PrecisionStopwatch p = PrecisionStopwatch.start();
|
||||||
|
List<Runnable> post = Collections.synchronizedList(new KList<>());
|
||||||
|
Consumer<Runnable> c = post::add;
|
||||||
|
int s = getRealRadius();
|
||||||
|
BurstExecutor burst = burst().burst();
|
||||||
|
|
||||||
|
for (int i = -s; i <= s; i++) {
|
||||||
|
int xx = i + x;
|
||||||
|
for (int j = -s; j <= s; j++) {
|
||||||
|
int zz = j + z;
|
||||||
|
burst.queue(() -> {
|
||||||
|
getComponents().forEach((f) -> generateMantleComponent(xx, zz, f, c));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
burst.complete();
|
||||||
|
burst().burst(post);
|
||||||
|
}
|
||||||
|
|
||||||
|
default void generateMantleComponent(int x, int z, MantleComponent c, Consumer<Runnable> post)
|
||||||
|
{
|
||||||
|
getMantle().raiseFlag(x, z, c.getFlag(), () -> c.generateLayer(x, z, post));
|
||||||
|
}
|
||||||
|
|
||||||
|
@ChunkCoordinates
|
||||||
|
default <T> void insertMatter(int x, int z, Class<T> t, Hunk<T> blocks)
|
||||||
|
{
|
||||||
|
if (!getEngine().getDimension().isUseMantle()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
getMantle().iterateChunk(x, z, t, blocks::set);
|
||||||
|
}
|
||||||
|
|
||||||
|
@BlockCoordinates
|
||||||
|
default void updateBlock(int x, int y, int z)
|
||||||
|
{
|
||||||
|
getMantle().flag(x>>4, z>>4, MantleFlag.UPDATE, true);
|
||||||
|
getMantle().set(x,y,z,true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ChunkCoordinates
|
||||||
|
default KList<IrisFeaturePositional> getFeaturesInChunk(Chunk c)
|
||||||
|
{
|
||||||
|
return getFeaturesInChunk(c.getX(), c.getZ());
|
||||||
|
}
|
||||||
|
|
||||||
|
@ChunkCoordinates
|
||||||
|
default KList<IrisFeaturePositional> getFeaturesInChunk(int x, int z)
|
||||||
|
{
|
||||||
|
KList<IrisFeaturePositional> pos = new KList<>();
|
||||||
|
getMantle().iterateChunk(x, z, IrisFeaturePositional.class, (a,b,c,f) -> pos.add(f), MantleFlag.FEATURE);
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
@BlockCoordinates
|
||||||
|
default KList<IrisFeaturePositional> forEachFeature(double x, double z) {
|
||||||
|
KList<IrisFeaturePositional> pos = new KList<>();
|
||||||
|
|
||||||
|
if (!getEngine().getDimension().hasFeatures(getEngine())) {
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (IrisFeaturePositional i : getEngine().getDimension().getSpecificFeatures()) {
|
||||||
|
if (i.shouldFilter(x, z, getEngine().getComplex().getRng(), getData())) {
|
||||||
|
pos.add(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int s = getRealRadius();
|
||||||
|
int i, j;
|
||||||
|
int cx = (int) x >> 4;
|
||||||
|
int cz = (int) z >> 4;
|
||||||
|
|
||||||
|
for (i = -s; i <= s; i++) {
|
||||||
|
for (j = -s; j <= s; j++) {
|
||||||
|
try {
|
||||||
|
for (IrisFeaturePositional k : getFeaturesInChunk(i + cx, j + cx)) {
|
||||||
|
if (k.shouldFilter(x, z, getEngine().getComplex().getRng(), getData())) {
|
||||||
|
pos.add(k);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Throwable e) {
|
||||||
|
Iris.error("FILTER ERROR" + " AT " + (cx + i) + " " + (j + cz));
|
||||||
|
e.printStackTrace();
|
||||||
|
Iris.reportError(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,28 @@
|
|||||||
|
/*
|
||||||
|
* 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.mantle;
|
||||||
|
|
||||||
|
import com.volmit.iris.util.mantle.MantleFlag;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public abstract class IrisMantleComponent implements MantleComponent{
|
||||||
|
private final EngineMantle engineMantle;
|
||||||
|
private final MantleFlag flag;
|
||||||
|
}
|
@ -0,0 +1,75 @@
|
|||||||
|
/*
|
||||||
|
* 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.mantle;
|
||||||
|
|
||||||
|
import com.volmit.iris.core.project.loader.IrisData;
|
||||||
|
import com.volmit.iris.engine.IrisComplex;
|
||||||
|
import com.volmit.iris.engine.object.dimensional.IrisDimension;
|
||||||
|
import com.volmit.iris.util.documentation.ChunkCoordinates;
|
||||||
|
import com.volmit.iris.util.mantle.Mantle;
|
||||||
|
import com.volmit.iris.util.mantle.MantleFlag;
|
||||||
|
import com.volmit.iris.util.parallel.BurstExecutor;
|
||||||
|
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
public interface MantleComponent
|
||||||
|
{
|
||||||
|
default int getRadius()
|
||||||
|
{
|
||||||
|
return getEngineMantle().getRealRadius();
|
||||||
|
}
|
||||||
|
|
||||||
|
default IrisData getData()
|
||||||
|
{
|
||||||
|
return getEngineMantle().getData();
|
||||||
|
}
|
||||||
|
|
||||||
|
default IrisDimension getDimension()
|
||||||
|
{
|
||||||
|
return getEngineMantle().getEngine().getDimension();
|
||||||
|
}
|
||||||
|
|
||||||
|
default IrisComplex getComplex()
|
||||||
|
{
|
||||||
|
return getEngineMantle().getComplex();
|
||||||
|
}
|
||||||
|
|
||||||
|
default long seed()
|
||||||
|
{
|
||||||
|
return getEngineMantle().getEngine().getTarget().getWorld().seed();
|
||||||
|
}
|
||||||
|
|
||||||
|
default BurstExecutor burst()
|
||||||
|
{
|
||||||
|
return getEngineMantle().getEngine().burst().burst();
|
||||||
|
}
|
||||||
|
|
||||||
|
EngineMantle getEngineMantle();
|
||||||
|
|
||||||
|
default Mantle getMantle()
|
||||||
|
{
|
||||||
|
return getEngineMantle().getMantle();
|
||||||
|
}
|
||||||
|
|
||||||
|
MantleFlag getFlag();
|
||||||
|
|
||||||
|
@ChunkCoordinates
|
||||||
|
void generateLayer(int x, int z, Consumer<Runnable> post);
|
||||||
|
}
|
@ -0,0 +1,75 @@
|
|||||||
|
/*
|
||||||
|
* 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.mantle.components;
|
||||||
|
|
||||||
|
import com.volmit.iris.engine.data.cache.Cache;
|
||||||
|
import com.volmit.iris.engine.mantle.EngineMantle;
|
||||||
|
import com.volmit.iris.engine.mantle.IrisMantleComponent;
|
||||||
|
import com.volmit.iris.engine.object.biome.IrisBiome;
|
||||||
|
import com.volmit.iris.engine.object.feature.IrisFeaturePositional;
|
||||||
|
import com.volmit.iris.engine.object.feature.IrisFeaturePotential;
|
||||||
|
import com.volmit.iris.engine.object.regional.IrisRegion;
|
||||||
|
import com.volmit.iris.util.collection.KList;
|
||||||
|
import com.volmit.iris.util.documentation.ChunkCoordinates;
|
||||||
|
import com.volmit.iris.util.mantle.MantleFlag;
|
||||||
|
import com.volmit.iris.util.math.RNG;
|
||||||
|
import com.volmit.iris.util.parallel.BurstExecutor;
|
||||||
|
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
public class MantleFeatureComponent extends IrisMantleComponent {
|
||||||
|
public MantleFeatureComponent(EngineMantle engineMantle) {
|
||||||
|
super(engineMantle, MantleFlag.FEATURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void generateLayer(int x, int z, Consumer<Runnable> post) {
|
||||||
|
RNG rng = new RNG(Cache.key(x, z) + seed());
|
||||||
|
int xxx = 8 + (x << 4);
|
||||||
|
int zzz = 8 + (z << 4);
|
||||||
|
IrisRegion region = getComplex().getRegionStream().get(xxx, zzz);
|
||||||
|
IrisBiome biome = getComplex().getTrueBiomeStreamNoFeatures().get(xxx, zzz);
|
||||||
|
generateFeatures(rng, x, z, region, biome);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ChunkCoordinates
|
||||||
|
private void generateFeatures(RNG rng, int cx, int cz, IrisRegion region, IrisBiome biome) {
|
||||||
|
for (IrisFeaturePotential i : getFeatures()) {
|
||||||
|
placeZone(rng, cx, cz, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (IrisFeaturePotential i : region.getFeatures()) {
|
||||||
|
placeZone(rng, cx, cz, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (IrisFeaturePotential i : biome.getFeatures()) {
|
||||||
|
placeZone(rng, cx, cz, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void placeZone(RNG rng, int cx, int cz, IrisFeaturePotential i) {
|
||||||
|
int x = (cx << 4) + rng.nextInt(16);
|
||||||
|
int z = (cz << 4) + rng.nextInt(16);
|
||||||
|
getMantle().set(x, 0, z, new IrisFeaturePositional(x, z, i.getZone()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private KList<IrisFeaturePotential> getFeatures() {
|
||||||
|
return getEngineMantle().getEngine().getDimension().getFeatures();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,121 @@
|
|||||||
|
/*
|
||||||
|
* 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.mantle.components;
|
||||||
|
|
||||||
|
import com.volmit.iris.engine.data.cache.Cache;
|
||||||
|
import com.volmit.iris.engine.jigsaw.PlannedStructure;
|
||||||
|
import com.volmit.iris.engine.mantle.EngineMantle;
|
||||||
|
import com.volmit.iris.engine.mantle.IrisMantleComponent;
|
||||||
|
import com.volmit.iris.engine.object.basic.IrisPosition;
|
||||||
|
import com.volmit.iris.engine.object.biome.IrisBiome;
|
||||||
|
import com.volmit.iris.engine.object.feature.IrisFeaturePositional;
|
||||||
|
import com.volmit.iris.engine.object.jigsaw.IrisJigsawStructure;
|
||||||
|
import com.volmit.iris.engine.object.jigsaw.IrisJigsawStructurePlacement;
|
||||||
|
import com.volmit.iris.engine.object.regional.IrisRegion;
|
||||||
|
import com.volmit.iris.util.documentation.BlockCoordinates;
|
||||||
|
import com.volmit.iris.util.documentation.ChunkCoordinates;
|
||||||
|
import com.volmit.iris.util.mantle.MantleFlag;
|
||||||
|
import com.volmit.iris.util.math.Position2;
|
||||||
|
import com.volmit.iris.util.math.RNG;
|
||||||
|
import com.volmit.iris.util.parallel.BurstExecutor;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
public class MantleJigsawComponent extends IrisMantleComponent
|
||||||
|
{
|
||||||
|
public MantleJigsawComponent(EngineMantle engineMantle) {
|
||||||
|
super(engineMantle, MantleFlag.JIGSAW);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void generateLayer(int x, int z, Consumer<Runnable> post) {
|
||||||
|
RNG rng = new RNG(Cache.key(x, z) + seed());
|
||||||
|
int xxx = 8 + (x << 4);
|
||||||
|
int zzz = 8 + (z << 4);
|
||||||
|
IrisRegion region = getComplex().getRegionStream().get(xxx, zzz);
|
||||||
|
IrisBiome biome = getComplex().getTrueBiomeStreamNoFeatures().get(xxx, zzz);
|
||||||
|
generateJigsaw(rng, x, z, biome, region, post);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ChunkCoordinates
|
||||||
|
private void generateJigsaw(RNG rng, int x, int z, IrisBiome biome, IrisRegion region, Consumer<Runnable> post) {
|
||||||
|
boolean placed = false;
|
||||||
|
|
||||||
|
if (getDimension().getStronghold() != null) {
|
||||||
|
List<Position2> poss = getDimension().getStrongholds(seed());
|
||||||
|
|
||||||
|
if (poss != null) {
|
||||||
|
for (Position2 pos : poss) {
|
||||||
|
if (x == pos.getX() >> 4 && z == pos.getZ() >> 4) {
|
||||||
|
IrisJigsawStructure structure = getData().getJigsawStructureLoader().load(getDimension().getStronghold());
|
||||||
|
place(pos.toIris(), structure, rng, post);
|
||||||
|
placed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!placed) {
|
||||||
|
for (IrisJigsawStructurePlacement i : biome.getJigsawStructures()) {
|
||||||
|
if (rng.nextInt(i.getRarity()) == 0) {
|
||||||
|
IrisPosition position = new IrisPosition((x << 4) + rng.nextInt(15), 0, (z << 4) + rng.nextInt(15));
|
||||||
|
IrisJigsawStructure structure = getData().getJigsawStructureLoader().load(i.getStructure());
|
||||||
|
place(position, structure, rng, post);
|
||||||
|
placed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!placed) {
|
||||||
|
for (IrisJigsawStructurePlacement i : region.getJigsawStructures()) {
|
||||||
|
if (rng.nextInt(i.getRarity()) == 0) {
|
||||||
|
IrisPosition position = new IrisPosition((x << 4) + rng.nextInt(15), 0, (z << 4) + rng.nextInt(15));
|
||||||
|
IrisJigsawStructure structure = getData().getJigsawStructureLoader().load(i.getStructure());
|
||||||
|
place(position, structure, rng, post);
|
||||||
|
placed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!placed) {
|
||||||
|
for (IrisJigsawStructurePlacement i : getDimension().getJigsawStructures()) {
|
||||||
|
if (rng.nextInt(i.getRarity()) == 0) {
|
||||||
|
IrisPosition position = new IrisPosition((x << 4) + rng.nextInt(15), 0, (z << 4) + rng.nextInt(15));
|
||||||
|
IrisJigsawStructure structure = getData().getJigsawStructureLoader().load(i.getStructure());
|
||||||
|
place(position, structure, rng, post);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@BlockCoordinates
|
||||||
|
private void place(IrisPosition position, IrisJigsawStructure structure, RNG rng, Consumer<Runnable> post) {
|
||||||
|
if (structure.getFeature() != null) {
|
||||||
|
if (structure.getFeature().getBlockRadius() == 32) {
|
||||||
|
structure.getFeature().setBlockRadius((double) structure.getMaxDimension() / 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
getMantle().set(position.getX(), 0, position.getZ(),
|
||||||
|
new IrisFeaturePositional(position.getX(), position.getZ(), structure.getFeature()));
|
||||||
|
}
|
||||||
|
|
||||||
|
post.accept(() -> new PlannedStructure(structure, position, rng).place(getEngineMantle(), getMantle(), post));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,135 @@
|
|||||||
|
/*
|
||||||
|
* 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.mantle.components;
|
||||||
|
|
||||||
|
import com.volmit.iris.Iris;
|
||||||
|
import com.volmit.iris.engine.data.cache.Cache;
|
||||||
|
import com.volmit.iris.engine.mantle.EngineMantle;
|
||||||
|
import com.volmit.iris.engine.mantle.IrisMantleComponent;
|
||||||
|
import com.volmit.iris.engine.object.biome.IrisBiome;
|
||||||
|
import com.volmit.iris.engine.object.feature.IrisFeature;
|
||||||
|
import com.volmit.iris.engine.object.feature.IrisFeaturePositional;
|
||||||
|
import com.volmit.iris.engine.object.feature.IrisFeaturePotential;
|
||||||
|
import com.volmit.iris.engine.object.objects.IrisObject;
|
||||||
|
import com.volmit.iris.engine.object.objects.IrisObjectPlacement;
|
||||||
|
import com.volmit.iris.engine.object.regional.IrisRegion;
|
||||||
|
import com.volmit.iris.util.documentation.BlockCoordinates;
|
||||||
|
import com.volmit.iris.util.documentation.ChunkCoordinates;
|
||||||
|
import com.volmit.iris.util.format.Form;
|
||||||
|
import com.volmit.iris.util.mantle.MantleFlag;
|
||||||
|
import com.volmit.iris.util.math.RNG;
|
||||||
|
import com.volmit.iris.util.parallel.BurstExecutor;
|
||||||
|
import com.volmit.iris.util.scheduling.PrecisionStopwatch;
|
||||||
|
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
public class MantleObjectComponent extends IrisMantleComponent {
|
||||||
|
public MantleObjectComponent(EngineMantle engineMantle) {
|
||||||
|
super(engineMantle, MantleFlag.OBJECT);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void generateLayer(int x, int z, Consumer<Runnable> post) {
|
||||||
|
RNG rng = new RNG(Cache.key(x, z) + seed());
|
||||||
|
int xxx = 8 + (x << 4);
|
||||||
|
int zzz = 8 + (z << 4);
|
||||||
|
IrisRegion region = getComplex().getRegionStream().get(xxx, zzz);
|
||||||
|
IrisBiome biome = getComplex().getTrueBiomeStreamNoFeatures().get(xxx, zzz);
|
||||||
|
placeObjects(rng, x, z, biome, region, post);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ChunkCoordinates
|
||||||
|
private void placeObjects(RNG rng, int x, int z, IrisBiome biome, IrisRegion region, Consumer<Runnable> post) {
|
||||||
|
for (IrisObjectPlacement i : biome.getSurfaceObjects()) {
|
||||||
|
if (rng.chance(i.getChance() + rng.d(-0.005, 0.005)) && rng.chance(getComplex().getObjectChanceStream().get(x << 4, z << 4))) {
|
||||||
|
try {
|
||||||
|
placeObject(rng, x << 4, z << 4, i, post);
|
||||||
|
} catch (Throwable e) {
|
||||||
|
Iris.reportError(e);
|
||||||
|
Iris.error("Failed to place objects in the following biome: " + biome.getName());
|
||||||
|
Iris.error("Object(s) " + i.getPlace().toString(", ") + " (" + e.getClass().getSimpleName() + ").");
|
||||||
|
Iris.error("Are these objects missing?");
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (IrisObjectPlacement i : region.getSurfaceObjects()) {
|
||||||
|
if (rng.chance(i.getChance() + rng.d(-0.005, 0.005)) && rng.chance(getComplex().getObjectChanceStream().get(x << 4, z << 4))) {
|
||||||
|
try {
|
||||||
|
placeObject(rng, x << 4, z << 4, i, post);
|
||||||
|
} catch (Throwable e) {
|
||||||
|
Iris.reportError(e);
|
||||||
|
Iris.error("Failed to place objects in the following region: " + region.getName());
|
||||||
|
Iris.error("Object(s) " + i.getPlace().toString(", ") + " (" + e.getClass().getSimpleName() + ").");
|
||||||
|
Iris.error("Are these objects missing?");
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@BlockCoordinates
|
||||||
|
private void placeObject(RNG rng, int x, int z, IrisObjectPlacement objectPlacement, Consumer<Runnable> post) {
|
||||||
|
for (int i = 0; i < objectPlacement.getDensity(); i++) {
|
||||||
|
IrisObject v = objectPlacement.getScale().get(rng, objectPlacement.getObject(getComplex(), rng));
|
||||||
|
if (v == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int xx = rng.i(x, x + 16);
|
||||||
|
int zz = rng.i(z, z + 16);
|
||||||
|
int id = rng.i(0, Integer.MAX_VALUE);
|
||||||
|
|
||||||
|
Runnable r = () -> {
|
||||||
|
int h = v.place(xx, -1, zz, getEngineMantle(), objectPlacement, rng,
|
||||||
|
(b) -> getMantle().set(b.getX(), b.getY(), b.getZ(),
|
||||||
|
v.getLoadKey() + "@" + id), null, getData());
|
||||||
|
|
||||||
|
if (objectPlacement.usesFeatures()) {
|
||||||
|
if (objectPlacement.isVacuum()) {
|
||||||
|
|
||||||
|
double a = Math.max(v.getW(), v.getD());
|
||||||
|
IrisFeature f = new IrisFeature();
|
||||||
|
f.setConvergeToHeight(h - (v.getH() >> 1));
|
||||||
|
f.setBlockRadius(a);
|
||||||
|
f.setInterpolationRadius(objectPlacement.getVacuumInterpolationRadius());
|
||||||
|
f.setInterpolator(objectPlacement.getVacuumInterpolationMethod());
|
||||||
|
f.setStrength(1D);
|
||||||
|
getMantle().set(xx,0,zz,new IrisFeaturePositional(xx, zz, f));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (IrisFeaturePotential j : objectPlacement.getAddFeatures()) {
|
||||||
|
if (j.hasZone(rng, xx >> 4, zz >> 4)) {
|
||||||
|
getMantle().set(xx,0,zz,new IrisFeaturePositional(xx, zz, j.getZone()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (objectPlacement.usesFeatures()) {
|
||||||
|
r.run();
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
post.accept(r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -62,11 +62,11 @@ public class IrisPostModifier extends EngineAssignedModifier<BlockData> {
|
|||||||
|
|
||||||
@SuppressWarnings("SynchronizationOnLocalVariableOrMethodParameter")
|
@SuppressWarnings("SynchronizationOnLocalVariableOrMethodParameter")
|
||||||
private void post(int currentPostX, int currentPostZ, Hunk<BlockData> currentData, int x, int z) {
|
private void post(int currentPostX, int currentPostZ, Hunk<BlockData> currentData, int x, int z) {
|
||||||
int h = getEngine().getEngineParallax().trueHeight(x, z);
|
int h = getEngine().getMantle().trueHeight(x, z);
|
||||||
int ha = getEngine().getEngineParallax().trueHeight(x + 1, z);
|
int ha = getEngine().getMantle().trueHeight(x + 1, z);
|
||||||
int hb = getEngine().getEngineParallax().trueHeight(x, z + 1);
|
int hb = getEngine().getMantle().trueHeight(x, z + 1);
|
||||||
int hc = getEngine().getEngineParallax().trueHeight(x - 1, z);
|
int hc = getEngine().getMantle().trueHeight(x - 1, z);
|
||||||
int hd = getEngine().getEngineParallax().trueHeight(x, z - 1);
|
int hd = getEngine().getMantle().trueHeight(x, z - 1);
|
||||||
|
|
||||||
// Floating Nibs
|
// Floating Nibs
|
||||||
int g = 0;
|
int g = 0;
|
||||||
|
@ -1,104 +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.biome;
|
|
||||||
|
|
||||||
import com.volmit.iris.engine.data.cache.AtomicCache;
|
|
||||||
import com.volmit.iris.engine.object.annotations.*;
|
|
||||||
import com.volmit.iris.engine.object.objects.IrisObject;
|
|
||||||
import com.volmit.iris.engine.object.objects.IrisObjectPlacement;
|
|
||||||
import com.volmit.iris.util.collection.KList;
|
|
||||||
import com.volmit.iris.util.collection.KSet;
|
|
||||||
import com.volmit.iris.util.data.DataProvider;
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.NoArgsConstructor;
|
|
||||||
import lombok.experimental.Accessors;
|
|
||||||
|
|
||||||
@Accessors(chain = true)
|
|
||||||
@NoArgsConstructor
|
|
||||||
@AllArgsConstructor
|
|
||||||
@Desc("A biome mutation if a condition is met")
|
|
||||||
@Data
|
|
||||||
public class IrisBiomeMutation {
|
|
||||||
@RegistryListResource(IrisBiome.class)
|
|
||||||
@Required
|
|
||||||
@ArrayType(min = 1, type = String.class)
|
|
||||||
@Desc("One of The following biomes or regions must show up")
|
|
||||||
private KList<String> sideA = new KList<>();
|
|
||||||
|
|
||||||
@RegistryListResource(IrisBiome.class)
|
|
||||||
@Required
|
|
||||||
@ArrayType(min = 1, type = String.class)
|
|
||||||
@Desc("One of The following biomes or regions must show up")
|
|
||||||
private KList<String> sideB = new KList<>();
|
|
||||||
|
|
||||||
@Required
|
|
||||||
@MinNumber(1)
|
|
||||||
@MaxNumber(1024)
|
|
||||||
@Desc("The scan radius for placing this mutator")
|
|
||||||
private int radius = 16;
|
|
||||||
|
|
||||||
@Required
|
|
||||||
@MinNumber(1)
|
|
||||||
@MaxNumber(32)
|
|
||||||
@Desc("How many tries per chunk to check for this mutation")
|
|
||||||
private int checks = 2;
|
|
||||||
|
|
||||||
@RegistryListResource(IrisObject.class)
|
|
||||||
@ArrayType(min = 1, type = IrisObjectPlacement.class)
|
|
||||||
@Desc("Objects define what schematics (iob files) iris will place in this biome mutation")
|
|
||||||
private KList<IrisObjectPlacement> objects = new KList<>();
|
|
||||||
|
|
||||||
private final transient AtomicCache<KList<String>> sideACache = new AtomicCache<>();
|
|
||||||
private final transient AtomicCache<KList<String>> sideBCache = new AtomicCache<>();
|
|
||||||
|
|
||||||
public KList<String> getRealSideA(DataProvider xg) {
|
|
||||||
return sideACache.aquire(() -> processList(xg, getSideA()));
|
|
||||||
}
|
|
||||||
|
|
||||||
public KList<String> getRealSideB(DataProvider xg) {
|
|
||||||
return sideBCache.aquire(() -> processList(xg, getSideB()));
|
|
||||||
}
|
|
||||||
|
|
||||||
public KList<String> processList(DataProvider xg, KList<String> s) {
|
|
||||||
KSet<String> r = new KSet<>();
|
|
||||||
|
|
||||||
for (String i : s) {
|
|
||||||
|
|
||||||
if (i.startsWith("^")) {
|
|
||||||
r.addAll(xg.getData().getRegionLoader().load(i.substring(1)).getLandBiomes());
|
|
||||||
} else if (i.startsWith("*")) {
|
|
||||||
String name = i.substring(1);
|
|
||||||
r.addAll(xg.getData().getBiomeLoader().load(name).getAllChildren(xg, 7));
|
|
||||||
} else if (i.startsWith("!")) {
|
|
||||||
r.remove(i.substring(1));
|
|
||||||
} else if (i.startsWith("!*")) {
|
|
||||||
String name = i.substring(2);
|
|
||||||
|
|
||||||
for (String g : xg.getData().getBiomeLoader().load(name).getAllChildren(xg, 7)) {
|
|
||||||
r.remove(g);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
r.add(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return new KList<>(r);
|
|
||||||
}
|
|
||||||
}
|
|
@ -26,7 +26,6 @@ import com.volmit.iris.engine.object.annotations.*;
|
|||||||
import com.volmit.iris.engine.object.biome.InferredType;
|
import com.volmit.iris.engine.object.biome.InferredType;
|
||||||
import com.volmit.iris.engine.object.biome.IrisBiome;
|
import com.volmit.iris.engine.object.biome.IrisBiome;
|
||||||
import com.volmit.iris.engine.object.biome.IrisBiomeCustom;
|
import com.volmit.iris.engine.object.biome.IrisBiomeCustom;
|
||||||
import com.volmit.iris.engine.object.biome.IrisBiomeMutation;
|
|
||||||
import com.volmit.iris.engine.object.block.IrisBlockDrops;
|
import com.volmit.iris.engine.object.block.IrisBlockDrops;
|
||||||
import com.volmit.iris.engine.object.block.IrisMaterialPalette;
|
import com.volmit.iris.engine.object.block.IrisMaterialPalette;
|
||||||
import com.volmit.iris.engine.object.carve.IrisCarveLayer;
|
import com.volmit.iris.engine.object.carve.IrisCarveLayer;
|
||||||
@ -294,8 +293,8 @@ public class IrisDimension extends IrisRegistrant {
|
|||||||
@Desc("The configuration for island mode dimensions")
|
@Desc("The configuration for island mode dimensions")
|
||||||
private IrisTerrainIsland islandMode = new IrisTerrainIsland();
|
private IrisTerrainIsland islandMode = new IrisTerrainIsland();
|
||||||
|
|
||||||
@Desc("Disable this to stop placing schematics in biomes")
|
@Desc("Disable this to stop placing objects, entities, features & updates")
|
||||||
private boolean placeObjects = true;
|
private boolean useMantle = true;
|
||||||
|
|
||||||
@Desc("Prevent Leaf decay as if placed in creative mode")
|
@Desc("Prevent Leaf decay as if placed in creative mode")
|
||||||
private boolean preventLeafDecay = false;
|
private boolean preventLeafDecay = false;
|
||||||
@ -330,10 +329,6 @@ public class IrisDimension extends IrisRegistrant {
|
|||||||
@Desc("The palette of blocks for 'water'")
|
@Desc("The palette of blocks for 'water'")
|
||||||
private IrisMaterialPalette fluidPalette = new IrisMaterialPalette().qclear().qadd("water");
|
private IrisMaterialPalette fluidPalette = new IrisMaterialPalette().qclear().qadd("water");
|
||||||
|
|
||||||
@ArrayType(min = 1, type = IrisBiomeMutation.class)
|
|
||||||
@Desc("Define biome mutations for this dimension")
|
|
||||||
private KList<IrisBiomeMutation> mutations = new KList<>();
|
|
||||||
|
|
||||||
@Desc("Cartographer map trade overrides")
|
@Desc("Cartographer map trade overrides")
|
||||||
private IrisVillagerOverride patchCartographers = new IrisVillagerOverride().setDisableTrade(false);
|
private IrisVillagerOverride patchCartographers = new IrisVillagerOverride().setDisableTrade(false);
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ package com.volmit.iris.engine.object.meta;
|
|||||||
|
|
||||||
import com.volmit.iris.Iris;
|
import com.volmit.iris.Iris;
|
||||||
import com.volmit.iris.engine.data.cache.AtomicCache;
|
import com.volmit.iris.engine.data.cache.AtomicCache;
|
||||||
import com.volmit.iris.engine.framework.GeneratorAccess;
|
import com.volmit.iris.engine.framework.Engine;
|
||||||
import com.volmit.iris.engine.object.annotations.*;
|
import com.volmit.iris.engine.object.annotations.*;
|
||||||
import com.volmit.iris.util.math.RNG;
|
import com.volmit.iris.util.math.RNG;
|
||||||
import com.volmit.iris.util.scheduling.ChronoLatch;
|
import com.volmit.iris.util.scheduling.ChronoLatch;
|
||||||
@ -29,6 +29,7 @@ import lombok.AllArgsConstructor;
|
|||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
import lombok.experimental.Accessors;
|
import lombok.experimental.Accessors;
|
||||||
|
import net.minecraft.world.level.GeneratorAccess;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Particle;
|
import org.bukkit.Particle;
|
||||||
import org.bukkit.Sound;
|
import org.bukkit.Sound;
|
||||||
@ -202,7 +203,7 @@ public class IrisEffect {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void apply(Player p, GeneratorAccess g) {
|
public void apply(Player p, Engine g) {
|
||||||
if (!canTick()) {
|
if (!canTick()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1,202 +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.parallax;
|
|
||||||
|
|
||||||
import com.volmit.iris.engine.object.tile.TileData;
|
|
||||||
import com.volmit.iris.util.documentation.BlockCoordinates;
|
|
||||||
import com.volmit.iris.util.documentation.ChunkCoordinates;
|
|
||||||
import com.volmit.iris.util.hunk.Hunk;
|
|
||||||
import org.bukkit.block.TileState;
|
|
||||||
import org.bukkit.block.data.BlockData;
|
|
||||||
|
|
||||||
public interface ParallaxAccess {
|
|
||||||
@BlockCoordinates
|
|
||||||
default BlockData getBlock(int x, int y, int z) {
|
|
||||||
return getBlocksR(x >> 4, z >> 4).get(x & 15, y, z & 15);
|
|
||||||
}
|
|
||||||
|
|
||||||
@BlockCoordinates
|
|
||||||
default void setBlock(int x, int y, int z, BlockData d) {
|
|
||||||
getBlocksRW(x >> 4, z >> 4).set(x & 15, y, z & 15, d);
|
|
||||||
}
|
|
||||||
|
|
||||||
@BlockCoordinates
|
|
||||||
default TileData<? extends TileState> getTile(int x, int y, int z) {
|
|
||||||
return getTilesR(x >> 4, z >> 4).get(x & 15, y, z & 15);
|
|
||||||
}
|
|
||||||
|
|
||||||
@BlockCoordinates
|
|
||||||
default void setTile(int x, int y, int z, TileData<? extends TileState> d) {
|
|
||||||
getTilesRW(x >> 4, z >> 4).set(x & 15, y, z & 15, d);
|
|
||||||
}
|
|
||||||
|
|
||||||
@BlockCoordinates
|
|
||||||
default String getObject(int x, int y, int z) {
|
|
||||||
return getObjectsR(x >> 4, z >> 4).get(x & 15, y, z & 15);
|
|
||||||
}
|
|
||||||
|
|
||||||
@BlockCoordinates
|
|
||||||
default void setObject(int x, int y, int z, String d) {
|
|
||||||
getObjectsRW(x >> 4, z >> 4).set(x & 15, y, z & 15, d);
|
|
||||||
}
|
|
||||||
|
|
||||||
@BlockCoordinates
|
|
||||||
default String getEntity(int x, int y, int z) {
|
|
||||||
return getEntitiesR(x >> 4, z >> 4).get(x & 15, y, z & 15);
|
|
||||||
}
|
|
||||||
|
|
||||||
@BlockCoordinates
|
|
||||||
default void setEntity(int x, int y, int z, String d) {
|
|
||||||
getEntitiesRW(x >> 4, z >> 4).set(x & 15, y, z & 15, d);
|
|
||||||
}
|
|
||||||
|
|
||||||
@BlockCoordinates
|
|
||||||
default Boolean isUpdate(int x, int y, int z) {
|
|
||||||
return getUpdatesR(x >> 4, z >> 4).get(x & 15, y, z & 15);
|
|
||||||
}
|
|
||||||
|
|
||||||
@BlockCoordinates
|
|
||||||
default void updateBlock(int x, int y, int z) {
|
|
||||||
setUpdate(x, y, z, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@BlockCoordinates
|
|
||||||
default void setUpdate(int x, int y, int z, boolean d) {
|
|
||||||
getUpdatesRW(x >> 4, z >> 4).set(x & 15, y, z & 15, d);
|
|
||||||
}
|
|
||||||
|
|
||||||
@ChunkCoordinates
|
|
||||||
default boolean isParallaxGenerated(int x, int z) {
|
|
||||||
return getMetaR(x, z).isParallaxGenerated();
|
|
||||||
}
|
|
||||||
|
|
||||||
@ChunkCoordinates
|
|
||||||
default boolean isChunkGenerated(int x, int z) {
|
|
||||||
return getMetaR(x, z).isGenerated();
|
|
||||||
}
|
|
||||||
|
|
||||||
@ChunkCoordinates
|
|
||||||
default boolean isFeatureGenerated(int x, int z) {
|
|
||||||
return getMetaR(x, z).isFeatureGenerated();
|
|
||||||
}
|
|
||||||
|
|
||||||
@ChunkCoordinates
|
|
||||||
default void setParallaxGenerated(int x, int z) {
|
|
||||||
setParallaxGenerated(x, z, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@ChunkCoordinates
|
|
||||||
default void setChunkGenerated(int x, int z) {
|
|
||||||
setChunkGenerated(x, z, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@ChunkCoordinates
|
|
||||||
default void setFeatureGenerated(int x, int z) {
|
|
||||||
setFeatureGenerated(x, z, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@ChunkCoordinates
|
|
||||||
default void setParallaxGenerated(int x, int z, boolean v) {
|
|
||||||
getMetaRW(x, z).setParallaxGenerated(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
@ChunkCoordinates
|
|
||||||
default void maxMin(int x, int z, int value) {
|
|
||||||
ParallaxChunkMeta meat = getMetaRW(x, z);
|
|
||||||
|
|
||||||
if (value > meat.getMaxObject()) {
|
|
||||||
meat.setMaxObject(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (meat.getMinObject() <= -1) {
|
|
||||||
meat.setMinObject(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (value < meat.getMinObject()) {
|
|
||||||
meat.setMinObject(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@ChunkCoordinates
|
|
||||||
default void setChunkGenerated(int x, int z, boolean v) {
|
|
||||||
getMetaRW(x, z).setGenerated(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
@ChunkCoordinates
|
|
||||||
default void setFeatureGenerated(int x, int z, boolean v) {
|
|
||||||
getMetaRW(x, z).setFeatureGenerated(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
@ChunkCoordinates
|
|
||||||
Hunk<TileData<? extends TileState>> getTilesR(int x, int z);
|
|
||||||
|
|
||||||
@ChunkCoordinates
|
|
||||||
Hunk<TileData<? extends TileState>> getTilesRW(int x, int z);
|
|
||||||
|
|
||||||
@ChunkCoordinates
|
|
||||||
Hunk<BlockData> getBlocksR(int x, int z);
|
|
||||||
|
|
||||||
@ChunkCoordinates
|
|
||||||
Hunk<BlockData> getBlocksRW(int x, int z);
|
|
||||||
|
|
||||||
@ChunkCoordinates
|
|
||||||
Hunk<String> getObjectsR(int x, int z);
|
|
||||||
|
|
||||||
@ChunkCoordinates
|
|
||||||
Hunk<String> getObjectsRW(int x, int z);
|
|
||||||
|
|
||||||
@ChunkCoordinates
|
|
||||||
Hunk<String> getEntitiesRW(int x, int z);
|
|
||||||
|
|
||||||
@ChunkCoordinates
|
|
||||||
Hunk<String> getEntitiesR(int x, int z);
|
|
||||||
|
|
||||||
@ChunkCoordinates
|
|
||||||
Hunk<Boolean> getUpdatesR(int x, int z);
|
|
||||||
|
|
||||||
@ChunkCoordinates
|
|
||||||
Hunk<Boolean> getUpdatesRW(int x, int z);
|
|
||||||
|
|
||||||
@ChunkCoordinates
|
|
||||||
ParallaxChunkMeta getMetaR(int x, int z);
|
|
||||||
|
|
||||||
@ChunkCoordinates
|
|
||||||
ParallaxChunkMeta getMetaRW(int x, int z);
|
|
||||||
|
|
||||||
void cleanup(long regionIdle, long chunkIdle);
|
|
||||||
|
|
||||||
void cleanup();
|
|
||||||
|
|
||||||
void saveAll();
|
|
||||||
|
|
||||||
void saveAllNOW();
|
|
||||||
|
|
||||||
int getRegionCount();
|
|
||||||
|
|
||||||
int getChunkCount();
|
|
||||||
|
|
||||||
@ChunkCoordinates
|
|
||||||
default void delete(int x, int z) {
|
|
||||||
getUpdatesRW(x, z).empty(false);
|
|
||||||
getBlocksRW(x, z).empty(null);
|
|
||||||
getTilesRW(x, z).empty(null);
|
|
||||||
getEntitiesRW(x, z).empty(null);
|
|
||||||
getObjectsRW(x, z).empty(null);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,100 +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.parallax;
|
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
|
||||||
import com.volmit.iris.engine.object.feature.IrisFeaturePositional;
|
|
||||||
import com.volmit.iris.util.hunk.io.HunkIOAdapter;
|
|
||||||
import com.volmit.iris.util.hunk.io.PaletteHunkIOAdapter;
|
|
||||||
import com.volmit.iris.util.oldnbt.CompoundTag;
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
import java.io.DataInputStream;
|
|
||||||
import java.io.DataOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.CopyOnWriteArraySet;
|
|
||||||
import java.util.function.Function;
|
|
||||||
|
|
||||||
@AllArgsConstructor
|
|
||||||
@Data
|
|
||||||
public class ParallaxChunkMeta {
|
|
||||||
private static final Gson gson = new Gson();
|
|
||||||
public static final Function<CompoundTag, HunkIOAdapter<ParallaxChunkMeta>> adapter = (c) -> new PaletteHunkIOAdapter<>() {
|
|
||||||
@Override
|
|
||||||
public void write(ParallaxChunkMeta parallaxChunkMeta, DataOutputStream dos) throws IOException {
|
|
||||||
dos.writeBoolean(parallaxChunkMeta.updates);
|
|
||||||
dos.writeBoolean(parallaxChunkMeta.generated);
|
|
||||||
dos.writeBoolean(parallaxChunkMeta.tilesGenerated);
|
|
||||||
dos.writeBoolean(parallaxChunkMeta.parallaxGenerated);
|
|
||||||
dos.writeBoolean(parallaxChunkMeta.featureGenerated);
|
|
||||||
dos.writeBoolean(parallaxChunkMeta.objects);
|
|
||||||
dos.writeInt(parallaxChunkMeta.maxObject);
|
|
||||||
dos.writeInt(parallaxChunkMeta.minObject);
|
|
||||||
dos.writeInt(parallaxChunkMeta.count);
|
|
||||||
dos.writeInt(parallaxChunkMeta.features.size());
|
|
||||||
|
|
||||||
for (IrisFeaturePositional i : parallaxChunkMeta.features) {
|
|
||||||
dos.writeUTF(gson.toJson(i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ParallaxChunkMeta read(DataInputStream din) throws IOException {
|
|
||||||
ParallaxChunkMeta pcm = new ParallaxChunkMeta();
|
|
||||||
pcm.setUpdates(din.readBoolean());
|
|
||||||
pcm.setGenerated(din.readBoolean());
|
|
||||||
pcm.setTilesGenerated(din.readBoolean());
|
|
||||||
pcm.setParallaxGenerated(din.readBoolean());
|
|
||||||
pcm.setFeatureGenerated(din.readBoolean());
|
|
||||||
pcm.setObjects(din.readBoolean());
|
|
||||||
pcm.setMaxObject(din.readInt());
|
|
||||||
pcm.setMinObject(din.readInt());
|
|
||||||
pcm.setCount(din.readInt());
|
|
||||||
pcm.setFeatures(newSet());
|
|
||||||
int c = din.readInt();
|
|
||||||
|
|
||||||
for (int i = 0; i < c; i++) {
|
|
||||||
pcm.getFeatures().add(gson.fromJson(din.readUTF(), IrisFeaturePositional.class));
|
|
||||||
}
|
|
||||||
|
|
||||||
return pcm;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private boolean updates;
|
|
||||||
private boolean generated;
|
|
||||||
private boolean tilesGenerated;
|
|
||||||
private boolean parallaxGenerated;
|
|
||||||
private boolean featureGenerated;
|
|
||||||
private boolean objects;
|
|
||||||
private int maxObject = -1;
|
|
||||||
private int minObject = -1;
|
|
||||||
private int count;
|
|
||||||
private Set<IrisFeaturePositional> features;
|
|
||||||
|
|
||||||
private static Set<IrisFeaturePositional> newSet() {
|
|
||||||
return new CopyOnWriteArraySet<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public ParallaxChunkMeta() {
|
|
||||||
this(false, false, false, false, false, false, -1, -1, 0, newSet());
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,223 +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.parallax;
|
|
||||||
|
|
||||||
import com.volmit.iris.Iris;
|
|
||||||
import com.volmit.iris.core.IrisSettings;
|
|
||||||
import com.volmit.iris.engine.object.tile.TileData;
|
|
||||||
import com.volmit.iris.util.format.C;
|
|
||||||
import com.volmit.iris.util.hunk.Hunk;
|
|
||||||
import com.volmit.iris.util.hunk.io.HunkIOAdapter;
|
|
||||||
import com.volmit.iris.util.hunk.io.HunkRegion;
|
|
||||||
import com.volmit.iris.util.hunk.io.HunkRegionSlice;
|
|
||||||
import com.volmit.iris.util.math.M;
|
|
||||||
import com.volmit.iris.util.oldnbt.ByteArrayTag;
|
|
||||||
import com.volmit.iris.util.oldnbt.CompoundTag;
|
|
||||||
import com.volmit.iris.util.oldnbt.Tag;
|
|
||||||
import com.volmit.iris.util.parallel.GridLock;
|
|
||||||
import com.volmit.iris.util.parallel.MultiBurst;
|
|
||||||
import com.volmit.iris.util.parallel.NOOPGridLock;
|
|
||||||
import org.bukkit.block.TileState;
|
|
||||||
import org.bukkit.block.data.BlockData;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
public class ParallaxRegion extends HunkRegion {
|
|
||||||
private boolean dirtyMeta;
|
|
||||||
private Hunk<ParallaxChunkMeta> meta;
|
|
||||||
private HunkIOAdapter<ParallaxChunkMeta> metaAdapter;
|
|
||||||
private HunkRegionSlice<BlockData> blockSlice;
|
|
||||||
private HunkRegionSlice<TileData<? extends TileState>> tileSlice;
|
|
||||||
private HunkRegionSlice<String> objectSlice;
|
|
||||||
private HunkRegionSlice<String> entitySlice;
|
|
||||||
private HunkRegionSlice<Boolean> updateSlice;
|
|
||||||
private final GridLock lock;
|
|
||||||
private long lastUse;
|
|
||||||
private final int height;
|
|
||||||
private final MultiBurst burst;
|
|
||||||
|
|
||||||
public ParallaxRegion(MultiBurst burst, int height, File folder, int x, int z, CompoundTag compound) {
|
|
||||||
super(folder, x, z, compound);
|
|
||||||
this.burst = burst;
|
|
||||||
this.height = height;
|
|
||||||
setupSlices();
|
|
||||||
lock = newGridLock();
|
|
||||||
}
|
|
||||||
|
|
||||||
public ParallaxRegion(MultiBurst burst, int height, File folder, int x, int z) {
|
|
||||||
super(folder, x, z);
|
|
||||||
this.burst = burst;
|
|
||||||
this.height = height;
|
|
||||||
setupSlices();
|
|
||||||
lock = newGridLock();
|
|
||||||
}
|
|
||||||
|
|
||||||
private GridLock newGridLock() {
|
|
||||||
return IrisSettings.get().getConcurrency().isUnstableLockingHeuristics() ? new NOOPGridLock(1, 1) : new GridLock(32, 32);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setupSlices() {
|
|
||||||
blockSlice = HunkRegionSlice.BLOCKDATA.apply(height, getCompound());
|
|
||||||
tileSlice = HunkRegionSlice.TILE.apply(height, getCompound());
|
|
||||||
objectSlice = HunkRegionSlice.STRING.apply(height, getCompound(), "objects");
|
|
||||||
entitySlice = HunkRegionSlice.STRING.apply(height, getCompound(), "entities");
|
|
||||||
updateSlice = HunkRegionSlice.BOOLEAN.apply(height, getCompound(), "updates");
|
|
||||||
metaAdapter = ParallaxChunkMeta.adapter.apply(getCompound());
|
|
||||||
dirtyMeta = false;
|
|
||||||
meta = null;
|
|
||||||
lastUse = M.ms();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean hasBeenIdleLongerThan(long time) {
|
|
||||||
return M.ms() - lastUse > time;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ParallaxChunkMeta getMetaR(int x, int z) {
|
|
||||||
return lock.withResult(x, z, () -> getMetaHunkR().getOr(x, 0, z, new ParallaxChunkMeta()));
|
|
||||||
}
|
|
||||||
|
|
||||||
public ParallaxChunkMeta getMetaRW(int x, int z) {
|
|
||||||
return lock.withResult(x, z, () -> {
|
|
||||||
lastUse = M.ms();
|
|
||||||
dirtyMeta = true;
|
|
||||||
ParallaxChunkMeta p = getMetaHunkRW().get(x, 0, z);
|
|
||||||
if (p == null) {
|
|
||||||
p = new ParallaxChunkMeta();
|
|
||||||
getMetaHunkRW().set(x, 0, z, p);
|
|
||||||
}
|
|
||||||
|
|
||||||
return p;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private Hunk<ParallaxChunkMeta> getMetaHunkR() {
|
|
||||||
if (meta == null) {
|
|
||||||
meta = loadMetaHunk();
|
|
||||||
}
|
|
||||||
|
|
||||||
return meta;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Hunk<ParallaxChunkMeta> getMetaHunkRW() {
|
|
||||||
dirtyMeta = true;
|
|
||||||
return getMetaHunkR();
|
|
||||||
}
|
|
||||||
|
|
||||||
private Hunk<ParallaxChunkMeta> loadMetaHunk() {
|
|
||||||
lastUse = M.ms();
|
|
||||||
if (meta == null) {
|
|
||||||
Tag t = getCompound().getValue().get("meta");
|
|
||||||
|
|
||||||
if ((t instanceof ByteArrayTag)) {
|
|
||||||
try {
|
|
||||||
meta = metaAdapter.read((x, y, z) -> Hunk.newAtomicHunk(32, 1, 32), (ByteArrayTag) t);
|
|
||||||
} catch (IOException e) {
|
|
||||||
Iris.reportError(e);
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (meta == null) {
|
|
||||||
meta = Hunk.newAtomicHunk(32, 1, 32);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return meta;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void unloadMetaHunk() {
|
|
||||||
if (dirtyMeta) {
|
|
||||||
saveMetaHunk();
|
|
||||||
dirtyMeta = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
meta = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void saveMetaHunk() {
|
|
||||||
if (meta != null && dirtyMeta) {
|
|
||||||
try {
|
|
||||||
getCompound().getValue().put("meta", meta.writeByteArrayTag(metaAdapter, "meta"));
|
|
||||||
dirtyMeta = false;
|
|
||||||
} catch (IOException e) {
|
|
||||||
Iris.reportError(e);
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public synchronized void save() throws IOException {
|
|
||||||
blockSlice.save(burst);
|
|
||||||
objectSlice.save(burst);
|
|
||||||
entitySlice.save(burst);
|
|
||||||
tileSlice.save(burst);
|
|
||||||
updateSlice.save(burst);
|
|
||||||
saveMetaHunk();
|
|
||||||
Iris.debug("Saved Parallax Region " + C.GOLD + getX() + " " + getZ());
|
|
||||||
super.save();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int unload() {
|
|
||||||
unloadMetaHunk();
|
|
||||||
return blockSlice.unloadAll() +
|
|
||||||
objectSlice.unloadAll() +
|
|
||||||
entitySlice.unloadAll() +
|
|
||||||
tileSlice.unloadAll() +
|
|
||||||
updateSlice.unloadAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
public HunkRegionSlice<BlockData> getBlockSlice() {
|
|
||||||
lastUse = M.ms();
|
|
||||||
return blockSlice;
|
|
||||||
}
|
|
||||||
|
|
||||||
public HunkRegionSlice<String> getEntitySlice() {
|
|
||||||
lastUse = M.ms();
|
|
||||||
return entitySlice;
|
|
||||||
}
|
|
||||||
|
|
||||||
public HunkRegionSlice<TileData<? extends TileState>> getTileSlice() {
|
|
||||||
lastUse = M.ms();
|
|
||||||
return tileSlice;
|
|
||||||
}
|
|
||||||
|
|
||||||
public HunkRegionSlice<String> getObjectSlice() {
|
|
||||||
lastUse = M.ms();
|
|
||||||
return objectSlice;
|
|
||||||
}
|
|
||||||
|
|
||||||
public HunkRegionSlice<Boolean> getUpdateSlice() {
|
|
||||||
lastUse = M.ms();
|
|
||||||
return updateSlice;
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized int cleanup(long c) {
|
|
||||||
return blockSlice.cleanup(c) +
|
|
||||||
objectSlice.cleanup(c) +
|
|
||||||
entitySlice.cleanup(c) +
|
|
||||||
tileSlice.cleanup(c) +
|
|
||||||
updateSlice.cleanup(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getChunkCount() {
|
|
||||||
return blockSlice.getLoadCount() + objectSlice.getLoadCount() + entitySlice.getLoadCount() + tileSlice.getLoadCount() + updateSlice.getLoadCount();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,270 +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.parallax;
|
|
||||||
|
|
||||||
import com.volmit.iris.Iris;
|
|
||||||
import com.volmit.iris.core.IrisSettings;
|
|
||||||
import com.volmit.iris.engine.object.tile.TileData;
|
|
||||||
import com.volmit.iris.util.collection.KList;
|
|
||||||
import com.volmit.iris.util.collection.KMap;
|
|
||||||
import com.volmit.iris.util.documentation.ChunkCoordinates;
|
|
||||||
import com.volmit.iris.util.documentation.RegionCoordinates;
|
|
||||||
import com.volmit.iris.util.format.C;
|
|
||||||
import com.volmit.iris.util.hunk.Hunk;
|
|
||||||
import com.volmit.iris.util.parallel.MultiBurst;
|
|
||||||
import org.bukkit.block.TileState;
|
|
||||||
import org.bukkit.block.data.BlockData;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
@SuppressWarnings("ALL")
|
|
||||||
public class ParallaxWorld implements ParallaxAccess {
|
|
||||||
private final KMap<Long, ParallaxRegion> loadedRegions;
|
|
||||||
private final KList<Long> save;
|
|
||||||
private final File folder;
|
|
||||||
private final MultiBurst burst;
|
|
||||||
private final int height;
|
|
||||||
|
|
||||||
public ParallaxWorld(MultiBurst burst, int height, File folder) {
|
|
||||||
this.height = height;
|
|
||||||
this.burst = burst;
|
|
||||||
this.folder = folder;
|
|
||||||
save = new KList<>();
|
|
||||||
loadedRegions = new KMap<>();
|
|
||||||
folder.mkdirs();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getRegionCount() {
|
|
||||||
return loadedRegions.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getChunkCount() {
|
|
||||||
int m = 0;
|
|
||||||
|
|
||||||
try {
|
|
||||||
for (ParallaxRegion i : loadedRegions.values()) {
|
|
||||||
m += i.getChunkCount();
|
|
||||||
}
|
|
||||||
} catch (Throwable e) {
|
|
||||||
Iris.reportError(e);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void close() {
|
|
||||||
for (ParallaxRegion i : loadedRegions.v()) {
|
|
||||||
unload(i.getX(), i.getZ());
|
|
||||||
}
|
|
||||||
|
|
||||||
save.clear();
|
|
||||||
loadedRegions.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void save(ParallaxRegion region) {
|
|
||||||
try {
|
|
||||||
region.save();
|
|
||||||
} catch (IOException e) {
|
|
||||||
Iris.reportError(e);
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@RegionCoordinates
|
|
||||||
public boolean isLoaded(int x, int z) {
|
|
||||||
return loadedRegions.containsKey(key(x, z));
|
|
||||||
}
|
|
||||||
|
|
||||||
@RegionCoordinates
|
|
||||||
public void save(int x, int z) {
|
|
||||||
if (isLoaded(x, z)) {
|
|
||||||
save(getR(x, z));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@RegionCoordinates
|
|
||||||
public int unload(int x, int z) {
|
|
||||||
long key = key(x, z);
|
|
||||||
int v = 0;
|
|
||||||
if (isLoaded(x, z)) {
|
|
||||||
if (save.contains(key)) {
|
|
||||||
save(x, z);
|
|
||||||
save.remove(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
ParallaxRegion lr = loadedRegions.remove(key);
|
|
||||||
|
|
||||||
if (lr != null) {
|
|
||||||
v += lr.unload();
|
|
||||||
Iris.debug("Unloaded Parallax Region " + C.RED + x + " " + z);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
@RegionCoordinates
|
|
||||||
public ParallaxRegion load(int x, int z) {
|
|
||||||
if (isLoaded(x, z)) {
|
|
||||||
return loadedRegions.get(key(x, z));
|
|
||||||
}
|
|
||||||
|
|
||||||
ParallaxRegion v = new ParallaxRegion(burst, height, folder, x, z);
|
|
||||||
loadedRegions.put(key(x, z), v);
|
|
||||||
Iris.debug("Loaded Parallax Region " + C.RED + x + " " + z);
|
|
||||||
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
@RegionCoordinates
|
|
||||||
public ParallaxRegion getR(int x, int z) {
|
|
||||||
long key = key(x, z);
|
|
||||||
|
|
||||||
ParallaxRegion region = loadedRegions.get(key);
|
|
||||||
|
|
||||||
if (region == null) {
|
|
||||||
region = load(x, z);
|
|
||||||
}
|
|
||||||
|
|
||||||
return region;
|
|
||||||
}
|
|
||||||
|
|
||||||
@RegionCoordinates
|
|
||||||
public ParallaxRegion getRW(int x, int z) {
|
|
||||||
save.addIfMissing(key(x, z));
|
|
||||||
return getR(x, z);
|
|
||||||
}
|
|
||||||
|
|
||||||
@RegionCoordinates
|
|
||||||
private long key(int x, int z) {
|
|
||||||
return (((long) x) << 32) | (((long) z) & 0xffffffffL);
|
|
||||||
}
|
|
||||||
|
|
||||||
@ChunkCoordinates
|
|
||||||
@Override
|
|
||||||
public Hunk<BlockData> getBlocksR(int x, int z) {
|
|
||||||
return getR(x >> 5, z >> 5).getBlockSlice().getR(x & 31, z & 31);
|
|
||||||
}
|
|
||||||
|
|
||||||
@ChunkCoordinates
|
|
||||||
@Override
|
|
||||||
public Hunk<BlockData> getBlocksRW(int x, int z) {
|
|
||||||
return getRW(x >> 5, z >> 5).getBlockSlice().getRW(x & 31, z & 31);
|
|
||||||
}
|
|
||||||
|
|
||||||
@ChunkCoordinates
|
|
||||||
@Override
|
|
||||||
public Hunk<TileData<? extends TileState>> getTilesR(int x, int z) {
|
|
||||||
return getR(x >> 5, z >> 5).getTileSlice().getR(x & 31, z & 31);
|
|
||||||
}
|
|
||||||
|
|
||||||
@ChunkCoordinates
|
|
||||||
@Override
|
|
||||||
public Hunk<TileData<? extends TileState>> getTilesRW(int x, int z) {
|
|
||||||
return getRW(x >> 5, z >> 5).getTileSlice().getRW(x & 31, z & 31);
|
|
||||||
}
|
|
||||||
|
|
||||||
@ChunkCoordinates
|
|
||||||
@Override
|
|
||||||
public Hunk<String> getObjectsR(int x, int z) {
|
|
||||||
return getR(x >> 5, z >> 5).getObjectSlice().getR(x & 31, z & 31);
|
|
||||||
}
|
|
||||||
|
|
||||||
@ChunkCoordinates
|
|
||||||
@Override
|
|
||||||
public Hunk<String> getObjectsRW(int x, int z) {
|
|
||||||
return getRW(x >> 5, z >> 5).getObjectSlice().getRW(x & 31, z & 31);
|
|
||||||
}
|
|
||||||
|
|
||||||
@ChunkCoordinates
|
|
||||||
@Override
|
|
||||||
public Hunk<String> getEntitiesRW(int x, int z) {
|
|
||||||
return getRW(x >> 5, z >> 5).getEntitySlice().getRW(x & 31, z & 31);
|
|
||||||
}
|
|
||||||
|
|
||||||
@ChunkCoordinates
|
|
||||||
@Override
|
|
||||||
public Hunk<String> getEntitiesR(int x, int z) {
|
|
||||||
return getRW(x >> 5, z >> 5).getEntitySlice().getR(x & 31, z & 31);
|
|
||||||
}
|
|
||||||
|
|
||||||
@ChunkCoordinates
|
|
||||||
@Override
|
|
||||||
public Hunk<Boolean> getUpdatesR(int x, int z) {
|
|
||||||
return getR(x >> 5, z >> 5).getUpdateSlice().getR(x & 31, z & 31);
|
|
||||||
}
|
|
||||||
|
|
||||||
@ChunkCoordinates
|
|
||||||
@Override
|
|
||||||
public Hunk<Boolean> getUpdatesRW(int x, int z) {
|
|
||||||
return getRW(x >> 5, z >> 5).getUpdateSlice().getRW(x & 31, z & 31);
|
|
||||||
}
|
|
||||||
|
|
||||||
@ChunkCoordinates
|
|
||||||
@Override
|
|
||||||
public ParallaxChunkMeta getMetaR(int x, int z) {
|
|
||||||
return getR(x >> 5, z >> 5).getMetaR(x & 31, z & 31);
|
|
||||||
}
|
|
||||||
|
|
||||||
@ChunkCoordinates
|
|
||||||
@Override
|
|
||||||
public ParallaxChunkMeta getMetaRW(int x, int z) {
|
|
||||||
return getRW(x >> 5, z >> 5).getMetaRW(x & 31, z & 31);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void cleanup() {
|
|
||||||
cleanup(IrisSettings.get().getParallaxRegionEvictionMS(), IrisSettings.get().getParallax().getParallaxChunkEvictionMS());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public synchronized void cleanup(long r, long c) {
|
|
||||||
try {
|
|
||||||
int rr = 0;
|
|
||||||
for (ParallaxRegion i : loadedRegions.v()) {
|
|
||||||
burst.lazy(() -> {
|
|
||||||
if (i.hasBeenIdleLongerThan(r)) {
|
|
||||||
unload(i.getX(), i.getZ());
|
|
||||||
} else {
|
|
||||||
i.cleanup(c);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} catch (Throwable e) {
|
|
||||||
Iris.reportError(e);
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void saveAll() {
|
|
||||||
burst.lazy(this::saveAllNOW);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void saveAllNOW() {
|
|
||||||
Iris.debug("Saving " + C.GREEN + loadedRegions.size() + " Parallax Regions");
|
|
||||||
for (ParallaxRegion i : loadedRegions.v()) {
|
|
||||||
if (save.contains(key(i.getX(), i.getZ()))) {
|
|
||||||
save(i.getX(), i.getZ());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -51,7 +51,6 @@ import java.util.Random;
|
|||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChunkGenerator {
|
public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChunkGenerator {
|
||||||
private static final BlockData ERROR_BLOCK = Material.RED_GLAZED_TERRACOTTA.createBlockData();
|
|
||||||
private final EngineProvider provider;
|
private final EngineProvider provider;
|
||||||
private final IrisWorld world;
|
private final IrisWorld world;
|
||||||
private final File dataLocation;
|
private final File dataLocation;
|
||||||
@ -150,7 +149,7 @@ public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChun
|
|||||||
|
|
||||||
for (int i = 0; i < 16; i++) {
|
for (int i = 0; i < 16; i++) {
|
||||||
for (int j = 0; j < 16; j++) {
|
for (int j = 0; j < 16; j++) {
|
||||||
d.setBlock(i, 0, j, ERROR_BLOCK);
|
d.setBlock(i, 0, j, Material.RED_GLAZED_TERRACOTTA.createBlockData());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,14 +54,21 @@ public class EngineProvider {
|
|||||||
public Engine getEngine()
|
public Engine getEngine()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
return engine.get().get();
|
Engine e = engine.get().get();
|
||||||
} catch (InterruptedException e) {
|
|
||||||
e.printStackTrace();
|
if(e == null)
|
||||||
} catch (ExecutionException e) {
|
{
|
||||||
e.printStackTrace();
|
throw new RuntimeException("NULL");
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return e;
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
throw new RuntimeException("INTERRUPTED");
|
||||||
|
} catch (ExecutionException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
throw new RuntimeException("EXECUTION ERROR");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void close() {
|
public void close() {
|
||||||
|
126
src/main/java/com/volmit/iris/util/collection/StateList.java
Normal file
126
src/main/java/com/volmit/iris/util/collection/StateList.java
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
/*
|
||||||
|
* 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.util.collection;
|
||||||
|
|
||||||
|
public class StateList
|
||||||
|
{
|
||||||
|
private final KList<String> states;
|
||||||
|
|
||||||
|
public StateList(String... states)
|
||||||
|
{
|
||||||
|
this.states = new KList<String>(states);
|
||||||
|
|
||||||
|
if(getBits() > 64)
|
||||||
|
{
|
||||||
|
throw new RuntimeException("StateLists cannot exceed 64 bits! You are trying to use " + getBits() + " bits!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public StateList(Enum<?>... states)
|
||||||
|
{
|
||||||
|
this.states = new KList<Enum<?>>().convert(Enum::name);
|
||||||
|
|
||||||
|
if(getBits() > 64)
|
||||||
|
{
|
||||||
|
throw new RuntimeException("StateLists cannot exceed 64 bits! You are trying to use " + getBits() + " bits!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public long max()
|
||||||
|
{
|
||||||
|
return (long) (Math.pow(2, getBits()) - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public KList<String> getEnabled(long list)
|
||||||
|
{
|
||||||
|
KList<String> f = new KList<>();
|
||||||
|
|
||||||
|
for(String i : states)
|
||||||
|
{
|
||||||
|
if(is(list, i))
|
||||||
|
{
|
||||||
|
f.add(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long of(String... enabledStates)
|
||||||
|
{
|
||||||
|
long b = 0;
|
||||||
|
|
||||||
|
for(String i : enabledStates)
|
||||||
|
{
|
||||||
|
b |= getBit(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long set(long list, String state, boolean enabled)
|
||||||
|
{
|
||||||
|
long bit = getBit(state);
|
||||||
|
boolean is = is(list, state);
|
||||||
|
|
||||||
|
if(enabled && !is)
|
||||||
|
{
|
||||||
|
return list | bit;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if(!enabled && is)
|
||||||
|
{
|
||||||
|
return list ^ bit;
|
||||||
|
}
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean is(long list, String state)
|
||||||
|
{
|
||||||
|
long bit = getBit(state);
|
||||||
|
|
||||||
|
return bit > 0 && (list & bit) == bit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasBit(String state)
|
||||||
|
{
|
||||||
|
return getBit(state) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getBit(String state)
|
||||||
|
{
|
||||||
|
return getBit(states.indexOf(state));
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getBit(int index)
|
||||||
|
{
|
||||||
|
return (long) (index < 0 ? -1 : Math.pow(2, index));
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getBytes()
|
||||||
|
{
|
||||||
|
return getBits() == 0 ? 0 : ((getBits() >> 2) + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getBits()
|
||||||
|
{
|
||||||
|
return states.size();
|
||||||
|
}
|
||||||
|
}
|
@ -23,9 +23,11 @@ import com.volmit.iris.engine.data.cache.Cache;
|
|||||||
import com.volmit.iris.util.collection.KMap;
|
import com.volmit.iris.util.collection.KMap;
|
||||||
import com.volmit.iris.util.collection.KSet;
|
import com.volmit.iris.util.collection.KSet;
|
||||||
import com.volmit.iris.util.documentation.BlockCoordinates;
|
import com.volmit.iris.util.documentation.BlockCoordinates;
|
||||||
|
import com.volmit.iris.util.documentation.ChunkCoordinates;
|
||||||
import com.volmit.iris.util.documentation.RegionCoordinates;
|
import com.volmit.iris.util.documentation.RegionCoordinates;
|
||||||
import com.volmit.iris.util.format.C;
|
import com.volmit.iris.util.format.C;
|
||||||
import com.volmit.iris.util.format.Form;
|
import com.volmit.iris.util.format.Form;
|
||||||
|
import com.volmit.iris.util.function.Consumer4;
|
||||||
import com.volmit.iris.util.math.M;
|
import com.volmit.iris.util.math.M;
|
||||||
import com.volmit.iris.util.matter.Matter;
|
import com.volmit.iris.util.matter.Matter;
|
||||||
import com.volmit.iris.util.parallel.BurstExecutor;
|
import com.volmit.iris.util.parallel.BurstExecutor;
|
||||||
@ -42,6 +44,7 @@ import java.util.UUID;
|
|||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
import java.util.zip.GZIPInputStream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The mantle can store any type of data slice anywhere and manage regions & IO on it's own.
|
* The mantle can store any type of data slice anywhere and manage regions & IO on it's own.
|
||||||
@ -77,6 +80,66 @@ public class Mantle {
|
|||||||
Iris.debug("Opened The Mantle " + C.DARK_AQUA + dataFolder.getAbsolutePath());
|
Iris.debug("Opened The Mantle " + C.DARK_AQUA + dataFolder.getAbsolutePath());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ChunkCoordinates
|
||||||
|
public void raiseFlag(int x, int z, MantleFlag flag, Runnable r)
|
||||||
|
{
|
||||||
|
if(!hasFlag(x, z, flag))
|
||||||
|
{
|
||||||
|
flag(x, z, flag, true);
|
||||||
|
r.run();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ChunkCoordinates
|
||||||
|
public void lowerFlag(int x, int z, MantleFlag flag, Runnable r)
|
||||||
|
{
|
||||||
|
if(hasFlag(x, z, flag))
|
||||||
|
{
|
||||||
|
flag(x, z, flag, false);
|
||||||
|
r.run();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ChunkCoordinates
|
||||||
|
public void flag(int x, int z, MantleFlag flag, boolean flagged)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
get(x >> 5, z >> 5).get().getOrCreate(x & 31, z & 31).flag(flag, flagged);
|
||||||
|
} catch (InterruptedException | ExecutionException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ChunkCoordinates
|
||||||
|
public <T> void iterateChunk(int x, int z, Class<T> type, Consumer4<Integer, Integer, Integer, T> iterator, MantleFlag... requiredFlags)
|
||||||
|
{
|
||||||
|
for(MantleFlag i : requiredFlags)
|
||||||
|
{
|
||||||
|
if(!hasFlag(x, z, i))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
get(x >> 5, z >> 5).get().getOrCreate(x & 31, z & 31).iterate(type, iterator);
|
||||||
|
} catch (InterruptedException | ExecutionException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ChunkCoordinates
|
||||||
|
public boolean hasFlag(int x, int z, MantleFlag flag)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
return get(x >> 5, z >> 5).get().getOrCreate(x & 31, z & 31).isFlagged(flag);
|
||||||
|
} catch (InterruptedException | ExecutionException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set data T at the given block position. This method will attempt to find a
|
* Set data T at the given block position. This method will attempt to find a
|
||||||
* Tectonic Plate either by loading it or creating a new one. This method uses
|
* Tectonic Plate either by loading it or creating a new one. This method uses
|
||||||
@ -203,27 +266,28 @@ public class Mantle {
|
|||||||
unload.clear();
|
unload.clear();
|
||||||
|
|
||||||
for (Long i : lastUse.keySet()) {
|
for (Long i : lastUse.keySet()) {
|
||||||
|
hyperLock.withLong(i, () -> {
|
||||||
if (M.ms() - lastUse.get(i) >= idleDuration) {
|
if (M.ms() - lastUse.get(i) >= idleDuration) {
|
||||||
unload.add(i);
|
unload.add(i);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Long i : unload) {
|
for (Long i : unload) {
|
||||||
|
hyperLock.withLong(i, () ->{
|
||||||
TectonicPlate m = loadedRegions.remove(i);
|
TectonicPlate m = loadedRegions.remove(i);
|
||||||
lastUse.remove(i);
|
lastUse.remove(i);
|
||||||
Iris.debug("Unloaded Tectonic Plate " + C.DARK_GREEN + i);
|
|
||||||
|
|
||||||
if (m != null) {
|
|
||||||
ioBurst.lazy(() -> {
|
|
||||||
try {
|
try {
|
||||||
m.write(fileForRegion(dataFolder, i));
|
m.write(fileForRegion(dataFolder, i));
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Iris.debug("Unloaded Tectonic Plate " + C.DARK_GREEN + Cache.keyX(i) + " " + Cache.keyZ(i));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This retreives a future of the Tectonic Plate at the given coordinates.
|
* This retreives a future of the Tectonic Plate at the given coordinates.
|
||||||
@ -234,9 +298,17 @@ public class Mantle {
|
|||||||
* @return the future of a tectonic plate.
|
* @return the future of a tectonic plate.
|
||||||
*/
|
*/
|
||||||
@RegionCoordinates
|
@RegionCoordinates
|
||||||
private CompletableFuture<TectonicPlate> get(int x, int z) {
|
private synchronized CompletableFuture<TectonicPlate> get(int x, int z) {
|
||||||
return ioBurst.completeValue(() -> hyperLock.withResult(x, z, () -> {
|
|
||||||
Long k = key(x, z);
|
Long k = key(x, z);
|
||||||
|
TectonicPlate p = loadedRegions.get(k);
|
||||||
|
|
||||||
|
if(p != null)
|
||||||
|
{
|
||||||
|
lastUse.put(k, M.ms());
|
||||||
|
return CompletableFuture.completedFuture(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ioBurst.completeValue(() -> hyperLock.withResult(x, z, () -> {
|
||||||
lastUse.put(k, M.ms());
|
lastUse.put(k, M.ms());
|
||||||
TectonicPlate region = loadedRegions.get(k);
|
TectonicPlate region = loadedRegions.get(k);
|
||||||
|
|
||||||
@ -248,10 +320,7 @@ public class Mantle {
|
|||||||
|
|
||||||
if (file.exists()) {
|
if (file.exists()) {
|
||||||
try {
|
try {
|
||||||
FileInputStream fin = new FileInputStream(file);
|
region = TectonicPlate.read(worldHeight, file);
|
||||||
DataInputStream din = new DataInputStream(fin);
|
|
||||||
region = new TectonicPlate(worldHeight, din);
|
|
||||||
din.close();
|
|
||||||
loadedRegions.put(k, region);
|
loadedRegions.put(k, region);
|
||||||
Iris.debug("Loaded Tectonic Plate " + C.DARK_GREEN + x + " " + z + C.DARK_AQUA + " " + file.getName());
|
Iris.debug("Loaded Tectonic Plate " + C.DARK_GREEN + x + " " + z + C.DARK_AQUA + " " + file.getName());
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
@ -268,7 +337,7 @@ public class Mantle {
|
|||||||
|
|
||||||
region = new TectonicPlate(worldHeight);
|
region = new TectonicPlate(worldHeight);
|
||||||
loadedRegions.put(k, region);
|
loadedRegions.put(k, region);
|
||||||
Iris.debug("Created new Tectonic Plate (Due to Load Failure) " + C.DARK_GREEN + x + " " + z);
|
Iris.debug("Created new Tectonic Plate " + C.DARK_GREEN + x + " " + z);
|
||||||
return region;
|
return region;
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
@ -287,4 +356,8 @@ public class Mantle {
|
|||||||
public static Long key(int x, int z) {
|
public static Long key(int x, int z) {
|
||||||
return Cache.key(x, z);
|
return Cache.key(x, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void saveAll() {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,14 +18,20 @@
|
|||||||
|
|
||||||
package com.volmit.iris.util.mantle;
|
package com.volmit.iris.util.mantle;
|
||||||
|
|
||||||
|
import com.volmit.iris.Iris;
|
||||||
import com.volmit.iris.util.collection.KSet;
|
import com.volmit.iris.util.collection.KSet;
|
||||||
|
import com.volmit.iris.util.collection.StateList;
|
||||||
|
import com.volmit.iris.util.data.Varint;
|
||||||
import com.volmit.iris.util.documentation.ChunkCoordinates;
|
import com.volmit.iris.util.documentation.ChunkCoordinates;
|
||||||
|
import com.volmit.iris.util.function.Consumer4;
|
||||||
import com.volmit.iris.util.matter.IrisMatter;
|
import com.volmit.iris.util.matter.IrisMatter;
|
||||||
import com.volmit.iris.util.matter.Matter;
|
import com.volmit.iris.util.matter.Matter;
|
||||||
|
import com.volmit.iris.util.matter.MatterSlice;
|
||||||
|
|
||||||
import java.io.DataInputStream;
|
import java.io.DataInputStream;
|
||||||
import java.io.DataOutputStream;
|
import java.io.DataOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.concurrent.atomic.AtomicIntegerArray;
|
||||||
import java.util.concurrent.atomic.AtomicReferenceArray;
|
import java.util.concurrent.atomic.AtomicReferenceArray;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -33,7 +39,7 @@ import java.util.concurrent.atomic.AtomicReferenceArray;
|
|||||||
* Mantle Chunks are fully atomic & thread safe
|
* Mantle Chunks are fully atomic & thread safe
|
||||||
*/
|
*/
|
||||||
public class MantleChunk {
|
public class MantleChunk {
|
||||||
private final KSet<String> flags;
|
private final AtomicIntegerArray flags;
|
||||||
private final AtomicReferenceArray<Matter> sections;
|
private final AtomicReferenceArray<Matter> sections;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -44,7 +50,12 @@ public class MantleChunk {
|
|||||||
@ChunkCoordinates
|
@ChunkCoordinates
|
||||||
public MantleChunk(int sectionHeight) {
|
public MantleChunk(int sectionHeight) {
|
||||||
sections = new AtomicReferenceArray<>(sectionHeight);
|
sections = new AtomicReferenceArray<>(sectionHeight);
|
||||||
flags = new KSet<>();
|
flags = new AtomicIntegerArray(MantleFlag.values().length);
|
||||||
|
|
||||||
|
for (int i = 0; i < flags.length(); i++)
|
||||||
|
{
|
||||||
|
flags.set(i, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -58,10 +69,10 @@ public class MantleChunk {
|
|||||||
public MantleChunk(int sectionHeight, DataInputStream din) throws IOException, ClassNotFoundException {
|
public MantleChunk(int sectionHeight, DataInputStream din) throws IOException, ClassNotFoundException {
|
||||||
this(sectionHeight);
|
this(sectionHeight);
|
||||||
int s = din.readByte();
|
int s = din.readByte();
|
||||||
int f = din.readByte();
|
|
||||||
|
|
||||||
for (int i = 0; i < f; i++) {
|
for(int i = 0; i < flags.length(); i++)
|
||||||
flags.add(din.readUTF());
|
{
|
||||||
|
flags.set(i, din.readBoolean() ? 1 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < s; i++) {
|
for (int i = 0; i < s; i++) {
|
||||||
@ -71,16 +82,12 @@ public class MantleChunk {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void flag(String s, boolean f) {
|
public void flag(MantleFlag flag, boolean f) {
|
||||||
if (f) {
|
flags.set(flag.ordinal(), f ? 1 : 0);
|
||||||
flags.add(s);
|
|
||||||
} else {
|
|
||||||
flags.remove(s);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isFlagged(String s) {
|
public boolean isFlagged(MantleFlag flag) {
|
||||||
return flags.contains(s);
|
return flags.get(flag.ordinal()) == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -150,13 +157,14 @@ public class MantleChunk {
|
|||||||
*/
|
*/
|
||||||
public void write(DataOutputStream dos) throws IOException {
|
public void write(DataOutputStream dos) throws IOException {
|
||||||
dos.writeByte(sections.length());
|
dos.writeByte(sections.length());
|
||||||
dos.writeByte(flags.size());
|
|
||||||
|
|
||||||
for (String i : flags) {
|
for (int i = 0; i < flags.length(); i++) {
|
||||||
dos.writeUTF(i);
|
dos.writeBoolean(flags.get(i) == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < sections.length(); i++) {
|
for (int i = 0; i < sections.length(); i++) {
|
||||||
|
trimSlice(i);
|
||||||
|
|
||||||
if (exists(i)) {
|
if (exists(i)) {
|
||||||
dos.writeBoolean(true);
|
dos.writeBoolean(true);
|
||||||
Matter matter = get(i);
|
Matter matter = get(i);
|
||||||
@ -166,4 +174,42 @@ public class MantleChunk {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void trimSlice(int i) {
|
||||||
|
if(exists(i))
|
||||||
|
{
|
||||||
|
Matter m = get(i);
|
||||||
|
|
||||||
|
if(m.getSliceMap().isEmpty())
|
||||||
|
{
|
||||||
|
sections.set(i, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
else{
|
||||||
|
m.trimSlices();
|
||||||
|
if(m.getSliceMap().isEmpty())
|
||||||
|
{
|
||||||
|
sections.set(i, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> void iterate(Class<T> type, Consumer4<Integer, Integer, Integer,T> iterator) {
|
||||||
|
for(int i = 0; i < sections.length(); i++)
|
||||||
|
{
|
||||||
|
int bs = (i << 4);
|
||||||
|
Matter matter = get(i);
|
||||||
|
|
||||||
|
if(matter != null)
|
||||||
|
{
|
||||||
|
MatterSlice<T> t = matter.getSlice(type);
|
||||||
|
|
||||||
|
if(t != null)
|
||||||
|
{
|
||||||
|
t.iterateSync((a, b, c, f) -> iterator.accept(a,b + bs, c, f));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,21 +16,18 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.volmit.iris.engine;
|
package com.volmit.iris.util.mantle;
|
||||||
|
|
||||||
import com.volmit.iris.engine.framework.Engine;
|
import com.volmit.iris.util.collection.StateList;
|
||||||
import com.volmit.iris.engine.framework.EngineParallaxManager;
|
|
||||||
import lombok.Getter;
|
|
||||||
|
|
||||||
public class IrisEngineParallax implements EngineParallaxManager {
|
public enum MantleFlag {
|
||||||
@Getter
|
OBJECT,
|
||||||
private final Engine engine;
|
UPDATE,
|
||||||
|
JIGSAW,
|
||||||
@Getter
|
FEATURE
|
||||||
private final int parallaxSize;
|
;
|
||||||
|
static StateList getStateList()
|
||||||
public IrisEngineParallax(Engine engine) {
|
{
|
||||||
this.engine = engine;
|
return new StateList(MantleFlag.values());
|
||||||
parallaxSize = computeParallaxSize();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -21,9 +21,13 @@ package com.volmit.iris.util.mantle;
|
|||||||
import com.volmit.iris.Iris;
|
import com.volmit.iris.Iris;
|
||||||
import com.volmit.iris.util.documentation.ChunkCoordinates;
|
import com.volmit.iris.util.documentation.ChunkCoordinates;
|
||||||
import com.volmit.iris.util.format.C;
|
import com.volmit.iris.util.format.C;
|
||||||
|
import com.volmit.iris.util.format.Form;
|
||||||
|
import com.volmit.iris.util.scheduling.PrecisionStopwatch;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.util.concurrent.atomic.AtomicReferenceArray;
|
import java.util.concurrent.atomic.AtomicReferenceArray;
|
||||||
|
import java.util.zip.GZIPInputStream;
|
||||||
|
import java.util.zip.GZIPOutputStream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tectonic Plates are essentially representations of regions in minecraft.
|
* Tectonic Plates are essentially representations of regions in minecraft.
|
||||||
@ -61,6 +65,16 @@ public class TectonicPlate {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static TectonicPlate read(int worldHeight, File file) throws IOException, ClassNotFoundException {
|
||||||
|
FileInputStream fin = new FileInputStream(file);
|
||||||
|
GZIPInputStream gzi = new GZIPInputStream(fin);
|
||||||
|
DataInputStream din = new DataInputStream(gzi);
|
||||||
|
TectonicPlate p = new TectonicPlate(worldHeight, din);
|
||||||
|
din.close();
|
||||||
|
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if a chunk exists in this plate or not (same as get(x, z) != null)
|
* Check if a chunk exists in this plate or not (same as get(x, z) != null)
|
||||||
*
|
*
|
||||||
@ -136,11 +150,13 @@ public class TectonicPlate {
|
|||||||
* @throws IOException shit happens
|
* @throws IOException shit happens
|
||||||
*/
|
*/
|
||||||
public void write(File file) throws IOException {
|
public void write(File file) throws IOException {
|
||||||
|
PrecisionStopwatch p = PrecisionStopwatch.start();
|
||||||
FileOutputStream fos = new FileOutputStream(file);
|
FileOutputStream fos = new FileOutputStream(file);
|
||||||
DataOutputStream dos = new DataOutputStream(fos);
|
GZIPOutputStream gzo = new GZIPOutputStream(fos);
|
||||||
|
DataOutputStream dos = new DataOutputStream(gzo);
|
||||||
write(dos);
|
write(dos);
|
||||||
dos.close();
|
dos.close();
|
||||||
Iris.debug("Saved Tectonic Plate " + C.DARK_GREEN + file.getName().split("\\Q.\\E")[0]);
|
Iris.debug("Saved Tectonic Plate " + C.DARK_GREEN + file.getName().split("\\Q.\\E")[0] + C.RED + " in " + Form.duration(p.getMilliseconds(), 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -152,11 +168,16 @@ public class TectonicPlate {
|
|||||||
public void write(DataOutputStream dos) throws IOException {
|
public void write(DataOutputStream dos) throws IOException {
|
||||||
for (int i = 0; i < chunks.length(); i++) {
|
for (int i = 0; i < chunks.length(); i++) {
|
||||||
MantleChunk chunk = chunks.get(i);
|
MantleChunk chunk = chunks.get(i);
|
||||||
dos.writeBoolean(chunk != null);
|
|
||||||
|
|
||||||
if (chunk != null) {
|
if (chunk != null) {
|
||||||
|
dos.writeBoolean(true);
|
||||||
chunk.write(dos);
|
chunk.write(dos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dos.writeBoolean(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -186,18 +186,19 @@ public interface Matter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
default <T> MatterSlice<T> slice(Class<?> c) {
|
default <T> MatterSlice<T> slice(Class<?> c) {
|
||||||
if (!hasSlice(c)) {
|
MatterSlice<T> slice = (MatterSlice<T>) getSlice(c);
|
||||||
MatterSlice<?> s = createSlice(c, this);
|
if (slice == null) {
|
||||||
|
slice = (MatterSlice<T>) createSlice(c, this);
|
||||||
|
|
||||||
if (s == null) {
|
if (slice == null) {
|
||||||
Iris.error("Unable to find a slice for class " + C.DARK_RED + c.getCanonicalName());
|
Iris.error("Unable to find a slice for class " + C.DARK_RED + c.getCanonicalName());
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
putSlice(c, (MatterSlice<T>) s);
|
putSlice(c, slice);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (MatterSlice<T>) getSlice(c);
|
return slice;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -255,10 +256,13 @@ public interface Matter {
|
|||||||
Map<Class<?>, MatterSlice<?>> getSliceMap();
|
Map<Class<?>, MatterSlice<?>> getSliceMap();
|
||||||
|
|
||||||
default void write(File f) throws IOException {
|
default void write(File f) throws IOException {
|
||||||
FileOutputStream out = new FileOutputStream(f);
|
write(f, true);
|
||||||
GZIPOutputStream gzo = new GZIPOutputStream(out);
|
}
|
||||||
write(gzo);
|
|
||||||
gzo.close();
|
default void write(File f, boolean compression) throws IOException {
|
||||||
|
OutputStream out = new FileOutputStream(f);
|
||||||
|
write(out);
|
||||||
|
out.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -310,9 +314,8 @@ public interface Matter {
|
|||||||
|
|
||||||
static Matter read(File f) throws IOException, ClassNotFoundException {
|
static Matter read(File f) throws IOException, ClassNotFoundException {
|
||||||
FileInputStream in = new FileInputStream(f);
|
FileInputStream in = new FileInputStream(f);
|
||||||
GZIPInputStream gzi = new GZIPInputStream(in);
|
Matter m = read(in);
|
||||||
Matter m = read(gzi);
|
in.close();
|
||||||
gzi.close();
|
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ import java.io.IOException;
|
|||||||
|
|
||||||
@Data
|
@Data
|
||||||
public class MatterHeader {
|
public class MatterHeader {
|
||||||
private String author = "anonymous";
|
private String author = "";
|
||||||
private long createdAt = M.ms();
|
private long createdAt = M.ms();
|
||||||
private int version = Matter.VERSION;
|
private int version = Matter.VERSION;
|
||||||
|
|
||||||
|
@ -18,7 +18,9 @@
|
|||||||
|
|
||||||
package com.volmit.iris.util.matter;
|
package com.volmit.iris.util.matter;
|
||||||
|
|
||||||
|
import com.volmit.iris.Iris;
|
||||||
import com.volmit.iris.engine.data.cache.Cache;
|
import com.volmit.iris.engine.data.cache.Cache;
|
||||||
|
import com.volmit.iris.util.data.NibbleDataPalette;
|
||||||
import com.volmit.iris.util.data.Varint;
|
import com.volmit.iris.util.data.Varint;
|
||||||
import com.volmit.iris.util.hunk.Hunk;
|
import com.volmit.iris.util.hunk.Hunk;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
@ -106,6 +108,19 @@ public interface MatterSlice<T> extends Hunk<T> {
|
|||||||
return readFrom(mediumType) != null;
|
return readFrom(mediumType) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
default int getBitsPer(int needed)
|
||||||
|
{
|
||||||
|
int target = 1;
|
||||||
|
for (int i = 1; i < 8; i++) {
|
||||||
|
if (Math.pow(2, i) > needed) {
|
||||||
|
target = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return target;
|
||||||
|
}
|
||||||
|
|
||||||
default void write(DataOutputStream dos) throws IOException {
|
default void write(DataOutputStream dos) throws IOException {
|
||||||
int w = getWidth();
|
int w = getWidth();
|
||||||
int h = getHeight();
|
int h = getHeight();
|
||||||
|
@ -0,0 +1,54 @@
|
|||||||
|
/*
|
||||||
|
* 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.util.matter.slices;
|
||||||
|
|
||||||
|
import com.volmit.iris.util.data.Varint;
|
||||||
|
import com.volmit.iris.util.matter.Sliced;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.OfflinePlayer;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
import java.io.DataInputStream;
|
||||||
|
import java.io.DataOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
@Sliced
|
||||||
|
public class PlayerMatter extends RawMatter<Player> {
|
||||||
|
public PlayerMatter() {
|
||||||
|
this(1, 1, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PlayerMatter(int width, int height, int depth) {
|
||||||
|
super(width, height, depth, Player.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeNode(Player b, DataOutputStream dos) throws IOException {
|
||||||
|
Varint.writeSignedVarLong(b.getUniqueId().getMostSignificantBits(), dos);
|
||||||
|
Varint.writeSignedVarLong(b.getUniqueId().getLeastSignificantBits(), dos);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Player readNode(DataInputStream din) throws IOException {
|
||||||
|
UUID id = new UUID(Varint.readSignedVarLong(din), Varint.readSignedVarLong(din));
|
||||||
|
|
||||||
|
return Bukkit.getPlayer(id);
|
||||||
|
}
|
||||||
|
}
|
@ -21,6 +21,7 @@ package com.volmit.iris.util.parallel;
|
|||||||
import com.volmit.iris.Iris;
|
import com.volmit.iris.Iris;
|
||||||
import com.volmit.iris.util.collection.KList;
|
import com.volmit.iris.util.collection.KList;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
import java.util.concurrent.*;
|
import java.util.concurrent.*;
|
||||||
|
|
||||||
@SuppressWarnings("ALL")
|
@SuppressWarnings("ALL")
|
||||||
@ -42,7 +43,7 @@ public class BurstExecutor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public BurstExecutor queue(KList<Runnable> r) {
|
public BurstExecutor queue(List<Runnable> r) {
|
||||||
synchronized (futures) {
|
synchronized (futures) {
|
||||||
for (Runnable i : r) {
|
for (Runnable i : r) {
|
||||||
CompletableFuture<Void> c = CompletableFuture.runAsync(i, executor);
|
CompletableFuture<Void> c = CompletableFuture.runAsync(i, executor);
|
||||||
|
@ -33,6 +33,7 @@ import java.util.function.Supplier;
|
|||||||
public class HyperLock {
|
public class HyperLock {
|
||||||
private final ConcurrentLinkedHashMap<Long, ReentrantLock> locks;
|
private final ConcurrentLinkedHashMap<Long, ReentrantLock> locks;
|
||||||
private final BiFunction<? super Long, ? super ReentrantLock, ? extends ReentrantLock> accessor;
|
private final BiFunction<? super Long, ? super ReentrantLock, ? extends ReentrantLock> accessor;
|
||||||
|
private boolean enabled = true;
|
||||||
|
|
||||||
public HyperLock() {
|
public HyperLock() {
|
||||||
this(1024, false);
|
this(1024, false);
|
||||||
@ -62,6 +63,12 @@ public class HyperLock {
|
|||||||
unlock(x, z);
|
unlock(x, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void withLong(long k, Runnable r) {
|
||||||
|
lock(Cache.keyX(k), Cache.keyZ(k));
|
||||||
|
r.run();
|
||||||
|
unlock(Cache.keyX(k), Cache.keyZ(k));
|
||||||
|
}
|
||||||
|
|
||||||
public void withNasty(int x, int z, NastyRunnable r) throws Throwable {
|
public void withNasty(int x, int z, NastyRunnable r) throws Throwable {
|
||||||
lock(x, z);
|
lock(x, z);
|
||||||
Throwable ee = null;
|
Throwable ee = null;
|
||||||
@ -120,10 +127,24 @@ public class HyperLock {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void lock(int x, int z) {
|
public void lock(int x, int z) {
|
||||||
|
if(!enabled)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
getLock(x, z).lock();
|
getLock(x, z).lock();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void unlock(int x, int z) {
|
public void unlock(int x, int z) {
|
||||||
|
if(!enabled)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
getLock(x, z).unlock();
|
getLock(x, z).unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void disable() {
|
||||||
|
enabled = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,7 @@ import com.volmit.iris.util.math.M;
|
|||||||
import com.volmit.iris.util.scheduling.J;
|
import com.volmit.iris.util.scheduling.J;
|
||||||
import com.volmit.iris.util.scheduling.Looper;
|
import com.volmit.iris.util.scheduling.Looper;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
import java.util.concurrent.*;
|
import java.util.concurrent.*;
|
||||||
import java.util.concurrent.atomic.AtomicLong;
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
@ -99,7 +100,7 @@ public class MultiBurst {
|
|||||||
burst(r.length).queue(r).complete();
|
burst(r.length).queue(r).complete();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void burst(KList<Runnable> r) {
|
public void burst(List<Runnable> r) {
|
||||||
burst(r.size()).queue(r).complete();
|
burst(r.size()).queue(r).complete();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user