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

Eradicate the old structure system

This commit is contained in:
Daniel Mills
2021-01-12 06:05:37 -05:00
parent 93508d7514
commit dd7a8bae16
32 changed files with 3 additions and 2574 deletions

View File

@@ -1,196 +0,0 @@
package com.volmit.iris.object;
import com.volmit.iris.scaffold.cache.AtomicCache;
import com.volmit.iris.generator.noise.CNG;
import com.volmit.iris.util.ArrayType;
import com.volmit.iris.util.BlockPosition;
import com.volmit.iris.util.Desc;
import com.volmit.iris.util.DontObfuscate;
import com.volmit.iris.util.KList;
import com.volmit.iris.util.MaxNumber;
import com.volmit.iris.util.MinNumber;
import com.volmit.iris.util.RNG;
import com.volmit.iris.util.Required;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
@Accessors(chain = true)
@NoArgsConstructor
@AllArgsConstructor
@DontObfuscate
@Desc("Represents a structure in iris.")
@Data
@EqualsAndHashCode(callSuper = false)
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("Entity spawns to override or add to this structure")
@ArrayType(min = 1, type = IrisEntitySpawnOverride.class)
private KList<IrisEntitySpawnOverride> entitySpawnOverrides = new KList<>();
@DontObfuscate
@Desc("Entity spawns during generation")
@ArrayType(min = 1, type = IrisEntityInitialSpawn.class)
private KList<IrisEntityInitialSpawn> entityInitialSpawns = new KList<>();
@DontObfuscate
@Desc("Wall style noise")
private IrisGeneratorStyle wallStyle = NoiseStyle.STATIC.style();
@Desc("Setting underwater to true will waterlog blocks")
@DontObfuscate
private boolean underwater = false;
@Desc("The max & min height any part of this structure can place at")
@DontObfuscate
private IrisObjectLimit clamp = new IrisObjectLimit();
@Desc("Setting bore to true will dig out blocks before placing tiles")
@DontObfuscate
private boolean bore = false;
@Required
@MinNumber(3)
@MaxNumber(64)
@DontObfuscate
@Desc("This is the x and z size of each grid cell")
private int gridSize = 11;
@DontObfuscate
@Desc("Reference loot tables in this area")
private IrisLootReference loot = new IrisLootReference();
@Required
@MinNumber(1)
@MaxNumber(255)
@DontObfuscate
@Desc("This is the y size of each grid cell")
private int gridHeight = 5;
@MinNumber(1)
@MaxNumber(82)
@DontObfuscate
@Desc("This is the maximum layers iris will generate for (height cells)")
private int maxLayers = 1;
@Required
@MinNumber(0)
@MaxNumber(1)
@DontObfuscate
@Desc("This is the wall chance. Higher values makes more rooms and less open halls")
private double wallChance = 0.25;
@DontObfuscate
@Desc("Edges of tiles replace each other instead of having their own.")
private boolean mergeEdges = false;
@Required
@ArrayType(min = 1, type = IrisStructureTile.class)
@DontObfuscate
@Desc("The tiles")
private KList<IrisStructureTile> tiles = new KList<>();
private final transient AtomicCache<CNG> wallGenerator = new AtomicCache<>();
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))
{
walls.add(StructureTileFace.NORTH);
}
if(isWall(rng, x, y, z, StructureTileFace.SOUTH))
{
walls.add(StructureTileFace.SOUTH);
}
if(isWall(rng, x, y, z, StructureTileFace.EAST))
{
walls.add(StructureTileFace.EAST);
}
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, faces, openings))
{
return new TileResult(this, i, rt);
}
}
if(cx < 3)
{
rotate(walls);
rt += 90;
}
}
return null;
}
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)
{
return true;
}
BlockPosition p = asTileHorizon(new BlockPosition((int) x, (int) y, (int) z), face);
return (getWallGenerator(rng).fitDouble(0, 1, p.getX(), p.getY(), p.getZ()) < getWallChance());
}
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()));
return b;
}
public CNG getWallGenerator(RNG rng)
{
return wallGenerator.aquire(() ->
{
RNG rngx = new RNG(228385999).nextParallelRNG((int) (name.hashCode() + gridHeight - gridSize + maxLayers + tiles.size()));
return wallStyle.create(rngx).scale(0.8);
});
}
}

View File

@@ -1,99 +0,0 @@
package com.volmit.iris.object;
import com.volmit.iris.scaffold.cache.AtomicCache;
import com.volmit.iris.generator.noise.CellGenerator;
import com.volmit.iris.scaffold.data.DataProvider;
import com.volmit.iris.util.*;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
@Accessors(chain = true)
@NoArgsConstructor
@AllArgsConstructor
@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 final transient AtomicCache<CellGenerator> chanceCell = new AtomicCache<>();
private final transient AtomicCache<IrisStructure> structure = new AtomicCache<>();
private final transient AtomicCache<IrisObjectPlacement> config = new AtomicCache<>();
private IrisObjectPlacement getConfig()
{
return config.aquire(() ->
{
IrisObjectPlacement p = new IrisObjectPlacement();
p.setWaterloggable(false);
return p;
});
}
public IrisObject load(DataProvider g, String s)
{
return g.getData().getObjectLoader().load(s);
}
public int gridSize(DataProvider g)
{
return getStructure(g).getGridSize();
}
public int gridHeight(DataProvider g)
{
return getStructure(g).getGridHeight();
}
public IrisStructure getStructure(DataProvider g)
{
return structure.aquire(() -> g.getData().getStructureLoader().load(getTileset()));
}
public CellGenerator getChanceGenerator(RNG g)
{
return chanceCell.aquire(() ->
{
CellGenerator chanceCell = new CellGenerator(g.nextParallelRNG(-72346).nextParallelRNG((height + 10000) * rarity));
chanceCell.setCellScale(1D);
chanceCell.setShuffle(getShuffle());
return chanceCell;
});
}
}

View File

@@ -1,169 +0,0 @@
package com.volmit.iris.object;
import java.util.Objects;
import com.volmit.iris.scaffold.cache.AtomicCache;
import com.volmit.iris.util.ArrayType;
import com.volmit.iris.util.Desc;
import com.volmit.iris.util.DontObfuscate;
import com.volmit.iris.util.KList;
import com.volmit.iris.util.KMap;
import com.volmit.iris.util.RegistryListObject;
import com.volmit.iris.util.Required;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
@Accessors(chain = true)
@NoArgsConstructor
@AllArgsConstructor
@DontObfuscate
@Desc("Represents a structure tile")
@Data
@EqualsAndHashCode(callSuper = false)
public class IrisStructureTile
{
@DontObfuscate
@Desc("Reference loot tables in this area")
private IrisLootReference loot = new IrisLootReference();
@DontObfuscate
@Desc("Entity spawns to override or add to this structure tile")
@ArrayType(min = 1, type = IrisEntitySpawnOverride.class)
private KList<IrisEntitySpawnOverride> entitySpawnOverrides = new KList<>();
@DontObfuscate
@Desc("Entity spawns during generation")
@ArrayType(min = 1, type = IrisEntityInitialSpawn.class)
private KList<IrisEntityInitialSpawn> entityInitialSpawns = new KList<>();
@DontObfuscate
@Desc("The place mode for this tile")
private ObjectPlaceMode placeMode = ObjectPlaceMode.CENTER_HEIGHT;
@Required
@DontObfuscate
@Desc("Is this structure allowed to place if there is supposed to be a ceiling?")
private StructureTileCondition ceiling = StructureTileCondition.AGNOSTIC;
@Required
@DontObfuscate
@Desc("Is this structure allowed to place if there is supposed to be a floor?")
private StructureTileCondition floor = StructureTileCondition.REQUIRED;
@Required
@DontObfuscate
@Desc("Is this structure allowed to place if there is supposed to be a north wall?")
private StructureTileCondition north = StructureTileCondition.AGNOSTIC;
@Required
@DontObfuscate
@Desc("Is this structure allowed to place if there is supposed to be a south wall?")
private StructureTileCondition south = StructureTileCondition.AGNOSTIC;
@Required
@DontObfuscate
@Desc("Is this structure allowed to place if there is supposed to be a east wall?")
private StructureTileCondition east = StructureTileCondition.AGNOSTIC;
@Required
@DontObfuscate
@Desc("Is this structure allowed to place if there is supposed to be a west wall?")
private StructureTileCondition west = StructureTileCondition.AGNOSTIC;
@RegistryListObject
@Required
@ArrayType(min = 1, type = String.class)
@DontObfuscate
@Desc("List of objects to place centered in this tile")
private KList<String> objects = new KList<>();
@DontObfuscate
@Desc("If set to true, Iris will try to fill the insides of 'rooms' and 'pockets' where air should fit based off of raytrace checks. This prevents a village house placing in an area where a tree already exists, and instead replaces the parts of the tree where the interior of the structure is. \n\nThis operation does not affect warmed-up generation speed however it does slow down loading objects.")
private boolean smartBore = false;
@RegistryListObject
@ArrayType(min = 1, type = IrisRareObject.class)
@DontObfuscate
@Desc("List of objects to place centered in this tile but with rarity. These items only place some of the time so specify objects for common stuff too.")
private KList<IrisRareObject> rareObjects = new KList<>();
private final transient KMap<Integer, IrisObject> forceObjects = new KMap<>();
private final transient AtomicCache<Integer> minFaces = new AtomicCache<>();
private final transient AtomicCache<Integer> maxFaces = new AtomicCache<>();
public int hashFace()
{
return Objects.hash(ceiling, floor, south, north, east, west);
}
public String toString()
{
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, int faces, int openings)
{
// @NoArgsConstructor
if((getFloor().required() && !floor) || (getCeiling().required() && !ceiling))
{
return false;
}
if((!getFloor().supported() && floor) || (!getCeiling().supported() && ceiling))
{
return false;
}
if(!fitsWalls(walls, faces, openings))
{
return false;
}
//@done
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, int faces, int openings)
{
// @NoArgsConstructor
if((getNorth().required() && !walls.contains(StructureTileFace.NORTH)) || (getSouth().required() && !walls.contains(StructureTileFace.SOUTH)) || (getEast().required() && !walls.contains(StructureTileFace.EAST)) || (getWest().required() && !walls.contains(StructureTileFace.WEST)))
{
return false;
}
if((!getNorth().supported() && walls.contains(StructureTileFace.NORTH)) || (!getSouth().supported() && walls.contains(StructureTileFace.SOUTH)) || (!getEast().supported() && walls.contains(StructureTileFace.EAST)) || (!getWest().supported() && walls.contains(StructureTileFace.WEST)))
{
return false;
}
//@done
return true;
}
}

View File

@@ -1,30 +0,0 @@
package com.volmit.iris.object;
import com.volmit.iris.util.Desc;
import com.volmit.iris.util.DontObfuscate;
@Desc("A structure tile condition is for a specific wall if a tile is allowed to place if a wall exists.")
public enum StructureTileCondition
{
@Desc("This face REQUIRES a wall for this tile to place here")
@DontObfuscate
REQUIRED,
@Desc("This face DOESNT CARE if a wall is here for this tile to place here")
@DontObfuscate
AGNOSTIC,
@Desc("This face CANNOT HAVE a wall for this tile to place here")
@DontObfuscate
NEVER;
public boolean supported()
{
return !this.equals(NEVER);
}
public boolean required()
{
return this.equals(REQUIRED);
}
}

View File

@@ -1,43 +0,0 @@
package com.volmit.iris.object;
public enum StructureTileFace
{
UP,
DOWN,
NORTH,
SOUTH,
EAST,
WEST;
public int x()
{
return this.equals(EAST) ? 1 : this.equals(WEST) ? -1 : 0;
}
public int y()
{
return this.equals(UP) ? 1 : this.equals(DOWN) ? -1 : 0;
}
public int z()
{
return this.equals(SOUTH) ? 1 : this.equals(NORTH) ? -1 : 0;
}
public StructureTileFace rotate90CW()
{
switch(this)
{
case EAST:
return SOUTH;
case NORTH:
return EAST;
case SOUTH:
return WEST;
case WEST:
return NORTH;
default:
return this;
}
}
}

View File

@@ -1,32 +0,0 @@
package com.volmit.iris.object;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class TileResult
{
private IrisStructure structure;
private IrisStructureTile tile;
private IrisObjectPlacement placement;
public TileResult(IrisStructure structure, IrisStructureTile tile, int rot)
{
this.structure = structure;
this.tile = tile;
IrisObjectPlacement p = new IrisObjectPlacement();
IrisObjectRotation rt = new IrisObjectRotation();
rt.setYAxis(new IrisAxisRotationClamp(rot != 0, false, rot, rot, 0));
p.setRotation(rt);
p.setBottom(true);
p.setBore(structure.isBore());
p.setClamp(structure.getClamp());
p.setSmartBore(tile.isSmartBore());
p.setWaterloggable(structure.isUnderwater());
p.setMode(tile.getPlaceMode());
placement = p;
}
}