This commit is contained in:
Daniel Mills 2020-08-20 01:48:27 -04:00
parent ec452125e2
commit bff242dc99
7 changed files with 261 additions and 34 deletions

View File

@ -134,7 +134,113 @@ public class IrisObject extends IrisRegistrant
int spinz = rng.imax() / 1000;
int rty = config.getRotation().rotate(new BlockVector(0, getCenter().getBlockY(), 0), spinx, spiny, spinz).getBlockY();
int ty = config.getTranslate().translate(new BlockVector(0, getCenter().getBlockY(), 0), config.getRotation(), spinx, spiny, spinz).getBlockY();
int y = yv < 0 ? placer.getHighest(x, z, config.isUnderwater()) + rty : yv;
int y = -1;
KMap<ChunkPosition, Integer> paintmap = null;
if(yv < 0)
{
if(config.getMode().equals(ObjectPlaceMode.CENTER_HEIGHT_RIGID))
{
if(config.isTranslateCenter())
{
y = placer.getHighest(x, z, config.isUnderwater()) + rty;
}
else
{
y = placer.getHighest(x, z, config.isUnderwater()) + rty;
}
}
if(config.getMode().equals(ObjectPlaceMode.MAX_HEIGHT_RIGID_ACCURATE))
{
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();
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, config.isUnderwater()) + rty;
if(h > y)
{
y = h;
}
}
}
}
else if(config.getMode().equals(ObjectPlaceMode.MAX_HEIGHT_RIGID))
{
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();
for(int i = x - (rotatedDimensions.getBlockX() / 2) + offset.getBlockX(); i <= x + (rotatedDimensions.getBlockX() / 2) + offset.getBlockX(); i += (rotatedDimensions.getBlockX() / 2))
{
for(int j = z - (rotatedDimensions.getBlockZ() / 2) + offset.getBlockZ(); j <= z + (rotatedDimensions.getBlockZ() / 2) + offset.getBlockZ(); j += (rotatedDimensions.getBlockZ() / 2))
{
int h = placer.getHighest(i, j, config.isUnderwater()) + rty;
if(h > y)
{
y = h;
}
}
}
}
else if(config.getMode().equals(ObjectPlaceMode.MIN_HEIGHT_RIGID_ACCURATE))
{
y = 257;
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();
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, config.isUnderwater()) + rty;
if(h < y)
{
y = h;
}
}
}
}
else if(config.getMode().equals(ObjectPlaceMode.MIN_HEIGHT_RIGID))
{
y = 257;
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();
for(int i = x - (rotatedDimensions.getBlockX() / 2) + offset.getBlockX(); i <= x + (rotatedDimensions.getBlockX() / 2) + offset.getBlockX(); i += (rotatedDimensions.getBlockX() / 2))
{
for(int j = z - (rotatedDimensions.getBlockZ() / 2) + offset.getBlockZ(); j <= z + (rotatedDimensions.getBlockZ() / 2) + offset.getBlockZ(); j += (rotatedDimensions.getBlockZ() / 2))
{
int h = placer.getHighest(i, j, config.isUnderwater()) + rty;
if(h < y)
{
y = h;
}
}
}
}
else if(config.getMode().equals(ObjectPlaceMode.PAINT) || config.getMode().equals(ObjectPlaceMode.STILT))
{
y = placer.getHighest(x, z, config.isUnderwater()) + rty;
paintmap = new KMap<>();
}
}
else
{
y = yv;
}
if(yv >= 0 && config.isBottom())
{
@ -203,6 +309,19 @@ public class IrisObject extends IrisRegistrant
int yy = y + (int) Math.round(i.getY());
int zz = z + (int) Math.round(i.getZ());
if(config.getMode().equals(ObjectPlaceMode.PAINT))
{
yy = (int) Math.round(i.getY()) + Math.floorDiv(h, 2) + paintmap.compute(new ChunkPosition(xx, zz), (k, v) ->
{
if(k == null || v == null)
{
return placer.getHighest(xx, zz, config.isUnderwater());
}
return v;
});
}
if(heightmap != null)
{
ChunkPosition pos = new ChunkPosition(xx, zz);

View File

@ -25,6 +25,14 @@ public class IrisObjectPlacement
@Desc("List of objects to place")
private KList<String> place = new KList<>();
@DontObfuscate
@Desc("If the place mode is set to CENTER_HEIGHT_RIGID and you have an X/Z translation, Turning on translate center will also translate the center height check.")
private boolean translateCenter = false;
@DontObfuscate
@Desc("The placement mode")
private ObjectPlaceMode mode = ObjectPlaceMode.CENTER_HEIGHT_RIGID;
@ArrayType(min = 1, type = IrisObjectReplace.class)
@DontObfuscate
@Desc("Find and replace blocks")
@ -77,7 +85,7 @@ public class IrisObjectPlacement
private boolean meld = false;
@DontObfuscate
@Desc("If set to true, this object will place from the ground up instead of height checks when not y locked to the surface.")
@Desc("If set to true, this object will place from the ground up instead of height checks when not y locked to the surface. This is not compatable with X and Z axis rotations (it may look off)")
private boolean bottom = false;
@DontObfuscate

View File

@ -19,13 +19,18 @@ import lombok.EqualsAndHashCode;
@Desc("Represents a structure in iris.")
@Data
@EqualsAndHashCode(callSuper = false)
public class IrisStructure extends IrisRegistrant {
public class IrisStructure extends IrisRegistrant
{
@MinNumber(2)
@Required
@DontObfuscate
@Desc("This is the human readable name for this structure. Such as Red Dungeon or Tropical Village.")
private String name = "A Structure Type";
@DontObfuscate
@Desc("Wall style noise")
private IrisGeneratorStyle wallStyle = NoiseStyle.STATIC.style();
@Required
@MinNumber(3)
@MaxNumber(64)
@ -65,37 +70,48 @@ public class IrisStructure extends IrisRegistrant {
private transient AtomicCache<CNG> wallGenerator = new AtomicCache<>();
public TileResult getTile(RNG rng, double x, double y, double z) {
public TileResult getTile(RNG rng, double x, double y, double z)
{
KList<StructureTileFace> walls = new KList<>();
boolean floor = isWall(rng, x, y, z, StructureTileFace.DOWN);
boolean ceiling = isWall(rng, x, y, z, StructureTileFace.UP);
if (isWall(rng, x, y, z, StructureTileFace.NORTH)) {
if(isWall(rng, x, y, z, StructureTileFace.NORTH))
{
walls.add(StructureTileFace.NORTH);
}
if (isWall(rng, x, y, z, StructureTileFace.SOUTH)) {
if(isWall(rng, x, y, z, StructureTileFace.SOUTH))
{
walls.add(StructureTileFace.SOUTH);
}
if (isWall(rng, x, y, z, StructureTileFace.EAST)) {
if(isWall(rng, x, y, z, StructureTileFace.EAST))
{
walls.add(StructureTileFace.EAST);
}
if (isWall(rng, x, y, z, StructureTileFace.WEST)) {
if(isWall(rng, x, y, z, StructureTileFace.WEST))
{
walls.add(StructureTileFace.WEST);
}
int faces = walls.size() + (floor ? 1 : 0) + (ceiling ? +1 : 0);
int openings = 6 - faces;
int rt = 0;
for (int cx = 0; cx < 4; cx++) {
for (IrisStructureTile i : tiles) {
if (i.likeAGlove(floor, ceiling, walls)) {
for(int cx = 0; cx < 4; cx++)
{
for(IrisStructureTile i : tiles)
{
if(i.likeAGlove(floor, ceiling, walls, faces, openings))
{
return new TileResult(i, rt);
}
}
if (cx < 3) {
if(cx < 3)
{
rotate(walls);
rt += 90;
}
@ -104,14 +120,18 @@ public class IrisStructure extends IrisRegistrant {
return null;
}
public void rotate(KList<StructureTileFace> faces) {
for (int i = 0; i < faces.size(); i++) {
public void rotate(KList<StructureTileFace> faces)
{
for(int i = 0; i < faces.size(); i++)
{
faces.set(i, faces.get(i).rotate90CW());
}
}
public boolean isWall(RNG rng, double x, double y, double z, StructureTileFace face) {
if ((face == StructureTileFace.DOWN || face == StructureTileFace.UP) && maxLayers == 1) {
public boolean isWall(RNG rng, double x, double y, double z, StructureTileFace face)
{
if((face == StructureTileFace.DOWN || face == StructureTileFace.UP) && maxLayers == 1)
{
return true;
}
@ -119,25 +139,30 @@ public class IrisStructure extends IrisRegistrant {
return (getWallGenerator(rng).fitDouble(0, 1, p.getX(), p.getY(), p.getZ()) < getWallChance());
}
public int getTileHorizon(double v) {
public int getTileHorizon(double v)
{
return (int) Math.floor(v / gridSize);
}
public BlockPosition asTileHorizon(BlockPosition b, StructureTileFace face) {
b.setX((int) (Math.floor((b.getX() * 2) / gridSize) + face.x()));
b.setY((int) (Math.floor((b.getY() * 2) / gridHeight) + face.y()));
b.setZ((int) (Math.floor((b.getZ() * 2) / gridSize) + face.z()));
public BlockPosition asTileHorizon(BlockPosition b, StructureTileFace face)
{
b.setX((int) (Math.floor((b.getX() * 2) / (gridSize)) + face.x()));
b.setY((int) (Math.floor((b.getY() * 2) / (gridHeight)) + face.y()));
b.setZ((int) (Math.floor((b.getZ() * 2) / (gridSize)) + face.z()));
return b;
}
public CNG getWallGenerator(RNG rng) {
return wallGenerator.aquire(() -> {
public CNG getWallGenerator(RNG rng)
{
return wallGenerator.aquire(() ->
{
RNG rngx = rng.nextParallelRNG((int) (name.hashCode() + gridHeight - gridSize + maxLayers + tiles.size()));
return CNG.signature(rngx).scale(0.8);
return wallStyle.create(rngx).scale(0.8);
});
}
public IrisStructure() {
public IrisStructure()
{
}
}

View File

@ -5,8 +5,10 @@ import com.volmit.iris.gen.ContextualChunkGenerator;
import com.volmit.iris.gen.ParallaxChunkGenerator;
import com.volmit.iris.gen.atomics.AtomicCache;
import com.volmit.iris.noise.CellGenerator;
import com.volmit.iris.util.ChunkPosition;
import com.volmit.iris.util.Desc;
import com.volmit.iris.util.DontObfuscate;
import com.volmit.iris.util.KSet;
import com.volmit.iris.util.MaxNumber;
import com.volmit.iris.util.MinNumber;
import com.volmit.iris.util.RNG;
@ -68,14 +70,34 @@ public class IrisStructurePlacement
try
{
RNG rng = g.getMasterRandom().nextParallelRNG(-88738456);
RNG rnp = rng.nextParallelRNG(cx - (cz * cz));
RNG rnp = rng.nextParallelRNG(cx - (cz * cz << 3));
int s = gridSize(g) - (getStructure(g).isMergeEdges() ? 1 : 0);
int sh = gridHeight(g) - (getStructure(g).isMergeEdges() ? 1 : 0);
KSet<ChunkPosition> m = new KSet<>();
for(int i = cx << 4; i < (cx << 4) + 15; i += Math.max(s, 1))
for(int i = cx << 4; i <= (cx << 4) + 15; i += 1)
{
for(int j = cz << 4; j < (cz << 4) + 15; j += Math.max(s, 1))
if(Math.floorDiv(i, s) * s >> 4 < cx)
{
continue;
}
for(int j = cz << 4; j <= (cz << 4) + 15; j += 1)
{
if(Math.floorDiv(j, s) * s >> 4 < cz)
{
continue;
}
ChunkPosition p = new ChunkPosition(Math.floorDiv(i, s) * s, Math.floorDiv(j, s) * s);
if(m.contains(p))
{
continue;
}
m.add(p);
if(getStructure(g).getMaxLayers() <= 1)
{
placeLayer(g, rng, rnp, i, 0, j, s, sh);
@ -104,7 +126,7 @@ public class IrisStructurePlacement
}
int h = (height == -1 ? 0 : height) + (Math.floorDiv(k, sh) * sh);
TileResult t = getStructure(g).getTile(rng, i, h, j);
TileResult t = getStructure(g).getTile(rng, Math.floorDiv(i, s) * s, h, Math.floorDiv(j, s) * s);
if(t != null)
{
@ -120,7 +142,8 @@ public class IrisStructurePlacement
private IrisObjectPlacement getConfig()
{
return config.aquire(() -> {
return config.aquire(() ->
{
IrisObjectPlacement p = new IrisObjectPlacement();
p.setWaterloggable(false);
return p;

View File

@ -1,5 +1,6 @@
package com.volmit.iris.object;
import com.volmit.iris.gen.atomics.AtomicCache;
import com.volmit.iris.util.ArrayType;
import com.volmit.iris.util.Desc;
import com.volmit.iris.util.DontObfuscate;
@ -53,6 +54,9 @@ public class IrisStructureTile
@Desc("List of objects to place centered in this tile")
private KList<String> objects = new KList<>();
private AtomicCache<Integer> minFaces = new AtomicCache<>();
private AtomicCache<Integer> maxFaces = new AtomicCache<>();
public IrisStructureTile()
{
@ -63,7 +67,7 @@ public class IrisStructureTile
return (ceiling.required() ? "C" : "") + (floor.required() ? "F" : "") + "| " + (north.required() ? "X" : "-") + (south.required() ? "X" : "-") + (east.required() ? "X" : "-") + (west.required() ? "X" : "-") + " |";
}
public boolean likeAGlove(boolean floor, boolean ceiling, KList<StructureTileFace> walls)
public boolean likeAGlove(boolean floor, boolean ceiling, KList<StructureTileFace> walls, int faces, int openings)
{
//@builder
@ -77,17 +81,37 @@ public class IrisStructureTile
return false;
}
if(!fitsWalls(walls))
if(!fitsWalls(walls, faces, openings))
{
return false;
}
//@done
return true;
return faces >= minFaces.aquire(() ->
{
int m = 0;
m += this.ceiling.required() ? 1 : 0;
m += this.floor.required() ? 1 : 0;
m += this.north.required() ? 1 : 0;
m += this.south.required() ? 1 : 0;
m += this.east.required() ? 1 : 0;
m += this.west.required() ? 1 : 0;
return m;
}) && faces <= maxFaces.aquire(() ->
{
int m = 0;
m += this.ceiling.supported() ? 1 : 0;
m += this.floor.supported() ? 1 : 0;
m += this.north.supported() ? 1 : 0;
m += this.south.supported() ? 1 : 0;
m += this.east.supported() ? 1 : 0;
m += this.west.supported() ? 1 : 0;
return m;
});
}
private boolean fitsWalls(KList<StructureTileFace> walls)
private boolean fitsWalls(KList<StructureTileFace> walls, int faces, int openings)
{
//@builder
if((getNorth().required() && !walls.contains(StructureTileFace.NORTH))

View File

@ -0,0 +1,27 @@
package com.volmit.iris.object;
import com.volmit.iris.util.DontObfuscate;
public enum ObjectPlaceMode
{
@DontObfuscate
CENTER_HEIGHT_RIGID,
@DontObfuscate
MAX_HEIGHT_RIGID_ACCURATE,
@DontObfuscate
MAX_HEIGHT_RIGID,
@DontObfuscate
MIN_HEIGHT_RIGID_ACCURATE,
@DontObfuscate
MIN_HEIGHT_RIGID,
@DontObfuscate
PAINT,
@DontObfuscate
STILT;
}

View File

@ -16,6 +16,7 @@ public class TileResult
rt.setYAxis(new IrisAxisRotationClamp(rot != 0, rot, rot, 0));
p.setRotation(rt);
p.setBottom(true);
p.setMode(ObjectPlaceMode.PAINT);
placement = p;
}
}