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 spinz = rng.imax() / 1000;
int rty = config.getRotation().rotate(new BlockVector(0, getCenter().getBlockY(), 0), spinx, spiny, spinz).getBlockY(); 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 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()) if(yv >= 0 && config.isBottom())
{ {
@ -203,6 +309,19 @@ public class IrisObject extends IrisRegistrant
int yy = y + (int) Math.round(i.getY()); int yy = y + (int) Math.round(i.getY());
int zz = z + (int) Math.round(i.getZ()); 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) if(heightmap != null)
{ {
ChunkPosition pos = new ChunkPosition(xx, zz); ChunkPosition pos = new ChunkPosition(xx, zz);

View File

@ -25,6 +25,14 @@ public class IrisObjectPlacement
@Desc("List of objects to place") @Desc("List of objects to place")
private KList<String> place = new KList<>(); 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) @ArrayType(min = 1, type = IrisObjectReplace.class)
@DontObfuscate @DontObfuscate
@Desc("Find and replace blocks") @Desc("Find and replace blocks")
@ -77,7 +85,7 @@ public class IrisObjectPlacement
private boolean meld = false; private boolean meld = false;
@DontObfuscate @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; private boolean bottom = false;
@DontObfuscate @DontObfuscate

View File

@ -19,13 +19,18 @@ import lombok.EqualsAndHashCode;
@Desc("Represents a structure in iris.") @Desc("Represents a structure in iris.")
@Data @Data
@EqualsAndHashCode(callSuper = false) @EqualsAndHashCode(callSuper = false)
public class IrisStructure extends IrisRegistrant { public class IrisStructure extends IrisRegistrant
{
@MinNumber(2) @MinNumber(2)
@Required @Required
@DontObfuscate @DontObfuscate
@Desc("This is the human readable name for this structure. Such as Red Dungeon or Tropical Village.") @Desc("This is the human readable name for this structure. Such as Red Dungeon or Tropical Village.")
private String name = "A Structure Type"; private String name = "A Structure Type";
@DontObfuscate
@Desc("Wall style noise")
private IrisGeneratorStyle wallStyle = NoiseStyle.STATIC.style();
@Required @Required
@MinNumber(3) @MinNumber(3)
@MaxNumber(64) @MaxNumber(64)
@ -65,37 +70,48 @@ public class IrisStructure extends IrisRegistrant {
private transient AtomicCache<CNG> wallGenerator = new AtomicCache<>(); 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<>(); KList<StructureTileFace> walls = new KList<>();
boolean floor = isWall(rng, x, y, z, StructureTileFace.DOWN); boolean floor = isWall(rng, x, y, z, StructureTileFace.DOWN);
boolean ceiling = isWall(rng, x, y, z, StructureTileFace.UP); 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); walls.add(StructureTileFace.NORTH);
} }
if (isWall(rng, x, y, z, StructureTileFace.SOUTH)) { if(isWall(rng, x, y, z, StructureTileFace.SOUTH))
{
walls.add(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); walls.add(StructureTileFace.EAST);
} }
if (isWall(rng, x, y, z, StructureTileFace.WEST)) { if(isWall(rng, x, y, z, StructureTileFace.WEST))
{
walls.add(StructureTileFace.WEST); walls.add(StructureTileFace.WEST);
} }
int faces = walls.size() + (floor ? 1 : 0) + (ceiling ? +1 : 0);
int openings = 6 - faces;
int rt = 0; int rt = 0;
for (int cx = 0; cx < 4; cx++) { for(int cx = 0; cx < 4; cx++)
for (IrisStructureTile i : tiles) { {
if (i.likeAGlove(floor, ceiling, walls)) { for(IrisStructureTile i : tiles)
{
if(i.likeAGlove(floor, ceiling, walls, faces, openings))
{
return new TileResult(i, rt); return new TileResult(i, rt);
} }
} }
if (cx < 3) { if(cx < 3)
{
rotate(walls); rotate(walls);
rt += 90; rt += 90;
} }
@ -104,14 +120,18 @@ public class IrisStructure extends IrisRegistrant {
return null; return null;
} }
public void rotate(KList<StructureTileFace> faces) { public void rotate(KList<StructureTileFace> faces)
for (int i = 0; i < faces.size(); i++) { {
for(int i = 0; i < faces.size(); i++)
{
faces.set(i, faces.get(i).rotate90CW()); faces.set(i, faces.get(i).rotate90CW());
} }
} }
public boolean isWall(RNG rng, double x, double y, double z, StructureTileFace face) { public boolean isWall(RNG rng, double x, double y, double z, StructureTileFace face)
if ((face == StructureTileFace.DOWN || face == StructureTileFace.UP) && maxLayers == 1) { {
if((face == StructureTileFace.DOWN || face == StructureTileFace.UP) && maxLayers == 1)
{
return true; return true;
} }
@ -119,25 +139,30 @@ public class IrisStructure extends IrisRegistrant {
return (getWallGenerator(rng).fitDouble(0, 1, p.getX(), p.getY(), p.getZ()) < getWallChance()); 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); return (int) Math.floor(v / gridSize);
} }
public BlockPosition asTileHorizon(BlockPosition b, StructureTileFace face) { 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.setX((int) (Math.floor((b.getX() * 2) / (gridSize)) + face.x()));
b.setZ((int) (Math.floor((b.getZ() * 2) / gridSize) + face.z())); b.setY((int) (Math.floor((b.getY() * 2) / (gridHeight)) + face.y()));
b.setZ((int) (Math.floor((b.getZ() * 2) / (gridSize)) + face.z()));
return b; return b;
} }
public CNG getWallGenerator(RNG rng) { public CNG getWallGenerator(RNG rng)
return wallGenerator.aquire(() -> { {
return wallGenerator.aquire(() ->
{
RNG rngx = rng.nextParallelRNG((int) (name.hashCode() + gridHeight - gridSize + maxLayers + tiles.size())); 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.ParallaxChunkGenerator;
import com.volmit.iris.gen.atomics.AtomicCache; import com.volmit.iris.gen.atomics.AtomicCache;
import com.volmit.iris.noise.CellGenerator; import com.volmit.iris.noise.CellGenerator;
import com.volmit.iris.util.ChunkPosition;
import com.volmit.iris.util.Desc; import com.volmit.iris.util.Desc;
import com.volmit.iris.util.DontObfuscate; import com.volmit.iris.util.DontObfuscate;
import com.volmit.iris.util.KSet;
import com.volmit.iris.util.MaxNumber; import com.volmit.iris.util.MaxNumber;
import com.volmit.iris.util.MinNumber; import com.volmit.iris.util.MinNumber;
import com.volmit.iris.util.RNG; import com.volmit.iris.util.RNG;
@ -68,14 +70,34 @@ public class IrisStructurePlacement
try try
{ {
RNG rng = g.getMasterRandom().nextParallelRNG(-88738456); 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 s = gridSize(g) - (getStructure(g).isMergeEdges() ? 1 : 0);
int sh = gridHeight(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) if(getStructure(g).getMaxLayers() <= 1)
{ {
placeLayer(g, rng, rnp, i, 0, j, s, sh); 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); 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) if(t != null)
{ {
@ -120,7 +142,8 @@ public class IrisStructurePlacement
private IrisObjectPlacement getConfig() private IrisObjectPlacement getConfig()
{ {
return config.aquire(() -> { return config.aquire(() ->
{
IrisObjectPlacement p = new IrisObjectPlacement(); IrisObjectPlacement p = new IrisObjectPlacement();
p.setWaterloggable(false); p.setWaterloggable(false);
return p; return p;

View File

@ -1,5 +1,6 @@
package com.volmit.iris.object; package com.volmit.iris.object;
import com.volmit.iris.gen.atomics.AtomicCache;
import com.volmit.iris.util.ArrayType; import com.volmit.iris.util.ArrayType;
import com.volmit.iris.util.Desc; import com.volmit.iris.util.Desc;
import com.volmit.iris.util.DontObfuscate; import com.volmit.iris.util.DontObfuscate;
@ -53,6 +54,9 @@ public class IrisStructureTile
@Desc("List of objects to place centered in this tile") @Desc("List of objects to place centered in this tile")
private KList<String> objects = new KList<>(); private KList<String> objects = new KList<>();
private AtomicCache<Integer> minFaces = new AtomicCache<>();
private AtomicCache<Integer> maxFaces = new AtomicCache<>();
public IrisStructureTile() 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" : "-") + " |"; 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 //@builder
@ -77,17 +81,37 @@ public class IrisStructureTile
return false; return false;
} }
if(!fitsWalls(walls)) if(!fitsWalls(walls, faces, openings))
{ {
return false; return false;
} }
//@done //@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 //@builder
if((getNorth().required() && !walls.contains(StructureTileFace.NORTH)) 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)); rt.setYAxis(new IrisAxisRotationClamp(rot != 0, rot, rot, 0));
p.setRotation(rt); p.setRotation(rt);
p.setBottom(true); p.setBottom(true);
p.setMode(ObjectPlaceMode.PAINT);
placement = p; placement = p;
} }
} }