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

This commit is contained in:
CocoTheOwner 2021-08-28 17:59:40 +02:00
commit cf1f3677ae
19 changed files with 387 additions and 12 deletions

View File

@ -252,6 +252,11 @@ public class CommandIrisObjectPaste extends MortarCommand {
return false;
}
@Override
public boolean isCarved(int x, int y, int z) {
return false;
}
@Override
public boolean isSolid(int x, int y, int z) {
return world.getBlockAt(x, y, z).getType().isSolid();

View File

@ -133,6 +133,11 @@ public class CommandIrisObjectPasteMatter extends MortarCommand {
return false;
}
@Override
public boolean isCarved(int x, int y, int z) {
return false;
}
@Override
public boolean isSolid(int x, int y, int z) {
return world.getBlockAt(x, y, z).getType().isSolid();

View File

@ -281,6 +281,11 @@ public class DecObject implements DecreeExecutor {
return false;
}
@Override
public boolean isCarved(int x, int y, int z) {
return false;
}
@Override
public boolean isSolid(int x, int y, int z) {
return world.getBlockAt(x, y, z).getType().isSolid();

View File

@ -23,6 +23,7 @@ import com.volmit.iris.engine.framework.Engine;
import com.volmit.iris.engine.object.biome.IrisBiome;
import com.volmit.iris.engine.object.block.IrisBlockData;
import com.volmit.iris.engine.object.carving.IrisCave;
import com.volmit.iris.engine.object.carving.IrisRavine;
import com.volmit.iris.engine.object.common.IrisScript;
import com.volmit.iris.engine.object.dimensional.IrisDimension;
import com.volmit.iris.engine.object.entity.IrisEntity;
@ -65,6 +66,7 @@ public class IrisData {
private ResourceLoader<IrisObject> objectLoader;
private ResourceLoader<IrisScript> scriptLoader;
private ResourceLoader<IrisCave> caveLoader;
private ResourceLoader<IrisRavine> ravineLoader;
private KMap<Class<? extends IrisRegistrant>, ResourceLoader<? extends IrisRegistrant>> loaders = new KMap<>();
private boolean closed;
private final File dataFolder;
@ -210,6 +212,7 @@ public class IrisData {
this.jigsawPieceLoader = registerLoader(IrisJigsawPiece.class);
this.generatorLoader = registerLoader(IrisGenerator.class);
this.caveLoader = registerLoader(IrisCave.class);
this.ravineLoader = registerLoader(IrisRavine.class);
this.blockLoader = registerLoader(IrisBlockData.class);
this.expressionLoader = registerLoader(IrisExpression.class);
this.objectLoader = registerLoader(IrisObject.class);
@ -280,6 +283,10 @@ public class IrisData {
return loadAny(key, (dm) -> dm.getScriptLoader().load(key, false));
}
public static IrisRavine loadAnyRavine(String key) {
return loadAny(key, (dm) -> dm.getRavineLoader().load(key, false));
}
public static IrisRegion loadAnyRegion(String key) {
return loadAny(key, (dm) -> dm.getRegionLoader().load(key, false));
}

View File

@ -146,6 +146,11 @@ public class TreeSVC implements IrisService {
return true;
}
@Override
public boolean isCarved(int x, int y, int z) {
return false;
}
@Override
public boolean isSolid(int x, int y, int z) {
return get(x, y, z).getMaterial().isSolid();

View File

@ -414,9 +414,9 @@ public class IrisEngine implements Engine {
getTerrainActuator().actuate(x, z, blocks, multicore);
getBiomeActuator().actuate(x, z, vbiomes, multicore);
getDecorantActuator().actuate(x, z, blocks, multicore);
getPostModifier().modify(x, z, blocks, multicore);
getDepositModifier().modify(x, z, blocks, multicore);
getCaveModifier().modify(x >> 4,z >> 4, blocks, multicore);
getPostModifier().modify(x, z, blocks, multicore);
getMantle().insertMatter(x >> 4, z >> 4, BlockData.class, blocks, multicore);
}
getMetrics().getTotal().put(p.getMilliseconds());

View File

@ -246,11 +246,25 @@ public interface Engine extends DataProvider, Fallible, LootProvider, BlockUpdat
{
getMantle().getMantle().raiseFlag(c.getX(), c.getZ(), MantleFlag.UPDATE, () -> J.s(() -> {
PrecisionStopwatch p = PrecisionStopwatch.start();
KMap<Long, Integer> updates = new KMap<>();
RNG r = new RNG(Cache.key(c.getX(), c.getZ()));
getMantle().getMantle().iterateChunk(c.getX(), c.getZ(), MatterCavern.class, (x, y, z, v) -> {
update(x, y, z, c, new RNG(Cache.key(c.getX(), c.getZ())));
if(B.isAir(c.getBlock(x & 15, y, z & 15).getBlockData()))
{
return;
}
updates.compute(Cache.key(x & 15, z & 15), (k,vv) -> {
if(vv != null)
{
return Math.max(vv, y);
}
return y;
});
});
updates.forEach((k,v) -> update(Cache.keyX(k), v, Cache.keyZ(k), c, r));
getMantle().getMantle().iterateChunk(c.getX(), c.getZ(), MatterUpdate.class, (x, y, z, v) -> {
if (v != null && v.isUpdate()) {
int vx = x & 15;
@ -262,7 +276,6 @@ public interface Engine extends DataProvider, Fallible, LootProvider, BlockUpdat
}
});
getMantle().getMantle().deleteChunkSlice(c.getX(), c.getZ(), MatterCavern.class);
getMantle().getMantle().deleteChunkSlice(c.getX(), c.getZ(), MatterUpdate.class);
getMetrics().getUpdates().put(p.getMilliseconds());

View File

@ -56,7 +56,7 @@ public abstract class EngineAssignedWorldManager extends EngineAssignedComponent
@EventHandler
public void on(IrisEngineHotloadEvent e) {
for (Player i : e.getEngine().getWorld().getPlayers()) {
i.playSound(i.getLocation(), Sound.ITEM_TRIDENT_RETURN, 1f, 1.6f);
i.playSound(i.getLocation(), Sound.BLOCK_AMETHYST_BLOCK_BREAK, 1f, 1.8f);
VolmitSender s = new VolmitSender(i);
s.sendTitle(C.IRIS + "Engine " + C.AQUA + "<font:minecraft:uniform>Hotloaded", 70, 60, 410);
}

View File

@ -57,6 +57,11 @@ public class HeightmapObjectPlacer implements IObjectPlacer {
return oplacer.isPreventingDecay();
}
@Override
public boolean isCarved(int x, int y, int z) {
return false;
}
public boolean isSolid(int param1Int1, int param1Int2, int param1Int3) {
return oplacer.isSolid(param1Int1, param1Int2, param1Int3);
}

View File

@ -208,6 +208,11 @@ public class PlannedPiece {
return false;
}
@Override
public boolean isCarved(int x, int y, int z) {
return false;
}
@Override
public boolean isSolid(int x, int y, int z) {
return world.getBlockAt(x, y, z).getType().isSolid();

View File

@ -84,6 +84,11 @@ public interface EngineMantle extends IObjectPlacer {
return getComplex().getTrueHeightStream().get(x, z);
}
default boolean isCarved(int x, int h, int z)
{
return getMantle().get(x, h, z, MatterCavern.class) != null;
}
@Override
default void set(int x, int y, int z, BlockData d) {
getMantle().set(x, y, z, d == null ? AIR : d);
@ -226,6 +231,7 @@ public interface EngineMantle extends IObjectPlacer {
}
getMantle().iterateChunk(x, z, t, blocks::set);
getMantle().deleteChunkSlice(x, z, BlockData.class);
}
@BlockCoordinates

View File

@ -121,6 +121,11 @@ public class MantleWriter implements IObjectPlacer {
return getEngineMantle().isPreventingDecay();
}
@Override
public boolean isCarved(int x, int y, int z) {
return getEngineMantle().isCarved(x, y, z);
}
@Override
public boolean isSolid(int x, int y, int z) {
return getEngineMantle().isSolid(x, y, z);

View File

@ -94,7 +94,6 @@ public class MantleObjectComponent extends IrisMantleComponent {
int zz = rng.i(z, z + 15);
int id = rng.i(0, Integer.MAX_VALUE);
int h = v.place(xx, -1, zz, writer, objectPlacement, rng,
(b) -> writer.setData(b.getX(), b.getY(), b.getZ(),
v.getLoadKey() + "@" + id), null, getData());

View File

@ -41,6 +41,10 @@ public class IrisCarving {
@Desc("Define cave placers")
private KList<IrisCavePlacer> caves = new KList<>();
@ArrayType(type = IrisRavinePlacer.class, min = 1)
@Desc("Define ravine placers")
private KList<IrisRavinePlacer> ravines = new KList<>();
@ArrayType(type = IrisElipsoid.class, min = 1)
@Desc("Define elipsoids")
private KList<IrisElipsoid> elipsoids = new KList<>();
@ -53,8 +57,6 @@ public class IrisCarving {
@Desc("Define pyramids")
private KList<IrisPyramid> pyramids = new KList<>();
@BlockCoordinates
public void doCarving(MantleWriter writer, RNG rng, Engine engine, int x, int y, int z) {
if(caves.isNotEmpty())
@ -65,6 +67,14 @@ public class IrisCarving {
}
}
if(ravines.isNotEmpty())
{
for(IrisRavinePlacer i : ravines)
{
i.generateRavine(writer, rng, engine, x, y, z);
}
}
if(spheres.isNotEmpty())
{
for(IrisSphere i : spheres)

View File

@ -0,0 +1,162 @@
/*
* Iris is a World Generator for Minecraft Bukkit Servers
* Copyright (c) 2021 Arcane Arts (Volmit Software)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.volmit.iris.engine.object.carving;
import com.volmit.iris.Iris;
import com.volmit.iris.core.loader.IrisData;
import com.volmit.iris.core.loader.IrisRegistrant;
import com.volmit.iris.engine.framework.Engine;
import com.volmit.iris.engine.mantle.MantleWriter;
import com.volmit.iris.engine.object.annotations.Desc;
import com.volmit.iris.engine.object.annotations.MaxNumber;
import com.volmit.iris.engine.object.annotations.MinNumber;
import com.volmit.iris.engine.object.basic.IrisPosition;
import com.volmit.iris.engine.object.basic.IrisRange;
import com.volmit.iris.engine.object.noise.IrisShapedGeneratorStyle;
import com.volmit.iris.engine.object.noise.IrisWorm;
import com.volmit.iris.engine.object.noise.NoiseStyle;
import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.json.JSONObject;
import com.volmit.iris.util.math.RNG;
import com.volmit.iris.util.matter.slices.CavernMatter;
import com.volmit.iris.util.noise.CNG;
import com.volmit.iris.util.plugin.VolmitSender;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
@EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
@NoArgsConstructor
@AllArgsConstructor
@Desc("Translate objects")
@Data
public class IrisRavine extends IrisRegistrant {
@Desc("Define the shape of this ravine (2d, ignores Y)")
private IrisWorm worm;
@Desc("Define potential forking features")
private IrisCarving fork = new IrisCarving();
@Desc("The style used to determine the curvature of this worm's y")
private IrisShapedGeneratorStyle depthStyle = new IrisShapedGeneratorStyle(NoiseStyle.PERLIN, 5, 18);
@Desc("The style used to determine the curvature of this worm's y")
private IrisShapedGeneratorStyle baseWidthStyle = new IrisShapedGeneratorStyle(NoiseStyle.PERLIN, 3, 6);
@MinNumber(1)
@MaxNumber(70)
@Desc("The angle at which the ravine widens as it gets closer to the surface")
private double angle = 18;
@MinNumber(1)
@MaxNumber(70)
@Desc("The angle at which the ravine widens as it gets closer to the surface")
private double topAngle = 38;
@Desc("How many worm nodes must be placed to actually generate a ravine? Higher reduces the chances but also reduces ravine 'holes'")
private int nodeThreshold = 5;
@MinNumber(1)
@MaxNumber(8)
@Desc("The thickness of the ravine ribs")
private double ribThickness = 3;
@Override
public String getFolderName() {
return "ravines";
}
@Override
public String getTypeName() {
return "Ravine";
}
public void generate(MantleWriter writer, RNG rng, Engine engine, int x, int y, int z) {
KList<IrisPosition> pos = getWorm().generate(rng, engine.getData(), writer, null, x, y, z, (at) -> {});
CNG dg = depthStyle.getGenerator().createNoCache(rng, engine.getData());
CNG bw = baseWidthStyle.getGenerator().createNoCache(rng, engine.getData());
if(pos.size() < nodeThreshold)
{
return;
}
for(IrisPosition p : pos)
{
int rsurface = y == -1 ? engine.getComplex().getHeightStream().get(x, z).intValue() : y;
int depth = (int) Math.round(dg.fitDouble(depthStyle.getMin(), depthStyle.getMax(), p.getX(), p.getZ()));
int width = (int) Math.round(bw.fitDouble(baseWidthStyle.getMin(), baseWidthStyle.getMax(), p.getX(), p.getZ()));
int surface = (int) Math.round(rsurface - depth * 0.45);
fork.doCarving(writer, rng, engine, p.getX(), rng.r.i(surface-depth, surface), p.getZ());
for(int i = surface + depth; i >= surface; i--)
{
if(i % ribThickness == 0) {
double v = width + ((((surface + depth) - i) * (angle / 360D)));
if(v <= 0.25)
{
break;
}
if(i <= ribThickness+2)
{
break;
}
writer.setElipsoid(p.getX(), i, p.getZ(), v, ribThickness, v, true, CavernMatter.ON);
}
}
for(int i = surface - depth; i <= surface; i++)
{
if(i % ribThickness == 0) {
double v = width - ((((surface - depth) - i) * (angle / 360D)));
if(v <= 0.25)
{
break;
}
if(i <= ribThickness+2)
{
break;
}
writer.setElipsoid(p.getX(), i, p.getZ(), v, ribThickness, v, true, CavernMatter.ON);
}
}
}
}
@Override
public void scanForErrors(JSONObject p, VolmitSender sender) {
}
public int getMaxSize(IrisData data) {
return getWorm().getMaxDistance() + fork.getMaxRange(data);
}
}

View File

@ -0,0 +1,102 @@
/*
* Iris is a World Generator for Minecraft Bukkit Servers
* Copyright (c) 2021 Arcane Arts (Volmit Software)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.volmit.iris.engine.object.carving;
import com.volmit.iris.Iris;
import com.volmit.iris.core.loader.IrisData;
import com.volmit.iris.engine.data.cache.AtomicCache;
import com.volmit.iris.engine.framework.Engine;
import com.volmit.iris.engine.mantle.MantleWriter;
import com.volmit.iris.engine.object.annotations.Desc;
import com.volmit.iris.engine.object.annotations.MinNumber;
import com.volmit.iris.engine.object.annotations.RegistryListResource;
import com.volmit.iris.engine.object.annotations.Required;
import com.volmit.iris.engine.object.common.IRare;
import com.volmit.iris.engine.object.noise.IrisGeneratorStyle;
import com.volmit.iris.engine.object.noise.IrisStyledRange;
import com.volmit.iris.engine.object.noise.NoiseStyle;
import com.volmit.iris.util.math.RNG;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import java.util.concurrent.atomic.AtomicBoolean;
@Accessors(chain = true)
@NoArgsConstructor
@AllArgsConstructor
@Desc("Translate objects")
@Data
public class IrisRavinePlacer implements IRare {
@Required
@Desc("Typically a 1 in RARITY on a per chunk/fork basis")
@MinNumber(1)
private int rarity = 15;
@MinNumber(1)
@Required
@Desc("The ravine to place")
@RegistryListResource(IrisRavine.class)
private String ravine;
private transient final AtomicCache<IrisRavine> ravineCache = new AtomicCache<>();
private transient final AtomicBoolean fail = new AtomicBoolean(false);
public IrisRavine getRealRavine(IrisData data) {
return ravineCache.aquire(() -> data.getRavineLoader().load(getRavine()));
}
public void generateRavine(MantleWriter mantle, RNG rng, Engine engine, int x, int y, int z) {
if (fail.get()) {
return;
}
if(rng.nextInt(rarity) != 0)
{
return;
}
IrisData data = engine.getData();
IrisRavine ravine = getRealRavine(data);
if (ravine == null) {
Iris.warn("Unable to locate ravine for generation!");
fail.set(true);
return;
}
try
{
int xx = x + rng.nextInt(15);
int zz = z + rng.nextInt(15);
ravine.generate(mantle, rng, engine, xx, y, zz);
}
catch(Throwable e)
{
e.printStackTrace();
fail.set(true);
}
}
public int getSize(IrisData data) {
return getRealRavine(data).getMaxSize(data);
}
}

View File

@ -34,6 +34,8 @@ public interface IObjectPlacer {
boolean isPreventingDecay();
boolean isCarved(int x, int y, int z);
boolean isSolid(int x, int y, int z);
boolean isUnderwater(int x, int z);

View File

@ -98,12 +98,12 @@ public class IrisWorm {
cz += jz;
IrisPosition next = new IrisPosition(Math.round(cx), Math.round(cy), Math.round(cz));
if(!verticalRange.contains(next.getY()))
if(verticalRange != null && !verticalRange.contains(next.getY()))
{
break;
}
if(!writer.isWithin((int)Math.round(cx), (int)Math.round(cy), (int)Math.round(cz)))
if(!writer.isWithin((int)Math.round(cx), verticalRange != null ? (int)Math.round(cy) : 5, (int)Math.round(cz)))
{
break;
}

View File

@ -459,10 +459,15 @@ public class IrisObject extends IrisRegistrant {
int xx, zz;
int yrand = config.getTranslate().getYRandom();
yrand = yrand > 0 ? rng.i(0, yrand) : yrand < 0 ? rng.i(yrand, 0) : yrand;
boolean bail = false;
if (yv < 0) {
if (config.getMode().equals(ObjectPlaceMode.CENTER_HEIGHT)) {
y = (c != null ? c.getSurface() : placer.getHighest(x, z, getLoader(), config.isUnderwater())) + rty;
if(placer.isCarved(x, y, z) || placer.isCarved(x, y-1, z))
{
bail = true;
}
} else if (config.getMode().equals(ObjectPlaceMode.MAX_HEIGHT) || config.getMode().equals(ObjectPlaceMode.STILT)) {
BlockVector offset = new BlockVector(config.getTranslate().getX(), config.getTranslate().getY(), config.getTranslate().getZ());
BlockVector rotatedDimensions = config.getRotation().rotate(new BlockVector(getW(), getH(), getD()), spinx, spiny, spinz).clone();
@ -471,6 +476,12 @@ public class IrisObject extends IrisRegistrant {
for (int j = z - (rotatedDimensions.getBlockZ() / 2) + offset.getBlockZ(); j <= z + (rotatedDimensions.getBlockZ() / 2) + offset.getBlockZ(); j++) {
int h = placer.getHighest(i, j, getLoader(), config.isUnderwater()) + rty;
if(placer.isCarved(i, h, j))
{
bail = true;
break;
}
if (h > y) {
y = h;
}
@ -484,6 +495,12 @@ public class IrisObject extends IrisRegistrant {
for (int j = z - (rotatedDimensions.getBlockZ() / 2) + offset.getBlockZ(); j <= z + (rotatedDimensions.getBlockZ() / 2) + offset.getBlockZ(); j += (rotatedDimensions.getBlockZ() / 2) + 1) {
int h = placer.getHighest(i, j, getLoader(), config.isUnderwater()) + rty;
if(placer.isCarved(i, h, j))
{
bail = true;
break;
}
if (h > y) {
y = h;
}
@ -497,7 +514,11 @@ public class IrisObject extends IrisRegistrant {
for (int i = x - (rotatedDimensions.getBlockX() / 2) + offset.getBlockX(); i <= x + (rotatedDimensions.getBlockX() / 2) + offset.getBlockX(); i++) {
for (int j = z - (rotatedDimensions.getBlockZ() / 2) + offset.getBlockZ(); j <= z + (rotatedDimensions.getBlockZ() / 2) + offset.getBlockZ(); j++) {
int h = placer.getHighest(i, j, getLoader(), config.isUnderwater()) + rty;
if(placer.isCarved(i, h, j))
{
bail = true;
break;
}
if (h < y) {
y = h;
}
@ -511,7 +532,11 @@ public class IrisObject extends IrisRegistrant {
for (int i = x - (rotatedDimensions.getBlockX() / 2) + offset.getBlockX(); i <= x + (rotatedDimensions.getBlockX() / 2) + offset.getBlockX(); i += (rotatedDimensions.getBlockX() / 2) + 1) {
for (int j = z - (rotatedDimensions.getBlockZ() / 2) + offset.getBlockZ(); j <= z + (rotatedDimensions.getBlockZ() / 2) + offset.getBlockZ(); j += (rotatedDimensions.getBlockZ() / 2) + 1) {
int h = placer.getHighest(i, j, getLoader(), config.isUnderwater()) + rty;
if(placer.isCarved(i, h, j))
{
bail = true;
break;
}
if (h < y) {
y = h;
}
@ -519,13 +544,27 @@ public class IrisObject extends IrisRegistrant {
}
} else if (config.getMode().equals(ObjectPlaceMode.PAINT)) {
y = placer.getHighest(x, z, getLoader(), config.isUnderwater()) + rty;
if(placer.isCarved(x, y, z))
{
bail = true;
}
}
} else {
y = yv;
if(placer.isCarved(x, y, z))
{
bail = true;
}
}
if (yv >= 0 && config.isBottom()) {
y += Math.floorDiv(h, 2);
bail = placer.isCarved(x, y, z);
}
if(bail)
{
return -1;
}
if (yv < 0) {