mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2025-07-19 02:36:59 +00:00
205 lines
5.2 KiB
Java
205 lines
5.2 KiB
Java
package com.volmit.iris.object;
|
|
|
|
import com.volmit.iris.Iris;
|
|
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;
|
|
import com.volmit.iris.util.RegistryListStructure;
|
|
import com.volmit.iris.util.Required;
|
|
|
|
import lombok.Data;
|
|
|
|
@Desc("Represents a structure placement")
|
|
@Data
|
|
public class IrisStructurePlacement
|
|
{
|
|
@RegistryListStructure
|
|
@Required
|
|
@DontObfuscate
|
|
@Desc("The structure tileset to use")
|
|
private String tileset = "";
|
|
|
|
@Required
|
|
@MinNumber(0.0001)
|
|
@DontObfuscate
|
|
@Desc("The structure chance zoom. Higher = bigger cells, further away")
|
|
private double zoom = 1D;
|
|
|
|
@MinNumber(-1)
|
|
@MaxNumber(1)
|
|
@DontObfuscate
|
|
@Desc("The ratio. Lower values means cells can get closer to other cells. Negative values means make veins of structures")
|
|
private double ratio = 0.25D;
|
|
|
|
@Required
|
|
@MinNumber(1)
|
|
@DontObfuscate
|
|
@Desc("The rarity for this structure")
|
|
private int rarity = 4;
|
|
|
|
@MinNumber(-1)
|
|
@MaxNumber(255)
|
|
@DontObfuscate
|
|
@Desc("The height or -1 for surface")
|
|
private int height = -1;
|
|
|
|
@MinNumber(0)
|
|
@DontObfuscate
|
|
@Desc("The chance cell shuffle (rougher edges)")
|
|
private double shuffle = 22;
|
|
|
|
private transient AtomicCache<CellGenerator> chanceCell = new AtomicCache<>();
|
|
private transient AtomicCache<IrisStructure> structure = new AtomicCache<>();
|
|
private transient AtomicCache<IrisObjectPlacement> config = new AtomicCache<>();
|
|
|
|
public IrisStructurePlacement()
|
|
{
|
|
|
|
}
|
|
|
|
public void place(ParallaxChunkGenerator g, RNG rngno, int cx, int cz)
|
|
{
|
|
try
|
|
{
|
|
RNG rng = g.getMasterRandom().nextParallelRNG(-88738456);
|
|
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 += 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);
|
|
continue;
|
|
}
|
|
|
|
for(int k = 0; k < s * getStructure(g).getMaxLayers(); k += Math.max(sh, 1))
|
|
{
|
|
placeLayer(g, rng, rnp, i, k, j, s, sh);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
catch(Throwable e)
|
|
{
|
|
e.printStackTrace();
|
|
}
|
|
}
|
|
|
|
public void placeLayer(ParallaxChunkGenerator g, RNG rng, RNG rnp, int i, int k, int j, int s, int sh)
|
|
{
|
|
if(!hasStructure(g, rng, i, k, j))
|
|
{
|
|
return;
|
|
}
|
|
|
|
int h = (height == -1 ? 0 : height) + (Math.floorDiv(k, sh) * sh);
|
|
TileResult t = getStructure(g).getTile(rng, Math.floorDiv(i, s) * s, h, Math.floorDiv(j, s) * s);
|
|
|
|
if(t != null)
|
|
{
|
|
IrisObject o = null;
|
|
|
|
for(IrisRareObject l : t.getTile().getRareObjects())
|
|
{
|
|
if(rnp.i(1, l.getRarity()) == 1)
|
|
{
|
|
o = load(g, l.getObject());
|
|
break;
|
|
}
|
|
}
|
|
|
|
o = o != null ? o : load(g, t.getTile().getObjects().get(rnp.nextInt(t.getTile().getObjects().size())));
|
|
o.place(Math.floorDiv(i, s) * s, height == -1 ? -1 : h, Math.floorDiv(j, s) * s, g, t.getPlacement(), rng, (gg) -> g.getParallaxChunk(gg.getChunkX(), gg.getChunkZ()).setStructure(gg.getY(), t.getStructure(), t.getTile()));
|
|
}
|
|
}
|
|
|
|
private IrisObjectPlacement getConfig()
|
|
{
|
|
return config.aquire(() ->
|
|
{
|
|
IrisObjectPlacement p = new IrisObjectPlacement();
|
|
p.setWaterloggable(false);
|
|
return p;
|
|
});
|
|
}
|
|
|
|
public IrisObject load(ContextualChunkGenerator g, String s)
|
|
{
|
|
return g.getData().getObjectLoader().load(s);
|
|
}
|
|
|
|
public int gridSize(ContextualChunkGenerator g)
|
|
{
|
|
return getStructure(g).getGridSize();
|
|
}
|
|
|
|
public int gridHeight(ContextualChunkGenerator g)
|
|
{
|
|
return getStructure(g).getGridHeight();
|
|
}
|
|
|
|
public IrisStructure getStructure(ContextualChunkGenerator g)
|
|
{
|
|
return structure.aquire(() -> (g == null ? Iris.globaldata : g.getData()).getStructureLoader().load(getTileset()));
|
|
}
|
|
|
|
public boolean hasStructure(ParallaxChunkGenerator g, RNG random, double x, double y, double z)
|
|
{
|
|
if(g.getGlCarve().isCarved((int) x, (int) y, (int) z))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if(getChanceGenerator(random).getIndex(x / zoom, y / zoom, z / zoom, getRarity()) == getRarity() / 2)
|
|
{
|
|
return ratio > 0 ? getChanceGenerator(random).getDistance(x / zoom, z / zoom) > ratio : getChanceGenerator(random).getDistance(x / zoom, z / zoom) < Math.abs(ratio);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public CellGenerator getChanceGenerator(RNG random)
|
|
{
|
|
return chanceCell.aquire(() ->
|
|
{
|
|
CellGenerator chanceCell = new CellGenerator(random.nextParallelRNG(-72346));
|
|
chanceCell.setCellScale(1D);
|
|
chanceCell.setShuffle(getShuffle());
|
|
return chanceCell;
|
|
});
|
|
}
|
|
}
|