9
0
mirror of https://github.com/VolmitSoftware/Iris.git synced 2025-12-28 11:39:07 +00:00

Matter apis

This commit is contained in:
Daniel Mills
2021-08-04 19:27:28 -04:00
parent 6e369ea787
commit f2b301cb17
207 changed files with 1381 additions and 2386 deletions

View File

@@ -22,18 +22,18 @@ import com.google.common.util.concurrent.AtomicDouble;
import com.volmit.iris.Iris;
import com.volmit.iris.core.project.loader.IrisData;
import com.volmit.iris.engine.actuator.IrisTerrainNormalActuator;
import com.volmit.iris.engine.data.DataProvider;
import com.volmit.iris.util.data.DataProvider;
import com.volmit.iris.engine.framework.Engine;
import com.volmit.iris.engine.modifier.IrisCaveModifier;
import com.volmit.iris.engine.object.biome.InferredType;
import com.volmit.iris.engine.object.biome.LoaderBiome;
import com.volmit.iris.engine.object.biome.IrisBiome;
import com.volmit.iris.engine.object.decoration.IrisDecorationPart;
import com.volmit.iris.engine.object.decoration.IrisDecorator;
import com.volmit.iris.engine.object.dimensional.IrisTerrainMode;
import com.volmit.iris.engine.object.feature.IrisFeaturePositional;
import com.volmit.iris.engine.object.noise.LoaderGenerator;
import com.volmit.iris.engine.object.noise.IrisGenerator;
import com.volmit.iris.engine.object.noise.IrisInterpolator;
import com.volmit.iris.engine.object.regional.LoaderRegion;
import com.volmit.iris.engine.object.regional.IrisRegion;
import com.volmit.iris.util.noise.CNG;
import com.volmit.iris.engine.object.common.CaveResult;
import com.volmit.iris.util.stream.ProceduralStream;
@@ -55,9 +55,9 @@ public class IrisComplex implements DataProvider {
private RNG rng;
private double fluidHeight;
private IrisData data;
private KList<LoaderGenerator> generators;
private KList<IrisGenerator> generators;
private static final BlockData AIR = Material.AIR.createBlockData();
private ProceduralStream<LoaderRegion> regionStream;
private ProceduralStream<IrisRegion> regionStream;
private ProceduralStream<Double> regionStyleStream;
private ProceduralStream<Double> regionIdentityStream;
private ProceduralStream<UUID> regionIDStream;
@@ -65,14 +65,14 @@ public class IrisComplex implements DataProvider {
private ProceduralStream<Double> islandHeightStream;
private ProceduralStream<Double> islandDepthStream;
private ProceduralStream<InferredType> bridgeStream;
private ProceduralStream<LoaderBiome> landBiomeStream;
private ProceduralStream<LoaderBiome> caveBiomeStream;
private ProceduralStream<LoaderBiome> seaBiomeStream;
private ProceduralStream<LoaderBiome> shoreBiomeStream;
private ProceduralStream<LoaderBiome> baseBiomeStream;
private ProceduralStream<IrisBiome> landBiomeStream;
private ProceduralStream<IrisBiome> caveBiomeStream;
private ProceduralStream<IrisBiome> seaBiomeStream;
private ProceduralStream<IrisBiome> shoreBiomeStream;
private ProceduralStream<IrisBiome> baseBiomeStream;
private ProceduralStream<UUID> baseBiomeIDStream;
private ProceduralStream<LoaderBiome> trueBiomeStream;
private ProceduralStream<LoaderBiome> trueBiomeStreamNoFeatures;
private ProceduralStream<IrisBiome> trueBiomeStream;
private ProceduralStream<IrisBiome> trueBiomeStreamNoFeatures;
private ProceduralStream<Biome> trueBiomeDerivativeStream;
private ProceduralStream<Double> heightStream;
private ProceduralStream<Double> heightStreamNoFeatures;
@@ -95,9 +95,9 @@ public class IrisComplex implements DataProvider {
private ProceduralStream<IrisDecorator> shoreSurfaceDecoration;
private ProceduralStream<BlockData> rockStream;
private ProceduralStream<BlockData> fluidStream;
private LoaderBiome focus;
private IrisBiome focus;
public ProceduralStream<LoaderBiome> getBiomeStream(InferredType type) {
public ProceduralStream<IrisBiome> getBiomeStream(InferredType type) {
switch (type) {
case CAVE:
return caveBiomeStream;
@@ -123,7 +123,7 @@ public class IrisComplex implements DataProvider {
public IrisComplex(Engine engine, boolean simple) {
int cacheSize = 131072;
LoaderBiome emptyBiome = new LoaderBiome();
IrisBiome emptyBiome = new IrisBiome();
UUID focusUUID = UUID.nameUUIDFromBytes("focus".getBytes());
this.rng = new RNG(engine.getWorld().seed());
this.data = engine.getData();
@@ -131,13 +131,13 @@ public class IrisComplex implements DataProvider {
fluidHeight = engine.getDimension().getFluidHeight();
generators = new KList<>();
focus = engine.getFocus();
KMap<InferredType, ProceduralStream<LoaderBiome>> inferredStreams = new KMap<>();
KMap<InferredType, ProceduralStream<IrisBiome>> inferredStreams = new KMap<>();
if (focus != null) {
focus.setInferredType(InferredType.LAND);
}
LoaderRegion focusRegion = focus != null ? findRegion(focus, engine) : null;
IrisRegion focusRegion = focus != null ? findRegion(focus, engine) : null;
RNG rng = new RNG(engine.getWorld().seed());
//@builder
engine.getDimension().getRegions().forEach((i) -> data.getRegionLoader().load(i)
@@ -219,11 +219,11 @@ public class IrisComplex implements DataProvider {
bridgeStream.convertAware2D((t, x, z) -> inferredStreams.get(t).get(x, z))
.convertAware2D(this::implode).cache2D(cacheSize);
heightStream = ProceduralStream.of((x, z) -> {
LoaderBiome b = focus != null ? focus : baseBiomeStream.get(x, z);
IrisBiome b = focus != null ? focus : baseBiomeStream.get(x, z);
return getHeight(engine, b, x, z, engine.getWorld().seed(), true);
}, Interpolated.DOUBLE).clamp(0, engine.getHeight()).cache2D(cacheSize);
heightStreamNoFeatures = ProceduralStream.of((x, z) -> {
LoaderBiome b = focus != null ? focus : baseBiomeStream.get(x, z);
IrisBiome b = focus != null ? focus : baseBiomeStream.get(x, z);
return getHeight(engine, b, x, z, engine.getWorld().seed(), false);
}, Interpolated.DOUBLE).clamp(0, engine.getHeight()).cache2D(cacheSize);
slopeStream = heightStream.slope(3).cache2D(cacheSize);
@@ -242,7 +242,7 @@ public class IrisComplex implements DataProvider {
trueBiomeStream = focus != null ? ProceduralStream.of((x, y) -> focus, Interpolated.of(a -> 0D,
b -> focus)).convertAware2D((b, x, z) -> {
for (IrisFeaturePositional i : engine.getFramework().getEngineParallax().forEachFeature(x, z)) {
LoaderBiome bx = i.filter(x, z, b, rng);
IrisBiome bx = i.filter(x, z, b, rng);
if (bx != null) {
bx.setInferredType(b.getInferredType());
@@ -258,7 +258,7 @@ public class IrisComplex implements DataProvider {
regionStream.get(x, z), x, z, fluidHeight))
.convertAware2D((b, x, z) -> {
for (IrisFeaturePositional i : engine.getFramework().getEngineParallax().forEachFeature(x, z)) {
LoaderBiome bx = i.filter(x, z, b, rng);
IrisBiome bx = i.filter(x, z, b, rng);
if (bx != null) {
bx.setInferredType(b.getInferredType());
@@ -272,7 +272,7 @@ public class IrisComplex implements DataProvider {
trueBiomeStream = focus != null ? ProceduralStream.of((x, y) -> focus, Interpolated.of(a -> 0D,
b -> focus)).convertAware2D((b, x, z) -> {
for (IrisFeaturePositional i : engine.getFramework().getEngineParallax().forEachFeature(x, z)) {
LoaderBiome bx = i.filter(x, z, b, rng);
IrisBiome bx = i.filter(x, z, b, rng);
if (bx != null) {
bx.setInferredType(b.getInferredType());
@@ -288,7 +288,7 @@ public class IrisComplex implements DataProvider {
regionStream.get(x, z), x, z, fluidHeight))
.convertAware2D((b, x, z) -> {
for (IrisFeaturePositional i : engine.getFramework().getEngineParallax().forEachFeature(x, z)) {
LoaderBiome bx = i.filter(x, z, b, rng);
IrisBiome bx = i.filter(x, z, b, rng);
if (bx != null) {
bx.setInferredType(b.getInferredType());
@@ -306,7 +306,7 @@ public class IrisComplex implements DataProvider {
fixBiomeType(h, baseBiomeStream.get(x, z),
regionStream.get(x, z), x, z, fluidHeight))
.cache2D(cacheSize);
trueBiomeDerivativeStream = trueBiomeStream.convert(LoaderBiome::getDerivative).cache2D(cacheSize);
trueBiomeDerivativeStream = trueBiomeStream.convert(IrisBiome::getDerivative).cache2D(cacheSize);
heightFluidStream = heightStream.max(fluidHeight).cache2D(cacheSize);
maxHeightStream = ProceduralStream.ofDouble((x, z) -> height);
terrainSurfaceDecoration = trueBiomeStream
@@ -383,8 +383,8 @@ public class IrisComplex implements DataProvider {
});
}
private LoaderRegion findRegion(LoaderBiome focus, Engine engine) {
for (LoaderRegion i : engine.getDimension().getAllRegions(engine)) {
private IrisRegion findRegion(IrisBiome focus, Engine engine) {
for (IrisRegion i : engine.getDimension().getAllRegions(engine)) {
if (i.getAllBiomeIds().contains(focus.getLoadKey())) {
return i;
}
@@ -393,7 +393,7 @@ public class IrisComplex implements DataProvider {
return null;
}
private IrisDecorator decorateFor(LoaderBiome b, double x, double z, IrisDecorationPart part) {
private IrisDecorator decorateFor(IrisBiome b, double x, double z, IrisDecorationPart part) {
RNG rngc = chunkRngStream.get(x, z);
for (IrisDecorator i : b.getDecorators()) {
@@ -411,7 +411,7 @@ public class IrisComplex implements DataProvider {
return null;
}
private LoaderBiome fixBiomeType(Double height, LoaderBiome biome, LoaderRegion region, Double x, Double z, double fluidHeight) {
private IrisBiome fixBiomeType(Double height, IrisBiome biome, IrisRegion region, Double x, Double z, double fluidHeight) {
double sh = region.getShoreHeight(x, z);
if (height >= fluidHeight - 1 && height <= fluidHeight + sh && !biome.isShore()) {
@@ -433,14 +433,14 @@ public class IrisComplex implements DataProvider {
return biome;
}
private double getHeight(Engine engine, LoaderBiome b, double x, double z, long seed, boolean features) {
private double getHeight(Engine engine, IrisBiome b, double x, double z, long seed, boolean features) {
double h = 0;
for (LoaderGenerator gen : generators) {
for (IrisGenerator gen : generators) {
h += gen.getInterpolator().interpolate(x, z, (xx, zz) ->
{
try {
LoaderBiome bx = baseBiomeStream.get(xx, zz);
IrisBiome bx = baseBiomeStream.get(xx, zz);
return M.lerp(bx.getGenLinkMin(gen.getLoadKey()),
bx.getGenLinkMax(gen.getLoadKey()),
@@ -468,8 +468,8 @@ public class IrisComplex implements DataProvider {
return Math.min(engine.getHeight(), Math.max(noise.get(), 0));
}
private void registerGenerator(LoaderGenerator cachedGenerator) {
for (LoaderGenerator i : generators) {
private void registerGenerator(IrisGenerator cachedGenerator) {
for (IrisGenerator i : generators) {
if (i.getLoadKey().equals(cachedGenerator.getLoadKey())) {
return;
}
@@ -478,7 +478,7 @@ public class IrisComplex implements DataProvider {
generators.add(cachedGenerator);
}
private LoaderBiome implode(LoaderBiome b, Double x, Double z) {
private IrisBiome implode(IrisBiome b, Double x, Double z) {
if (b.getChildren().isEmpty()) {
return b;
}
@@ -486,7 +486,7 @@ public class IrisComplex implements DataProvider {
return implode(b, x, z, 3);
}
private LoaderBiome implode(LoaderBiome b, Double x, Double z, int max) {
private IrisBiome implode(IrisBiome b, Double x, Double z, int max) {
if (max < 0) {
return b;
}
@@ -496,9 +496,9 @@ public class IrisComplex implements DataProvider {
}
CNG childCell = b.getChildrenGenerator(rng, 123, b.getChildShrinkFactor());
KList<LoaderBiome> chx = b.getRealChildren(this).copy();
KList<IrisBiome> chx = b.getRealChildren(this).copy();
chx.add(b);
LoaderBiome biome = childCell.fitRarity(chx, x, z);
IrisBiome biome = childCell.fitRarity(chx, x, z);
biome.setInferredType(b.getInferredType());
return implode(biome, x, z, max - 1);
}

View File

@@ -25,7 +25,7 @@ import com.volmit.iris.core.events.IrisEngineHotloadEvent;
import com.volmit.iris.engine.data.cache.AtomicCache;
import com.volmit.iris.engine.framework.*;
import com.volmit.iris.util.hunk.Hunk;
import com.volmit.iris.engine.object.biome.LoaderBiome;
import com.volmit.iris.engine.object.biome.IrisBiome;
import com.volmit.iris.engine.object.biome.IrisBiomePaletteLayer;
import com.volmit.iris.engine.object.decoration.IrisDecorator;
import com.volmit.iris.engine.object.objects.IrisObjectPlacement;
@@ -142,7 +142,7 @@ public class IrisEngine extends BlockPopulator implements Engine {
}
private void computeBiomeMaxes() {
for (LoaderBiome i : getDimension().getAllBiomes(this)) {
for (IrisBiome i : getDimension().getAllBiomes(this)) {
double density = 0;
for (IrisObjectPlacement j : i.getObjects()) {
@@ -257,7 +257,7 @@ public class IrisEngine extends BlockPopulator implements Engine {
}
@Override
public LoaderBiome getFocus() {
public IrisBiome getFocus() {
if (getDimension().getFocus() == null || getDimension().getFocus().trim().isEmpty()) {
return null;
}

View File

@@ -26,7 +26,7 @@ import com.volmit.iris.engine.framework.EngineCompound;
import com.volmit.iris.engine.framework.EngineData;
import com.volmit.iris.engine.framework.EngineTarget;
import com.volmit.iris.util.hunk.Hunk;
import com.volmit.iris.engine.object.dimensional.LoaderDimension;
import com.volmit.iris.engine.object.dimensional.IrisDimension;
import com.volmit.iris.engine.object.dimensional.IrisDimensionIndex;
import com.volmit.iris.engine.object.basic.IrisPosition;
import com.volmit.iris.engine.object.common.IrisWorld;
@@ -71,7 +71,7 @@ public class IrisEngineCompound implements EngineCompound {
private final KList<BlockPopulator> populators;
@Getter
private final LoaderDimension rootDimension;
private final IrisDimension rootDimension;
@Getter
private final int threadCount = -1;
@@ -80,7 +80,7 @@ public class IrisEngineCompound implements EngineCompound {
@Setter
private boolean studio;
public IrisEngineCompound(IrisWorld world, LoaderDimension rootDimension, IrisData data, int maximumThreads) {
public IrisEngineCompound(IrisWorld world, IrisDimension rootDimension, IrisData data, int maximumThreads) {
wallClock = new AtomicRollingSequence(32);
this.rootDimension = rootDimension;
Iris.info("Initializing Engine Composite for " + world.name());
@@ -115,7 +115,7 @@ public class IrisEngineCompound implements EngineCompound {
for (int i = 0; i < engines.length; i++) {
IrisDimensionIndex index = rootDimension.getDimensionalComposite().get(i);
LoaderDimension dimension = data.getDimensionLoader().load(index.getDimension());
IrisDimension dimension = data.getDimensionLoader().load(index.getDimension());
// TODO: WARNING HEIGHT
engines[i] = new IrisEngine(new EngineTarget(world, dimension, data.copy(), (int) Math.floor(256D * (index.getWeight() / totalWeight)), index.isInverted(), threadDist), this, i);
engines[i].setMinHeight(buf);

View File

@@ -22,14 +22,14 @@ import com.volmit.iris.Iris;
import com.volmit.iris.engine.data.cache.Cache;
import com.volmit.iris.engine.framework.Engine;
import com.volmit.iris.engine.framework.EngineAssignedWorldManager;
import com.volmit.iris.engine.object.biome.LoaderBiome;
import com.volmit.iris.engine.object.biome.IrisBiome;
import com.volmit.iris.engine.object.block.IrisBlockDrops;
import com.volmit.iris.engine.object.common.IRare;
import com.volmit.iris.engine.object.engine.IrisEngineData;
import com.volmit.iris.engine.object.engine.IrisEngineSpawnerCooldown;
import com.volmit.iris.engine.object.entity.IrisEntitySpawn;
import com.volmit.iris.engine.object.regional.LoaderRegion;
import com.volmit.iris.engine.object.spawners.LoaderSpawner;
import com.volmit.iris.engine.object.regional.IrisRegion;
import com.volmit.iris.engine.object.spawners.IrisSpawner;
import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.collection.KMap;
import com.volmit.iris.util.format.Form;
@@ -165,8 +165,8 @@ public class IrisWorldManager extends EngineAssignedWorldManager {
}
Chunk c = cc[RNG.r.nextInt(cc.length)];
LoaderBiome biome = getEngine().getSurfaceBiome(c);
LoaderRegion region = getEngine().getRegion(c);
IrisBiome biome = getEngine().getSurfaceBiome(c);
IrisRegion region = getEngine().getRegion(c);
spawnIn(c, biome, region, maxGroups);
chunkCooldowns.put(Cache.key(c), M.ms());
}
@@ -179,7 +179,7 @@ public class IrisWorldManager extends EngineAssignedWorldManager {
energy = M.clip(energy, 1D, 1000D);
}
private void spawnIn(Chunk c, LoaderBiome biome, LoaderRegion region, int max) {
private void spawnIn(Chunk c, IrisBiome biome, IrisRegion region, int max) {
for(Entity i : c.getEntities())
{
if(i instanceof LivingEntity)
@@ -221,7 +221,7 @@ public class IrisWorldManager extends EngineAssignedWorldManager {
}
}
private Stream<IrisEntitySpawn> stream(LoaderSpawner s) {
private Stream<IrisEntitySpawn> stream(IrisSpawner s) {
for (IrisEntitySpawn i : s.getSpawns()) {
i.setReferenceSpawner(s);
}
@@ -243,12 +243,12 @@ public class IrisWorldManager extends EngineAssignedWorldManager {
return rarityTypes;
}
public boolean canSpawn(LoaderSpawner i) {
public boolean canSpawn(IrisSpawner i) {
return i.isValid(getEngine().getWorld().realWorld())
&& getCooldown(i).canSpawn(i.getMaximumRate());
}
private IrisEngineSpawnerCooldown getCooldown(LoaderSpawner i) {
private IrisEngineSpawnerCooldown getCooldown(IrisSpawner i) {
IrisEngineData ed = getEngine().getEngineData();
IrisEngineSpawnerCooldown cd = null;
@@ -298,7 +298,7 @@ public class IrisWorldManager extends EngineAssignedWorldManager {
if (e.getBlock().getWorld().equals(getTarget().getWorld().realWorld()) && getEngine().contains(e.getBlock().getLocation())) {
KList<ItemStack> d = new KList<>();
Runnable drop = () -> J.s(() -> d.forEach((i) -> e.getBlock().getWorld().dropItemNaturally(e.getBlock().getLocation().clone().add(0.5, 0.5, 0.5), i)));
LoaderBiome b = getEngine().getBiome(e.getBlock().getLocation());
IrisBiome b = getEngine().getBiome(e.getBlock().getLocation());
for (IrisBlockDrops i : b.getBlockDrops()) {
if (i.shouldDropFor(e.getBlock().getBlockData(), getData())) {
@@ -315,7 +315,7 @@ public class IrisWorldManager extends EngineAssignedWorldManager {
}
}
LoaderRegion r = getEngine().getRegion(e.getBlock().getLocation());
IrisRegion r = getEngine().getRegion(e.getBlock().getLocation());
for (IrisBlockDrops i : r.getBlockDrops()) {
if (i.shouldDropFor(e.getBlock().getBlockData(), getData())) {

View File

@@ -25,7 +25,7 @@ import com.volmit.iris.engine.framework.Engine;
import com.volmit.iris.engine.framework.EngineAssignedActuator;
import com.volmit.iris.util.hunk.Hunk;
import com.volmit.iris.util.hunk.view.BiomeGridHunkView;
import com.volmit.iris.engine.object.biome.LoaderBiome;
import com.volmit.iris.engine.object.biome.IrisBiome;
import com.volmit.iris.engine.object.biome.IrisBiomeCustom;
import com.volmit.iris.util.documentation.BlockCoordinates;
import com.volmit.iris.util.math.RNG;
@@ -66,7 +66,7 @@ public class IrisBiomeActuator extends EngineAssignedActuator<Biome> {
public void onActuate(int x, int z, Hunk<Biome> h, boolean multicore) {
PrecisionStopwatch p = PrecisionStopwatch.start();
int zf, maxHeight;
LoaderBiome ib;
IrisBiome ib;
for (int xf = 0; xf < h.getWidth(); xf++) {
for (zf = 0; zf < h.getDepth(); zf++) {

View File

@@ -23,7 +23,7 @@ import com.volmit.iris.engine.framework.Engine;
import com.volmit.iris.engine.framework.EngineAssignedActuator;
import com.volmit.iris.engine.framework.EngineDecorator;
import com.volmit.iris.util.hunk.Hunk;
import com.volmit.iris.engine.object.biome.LoaderBiome;
import com.volmit.iris.engine.object.biome.IrisBiome;
import com.volmit.iris.engine.object.carve.IrisCaveLayer;
import com.volmit.iris.util.documentation.BlockCoordinates;
import com.volmit.iris.util.math.RNG;
@@ -88,7 +88,7 @@ public class IrisDecorantActuator extends EngineAssignedActuator<BlockData> {
PrecisionStopwatch p = PrecisionStopwatch.start();
int j, realX, realZ, height;
LoaderBiome biome, cave;
IrisBiome biome, cave;
for (int i = 0; i < output.getWidth(); i++) {

View File

@@ -21,7 +21,7 @@ package com.volmit.iris.engine.actuator;
import com.volmit.iris.engine.framework.Engine;
import com.volmit.iris.engine.framework.EngineAssignedActuator;
import com.volmit.iris.util.hunk.Hunk;
import com.volmit.iris.engine.object.biome.LoaderBiome;
import com.volmit.iris.engine.object.biome.IrisBiome;
import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.documentation.BlockCoordinates;
import com.volmit.iris.util.math.RNG;
@@ -56,7 +56,7 @@ public class IrisTerrainIslandActuator extends EngineAssignedActuator<BlockData>
public void onActuate(int x, int z, Hunk<BlockData> h, boolean multicore) {
PrecisionStopwatch p = PrecisionStopwatch.start();
int i, zf, depth, surface, realX, realZ;
LoaderBiome biome;
IrisBiome biome;
KList<BlockData> blocks, fblocks;
int hi, lo;
double hh;

View File

@@ -21,7 +21,7 @@ package com.volmit.iris.engine.actuator;
import com.volmit.iris.engine.framework.Engine;
import com.volmit.iris.engine.framework.EngineAssignedActuator;
import com.volmit.iris.util.hunk.Hunk;
import com.volmit.iris.engine.object.biome.LoaderBiome;
import com.volmit.iris.engine.object.biome.IrisBiome;
import com.volmit.iris.util.parallel.BurstExecutor;
import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.documentation.BlockCoordinates;
@@ -82,7 +82,7 @@ public class IrisTerrainNormalActuator extends EngineAssignedActuator<BlockData>
@BlockCoordinates
public void terrainSliver(int x, int z, int xf, Hunk<BlockData> h) {
int i, depth, realX, realZ, hf, he, b, fdepth;
LoaderBiome biome;
IrisBiome biome;
KList<BlockData> blocks, fblocks;
for (int zf = 0; zf < h.getDepth(); zf++) {

View File

@@ -1,595 +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.data;
import com.volmit.iris.Iris;
import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.collection.KMap;
import com.volmit.iris.util.collection.KSet;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.block.data.BlockData;
import org.bukkit.block.data.type.Leaves;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class B {
private static final Material AIR_MATERIAL = Material.AIR;
private static final BlockData AIR = AIR_MATERIAL.createBlockData();
private static final KSet<String> nullBlockDataCache = new KSet<>();
private static final KSet<String> nullMaterialCache = new KSet<>();
private static final KMap<Material, Boolean> solidCache = new KMap<>();
private static final KMap<Material, Boolean> updatableCache = new KMap<>();
private static final KMap<Material, Boolean> foliageCache = new KMap<>();
private static final KMap<Material, Boolean> litCache = new KMap<>();
private static final KMap<Material, Boolean> decorantCache = new KMap<>();
private static final KMap<Material, Boolean> storageCache = new KMap<>();
private static final KMap<Material, Boolean> storageChestCache = new KMap<>();
private static final KMap<String, BlockData> blockDataCache = new KMap<>();
private static final KMap<String, Material> materialCache = new KMap<>();
public static boolean isWater(BlockData b) {
return b.getMaterial().equals(Material.WATER);
}
public static BlockData getAir() {
return AIR;
}
public static Material getMaterial(String bdx) {
Material mat = getMaterialOrNull(bdx);
if (mat != null) {
return mat;
}
return AIR_MATERIAL;
}
public static Material getMaterialOrNull(String bdxx) {
String bx = bdxx.trim().toUpperCase();
if (nullMaterialCache.contains(bx)) {
return null;
}
Material mat = materialCache.get(bx);
if (mat != null) {
return mat;
}
try {
Material mm = Material.valueOf(bx);
materialCache.put(bx, mm);
return mm;
} catch (Throwable e) {
Iris.reportError(e);
nullMaterialCache.add(bx);
return null;
}
}
public static boolean isSolid(BlockData mat) {
return isSolid(mat.getMaterial());
}
public static boolean isSolid(Material mat) {
Boolean solid = solidCache.get(mat);
if (solid != null) {
return solid;
}
solid = mat.isSolid();
solidCache.put(mat, solid);
return solid;
}
public static BlockData getOrNull(String bdxf) {
try {
String bd = bdxf.trim();
BlockData bdx = parseBlockData(bd);
if (bdx == null) {
Iris.warn("Unknown Block Data '" + bd + "'");
return AIR;
}
return bdx;
} catch (Throwable e) {
Iris.reportError(e);
Iris.warn("Unknown Block Data '" + bdxf + "'");
}
return null;
}
public static BlockData get(String bdxf) {
BlockData bd = getOrNull(bdxf);
if (bd != null) {
return bd;
}
return AIR;
}
private static BlockData parseBlockDataOrNull(String ix) {
if (nullBlockDataCache.contains(ix)) {
return null;
}
try {
BlockData bb = blockDataCache.get(ix);
if (bb != null) {
return bb;
}
BlockData bx = null;
if (ix.startsWith("oraxen:") && Iris.linkOraxen.supported()) {
bx = Iris.linkOraxen.getBlockDataFor(ix.split("\\Q:\\E")[1]);
}
if (bx == null) {
bx = Bukkit.createBlockData(ix);
}
if (bx instanceof Leaves) {
((Leaves) bx).setPersistent(true);
}
blockDataCache.put(ix, bx);
return bx;
} catch (Exception e) {
//Iris.reportError(e);
Iris.debug("Failed to load block \"" + ix + "\"");
String block = ix.contains(":") ? ix.split(":")[1].toLowerCase() : ix.toLowerCase();
String state = block.contains("[") ? block.split("\\[")[1].split("\\]")[0] : "";
Map<String, String> stateMap = new HashMap<>();
if (!state.equals("")) {
Arrays.stream(state.split(",")).forEach(s -> {
stateMap.put(s.split("=")[0], s.split("=")[1]);
});
}
block = block.split("\\[")[0];
switch (block) {
case "cauldron" -> block = "water_cauldron"; //Would fail to load if it has a level parameter
case "grass_path" -> block = "dirt_path";
case "concrete" -> block = "white_concrete";
case "wool" -> block = "white_wool";
case "beetroots" -> {
if (stateMap.containsKey("age")) {
String updated = stateMap.get("age");
switch (updated) {
case "7" -> updated = "3";
case "3", "4", "5" -> updated = "2";
case "1", "2" -> updated = "1";
}
stateMap.put("age", updated);
}
}
}
Map<String, String> newStates = new HashMap<>();
for (String key : stateMap.keySet()) { //Iterate through every state and check if its valid
try {
String newState = block + "[" + key + "=" + stateMap.get(key) + "]";
Bukkit.createBlockData(newState);
//If we get to here, the state is okay so we can use it
newStates.put(key, stateMap.get(key));
} catch (IllegalArgumentException ignored) { }
}
//Combine all the "good" states again
state = newStates.entrySet().stream().map(entry -> entry.getKey() + "=" + entry.getValue()).collect(Collectors.joining(","));
if (!state.equals("")) state = "[" + state + "]";
String newBlock = block + state;
Iris.debug("Converting " + ix + " to " + newBlock);
try {
BlockData bd = Bukkit.createBlockData(newBlock);
blockDataCache.put(ix, bd);
return bd;
} catch (Throwable e1) {
Iris.reportError(e1);
}
nullBlockDataCache.add(ix);
return null;
}
}
private static BlockData parseBlockData(String ix) {
BlockData bd = parseBlockDataOrNull(ix);
if (bd != null) {
return bd;
}
return AIR;
}
public static boolean isStorage(BlockData mat) {
Material mm = mat.getMaterial();
Boolean f = storageCache.get(mm);
if (f != null) {
return f;
}
f = mm.equals(B.getMaterial("CHEST"))
|| mm.equals(B.getMaterial("TRAPPED_CHEST"))
|| mm.equals(B.getMaterial("SHULKER_BOX"))
|| mm.equals(B.getMaterial("WHITE_SHULKER_BOX"))
|| mm.equals(B.getMaterial("ORANGE_SHULKER_BOX"))
|| mm.equals(B.getMaterial("MAGENTA_SHULKER_BOX"))
|| mm.equals(B.getMaterial("LIGHT_BLUE_SHULKER_BOX"))
|| mm.equals(B.getMaterial("YELLOW_SHULKER_BOX"))
|| mm.equals(B.getMaterial("LIME_SHULKER_BOX"))
|| mm.equals(B.getMaterial("PINK_SHULKER_BOX"))
|| mm.equals(B.getMaterial("GRAY_SHULKER_BOX"))
|| mm.equals(B.getMaterial("LIGHT_GRAY_SHULKER_BOX"))
|| mm.equals(B.getMaterial("CYAN_SHULKER_BOX"))
|| mm.equals(B.getMaterial("PURPLE_SHULKER_BOX"))
|| mm.equals(B.getMaterial("BLUE_SHULKER_BOX"))
|| mm.equals(B.getMaterial("BROWN_SHULKER_BOX"))
|| mm.equals(B.getMaterial("GREEN_SHULKER_BOX"))
|| mm.equals(B.getMaterial("RED_SHULKER_BOX"))
|| mm.equals(B.getMaterial("BLACK_SHULKER_BOX"))
|| mm.equals(B.getMaterial("BARREL"))
|| mm.equals(B.getMaterial("DISPENSER"))
|| mm.equals(B.getMaterial("DROPPER"))
|| mm.equals(B.getMaterial("HOPPER"))
|| mm.equals(B.getMaterial("FURNACE"))
|| mm.equals(B.getMaterial("BLAST_FURNACE"))
|| mm.equals(B.getMaterial("SMOKER"));
storageCache.put(mm, f);
return f;
}
public static boolean isStorageChest(BlockData mat) {
if (!isStorage(mat)) {
return false;
}
Material mm = mat.getMaterial();
Boolean f = storageChestCache.get(mm);
if (f != null) {
return f;
}
f = mm.equals(B.getMaterial("CHEST"))
|| mm.equals(B.getMaterial("TRAPPED_CHEST"))
|| mm.equals(B.getMaterial("SHULKER_BOX"))
|| mm.equals(B.getMaterial("WHITE_SHULKER_BOX"))
|| mm.equals(B.getMaterial("ORANGE_SHULKER_BOX"))
|| mm.equals(B.getMaterial("MAGENTA_SHULKER_BOX"))
|| mm.equals(B.getMaterial("LIGHT_BLUE_SHULKER_BOX"))
|| mm.equals(B.getMaterial("YELLOW_SHULKER_BOX"))
|| mm.equals(B.getMaterial("LIME_SHULKER_BOX"))
|| mm.equals(B.getMaterial("PINK_SHULKER_BOX"))
|| mm.equals(B.getMaterial("GRAY_SHULKER_BOX"))
|| mm.equals(B.getMaterial("LIGHT_GRAY_SHULKER_BOX"))
|| mm.equals(B.getMaterial("CYAN_SHULKER_BOX"))
|| mm.equals(B.getMaterial("PURPLE_SHULKER_BOX"))
|| mm.equals(B.getMaterial("BLUE_SHULKER_BOX"))
|| mm.equals(B.getMaterial("BROWN_SHULKER_BOX"))
|| mm.equals(B.getMaterial("GREEN_SHULKER_BOX"))
|| mm.equals(B.getMaterial("RED_SHULKER_BOX"))
|| mm.equals(B.getMaterial("BLACK_SHULKER_BOX"))
|| mm.equals(B.getMaterial("BARREL"))
|| mm.equals(B.getMaterial("DISPENSER"))
|| mm.equals(B.getMaterial("DROPPER"))
|| mm.equals(B.getMaterial("HOPPER"));
storageChestCache.put(mm, f);
return f;
}
public static boolean isLit(BlockData mat) {
Material mm = mat.getMaterial();
Boolean f = litCache.get(mm);
if (f != null) {
return f;
}
f = mm.equals(B.getMaterial("GLOWSTONE"))
|| mm.equals(B.getMaterial("END_ROD"))
|| mm.equals(B.getMaterial("SOUL_SAND"))
|| mm.equals(B.getMaterial("TORCH"))
|| mm.equals(Material.REDSTONE_TORCH)
|| mm.equals(B.getMaterial("SOUL_TORCH"))
|| mm.equals(Material.REDSTONE_WALL_TORCH)
|| mm.equals(Material.WALL_TORCH)
|| mm.equals(B.getMaterial("SOUL_WALL_TORCH"))
|| mm.equals(B.getMaterial("LANTERN"))
|| mm.equals(Material.JACK_O_LANTERN)
|| mm.equals(Material.REDSTONE_LAMP)
|| mm.equals(Material.MAGMA_BLOCK)
|| mm.equals(B.getMaterial("SHROOMLIGHT"))
|| mm.equals(B.getMaterial("SEA_LANTERN"))
|| mm.equals(B.getMaterial("SOUL_LANTERN"))
|| mm.equals(Material.FIRE)
|| mm.equals(B.getMaterial("SOUL_FIRE"))
|| mm.equals(B.getMaterial("SEA_PICKLE"))
|| mm.equals(Material.BREWING_STAND)
|| mm.equals(Material.REDSTONE_ORE);
litCache.put(mm, f);
return f;
}
public static boolean isUpdatable(BlockData mat) {
Boolean u = updatableCache.get(mat.getMaterial());
if (u != null) {
return u;
}
u = isLit(mat) || isStorage(mat);
updatableCache.put(mat.getMaterial(), u);
return u;
}
public static boolean isFoliage(Material d) {
return isFoliage(d.createBlockData());
}
public static boolean isFoliage(BlockData d) {
Boolean f = foliageCache.get(d.getMaterial());
if (f != null) {
return f;
}
if (isFluid(d) || isAir(d) || isSolid(d)) {
foliageCache.put(d.getMaterial(), false);
return false;
}
Material mat = d.getMaterial();
f = mat.equals(Material.POPPY)
|| mat.equals(Material.DANDELION)
|| mat.equals(B.getMaterial("CORNFLOWER"))
|| mat.equals(B.getMaterial("SWEET_BERRY_BUSH"))
|| mat.equals(B.getMaterial("CRIMSON_ROOTS"))
|| mat.equals(B.getMaterial("WARPED_ROOTS"))
|| mat.equals(B.getMaterial("NETHER_SPROUTS"))
|| mat.equals(B.getMaterial("ALLIUM"))
|| mat.equals(B.getMaterial("AZURE_BLUET"))
|| mat.equals(B.getMaterial("BLUE_ORCHID"))
|| mat.equals(B.getMaterial("POPPY"))
|| mat.equals(B.getMaterial("DANDELION"))
|| mat.equals(B.getMaterial("OXEYE_DAISY"))
|| mat.equals(B.getMaterial("LILY_OF_THE_VALLEY"))
|| mat.equals(B.getMaterial("WITHER_ROSE"))
|| mat.equals(Material.DARK_OAK_SAPLING)
|| mat.equals(Material.ACACIA_SAPLING)
|| mat.equals(Material.JUNGLE_SAPLING)
|| mat.equals(Material.BIRCH_SAPLING)
|| mat.equals(Material.SPRUCE_SAPLING)
|| mat.equals(Material.OAK_SAPLING)
|| mat.equals(Material.ORANGE_TULIP)
|| mat.equals(Material.PINK_TULIP)
|| mat.equals(Material.RED_TULIP)
|| mat.equals(Material.WHITE_TULIP)
|| mat.equals(Material.FERN)
|| mat.equals(Material.LARGE_FERN)
|| mat.equals(Material.GRASS)
|| mat.equals(Material.TALL_GRASS);
foliageCache.put(d.getMaterial(), f);
return f;
}
public static boolean canPlaceOnto(Material mat, Material onto) {
String key = mat.name() + "" + onto.name();
if (isFoliage(mat)) {
if (!isFoliagePlantable(onto)) {
return false;
}
}
if (onto.equals(Material.AIR) || onto.equals(B.getMaterial("CAVE_AIR")) || onto.equals(B.getMaterial("VOID_AIR"))) {
return false;
}
if (onto.equals(Material.GRASS_BLOCK) && mat.equals(Material.DEAD_BUSH)) {
return false;
}
if (onto.equals(Material.DIRT_PATH)) {
if (!mat.isSolid()) {
return false;
}
}
if (onto.equals(Material.ACACIA_LEAVES)
|| onto.equals(Material.BIRCH_LEAVES)
|| onto.equals(Material.DARK_OAK_LEAVES)
|| onto.equals(Material.JUNGLE_LEAVES)
|| onto.equals(Material.OAK_LEAVES)
|| onto.equals(Material.SPRUCE_LEAVES)) {
return mat.isSolid();
}
return true;
}
public static boolean isDecorant(BlockData m) {
Material mm = m.getMaterial();
Boolean f = decorantCache.get(mm);
if (f != null) {
return f;
}
f = mm.equals(Material.GRASS)
|| mm.equals(Material.TALL_GRASS)
|| mm.equals(Material.FERN)
|| mm.equals(Material.LARGE_FERN)
|| mm.equals(B.getMaterial("CORNFLOWER"))
|| mm.equals(Material.SUNFLOWER)
|| mm.equals(Material.CHORUS_FLOWER)
|| mm.equals(Material.POPPY)
|| mm.equals(Material.DANDELION)
|| mm.equals(Material.OXEYE_DAISY)
|| mm.equals(Material.ORANGE_TULIP)
|| mm.equals(Material.PINK_TULIP)
|| mm.equals(Material.RED_TULIP)
|| mm.equals(Material.WHITE_TULIP)
|| mm.equals(Material.LILAC)
|| mm.equals(Material.DEAD_BUSH)
|| mm.equals(B.getMaterial("SWEET_BERRY_BUSH"))
|| mm.equals(Material.ROSE_BUSH)
|| mm.equals(B.getMaterial("WITHER_ROSE"))
|| mm.equals(Material.ALLIUM)
|| mm.equals(Material.BLUE_ORCHID)
|| mm.equals(B.getMaterial("LILY_OF_THE_VALLEY"))
|| mm.equals(B.getMaterial("CRIMSON_FUNGUS"))
|| mm.equals(B.getMaterial("WARPED_FUNGUS"))
|| mm.equals(Material.RED_MUSHROOM)
|| mm.equals(Material.BROWN_MUSHROOM)
|| mm.equals(B.getMaterial("CRIMSON_ROOTS"))
|| mm.equals(B.getMaterial("AZURE_BLUET"))
|| mm.equals(B.getMaterial("WEEPING_VINES"))
|| mm.equals(B.getMaterial("WEEPING_VINES_PLANT"))
|| mm.equals(B.getMaterial("WARPED_ROOTS"))
|| mm.equals(B.getMaterial("NETHER_SPROUTS"))
|| mm.equals(B.getMaterial("TWISTING_VINES"))
|| mm.equals(B.getMaterial("TWISTING_VINES_PLANT"))
|| mm.equals(Material.SUGAR_CANE)
|| mm.equals(Material.WHEAT)
|| mm.equals(Material.POTATOES)
|| mm.equals(Material.CARROTS)
|| mm.equals(Material.BEETROOTS)
|| mm.equals(Material.NETHER_WART)
|| mm.equals(B.getMaterial("SEA_PICKLE"))
|| mm.equals(B.getMaterial("SEAGRASS"))
|| mm.equals(B.getMaterial("ACACIA_BUTTON"))
|| mm.equals(B.getMaterial("BIRCH_BUTTON"))
|| mm.equals(B.getMaterial("CRIMSON_BUTTON"))
|| mm.equals(B.getMaterial("DARK_OAK_BUTTON"))
|| mm.equals(B.getMaterial("JUNGLE_BUTTON"))
|| mm.equals(B.getMaterial("OAK_BUTTON"))
|| mm.equals(B.getMaterial("POLISHED_BLACKSTONE_BUTTON"))
|| mm.equals(B.getMaterial("SPRUCE_BUTTON"))
|| mm.equals(B.getMaterial("STONE_BUTTON"))
|| mm.equals(B.getMaterial("WARPED_BUTTON"))
|| mm.equals(Material.TORCH)
|| mm.equals(B.getMaterial("SOUL_TORCH"));
decorantCache.put(mm, f);
return f;
}
public static KList<BlockData> get(KList<String> find) {
KList<BlockData> b = new KList<>();
for (String i : find) {
BlockData bd = get(i);
if (bd != null) {
b.add(bd);
}
}
return b;
}
public static boolean isFoliagePlantable(BlockData d) {
return d.getMaterial().equals(Material.GRASS_BLOCK)
|| d.getMaterial().equals(Material.ROOTED_DIRT)
|| d.getMaterial().equals(Material.DIRT)
|| d.getMaterial().equals(Material.COARSE_DIRT)
|| d.getMaterial().equals(Material.PODZOL);
}
public static boolean isFoliagePlantable(Material d) {
return d.equals(Material.GRASS_BLOCK)
|| d.equals(Material.DIRT)
|| d.equals(Material.ROOTED_DIRT)
|| d.equals(Material.COARSE_DIRT)
|| d.equals(Material.PODZOL);
}
public static boolean isFluid(BlockData d) {
return d.getMaterial().equals(Material.WATER) || d.getMaterial().equals(Material.LAVA);
}
public static boolean isAirOrFluid(BlockData d) {
return isAir(d) || isFluid(d);
}
public static boolean isAir(BlockData d) {
if (d == null) {
return true;
}
return d.getMaterial().equals(Material.AIR) || d.getMaterial().equals(Material.CAVE_AIR) || d.getMaterial().equals(Material.VOID_AIR);
}
public static String[] getBlockTypes() {
KList<String> bt = new KList<>();
for (Material i : Material.values()) {
if (i.isBlock()) {
String v = i.createBlockData().getAsString(true);
if (v.contains("[")) {
v = v.split("\\Q[\\E")[0];
}
if (v.contains(":")) {
v = v.split("\\Q:\\E")[1];
}
bt.add(v);
}
}
return bt.toArray(new String[0]);
}
public static String[] getItemTypes() {
KList<String> bt = new KList<>();
for (Material i : Material.values()) {
String v = i.name().toLowerCase().trim();
bt.add(v);
}
if (Iris.linkOraxen.supported()) {
for (String i : Iris.linkOraxen.getItemTypes()) {
bt.add("oraxen:" + i);
}
}
return bt.toArray(new String[0]);
}
}

View File

@@ -1,77 +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.data;
import com.volmit.iris.util.collection.KList;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
public class DataPalette<T> {
private final KList<T> palette;
public DataPalette() {
this(new KList<>(16));
}
public DataPalette(KList<T> palette) {
this.palette = palette;
}
public KList<T> getPalette() {
return palette;
}
public int getIndex(T t) {
int v = 0;
synchronized (palette) {
v = palette.indexOf(t);
if (v == -1) {
v = palette.size();
palette.add(t);
}
}
return v;
}
public void write(IOAdapter<T> adapter, DataOutputStream dos) throws IOException {
synchronized (palette) {
dos.writeShort(getPalette().size() + Short.MIN_VALUE);
for (T t : palette) {
adapter.write(t, dos);
}
}
}
public static <T> DataPalette<T> getPalette(IOAdapter<T> adapter, DataInputStream din) throws IOException {
KList<T> palette = new KList<>();
int s = din.readShort() - Short.MIN_VALUE;
for (int i = 0; i < s; i++) {
palette.add(adapter.read(din));
}
return new DataPalette<>(palette);
}
}

View File

@@ -1,25 +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.data;
import com.volmit.iris.core.project.loader.IrisData;
public interface DataProvider {
IrisData getData();
}

View File

@@ -1,29 +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.data;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
public interface IOAdapter<T> {
void write(T t, DataOutputStream dos) throws IOException;
T read(DataInputStream din) throws IOException;
}

View File

@@ -19,8 +19,8 @@
package com.volmit.iris.engine.data.chunk;
import com.volmit.iris.core.nms.BiomeBaseInjector;
import com.volmit.iris.engine.data.mca.Chunk;
import com.volmit.iris.engine.data.mca.NBTWorld;
import com.volmit.iris.util.nbt.mca.Chunk;
import com.volmit.iris.util.nbt.mca.NBTWorld;
import lombok.AllArgsConstructor;
import lombok.Builder;
import org.bukkit.Material;

View File

@@ -1,701 +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.data.mca;
import com.volmit.iris.engine.data.nbt.io.NBTDeserializer;
import com.volmit.iris.engine.data.nbt.io.NBTSerializer;
import com.volmit.iris.engine.data.nbt.io.NamedTag;
import com.volmit.iris.engine.data.nbt.tag.CompoundTag;
import com.volmit.iris.engine.data.nbt.tag.ListTag;
import java.io.*;
import java.util.Arrays;
import java.util.concurrent.atomic.AtomicReferenceArray;
import static com.volmit.iris.engine.data.mca.LoadFlags.*;
public class Chunk {
public static final int DEFAULT_DATA_VERSION = 1628;
private boolean partial;
private int lastMCAUpdate;
private CompoundTag data;
private int dataVersion;
private long lastUpdate;
private long inhabitedTime;
private int[] biomes;
private CompoundTag heightMaps;
private CompoundTag carvingMasks;
private final AtomicReferenceArray<Section> sections = new AtomicReferenceArray<>(16);
private ListTag<CompoundTag> entities;
private ListTag<CompoundTag> tileEntities;
private ListTag<CompoundTag> tileTicks;
private ListTag<CompoundTag> liquidTicks;
private ListTag<ListTag<?>> lights;
private ListTag<ListTag<?>> liquidsToBeTicked;
private ListTag<ListTag<?>> toBeTicked;
private ListTag<ListTag<?>> postProcessing;
private String status;
private CompoundTag structures;
Chunk(int lastMCAUpdate) {
this.lastMCAUpdate = lastMCAUpdate;
}
/**
* Create a new chunk based on raw base data from a region file.
*
* @param data The raw base data to be used.
*/
public Chunk(CompoundTag data) {
this.data = data;
initReferences(ALL_DATA);
}
private void initReferences(long loadFlags) {
if (data == null) {
throw new NullPointerException("data cannot be null");
}
CompoundTag level;
if ((level = data.getCompoundTag("Level")) == null) {
throw new IllegalArgumentException("data does not contain \"Level\" tag");
}
dataVersion = data.getInt("DataVersion");
inhabitedTime = level.getLong("InhabitedTime");
lastUpdate = level.getLong("LastUpdate");
if ((loadFlags & BIOMES) != 0) {
biomes = level.getIntArray("Biomes");
}
if ((loadFlags & HEIGHTMAPS) != 0) {
heightMaps = level.getCompoundTag("Heightmaps");
}
if ((loadFlags & CARVING_MASKS) != 0) {
carvingMasks = level.getCompoundTag("CarvingMasks");
}
if ((loadFlags & ENTITIES) != 0) {
entities = level.containsKey("Entities") ? level.getListTag("Entities").asCompoundTagList() : null;
}
if ((loadFlags & TILE_ENTITIES) != 0) {
tileEntities = level.containsKey("TileEntities") ? level.getListTag("TileEntities").asCompoundTagList() : null;
}
if ((loadFlags & TILE_TICKS) != 0) {
tileTicks = level.containsKey("TileTicks") ? level.getListTag("TileTicks").asCompoundTagList() : null;
}
if ((loadFlags & LIQUID_TICKS) != 0) {
liquidTicks = level.containsKey("LiquidTicks") ? level.getListTag("LiquidTicks").asCompoundTagList() : null;
}
if ((loadFlags & LIGHTS) != 0) {
lights = level.containsKey("Lights") ? level.getListTag("Lights").asListTagList() : null;
}
if ((loadFlags & LIQUIDS_TO_BE_TICKED) != 0) {
liquidsToBeTicked = level.containsKey("LiquidsToBeTicked") ? level.getListTag("LiquidsToBeTicked").asListTagList() : null;
}
if ((loadFlags & TO_BE_TICKED) != 0) {
toBeTicked = level.containsKey("ToBeTicked") ? level.getListTag("ToBeTicked").asListTagList() : null;
}
if ((loadFlags & POST_PROCESSING) != 0) {
postProcessing = level.containsKey("PostProcessing") ? level.getListTag("PostProcessing").asListTagList() : null;
}
status = level.getString("Status");
if ((loadFlags & STRUCTURES) != 0) {
structures = level.getCompoundTag("Structures");
}
if ((loadFlags & (BLOCK_LIGHTS | BLOCK_STATES | SKY_LIGHT)) != 0 && level.containsKey("Sections")) {
for (CompoundTag section : level.getListTag("Sections").asCompoundTagList()) {
int sectionIndex = section.getByte("Y");
if (sectionIndex > 15 || sectionIndex < 0) {
continue;
}
Section newSection = new Section(section, dataVersion, loadFlags);
if (newSection.isEmpty()) {
continue;
}
sections.set(sectionIndex, newSection);
}
}
// If we haven't requested the full set of data we can drop the underlying raw data to let the GC handle it.
if (loadFlags != ALL_DATA) {
data = null;
partial = true;
} else {
partial = false;
}
}
/**
* Serializes this chunk to a <code>RandomAccessFile</code>.
*
* @param raf The RandomAccessFile to be written to.
* @param xPos The x-coordinate of the chunk.
* @param zPos The z-coodrinate of the chunk.
* @return The amount of bytes written to the RandomAccessFile.
* @throws UnsupportedOperationException When something went wrong during writing.
* @throws IOException When something went wrong during writing.
*/
public int serialize(RandomAccessFile raf, int xPos, int zPos) throws IOException {
if (partial) {
throw new UnsupportedOperationException("Partially loaded chunks cannot be serialized");
}
ByteArrayOutputStream baos = new ByteArrayOutputStream(4096);
try (BufferedOutputStream nbtOut = new BufferedOutputStream(CompressionType.ZLIB.compress(baos))) {
new NBTSerializer(false).toStream(new NamedTag(null, updateHandle(xPos, zPos)), nbtOut);
}
byte[] rawData = baos.toByteArray();
raf.writeInt(rawData.length + 1); // including the byte to store the compression type
raf.writeByte(CompressionType.ZLIB.getID());
raf.write(rawData);
return rawData.length + 5;
}
/**
* Reads chunk data from a RandomAccessFile. The RandomAccessFile must already be at the correct position.
*
* @param raf The RandomAccessFile to read the chunk data from.
* @throws IOException When something went wrong during reading.
*/
public void deserialize(RandomAccessFile raf) throws IOException {
deserialize(raf, ALL_DATA);
}
/**
* Reads chunk data from a RandomAccessFile. The RandomAccessFile must already be at the correct position.
*
* @param raf The RandomAccessFile to read the chunk data from.
* @param loadFlags A logical or of {@link LoadFlags} constants indicating what data should be loaded
* @throws IOException When something went wrong during reading.
*/
public void deserialize(RandomAccessFile raf, long loadFlags) throws IOException {
byte compressionTypeByte = raf.readByte();
CompressionType compressionType = CompressionType.getFromID(compressionTypeByte);
if (compressionType == null) {
throw new IOException("invalid compression type " + compressionTypeByte);
}
BufferedInputStream dis = new BufferedInputStream(compressionType.decompress(new FileInputStream(raf.getFD())));
NamedTag tag = new NBTDeserializer(false).fromStream(dis);
if (tag != null && tag.getTag() instanceof CompoundTag) {
data = (CompoundTag) tag.getTag();
initReferences(loadFlags);
} else {
throw new IOException("invalid data tag: " + (tag == null ? "null" : tag.getClass().getName()));
}
}
/**
* @deprecated Use {@link #getBiomeAt(int, int, int)} instead
*/
@Deprecated
public int getBiomeAt(int blockX, int blockZ) {
if (dataVersion < 2202) {
if (biomes == null || biomes.length != 256) {
return -1;
}
return biomes[getBlockIndex(blockX, blockZ)];
} else {
throw new IllegalStateException("cannot get biome using Chunk#getBiomeAt(int,int) from biome data with DataVersion of 2202 or higher, use Chunk#getBiomeAt(int,int,int) instead");
}
}
/**
* Fetches a biome id at a specific block in this chunk.
* The coordinates can be absolute coordinates or relative to the region or chunk.
*
* @param blockX The x-coordinate of the block.
* @param blockY The y-coordinate of the block.
* @param blockZ The z-coordinate of the block.
* @return The biome id or -1 if the biomes are not correctly initialized.
*/
public int getBiomeAt(int blockX, int blockY, int blockZ) {
if (dataVersion < 2202) {
if (biomes == null || biomes.length != 256) {
return -1;
}
return biomes[getBlockIndex(blockX, blockZ)];
} else {
if (biomes == null || biomes.length != 1024) {
return -1;
}
int biomeX = (blockX & 0xF) >> 2;
int biomeY = (blockY & 0xF) >> 2;
int biomeZ = (blockZ & 0xF) >> 2;
return biomes[getBiomeIndex(biomeX, biomeY, biomeZ)];
}
}
@Deprecated
public void setBiomeAt(int blockX, int blockZ, int biomeID) {
if (dataVersion < 2202) {
if (biomes == null || biomes.length != 256) {
biomes = new int[256];
Arrays.fill(biomes, -1);
}
biomes[getBlockIndex(blockX, blockZ)] = biomeID;
} else {
if (biomes == null || biomes.length != 1024) {
biomes = new int[1024];
Arrays.fill(biomes, -1);
}
int biomeX = (blockX & 0xF) >> 2;
int biomeZ = (blockZ & 0xF) >> 2;
for (int y = 0; y < 64; y++) {
biomes[getBiomeIndex(biomeX, y, biomeZ)] = biomeID;
}
}
}
/**
* Sets a biome id at a specific block column.
* The coordinates can be absolute coordinates or relative to the region or chunk.
*
* @param blockX The x-coordinate of the block column.
* @param blockZ The z-coordinate of the block column.
* @param biomeID The biome id to be set.
* When set to a negative number, Minecraft will replace it with the block column's default biome.
*/
public void setBiomeAt(int blockX, int blockY, int blockZ, int biomeID) {
if (dataVersion < 2202) {
if (biomes == null || biomes.length != 256) {
biomes = new int[256];
Arrays.fill(biomes, -1);
}
biomes[getBlockIndex(blockX, blockZ)] = biomeID;
} else {
if (biomes == null || biomes.length != 1024) {
biomes = new int[1024];
Arrays.fill(biomes, -1);
}
int biomeX = (blockX & 0xF) >> 2;
int biomeZ = (blockZ & 0xF) >> 2;
biomes[getBiomeIndex(biomeX, blockY, biomeZ)] = biomeID;
}
}
int getBiomeIndex(int biomeX, int biomeY, int biomeZ) {
return biomeY * 64 + biomeZ * 4 + biomeX;
}
public CompoundTag getBlockStateAt(int blockX, int blockY, int blockZ) {
Section section = sections.get(MCAUtil.blockToChunk(blockY));
if (section == null) {
return null;
}
return section.getBlockStateAt(blockX, blockY, blockZ);
}
/**
* Sets a block state at a specific location.
* The block coordinates can be absolute or relative to the region or chunk.
*
* @param blockX The x-coordinate of the block.
* @param blockY The y-coordinate of the block.
* @param blockZ The z-coordinate of the block.
* @param state The block state to be set.
* @param cleanup When <code>true</code>, it will cleanup all palettes of this chunk.
* This option should only be used moderately to avoid unnecessary recalculation of the palette indices.
* Recalculating the Palette should only be executed once right before saving the Chunk to file.
*/
public void setBlockStateAt(int blockX, int blockY, int blockZ, CompoundTag state, boolean cleanup) {
int sectionIndex = MCAUtil.blockToChunk(blockY);
Section section = sections.get(sectionIndex);
if (section == null) {
section = Section.newSection();
sections.set(sectionIndex, section);
}
section.setBlockStateAt(blockX, blockY, blockZ, state, cleanup);
}
/**
* @return The DataVersion of this chunk.
*/
public int getDataVersion() {
return dataVersion;
}
/**
* Sets the DataVersion of this chunk. This does not check if the data of this chunk conforms
* to that DataVersion, that is the responsibility of the developer.
*
* @param dataVersion The DataVersion to be set.
*/
public void setDataVersion(int dataVersion) {
this.dataVersion = dataVersion;
}
/**
* @return The timestamp when this region file was last updated in seconds since 1970-01-01.
*/
public int getLastMCAUpdate() {
return lastMCAUpdate;
}
/**
* Sets the timestamp when this region file was last updated in seconds since 1970-01-01.
*
* @param lastMCAUpdate The time in seconds since 1970-01-01.
*/
public void setLastMCAUpdate(int lastMCAUpdate) {
this.lastMCAUpdate = lastMCAUpdate;
}
/**
* @return The generation station of this chunk.
*/
public String getStatus() {
return status;
}
/**
* Sets the generation status of this chunk.
*
* @param status The generation status of this chunk.
*/
public void setStatus(String status) {
this.status = status;
}
/**
* Fetches the section at the given y-coordinate.
*
* @param sectionY The y-coordinate of the section in this chunk ranging from 0 to 15.
* @return The Section.
*/
public Section getSection(int sectionY) {
return sections.get(sectionY);
}
/**
* Sets a section at a givesn y-coordinate
*
* @param sectionY The y-coordinate of the section in this chunk ranging from 0 to 15.
* @param section The section to be set.
*/
public void setSection(int sectionY, Section section) {
sections.set(sectionY, section);
}
/**
* @return The timestamp when this chunk was last updated as a UNIX timestamp.
*/
public long getLastUpdate() {
return lastUpdate;
}
/**
* Sets the time when this chunk was last updated as a UNIX timestamp.
*
* @param lastUpdate The UNIX timestamp.
*/
public void setLastUpdate(long lastUpdate) {
this.lastUpdate = lastUpdate;
}
/**
* @return The cumulative amount of time players have spent in this chunk in ticks.
*/
public long getInhabitedTime() {
return inhabitedTime;
}
/**
* Sets the cumulative amount of time players have spent in this chunk in ticks.
*
* @param inhabitedTime The time in ticks.
*/
public void setInhabitedTime(long inhabitedTime) {
this.inhabitedTime = inhabitedTime;
}
/**
* @return A matrix of biome IDs for all block columns in this chunk.
*/
public int[] getBiomes() {
return biomes;
}
/**
* Sets the biome IDs for this chunk.
*
* @param biomes The biome ID matrix of this chunk. Must have a length of <code>256</code>.
* @throws IllegalArgumentException When the biome matrix does not have a length of <code>256</code>
* or is <code>null</code>
*/
public void setBiomes(int[] biomes) {
if (biomes != null) {
if (dataVersion < 2202 && biomes.length != 256 || dataVersion >= 2202 && biomes.length != 1024) {
throw new IllegalArgumentException("biomes array must have a length of " + (dataVersion < 2202 ? "256" : "1024"));
}
}
this.biomes = biomes;
}
/**
* @return The height maps of this chunk.
*/
public CompoundTag getHeightMaps() {
return heightMaps;
}
/**
* Sets the height maps of this chunk.
*
* @param heightMaps The height maps.
*/
public void setHeightMaps(CompoundTag heightMaps) {
this.heightMaps = heightMaps;
}
/**
* @return The carving masks of this chunk.
*/
public CompoundTag getCarvingMasks() {
return carvingMasks;
}
/**
* Sets the carving masks of this chunk.
*
* @param carvingMasks The carving masks.
*/
public void setCarvingMasks(CompoundTag carvingMasks) {
this.carvingMasks = carvingMasks;
}
/**
* @return The entities of this chunk.
*/
public ListTag<CompoundTag> getEntities() {
return entities;
}
/**
* Sets the entities of this chunk.
*
* @param entities The entities.
*/
public void setEntities(ListTag<CompoundTag> entities) {
this.entities = entities;
}
/**
* @return The tile entities of this chunk.
*/
public ListTag<CompoundTag> getTileEntities() {
return tileEntities;
}
/**
* Sets the tile entities of this chunk.
*
* @param tileEntities The tile entities of this chunk.
*/
public void setTileEntities(ListTag<CompoundTag> tileEntities) {
this.tileEntities = tileEntities;
}
/**
* @return The tile ticks of this chunk.
*/
public ListTag<CompoundTag> getTileTicks() {
return tileTicks;
}
/**
* Sets the tile ticks of this chunk.
*
* @param tileTicks Thee tile ticks.
*/
public void setTileTicks(ListTag<CompoundTag> tileTicks) {
this.tileTicks = tileTicks;
}
/**
* @return The liquid ticks of this chunk.
*/
public ListTag<CompoundTag> getLiquidTicks() {
return liquidTicks;
}
/**
* Sets the liquid ticks of this chunk.
*
* @param liquidTicks The liquid ticks.
*/
public void setLiquidTicks(ListTag<CompoundTag> liquidTicks) {
this.liquidTicks = liquidTicks;
}
/**
* @return The light sources in this chunk.
*/
public ListTag<ListTag<?>> getLights() {
return lights;
}
/**
* Sets the light sources in this chunk.
*
* @param lights The light sources.
*/
public void setLights(ListTag<ListTag<?>> lights) {
this.lights = lights;
}
/**
* @return THe liquids to be ticked in this chunk.
*/
public ListTag<ListTag<?>> getLiquidsToBeTicked() {
return liquidsToBeTicked;
}
/**
* Sets the liquids to be ticked in this chunk.
*
* @param liquidsToBeTicked The liquids to be ticked.
*/
public void setLiquidsToBeTicked(ListTag<ListTag<?>> liquidsToBeTicked) {
this.liquidsToBeTicked = liquidsToBeTicked;
}
/**
* @return Stuff to be ticked in this chunk.
*/
public ListTag<ListTag<?>> getToBeTicked() {
return toBeTicked;
}
/**
* Sets stuff to be ticked in this chunk.
*
* @param toBeTicked The stuff to be ticked.
*/
public void setToBeTicked(ListTag<ListTag<?>> toBeTicked) {
this.toBeTicked = toBeTicked;
}
/**
* @return Things that are in post processing in this chunk.
*/
public ListTag<ListTag<?>> getPostProcessing() {
return postProcessing;
}
/**
* Sets things to be post processed in this chunk.
*
* @param postProcessing The things to be post processed.
*/
public void setPostProcessing(ListTag<ListTag<?>> postProcessing) {
this.postProcessing = postProcessing;
}
/**
* @return Data about structures in this chunk.
*/
public CompoundTag getStructures() {
return structures;
}
/**
* Sets data about structures in this chunk.
*
* @param structures The data about structures.
*/
public void setStructures(CompoundTag structures) {
this.structures = structures;
}
int getBlockIndex(int blockX, int blockZ) {
return (blockZ & 0xF) * 16 + (blockX & 0xF);
}
public void cleanupPalettesAndBlockStates() {
for (int i = 0; i < sections.length(); i++) {
Section section = sections.get(i);
if (section != null) {
section.cleanupPaletteAndBlockStates();
}
}
}
public static Chunk newChunk() {
Chunk c = new Chunk(0);
c.dataVersion = DEFAULT_DATA_VERSION;
c.data = new CompoundTag();
c.data.put("Level", new CompoundTag());
c.status = "mobs_spawned";
return c;
}
public CompoundTag updateHandle(int xPos, int zPos) {
data.putInt("DataVersion", dataVersion);
CompoundTag level = data.getCompoundTag("Level");
level.putInt("xPos", xPos);
level.putInt("zPos", zPos);
level.putLong("LastUpdate", lastUpdate);
level.putLong("InhabitedTime", inhabitedTime);
if (dataVersion < 2202) {
if (biomes != null && biomes.length == 256) level.putIntArray("Biomes", biomes);
} else {
if (biomes != null && biomes.length == 1024) level.putIntArray("Biomes", biomes);
}
if (heightMaps != null) level.put("Heightmaps", heightMaps);
if (carvingMasks != null) level.put("CarvingMasks", carvingMasks);
if (entities != null) level.put("Entities", entities);
if (tileEntities != null) level.put("TileEntities", tileEntities);
if (tileTicks != null) level.put("TileTicks", tileTicks);
if (liquidTicks != null) level.put("LiquidTicks", liquidTicks);
if (lights != null) level.put("Lights", lights);
if (liquidsToBeTicked != null) level.put("LiquidsToBeTicked", liquidsToBeTicked);
if (toBeTicked != null) level.put("ToBeTicked", toBeTicked);
if (postProcessing != null) level.put("PostProcessing", postProcessing);
level.putString("Status", status);
if (structures != null) level.put("Structures", structures);
ListTag<CompoundTag> sections = new ListTag<>(CompoundTag.class);
for (int i = 0; i < this.sections.length(); i++) {
if (this.sections.get(i) != null) {
sections.add(this.sections.get(i).updateHandle(i));
}
}
level.put("Sections", sections);
return data;
}
public int sectionCount() {
return sections.length();
}
public void runLighting() {
for (int s = 15; s >= 0; s--) {
Section section = getSection(s);
if (section != null) {
section.runLighting();
}
}
}
}

View File

@@ -1,67 +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.data.mca;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.zip.DeflaterOutputStream;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
import java.util.zip.InflaterInputStream;
public enum CompressionType {
NONE(0, t -> t, t -> t),
GZIP(1, GZIPOutputStream::new, GZIPInputStream::new),
ZLIB(2, DeflaterOutputStream::new, InflaterInputStream::new);
private final byte id;
private final ExceptionFunction<OutputStream, ? extends OutputStream, IOException> compressor;
private final ExceptionFunction<InputStream, ? extends InputStream, IOException> decompressor;
CompressionType(int id,
ExceptionFunction<OutputStream, ? extends OutputStream, IOException> compressor,
ExceptionFunction<InputStream, ? extends InputStream, IOException> decompressor) {
this.id = (byte) id;
this.compressor = compressor;
this.decompressor = decompressor;
}
public byte getID() {
return id;
}
public OutputStream compress(OutputStream out) throws IOException {
return compressor.accept(out);
}
public InputStream decompress(InputStream in) throws IOException {
return decompressor.accept(in);
}
public static CompressionType getFromID(byte id) {
for (CompressionType c : CompressionType.values()) {
if (c.id == id) {
return c;
}
}
return null;
}
}

View File

@@ -1,25 +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.data.mca;
@FunctionalInterface
public interface ExceptionFunction<T, R, E extends Exception> {
R accept(T t) throws E;
}

View File

@@ -1,42 +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.data.mca;
public class LoadFlags {
public static final long BIOMES = 0x0001;
public static final long HEIGHTMAPS = 0x0002;
public static final long CARVING_MASKS = 0x0004;
public static final long ENTITIES = 0x0008;
public static final long TILE_ENTITIES = 0x0010;
public static final long TILE_TICKS = 0x0040;
public static final long LIQUID_TICKS = 0x0080;
public static final long TO_BE_TICKED = 0x0100;
public static final long POST_PROCESSING = 0x0200;
public static final long STRUCTURES = 0x0400;
public static final long BLOCK_LIGHTS = 0x0800;
public static final long BLOCK_STATES = 0x1000;
public static final long SKY_LIGHT = 0x2000;
public static final long LIGHTS = 0x4000;
public static final long LIQUIDS_TO_BE_TICKED = 0x8000;
public static final long ALL_DATA = 0xffffffffffffffffL;
}

View File

@@ -1,350 +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.data.mca;
import com.volmit.iris.engine.data.nbt.tag.CompoundTag;
import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.math.Position2;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.concurrent.atomic.AtomicReferenceArray;
@SuppressWarnings("ALL")
public class MCAFile {
/**
* The default chunk data version used when no custom version is supplied.
*/
public static final int DEFAULT_DATA_VERSION = 1628;
private final int regionX;
private final int regionZ;
private AtomicReferenceArray<Chunk> chunks;
/**
* MCAFile represents a world save file used by Minecraft to store world
* data on the hard drive.
* This constructor needs the x- and z-coordinates of the stored region,
* which can usually be taken from the file name {@code r.x.z.mca}
*
* @param regionX The x-coordinate of this region.
* @param regionZ The z-coordinate of this region.
*/
public MCAFile(int regionX, int regionZ) {
this.regionX = regionX;
this.regionZ = regionZ;
}
/**
* Reads an .mca file from a {@code RandomAccessFile} into this object.
* This method does not perform any cleanups on the data.
*
* @param raf The {@code RandomAccessFile} to read from.
* @throws IOException If something went wrong during deserialization.
*/
public void deserialize(RandomAccessFile raf) throws IOException {
deserialize(raf, LoadFlags.ALL_DATA);
}
/**
* Reads an .mca file from a {@code RandomAccessFile} into this object.
* This method does not perform any cleanups on the data.
*
* @param raf The {@code RandomAccessFile} to read from.
* @param loadFlags A logical or of {@link LoadFlags} constants indicating what data should be loaded
* @throws IOException If something went wrong during deserialization.
*/
public void deserialize(RandomAccessFile raf, long loadFlags) throws IOException {
chunks = new AtomicReferenceArray<>(1024);
for (int i = 0; i < 1024; i++) {
raf.seek(i * 4);
int offset = raf.read() << 16;
offset |= (raf.read() & 0xFF) << 8;
offset |= raf.read() & 0xFF;
if (raf.readByte() == 0) {
continue;
}
raf.seek(4096 + i * 4);
int timestamp = raf.readInt();
Chunk chunk = new Chunk(timestamp);
raf.seek(4096L * offset + 4); //+4: skip data size
chunk.deserialize(raf, loadFlags);
chunks.set(i, chunk);
}
}
public KList<Position2> samplePositions(RandomAccessFile raf) throws IOException {
KList<Position2> p2 = new KList<>();
chunks = new AtomicReferenceArray<>(1024);
int x = 0;
int z = 0;
for (int i = 0; i < 1024; i++) {
x++;
z++;
raf.seek(i * 4);
int offset = raf.read() << 16;
offset |= (raf.read() & 0xFF) << 8;
offset |= raf.read() & 0xFF;
if (raf.readByte() == 0) {
continue;
}
p2.add(new Position2(x & 31, (z / 32) & 31));
}
return p2;
}
public AtomicReferenceArray<Chunk> getChunks() {
return chunks;
}
/**
* Calls {@link MCAFile#serialize(RandomAccessFile, boolean)} without updating any timestamps.
*
* @param raf The {@code RandomAccessFile} to write to.
* @return The amount of chunks written to the file.
* @throws IOException If something went wrong during serialization.
* @see MCAFile#serialize(RandomAccessFile, boolean)
*/
public int serialize(RandomAccessFile raf) throws IOException {
return serialize(raf, false);
}
/**
* Serializes this object to an .mca file.
* This method does not perform any cleanups on the data.
*
* @param raf The {@code RandomAccessFile} to write to.
* @param changeLastUpdate Whether it should update all timestamps that show
* when this file was last updated.
* @return The amount of chunks written to the file.
* @throws IOException If something went wrong during serialization.
*/
public int serialize(RandomAccessFile raf, boolean changeLastUpdate) throws IOException {
int globalOffset = 2;
int lastWritten = 0;
int timestamp = (int) (System.currentTimeMillis() / 1000L);
int chunksWritten = 0;
int chunkXOffset = MCAUtil.regionToChunk(regionX);
int chunkZOffset = MCAUtil.regionToChunk(regionZ);
if (chunks == null) {
return 0;
}
for (int cx = 0; cx < 32; cx++) {
for (int cz = 0; cz < 32; cz++) {
int index = getChunkIndex(cx, cz);
Chunk chunk = chunks.get(index);
if (chunk == null) {
continue;
}
raf.seek(4096L * globalOffset);
lastWritten = chunk.serialize(raf, chunkXOffset + cx, chunkZOffset + cz);
if (lastWritten == 0) {
continue;
}
chunksWritten++;
int sectors = (lastWritten >> 12) + (lastWritten % 4096 == 0 ? 0 : 1);
raf.seek(index * 4L);
raf.writeByte(globalOffset >>> 16);
raf.writeByte(globalOffset >> 8 & 0xFF);
raf.writeByte(globalOffset & 0xFF);
raf.writeByte(sectors);
// write timestamp
raf.seek(index * 4L + 4096);
raf.writeInt(changeLastUpdate ? timestamp : chunk.getLastMCAUpdate());
globalOffset += sectors;
}
}
// padding
if (lastWritten % 4096 != 0) {
raf.seek(globalOffset * 4096L - 1);
raf.write(0);
}
return chunksWritten;
}
/**
* Set a specific Chunk at a specific index. The index must be in range of 0 - 1023.
*
* @param index The index of the Chunk.
* @param chunk The Chunk to be set.
* @throws IndexOutOfBoundsException If index is not in the range.
*/
public void setChunk(int index, Chunk chunk) {
checkIndex(index);
if (chunks == null) {
chunks = new AtomicReferenceArray<>(1024);
}
chunks.set(index, chunk);
}
/**
* Set a specific Chunk at a specific chunk location.
* The x- and z-value can be absolute chunk coordinates or they can be relative to the region origin.
*
* @param chunkX The x-coordinate of the Chunk.
* @param chunkZ The z-coordinate of the Chunk.
* @param chunk The chunk to be set.
*/
public void setChunk(int chunkX, int chunkZ, Chunk chunk) {
setChunk(getChunkIndex(chunkX, chunkZ), chunk);
}
/**
* Returns the chunk data of a chunk at a specific index in this file.
*
* @param index The index of the chunk in this file.
* @return The chunk data.
*/
public Chunk getChunk(int index) {
checkIndex(index);
if (chunks == null) {
return null;
}
return chunks.get(index);
}
/**
* Returns the chunk data of a chunk in this file.
*
* @param chunkX The x-coordinate of the chunk.
* @param chunkZ The z-coordinate of the chunk.
* @return The chunk data.
*/
public Chunk getChunk(int chunkX, int chunkZ) {
return getChunk(getChunkIndex(chunkX, chunkZ));
}
public boolean hasChunk(int chunkX, int chunkZ) {
return getChunk(chunkX, chunkZ) != null;
}
/**
* Calculates the index of a chunk from its x- and z-coordinates in this region.
* This works with absolute and relative coordinates.
*
* @param chunkX The x-coordinate of the chunk.
* @param chunkZ The z-coordinate of the chunk.
* @return The index of this chunk.
*/
public static int getChunkIndex(int chunkX, int chunkZ) {
return (chunkX & 0x1F) + (chunkZ & 0x1F) * 32;
}
private int checkIndex(int index) {
if (index < 0 || index > 1023) {
throw new IndexOutOfBoundsException();
}
return index;
}
private Chunk createChunkIfMissing(int blockX, int blockZ) {
int chunkX = MCAUtil.blockToChunk(blockX), chunkZ = MCAUtil.blockToChunk(blockZ);
Chunk chunk = getChunk(chunkX, chunkZ);
if (chunk == null) {
chunk = Chunk.newChunk();
setChunk(getChunkIndex(chunkX, chunkZ), chunk);
}
return chunk;
}
/**
* @deprecated Use {@link #setBiomeAt(int, int, int, int)} instead
*/
@Deprecated
public void setBiomeAt(int blockX, int blockZ, int biomeID) {
createChunkIfMissing(blockX, blockZ).setBiomeAt(blockX, blockZ, biomeID);
}
public void setBiomeAt(int blockX, int blockY, int blockZ, int biomeID) {
createChunkIfMissing(blockX, blockZ).setBiomeAt(blockX, blockY, blockZ, biomeID);
}
/**
* @deprecated Use {@link #getBiomeAt(int, int, int)} instead
*/
@Deprecated
public int getBiomeAt(int blockX, int blockZ) {
int chunkX = MCAUtil.blockToChunk(blockX), chunkZ = MCAUtil.blockToChunk(blockZ);
Chunk chunk = getChunk(getChunkIndex(chunkX, chunkZ));
if (chunk == null) {
return -1;
}
return chunk.getBiomeAt(blockX, blockZ);
}
/**
* Fetches the biome id at a specific block.
*
* @param blockX The x-coordinate of the block.
* @param blockY The y-coordinate of the block.
* @param blockZ The z-coordinate of the block.
* @return The biome id if the chunk exists and the chunk has biomes, otherwise -1.
*/
public int getBiomeAt(int blockX, int blockY, int blockZ) {
int chunkX = MCAUtil.blockToChunk(blockX), chunkZ = MCAUtil.blockToChunk(blockZ);
Chunk chunk = getChunk(getChunkIndex(chunkX, chunkZ));
if (chunk == null) {
return -1;
}
return chunk.getBiomeAt(blockX, blockY, blockZ);
}
/**
* Set a block state at a specific block location.
* The block coordinates can be absolute coordinates or they can be relative to the region.
*
* @param blockX The x-coordinate of the block.
* @param blockY The y-coordinate of the block.
* @param blockZ The z-coordinate of the block.
* @param state The block state to be set.
* @param cleanup Whether the Palette and the BLockStates should be recalculated after adding the block state.
*/
public void setBlockStateAt(int blockX, int blockY, int blockZ, CompoundTag state, boolean cleanup) {
createChunkIfMissing(blockX, blockZ).setBlockStateAt(blockX, blockY, blockZ, state, cleanup);
}
/**
* Fetches a block state at a specific block location.
* The block coordinates can be absolute coordinates or they can be relative to the region.
*
* @param blockX The x-coordinate of the block.
* @param blockY The y-coordinate of the block.
* @param blockZ The z-coordinate of the block.
* @return The block state or <code>null</code> if the chunk or the section do not exist.
*/
public CompoundTag getBlockStateAt(int blockX, int blockY, int blockZ) {
int chunkX = MCAUtil.blockToChunk(blockX), chunkZ = MCAUtil.blockToChunk(blockZ);
Chunk chunk = getChunk(chunkX, chunkZ);
if (chunk == null) {
return null;
}
return chunk.getBlockStateAt(blockX, blockY, blockZ);
}
}

View File

@@ -1,271 +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.data.mca;
import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.math.Position2;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Provides main and utility functions to read and write .mca files and
* to convert block, chunk and region coordinates.
*/
public final class MCAUtil {
private MCAUtil() {
}
/**
* @param file The file to read the data from.
* @return An in-memory representation of the MCA file with decompressed chunk data.
* @throws IOException if something during deserialization goes wrong.
* @see MCAUtil#read(File)
*/
public static MCAFile read(String file) throws IOException {
return read(new File(file), LoadFlags.ALL_DATA);
}
/**
* Reads an MCA file and loads all of its chunks.
*
* @param file The file to read the data from.
* @return An in-memory representation of the MCA file with decompressed chunk data.
* @throws IOException if something during deserialization goes wrong.
*/
public static MCAFile read(File file) throws IOException {
return read(file, LoadFlags.ALL_DATA);
}
/**
* @param file The file to read the data from.
* @param loadFlags A logical or of {@link LoadFlags} constants indicating what data should be loaded
* @return An in-memory representation of the MCA file with decompressed chunk data.
* @throws IOException if something during deserialization goes wrong.
* @see MCAUtil#read(File)
*/
public static MCAFile read(String file, long loadFlags) throws IOException {
return read(new File(file), loadFlags);
}
/**
* Reads an MCA file and loads all of its chunks.
*
* @param file The file to read the data from.
* @param loadFlags A logical or of {@link LoadFlags} constants indicating what data should be loaded
* @return An in-memory representation of the MCA file with decompressed chunk data
* @throws IOException if something during deserialization goes wrong.
*/
public static MCAFile read(File file, long loadFlags) throws IOException {
MCAFile mcaFile = newMCAFile(file);
try (RandomAccessFile raf = new RandomAccessFile(file, "r")) {
mcaFile.deserialize(raf, loadFlags);
return mcaFile;
}
}
public static KList<Position2> sampleChunkPositions(File file) throws IOException {
MCAFile mcaFile = newMCAFile(file);
try (RandomAccessFile raf = new RandomAccessFile(file, "r")) {
return mcaFile.samplePositions(raf);
}
}
/**
* Calls {@link MCAUtil#write(MCAFile, File, boolean)} without changing the timestamps.
*
* @param file The file to write to.
* @param mcaFile The data of the MCA file to write.
* @return The amount of chunks written to the file.
* @throws IOException If something goes wrong during serialization.
* @see MCAUtil#write(MCAFile, File, boolean)
*/
public static int write(MCAFile mcaFile, String file) throws IOException {
return write(mcaFile, new File(file), false);
}
/**
* Calls {@link MCAUtil#write(MCAFile, File, boolean)} without changing the timestamps.
*
* @param file The file to write to.
* @param mcaFile The data of the MCA file to write.
* @return The amount of chunks written to the file.
* @throws IOException If something goes wrong during serialization.
* @see MCAUtil#write(MCAFile, File, boolean)
*/
public static int write(MCAFile mcaFile, File file) throws IOException {
return write(mcaFile, file, false);
}
/**
* @param file The file to write to.
* @param mcaFile The data of the MCA file to write.
* @param changeLastUpdate Whether to adjust the timestamps of when the file was saved.
* @return The amount of chunks written to the file.
* @throws IOException If something goes wrong during serialization.
* @see MCAUtil#write(MCAFile, File, boolean)
*/
public static int write(MCAFile mcaFile, String file, boolean changeLastUpdate) throws IOException {
return write(mcaFile, new File(file), changeLastUpdate);
}
/**
* Writes an {@code MCAFile} object to disk. It optionally adjusts the timestamps
* when the file was last saved to the current date and time or leaves them at
* the value set by either loading an already existing MCA file or setting them manually.<br>
* If the file already exists, it is completely overwritten by the new file (no modification).
*
* @param file The file to write to.
* @param mcaFile The data of the MCA file to write.
* @param changeLastUpdate Whether to adjust the timestamps of when the file was saved.
* @return The amount of chunks written to the file.
* @throws IOException If something goes wrong during serialization.
*/
public static int write(MCAFile mcaFile, File file, boolean changeLastUpdate) throws IOException {
if (mcaFile == null) {
return 0;
}
File to = file;
if (file.exists()) {
to = File.createTempFile(to.getName(), null);
}
int chunks;
try (RandomAccessFile raf = new RandomAccessFile(to, "rw")) {
chunks = mcaFile.serialize(raf, changeLastUpdate);
}
if (chunks > 0 && to != file) {
Files.move(to.toPath(), file.toPath(), StandardCopyOption.REPLACE_EXISTING);
}
return chunks;
}
/**
* Turns the chunks coordinates into region coordinates and calls
* {@link MCAUtil#createNameFromRegionLocation(int, int)}
*
* @param chunkX The x-value of the location of the chunk.
* @param chunkZ The z-value of the location of the chunk.
* @return A mca filename in the format "r.{regionX}.{regionZ}.mca"
*/
public static String createNameFromChunkLocation(int chunkX, int chunkZ) {
return createNameFromRegionLocation(chunkToRegion(chunkX), chunkToRegion(chunkZ));
}
/**
* Turns the block coordinates into region coordinates and calls
* {@link MCAUtil#createNameFromRegionLocation(int, int)}
*
* @param blockX The x-value of the location of the block.
* @param blockZ The z-value of the location of the block.
* @return A mca filename in the format "r.{regionX}.{regionZ}.mca"
*/
public static String createNameFromBlockLocation(int blockX, int blockZ) {
return createNameFromRegionLocation(blockToRegion(blockX), blockToRegion(blockZ));
}
/**
* Creates a filename string from provided chunk coordinates.
*
* @param regionX The x-value of the location of the region.
* @param regionZ The z-value of the location of the region.
* @return A mca filename in the format "r.{regionX}.{regionZ}.mca"
*/
public static String createNameFromRegionLocation(int regionX, int regionZ) {
return "r." + regionX + "." + regionZ + ".mca";
}
/**
* Turns a block coordinate value into a chunk coordinate value.
*
* @param block The block coordinate value.
* @return The chunk coordinate value.
*/
public static int blockToChunk(int block) {
return block >> 4;
}
/**
* Turns a block coordinate value into a region coordinate value.
*
* @param block The block coordinate value.
* @return The region coordinate value.
*/
public static int blockToRegion(int block) {
return block >> 9;
}
/**
* Turns a chunk coordinate value into a region coordinate value.
*
* @param chunk The chunk coordinate value.
* @return The region coordinate value.
*/
public static int chunkToRegion(int chunk) {
return chunk >> 5;
}
/**
* Turns a region coordinate value into a chunk coordinate value.
*
* @param region The region coordinate value.
* @return The chunk coordinate value.
*/
public static int regionToChunk(int region) {
return region << 5;
}
/**
* Turns a region coordinate value into a block coordinate value.
*
* @param region The region coordinate value.
* @return The block coordinate value.
*/
public static int regionToBlock(int region) {
return region << 9;
}
/**
* Turns a chunk coordinate value into a block coordinate value.
*
* @param chunk The chunk coordinate value.
* @return The block coordinate value.
*/
public static int chunkToBlock(int chunk) {
return chunk << 4;
}
private static final Pattern mcaFilePattern = Pattern.compile("^.*r\\.(?<regionX>-?\\d+)\\.(?<regionZ>-?\\d+)\\.mca$");
public static MCAFile newMCAFile(File file) {
Matcher m = mcaFilePattern.matcher(file.getName());
if (m.find()) {
return new MCAFile(Integer.parseInt(m.group("regionX")), Integer.parseInt(m.group("regionZ")));
}
throw new IllegalArgumentException("invalid mca file name: " + file.getName());
}
}

View File

@@ -1,333 +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.data.mca;
import com.volmit.iris.Iris;
import com.volmit.iris.core.nms.INMS;
import com.volmit.iris.engine.data.cache.Cache;
import com.volmit.iris.engine.data.B;
import com.volmit.iris.engine.data.nbt.tag.CompoundTag;
import com.volmit.iris.engine.data.nbt.tag.StringTag;
import com.volmit.iris.util.collection.KMap;
import com.volmit.iris.util.format.C;
import com.volmit.iris.util.math.M;
import com.volmit.iris.util.scheduling.IrisLock;
import org.bukkit.NamespacedKey;
import org.bukkit.block.Biome;
import org.bukkit.block.data.BlockData;
import java.io.File;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class NBTWorld {
private static final BlockData AIR = B.get("AIR");
private static final Map<String, CompoundTag> blockDataCache = new KMap<>();
private static final Map<Biome, Integer> biomeIds = computeBiomeIDs();
private final IrisLock regionLock = new IrisLock("Region");
private final KMap<Long, MCAFile> loadedRegions;
private final KMap<Long, Long> lastUse;
private final File worldFolder;
private final ExecutorService saveQueue;
public NBTWorld(File worldFolder) {
this.worldFolder = worldFolder;
this.loadedRegions = new KMap<>();
this.lastUse = new KMap<>();
saveQueue = Executors.newSingleThreadExecutor(r -> {
Thread t = new Thread(r);
t.setName("Iris MCA Writer");
t.setPriority(Thread.MIN_PRIORITY);
return t;
});
}
public void close() {
regionLock.lock();
for (Long i : loadedRegions.k()) {
queueSaveUnload(Cache.keyX(i), Cache.keyZ(i));
}
regionLock.unlock();
saveQueue.shutdown();
try {
while (!saveQueue.awaitTermination(3, TimeUnit.SECONDS)) {
Iris.info("Still Waiting to save MCA Files...");
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void flushNow() {
regionLock.lock();
for (Long i : loadedRegions.k()) {
doSaveUnload(Cache.keyX(i), Cache.keyZ(i));
}
regionLock.unlock();
}
public void queueSaveUnload(int x, int z) {
saveQueue.submit(() -> doSaveUnload(x, z));
}
public void doSaveUnload(int x, int z) {
MCAFile f = getMCAOrNull(x, z);
if (f != null) {
unloadRegion(x, z);
}
saveRegion(x, z, f);
}
public void save() {
regionLock.lock();
boolean saving = true;
for (Long i : loadedRegions.k()) {
int x = Cache.keyX(i);
int z = Cache.keyZ(i);
if (!lastUse.containsKey(i)) {
lastUse.put(i, M.ms());
}
if (shouldUnload(x, z)) {
queueSaveUnload(x, z);
}
}
Iris.debug("Regions: " + C.GOLD + loadedRegions.size() + C.LIGHT_PURPLE);
regionLock.unlock();
}
public void queueSave() {
}
public synchronized void unloadRegion(int x, int z) {
long key = Cache.key(x, z);
regionLock.lock();
loadedRegions.remove(key);
lastUse.remove(key);
regionLock.unlock();
Iris.debug("Unloaded Region " + C.GOLD + x + " " + z);
}
public void saveRegion(int x, int z) {
long k = Cache.key(x, z);
MCAFile mca = getMCAOrNull(x, z);
try {
MCAUtil.write(mca, getRegionFile(x, z), true);
Iris.debug("Saved Region " + C.GOLD + x + " " + z);
} catch (IOException e) {
Iris.error("Failed to save region " + getRegionFile(x, z).getPath());
e.printStackTrace();
}
}
public void saveRegion(int x, int z, MCAFile mca) {
try {
MCAUtil.write(mca, getRegionFile(x, z), true);
Iris.debug("Saved Region " + C.GOLD + x + " " + z);
} catch (IOException e) {
Iris.error("Failed to save region " + getRegionFile(x, z).getPath());
e.printStackTrace();
}
}
public boolean shouldUnload(int x, int z) {
return getIdleDuration(x, z) > 60000;
}
public File getRegionFile(int x, int z) {
return new File(worldFolder, "region/r." + x + "." + z + ".mca");
}
public static BlockData getBlockData(CompoundTag tag) {
if (tag == null) {
return B.getAir();
}
StringBuilder p = new StringBuilder(tag.getString("Name"));
if (tag.containsKey("Properties")) {
CompoundTag props = tag.getCompoundTag("Properties");
p.append('[');
for (String i : props.keySet()) {
p.append(i).append('=').append(props.getString(i)).append(',');
}
p.deleteCharAt(p.length() - 1).append(']');
}
BlockData b = B.getOrNull(p.toString());
if (b == null) {
return B.getAir();
}
return b;
}
public static CompoundTag getCompound(BlockData blockData) {
String data = blockData.getAsString(true);
if (blockDataCache.containsKey(data)) {
return blockDataCache.get(data).clone();
}
CompoundTag s = new CompoundTag();
NamespacedKey key = blockData.getMaterial().getKey();
s.putString("Name", key.getNamespace() + ":" + key.getKey());
if (data.contains("[")) {
String raw = data.split("\\Q[\\E")[1].replaceAll("\\Q]\\E", "");
CompoundTag props = new CompoundTag();
if (raw.contains(",")) {
for (String i : raw.split("\\Q,\\E")) {
String[] m = i.split("\\Q=\\E");
String k = m[0];
String v = m[1];
props.put(k, new StringTag(v));
}
} else {
String[] m = raw.split("\\Q=\\E");
String k = m[0];
String v = m[1];
props.put(k, new StringTag(v));
}
s.put("Properties", props);
}
blockDataCache.put(data, s.clone());
return s;
}
public BlockData getBlockData(int x, int y, int z) {
try {
CompoundTag tag = getChunkSection(x >> 4, y >> 4, z >> 4).getBlockStateAt(x & 15, y & 15, z & 15);
if (tag == null) {
return AIR;
}
return getBlockData(tag);
} catch (Throwable e) {
Iris.reportError(e);
}
return AIR;
}
public void setBlockData(int x, int y, int z, BlockData data) {
getChunkSection(x >> 4, y >> 4, z >> 4).setBlockStateAt(x & 15, y & 15, z & 15, getCompound(data), false);
}
public void setBiome(int x, int y, int z, Biome biome) {
getChunk(x >> 4, z >> 4).setBiomeAt(x & 15, y, z & 15, biomeIds.get(biome));
}
public Section getChunkSection(int x, int y, int z) {
Chunk c = getChunk(x, z);
Section s = c.getSection(y);
if (s == null) {
s = Section.newSection();
c.setSection(y, s);
}
return s;
}
public synchronized Chunk getChunk(int x, int z) {
MCAFile mca = getMCA(x >> 5, z >> 5);
Chunk c = mca.getChunk(x & 31, z & 31);
if (c == null) {
c = Chunk.newChunk();
mca.setChunk(x & 31, z & 31, c);
}
return c;
}
public long getIdleDuration(int x, int z) {
Long l = lastUse.get(Cache.key(x, z));
return l == null ? 0 : (M.ms() - l);
}
public MCAFile getMCA(int x, int z) {
long key = Cache.key(x, z);
regionLock.lock();
lastUse.put(key, M.ms());
MCAFile mcaf = loadedRegions.get(key);
regionLock.unlock();
if (mcaf == null) {
mcaf = new MCAFile(x, z);
regionLock.lock();
loadedRegions.put(key, mcaf);
regionLock.unlock();
}
return mcaf;
}
public MCAFile getMCAOrNull(int x, int z) {
long key = Cache.key(x, z);
MCAFile ff = null;
regionLock.lock();
if (loadedRegions.containsKey(key)) {
lastUse.put(key, M.ms());
ff = loadedRegions.get(key);
}
regionLock.unlock();
return ff;
}
public int size() {
return loadedRegions.size();
}
private static Map<Biome, Integer> computeBiomeIDs() {
Map<Biome, Integer> biomeIds = new KMap<>();
for (Biome biome : Biome.values()) {
if (!biome.name().equals("CUSTOM")) {
biomeIds.put(biome, INMS.get().getBiomeId(biome));
}
}
return biomeIds;
}
}

View File

@@ -1,454 +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.data.mca;
import com.volmit.iris.Iris;
import com.volmit.iris.engine.data.nbt.tag.ByteArrayTag;
import com.volmit.iris.engine.data.nbt.tag.CompoundTag;
import com.volmit.iris.engine.data.nbt.tag.ListTag;
import com.volmit.iris.engine.data.nbt.tag.LongArrayTag;
import com.volmit.iris.util.collection.KMap;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicLongArray;
public class Section {
private CompoundTag data;
private Map<String, List<PaletteIndex>> valueIndexedPalette = new KMap<>();
private ListTag<CompoundTag> palette;
private byte[] blockLight;
private AtomicLongArray blockStates;
private byte[] skyLight;
private int dataVersion;
public Section(CompoundTag sectionRoot, int dataVersion) {
this(sectionRoot, dataVersion, LoadFlags.ALL_DATA);
}
public Section(CompoundTag sectionRoot, int dataVersion, long loadFlags) {
data = sectionRoot;
this.dataVersion = dataVersion;
ListTag<?> rawPalette = sectionRoot.getListTag("Palette");
if (rawPalette == null) {
return;
}
palette = rawPalette.asCompoundTagList();
for (int i = 0; i < palette.size(); i++) {
CompoundTag data = palette.get(i);
putValueIndexedPalette(data, i);
}
ByteArrayTag blockLight = sectionRoot.getByteArrayTag("BlockLight");
LongArrayTag blockStates = sectionRoot.getLongArrayTag("BlockStates");
ByteArrayTag skyLight = sectionRoot.getByteArrayTag("SkyLight");
if ((loadFlags & LoadFlags.BLOCK_LIGHTS) != 0) {
this.blockLight = blockLight != null ? blockLight.getValue() : null;
}
if ((loadFlags & LoadFlags.BLOCK_STATES) != 0) {
this.blockStates = blockStates != null ? new AtomicLongArray(blockStates.getValue()) : null;
}
if ((loadFlags & LoadFlags.SKY_LIGHT) != 0) {
this.skyLight = skyLight != null ? skyLight.getValue() : null;
}
}
Section() {
}
void putValueIndexedPalette(CompoundTag data, int index) {
PaletteIndex leaf = new PaletteIndex(data, index);
String name = data.getString("Name");
List<PaletteIndex> leaves = valueIndexedPalette.get(name);
if (leaves == null) {
leaves = new ArrayList<>(1);
leaves.add(leaf);
valueIndexedPalette.put(name, leaves);
} else {
for (PaletteIndex pal : leaves) {
if (pal.data.equals(data)) {
return;
}
}
leaves.add(leaf);
}
}
PaletteIndex getValueIndexedPalette(CompoundTag data) {
List<PaletteIndex> leaves = valueIndexedPalette.get(data.getString("Name"));
if (leaves == null) {
return null;
}
for (PaletteIndex leaf : leaves) {
if (leaf.data.equals(data)) {
return leaf;
}
}
return null;
}
public void runLighting() {
for (int x = 1; x < 14; x++) {
for (int z = 1; z < 14; z++) {
for (int y = 0; y < 16; y++) {
}
}
}
}
@SuppressWarnings("ClassCanBeRecord")
private static class PaletteIndex {
final CompoundTag data;
final int index;
PaletteIndex(CompoundTag data, int index) {
this.data = data;
this.index = index;
}
}
/**
* Checks whether the data of this Section is empty.
*
* @return true if empty
*/
public boolean isEmpty() {
return data == null;
}
/**
* Fetches a block state based on a block location from this section.
* The coordinates represent the location of the block inside of this Section.
*
* @param blockX The x-coordinate of the block in this Section
* @param blockY The y-coordinate of the block in this Section
* @param blockZ The z-coordinate of the block in this Section
* @return The block state data of this block.
*/
public CompoundTag getBlockStateAt(int blockX, int blockY, int blockZ) {
try {
int index = getBlockIndex(blockX, blockY, blockZ);
int paletteIndex = getPaletteIndex(index);
return palette.get(paletteIndex);
} catch (Throwable ignored) {
Iris.reportError(ignored);
}
return null;
}
/**
* Attempts to add a block state for a specific block location in this Section.
*
* @param blockX The x-coordinate of the block in this Section
* @param blockY The y-coordinate of the block in this Section
* @param blockZ The z-coordinate of the block in this Section
* @param state The block state to be set
* @param cleanup When <code>true</code>, it will cleanup the palette of this section.
* This option should only be used moderately to avoid unnecessary recalculation of the palette indices.
* Recalculating the Palette should only be executed once right before saving the Section to file.
*/
public void setBlockStateAt(int blockX, int blockY, int blockZ, CompoundTag state, boolean cleanup) {
int paletteSizeBefore = palette.size();
int paletteIndex = addToPalette(state);
//power of 2 --> bits must increase, but only if the palette size changed
//otherwise we would attempt to update all blockstates and the entire palette
//every time an existing blockstate was added while having 2^x blockstates in the palette
if (paletteSizeBefore != palette.size() && (paletteIndex & (paletteIndex - 1)) == 0) {
adjustBlockStateBits(null, blockStates);
cleanup = true;
}
setPaletteIndex(getBlockIndex(blockX, blockY, blockZ), paletteIndex, blockStates);
if (cleanup) {
cleanupPaletteAndBlockStates();
}
}
/**
* Returns the index of the block data in the palette.
*
* @param blockStateIndex The index of the block in this section, ranging from 0-4095.
* @return The index of the block data in the palette.
*/
public int getPaletteIndex(int blockStateIndex) {
int bits = blockStates.length() >> 6;
if (dataVersion < 2527) {
double blockStatesIndex = blockStateIndex / (4096D / blockStates.length());
int longIndex = (int) blockStatesIndex;
int startBit = (int) ((blockStatesIndex - Math.floor(blockStatesIndex)) * 64D);
if (startBit + bits > 64) {
long prev = bitRange(blockStates.get(longIndex), startBit, 64);
long next = bitRange(blockStates.get(longIndex + 1), 0, startBit + bits - 64);
return (int) ((next << 64 - startBit) + prev);
} else {
return (int) bitRange(blockStates.get(longIndex), startBit, startBit + bits);
}
} else {
int indicesPerLong = (int) (64D / bits);
int blockStatesIndex = blockStateIndex / indicesPerLong;
int startBit = (blockStateIndex % indicesPerLong) * bits;
return (int) bitRange(blockStates.get(blockStatesIndex), startBit, startBit + bits);
}
}
/**
* Sets the index of the block data in the BlockStates. Does not adjust the size of the BlockStates array.
*
* @param blockIndex The index of the block in this section, ranging from 0-4095.
* @param paletteIndex The block state to be set (index of block data in the palette).
* @param blockStates The block states to be updated.
*/
public void setPaletteIndex(int blockIndex, int paletteIndex, AtomicLongArray blockStates) {
int bits = blockStates.length() >> 6;
if (dataVersion < 2527) {
double blockStatesIndex = blockIndex / (4096D / blockStates.length());
int longIndex = (int) blockStatesIndex;
int startBit = (int) ((blockStatesIndex - Math.floor(longIndex)) * 64D);
if (startBit + bits > 64) {
blockStates.set(longIndex, updateBits(blockStates.get(longIndex), paletteIndex, startBit, 64));
blockStates.set(longIndex + 1, updateBits(blockStates.get(longIndex + 1), paletteIndex, startBit - 64, startBit + bits - 64));
} else {
blockStates.set(longIndex, updateBits(blockStates.get(longIndex), paletteIndex, startBit, startBit + bits));
}
} else {
int indicesPerLong = (int) (64D / bits);
int blockStatesIndex = blockIndex / indicesPerLong;
int startBit = (blockIndex % indicesPerLong) * bits;
blockStates.set(blockStatesIndex, updateBits(blockStates.get(blockStatesIndex), paletteIndex, startBit, startBit + bits));
}
}
/**
* Fetches the palette of this Section.
*
* @return The palette of this Section.
*/
public ListTag<CompoundTag> getPalette() {
return palette;
}
int addToPalette(CompoundTag data) {
PaletteIndex index;
if ((index = getValueIndexedPalette(data)) != null) {
return index.index;
}
palette.add(data);
putValueIndexedPalette(data, palette.size() - 1);
return palette.size() - 1;
}
int getBlockIndex(int blockX, int blockY, int blockZ) {
return (blockY & 0xF) * 256 + (blockZ & 0xF) * 16 + (blockX & 0xF);
}
static long updateBits(long n, long m, int i, int j) {
//replace i to j in n with j - i bits of m
long mShifted = i > 0 ? (m & ((1L << j - i) - 1)) << i : (m & ((1L << j - i) - 1)) >>> -i;
return ((n & ((j > 63 ? 0 : (~0L << j)) | (i < 0 ? 0 : ((1L << i) - 1L)))) | mShifted);
}
static long bitRange(long value, int from, int to) {
int waste = 64 - to;
return (value << waste) >>> (waste + from);
}
/**
* This method recalculates the palette and its indices.
* This should only be used moderately to avoid unnecessary recalculation of the palette indices.
* Recalculating the Palette should only be executed once right before saving the Section to file.
*/
public void cleanupPaletteAndBlockStates() {
Map<Integer, Integer> oldToNewMapping = cleanupPalette();
adjustBlockStateBits(oldToNewMapping, blockStates);
}
private Map<Integer, Integer> cleanupPalette() {
//create index - palette mapping
Map<Integer, Integer> allIndices = new HashMap<>();
for (int i = 0; i < 4096; i++) {
int paletteIndex = getPaletteIndex(i);
allIndices.put(paletteIndex, paletteIndex);
}
//delete unused blocks from palette
//start at index 1 because we need to keep minecraft:air
int index = 1;
valueIndexedPalette = new HashMap<>(valueIndexedPalette.size());
putValueIndexedPalette(palette.get(0), 0);
for (int i = 1; i < palette.size(); i++) {
if (!allIndices.containsKey(index)) {
palette.remove(i);
i--;
} else {
putValueIndexedPalette(palette.get(i), i);
allIndices.put(index, i);
}
index++;
}
return allIndices;
}
void adjustBlockStateBits(Map<Integer, Integer> oldToNewMapping, AtomicLongArray blockStates) {
//increases or decreases the amount of bits used per BlockState
//based on the size of the palette. oldToNewMapping can be used to update indices
//if the palette had been cleaned up before using MCAFile#cleanupPalette().
int newBits = 32 - Integer.numberOfLeadingZeros(palette.size() - 1);
newBits = Math.max(newBits, 4);
AtomicLongArray newBlockStates;
if (dataVersion < 2527) {
newBlockStates = newBits == blockStates.length() / 64 ? blockStates : new AtomicLongArray(newBits * 64);
} else {
int newLength = (int) Math.ceil(4096D / (64D / newBits));
newBlockStates = newBits == blockStates.length() / 64 ? blockStates : new AtomicLongArray(newLength);
}
if (oldToNewMapping != null) {
for (int i = 0; i < 4096; i++) {
setPaletteIndex(i, oldToNewMapping.get(getPaletteIndex(i)), newBlockStates);
}
} else {
for (int i = 0; i < 4096; i++) {
setPaletteIndex(i, getPaletteIndex(i), newBlockStates);
}
}
this.blockStates = newBlockStates;
}
/**
* @return The block light array of this Section
*/
public byte[] getBlockLight() {
return blockLight;
}
/**
* Sets the block light array for this section.
*
* @param blockLight The block light array
* @throws IllegalArgumentException When the length of the array is not 2048
*/
public void setBlockLight(byte[] blockLight) {
if (blockLight != null && blockLight.length != 2048) {
throw new IllegalArgumentException("BlockLight array must have a length of 2048");
}
this.blockLight = blockLight;
}
/**
* @return The indices of the block states of this Section.
*/
public AtomicLongArray getBlockStates() {
return blockStates;
}
/**
* Sets the block state indices to a custom value.
*
* @param blockStates The block state indices.
* @throws NullPointerException If <code>blockStates</code> is <code>null</code>
* @throws IllegalArgumentException When <code>blockStates</code>' length is &lt; 256 or &gt; 4096 and is not a multiple of 64
*/
public void setBlockStates(AtomicLongArray blockStates) {
if (blockStates == null) {
throw new NullPointerException("BlockStates cannot be null");
} else if (blockStates.length() % 64 != 0 || blockStates.length() < 256 || blockStates.length() > 4096) {
throw new IllegalArgumentException("BlockStates must have a length > 255 and < 4097 and must be divisible by 64");
}
this.blockStates = blockStates;
}
/**
* @return The sky light values of this Section
*/
public byte[] getSkyLight() {
return skyLight;
}
/**
* Sets the sky light values of this section.
*
* @param skyLight The custom sky light values
* @throws IllegalArgumentException If the length of the array is not 2048
*/
public void setSkyLight(byte[] skyLight) {
if (skyLight != null && skyLight.length != 2048) {
throw new IllegalArgumentException("SkyLight array must have a length of 2048");
}
this.skyLight = skyLight;
}
/**
* Creates an empty Section with base values.
*
* @return An empty Section
*/
public static Section newSection() {
Section s = new Section();
s.blockStates = new AtomicLongArray(256);
s.palette = new ListTag<>(CompoundTag.class);
CompoundTag air = new CompoundTag();
air.putString("Name", "minecraft:air");
s.palette.add(air);
s.data = new CompoundTag();
return s;
}
/**
* Updates the raw CompoundTag that this Section is based on.
* This must be called before saving a Section to disk if the Section was manually created
* to set the Y of this Section.
*
* @param y The Y-value of this Section
* @return A reference to the raw CompoundTag this Section is based on
*/
public CompoundTag updateHandle(int y) {
data.putByte("Y", (byte) y);
if (palette != null) {
data.put("Palette", palette);
}
if (blockLight != null) {
data.putByteArray("BlockLight", blockLight);
}
if (blockStates != null) {
long[] c = new long[blockStates.length()];
for (int i = 0; i < c.length; i++) {
c[i] = blockStates.get(i);
}
data.putLongArray("BlockStates", c);
}
if (skyLight != null) {
data.putByteArray("SkyLight", skyLight);
}
return data;
}
}

View File

@@ -1,50 +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.data.nbt.io;
import com.volmit.iris.engine.data.io.Deserializer;
import com.volmit.iris.engine.data.nbt.tag.Tag;
import java.io.IOException;
import java.io.InputStream;
import java.util.zip.GZIPInputStream;
public class NBTDeserializer implements Deserializer<NamedTag> {
private final boolean compressed;
public NBTDeserializer() {
this(true);
}
public NBTDeserializer(boolean compressed) {
this.compressed = compressed;
}
@Override
public NamedTag fromStream(InputStream stream) throws IOException {
NBTInputStream nbtIn;
if (compressed) {
nbtIn = new NBTInputStream(new GZIPInputStream(stream));
} else {
nbtIn = new NBTInputStream(stream);
}
return nbtIn.readTag(Tag.DEFAULT_MAX_DEPTH);
}
}

View File

@@ -1,155 +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.data.nbt.io;
import com.volmit.iris.engine.data.io.ExceptionBiFunction;
import com.volmit.iris.engine.data.io.MaxDepthIO;
import com.volmit.iris.engine.data.nbt.tag.*;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
public class NBTInputStream extends DataInputStream implements MaxDepthIO {
private static final Map<Byte, ExceptionBiFunction<NBTInputStream, Integer, ? extends Tag<?>, IOException>> readers = new HashMap<>();
private static final Map<Byte, Class<?>> idClassMapping = new HashMap<>();
static {
put(EndTag.ID, (i, d) -> EndTag.INSTANCE, EndTag.class);
put(ByteTag.ID, (i, d) -> readByte(i), ByteTag.class);
put(ShortTag.ID, (i, d) -> readShort(i), ShortTag.class);
put(IntTag.ID, (i, d) -> readInt(i), IntTag.class);
put(LongTag.ID, (i, d) -> readLong(i), LongTag.class);
put(FloatTag.ID, (i, d) -> readFloat(i), FloatTag.class);
put(DoubleTag.ID, (i, d) -> readDouble(i), DoubleTag.class);
put(ByteArrayTag.ID, (i, d) -> readByteArray(i), ByteArrayTag.class);
put(StringTag.ID, (i, d) -> readString(i), StringTag.class);
put(ListTag.ID, NBTInputStream::readListTag, ListTag.class);
put(CompoundTag.ID, NBTInputStream::readCompound, CompoundTag.class);
put(IntArrayTag.ID, (i, d) -> readIntArray(i), IntArrayTag.class);
put(LongArrayTag.ID, (i, d) -> readLongArray(i), LongArrayTag.class);
}
private static void put(byte id, ExceptionBiFunction<NBTInputStream, Integer, ? extends Tag<?>, IOException> reader, Class<?> clazz) {
readers.put(id, reader);
idClassMapping.put(id, clazz);
}
public NBTInputStream(InputStream in) {
super(in);
}
public NamedTag readTag(int maxDepth) throws IOException {
byte id = readByte();
return new NamedTag(readUTF(), readTag(id, maxDepth));
}
public Tag<?> readRawTag(int maxDepth) throws IOException {
byte id = readByte();
return readTag(id, maxDepth);
}
private Tag<?> readTag(byte type, int maxDepth) throws IOException {
ExceptionBiFunction<NBTInputStream, Integer, ? extends Tag<?>, IOException> f;
if ((f = readers.get(type)) == null) {
throw new IOException("invalid tag id \"" + type + "\"");
}
return f.accept(this, maxDepth);
}
private static ByteTag readByte(NBTInputStream in) throws IOException {
return new ByteTag(in.readByte());
}
private static ShortTag readShort(NBTInputStream in) throws IOException {
return new ShortTag(in.readShort());
}
private static IntTag readInt(NBTInputStream in) throws IOException {
return new IntTag(in.readInt());
}
private static LongTag readLong(NBTInputStream in) throws IOException {
return new LongTag(in.readLong());
}
private static FloatTag readFloat(NBTInputStream in) throws IOException {
return new FloatTag(in.readFloat());
}
private static DoubleTag readDouble(NBTInputStream in) throws IOException {
return new DoubleTag(in.readDouble());
}
private static StringTag readString(NBTInputStream in) throws IOException {
return new StringTag(in.readUTF());
}
private static ByteArrayTag readByteArray(NBTInputStream in) throws IOException {
ByteArrayTag bat = new ByteArrayTag(new byte[in.readInt()]);
in.readFully(bat.getValue());
return bat;
}
private static IntArrayTag readIntArray(NBTInputStream in) throws IOException {
int l = in.readInt();
int[] data = new int[l];
IntArrayTag iat = new IntArrayTag(data);
for (int i = 0; i < l; i++) {
data[i] = in.readInt();
}
return iat;
}
private static LongArrayTag readLongArray(NBTInputStream in) throws IOException {
int l = in.readInt();
long[] data = new long[l];
LongArrayTag iat = new LongArrayTag(data);
for (int i = 0; i < l; i++) {
data[i] = in.readLong();
}
return iat;
}
private static ListTag<?> readListTag(NBTInputStream in, int maxDepth) throws IOException {
byte listType = in.readByte();
ListTag<?> list = ListTag.createUnchecked(idClassMapping.get(listType));
int length = in.readInt();
if (length < 0) {
length = 0;
}
for (int i = 0; i < length; i++) {
list.addUnchecked(in.readTag(listType, in.decrementMaxDepth(maxDepth)));
}
return list;
}
private static CompoundTag readCompound(NBTInputStream in, int maxDepth) throws IOException {
CompoundTag comp = new CompoundTag();
for (int id = in.readByte() & 0xFF; id != 0; id = in.readByte() & 0xFF) {
String key = in.readUTF();
Tag<?> element = in.readTag((byte) id, in.decrementMaxDepth(maxDepth));
comp.put(key, element);
}
return comp;
}
}

View File

@@ -1,160 +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.data.nbt.io;
import com.volmit.iris.engine.data.io.ExceptionTriConsumer;
import com.volmit.iris.engine.data.io.MaxDepthIO;
import com.volmit.iris.engine.data.nbt.tag.*;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;
public class NBTOutputStream extends DataOutputStream implements MaxDepthIO {
private static final Map<Byte, ExceptionTriConsumer<NBTOutputStream, Tag<?>, Integer, IOException>> writers = new HashMap<>();
private static final Map<Class<?>, Byte> classIdMapping = new HashMap<>();
static {
put(EndTag.ID, (o, t, d) -> {
}, EndTag.class);
put(ByteTag.ID, (o, t, d) -> writeByte(o, t), ByteTag.class);
put(ShortTag.ID, (o, t, d) -> writeShort(o, t), ShortTag.class);
put(IntTag.ID, (o, t, d) -> writeInt(o, t), IntTag.class);
put(LongTag.ID, (o, t, d) -> writeLong(o, t), LongTag.class);
put(FloatTag.ID, (o, t, d) -> writeFloat(o, t), FloatTag.class);
put(DoubleTag.ID, (o, t, d) -> writeDouble(o, t), DoubleTag.class);
put(ByteArrayTag.ID, (o, t, d) -> writeByteArray(o, t), ByteArrayTag.class);
put(StringTag.ID, (o, t, d) -> writeString(o, t), StringTag.class);
put(ListTag.ID, NBTOutputStream::writeList, ListTag.class);
put(CompoundTag.ID, NBTOutputStream::writeCompound, CompoundTag.class);
put(IntArrayTag.ID, (o, t, d) -> writeIntArray(o, t), IntArrayTag.class);
put(LongArrayTag.ID, (o, t, d) -> writeLongArray(o, t), LongArrayTag.class);
}
private static void put(byte id, ExceptionTriConsumer<NBTOutputStream, Tag<?>, Integer, IOException> f, Class<?> clazz) {
writers.put(id, f);
classIdMapping.put(clazz, id);
}
public NBTOutputStream(OutputStream out) {
super(out);
}
public void writeTag(NamedTag tag, int maxDepth) throws IOException {
writeByte(tag.getTag().getID());
if (tag.getTag().getID() != 0) {
writeUTF(tag.getName() == null ? "" : tag.getName());
}
writeRawTag(tag.getTag(), maxDepth);
}
public void writeTag(Tag<?> tag, int maxDepth) throws IOException {
writeByte(tag.getID());
if (tag.getID() != 0) {
writeUTF("");
}
writeRawTag(tag, maxDepth);
}
public void writeRawTag(Tag<?> tag, int maxDepth) throws IOException {
ExceptionTriConsumer<NBTOutputStream, Tag<?>, Integer, IOException> f;
if ((f = writers.get(tag.getID())) == null) {
throw new IOException("invalid tag \"" + tag.getID() + "\"");
}
f.accept(this, tag, maxDepth);
}
static byte idFromClass(Class<?> clazz) {
Byte id = classIdMapping.get(clazz);
if (id == null) {
throw new IllegalArgumentException("unknown Tag class " + clazz.getName());
}
return id;
}
private static void writeByte(NBTOutputStream out, Tag<?> tag) throws IOException {
out.writeByte(((ByteTag) tag).asByte());
}
private static void writeShort(NBTOutputStream out, Tag<?> tag) throws IOException {
out.writeShort(((ShortTag) tag).asShort());
}
private static void writeInt(NBTOutputStream out, Tag<?> tag) throws IOException {
out.writeInt(((IntTag) tag).asInt());
}
private static void writeLong(NBTOutputStream out, Tag<?> tag) throws IOException {
out.writeLong(((LongTag) tag).asLong());
}
private static void writeFloat(NBTOutputStream out, Tag<?> tag) throws IOException {
out.writeFloat(((FloatTag) tag).asFloat());
}
private static void writeDouble(NBTOutputStream out, Tag<?> tag) throws IOException {
out.writeDouble(((DoubleTag) tag).asDouble());
}
private static void writeString(NBTOutputStream out, Tag<?> tag) throws IOException {
out.writeUTF(((StringTag) tag).getValue());
}
private static void writeByteArray(NBTOutputStream out, Tag<?> tag) throws IOException {
out.writeInt(((ByteArrayTag) tag).length());
out.write(((ByteArrayTag) tag).getValue());
}
private static void writeIntArray(NBTOutputStream out, Tag<?> tag) throws IOException {
out.writeInt(((IntArrayTag) tag).length());
for (int i : ((IntArrayTag) tag).getValue()) {
out.writeInt(i);
}
}
private static void writeLongArray(NBTOutputStream out, Tag<?> tag) throws IOException {
out.writeInt(((LongArrayTag) tag).length());
for (long l : ((LongArrayTag) tag).getValue()) {
out.writeLong(l);
}
}
private static void writeList(NBTOutputStream out, Tag<?> tag, int maxDepth) throws IOException {
out.writeByte(idFromClass(((ListTag<?>) tag).getTypeClass()));
out.writeInt(((ListTag<?>) tag).size());
for (Tag<?> t : ((ListTag<?>) tag)) {
out.writeRawTag(t, out.decrementMaxDepth(maxDepth));
}
}
private static void writeCompound(NBTOutputStream out, Tag<?> tag, int maxDepth) throws IOException {
for (Map.Entry<String, Tag<?>> entry : (CompoundTag) tag) {
if (entry.getValue().getID() == 0) {
throw new IOException("end tag not allowed");
}
out.writeByte(entry.getValue().getID());
out.writeUTF(entry.getKey());
out.writeRawTag(entry.getValue(), out.decrementMaxDepth(maxDepth));
}
out.writeByte(0);
}
}

View File

@@ -1,51 +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.data.nbt.io;
import com.volmit.iris.engine.data.io.Serializer;
import com.volmit.iris.engine.data.nbt.tag.Tag;
import java.io.IOException;
import java.io.OutputStream;
import java.util.zip.GZIPOutputStream;
public class NBTSerializer implements Serializer<NamedTag> {
private final boolean compressed;
public NBTSerializer() {
this(true);
}
public NBTSerializer(boolean compressed) {
this.compressed = compressed;
}
@Override
public void toStream(NamedTag object, OutputStream out) throws IOException {
NBTOutputStream nbtOut;
if (compressed) {
nbtOut = new NBTOutputStream(new GZIPOutputStream(out, true));
} else {
nbtOut = new NBTOutputStream(out);
}
nbtOut.writeTag(object, Tag.DEFAULT_MAX_DEPTH);
nbtOut.flush();
}
}

View File

@@ -1,95 +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.data.nbt.io;
import com.volmit.iris.engine.data.nbt.tag.Tag;
import java.io.*;
import java.util.zip.GZIPInputStream;
public final class NBTUtil {
private NBTUtil() {
}
public static void write(NamedTag tag, File file, boolean compressed) throws IOException {
try (FileOutputStream fos = new FileOutputStream(file)) {
new NBTSerializer(compressed).toStream(tag, fos);
}
}
public static void write(NamedTag tag, String file, boolean compressed) throws IOException {
write(tag, new File(file), compressed);
}
public static void write(NamedTag tag, File file) throws IOException {
write(tag, file, true);
}
public static void write(NamedTag tag, String file) throws IOException {
write(tag, new File(file), true);
}
public static void write(Tag<?> tag, File file, boolean compressed) throws IOException {
write(new NamedTag(null, tag), file, compressed);
}
public static void write(Tag<?> tag, String file, boolean compressed) throws IOException {
write(new NamedTag(null, tag), new File(file), compressed);
}
public static void write(Tag<?> tag, File file) throws IOException {
write(new NamedTag(null, tag), file, true);
}
public static void write(Tag<?> tag, String file) throws IOException {
write(new NamedTag(null, tag), new File(file), true);
}
public static NamedTag read(File file, boolean compressed) throws IOException {
try (FileInputStream fis = new FileInputStream(file)) {
return new NBTDeserializer(compressed).fromStream(fis);
}
}
public static NamedTag read(String file, boolean compressed) throws IOException {
return read(new File(file), compressed);
}
public static NamedTag read(File file) throws IOException {
try (FileInputStream fis = new FileInputStream(file)) {
return new NBTDeserializer(false).fromStream(detectDecompression(fis));
}
}
public static NamedTag read(String file) throws IOException {
return read(new File(file));
}
private static InputStream detectDecompression(InputStream is) throws IOException {
PushbackInputStream pbis = new PushbackInputStream(is, 2);
int signature = (pbis.read() & 0xFF) + (pbis.read() << 8);
pbis.unread(signature >> 8);
pbis.unread(signature & 0xFF);
if (signature == GZIPInputStream.GZIP_MAGIC) {
return new GZIPInputStream(pbis);
}
return pbis;
}
}

View File

@@ -1,48 +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.data.nbt.io;
import com.volmit.iris.engine.data.nbt.tag.Tag;
public class NamedTag {
private String name;
private Tag<?> tag;
public NamedTag(String name, Tag<?> tag) {
this.name = name;
this.tag = tag;
}
public void setName(String name) {
this.name = name;
}
public void setTag(Tag<?> tag) {
this.tag = tag;
}
public String getName() {
return name;
}
public Tag<?> getTag() {
return tag;
}
}

View File

@@ -1,43 +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.data.nbt.io;
import java.io.IOException;
public class ParseException extends IOException {
public ParseException(String msg) {
super(msg);
}
public ParseException(String msg, String value, int index) {
super(msg + " at: " + formatError(value, index));
}
private static String formatError(String value, int index) {
StringBuilder builder = new StringBuilder();
int i = Math.min(value.length(), index);
if (i > 35) {
builder.append("...");
}
builder.append(value, Math.max(0, i - 35), i);
builder.append("<--[HERE]");
return builder.toString();
}
}

View File

@@ -1,45 +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.data.nbt.io;
import com.volmit.iris.engine.data.io.StringDeserializer;
import com.volmit.iris.engine.data.nbt.tag.Tag;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.Reader;
import java.util.stream.Collectors;
public class SNBTDeserializer implements StringDeserializer<Tag<?>> {
@Override
public Tag<?> fromReader(Reader reader) throws IOException {
return fromReader(reader, Tag.DEFAULT_MAX_DEPTH);
}
public Tag<?> fromReader(Reader reader, int maxDepth) throws IOException {
BufferedReader bufferedReader;
if (reader instanceof BufferedReader) {
bufferedReader = (BufferedReader) reader;
} else {
bufferedReader = new BufferedReader(reader);
}
return SNBTParser.parse(bufferedReader.lines().collect(Collectors.joining()), maxDepth);
}
}

View File

@@ -1,258 +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.data.nbt.io;
import com.volmit.iris.Iris;
import com.volmit.iris.engine.data.io.MaxDepthIO;
import com.volmit.iris.engine.data.nbt.tag.*;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;
public final class SNBTParser implements MaxDepthIO {
private static final Pattern
FLOAT_LITERAL_PATTERN = Pattern.compile("^[-+]?(?:\\d+\\.?|\\d*\\.\\d+)(?:e[-+]?\\d+)?f$", Pattern.CASE_INSENSITIVE),
DOUBLE_LITERAL_PATTERN = Pattern.compile("^[-+]?(?:\\d+\\.?|\\d*\\.\\d+)(?:e[-+]?\\d+)?d$", Pattern.CASE_INSENSITIVE),
DOUBLE_LITERAL_NO_SUFFIX_PATTERN = Pattern.compile("^[-+]?(?:\\d+\\.|\\d*\\.\\d+)(?:e[-+]?\\d+)?$", Pattern.CASE_INSENSITIVE),
BYTE_LITERAL_PATTERN = Pattern.compile("^[-+]?\\d+b$", Pattern.CASE_INSENSITIVE),
SHORT_LITERAL_PATTERN = Pattern.compile("^[-+]?\\d+s$", Pattern.CASE_INSENSITIVE),
INT_LITERAL_PATTERN = Pattern.compile("^[-+]?\\d+$", Pattern.CASE_INSENSITIVE),
LONG_LITERAL_PATTERN = Pattern.compile("^[-+]?\\d+l$", Pattern.CASE_INSENSITIVE),
NUMBER_PATTERN = Pattern.compile("^[-+]?\\d+$");
private final StringPointer ptr;
private SNBTParser(String string) {
this.ptr = new StringPointer(string);
}
public static Tag<?> parse(String string, int maxDepth) throws ParseException {
SNBTParser parser = new SNBTParser(string);
Tag<?> tag = parser.parseAnything(maxDepth);
parser.ptr.skipWhitespace();
if (parser.ptr.hasNext()) {
throw parser.ptr.parseException("invalid characters after end of snbt");
}
return tag;
}
public static Tag<?> parse(String string) throws ParseException {
return parse(string, Tag.DEFAULT_MAX_DEPTH);
}
private Tag<?> parseAnything(int maxDepth) throws ParseException {
ptr.skipWhitespace();
switch (ptr.currentChar()) {
case '{':
return parseCompoundTag(maxDepth);
case '[':
if (ptr.hasCharsLeft(2) && ptr.lookAhead(1) != '"' && ptr.lookAhead(2) == ';') {
return parseNumArray();
}
return parseListTag(maxDepth);
}
return parseStringOrLiteral();
}
private Tag<?> parseStringOrLiteral() throws ParseException {
ptr.skipWhitespace();
if (ptr.currentChar() == '"') {
return new StringTag(ptr.parseQuotedString());
}
String s = ptr.parseSimpleString();
if (s.isEmpty()) {
throw new ParseException("expected non empty value");
}
if (FLOAT_LITERAL_PATTERN.matcher(s).matches()) {
return new FloatTag(Float.parseFloat(s.substring(0, s.length() - 1)));
} else if (BYTE_LITERAL_PATTERN.matcher(s).matches()) {
try {
return new ByteTag(Byte.parseByte(s.substring(0, s.length() - 1)));
} catch (NumberFormatException ex) {
Iris.reportError(ex);
throw ptr.parseException("byte not in range: \"" + s.substring(0, s.length() - 1) + "\"");
}
} else if (SHORT_LITERAL_PATTERN.matcher(s).matches()) {
try {
return new ShortTag(Short.parseShort(s.substring(0, s.length() - 1)));
} catch (NumberFormatException ex) {
Iris.reportError(ex);
throw ptr.parseException("short not in range: \"" + s.substring(0, s.length() - 1) + "\"");
}
} else if (LONG_LITERAL_PATTERN.matcher(s).matches()) {
try {
return new LongTag(Long.parseLong(s.substring(0, s.length() - 1)));
} catch (NumberFormatException ex) {
Iris.reportError(ex);
throw ptr.parseException("long not in range: \"" + s.substring(0, s.length() - 1) + "\"");
}
} else if (INT_LITERAL_PATTERN.matcher(s).matches()) {
try {
return new IntTag(Integer.parseInt(s));
} catch (NumberFormatException ex) {
Iris.reportError(ex);
throw ptr.parseException("int not in range: \"" + s.substring(0, s.length() - 1) + "\"");
}
} else if (DOUBLE_LITERAL_PATTERN.matcher(s).matches()) {
return new DoubleTag(Double.parseDouble(s.substring(0, s.length() - 1)));
} else if (DOUBLE_LITERAL_NO_SUFFIX_PATTERN.matcher(s).matches()) {
return new DoubleTag(Double.parseDouble(s));
} else if ("true".equalsIgnoreCase(s)) {
return new ByteTag(true);
} else if ("false".equalsIgnoreCase(s)) {
return new ByteTag(false);
}
return new StringTag(s);
}
private CompoundTag parseCompoundTag(int maxDepth) throws ParseException {
ptr.expectChar('{');
CompoundTag compoundTag = new CompoundTag();
ptr.skipWhitespace();
while (ptr.hasNext() && ptr.currentChar() != '}') {
ptr.skipWhitespace();
String key = ptr.currentChar() == '"' ? ptr.parseQuotedString() : ptr.parseSimpleString();
if (key.isEmpty()) {
throw new ParseException("empty keys are not allowed");
}
ptr.expectChar(':');
compoundTag.put(key, parseAnything(decrementMaxDepth(maxDepth)));
if (!ptr.nextArrayElement()) {
break;
}
}
ptr.expectChar('}');
return compoundTag;
}
private ListTag<?> parseListTag(int maxDepth) throws ParseException {
ptr.expectChar('[');
ptr.skipWhitespace();
ListTag<?> list = ListTag.createUnchecked(EndTag.class);
while (ptr.currentChar() != ']') {
Tag<?> element = parseAnything(decrementMaxDepth(maxDepth));
try {
list.addUnchecked(element);
} catch (IllegalArgumentException ex) {
Iris.reportError(ex);
throw ptr.parseException(ex.getMessage());
}
if (!ptr.nextArrayElement()) {
break;
}
}
ptr.expectChar(']');
return list;
}
private ArrayTag<?> parseNumArray() throws ParseException {
ptr.expectChar('[');
char arrayType = ptr.next();
ptr.expectChar(';');
ptr.skipWhitespace();
switch (arrayType) {
case 'B':
return parseByteArrayTag();
case 'I':
return parseIntArrayTag();
case 'L':
return parseLongArrayTag();
}
throw new ParseException("invalid array type '" + arrayType + "'");
}
private ByteArrayTag parseByteArrayTag() throws ParseException {
List<Byte> byteList = new ArrayList<>();
while (ptr.currentChar() != ']') {
String s = ptr.parseSimpleString();
ptr.skipWhitespace();
if (NUMBER_PATTERN.matcher(s).matches()) {
try {
byteList.add(Byte.parseByte(s));
} catch (NumberFormatException ex) {
Iris.reportError(ex);
throw ptr.parseException("byte not in range: \"" + s + "\"");
}
} else {
throw ptr.parseException("invalid byte in ByteArrayTag: \"" + s + "\"");
}
if (!ptr.nextArrayElement()) {
break;
}
}
ptr.expectChar(']');
byte[] bytes = new byte[byteList.size()];
for (int i = 0; i < byteList.size(); i++) {
bytes[i] = byteList.get(i);
}
return new ByteArrayTag(bytes);
}
private IntArrayTag parseIntArrayTag() throws ParseException {
List<Integer> intList = new ArrayList<>();
while (ptr.currentChar() != ']') {
String s = ptr.parseSimpleString();
ptr.skipWhitespace();
if (NUMBER_PATTERN.matcher(s).matches()) {
try {
intList.add(Integer.parseInt(s));
} catch (NumberFormatException ex) {
Iris.reportError(ex);
throw ptr.parseException("int not in range: \"" + s + "\"");
}
} else {
throw ptr.parseException("invalid int in IntArrayTag: \"" + s + "\"");
}
if (!ptr.nextArrayElement()) {
break;
}
}
ptr.expectChar(']');
return new IntArrayTag(intList.stream().mapToInt(i -> i).toArray());
}
private LongArrayTag parseLongArrayTag() throws ParseException {
List<Long> longList = new ArrayList<>();
while (ptr.currentChar() != ']') {
String s = ptr.parseSimpleString();
ptr.skipWhitespace();
if (NUMBER_PATTERN.matcher(s).matches()) {
try {
longList.add(Long.parseLong(s));
} catch (NumberFormatException ex) {
Iris.reportError(ex);
throw ptr.parseException("long not in range: \"" + s + "\"");
}
} else {
throw ptr.parseException("invalid long in LongArrayTag: \"" + s + "\"");
}
if (!ptr.nextArrayElement()) {
break;
}
}
ptr.expectChar(']');
return new LongArrayTag(longList.stream().mapToLong(l -> l).toArray());
}
}

View File

@@ -1,37 +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.data.nbt.io;
import com.volmit.iris.engine.data.io.StringSerializer;
import com.volmit.iris.engine.data.nbt.tag.Tag;
import java.io.IOException;
import java.io.Writer;
public class SNBTSerializer implements StringSerializer<Tag<?>> {
@Override
public void toWriter(Tag<?> tag, Writer writer) throws IOException {
SNBTWriter.write(tag, writer);
}
public void toWriter(Tag<?> tag, Writer writer, int maxDepth) throws IOException {
SNBTWriter.write(tag, writer, maxDepth);
}
}

View File

@@ -1,34 +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.data.nbt.io;
import com.volmit.iris.engine.data.nbt.tag.Tag;
import java.io.IOException;
public class SNBTUtil {
public static String toSNBT(Tag<?> tag) throws IOException {
return new SNBTSerializer().toString(tag);
}
public static Tag<?> fromSNBT(String string) throws IOException {
return new SNBTDeserializer().fromString(string);
}
}

View File

@@ -1,135 +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.data.nbt.io;
import com.volmit.iris.engine.data.io.MaxDepthIO;
import com.volmit.iris.engine.data.nbt.tag.*;
import java.io.IOException;
import java.io.Writer;
import java.lang.reflect.Array;
import java.util.Map;
import java.util.regex.Pattern;
/**
* SNBTWriter creates an SNBT String.
*/
@SuppressWarnings("ClassCanBeRecord")
public final class SNBTWriter implements MaxDepthIO {
private static final Pattern NON_QUOTE_PATTERN = Pattern.compile("[a-zA-Z_.+\\-]+");
private final Writer writer;
private SNBTWriter(Writer writer) {
this.writer = writer;
}
public static void write(Tag<?> tag, Writer writer, int maxDepth) throws IOException {
new SNBTWriter(writer).writeAnything(tag, maxDepth);
}
public static void write(Tag<?> tag, Writer writer) throws IOException {
write(tag, writer, Tag.DEFAULT_MAX_DEPTH);
}
private void writeAnything(Tag<?> tag, int maxDepth) throws IOException {
switch (tag.getID()) {
case EndTag.ID:
//do nothing
break;
case ByteTag.ID:
writer.append(Byte.toString(((ByteTag) tag).asByte())).write('b');
break;
case ShortTag.ID:
writer.append(Short.toString(((ShortTag) tag).asShort())).write('s');
break;
case IntTag.ID:
writer.write(Integer.toString(((IntTag) tag).asInt()));
break;
case LongTag.ID:
writer.append(Long.toString(((LongTag) tag).asLong())).write('l');
break;
case FloatTag.ID:
writer.append(Float.toString(((FloatTag) tag).asFloat())).write('f');
break;
case DoubleTag.ID:
writer.append(Double.toString(((DoubleTag) tag).asDouble())).write('d');
break;
case ByteArrayTag.ID:
writeArray(((ByteArrayTag) tag).getValue(), ((ByteArrayTag) tag).length(), "B");
break;
case StringTag.ID:
writer.write(escapeString(((StringTag) tag).getValue()));
break;
case ListTag.ID:
writer.write('[');
for (int i = 0; i < ((ListTag<?>) tag).size(); i++) {
writer.write(i == 0 ? "" : ",");
writeAnything(((ListTag<?>) tag).get(i), decrementMaxDepth(maxDepth));
}
writer.write(']');
break;
case CompoundTag.ID:
writer.write('{');
boolean first = true;
for (Map.Entry<String, Tag<?>> entry : (CompoundTag) tag) {
writer.write(first ? "" : ",");
writer.append(escapeString(entry.getKey())).write(':');
writeAnything(entry.getValue(), decrementMaxDepth(maxDepth));
first = false;
}
writer.write('}');
break;
case IntArrayTag.ID:
writeArray(((IntArrayTag) tag).getValue(), ((IntArrayTag) tag).length(), "I");
break;
case LongArrayTag.ID:
writeArray(((LongArrayTag) tag).getValue(), ((LongArrayTag) tag).length(), "L");
break;
default:
throw new IOException("unknown tag with id \"" + tag.getID() + "\"");
}
}
private void writeArray(Object array, int length, String prefix) throws IOException {
writer.append('[').append(prefix).write(';');
for (int i = 0; i < length; i++) {
writer.append(i == 0 ? "" : ",").write(Array.get(array, i).toString());
}
writer.write(']');
}
public static String escapeString(String s) {
if (!NON_QUOTE_PATTERN.matcher(s).matches()) {
StringBuilder sb = new StringBuilder();
sb.append('"');
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (c == '\\' || c == '"') {
sb.append('\\');
}
sb.append(c);
}
sb.append('"');
return sb.toString();
}
return s;
}
}

View File

@@ -1,133 +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.data.nbt.io;
public class StringPointer {
private final String value;
private int index;
public StringPointer(String value) {
this.value = value;
}
public String parseSimpleString() {
int oldIndex = index;
while (hasNext() && isSimpleChar(currentChar())) {
index++;
}
return value.substring(oldIndex, index);
}
public String parseQuotedString() throws ParseException {
int oldIndex = ++index; //ignore beginning quotes
StringBuilder sb = null;
boolean escape = false;
while (hasNext()) {
char c = next();
if (escape) {
if (c != '\\' && c != '"') {
throw parseException("invalid escape of '" + c + "'");
}
escape = false;
} else {
if (c == '\\') { //escape
escape = true;
if (sb != null) {
continue;
}
sb = new StringBuilder(value.substring(oldIndex, index - 1));
continue;
}
if (c == '"') {
return sb == null ? value.substring(oldIndex, index - 1) : sb.toString();
}
}
if (sb != null) {
sb.append(c);
}
}
throw parseException("missing end quote");
}
@SuppressWarnings("BooleanMethodIsAlwaysInverted")
public boolean nextArrayElement() {
skipWhitespace();
if (hasNext() && currentChar() == ',') {
index++;
skipWhitespace();
return true;
}
return false;
}
public void expectChar(char c) throws ParseException {
skipWhitespace();
boolean hasNext = hasNext();
if (hasNext && currentChar() == c) {
index++;
return;
}
throw parseException("expected '" + c + "' but got " + (hasNext ? "'" + currentChar() + "'" : "EOF"));
}
public void skipWhitespace() {
while (hasNext() && Character.isWhitespace(currentChar())) {
index++;
}
}
public boolean hasNext() {
return index < value.length();
}
public boolean hasCharsLeft(int num) {
return this.index + num < value.length();
}
public char currentChar() {
return value.charAt(index);
}
public char next() {
return value.charAt(index++);
}
public void skip(int offset) {
index += offset;
}
public char lookAhead(int offset) {
return value.charAt(index + offset);
}
private static boolean isSimpleChar(char c) {
return c >= 'a' && c <= 'z'
|| c >= 'A' && c <= 'Z'
|| c >= '0' && c <= '9'
|| c == '-'
|| c == '+'
|| c == '.'
|| c == '_';
}
public ParseException parseException(String msg) {
return new ParseException(msg, value, index);
}
}

View File

@@ -1,65 +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.data.nbt.tag;
import java.lang.reflect.Array;
/**
* ArrayTag is an abstract representation of any NBT array tag.
* For implementations see {@link ByteArrayTag}, {@link IntArrayTag}, {@link LongArrayTag}.
*
* @param <T> The array type.
*/
public abstract class ArrayTag<T> extends Tag<T> {
public ArrayTag(T value) {
super(value);
if (!value.getClass().isArray()) {
throw new UnsupportedOperationException("type of array tag must be an array");
}
}
public int length() {
return Array.getLength(getValue());
}
@Override
public T getValue() {
return super.getValue();
}
@Override
public void setValue(T value) {
super.setValue(value);
}
@Override
public String valueToString(int maxDepth) {
return arrayToString("", "");
}
protected String arrayToString(@SuppressWarnings("SameParameterValue") String prefix, @SuppressWarnings("SameParameterValue") String suffix) {
StringBuilder sb = new StringBuilder("[").append(prefix).append("".equals(prefix) ? "" : ";");
for (int i = 0; i < length(); i++) {
sb.append(i == 0 ? "" : ",").append(Array.get(getValue(), i)).append(suffix);
}
sb.append("]");
return sb.toString();
}
}

View File

@@ -1,60 +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.data.nbt.tag;
import java.util.Arrays;
public class ByteArrayTag extends ArrayTag<byte[]> implements Comparable<ByteArrayTag> {
public static final byte ID = 7;
public static final byte[] ZERO_VALUE = new byte[0];
public ByteArrayTag() {
super(ZERO_VALUE);
}
public ByteArrayTag(byte[] value) {
super(value);
}
@Override
public byte getID() {
return ID;
}
@Override
public boolean equals(Object other) {
return super.equals(other) && Arrays.equals(getValue(), ((ByteArrayTag) other).getValue());
}
@Override
public int hashCode() {
return Arrays.hashCode(getValue());
}
@Override
public int compareTo(ByteArrayTag other) {
return Integer.compare(length(), other.length());
}
@Override
public ByteArrayTag clone() {
return new ByteArrayTag(Arrays.copyOf(getValue(), length()));
}
}

View File

@@ -1,65 +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.data.nbt.tag;
public class ByteTag extends NumberTag<Byte> implements Comparable<ByteTag> {
public static final byte ID = 1;
public static final byte ZERO_VALUE = 0;
public ByteTag() {
super(ZERO_VALUE);
}
public ByteTag(byte value) {
super(value);
}
public ByteTag(boolean value) {
super((byte) (value ? 1 : 0));
}
@Override
public byte getID() {
return ID;
}
public boolean asBoolean() {
return getValue() > 0;
}
public void setValue(byte value) {
super.setValue(value);
}
@Override
public boolean equals(Object other) {
return super.equals(other) && asByte() == ((ByteTag) other).asByte();
}
@Override
public int compareTo(ByteTag other) {
return getValue().compareTo(other.getValue());
}
@Override
public ByteTag clone() {
return new ByteTag(getValue());
}
}

View File

@@ -1,293 +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.data.nbt.tag;
import com.volmit.iris.engine.data.io.MaxDepthIO;
import com.volmit.iris.util.collection.KMap;
import java.util.*;
import java.util.function.BiConsumer;
@SuppressWarnings("ALL")
public class CompoundTag extends Tag<Map<String, Tag<?>>> implements Iterable<Map.Entry<String, Tag<?>>>, Comparable<CompoundTag>, MaxDepthIO {
public static final byte ID = 10;
public CompoundTag() {
super(createEmptyValue());
}
@Override
public byte getID() {
return ID;
}
private static Map<String, Tag<?>> createEmptyValue() {
return new KMap<>();
}
public int size() {
return getValue().size();
}
public Tag<?> remove(String key) {
return getValue().remove(key);
}
public void clear() {
getValue().clear();
}
public boolean containsKey(String key) {
return getValue().containsKey(key);
}
public boolean containsValue(Tag<?> value) {
return getValue().containsValue(value);
}
public Collection<Tag<?>> values() {
return getValue().values();
}
public Set<String> keySet() {
return getValue().keySet();
}
public Set<Map.Entry<String, Tag<?>>> entrySet() {
return new NonNullEntrySet<>(getValue().entrySet());
}
@Override
public Iterator<Map.Entry<String, Tag<?>>> iterator() {
return entrySet().iterator();
}
public void forEach(BiConsumer<String, Tag<?>> action) {
getValue().forEach(action);
}
public <C extends Tag<?>> C get(String key, Class<C> type) {
Tag<?> t = getValue().get(key);
if (t != null) {
return type.cast(t);
}
return null;
}
public Tag<?> get(String key) {
return getValue().get(key);
}
public ByteTag getByteTag(String key) {
return get(key, ByteTag.class);
}
public ShortTag getShortTag(String key) {
return get(key, ShortTag.class);
}
public IntTag getIntTag(String key) {
return get(key, IntTag.class);
}
public LongTag getLongTag(String key) {
return get(key, LongTag.class);
}
public FloatTag getFloatTag(String key) {
return get(key, FloatTag.class);
}
public DoubleTag getDoubleTag(String key) {
return get(key, DoubleTag.class);
}
public StringTag getStringTag(String key) {
return get(key, StringTag.class);
}
public ByteArrayTag getByteArrayTag(String key) {
return get(key, ByteArrayTag.class);
}
public IntArrayTag getIntArrayTag(String key) {
return get(key, IntArrayTag.class);
}
public LongArrayTag getLongArrayTag(String key) {
return get(key, LongArrayTag.class);
}
public ListTag<?> getListTag(String key) {
return get(key, ListTag.class);
}
public CompoundTag getCompoundTag(String key) {
return get(key, CompoundTag.class);
}
public boolean getBoolean(String key) {
Tag<?> t = get(key);
return t instanceof ByteTag && ((ByteTag) t).asByte() > 0;
}
public byte getByte(String key) {
ByteTag t = getByteTag(key);
return t == null ? ByteTag.ZERO_VALUE : t.asByte();
}
public short getShort(String key) {
ShortTag t = getShortTag(key);
return t == null ? ShortTag.ZERO_VALUE : t.asShort();
}
public int getInt(String key) {
IntTag t = getIntTag(key);
return t == null ? IntTag.ZERO_VALUE : t.asInt();
}
public long getLong(String key) {
LongTag t = getLongTag(key);
return t == null ? LongTag.ZERO_VALUE : t.asLong();
}
public float getFloat(String key) {
FloatTag t = getFloatTag(key);
return t == null ? FloatTag.ZERO_VALUE : t.asFloat();
}
public double getDouble(String key) {
DoubleTag t = getDoubleTag(key);
return t == null ? DoubleTag.ZERO_VALUE : t.asDouble();
}
public String getString(String key) {
StringTag t = getStringTag(key);
return t == null ? StringTag.ZERO_VALUE : t.getValue();
}
public byte[] getByteArray(String key) {
ByteArrayTag t = getByteArrayTag(key);
return t == null ? ByteArrayTag.ZERO_VALUE : t.getValue();
}
public int[] getIntArray(String key) {
IntArrayTag t = getIntArrayTag(key);
return t == null ? IntArrayTag.ZERO_VALUE : t.getValue();
}
public long[] getLongArray(String key) {
LongArrayTag t = getLongArrayTag(key);
return t == null ? LongArrayTag.ZERO_VALUE : t.getValue();
}
public Tag<?> put(String key, Tag<?> tag) {
return getValue().put(Objects.requireNonNull(key), Objects.requireNonNull(tag));
}
public Tag<?> putBoolean(String key, boolean value) {
return put(key, new ByteTag(value));
}
public Tag<?> putByte(String key, byte value) {
return put(key, new ByteTag(value));
}
public Tag<?> putShort(String key, short value) {
return put(key, new ShortTag(value));
}
public Tag<?> putInt(String key, int value) {
return put(key, new IntTag(value));
}
public Tag<?> putLong(String key, long value) {
return put(key, new LongTag(value));
}
public Tag<?> putFloat(String key, float value) {
return put(key, new FloatTag(value));
}
public Tag<?> putDouble(String key, double value) {
return put(key, new DoubleTag(value));
}
public Tag<?> putString(String key, String value) {
return put(key, new StringTag(value));
}
public Tag<?> putByteArray(String key, byte[] value) {
return put(key, new ByteArrayTag(value));
}
public Tag<?> putIntArray(String key, int[] value) {
return put(key, new IntArrayTag(value));
}
public Tag<?> putLongArray(String key, long[] value) {
return put(key, new LongArrayTag(value));
}
@Override
public String valueToString(int maxDepth) {
StringBuilder sb = new StringBuilder("{");
boolean first = true;
for (Map.Entry<String, Tag<?>> e : getValue().entrySet()) {
sb.append(first ? "" : ",")
.append(escapeString(e.getKey(), false)).append(":")
.append(e.getValue().toString(decrementMaxDepth(maxDepth)));
first = false;
}
sb.append("}");
return sb.toString();
}
@Override
public boolean equals(Object other) {
if (this == other) {
return true;
}
if (!super.equals(other) || size() != ((CompoundTag) other).size()) {
return false;
}
for (Map.Entry<String, Tag<?>> e : getValue().entrySet()) {
Tag<?> v;
if ((v = ((CompoundTag) other).get(e.getKey())) == null || !e.getValue().equals(v)) {
return false;
}
}
return true;
}
@Override
public int compareTo(CompoundTag o) {
return Integer.compare(size(), o.getValue().size());
}
@Override
public CompoundTag clone() {
CompoundTag copy = new CompoundTag();
for (Map.Entry<String, Tag<?>> e : getValue().entrySet()) {
copy.put(e.getKey(), e.getValue().clone());
}
return copy;
}
}

View File

@@ -1,57 +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.data.nbt.tag;
public class DoubleTag extends NumberTag<Double> implements Comparable<DoubleTag> {
public static final byte ID = 6;
public static final double ZERO_VALUE = 0.0D;
public DoubleTag() {
super(ZERO_VALUE);
}
public DoubleTag(double value) {
super(value);
}
@Override
public byte getID() {
return ID;
}
public void setValue(double value) {
super.setValue(value);
}
@Override
public boolean equals(Object other) {
return super.equals(other) && getValue().equals(((DoubleTag) other).getValue());
}
@Override
public int compareTo(DoubleTag other) {
return getValue().compareTo(other.getValue());
}
@Override
public DoubleTag clone() {
return new DoubleTag(getValue());
}
}

View File

@@ -1,49 +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.data.nbt.tag;
public final class EndTag extends Tag<Void> {
public static final byte ID = 0;
public static final EndTag INSTANCE = new EndTag();
private EndTag() {
super(null);
}
@Override
public byte getID() {
return ID;
}
@Override
protected Void checkValue(Void value) {
return value;
}
@Override
public String valueToString(int maxDepth) {
return "\"end\"";
}
@Override
public EndTag clone() {
return INSTANCE;
}
}

View File

@@ -1,57 +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.data.nbt.tag;
public class FloatTag extends NumberTag<Float> implements Comparable<FloatTag> {
public static final byte ID = 5;
public static final float ZERO_VALUE = 0.0F;
public FloatTag() {
super(ZERO_VALUE);
}
public FloatTag(float value) {
super(value);
}
@Override
public byte getID() {
return ID;
}
public void setValue(float value) {
super.setValue(value);
}
@Override
public boolean equals(Object other) {
return super.equals(other) && getValue().equals(((FloatTag) other).getValue());
}
@Override
public int compareTo(FloatTag other) {
return getValue().compareTo(other.getValue());
}
@Override
public FloatTag clone() {
return new FloatTag(getValue());
}
}

View File

@@ -1,60 +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.data.nbt.tag;
import java.util.Arrays;
public class IntArrayTag extends ArrayTag<int[]> implements Comparable<IntArrayTag> {
public static final byte ID = 11;
public static final int[] ZERO_VALUE = new int[0];
public IntArrayTag() {
super(ZERO_VALUE);
}
public IntArrayTag(int[] value) {
super(value);
}
@Override
public byte getID() {
return ID;
}
@Override
public boolean equals(Object other) {
return super.equals(other) && Arrays.equals(getValue(), ((IntArrayTag) other).getValue());
}
@Override
public int hashCode() {
return Arrays.hashCode(getValue());
}
@Override
public int compareTo(IntArrayTag other) {
return Integer.compare(length(), other.length());
}
@Override
public IntArrayTag clone() {
return new IntArrayTag(Arrays.copyOf(getValue(), length()));
}
}

View File

@@ -1,57 +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.data.nbt.tag;
public class IntTag extends NumberTag<Integer> implements Comparable<IntTag> {
public static final byte ID = 3;
public static final int ZERO_VALUE = 0;
public IntTag() {
super(ZERO_VALUE);
}
public IntTag(int value) {
super(value);
}
@Override
public byte getID() {
return ID;
}
public void setValue(int value) {
super.setValue(value);
}
@Override
public boolean equals(Object other) {
return super.equals(other) && asInt() == ((IntTag) other).asInt();
}
@Override
public int compareTo(IntTag other) {
return getValue().compareTo(other.getValue());
}
@Override
public IntTag clone() {
return new IntTag(getValue());
}
}

View File

@@ -1,343 +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.data.nbt.tag;
import com.volmit.iris.engine.data.io.MaxDepthIO;
import com.volmit.iris.util.collection.KList;
import java.util.*;
import java.util.function.Consumer;
/**
* ListTag represents a typed List in the nbt structure.
* An empty {@link ListTag} created using {@link ListTag#createUnchecked(Class)} will be of unknown type
* and returns an {@link EndTag}{@code .class} in {@link ListTag#getTypeClass()}.
* The type of an empty untyped {@link ListTag} can be set by using any of the {@code add()}
* methods or any of the {@code as...List()} methods.
*/
@SuppressWarnings("ALL")
public class ListTag<T extends Tag<?>> extends Tag<List<T>> implements Iterable<T>, Comparable<ListTag<T>>, MaxDepthIO {
public static final byte ID = 9;
private Class<?> typeClass = null;
private ListTag() {
super(createEmptyValue(3));
}
@Override
public byte getID() {
return ID;
}
/**
* <p>Creates a non-type-safe ListTag. Its element type will be set after the first
* element was added.</p>
*
* <p>This is an internal helper method for cases where the element type is not known
* at construction time. Use {@link #ListTag(Class)} when the type is known.</p>
*
* @return A new non-type-safe ListTag
*/
public static ListTag<?> createUnchecked(Class<?> typeClass) {
ListTag<?> list = new ListTag<>();
list.typeClass = typeClass;
return list;
}
/**
* <p>Creates an empty mutable list to be used as empty value of ListTags.</p>
*
* @param <T> Type of the list elements
* @param initialCapacity The initial capacity of the returned List
* @return An instance of {@link List} with an initial capacity of 3
*/
private static <T> List<T> createEmptyValue(@SuppressWarnings("SameParameterValue") int initialCapacity) {
return new KList<>(initialCapacity);
}
/**
* @param typeClass The exact class of the elements
* @throws IllegalArgumentException When {@code typeClass} is {@link EndTag}{@code .class}
* @throws NullPointerException When {@code typeClass} is {@code null}
*/
public ListTag(Class<? super T> typeClass) throws IllegalArgumentException, NullPointerException {
super(createEmptyValue(3));
if (typeClass == EndTag.class) {
throw new IllegalArgumentException("cannot create ListTag with EndTag elements");
}
this.typeClass = Objects.requireNonNull(typeClass);
}
public Class<?> getTypeClass() {
return typeClass == null ? EndTag.class : typeClass;
}
public int size() {
return getValue().size();
}
public T remove(int index) {
return getValue().remove(index);
}
public void clear() {
getValue().clear();
}
public boolean contains(T t) {
return getValue().contains(t);
}
public boolean containsAll(Collection<Tag<?>> tags) {
return getValue().containsAll(tags);
}
public void sort(Comparator<T> comparator) {
getValue().sort(comparator);
}
@Override
public Iterator<T> iterator() {
return getValue().iterator();
}
@Override
public void forEach(Consumer<? super T> action) {
getValue().forEach(action);
}
public T set(int index, T t) {
return getValue().set(index, Objects.requireNonNull(t));
}
/**
* Adds a Tag to this ListTag after the last index.
*
* @param t The element to be added.
*/
public void add(T t) {
add(size(), t);
}
public void add(int index, T t) {
Objects.requireNonNull(t);
if (typeClass == null || typeClass == EndTag.class) {
typeClass = t.getClass();
} else if (typeClass != t.getClass()) {
throw new ClassCastException(
String.format("cannot add %s to ListTag<%s>",
t.getClass().getSimpleName(),
typeClass.getSimpleName()));
}
getValue().add(index, t);
}
public void addAll(Collection<T> t) {
for (T tt : t) {
add(tt);
}
}
public void addAll(int index, Collection<T> t) {
int i = 0;
for (T tt : t) {
add(index + i, tt);
i++;
}
}
public void addBoolean(boolean value) {
addUnchecked(new ByteTag(value));
}
public void addByte(byte value) {
addUnchecked(new ByteTag(value));
}
public void addShort(short value) {
addUnchecked(new ShortTag(value));
}
public void addInt(int value) {
addUnchecked(new IntTag(value));
}
public void addLong(long value) {
addUnchecked(new LongTag(value));
}
public void addFloat(float value) {
addUnchecked(new FloatTag(value));
}
public void addDouble(double value) {
addUnchecked(new DoubleTag(value));
}
public void addString(String value) {
addUnchecked(new StringTag(value));
}
public void addByteArray(byte[] value) {
addUnchecked(new ByteArrayTag(value));
}
public void addIntArray(int[] value) {
addUnchecked(new IntArrayTag(value));
}
public void addLongArray(long[] value) {
addUnchecked(new LongArrayTag(value));
}
public T get(int index) {
return getValue().get(index);
}
public int indexOf(T t) {
return getValue().indexOf(t);
}
@SuppressWarnings("unchecked")
public <L extends Tag<?>> ListTag<L> asTypedList(Class<L> type) {
checkTypeClass(type);
typeClass = type;
return (ListTag<L>) this;
}
public ListTag<ByteTag> asByteTagList() {
return asTypedList(ByteTag.class);
}
public ListTag<ShortTag> asShortTagList() {
return asTypedList(ShortTag.class);
}
public ListTag<IntTag> asIntTagList() {
return asTypedList(IntTag.class);
}
public ListTag<LongTag> asLongTagList() {
return asTypedList(LongTag.class);
}
public ListTag<FloatTag> asFloatTagList() {
return asTypedList(FloatTag.class);
}
public ListTag<DoubleTag> asDoubleTagList() {
return asTypedList(DoubleTag.class);
}
public ListTag<StringTag> asStringTagList() {
return asTypedList(StringTag.class);
}
public ListTag<ByteArrayTag> asByteArrayTagList() {
return asTypedList(ByteArrayTag.class);
}
public ListTag<IntArrayTag> asIntArrayTagList() {
return asTypedList(IntArrayTag.class);
}
public ListTag<LongArrayTag> asLongArrayTagList() {
return asTypedList(LongArrayTag.class);
}
@SuppressWarnings("unchecked")
public ListTag<ListTag<?>> asListTagList() {
checkTypeClass(ListTag.class);
typeClass = ListTag.class;
return (ListTag<ListTag<?>>) this;
}
public ListTag<CompoundTag> asCompoundTagList() {
return asTypedList(CompoundTag.class);
}
@Override
public String valueToString(int maxDepth) {
StringBuilder sb = new StringBuilder("{\"type\":\"").append(getTypeClass().getSimpleName()).append("\",\"list\":[");
for (int i = 0; i < size(); i++) {
sb.append(i > 0 ? "," : "").append(get(i).valueToString(decrementMaxDepth(maxDepth)));
}
sb.append("]}");
return sb.toString();
}
@Override
public boolean equals(Object other) {
if (this == other) {
return true;
}
if (!super.equals(other) || size() != ((ListTag<?>) other).size() || getTypeClass() != ((ListTag<?>) other).getTypeClass()) {
return false;
}
for (int i = 0; i < size(); i++) {
if (!get(i).equals(((ListTag<?>) other).get(i))) {
return false;
}
}
return true;
}
@Override
public int hashCode() {
return Objects.hash(getTypeClass().hashCode(), getValue().hashCode());
}
@Override
public int compareTo(ListTag<T> o) {
return Integer.compare(size(), o.getValue().size());
}
@SuppressWarnings("unchecked")
@Override
public ListTag<T> clone() {
ListTag<T> copy = new ListTag<>();
// assure type safety for clone
copy.typeClass = typeClass;
for (T t : getValue()) {
copy.add((T) t.clone());
}
return copy;
}
//TODO: make private
@SuppressWarnings("unchecked")
public void addUnchecked(Tag<?> tag) {
if (typeClass != null && typeClass != tag.getClass() && typeClass != EndTag.class) {
throw new IllegalArgumentException(String.format(
"cannot add %s to ListTag<%s>",
tag.getClass().getSimpleName(), typeClass.getSimpleName()));
}
add(size(), (T) tag);
}
private void checkTypeClass(Class<?> clazz) {
if (typeClass != null && typeClass != EndTag.class && typeClass != clazz) {
throw new ClassCastException(String.format(
"cannot cast ListTag<%s> to ListTag<%s>",
typeClass.getSimpleName(), clazz.getSimpleName()));
}
}
}

View File

@@ -1,60 +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.data.nbt.tag;
import java.util.Arrays;
public class LongArrayTag extends ArrayTag<long[]> implements Comparable<LongArrayTag> {
public static final byte ID = 12;
public static final long[] ZERO_VALUE = new long[0];
public LongArrayTag() {
super(ZERO_VALUE);
}
public LongArrayTag(long[] value) {
super(value);
}
@Override
public byte getID() {
return ID;
}
@Override
public boolean equals(Object other) {
return super.equals(other) && Arrays.equals(getValue(), ((LongArrayTag) other).getValue());
}
@Override
public int hashCode() {
return Arrays.hashCode(getValue());
}
@Override
public int compareTo(LongArrayTag other) {
return Integer.compare(length(), other.length());
}
@Override
public LongArrayTag clone() {
return new LongArrayTag(Arrays.copyOf(getValue(), length()));
}
}

View File

@@ -1,57 +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.data.nbt.tag;
public class LongTag extends NumberTag<Long> implements Comparable<LongTag> {
public static final byte ID = 4;
public static final long ZERO_VALUE = 0L;
public LongTag() {
super(ZERO_VALUE);
}
public LongTag(long value) {
super(value);
}
@Override
public byte getID() {
return ID;
}
public void setValue(long value) {
super.setValue(value);
}
@Override
public boolean equals(Object other) {
return super.equals(other) && asLong() == ((LongTag) other).asLong();
}
@Override
public int compareTo(LongTag other) {
return getValue().compareTo(other.getValue());
}
@Override
public LongTag clone() {
return new LongTag(getValue());
}
}

View File

@@ -1,160 +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.data.nbt.tag;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
/**
* A decorator for the Set returned by CompoundTag#entrySet()
* that disallows setting null values.
*/
@SuppressWarnings("ClassCanBeRecord")
class NonNullEntrySet<K, V> implements Set<Map.Entry<K, V>> {
private final Set<Map.Entry<K, V>> set;
NonNullEntrySet(Set<Map.Entry<K, V>> set) {
this.set = set;
}
@Override
public int size() {
return set.size();
}
@Override
public boolean isEmpty() {
return set.isEmpty();
}
@Override
public boolean contains(Object o) {
return set.contains(o);
}
@Override
public Iterator<Map.Entry<K, V>> iterator() {
return new NonNullEntrySetIterator(set.iterator());
}
@Override
public Object[] toArray() {
return set.toArray();
}
@Override
public <T> T[] toArray(T[] a) {
return set.toArray(a);
}
@Override
public boolean add(Map.Entry<K, V> kvEntry) {
return set.add(kvEntry);
}
@Override
public boolean remove(Object o) {
return set.remove(o);
}
@Override
public boolean containsAll(Collection<?> c) {
return set.containsAll(c);
}
@Override
public boolean addAll(Collection<? extends Map.Entry<K, V>> c) {
return set.addAll(c);
}
@Override
public boolean retainAll(Collection<?> c) {
return set.retainAll(c);
}
@Override
public boolean removeAll(Collection<?> c) {
return set.removeAll(c);
}
@Override
public void clear() {
set.clear();
}
class NonNullEntrySetIterator implements Iterator<Map.Entry<K, V>> {
private final Iterator<Map.Entry<K, V>> iterator;
NonNullEntrySetIterator(Iterator<Map.Entry<K, V>> iterator) {
this.iterator = iterator;
}
@Override
public boolean hasNext() {
return iterator.hasNext();
}
@Override
public Map.Entry<K, V> next() {
return new NonNullEntry(iterator.next());
}
}
class NonNullEntry implements Map.Entry<K, V> {
private final Map.Entry<K, V> entry;
NonNullEntry(Map.Entry<K, V> entry) {
this.entry = entry;
}
@Override
public K getKey() {
return entry.getKey();
}
@Override
public V getValue() {
return entry.getValue();
}
@Override
public V setValue(V value) {
if (value == null) {
throw new NullPointerException(getClass().getSimpleName() + " does not allow setting null");
}
return entry.setValue(value);
}
@SuppressWarnings("EqualsWhichDoesntCheckParameterClass")
@Override
public boolean equals(Object o) {
return entry.equals(o);
}
@Override
public int hashCode() {
return entry.hashCode();
}
}
}

View File

@@ -1,55 +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.data.nbt.tag;
public abstract class NumberTag<T extends Number & Comparable<T>> extends Tag<T> {
public NumberTag(T value) {
super(value);
}
public byte asByte() {
return getValue().byteValue();
}
public short asShort() {
return getValue().shortValue();
}
public int asInt() {
return getValue().intValue();
}
public long asLong() {
return getValue().longValue();
}
public float asFloat() {
return getValue().floatValue();
}
public double asDouble() {
return getValue().doubleValue();
}
@Override
public String valueToString(int maxDepth) {
return getValue().toString();
}
}

View File

@@ -1,57 +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.data.nbt.tag;
public class ShortTag extends NumberTag<Short> implements Comparable<ShortTag> {
public static final byte ID = 2;
public static final short ZERO_VALUE = 0;
public ShortTag() {
super(ZERO_VALUE);
}
public ShortTag(short value) {
super(value);
}
@Override
public byte getID() {
return ID;
}
public void setValue(short value) {
super.setValue(value);
}
@Override
public boolean equals(Object other) {
return super.equals(other) && asShort() == ((ShortTag) other).asShort();
}
@Override
public int compareTo(ShortTag other) {
return getValue().compareTo(other.getValue());
}
@Override
public ShortTag clone() {
return new ShortTag(getValue());
}
}

View File

@@ -1,68 +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.data.nbt.tag;
public class StringTag extends Tag<String> implements Comparable<StringTag> {
public static final byte ID = 8;
public static final String ZERO_VALUE = "";
public StringTag() {
super(ZERO_VALUE);
}
public StringTag(String value) {
super(value);
}
@Override
public byte getID() {
return ID;
}
@Override
public String getValue() {
return super.getValue();
}
@Override
public void setValue(String value) {
super.setValue(value);
}
@Override
public String valueToString(int maxDepth) {
return escapeString(getValue(), false);
}
@Override
public boolean equals(Object other) {
return super.equals(other) && getValue().equals(((StringTag) other).getValue());
}
@Override
public int compareTo(StringTag o) {
return getValue().compareTo(o.getValue());
}
@Override
public StringTag clone() {
return new StringTag(getValue());
}
}

View File

@@ -1,219 +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.data.nbt.tag;
import com.volmit.iris.engine.data.io.MaxDepthReachedException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Base class for all NBT tags.
*
* <h1>Nesting</h1>
* <p>All methods serializing instances or deserializing data track the nesting levels to prevent
* circular references or malicious data which could, when deserialized, result in thousands
* of instances causing a denial of service.</p>
*
* <p>These methods have a parameter for the maximum nesting depth they are allowed to traverse. A
* value of {@code 0} means that only the object itself, but no nested objects may be processed.
* If an instance is nested further than allowed, a {@link MaxDepthReachedException} will be thrown.
* Providing a negative maximum nesting depth will cause an {@code IllegalArgumentException}
* to be thrown.</p>
*
* <p>Some methods do not provide a parameter to specify the maximum nesting depth, but instead use
* {@link #DEFAULT_MAX_DEPTH}, which is also the maximum used by Minecraft. This is documented for
* the respective methods.</p>
*
* <p>If custom NBT tags contain objects other than NBT tags, which can be nested as well, then there
* is no guarantee that {@code MaxDepthReachedException}s are thrown for them. The respective class
* will document this behavior accordingly.</p>
*
* @param <T> The type of the contained value
*/
public abstract class Tag<T> implements Cloneable {
/**
* The default maximum depth of the NBT structure.
*/
public static final int DEFAULT_MAX_DEPTH = 512;
private static final Map<String, String> ESCAPE_CHARACTERS;
static {
final Map<String, String> temp = new HashMap<>();
temp.put("\\", "\\\\\\\\");
temp.put("\n", "\\\\n");
temp.put("\t", "\\\\t");
temp.put("\r", "\\\\r");
temp.put("\"", "\\\\\"");
//noinspection Java9CollectionFactory
ESCAPE_CHARACTERS = Collections.unmodifiableMap(temp);
}
private static final Pattern ESCAPE_PATTERN = Pattern.compile("[\\\\\n\t\r\"]");
private static final Pattern NON_QUOTE_PATTERN = Pattern.compile("[a-zA-Z0-9_\\-+]+");
private T value;
/**
* Initializes this Tag with some value. If the value is {@code null}, it will
* throw a {@code NullPointerException}
*
* @param value The value to be set for this Tag.
*/
public Tag(T value) {
setValue(value);
}
/**
* @return This Tag's ID, usually used for serialization and deserialization.
*/
public abstract byte getID();
/**
* @return The value of this Tag.
*/
protected T getValue() {
return value;
}
/**
* Sets the value for this Tag directly.
*
* @param value The value to be set.
* @throws NullPointerException If the value is null
*/
protected void setValue(T value) {
this.value = checkValue(value);
}
/**
* Checks if the value {@code value} is {@code null}.
*
* @param value The value to check
* @return The parameter {@code value}
* @throws NullPointerException If {@code value} was {@code null}
*/
protected T checkValue(T value) {
return Objects.requireNonNull(value);
}
/**
* Calls {@link Tag#toString(int)} with an initial depth of {@code 0}.
*
* @throws MaxDepthReachedException If the maximum nesting depth is exceeded.
* @see Tag#toString(int)
*/
@Override
public final String toString() {
return toString(DEFAULT_MAX_DEPTH);
}
/**
* Creates a string representation of this Tag in a valid JSON format.
*
* @param maxDepth The maximum nesting depth.
* @return The string representation of this Tag.
* @throws MaxDepthReachedException If the maximum nesting depth is exceeded.
*/
public String toString(int maxDepth) {
return "{\"type\":\"" + getClass().getSimpleName() + "\"," +
"\"value\":" + valueToString(maxDepth) + "}";
}
/**
* Calls {@link Tag#valueToString(int)} with {@link Tag#DEFAULT_MAX_DEPTH}.
*
* @return The string representation of the value of this Tag.
* @throws MaxDepthReachedException If the maximum nesting depth is exceeded.
*/
public String valueToString() {
return valueToString(DEFAULT_MAX_DEPTH);
}
/**
* Returns a JSON representation of the value of this Tag.
*
* @param maxDepth The maximum nesting depth.
* @return The string representation of the value of this Tag.
* @throws MaxDepthReachedException If the maximum nesting depth is exceeded.
*/
public abstract String valueToString(int maxDepth);
/**
* Returns whether this Tag and some other Tag are equal.
* They are equal if {@code other} is not {@code null} and they are of the same class.
* Custom Tag implementations should overwrite this but check the result
* of this {@code super}-method while comparing.
*
* @param other The Tag to compare to.
* @return {@code true} if they are equal based on the conditions mentioned above.
*/
@Override
public boolean equals(Object other) {
return other != null && getClass() == other.getClass();
}
/**
* Calculates the hash code of this Tag. Tags which are equal according to {@link Tag#equals(Object)}
* must return an equal hash code.
*
* @return The hash code of this Tag.
*/
@Override
public int hashCode() {
return value.hashCode();
}
/**
* Creates a clone of this Tag.
*
* @return A clone of this Tag.
*/
public abstract Tag<T> clone();
/**
* Escapes a string to fit into a JSON-like string representation for Minecraft
* or to create the JSON string representation of a Tag returned from {@link Tag#toString()}
*
* @param s The string to be escaped.
* @param lenient {@code true} if it should force double quotes ({@code "}) at the start and
* the end of the string.
* @return The escaped string.
*/
@SuppressWarnings("StringBufferMayBeStringBuilder")
protected static String escapeString(String s, @SuppressWarnings("SameParameterValue") boolean lenient) {
StringBuffer sb = new StringBuffer();
Matcher m = ESCAPE_PATTERN.matcher(s);
while (m.find()) {
m.appendReplacement(sb, ESCAPE_CHARACTERS.get(m.group()));
}
m.appendTail(sb);
m = NON_QUOTE_PATTERN.matcher(s);
if (!lenient || !m.matches()) {
sb.insert(0, "\"").append("\"");
}
return sb.toString();
}
}

View File

@@ -22,7 +22,7 @@ import com.volmit.iris.engine.data.cache.Cache;
import com.volmit.iris.engine.framework.Engine;
import com.volmit.iris.util.hunk.Hunk;
import com.volmit.iris.engine.object.decoration.IrisDecorationPart;
import com.volmit.iris.engine.object.biome.LoaderBiome;
import com.volmit.iris.engine.object.biome.IrisBiome;
import com.volmit.iris.engine.object.decoration.IrisDecorator;
import com.volmit.iris.util.documentation.BlockCoordinates;
import org.bukkit.block.data.BlockData;
@@ -34,7 +34,7 @@ public class IrisCeilingDecorator extends IrisEngineDecorator {
@BlockCoordinates
@Override
public void decorate(int x, int z, int realX, int realX1, int realX_1, int realZ, int realZ1, int realZ_1, Hunk<BlockData> data, LoaderBiome biome, int height, int max) {
public void decorate(int x, int z, int realX, int realX1, int realX_1, int realZ, int realZ1, int realZ_1, Hunk<BlockData> data, IrisBiome biome, int height, int max) {
IrisDecorator decorator = getDecorator(biome, realX, realZ);
if (decorator != null) {

View File

@@ -24,7 +24,7 @@ import com.volmit.iris.engine.framework.Engine;
import com.volmit.iris.engine.framework.EngineAssignedComponent;
import com.volmit.iris.engine.framework.EngineDecorator;
import com.volmit.iris.engine.object.decoration.IrisDecorationPart;
import com.volmit.iris.engine.object.biome.LoaderBiome;
import com.volmit.iris.engine.object.biome.IrisBiome;
import com.volmit.iris.engine.object.decoration.IrisDecorator;
import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.math.RNG;
@@ -44,7 +44,7 @@ public abstract class IrisEngineDecorator extends EngineAssignedComponent implem
this.rng = new RNG(getSeed() + 29356788 - (part.ordinal() * 10439677L));
}
protected IrisDecorator getDecorator(LoaderBiome biome, double realX, double realZ) {
protected IrisDecorator getDecorator(IrisBiome biome, double realX, double realZ) {
KList<IrisDecorator> v = new KList<>();
RNG rng = new RNG(Cache.key((int) realX, (int) realZ));

View File

@@ -22,7 +22,7 @@ import com.volmit.iris.engine.data.cache.Cache;
import com.volmit.iris.engine.framework.Engine;
import com.volmit.iris.util.hunk.Hunk;
import com.volmit.iris.engine.object.decoration.IrisDecorationPart;
import com.volmit.iris.engine.object.biome.LoaderBiome;
import com.volmit.iris.engine.object.biome.IrisBiome;
import com.volmit.iris.engine.object.decoration.IrisDecorator;
import com.volmit.iris.util.documentation.BlockCoordinates;
import org.bukkit.block.data.BlockData;
@@ -34,7 +34,7 @@ public class IrisSeaFloorDecorator extends IrisEngineDecorator {
@BlockCoordinates
@Override
public void decorate(int x, int z, int realX, int realX1, int realX_1, int realZ, int realZ1, int realZ_1, Hunk<BlockData> data, LoaderBiome biome, int height, int max) {
public void decorate(int x, int z, int realX, int realX1, int realX_1, int realZ, int realZ1, int realZ_1, Hunk<BlockData> data, IrisBiome biome, int height, int max) {
IrisDecorator decorator = getDecorator(biome, realX, realZ);
if (decorator != null) {

View File

@@ -22,7 +22,7 @@ import com.volmit.iris.engine.data.cache.Cache;
import com.volmit.iris.engine.framework.Engine;
import com.volmit.iris.util.hunk.Hunk;
import com.volmit.iris.engine.object.decoration.IrisDecorationPart;
import com.volmit.iris.engine.object.biome.LoaderBiome;
import com.volmit.iris.engine.object.biome.IrisBiome;
import com.volmit.iris.engine.object.decoration.IrisDecorator;
import com.volmit.iris.util.documentation.BlockCoordinates;
import org.bukkit.block.data.BlockData;
@@ -34,7 +34,7 @@ public class IrisSeaSurfaceDecorator extends IrisEngineDecorator {
@BlockCoordinates
@Override
public void decorate(int x, int z, int realX, int realX1, int realX_1, int realZ, int realZ1, int realZ_1, Hunk<BlockData> data, LoaderBiome biome, int height, int max) {
public void decorate(int x, int z, int realX, int realX1, int realX_1, int realZ, int realZ1, int realZ_1, Hunk<BlockData> data, IrisBiome biome, int height, int max) {
IrisDecorator decorator = getDecorator(biome, realX, realZ);
if (decorator != null) {

View File

@@ -22,7 +22,7 @@ import com.volmit.iris.engine.data.cache.Cache;
import com.volmit.iris.engine.framework.Engine;
import com.volmit.iris.util.hunk.Hunk;
import com.volmit.iris.engine.object.decoration.IrisDecorationPart;
import com.volmit.iris.engine.object.biome.LoaderBiome;
import com.volmit.iris.engine.object.biome.IrisBiome;
import com.volmit.iris.engine.object.decoration.IrisDecorator;
import com.volmit.iris.util.documentation.BlockCoordinates;
import org.bukkit.block.data.BlockData;
@@ -34,7 +34,7 @@ public class IrisShoreLineDecorator extends IrisEngineDecorator {
@BlockCoordinates
@Override
public void decorate(int x, int z, int realX, int realX1, int realX_1, int realZ, int realZ1, int realZ_1, Hunk<BlockData> data, LoaderBiome biome, int height, int max) {
public void decorate(int x, int z, int realX, int realX1, int realX_1, int realZ, int realZ1, int realZ_1, Hunk<BlockData> data, IrisBiome biome, int height, int max) {
if (height == getDimension().getFluidHeight()) {
if (Math.round(getComplex().getHeightStream().get(realX1, realZ)) < getComplex().getFluidHeight() ||

View File

@@ -24,7 +24,7 @@ import com.volmit.iris.engine.framework.Engine;
import com.volmit.iris.util.hunk.Hunk;
import com.volmit.iris.engine.object.decoration.IrisDecorationPart;
import com.volmit.iris.engine.object.biome.InferredType;
import com.volmit.iris.engine.object.biome.LoaderBiome;
import com.volmit.iris.engine.object.biome.IrisBiome;
import com.volmit.iris.engine.object.decoration.IrisDecorator;
import com.volmit.iris.util.documentation.BlockCoordinates;
import org.bukkit.block.data.Bisected;
@@ -37,7 +37,7 @@ public class IrisSurfaceDecorator extends IrisEngineDecorator {
@BlockCoordinates
@Override
public void decorate(int x, int z, int realX, int realX1, int realX_1, int realZ, int realZ1, int realZ_1, Hunk<BlockData> data, LoaderBiome biome, int height, int max) {
public void decorate(int x, int z, int realX, int realX1, int realX_1, int realZ, int realZ1, int realZ_1, Hunk<BlockData> data, IrisBiome biome, int height, int max) {
if (biome.getInferredType().equals(InferredType.SHORE) && height < getDimension().getFluidHeight()) {
return;
}

View File

@@ -23,16 +23,16 @@ import com.volmit.iris.core.gui.components.RenderType;
import com.volmit.iris.core.gui.components.Renderer;
import com.volmit.iris.core.project.loader.IrisData;
import com.volmit.iris.engine.data.cache.Cache;
import com.volmit.iris.engine.data.B;
import com.volmit.iris.engine.data.DataProvider;
import com.volmit.iris.util.data.B;
import com.volmit.iris.util.data.DataProvider;
import com.volmit.iris.engine.object.basic.IrisColor;
import com.volmit.iris.engine.object.biome.LoaderBiome;
import com.volmit.iris.engine.object.dimensional.LoaderDimension;
import com.volmit.iris.engine.object.biome.IrisBiome;
import com.volmit.iris.engine.object.dimensional.IrisDimension;
import com.volmit.iris.engine.object.loot.IrisLootReference;
import com.volmit.iris.engine.object.loot.LoaderLootTable;
import com.volmit.iris.engine.object.loot.IrisLootTable;
import com.volmit.iris.engine.object.loot.IrisLootMode;
import com.volmit.iris.engine.object.meta.InventorySlotType;
import com.volmit.iris.engine.object.regional.LoaderRegion;
import com.volmit.iris.engine.object.regional.IrisRegion;
import com.volmit.iris.util.hunk.Hunk;
import com.volmit.iris.engine.object.common.IrisWorld;
import com.volmit.iris.engine.object.engine.IrisEngineData;
@@ -132,7 +132,7 @@ public interface Engine extends DataProvider, Fallible, GeneratorAccess, LootPro
return getTarget().getWorld();
}
default LoaderDimension getDimension() {
default IrisDimension getDimension() {
return getTarget().getDimension();
}
@@ -142,8 +142,8 @@ public interface Engine extends DataProvider, Fallible, GeneratorAccess, LootPro
@BlockCoordinates
default Color draw(double x, double z) {
LoaderRegion region = getRegion((int) x, (int) z);
LoaderBiome biome = getSurfaceBiome((int) x, (int) z);
IrisRegion region = getRegion((int) x, (int) z);
IrisBiome biome = getSurfaceBiome((int) x, (int) z);
int height = getHeight((int) x, (int) z);
double heightFactor = M.lerpInverse(0, getHeight(), height);
Color irc = region.getColor(this.getFramework().getComplex(), RenderType.BIOME);
@@ -157,7 +157,7 @@ public interface Engine extends DataProvider, Fallible, GeneratorAccess, LootPro
@BlockCoordinates
@Override
default LoaderRegion getRegion(int x, int z) {
default IrisRegion getRegion(int x, int z) {
return getFramework().getComplex().getRegionStream().get(x, z);
}
@@ -168,13 +168,13 @@ public interface Engine extends DataProvider, Fallible, GeneratorAccess, LootPro
@BlockCoordinates
@Override
default LoaderBiome getCaveBiome(int x, int z) {
default IrisBiome getCaveBiome(int x, int z) {
return getFramework().getComplex().getCaveBiomeStream().get(x, z);
}
@BlockCoordinates
@Override
default LoaderBiome getSurfaceBiome(int x, int z) {
default IrisBiome getSurfaceBiome(int x, int z) {
return getFramework().getComplex().getTrueBiomeStream().get(x, z);
}
@@ -262,7 +262,7 @@ public interface Engine extends DataProvider, Fallible, GeneratorAccess, LootPro
}
if (slot != null) {
KList<LoaderLootTable> tables = getLootTables(rx, block);
KList<IrisLootTable> tables = getLootTables(rx, block);
try {
InventoryHolder m = (InventoryHolder) block.getState();
@@ -315,7 +315,7 @@ public interface Engine extends DataProvider, Fallible, GeneratorAccess, LootPro
}
@Override
default void injectTables(KList<LoaderLootTable> list, IrisLootReference r) {
default void injectTables(KList<IrisLootTable> list, IrisLootReference r) {
if (r.getMode().equals(IrisLootMode.CLEAR) || r.getMode().equals(IrisLootMode.REPLACE)) {
list.clear();
}
@@ -325,7 +325,7 @@ public interface Engine extends DataProvider, Fallible, GeneratorAccess, LootPro
@BlockCoordinates
@Override
default KList<LoaderLootTable> getLootTables(RNG rng, Block b) {
default KList<IrisLootTable> getLootTables(RNG rng, Block b) {
int rx = b.getX();
int rz = b.getZ();
double he = getFramework().getComplex().getHeightStream().get(rx, rz);
@@ -333,16 +333,16 @@ public interface Engine extends DataProvider, Fallible, GeneratorAccess, LootPro
if (po != null && po.getPlacement() != null) {
if (B.isStorageChest(b.getBlockData())) {
LoaderLootTable table = po.getPlacement().getTable(b.getBlockData(), getData());
IrisLootTable table = po.getPlacement().getTable(b.getBlockData(), getData());
if (table != null) {
return new KList<>(table);
}
}
}
LoaderRegion region = getFramework().getComplex().getRegionStream().get(rx, rz);
LoaderBiome biomeSurface = getFramework().getComplex().getTrueBiomeStream().get(rx, rz);
LoaderBiome biomeUnder = b.getY() < he ? getFramework().getComplex().getCaveBiomeStream().get(rx, rz) : biomeSurface;
KList<LoaderLootTable> tables = new KList<>();
IrisRegion region = getFramework().getComplex().getRegionStream().get(rx, rz);
IrisBiome biomeSurface = getFramework().getComplex().getTrueBiomeStream().get(rx, rz);
IrisBiome biomeUnder = b.getY() < he ? getFramework().getComplex().getCaveBiomeStream().get(rx, rz) : biomeSurface;
KList<IrisLootTable> tables = new KList<>();
double multiplier = 1D * getDimension().getLoot().getMultiplier() * region.getLoot().getMultiplier() * biomeSurface.getLoot().getMultiplier() * biomeUnder.getLoot().getMultiplier();
injectTables(tables, getDimension().getLoot());
injectTables(tables, region.getLoot());
@@ -365,11 +365,11 @@ public interface Engine extends DataProvider, Fallible, GeneratorAccess, LootPro
}
@Override
default void addItems(boolean debug, Inventory inv, RNG rng, KList<LoaderLootTable> tables, InventorySlotType slot, int x, int y, int z, int mgf) {
default void addItems(boolean debug, Inventory inv, RNG rng, KList<IrisLootTable> tables, InventorySlotType slot, int x, int y, int z, int mgf) {
KList<ItemStack> items = new KList<>();
int b = 4;
for (LoaderLootTable i : tables) {
for (IrisLootTable i : tables) {
b++;
items.addAll(i.getLoot(debug, items.isEmpty(), rng, slot, x, y, z, b + b, mgf + b));
}
@@ -402,12 +402,12 @@ public interface Engine extends DataProvider, Fallible, GeneratorAccess, LootPro
}
@BlockCoordinates
default LoaderBiome getBiome(Location l) {
default IrisBiome getBiome(Location l) {
return getBiome(l.getBlockX(), l.getBlockY(), l.getBlockZ());
}
@BlockCoordinates
default LoaderRegion getRegion(Location l) {
default IrisRegion getRegion(Location l) {
return getRegion(l.getBlockX(), l.getBlockZ());
}
@@ -416,15 +416,15 @@ public interface Engine extends DataProvider, Fallible, GeneratorAccess, LootPro
return l.getBlockY() >= getMinHeight() && l.getBlockY() <= getMaxHeight();
}
LoaderBiome getFocus();
IrisBiome getFocus();
IrisEngineData getEngineData();
default LoaderBiome getSurfaceBiome(Chunk c) {
default IrisBiome getSurfaceBiome(Chunk c) {
return getSurfaceBiome((c.getX() << 4) + 8, (c.getZ() << 4) + 8);
}
default LoaderRegion getRegion(Chunk c) {
default IrisRegion getRegion(Chunk c) {
return getRegion((c.getX() << 4) + 8, (c.getZ() << 4) + 8);
}
}

View File

@@ -21,7 +21,7 @@ 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.object.dimensional.LoaderDimension;
import com.volmit.iris.engine.object.dimensional.IrisDimension;
import com.volmit.iris.engine.parallax.ParallaxAccess;
import com.volmit.iris.util.math.RollingSequence;
import org.bukkit.event.Listener;
@@ -64,7 +64,7 @@ public interface EngineComponent {
return getEngine().getTarget();
}
default LoaderDimension getDimension() {
default IrisDimension getDimension() {
return getEngine().getDimension();
}

View File

@@ -25,15 +25,15 @@ import com.volmit.iris.core.pregenerator.PregenListener;
import com.volmit.iris.core.pregenerator.PregenTask;
import com.volmit.iris.core.project.loader.IrisData;
import com.volmit.iris.engine.IrisEngineCompound;
import com.volmit.iris.engine.data.B;
import com.volmit.iris.util.data.B;
import com.volmit.iris.engine.data.chunk.MCATerrainChunk;
import com.volmit.iris.engine.data.chunk.TerrainChunk;
import com.volmit.iris.engine.data.mca.NBTWorld;
import com.volmit.iris.engine.data.nbt.tag.CompoundTag;
import com.volmit.iris.util.nbt.mca.NBTWorld;
import com.volmit.iris.util.nbt.tag.CompoundTag;
import com.volmit.iris.engine.framework.headless.HeadlessGenerator;
import com.volmit.iris.util.hunk.Hunk;
import com.volmit.iris.engine.object.biome.LoaderBiome;
import com.volmit.iris.engine.object.dimensional.LoaderDimension;
import com.volmit.iris.engine.object.biome.IrisBiome;
import com.volmit.iris.engine.object.dimensional.IrisDimension;
import com.volmit.iris.engine.object.basic.IrisPosition;
import com.volmit.iris.engine.object.common.IrisWorld;
import com.volmit.iris.util.parallel.BurstExecutor;
@@ -202,11 +202,11 @@ public class EngineCompositeGenerator extends ChunkGenerator implements IrisAcce
return false;
}
private synchronized LoaderDimension getDimension(IrisWorld world) {
private synchronized IrisDimension getDimension(IrisWorld world) {
String query = dimensionQuery;
query = Iris.linkMultiverseCore.getWorldNameType(world.name(), query);
LoaderDimension dim = null;
IrisDimension dim = null;
if (query == null) {
File iris = new File(world.worldFolder(), "iris");
@@ -253,7 +253,7 @@ public class EngineCompositeGenerator extends ChunkGenerator implements IrisAcce
}
if (production) {
LoaderDimension od = dim;
IrisDimension od = dim;
dim = new IrisData(getDataFolder(world)).getDimensionLoader().load(od.getLoadKey());
if (dim == null) {
@@ -270,9 +270,9 @@ public class EngineCompositeGenerator extends ChunkGenerator implements IrisAcce
return dim;
}
private synchronized LoaderDimension getDimension(String world) {
private synchronized IrisDimension getDimension(String world) {
String query = dimensionQuery;
LoaderDimension dim = null;
IrisDimension dim = null;
if (query == null) {
File iris = new File(world + "/iris");
@@ -319,7 +319,7 @@ public class EngineCompositeGenerator extends ChunkGenerator implements IrisAcce
}
if (production) {
LoaderDimension od = dim;
IrisDimension od = dim;
dim = new IrisData(getDataFolder(world)).getDimensionLoader().load(od.getLoadKey());
if (dim == null) {
@@ -345,7 +345,7 @@ public class EngineCompositeGenerator extends ChunkGenerator implements IrisAcce
try {
initialized.set(true);
LoaderDimension dim = getDimension(world);
IrisDimension dim = getDimension(world);
IrisData data = production ? new IrisData(getDataFolder(world)) : dim.getLoader().copy();
compound.set(new IrisEngineCompound(world, dim, data, IrisSettings.getThreadCount(IrisSettings.get().getConcurrency().getEngineThreadCount())));
compound.get().setStudio(!production);
@@ -572,7 +572,7 @@ public class EngineCompositeGenerator extends ChunkGenerator implements IrisAcce
try {
int ox = x << 4;
int oz = z << 4;
com.volmit.iris.engine.data.mca.Chunk chunk = writer.getChunk(x, z);
com.volmit.iris.util.nbt.mca.Chunk chunk = writer.getChunk(x, z);
generateChunkRawData(w, x, z, MCATerrainChunk.builder()
.writer(writer).ox(ox).oz(oz).mcaChunk(chunk)
.minHeight(w.minHeight()).maxHeight(w.maxHeight())
@@ -584,7 +584,7 @@ public class EngineCompositeGenerator extends ChunkGenerator implements IrisAcce
e.printStackTrace();
Iris.reportErrorChunk(x, z, e, "MCA");
Iris.error("======================================");
com.volmit.iris.engine.data.mca.Chunk chunk = writer.getChunk(x, z);
com.volmit.iris.util.nbt.mca.Chunk chunk = writer.getChunk(x, z);
CompoundTag c = NBTWorld.getCompound(ERROR_BLOCK);
for (int i = 0; i < 16; i++) {
for (int j = 0; j < 16; j++) {
@@ -673,12 +673,12 @@ public class EngineCompositeGenerator extends ChunkGenerator implements IrisAcce
}
@Override
public LoaderBiome getBiome(int x, int z) {
public IrisBiome getBiome(int x, int z) {
return getBiome(x, 0, z);
}
@Override
public LoaderBiome getCaveBiome(int x, int z) {
public IrisBiome getCaveBiome(int x, int z) {
return getCaveBiome(x, 0, z);
}
@@ -693,13 +693,13 @@ public class EngineCompositeGenerator extends ChunkGenerator implements IrisAcce
}
@Override
public LoaderBiome getBiome(int x, int y, int z) {
public IrisBiome getBiome(int x, int y, int z) {
// TODO: REMOVE GET ABS BIOME OR THIS ONE
return getEngineAccess(y).getBiome(x, y - getComposite().getEngineForHeight(y).getMinHeight(), z);
}
@Override
public LoaderBiome getCaveBiome(int x, int y, int z) {
public IrisBiome getCaveBiome(int x, int y, int z) {
return getEngineAccess(y).getCaveBiome(x, z);
}
@@ -792,12 +792,12 @@ public class EngineCompositeGenerator extends ChunkGenerator implements IrisAcce
return false;
}
public KList<LoaderBiome> getAllBiomes(String worldName) {
public KList<IrisBiome> getAllBiomes(String worldName) {
if (getComposite() != null) {
return getComposite().getAllBiomes();
} else {
KMap<String, LoaderBiome> v = new KMap<>();
LoaderDimension dim = getDimension(worldName);
KMap<String, IrisBiome> v = new KMap<>();
IrisDimension dim = getDimension(worldName);
dim.getAllAnyBiomes().forEach((i) -> v.put(i.getLoadKey(), i));
try {

View File

@@ -21,10 +21,10 @@ package com.volmit.iris.engine.framework;
import com.volmit.iris.Iris;
import com.volmit.iris.core.project.loader.IrisData;
import com.volmit.iris.engine.actuator.IrisTerrainNormalActuator;
import com.volmit.iris.engine.data.DataProvider;
import com.volmit.iris.util.data.DataProvider;
import com.volmit.iris.util.hunk.Hunk;
import com.volmit.iris.engine.object.biome.LoaderBiome;
import com.volmit.iris.engine.object.dimensional.LoaderDimension;
import com.volmit.iris.engine.object.biome.IrisBiome;
import com.volmit.iris.engine.object.dimensional.IrisDimension;
import com.volmit.iris.engine.object.basic.IrisPosition;
import com.volmit.iris.engine.object.common.IrisWorld;
import com.volmit.iris.util.parallel.MultiBurst;
@@ -39,7 +39,7 @@ import org.bukkit.generator.BlockPopulator;
import java.util.List;
public interface EngineCompound extends Listener, Hotloadable, DataProvider {
LoaderDimension getRootDimension();
IrisDimension getRootDimension();
void generate(int x, int z, Hunk<BlockData> blocks, Hunk<BlockData> postblocks, Hunk<Biome> biomes, boolean multicore);
@@ -133,10 +133,10 @@ public interface EngineCompound extends Listener, Hotloadable, DataProvider {
Engine getDefaultEngine();
default KList<LoaderBiome> getAllBiomes() {
KMap<String, LoaderBiome> v = new KMap<>();
default KList<IrisBiome> getAllBiomes() {
KMap<String, IrisBiome> v = new KMap<>();
LoaderDimension dim = getRootDimension();
IrisDimension dim = getRootDimension();
dim.getAllBiomes(this).forEach((i) -> v.put(i.getLoadKey(), i));
try {

View File

@@ -18,19 +18,19 @@
package com.volmit.iris.engine.framework;
import com.volmit.iris.engine.data.B;
import com.volmit.iris.util.data.B;
import com.volmit.iris.util.hunk.Hunk;
import com.volmit.iris.engine.object.biome.LoaderBiome;
import com.volmit.iris.engine.object.biome.IrisBiome;
import com.volmit.iris.util.documentation.BlockCoordinates;
import org.bukkit.block.data.BlockData;
public interface EngineDecorator extends EngineComponent {
@BlockCoordinates
void decorate(int x, int z, int realX, int realX1, int realX_1, int realZ, int realZ1, int realZ_1, Hunk<BlockData> data, LoaderBiome biome, int height, int max);
void decorate(int x, int z, int realX, int realX1, int realX_1, int realZ, int realZ1, int realZ_1, Hunk<BlockData> data, IrisBiome biome, int height, int max);
@BlockCoordinates
default void decorate(int x, int z, int realX, int realZ, Hunk<BlockData> data, LoaderBiome biome, int height, int max) {
default void decorate(int x, int z, int realX, int realZ, Hunk<BlockData> data, IrisBiome biome, int height, int max) {
decorate(x, z, realX, realX, realX, realZ, realZ, realZ, data, biome, height, max);
}

View File

@@ -20,7 +20,7 @@ package com.volmit.iris.engine.framework;
import com.volmit.iris.core.project.loader.IrisData;
import com.volmit.iris.engine.IrisComplex;
import com.volmit.iris.engine.data.DataProvider;
import com.volmit.iris.util.data.DataProvider;
import org.bukkit.block.Biome;
import org.bukkit.block.data.BlockData;

View File

@@ -22,21 +22,21 @@ 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.data.B;
import com.volmit.iris.engine.data.DataProvider;
import com.volmit.iris.util.data.B;
import com.volmit.iris.util.data.DataProvider;
import com.volmit.iris.engine.object.basic.IrisPosition;
import com.volmit.iris.engine.object.biome.LoaderBiome;
import com.volmit.iris.engine.object.biome.IrisBiome;
import com.volmit.iris.engine.object.biome.IrisBiomeMutation;
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.LoaderJigsawStructure;
import com.volmit.iris.engine.object.jigsaw.IrisJigsawStructure;
import com.volmit.iris.engine.object.jigsaw.IrisJigsawStructurePlacement;
import com.volmit.iris.engine.object.objects.LoaderObject;
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.LoaderRegion;
import com.volmit.iris.engine.object.regional.IrisRegion;
import com.volmit.iris.util.hunk.Hunk;
import com.volmit.iris.engine.jigsaw.PlannedStructure;
import com.volmit.iris.engine.object.common.IObjectPlacer;
@@ -90,8 +90,8 @@ public interface EngineParallaxManager extends DataProvider, IObjectPlacer {
return getEngine().getFramework().getComplex();
}
default KList<LoaderRegion> getAllRegions() {
KList<LoaderRegion> r = new KList<>();
default KList<IrisRegion> getAllRegions() {
KList<IrisRegion> r = new KList<>();
for (String i : getEngine().getDimension().getRegions()) {
r.add(getEngine().getData().getRegionLoader().load(i));
@@ -108,10 +108,10 @@ public interface EngineParallaxManager extends DataProvider, IObjectPlacer {
return r;
}
default KList<LoaderBiome> getAllBiomes() {
KList<LoaderBiome> r = new KList<>();
default KList<IrisBiome> getAllBiomes() {
KList<IrisBiome> r = new KList<>();
for (LoaderRegion i : getAllRegions()) {
for (IrisRegion i : getAllRegions()) {
r.addAll(i.getAllBiomes(this));
}
@@ -299,8 +299,8 @@ public interface EngineParallaxManager extends DataProvider, IObjectPlacer {
getParallaxAccess().setFeatureGenerated(xx, zz);
burst.queue(() -> {
RNG rng = new RNG(Cache.key(xx, zz) + getEngine().getTarget().getWorld().seed());
LoaderRegion region = getComplex().getRegionStream().get(xxx, zzz);
LoaderBiome biome = getComplex().getTrueBiomeStreamNoFeatures().get(xxx, zzz);
IrisRegion region = getComplex().getRegionStream().get(xxx, zzz);
IrisBiome biome = getComplex().getTrueBiomeStreamNoFeatures().get(xxx, zzz);
generateParallaxFeatures(rng, xx, zz, region, biome);
});
}
@@ -361,8 +361,8 @@ public interface EngineParallaxManager extends DataProvider, IObjectPlacer {
int xx = x << 4;
int zz = z << 4;
RNG rng = new RNG(Cache.key(x, z)).nextParallelRNG(getEngine().getTarget().getWorld().seed());
LoaderRegion region = getComplex().getRegionStream().get(xx + 8, zz + 8);
LoaderBiome biome = getComplex().getTrueBiomeStreamNoFeatures().get(xx + 8, zz + 8);
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);
@@ -380,14 +380,14 @@ public interface EngineParallaxManager extends DataProvider, IObjectPlacer {
int zz = z << 4;
getParallaxAccess().setParallaxGenerated(x, z);
RNG rng = new RNG(Cache.key(x, z)).nextParallelRNG(getEngine().getTarget().getWorld().seed());
LoaderBiome biome = getComplex().getTrueBiomeStreamNoFeatures().get(xx + 8, zz + 8);
LoaderRegion region = getComplex().getRegionStream().get(xx + 8, zz + 8);
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, LoaderRegion region, LoaderBiome biome) {
default void generateParallaxFeatures(RNG rng, int cx, int cz, IrisRegion region, IrisBiome biome) {
for (IrisFeaturePotential i : getEngine().getDimension().getFeatures()) {
placeZone(rng, cx, cz, i);
}
@@ -415,7 +415,7 @@ public interface EngineParallaxManager extends DataProvider, IObjectPlacer {
generateParallaxLayer(x, z, false);
}
default KList<Runnable> placeStructure(IrisPosition position, LoaderJigsawStructure structure, RNG rng) {
default KList<Runnable> placeStructure(IrisPosition position, IrisJigsawStructure structure, RNG rng) {
KList<Runnable> placeAfter = new KList<>();
if (structure == null) {
@@ -435,7 +435,7 @@ public interface EngineParallaxManager extends DataProvider, IObjectPlacer {
return placeAfter;
}
default KList<Runnable> generateParallaxJigsaw(RNG rng, int x, int z, LoaderBiome biome, LoaderRegion region) {
default KList<Runnable> generateParallaxJigsaw(RNG rng, int x, int z, IrisBiome biome, IrisRegion region) {
KList<Runnable> placeAfter = new KList<>();
if (getEngine().getDimension().isPlaceObjects()) {
@@ -447,7 +447,7 @@ public interface EngineParallaxManager extends DataProvider, IObjectPlacer {
if (poss != null) {
for (Position2 pos : poss) {
if (x == pos.getX() >> 4 && z == pos.getZ() >> 4) {
LoaderJigsawStructure structure = getData().getJigsawStructureLoader().load(getEngine().getDimension().getStronghold());
IrisJigsawStructure structure = getData().getJigsawStructureLoader().load(getEngine().getDimension().getStronghold());
placeAfter.addAll(placeStructure(pos.toIris(), structure, rng));
placed = true;
}
@@ -459,7 +459,7 @@ public interface EngineParallaxManager extends DataProvider, IObjectPlacer {
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));
LoaderJigsawStructure structure = getData().getJigsawStructureLoader().load(i.getStructure());
IrisJigsawStructure structure = getData().getJigsawStructureLoader().load(i.getStructure());
placeAfter.addAll(placeStructure(position, structure, rng));
placed = true;
}
@@ -470,7 +470,7 @@ public interface EngineParallaxManager extends DataProvider, IObjectPlacer {
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));
LoaderJigsawStructure structure = getData().getJigsawStructureLoader().load(i.getStructure());
IrisJigsawStructure structure = getData().getJigsawStructureLoader().load(i.getStructure());
placeAfter.addAll(placeStructure(position, structure, rng));
placed = true;
}
@@ -481,7 +481,7 @@ public interface EngineParallaxManager extends DataProvider, IObjectPlacer {
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));
LoaderJigsawStructure structure = getData().getJigsawStructureLoader().load(i.getStructure());
IrisJigsawStructure structure = getData().getJigsawStructureLoader().load(i.getStructure());
placeAfter.addAll(placeStructure(position, structure, rng));
placed = true;
}
@@ -492,7 +492,7 @@ public interface EngineParallaxManager extends DataProvider, IObjectPlacer {
return placeAfter;
}
default void generateParallaxSurface(RNG rng, int x, int z, LoaderBiome biome, LoaderRegion region, boolean useFeatures) {
default void generateParallaxSurface(RNG rng, int x, int z, IrisBiome biome, IrisRegion region, boolean useFeatures) {
for (IrisObjectPlacement i : biome.getSurfaceObjects()) {
if (i.usesFeatures() != useFeatures) {
@@ -539,8 +539,8 @@ public interface EngineParallaxManager extends DataProvider, IObjectPlacer {
searching:
for (IrisBiomeMutation k : getEngine().getDimension().getMutations()) {
for (int l = 0; l < k.getChecks(); l++) {
LoaderBiome 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()));
LoaderBiome 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()));
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;
@@ -565,7 +565,7 @@ public interface EngineParallaxManager extends DataProvider, IObjectPlacer {
place(rng, x, -1, z, objectPlacement);
}
default void placePiece(RNG rng, int xx, int forceY, int zz, LoaderObject v, IrisObjectPlacement p) {
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);
@@ -612,7 +612,7 @@ public interface EngineParallaxManager extends DataProvider, IObjectPlacer {
default void place(RNG rng, int x, int forceY, int z, IrisObjectPlacement objectPlacement) {
placing:
for (int i = 0; i < objectPlacement.getDensity(); i++) {
LoaderObject v = objectPlacement.getScale().get(rng, objectPlacement.getObject(getComplex(), rng));
IrisObject v = objectPlacement.getScale().get(rng, objectPlacement.getObject(getComplex(), rng));
if (v == null) {
return;
}
@@ -656,7 +656,7 @@ public interface EngineParallaxManager extends DataProvider, IObjectPlacer {
}
}
default void updateParallaxChunkObjectData(int minY, int maxY, int x, int z, LoaderObject v) {
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()));
@@ -676,10 +676,10 @@ public interface EngineParallaxManager extends DataProvider, IObjectPlacer {
int z = zg.get();
if (getEngine().getDimension().isPlaceObjects()) {
KList<LoaderRegion> r = getAllRegions();
KList<LoaderBiome> b = getAllBiomes();
KList<IrisRegion> r = getAllRegions();
KList<IrisBiome> b = getAllBiomes();
for (LoaderBiome i : b) {
for (IrisBiome i : b) {
for (IrisObjectPlacement j : i.getObjects()) {
if (j.getScale().canScaleBeyond()) {
scalars.put(j.getScale(), j.getPlace());
@@ -693,7 +693,7 @@ public interface EngineParallaxManager extends DataProvider, IObjectPlacer {
}
}
for (LoaderRegion i : r) {
for (IrisRegion i : r) {
for (IrisObjectPlacement j : i.getObjects()) {
if (j.getScale().canScaleBeyond()) {
scalars.put(j.getScale(), j.getPlace());
@@ -733,7 +733,7 @@ public interface EngineParallaxManager extends DataProvider, IObjectPlacer {
}
try {
return LoaderObject.sampleSize(getData().getObjectLoader().findFile(i));
return IrisObject.sampleSize(getData().getObjectLoader().findFile(i));
} catch (IOException ex) {
Iris.reportError(ex);
ex.printStackTrace();
@@ -773,7 +773,7 @@ public interface EngineParallaxManager extends DataProvider, IObjectPlacer {
}
try {
return LoaderObject.sampleSize(getData().getObjectLoader().findFile(j));
return IrisObject.sampleSize(getData().getObjectLoader().findFile(j));
} catch (IOException ioException) {
Iris.reportError(ioException);
ioException.printStackTrace();
@@ -814,7 +814,7 @@ public interface EngineParallaxManager extends DataProvider, IObjectPlacer {
z = Math.max(max, z);
}
for (LoaderRegion v : r) {
for (IrisRegion v : r) {
for (IrisDepositGenerator i : v.getDeposits()) {
int max = i.getMaxDimension();
x = Math.max(max, x);
@@ -822,7 +822,7 @@ public interface EngineParallaxManager extends DataProvider, IObjectPlacer {
}
}
for (LoaderBiome v : b) {
for (IrisBiome v : b) {
for (IrisDepositGenerator i : v.getDeposits()) {
int max = i.getMaxDimension();
x = Math.max(max, x);

View File

@@ -19,9 +19,9 @@
package com.volmit.iris.engine.framework;
import com.volmit.iris.Iris;
import com.volmit.iris.engine.object.biome.LoaderBiome;
import com.volmit.iris.engine.object.biome.IrisBiome;
import com.volmit.iris.engine.object.meta.IrisEffect;
import com.volmit.iris.engine.object.regional.LoaderRegion;
import com.volmit.iris.engine.object.regional.IrisRegion;
import com.volmit.iris.util.math.M;
import com.volmit.iris.util.scheduling.J;
import lombok.Data;
@@ -32,8 +32,8 @@ import org.bukkit.entity.Player;
public class EnginePlayer {
private final Engine engine;
private final Player player;
private LoaderBiome biome;
private LoaderRegion region;
private IrisBiome biome;
private IrisRegion region;
private Location lastLocation;
private long lastSample;

View File

@@ -20,7 +20,7 @@ package com.volmit.iris.engine.framework;
import com.volmit.iris.core.IrisSettings;
import com.volmit.iris.core.project.loader.IrisData;
import com.volmit.iris.engine.object.dimensional.LoaderDimension;
import com.volmit.iris.engine.object.dimensional.IrisDimension;
import com.volmit.iris.engine.object.common.IrisWorld;
import com.volmit.iris.engine.parallax.ParallaxWorld;
import com.volmit.iris.util.parallel.MultiBurst;
@@ -32,14 +32,14 @@ import java.io.File;
public class EngineTarget {
private final MultiBurst parallaxBurster;
private final MultiBurst burster;
private final LoaderDimension dimension;
private final IrisDimension dimension;
private IrisWorld world;
private final int height;
private final IrisData data;
private final ParallaxWorld parallaxWorld;
private final boolean inverted;
public EngineTarget(IrisWorld world, LoaderDimension dimension, IrisData data, int height, boolean inverted, int threads) {
public EngineTarget(IrisWorld world, IrisDimension dimension, IrisData data, int height, boolean inverted, int threads) {
this.world = world;
this.height = height;
this.dimension = dimension;
@@ -50,7 +50,7 @@ public class EngineTarget {
this.parallaxWorld = new ParallaxWorld(parallaxBurster, 256, new File(world.worldFolder(), "iris/" + dimension.getLoadKey() + "/parallax"));
}
public EngineTarget(IrisWorld world, LoaderDimension dimension, IrisData data, int height, int threads) {
public EngineTarget(IrisWorld world, IrisDimension dimension, IrisData data, int height, int threads) {
this(world, dimension, data, height, false, threads);
}

View File

@@ -20,26 +20,26 @@ 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.data.DataProvider;
import com.volmit.iris.engine.object.biome.LoaderBiome;
import com.volmit.iris.util.data.DataProvider;
import com.volmit.iris.engine.object.biome.IrisBiome;
import com.volmit.iris.engine.object.objects.IrisObjectPlacement;
import com.volmit.iris.engine.object.regional.LoaderRegion;
import com.volmit.iris.engine.object.regional.IrisRegion;
import com.volmit.iris.engine.parallax.ParallaxAccess;
public interface GeneratorAccess extends DataProvider, Renderer {
LoaderRegion getRegion(int x, int z);
IrisRegion getRegion(int x, int z);
ParallaxAccess getParallaxAccess();
IrisData getData();
LoaderBiome getCaveBiome(int x, int z);
IrisBiome getCaveBiome(int x, int z);
LoaderBiome getSurfaceBiome(int x, int z);
IrisBiome getSurfaceBiome(int x, int z);
int getHeight(int x, int z);
default LoaderBiome getBiome(int x, int y, int z) {
default IrisBiome getBiome(int x, int y, int z) {
if (y <= getHeight(x, z) - 2) {
return getCaveBiome(x, z);
}
@@ -57,7 +57,7 @@ public interface GeneratorAccess extends DataProvider, Renderer {
String[] v = objectAt.split("\\Q@\\E");
String object = v[0];
int id = Integer.parseInt(v[1]);
LoaderRegion region = getRegion(x, z);
IrisRegion region = getRegion(x, z);
for (IrisObjectPlacement i : region.getObjects()) {
if (i.getPlace().contains(object)) {
@@ -65,7 +65,7 @@ public interface GeneratorAccess extends DataProvider, Renderer {
}
}
LoaderBiome biome = getBiome(x, y, z);
IrisBiome biome = getBiome(x, y, z);
for (IrisObjectPlacement i : biome.getObjects()) {
if (i.getPlace().contains(object)) {

View File

@@ -21,11 +21,11 @@ package com.volmit.iris.engine.framework;
import com.volmit.iris.Iris;
import com.volmit.iris.core.pregenerator.PregenListener;
import com.volmit.iris.core.project.loader.IrisData;
import com.volmit.iris.engine.data.DataProvider;
import com.volmit.iris.engine.data.mca.NBTWorld;
import com.volmit.iris.util.data.DataProvider;
import com.volmit.iris.util.nbt.mca.NBTWorld;
import com.volmit.iris.engine.framework.headless.HeadlessGenerator;
import com.volmit.iris.engine.object.biome.LoaderBiome;
import com.volmit.iris.engine.object.regional.LoaderRegion;
import com.volmit.iris.engine.object.biome.IrisBiome;
import com.volmit.iris.engine.object.regional.IrisRegion;
import com.volmit.iris.engine.object.common.IrisWorld;
import com.volmit.iris.util.parallel.MultiBurst;
import com.volmit.iris.util.collection.KList;
@@ -71,29 +71,29 @@ public interface IrisAccess extends Hotloadable, DataProvider {
* @param l the location
* @return the biome
*/
default LoaderBiome getBiome(Location l) {
default IrisBiome getBiome(Location l) {
return getBiome(l.toVector());
}
default LoaderRegion getRegion(int x, int y, int z) {
default IrisRegion getRegion(int x, int y, int z) {
return getEngineAccess(y).getRegion(x, z);
}
default LoaderRegion getRegion(Location l) {
default IrisRegion getRegion(Location l) {
return getRegion(l.getBlockX(), l.getBlockY(), l.getBlockZ());
}
default LoaderBiome getBiome(Vector l) {
default IrisBiome getBiome(Vector l) {
return getBiome(l.getBlockX(), l.getBlockY(), l.getBlockZ());
}
LoaderBiome getBiome(int x, int y, int z);
IrisBiome getBiome(int x, int y, int z);
LoaderBiome getCaveBiome(int x, int y, int z);
IrisBiome getCaveBiome(int x, int y, int z);
LoaderBiome getBiome(int x, int z);
IrisBiome getBiome(int x, int z);
LoaderBiome getCaveBiome(int x, int z);
IrisBiome getCaveBiome(int x, int z);
GeneratorAccess getEngineAccess(int y);
@@ -117,7 +117,7 @@ public interface IrisAccess extends Hotloadable, DataProvider {
boolean isStudio();
default Location lookForBiome(LoaderBiome biome, long timeout, Consumer<Integer> triesc) {
default Location lookForBiome(IrisBiome biome, long timeout, Consumer<Integer> triesc) {
if (!getCompound().getWorld().hasRealWorld()) {
Iris.error("Cannot GOTO without a bound world (headless mode)");
return null;
@@ -146,7 +146,7 @@ public interface IrisAccess extends Hotloadable, DataProvider {
J.a(() -> {
try {
Engine e;
LoaderBiome b;
IrisBiome b;
int x, z;
while (!found.get() && running.get()) {
@@ -198,7 +198,7 @@ public interface IrisAccess extends Hotloadable, DataProvider {
return location.get();
}
default Location lookForRegion(LoaderRegion reg, long timeout, Consumer<Integer> triesc) {
default Location lookForRegion(IrisRegion reg, long timeout, Consumer<Integer> triesc) {
if (!getCompound().getWorld().hasRealWorld()) {
Iris.error("Cannot GOTO without a bound world (headless mode)");
return null;
@@ -227,7 +227,7 @@ public interface IrisAccess extends Hotloadable, DataProvider {
for (int i = 0; i < cpus; i++) {
J.a(() -> {
Engine e;
LoaderRegion b;
IrisRegion b;
int x, z;
while (!found.get() && running.get()) {

View File

@@ -20,7 +20,7 @@ package com.volmit.iris.engine.framework;
import com.volmit.iris.engine.object.meta.InventorySlotType;
import com.volmit.iris.engine.object.loot.IrisLootReference;
import com.volmit.iris.engine.object.loot.LoaderLootTable;
import com.volmit.iris.engine.object.loot.IrisLootTable;
import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.math.RNG;
import org.bukkit.block.Block;
@@ -29,9 +29,9 @@ import org.bukkit.inventory.Inventory;
public interface LootProvider {
void scramble(Inventory inventory, RNG rng);
void injectTables(KList<LoaderLootTable> list, IrisLootReference r);
void injectTables(KList<IrisLootTable> list, IrisLootReference r);
KList<LoaderLootTable> getLootTables(RNG rng, Block b);
KList<IrisLootTable> getLootTables(RNG rng, Block b);
void addItems(boolean debug, Inventory inv, RNG rng, KList<LoaderLootTable> tables, InventorySlotType slot, int x, int y, int z, int mgf);
void addItems(boolean debug, Inventory inv, RNG rng, KList<IrisLootTable> tables, InventorySlotType slot, int x, int y, int z, int mgf);
}

View File

@@ -18,7 +18,7 @@
package com.volmit.iris.engine.framework;
import com.volmit.iris.engine.object.objects.LoaderObject;
import com.volmit.iris.engine.object.objects.IrisObject;
import com.volmit.iris.engine.object.objects.IrisObjectPlacement;
import lombok.AllArgsConstructor;
import lombok.Data;
@@ -31,7 +31,7 @@ public class PlacedObject {
@Nullable
private IrisObjectPlacement placement;
@Nullable
private LoaderObject object;
private IrisObject object;
private int id;
private int xx;
private int zz;

View File

@@ -18,7 +18,7 @@
package com.volmit.iris.engine.framework;
import com.volmit.iris.engine.data.B;
import com.volmit.iris.util.data.B;
import com.volmit.iris.engine.data.chunk.TerrainChunk;
import com.volmit.iris.util.hunk.Hunk;
import lombok.Data;

View File

@@ -20,8 +20,8 @@ package com.volmit.iris.engine.framework.headless;
import com.volmit.iris.core.IrisSettings;
import com.volmit.iris.core.pregenerator.PregenListener;
import com.volmit.iris.engine.data.mca.MCAUtil;
import com.volmit.iris.engine.data.mca.NBTWorld;
import com.volmit.iris.util.nbt.mca.MCAUtil;
import com.volmit.iris.util.nbt.mca.NBTWorld;
import com.volmit.iris.engine.framework.EngineCompositeGenerator;
import com.volmit.iris.util.parallel.MultiBurst;
import com.volmit.iris.util.collection.KList;

View File

@@ -22,7 +22,7 @@ import com.volmit.iris.Iris;
import com.volmit.iris.core.project.loader.IrisData;
import com.volmit.iris.core.tools.IrisWorlds;
import com.volmit.iris.engine.framework.EngineCompositeGenerator;
import com.volmit.iris.engine.object.dimensional.LoaderDimension;
import com.volmit.iris.engine.object.dimensional.IrisDimension;
import com.volmit.iris.engine.object.common.IrisWorld;
import com.volmit.iris.util.plugin.VolmitSender;
import lombok.Data;
@@ -35,16 +35,16 @@ import java.io.File;
@Data
@SuppressWarnings("ResultOfMethodCallIgnored")
public class HeadlessWorld {
private final LoaderDimension dimension;
private final IrisDimension dimension;
private final String worldName;
private final IrisWorld world;
private boolean studio = false;
public HeadlessWorld(String worldName, LoaderDimension dimension, long seed) {
public HeadlessWorld(String worldName, IrisDimension dimension, long seed) {
this(worldName, dimension, seed, false);
}
public HeadlessWorld(String worldName, LoaderDimension dimension, long seed, boolean studio) {
public HeadlessWorld(String worldName, IrisDimension dimension, long seed, boolean studio) {
this.worldName = worldName;
this.dimension = dimension;
this.studio = studio;

View File

@@ -24,11 +24,11 @@ import com.volmit.iris.engine.framework.Engine;
import com.volmit.iris.engine.framework.IrisAccess;
import com.volmit.iris.engine.object.basic.IrisPosition;
import com.volmit.iris.engine.object.common.IObjectPlacer;
import com.volmit.iris.engine.object.jigsaw.LoaderJigsawPiece;
import com.volmit.iris.engine.object.jigsaw.IrisJigsawPiece;
import com.volmit.iris.engine.object.jigsaw.IrisJigsawPieceConnector;
import com.volmit.iris.engine.object.loot.LoaderLootTable;
import com.volmit.iris.engine.object.loot.IrisLootTable;
import com.volmit.iris.engine.object.meta.InventorySlotType;
import com.volmit.iris.engine.object.objects.LoaderObject;
import com.volmit.iris.engine.object.objects.IrisObject;
import com.volmit.iris.engine.object.objects.IrisObjectRotation;
import com.volmit.iris.engine.object.tile.TileData;
import com.volmit.iris.util.collection.KList;
@@ -49,9 +49,9 @@ import org.bukkit.util.BlockVector;
@Data
public class PlannedPiece {
private IrisPosition position;
private LoaderObject object;
private LoaderObject ogObject;
private LoaderJigsawPiece piece;
private IrisObject object;
private IrisObject ogObject;
private IrisJigsawPiece piece;
private IrisObjectRotation rotation;
private IrisData data;
private KList<IrisJigsawPieceConnector> connected;
@@ -59,15 +59,15 @@ public class PlannedPiece {
private AxisAlignedBB box;
private PlannedStructure structure;
public PlannedPiece(PlannedStructure structure, IrisPosition position, LoaderJigsawPiece piece) {
public PlannedPiece(PlannedStructure structure, IrisPosition position, IrisJigsawPiece piece) {
this(structure, position, piece, 0, 0, 0);
}
public PlannedPiece(PlannedStructure structure, IrisPosition position, LoaderJigsawPiece piece, int rx, int ry, int rz) {
public PlannedPiece(PlannedStructure structure, IrisPosition position, IrisJigsawPiece piece, int rx, int ry, int rz) {
this(structure, position, piece, IrisObjectRotation.of(rx * 90D, ry * 90D, rz * 90D));
}
public PlannedPiece(PlannedStructure structure, IrisPosition position, LoaderJigsawPiece piece, IrisObjectRotation rot) {
public PlannedPiece(PlannedStructure structure, IrisPosition position, IrisJigsawPiece piece, IrisObjectRotation rot) {
this.structure = structure;
this.position = position;
this.data = piece.getLoader();
@@ -187,7 +187,7 @@ public class PlannedPiece {
if (a != null && getPiece().getPlacementOptions().getLoot().isNotEmpty() &&
block.getState() instanceof InventoryHolder) {
LoaderLootTable table = getPiece().getPlacementOptions().getTable(block.getBlockData(), getData());
IrisLootTable table = getPiece().getPlacementOptions().getTable(block.getBlockData(), getData());
if (table == null) return;
Engine engine = a.getCompound().getEngineForHeight(y);
engine.addItems(false, ((InventoryHolder) block.getState()).getInventory(),

View File

@@ -27,12 +27,12 @@ import com.volmit.iris.engine.framework.IrisAccess;
import com.volmit.iris.engine.object.basic.IrisPosition;
import com.volmit.iris.util.interpolation.InterpolationMethod;
import com.volmit.iris.engine.object.common.IObjectPlacer;
import com.volmit.iris.engine.object.entity.LoaderEntity;
import com.volmit.iris.engine.object.entity.IrisEntity;
import com.volmit.iris.engine.object.feature.IrisFeature;
import com.volmit.iris.engine.object.feature.IrisFeaturePositional;
import com.volmit.iris.engine.object.jigsaw.LoaderJigsawPiece;
import com.volmit.iris.engine.object.jigsaw.IrisJigsawPiece;
import com.volmit.iris.engine.object.jigsaw.IrisJigsawPieceConnector;
import com.volmit.iris.engine.object.jigsaw.LoaderJigsawStructure;
import com.volmit.iris.engine.object.jigsaw.IrisJigsawStructure;
import com.volmit.iris.engine.object.objects.*;
import com.volmit.iris.engine.parallax.ParallaxChunkMeta;
import com.volmit.iris.util.collection.KList;
@@ -46,20 +46,20 @@ import org.bukkit.entity.Entity;
@Data
public class PlannedStructure {
private KList<PlannedPiece> pieces;
private LoaderJigsawStructure structure;
private IrisJigsawStructure structure;
private IrisPosition position;
private IrisData data;
private RNG rng;
private boolean verbose;
private boolean terminating;
private static transient ConcurrentLinkedHashMap<String, LoaderObject> objectRotationCache
= new ConcurrentLinkedHashMap.Builder<String, LoaderObject>()
private static transient ConcurrentLinkedHashMap<String, IrisObject> objectRotationCache
= new ConcurrentLinkedHashMap.Builder<String, IrisObject>()
.initialCapacity(64)
.maximumWeightedCapacity(1024)
.concurrencyLevel(32)
.build();
public PlannedStructure(LoaderJigsawStructure structure, IrisPosition position, RNG rng) {
public PlannedStructure(IrisJigsawStructure structure, IrisPosition position, RNG rng) {
terminating = false;
verbose = true;
this.pieces = new KList<>();
@@ -103,8 +103,8 @@ public class PlannedStructure {
options.setMode(i.getPiece().getPlaceMode());
}
LoaderObject vo = i.getOgObject();
LoaderObject v = i.getObject();
IrisObject vo = i.getOgObject();
IrisObject v = i.getObject();
int sx = (v.getW() / 2);
int sz = (v.getD() / 2);
int xx = i.getPosition().getX() + sx;
@@ -176,7 +176,7 @@ public class PlannedStructure {
break;
}
IrisPosition p = i.getWorldPosition(j).add(new IrisPosition(j.getDirection().toVector().multiply(2)));
LoaderEntity e = getData().getEntityLoader().load(j.getSpawnEntity());
IrisEntity e = getData().getEntityLoader().load(j.getSpawnEntity());
if (a != null) {
Entity entity = e.spawn(a.getCompound().getEngineForHeight(p.getY()), new Location(world, p.getX() + 0.5, p.getY(), p.getZ() + 0.5), rng);
@@ -213,7 +213,7 @@ public class PlannedStructure {
}
private boolean generateConnectorOutwards(PlannedPiece piece, IrisJigsawPieceConnector pieceConnector) {
for (LoaderJigsawPiece i : getShuffledPiecesFor(pieceConnector)) {
for (IrisJigsawPiece i : getShuffledPiecesFor(pieceConnector)) {
if (generateRotatedPiece(piece, pieceConnector, i)) {
return true;
}
@@ -222,7 +222,7 @@ public class PlannedStructure {
return false;
}
private boolean generateRotatedPiece(PlannedPiece piece, IrisJigsawPieceConnector pieceConnector, LoaderJigsawPiece idea) {
private boolean generateRotatedPiece(PlannedPiece piece, IrisJigsawPieceConnector pieceConnector, IrisJigsawPiece idea) {
if (!piece.getPiece().getPlacementOptions().getRotation().isEnabled()) {
if (generateRotatedPiece(piece, pieceConnector, idea, 0, 0, 0)) {
return true;
@@ -256,7 +256,7 @@ public class PlannedStructure {
return false;
}
private boolean generateRotatedPiece(PlannedPiece piece, IrisJigsawPieceConnector pieceConnector, LoaderJigsawPiece idea, IrisObjectRotation rotation) {
private boolean generateRotatedPiece(PlannedPiece piece, IrisJigsawPieceConnector pieceConnector, IrisJigsawPiece idea, IrisObjectRotation rotation) {
if (!idea.getPlacementOptions().getRotation().isEnabled())
rotation = piece.getRotation(); //Inherit parent rotation
@@ -271,7 +271,7 @@ public class PlannedStructure {
return false;
}
private boolean generateRotatedPiece(PlannedPiece piece, IrisJigsawPieceConnector pieceConnector, LoaderJigsawPiece idea, int x, int y, int z) {
private boolean generateRotatedPiece(PlannedPiece piece, IrisJigsawPieceConnector pieceConnector, IrisJigsawPiece idea, int x, int y, int z) {
return generateRotatedPiece(piece, pieceConnector, idea, IrisObjectRotation.of(x, y, z));
}
@@ -306,12 +306,12 @@ public class PlannedStructure {
return true;
}
private KList<LoaderJigsawPiece> getShuffledPiecesFor(IrisJigsawPieceConnector c) {
KList<LoaderJigsawPiece> p = new KList<>();
private KList<IrisJigsawPiece> getShuffledPiecesFor(IrisJigsawPieceConnector c) {
KList<IrisJigsawPiece> p = new KList<>();
for (String i : c.getPools().shuffleCopy(rng)) {
for (String j : getData().getJigsawPoolLoader().load(i).getPieces().shuffleCopy(rng)) {
LoaderJigsawPiece pi = getData().getJigsawPieceLoader().load(j);
IrisJigsawPiece pi = getData().getJigsawPieceLoader().load(j);
if (pi == null || (terminating && !pi.isTerminal())) {
continue;
@@ -382,7 +382,7 @@ public class PlannedStructure {
return false;
}
public LoaderObject rotated(LoaderJigsawPiece piece, IrisObjectRotation rotation) {
public IrisObject rotated(IrisJigsawPiece piece, IrisObjectRotation rotation) {
String key = piece.getObject() + "-" + rotation.hashCode();
return objectRotationCache.compute(key, (k, v) -> {

View File

@@ -18,12 +18,12 @@
package com.volmit.iris.engine.modifier;
import com.volmit.iris.engine.data.B;
import com.volmit.iris.util.data.B;
import com.volmit.iris.engine.framework.Engine;
import com.volmit.iris.engine.framework.EngineAssignedModifier;
import com.volmit.iris.util.hunk.Hunk;
import com.volmit.iris.util.noise.FastNoiseDouble;
import com.volmit.iris.engine.object.biome.LoaderBiome;
import com.volmit.iris.engine.object.biome.IrisBiome;
import com.volmit.iris.engine.object.carve.IrisCaveLayer;
import com.volmit.iris.engine.object.common.CaveResult;
import com.volmit.iris.util.parallel.BurstExecutor;
@@ -77,7 +77,7 @@ public class IrisCaveModifier extends EngineAssignedModifier<BlockData> {
KList<CaveResult> caves = genCaves(x + finalI, z + j, finalI, j, a);
int he = (int) Math.round(getComplex().getHeightStream().get(x + finalI, z + j));
if (caves != null && caves.isNotEmpty()) {
LoaderBiome cave = getComplex().getCaveBiomeStream().get(x + finalI, z + j);
IrisBiome cave = getComplex().getCaveBiomeStream().get(x + finalI, z + j);
if (cave == null) {
continue;

View File

@@ -18,7 +18,7 @@
package com.volmit.iris.engine.modifier;
import com.volmit.iris.engine.data.B;
import com.volmit.iris.util.data.B;
import com.volmit.iris.engine.framework.Engine;
import com.volmit.iris.engine.framework.EngineAssignedModifier;
import com.volmit.iris.util.hunk.Hunk;

View File

@@ -21,10 +21,10 @@ package com.volmit.iris.engine.modifier;
import com.volmit.iris.engine.framework.Engine;
import com.volmit.iris.engine.framework.EngineAssignedModifier;
import com.volmit.iris.util.hunk.Hunk;
import com.volmit.iris.engine.object.biome.LoaderBiome;
import com.volmit.iris.engine.object.biome.IrisBiome;
import com.volmit.iris.engine.object.deposits.IrisDepositGenerator;
import com.volmit.iris.engine.object.objects.LoaderObject;
import com.volmit.iris.engine.object.regional.LoaderRegion;
import com.volmit.iris.engine.object.objects.IrisObject;
import com.volmit.iris.engine.object.regional.IrisRegion;
import com.volmit.iris.util.data.HeightMap;
import com.volmit.iris.util.math.RNG;
import com.volmit.iris.util.scheduling.PrecisionStopwatch;
@@ -48,8 +48,8 @@ public class IrisDepositModifier extends EngineAssignedModifier<BlockData> {
public void generateDeposits(RNG rx, Hunk<BlockData> terrain, int x, int z) {
RNG ro = rx.nextParallelRNG(x * x).nextParallelRNG(z * z);
LoaderRegion region = getComplex().getRegionStream().get((x * 16) + 7, (z * 16) + 7);
LoaderBiome biome = getComplex().getTrueBiomeStream().get((x * 16) + 7, (z * 16) + 7);
IrisRegion region = getComplex().getRegionStream().get((x * 16) + 7, (z * 16) + 7);
IrisBiome biome = getComplex().getTrueBiomeStream().get((x * 16) + 7, (z * 16) + 7);
for (IrisDepositGenerator k : getDimension().getDeposits()) {
generate(k, terrain, ro, x, z, false);
@@ -74,7 +74,7 @@ public class IrisDepositModifier extends EngineAssignedModifier<BlockData> {
public void generate(IrisDepositGenerator k, Hunk<BlockData> data, RNG rng, int cx, int cz, boolean safe, HeightMap he) {
for (int l = 0; l < rng.i(k.getMinPerChunk(), k.getMaxPerChunk()); l++) {
LoaderObject clump = k.getClump(rng, getData());
IrisObject clump = k.getClump(rng, getData());
int af = (int) Math.ceil(clump.getW() / 2D);
int bf = (int) Math.floor(16D - (clump.getW() / 2D));

View File

@@ -19,11 +19,11 @@
package com.volmit.iris.engine.modifier;
import com.volmit.iris.Iris;
import com.volmit.iris.engine.data.B;
import com.volmit.iris.util.data.B;
import com.volmit.iris.engine.framework.Engine;
import com.volmit.iris.engine.framework.EngineAssignedModifier;
import com.volmit.iris.util.hunk.Hunk;
import com.volmit.iris.engine.object.biome.LoaderBiome;
import com.volmit.iris.engine.object.biome.IrisBiome;
import com.volmit.iris.engine.object.common.CaveResult;
import com.volmit.iris.util.math.RNG;
import com.volmit.iris.util.scheduling.PrecisionStopwatch;
@@ -136,7 +136,7 @@ public class IrisPostModifier extends EngineAssignedModifier<BlockData> {
}
// Wall Patcher
LoaderBiome biome = getComplex().getTrueBiomeStream().get(x, z);
IrisBiome biome = getComplex().getTrueBiomeStream().get(x, z);
if (getDimension().isPostProcessingWalls()) {
if (!biome.getWall().getPalette().isEmpty()) {
@@ -231,7 +231,7 @@ public class IrisPostModifier extends EngineAssignedModifier<BlockData> {
}
if (getDimension().isPostProcessCaves()) {
LoaderBiome cave = getComplex().getCaveBiomeStream().get(x, z);
IrisBiome cave = getComplex().getCaveBiomeStream().get(x, z);
if (cave != null) {
for (CaveResult i : ((IrisCaveModifier) getFramework().getCaveModifier()).genCaves(x, z, 0, 0, null)) {

View File

@@ -18,7 +18,7 @@
package com.volmit.iris.engine.modifier;
import com.volmit.iris.engine.data.B;
import com.volmit.iris.util.data.B;
import com.volmit.iris.engine.framework.Engine;
import com.volmit.iris.engine.framework.EngineAssignedModifier;
import com.volmit.iris.util.hunk.Hunk;

View File

@@ -18,7 +18,7 @@
package com.volmit.iris.engine.object.annotations;
import com.volmit.iris.core.project.loader.LoaderRegistrant;
import com.volmit.iris.core.project.loader.IrisRegistrant;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
@@ -29,5 +29,5 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
@Retention(RUNTIME)
@Target({PARAMETER, TYPE, FIELD})
public @interface RegistryListResource {
Class<? extends LoaderRegistrant> value();
Class<? extends IrisRegistrant> value();
}

View File

@@ -21,11 +21,11 @@ package com.volmit.iris.engine.object.biome;
import com.volmit.iris.Iris;
import com.volmit.iris.core.gui.components.RenderType;
import com.volmit.iris.core.project.loader.IrisData;
import com.volmit.iris.core.project.loader.LoaderRegistrant;
import com.volmit.iris.core.project.loader.IrisRegistrant;
import com.volmit.iris.engine.IrisComplex;
import com.volmit.iris.engine.data.cache.AtomicCache;
import com.volmit.iris.engine.data.B;
import com.volmit.iris.engine.data.DataProvider;
import com.volmit.iris.util.data.B;
import com.volmit.iris.util.data.DataProvider;
import com.volmit.iris.engine.framework.Engine;
import com.volmit.iris.engine.framework.IrisAccess;
import com.volmit.iris.engine.object.block.IrisBlockDrops;
@@ -38,9 +38,9 @@ import com.volmit.iris.engine.object.meta.IrisEffect;
import com.volmit.iris.engine.object.noise.IrisGeneratorStyle;
import com.volmit.iris.engine.object.noise.IrisSlopeClip;
import com.volmit.iris.engine.object.noise.NoiseStyle;
import com.volmit.iris.engine.object.objects.LoaderObject;
import com.volmit.iris.engine.object.objects.IrisObject;
import com.volmit.iris.engine.object.objects.IrisObjectPlacement;
import com.volmit.iris.engine.object.spawners.LoaderSpawner;
import com.volmit.iris.engine.object.spawners.IrisSpawner;
import com.volmit.iris.util.noise.CNG;
import com.volmit.iris.engine.object.annotations.*;
import com.volmit.iris.engine.object.common.IRare;
@@ -68,7 +68,7 @@ import java.awt.*;
@Desc("Represents a biome in iris. Biomes are placed inside of regions and hold objects.\nA biome consists of layers (block palletes), decorations, objects & generators.")
@Data
@EqualsAndHashCode(callSuper = false)
public class LoaderBiome extends LoaderRegistrant implements IRare {
public class IrisBiome extends IrisRegistrant implements IRare {
@MinNumber(2)
@Required
@Desc("This is the human readable name for this biome. This can and should be different than the file name. This is not used for loading biomes in other objects.")
@@ -80,7 +80,7 @@ public class LoaderBiome extends LoaderRegistrant implements IRare {
@Desc("Spawn Entities in this area over time. Iris will continually replenish these mobs just like vanilla does.")
@ArrayType(min = 1, type = String.class)
@RegistryListResource(LoaderSpawner.class)
@RegistryListResource(IrisSpawner.class)
private KList<String> entitySpawners = new KList<>();
@Desc("Add random chances for terrain features")
@@ -146,7 +146,7 @@ public class LoaderBiome extends LoaderRegistrant implements IRare {
@Desc("If this biome has children biomes, and the gen layer chooses one of this biomes children, How will it be shaped?")
private IrisGeneratorStyle childStyle = NoiseStyle.CELLULAR_IRIS_DOUBLE.style();
@RegistryListResource(LoaderBiome.class)
@RegistryListResource(IrisBiome.class)
@ArrayType(min = 1, type = String.class)
@Desc("List any biome names (file names without.json) here as children. Portions of this biome can sometimes morph into their children. Iris supports cyclic relationships such as A > B > A > B. Iris will stop checking 9 biomes down the tree.")
private KList<String> children = new KList<>();
@@ -155,7 +155,7 @@ public class LoaderBiome extends LoaderRegistrant implements IRare {
@Desc("Jigsaw structures")
private KList<IrisJigsawStructurePlacement> jigsawStructures = new KList<>();
@RegistryListResource(LoaderBiome.class)
@RegistryListResource(IrisBiome.class)
@Desc("The carving biome. If specified the biome will be used when under a carving instead of this current biome.")
private String carvingBiome = "";
@@ -207,8 +207,8 @@ public class LoaderBiome extends LoaderRegistrant implements IRare {
private final transient AtomicCache<CNG> biomeGenerator = new AtomicCache<>();
private final transient AtomicCache<Integer> maxHeight = new AtomicCache<>();
private final transient AtomicCache<Integer> maxWithObjectHeight = new AtomicCache<>();
private final transient AtomicCache<LoaderBiome> realCarveBiome = new AtomicCache<>();
private final transient AtomicCache<KList<LoaderBiome>> realChildren = new AtomicCache<>();
private final transient AtomicCache<IrisBiome> realCarveBiome = new AtomicCache<>();
private final transient AtomicCache<KList<IrisBiome>> realChildren = new AtomicCache<>();
private final transient AtomicCache<KList<CNG>> layerHeightGenerators = new AtomicCache<>();
private final transient AtomicCache<KList<CNG>> layerSeaHeightGenerators = new AtomicCache<>();
@@ -263,10 +263,10 @@ public class LoaderBiome extends LoaderRegistrant implements IRare {
}).get(loadKey);
}
public LoaderBiome getRealCarvingBiome(IrisData data) {
public IrisBiome getRealCarvingBiome(IrisData data) {
return realCarveBiome.aquire(() ->
{
LoaderBiome biome = data.getBiomeLoader().load(getCarvingBiome());
IrisBiome biome = data.getBiomeLoader().load(getCarvingBiome());
if (biome == null) {
biome = this;
@@ -445,7 +445,7 @@ public class LoaderBiome extends LoaderRegistrant implements IRare {
int gg = 0;
for (IrisObjectPlacement i : getObjects()) {
for (LoaderObject j : data.getObjectLoader().loadAll(i.getPlace())) {
for (IrisObject j : data.getObjectLoader().loadAll(i.getPlace())) {
gg = Math.max(gg, j.getH());
}
}
@@ -454,7 +454,7 @@ public class LoaderBiome extends LoaderRegistrant implements IRare {
});
}
public LoaderBiome infer(InferredType t, InferredType type) {
public IrisBiome infer(InferredType t, InferredType type) {
setInferredType(t.equals(InferredType.DEFER) ? type : t);
return this;
}
@@ -582,10 +582,10 @@ public class LoaderBiome extends LoaderRegistrant implements IRare {
return customDerivitives.get(getBiomeGenerator(rng).fit(0, customDerivitives.size() - 1, x, y, z));
}
public KList<LoaderBiome> getRealChildren(DataProvider g) {
public KList<IrisBiome> getRealChildren(DataProvider g) {
return realChildren.aquire(() ->
{
KList<LoaderBiome> realChildren = new KList<>();
KList<IrisBiome> realChildren = new KList<>();
for (String i : getChildren()) {
realChildren.add(g.getData().getBiomeLoader().load(i));
@@ -602,7 +602,7 @@ public class LoaderBiome extends LoaderRegistrant implements IRare {
if (limit > 0) {
for (String i : getChildren()) {
LoaderBiome b = g.getData().getBiomeLoader().load(i);
IrisBiome b = g.getData().getBiomeLoader().load(i);
m.addAll(b.getAllChildren(g, limit));
}
}

View File

@@ -19,10 +19,10 @@
package com.volmit.iris.engine.object.biome;
import com.volmit.iris.engine.data.cache.AtomicCache;
import com.volmit.iris.engine.data.DataProvider;
import com.volmit.iris.util.data.DataProvider;
import com.volmit.iris.util.interpolation.IrisInterpolation;
import com.volmit.iris.engine.object.annotations.*;
import com.volmit.iris.engine.object.noise.LoaderGenerator;
import com.volmit.iris.engine.object.noise.IrisGenerator;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@@ -35,7 +35,7 @@ import lombok.experimental.Accessors;
@Data
public class IrisBiomeGeneratorLink {
@RegistryListResource(LoaderGenerator.class)
@RegistryListResource(IrisGenerator.class)
@Desc("The generator id")
private String generator = "default";
@@ -53,15 +53,15 @@ public class IrisBiomeGeneratorLink {
@Desc("The max block value (value + fluidHeight)")
private int max = 0;
private final transient AtomicCache<LoaderGenerator> gen = new AtomicCache<>();
private final transient AtomicCache<IrisGenerator> gen = new AtomicCache<>();
public LoaderGenerator getCachedGenerator(DataProvider g) {
public IrisGenerator getCachedGenerator(DataProvider g) {
return gen.aquire(() ->
{
LoaderGenerator gen = g.getData().getGeneratorLoader().load(getGenerator());
IrisGenerator gen = g.getData().getGeneratorLoader().load(getGenerator());
if (gen == null) {
gen = new LoaderGenerator();
gen = new IrisGenerator();
}
return gen;

View File

@@ -19,9 +19,9 @@
package com.volmit.iris.engine.object.biome;
import com.volmit.iris.engine.data.cache.AtomicCache;
import com.volmit.iris.engine.data.DataProvider;
import com.volmit.iris.util.data.DataProvider;
import com.volmit.iris.engine.object.annotations.*;
import com.volmit.iris.engine.object.objects.LoaderObject;
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;
@@ -36,13 +36,13 @@ import lombok.experimental.Accessors;
@Desc("A biome mutation if a condition is met")
@Data
public class IrisBiomeMutation {
@RegistryListResource(LoaderBiome.class)
@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(LoaderBiome.class)
@RegistryListResource(IrisBiome.class)
@Required
@ArrayType(min = 1, type = String.class)
@Desc("One of The following biomes or regions must show up")
@@ -60,7 +60,7 @@ public class IrisBiomeMutation {
@Desc("How many tries per chunk to check for this mutation")
private int checks = 2;
@RegistryListResource(LoaderObject.class)
@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<>();

View File

@@ -20,7 +20,7 @@ package com.volmit.iris.engine.object.biome;
import com.volmit.iris.core.project.loader.IrisData;
import com.volmit.iris.engine.data.cache.AtomicCache;
import com.volmit.iris.engine.object.block.LoaderBlockData;
import com.volmit.iris.engine.object.block.IrisBlockData;
import com.volmit.iris.engine.object.noise.IrisGeneratorStyle;
import com.volmit.iris.engine.object.noise.IrisSlopeClip;
import com.volmit.iris.engine.object.noise.NoiseStyle;
@@ -66,9 +66,9 @@ public class IrisBiomePaletteLayer {
private double zoom = 5;
@Required
@ArrayType(min = 1, type = LoaderBlockData.class)
@ArrayType(min = 1, type = IrisBlockData.class)
@Desc("The palette of blocks to be used in this layer")
private KList<LoaderBlockData> palette = new KList<LoaderBlockData>().qadd(new LoaderBlockData("GRASS_BLOCK"));
private KList<IrisBlockData> palette = new KList<IrisBlockData>().qadd(new IrisBlockData("GRASS_BLOCK"));
private final transient AtomicCache<KList<BlockData>> blockData = new AtomicCache<>();
private final transient AtomicCache<CNG> layerGenerator = new AtomicCache<>();
@@ -98,8 +98,8 @@ public class IrisBiomePaletteLayer {
});
}
public KList<LoaderBlockData> add(String b) {
palette.add(new LoaderBlockData(b));
public KList<IrisBlockData> add(String b) {
palette.add(new IrisBlockData(b));
return palette;
}
@@ -108,7 +108,7 @@ public class IrisBiomePaletteLayer {
return blockData.aquire(() ->
{
KList<BlockData> blockData = new KList<>();
for (LoaderBlockData ix : palette) {
for (IrisBlockData ix : palette) {
BlockData bx = ix.getBlockData(data);
if (bx != null) {
for (int i = 0; i < ix.getWeight(); i++) {

View File

@@ -21,8 +21,8 @@ package com.volmit.iris.engine.object.block;
import com.volmit.iris.Iris;
import com.volmit.iris.core.project.loader.IrisData;
import com.volmit.iris.engine.data.cache.AtomicCache;
import com.volmit.iris.engine.data.B;
import com.volmit.iris.core.project.loader.LoaderRegistrant;
import com.volmit.iris.util.data.B;
import com.volmit.iris.core.project.loader.IrisRegistrant;
import com.volmit.iris.engine.object.annotations.*;
import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.collection.KMap;
@@ -42,7 +42,7 @@ import java.util.Map;
@Desc("Represents Block Data")
@Data
@EqualsAndHashCode(callSuper = false)
public class LoaderBlockData extends LoaderRegistrant {
public class IrisBlockData extends IrisRegistrant {
@RegistryListBlockType
@Required
@Desc("The block to use")
@@ -60,7 +60,7 @@ public class LoaderBlockData extends LoaderRegistrant {
private int weight = 1;
@Desc("If the block cannot be created on this version, Iris will attempt to use this backup block data instead.")
private LoaderBlockData backup = null;
private IrisBlockData backup = null;
@Desc("Optional properties for this block data such as 'waterlogged': true")
private KMap<String, Object> data = new KMap<>();
@@ -68,7 +68,7 @@ public class LoaderBlockData extends LoaderRegistrant {
private final transient AtomicCache<BlockData> blockdata = new AtomicCache<>();
private final transient AtomicCache<String> realProperties = new AtomicCache<>();
public LoaderBlockData(String b) {
public IrisBlockData(String b) {
this.block = b;
}
@@ -95,7 +95,7 @@ public class LoaderBlockData extends LoaderRegistrant {
{
BlockData b = null;
LoaderBlockData customData = data.getBlockLoader().load(getBlock(), false);
IrisBlockData customData = data.getBlockLoader().load(getBlock(), false);
if (customData != null) {
b = customData.getBlockData(data);
@@ -152,8 +152,8 @@ public class LoaderBlockData extends LoaderRegistrant {
});
}
public static LoaderBlockData from(String j) {
LoaderBlockData b = new LoaderBlockData();
public static IrisBlockData from(String j) {
IrisBlockData b = new IrisBlockData();
String m = j.toLowerCase().trim();
if (m.contains(":")) {

View File

@@ -40,9 +40,9 @@ import org.bukkit.inventory.ItemStack;
@Data
public class IrisBlockDrops {
@Required
@ArrayType(min = 1, type = LoaderBlockData.class)
@ArrayType(min = 1, type = IrisBlockData.class)
@Desc("The blocks that drop loot")
private KList<LoaderBlockData> blocks = new KList<>();
private KList<IrisBlockData> blocks = new KList<>();
@Desc("If exact blocks is set to true, minecraft:barrel[axis=x] will only drop for that axis. When exact is false (default) any barrel will drop the defined drops.")
private boolean exactBlocks = false;
@@ -64,7 +64,7 @@ public class IrisBlockDrops {
{
KList<BlockData> b = new KList<>();
for (LoaderBlockData i : getBlocks()) {
for (IrisBlockData i : getBlocks()) {
BlockData dd = i.getBlockData(rdata);
if (dd != null) {

View File

@@ -49,9 +49,9 @@ public class IrisMaterialPalette {
private double zoom = 5;
@Required
@ArrayType(min = 1, type = LoaderBlockData.class)
@ArrayType(min = 1, type = IrisBlockData.class)
@Desc("The palette of blocks to be used in this layer")
private KList<LoaderBlockData> palette = new KList<LoaderBlockData>().qadd(new LoaderBlockData("STONE"));
private KList<IrisBlockData> palette = new KList<IrisBlockData>().qadd(new IrisBlockData("STONE"));
private final transient AtomicCache<KList<BlockData>> blockData = new AtomicCache<>();
private final transient AtomicCache<CNG> layerGenerator = new AtomicCache<>();
@@ -82,14 +82,14 @@ public class IrisMaterialPalette {
return this;
}
public KList<LoaderBlockData> add(String b) {
palette.add(new LoaderBlockData(b));
public KList<IrisBlockData> add(String b) {
palette.add(new IrisBlockData(b));
return palette;
}
public IrisMaterialPalette qadd(String b) {
palette.add(new LoaderBlockData(b));
palette.add(new IrisBlockData(b));
return this;
}
@@ -98,7 +98,7 @@ public class IrisMaterialPalette {
return blockData.aquire(() ->
{
KList<BlockData> blockData = new KList<>();
for (LoaderBlockData ix : palette) {
for (IrisBlockData ix : palette) {
BlockData bx = ix.getBlockData(rdata);
if (bx != null) {
for (int i = 0; i < ix.getWeight(); i++) {

View File

@@ -20,8 +20,8 @@ package com.volmit.iris.engine.object.carve;
import com.volmit.iris.core.project.loader.IrisData;
import com.volmit.iris.engine.data.cache.AtomicCache;
import com.volmit.iris.engine.data.B;
import com.volmit.iris.engine.object.block.LoaderBlockData;
import com.volmit.iris.util.data.B;
import com.volmit.iris.engine.object.block.IrisBlockData;
import com.volmit.iris.engine.object.annotations.Desc;
import com.volmit.iris.engine.object.annotations.MaxNumber;
import com.volmit.iris.engine.object.annotations.MinNumber;
@@ -49,7 +49,7 @@ public class IrisCaveFluid {
@Required
@Desc("The fluid type that should spawn here")
private LoaderBlockData fluidType = new LoaderBlockData("CAVE_AIR");
private IrisBlockData fluidType = new IrisBlockData("CAVE_AIR");
private final transient AtomicCache<BlockData> fluidData = new AtomicCache<>();

View File

@@ -20,7 +20,7 @@ package com.volmit.iris.engine.object.compat;
import com.google.gson.Gson;
import com.volmit.iris.Iris;
import com.volmit.iris.engine.data.B;
import com.volmit.iris.util.data.B;
import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.io.IO;
import com.volmit.iris.util.json.JSONObject;

View File

@@ -20,7 +20,7 @@ package com.volmit.iris.engine.object.compat;
import com.volmit.iris.Iris;
import com.volmit.iris.engine.data.cache.AtomicCache;
import com.volmit.iris.engine.data.B;
import com.volmit.iris.util.data.B;
import com.volmit.iris.engine.object.annotations.Desc;
import com.volmit.iris.engine.object.annotations.Required;
import lombok.AllArgsConstructor;

View File

@@ -20,7 +20,7 @@ package com.volmit.iris.engine.object.compat;
import com.volmit.iris.Iris;
import com.volmit.iris.engine.data.cache.AtomicCache;
import com.volmit.iris.engine.data.B;
import com.volmit.iris.util.data.B;
import com.volmit.iris.engine.object.annotations.Desc;
import com.volmit.iris.engine.object.annotations.Required;
import lombok.Data;

View File

@@ -21,8 +21,8 @@ package com.volmit.iris.engine.object.decoration;
import com.volmit.iris.Iris;
import com.volmit.iris.core.project.loader.IrisData;
import com.volmit.iris.engine.data.cache.AtomicCache;
import com.volmit.iris.engine.object.biome.LoaderBiome;
import com.volmit.iris.engine.object.block.LoaderBlockData;
import com.volmit.iris.engine.object.biome.IrisBiome;
import com.volmit.iris.engine.object.block.IrisBlockData;
import com.volmit.iris.engine.object.noise.IrisGeneratorStyle;
import com.volmit.iris.engine.object.noise.NoiseStyle;
import com.volmit.iris.util.noise.CNG;
@@ -82,13 +82,13 @@ public class IrisDecorator {
private double chance = 0.1;
@Required
@ArrayType(min = 1, type = LoaderBlockData.class)
@ArrayType(min = 1, type = IrisBlockData.class)
@Desc("The palette of blocks to pick from when this decorator needs to place.")
private KList<LoaderBlockData> palette = new KList<LoaderBlockData>().qadd(new LoaderBlockData("grass"));
private KList<IrisBlockData> palette = new KList<IrisBlockData>().qadd(new IrisBlockData("grass"));
@ArrayType(min = 1, type = LoaderBlockData.class)
@ArrayType(min = 1, type = IrisBlockData.class)
@Desc("The palette of blocks used at the very top of a 'stackMax' of higher than 1. For example, bamboo tops.")
private KList<LoaderBlockData> topPalette = new KList<>();
private KList<IrisBlockData> topPalette = new KList<>();
@DependsOn("topPalette")
@MinNumber(0.01)
@@ -126,12 +126,12 @@ public class IrisDecorator {
.scale(1D / variance.getZoom()));
}
public KList<LoaderBlockData> add(String b) {
palette.add(new LoaderBlockData(b));
public KList<IrisBlockData> add(String b) {
palette.add(new IrisBlockData(b));
return palette;
}
public BlockData getBlockData(LoaderBiome b, RNG rng, double x, double z, IrisData data) {
public BlockData getBlockData(IrisBiome b, RNG rng, double x, double z, IrisData data) {
if (getBlockData(data).isEmpty()) {
Iris.warn("Empty Block Data for " + b.getName());
return null;
@@ -151,7 +151,7 @@ public class IrisDecorator {
return null;
}
public BlockData getBlockData100(LoaderBiome b, RNG rng, double x, double y, double z, IrisData data) {
public BlockData getBlockData100(IrisBiome b, RNG rng, double x, double y, double z, IrisData data) {
if (getBlockData(data).isEmpty()) {
Iris.warn("Empty Block Data for " + b.getName());
return null;
@@ -174,7 +174,7 @@ public class IrisDecorator {
return getVarianceGenerator(rng, data).fit(getBlockData(data), z, y, x).clone(); //X and Z must be switched
}
public BlockData getBlockDataForTop(LoaderBiome b, RNG rng, double x, double y, double z, IrisData data) {
public BlockData getBlockDataForTop(IrisBiome b, RNG rng, double x, double y, double z, IrisData data) {
if (getBlockDataTops(data).isEmpty()) {
return getBlockData100(b, rng, x, y, z, data);
}
@@ -197,7 +197,7 @@ public class IrisDecorator {
return blockData.aquire(() ->
{
KList<BlockData> blockData = new KList<>();
for (LoaderBlockData i : palette) {
for (IrisBlockData i : palette) {
BlockData bx = i.getBlockData(data);
if (bx != null) {
for (int n = 0; n < i.getWeight(); n++) {
@@ -214,7 +214,7 @@ public class IrisDecorator {
return blockDataTops.aquire(() ->
{
KList<BlockData> blockDataTops = new KList<>();
for (LoaderBlockData i : topPalette) {
for (IrisBlockData i : topPalette) {
BlockData bx = i.getBlockData(data);
if (bx != null) {
for (int n = 0; n < i.getWeight(); n++) {

View File

@@ -21,8 +21,8 @@ package com.volmit.iris.engine.object.deposits;
import com.volmit.iris.core.project.loader.IrisData;
import com.volmit.iris.engine.data.cache.AtomicCache;
import com.volmit.iris.engine.object.annotations.*;
import com.volmit.iris.engine.object.block.LoaderBlockData;
import com.volmit.iris.engine.object.objects.LoaderObject;
import com.volmit.iris.engine.object.block.IrisBlockData;
import com.volmit.iris.engine.object.objects.IrisObject;
import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.math.RNG;
import lombok.AllArgsConstructor;
@@ -75,23 +75,23 @@ public class IrisDepositGenerator {
private int minPerChunk = 1;
@Required
@ArrayType(min = 1, type = LoaderBlockData.class)
@ArrayType(min = 1, type = IrisBlockData.class)
@Desc("The palette of blocks to be used in this deposit generator")
private KList<LoaderBlockData> palette = new KList<>();
private KList<IrisBlockData> palette = new KList<>();
@MinNumber(1)
@MaxNumber(64)
@Desc("Ore varience is how many different objects clumps iris will create")
private int varience = 3;
private final transient AtomicCache<KList<LoaderObject>> objects = new AtomicCache<>();
private final transient AtomicCache<KList<IrisObject>> objects = new AtomicCache<>();
private final transient AtomicCache<KList<BlockData>> blockData = new AtomicCache<>();
public LoaderObject getClump(RNG rng, IrisData rdata) {
KList<LoaderObject> objects = this.objects.aquire(() ->
public IrisObject getClump(RNG rng, IrisData rdata) {
KList<IrisObject> objects = this.objects.aquire(() ->
{
RNG rngv = rng.nextParallelRNG(3957778);
KList<LoaderObject> objectsf = new KList<>();
KList<IrisObject> objectsf = new KList<>();
for (int i = 0; i < varience; i++) {
objectsf.add(generateClumpObject(rngv.nextParallelRNG(2349 * i + 3598), rdata));
@@ -106,11 +106,11 @@ public class IrisDepositGenerator {
return Math.min(11, (int) Math.round(Math.pow(maxSize, 1D / 3D)));
}
private LoaderObject generateClumpObject(RNG rngv, IrisData rdata) {
private IrisObject generateClumpObject(RNG rngv, IrisData rdata) {
int s = rngv.i(minSize, maxSize);
int dim = Math.min(11, (int) Math.round(Math.pow(maxSize, 1D / 3D)));
int w = dim / 2;
LoaderObject o = new LoaderObject(dim, dim, dim);
IrisObject o = new IrisObject(dim, dim, dim);
if (s == 1) {
o.getBlocks().put(o.getCenter(), nextBlock(rngv, rdata));
@@ -135,7 +135,7 @@ public class IrisDepositGenerator {
{
KList<BlockData> blockData = new KList<>();
for (LoaderBlockData ix : palette) {
for (IrisBlockData ix : palette) {
BlockData bx = ix.getBlockData(rdata);
if (bx != null) {

View File

@@ -20,11 +20,11 @@ package com.volmit.iris.engine.object.dimensional;
import com.volmit.iris.Iris;
import com.volmit.iris.core.project.loader.IrisData;
import com.volmit.iris.core.project.loader.LoaderRegistrant;
import com.volmit.iris.core.project.loader.IrisRegistrant;
import com.volmit.iris.engine.data.cache.AtomicCache;
import com.volmit.iris.engine.data.DataProvider;
import com.volmit.iris.util.data.DataProvider;
import com.volmit.iris.engine.object.biome.InferredType;
import com.volmit.iris.engine.object.biome.LoaderBiome;
import com.volmit.iris.engine.object.biome.IrisBiome;
import com.volmit.iris.engine.object.biome.IrisBiomeCustom;
import com.volmit.iris.engine.object.biome.IrisBiomeMutation;
import com.volmit.iris.engine.object.block.IrisBlockDrops;
@@ -36,15 +36,15 @@ import com.volmit.iris.engine.object.carve.IrisCaverns;
import com.volmit.iris.engine.object.deposits.IrisDepositGenerator;
import com.volmit.iris.engine.object.feature.IrisFeaturePositional;
import com.volmit.iris.engine.object.feature.IrisFeaturePotential;
import com.volmit.iris.engine.object.jigsaw.LoaderJigsawStructure;
import com.volmit.iris.engine.object.jigsaw.IrisJigsawStructure;
import com.volmit.iris.engine.object.jigsaw.IrisJigsawStructurePlacement;
import com.volmit.iris.engine.object.loot.IrisLootReference;
import com.volmit.iris.engine.object.noise.IrisGeneratorStyle;
import com.volmit.iris.engine.object.noise.IrisShapedGeneratorStyle;
import com.volmit.iris.engine.object.noise.NoiseStyle;
import com.volmit.iris.engine.object.objects.IrisObjectPlacement;
import com.volmit.iris.engine.object.regional.LoaderRegion;
import com.volmit.iris.engine.object.spawners.LoaderSpawner;
import com.volmit.iris.engine.object.regional.IrisRegion;
import com.volmit.iris.engine.object.spawners.IrisSpawner;
import com.volmit.iris.engine.object.trees.IrisTreeSettings;
import com.volmit.iris.util.noise.CNG;
import com.volmit.iris.engine.object.annotations.*;
@@ -71,7 +71,7 @@ import java.io.IOException;
@Desc("Represents a dimension")
@Data
@EqualsAndHashCode(callSuper = false)
public class LoaderDimension extends LoaderRegistrant {
public class IrisDimension extends IrisRegistrant {
public static final BlockData STONE = Material.STONE.createBlockData();
public static final BlockData WATER = Material.WATER.createBlockData();
@@ -85,9 +85,9 @@ public class LoaderDimension extends LoaderRegistrant {
private KList<IrisDimensionIndex> dimensionalComposite = new KList<>();
@Desc("Create an inverted dimension in the sky (like the nether)")
private LoaderDimension sky = null;
private IrisDimension sky = null;
@RegistryListResource(LoaderJigsawStructure.class)
@RegistryListResource(IrisJigsawStructure.class)
@Desc("If defined, Iris will place the given jigsaw structure where minecraft should place the overworld stronghold.")
private String stronghold;
@@ -114,7 +114,7 @@ public class LoaderDimension extends LoaderRegistrant {
@Desc("Spawn Entities in this dimension over time. Iris will continually replenish these mobs just like vanilla does.")
@ArrayType(min = 1, type = String.class)
@RegistryListResource(LoaderSpawner.class)
@RegistryListResource(IrisSpawner.class)
private KList<String> entitySpawners = new KList<>();
@Desc("Add specific features in exact positions")
@@ -218,7 +218,7 @@ public class LoaderDimension extends LoaderRegistrant {
@Desc("The world environment")
private Environment environment = Environment.NORMAL;
@RegistryListResource(LoaderRegion.class)
@RegistryListResource(IrisRegion.class)
@Required
@ArrayType(min = 1, type = String.class)
@Desc("Define all of the regions to include in this dimension. Dimensions -> Regions -> Biomes -> Objects etc")
@@ -234,11 +234,11 @@ public class LoaderDimension extends LoaderRegistrant {
@Desc("The fluid height for this dimension")
private int fluidHeight = 63;
@RegistryListResource(LoaderBiome.class)
@RegistryListResource(IrisBiome.class)
@Desc("Keep this either undefined or empty. Setting any biome name into this will force iris to only generate the specified biome. Great for testing.")
private String focus = "";
@RegistryListResource(LoaderBiome.class)
@RegistryListResource(IrisBiome.class)
@Desc("Keep this either undefined or empty. Setting any region name into this will force iris to only generate the specified region. Great for testing.")
private String focusRegion = "";
@@ -409,8 +409,8 @@ public class LoaderDimension extends LoaderRegistrant {
return cosr.aquire(() -> Math.cos(getDimensionAngle()));
}
public KList<LoaderRegion> getAllRegions(DataProvider g) {
KList<LoaderRegion> r = new KList<>();
public KList<IrisRegion> getAllRegions(DataProvider g) {
KList<IrisRegion> r = new KList<>();
for (String i : getRegions()) {
r.add(g.getData().getRegionLoader().load(i));
@@ -419,8 +419,8 @@ public class LoaderDimension extends LoaderRegistrant {
return r;
}
public KList<LoaderRegion> getAllAnyRegions() {
KList<LoaderRegion> r = new KList<>();
public KList<IrisRegion> getAllAnyRegions() {
KList<IrisRegion> r = new KList<>();
for (String i : getRegions()) {
r.add(IrisData.loadAnyRegion(i));
@@ -429,14 +429,14 @@ public class LoaderDimension extends LoaderRegistrant {
return r;
}
public KList<LoaderBiome> getAllBiomes(DataProvider g) {
public KList<IrisBiome> getAllBiomes(DataProvider g) {
return g.getData().getBiomeLoader().loadAll(g.getData().getBiomeLoader().getPossibleKeys());
}
public KList<LoaderBiome> getAllAnyBiomes() {
KList<LoaderBiome> r = new KList<>();
public KList<IrisBiome> getAllAnyBiomes() {
KList<IrisBiome> r = new KList<>();
for (LoaderRegion i : getAllAnyRegions()) {
for (IrisRegion i : getAllAnyRegions()) {
if (i == null) {
continue;
}
@@ -474,7 +474,7 @@ public class LoaderDimension extends LoaderRegistrant {
IO.delete(new File(datapacks, "iris/data/" + getLoadKey()));
for (LoaderBiome i : getAllBiomes(data)) {
for (IrisBiome i : getAllBiomes(data)) {
if (i.isCustom()) {
write = true;
@@ -524,7 +524,7 @@ public class LoaderDimension extends LoaderRegistrant {
return true;
}
for (LoaderRegion i : getAllRegions(data)) {
for (IrisRegion i : getAllRegions(data)) {
if (i.getFeatures().isNotEmpty()) {
return true;
}
@@ -535,7 +535,7 @@ public class LoaderDimension extends LoaderRegistrant {
}
}
for (LoaderBiome j : i.getAllBiomes(data)) {
for (IrisBiome j : i.getAllBiomes(data)) {
if (j.getFeatures().isNotEmpty()) {
return true;
}

View File

@@ -47,7 +47,7 @@ public class IrisDimensionIndex {
private boolean primary = false;
@Required
@RegistryListResource(LoaderDimension.class)
@RegistryListResource(IrisDimension.class)
@MinNumber(1)
@Desc("Name of dimension")
private String dimension = "";

View File

@@ -19,14 +19,14 @@
package com.volmit.iris.engine.object.entity;
import com.volmit.iris.Iris;
import com.volmit.iris.core.project.loader.LoaderRegistrant;
import com.volmit.iris.core.project.loader.IrisRegistrant;
import com.volmit.iris.engine.framework.Engine;
import com.volmit.iris.engine.object.annotations.ArrayType;
import com.volmit.iris.engine.object.annotations.Desc;
import com.volmit.iris.engine.object.annotations.Required;
import com.volmit.iris.engine.object.loot.IrisLoot;
import com.volmit.iris.engine.object.loot.IrisLootReference;
import com.volmit.iris.engine.object.loot.LoaderLootTable;
import com.volmit.iris.engine.object.loot.IrisLootTable;
import com.volmit.iris.engine.object.meta.InventorySlotType;
import com.volmit.iris.engine.object.meta.IrisAttributeModifier;
import com.volmit.iris.engine.object.meta.IrisEffect;
@@ -65,7 +65,7 @@ import java.util.concurrent.atomic.AtomicReference;
@Desc("Represents an iris entity.")
@Data
@EqualsAndHashCode(callSuper = false)
public class LoaderEntity extends LoaderRegistrant {
public class IrisEntity extends IrisRegistrant {
@Required
@Desc("The type of entity to spawn. To spawn a mythic mob, set this type to unknown and define mythic type.")
private EntityType type = EntityType.UNKNOWN;
@@ -119,8 +119,8 @@ public class LoaderEntity extends LoaderRegistrant {
private IrisLoot offHand = null;
@Desc("Make other entities ride this entity")
@ArrayType(min = 1, type = LoaderEntity.class)
private KList<LoaderEntity> passengers = new KList<>();
@ArrayType(min = 1, type = IrisEntity.class)
private KList<IrisEntity> passengers = new KList<>();
@Desc("Attribute modifiers for this entity")
@ArrayType(min = 1, type = IrisAttributeModifier.class)
@@ -130,7 +130,7 @@ public class LoaderEntity extends LoaderRegistrant {
private IrisLootReference loot = new IrisLootReference();
@Desc("If specified, this entity will be leashed by this entity. I.e. THIS ENTITY Leashed by SPECIFIED. This has no effect on EnderDragons, Withers, Players, or Bats.Non-living entities excluding leashes will not persist as leashholders.")
private LoaderEntity leashHolder = null;
private IrisEntity leashHolder = null;
@Desc("If specified, this entity will spawn with an effect")
private IrisEffect spawnEffect = null;
@@ -171,7 +171,7 @@ public class LoaderEntity extends LoaderRegistrant {
e.setPersistent(isKeepEntity());
int gg = 0;
for (LoaderEntity i : passengers) {
for (IrisEntity i : passengers) {
Entity passenger = i.spawn(gen, at, rng.nextParallelRNG(234858 + gg++));
if (!Bukkit.isPrimaryThread()) {
J.s(() -> e.addPassenger(passenger));
@@ -193,7 +193,7 @@ public class LoaderEntity extends LoaderRegistrant {
l.setLootTable(new LootTable() {
@Override
public NamespacedKey getKey() {
return new NamespacedKey(Iris.instance, "loot-" + LoaderEntity.this.hashCode());
return new NamespacedKey(Iris.instance, "loot-" + IrisEntity.this.hashCode());
}
@Override
@@ -201,7 +201,7 @@ public class LoaderEntity extends LoaderRegistrant {
KList<ItemStack> items = new KList<>();
for (String fi : getLoot().getTables()) {
LoaderLootTable i = gen.getData().getLootLoader().load(fi);
IrisLootTable i = gen.getData().getLootLoader().load(fi);
items.addAll(i.getLoot(gen.isStudio(), false, rng.nextParallelRNG(345911), InventorySlotType.STORAGE, at.getBlockX(), at.getBlockY(), at.getBlockZ(), 8, 4));
}

View File

@@ -24,8 +24,8 @@ import com.volmit.iris.engine.data.cache.AtomicCache;
import com.volmit.iris.engine.framework.Engine;
import com.volmit.iris.engine.framework.EngineFramework;
import com.volmit.iris.engine.modifier.IrisCaveModifier;
import com.volmit.iris.engine.object.biome.LoaderBiome;
import com.volmit.iris.engine.object.spawners.LoaderSpawner;
import com.volmit.iris.engine.object.biome.IrisBiome;
import com.volmit.iris.engine.object.spawners.IrisSpawner;
import com.volmit.iris.engine.object.annotations.Desc;
import com.volmit.iris.engine.object.annotations.MinNumber;
import com.volmit.iris.engine.object.annotations.RegistryListResource;
@@ -49,7 +49,7 @@ import org.bukkit.entity.Entity;
@Desc("Represents an entity spawn during initial chunk generation")
@Data
public class IrisEntitySpawn implements IRare {
@RegistryListResource(LoaderEntity.class)
@RegistryListResource(IrisEntity.class)
@Required
@Desc("The entity")
private String entity = "";
@@ -69,9 +69,9 @@ public class IrisEntitySpawn implements IRare {
@Desc("The max of this entity to spawn")
private int maxSpawns = 1;
private transient LoaderSpawner referenceSpawner;
private transient IrisSpawner referenceSpawner;
private final transient AtomicCache<RNG> rng = new AtomicCache<>();
private final transient AtomicCache<LoaderEntity> ent = new AtomicCache<>();
private final transient AtomicCache<IrisEntity> ent = new AtomicCache<>();
public int spawn(Engine gen, Chunk c, RNG rng) {
int spawns = minSpawns == maxSpawns ? minSpawns : rng.i(Math.min(minSpawns, maxSpawns), Math.max(minSpawns, maxSpawns));
@@ -88,7 +88,7 @@ public class IrisEntitySpawn implements IRare {
case CAVE -> {
IrisComplex comp = gen.getFramework().getComplex();
EngineFramework frame = gen.getFramework();
LoaderBiome cave = comp.getCaveBiomeStream().get(x, z);
IrisBiome cave = comp.getCaveBiomeStream().get(x, z);
KList<Location> r = new KList<>();
if (cave != null) {
for (CaveResult i : ((IrisCaveModifier) frame.getCaveModifier()).genCaves(x, z)) {
@@ -116,7 +116,7 @@ public class IrisEntitySpawn implements IRare {
return s;
}
public LoaderEntity getRealEntity(Engine g) {
public IrisEntity getRealEntity(Engine g) {
return ent.aquire(() -> g.getData().getEntityLoader().load(getEntity()));
}
@@ -134,7 +134,7 @@ public class IrisEntitySpawn implements IRare {
private Entity spawn100(Engine g, Location at) {
try {
LoaderEntity irisEntity = getRealEntity(g);
IrisEntity irisEntity = getRealEntity(g);
if (!irisEntity.getSurface().matches(at.clone().subtract(0, 1, 0).getBlock().getState())) return null; //Make sure it can spawn on the block

View File

@@ -40,7 +40,7 @@ import org.bukkit.event.entity.EntitySpawnEvent;
@Desc("Represents an entity spawn")
@Data
public class IrisEntitySpawnOverride {
@RegistryListResource(LoaderEntity.class)
@RegistryListResource(IrisEntity.class)
@Required
@Desc("The entity")
private String entity = "";
@@ -57,7 +57,7 @@ public class IrisEntitySpawnOverride {
private int rarity = 1;
private final transient AtomicCache<RNG> rng = new AtomicCache<>();
private final transient AtomicCache<LoaderEntity> ent = new AtomicCache<>();
private final transient AtomicCache<IrisEntity> ent = new AtomicCache<>();
public Entity on(Engine g, Location at, EntityType t, EntitySpawnEvent ee) {
@@ -89,7 +89,7 @@ public class IrisEntitySpawnOverride {
return null;
}
public LoaderEntity getRealEntity(Engine g) {
public IrisEntity getRealEntity(Engine g) {
return ent.aquire(() -> g.getData().getEntityLoader().load(getEntity()));
}
}

View File

@@ -22,8 +22,8 @@ import com.google.gson.Gson;
import com.volmit.iris.engine.data.cache.AtomicCache;
import com.volmit.iris.util.interpolation.InterpolationMethod;
import com.volmit.iris.util.interpolation.IrisInterpolation;
import com.volmit.iris.engine.object.biome.LoaderBiome;
import com.volmit.iris.engine.object.spawners.LoaderSpawner;
import com.volmit.iris.engine.object.biome.IrisBiome;
import com.volmit.iris.engine.object.spawners.IrisSpawner;
import com.volmit.iris.engine.object.annotations.*;
import com.volmit.iris.engine.object.noise.IrisGeneratorStyle;
import com.volmit.iris.util.collection.KList;
@@ -50,7 +50,7 @@ public class IrisFeature {
@Desc("The chance an object that should be place actually will place. Set to below 1 to affect objects in this zone")
private double objectChance = 1;
@RegistryListResource(LoaderBiome.class)
@RegistryListResource(IrisBiome.class)
@Desc("Apply a custom biome here")
private String customBiome = null;
@@ -85,7 +85,7 @@ public class IrisFeature {
@Desc("Fracture the radius ring with additional noise")
private IrisGeneratorStyle fractureRadius = null;
@RegistryListResource(LoaderSpawner.class)
@RegistryListResource(IrisSpawner.class)
@ArrayType(min = 1, type = String.class)
@Desc("Within this noise feature, use the following spawners")
private KList<String> entitySpawners = new KList<>();

Some files were not shown because too many files have changed in this diff Show More