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

Bugfixes for generation

This commit is contained in:
Daniel Mills
2020-12-20 21:04:11 -05:00
parent 70ae1cce4b
commit 1cf60544e1
11 changed files with 721 additions and 284 deletions

View File

@@ -0,0 +1,532 @@
package com.volmit.iris.object;
import com.volmit.iris.util.Cuboid.CuboidDirection;
import com.volmit.iris.util.*;
import org.bukkit.Axis;
import org.bukkit.block.BlockFace;
import org.bukkit.util.Vector;
/**
* Directions
*
* @author cyberpwn
*/
public enum IrisDirection
{
UP_POSITIVE_Y(0, 1, 0, CuboidDirection.Up),
DOWN_NEGATIVE_Y(0, -1, 0, CuboidDirection.Down),
NORTH_NEGATIVE_Z(0, 0, -1, CuboidDirection.North),
SOUTH_POSITIVE_Z(0, 0, 1, CuboidDirection.South),
EAST_POSITIVE_X(1, 0, 0, CuboidDirection.East),
WEST_NEGATIVE_X(-1, 0, 0, CuboidDirection.West);
private static KMap<GBiset<IrisDirection, IrisDirection>, DOP> permute = null;
private int x;
private int y;
private int z;
private CuboidDirection f;
public static IrisDirection getDirection(BlockFace f)
{
switch(f)
{
case DOWN:
return DOWN_NEGATIVE_Y;
case EAST:
return EAST_POSITIVE_X;
case EAST_NORTH_EAST:
return EAST_POSITIVE_X;
case EAST_SOUTH_EAST:
return EAST_POSITIVE_X;
case NORTH:
return NORTH_NEGATIVE_Z;
case NORTH_EAST:
return NORTH_NEGATIVE_Z;
case NORTH_NORTH_EAST:
return NORTH_NEGATIVE_Z;
case NORTH_NORTH_WEST:
return NORTH_NEGATIVE_Z;
case NORTH_WEST:
return NORTH_NEGATIVE_Z;
case SELF:
return UP_POSITIVE_Y;
case SOUTH:
return SOUTH_POSITIVE_Z;
case SOUTH_EAST:
return SOUTH_POSITIVE_Z;
case SOUTH_SOUTH_EAST:
return SOUTH_POSITIVE_Z;
case SOUTH_SOUTH_WEST:
return SOUTH_POSITIVE_Z;
case SOUTH_WEST:
return SOUTH_POSITIVE_Z;
case UP:
return UP_POSITIVE_Y;
case WEST:
return WEST_NEGATIVE_X;
case WEST_NORTH_WEST:
return WEST_NEGATIVE_X;
case WEST_SOUTH_WEST:
return WEST_NEGATIVE_X;
}
return DOWN_NEGATIVE_Y;
}
@Override
public String toString()
{
switch(this)
{
case DOWN_NEGATIVE_Y:
return "Down";
case EAST_POSITIVE_X:
return "East";
case NORTH_NEGATIVE_Z:
return "North";
case SOUTH_POSITIVE_Z:
return "South";
case UP_POSITIVE_Y:
return "Up";
case WEST_NEGATIVE_X:
return "West";
}
return "?";
}
public boolean isVertical()
{
return equals(DOWN_NEGATIVE_Y) || equals(UP_POSITIVE_Y);
}
public static IrisDirection closest(Vector v)
{
double m = Double.MAX_VALUE;
IrisDirection s = null;
for(IrisDirection i : values())
{
Vector x = i.toVector();
double g = x.dot(v);
if(g < m)
{
m = g;
s = i;
}
}
return s;
}
public static IrisDirection closest(Vector v, IrisDirection... d)
{
double m = Double.MAX_VALUE;
IrisDirection s = null;
for(IrisDirection i : d)
{
Vector x = i.toVector();
double g = x.distance(v);
if(g < m)
{
m = g;
s = i;
}
}
return s;
}
public static IrisDirection closest(Vector v, KList<IrisDirection> d)
{
double m = Double.MAX_VALUE;
IrisDirection s = null;
for(IrisDirection i : d)
{
Vector x = i.toVector();
double g = x.distance(v);
if(g < m)
{
m = g;
s = i;
}
}
return s;
}
public Vector toVector()
{
return new Vector(x, y, z);
}
public boolean isCrooked(IrisDirection to)
{
if(equals(to.reverse()))
{
return false;
}
if(equals(to))
{
return false;
}
return true;
}
private IrisDirection(int x, int y, int z, CuboidDirection f)
{
this.x = x;
this.y = y;
this.z = z;
this.f = f;
}
public Vector angle(Vector initial, IrisDirection d)
{
calculatePermutations();
for(GBiset<IrisDirection, IrisDirection> i : permute.keySet())
{
if(i.getA().equals(this) && i.getB().equals(d))
{
return permute.get(i).op(initial);
}
}
return initial;
}
public IrisDirection reverse()
{
switch(this)
{
case DOWN_NEGATIVE_Y:
return UP_POSITIVE_Y;
case EAST_POSITIVE_X:
return WEST_NEGATIVE_X;
case NORTH_NEGATIVE_Z:
return SOUTH_POSITIVE_Z;
case SOUTH_POSITIVE_Z:
return NORTH_NEGATIVE_Z;
case UP_POSITIVE_Y:
return DOWN_NEGATIVE_Y;
case WEST_NEGATIVE_X:
return EAST_POSITIVE_X;
default:
break;
}
return null;
}
public int x()
{
return x;
}
public int y()
{
return y;
}
public int z()
{
return z;
}
public CuboidDirection f()
{
return f;
}
public static KList<IrisDirection> news()
{
return new KList<IrisDirection>().add(NORTH_NEGATIVE_Z, EAST_POSITIVE_X, WEST_NEGATIVE_X, SOUTH_POSITIVE_Z);
}
public static IrisDirection getDirection(Vector v)
{
Vector k = VectorMath.triNormalize(v.clone().normalize());
for(IrisDirection i : udnews())
{
if(i.x == k.getBlockX() && i.y == k.getBlockY() && i.z == k.getBlockZ())
{
return i;
}
}
return IrisDirection.NORTH_NEGATIVE_Z;
}
public static KList<IrisDirection> udnews()
{
return new KList<IrisDirection>().add(UP_POSITIVE_Y, DOWN_NEGATIVE_Y, NORTH_NEGATIVE_Z, EAST_POSITIVE_X, WEST_NEGATIVE_X, SOUTH_POSITIVE_Z);
}
/**
* Get the directional value from the given byte from common directional blocks
* (MUST BE BETWEEN 0 and 5 INCLUSIVE)
*
* @param b
* the byte
* @return the direction or null if the byte is outside of the inclusive range
* 0-5
*/
public static IrisDirection fromByte(byte b)
{
if(b > 5 || b < 0)
{
return null;
}
if(b == 0)
{
return DOWN_NEGATIVE_Y;
}
else if(b == 1)
{
return UP_POSITIVE_Y;
}
else if(b == 2)
{
return NORTH_NEGATIVE_Z;
}
else if(b == 3)
{
return SOUTH_POSITIVE_Z;
}
else if(b == 4)
{
return WEST_NEGATIVE_X;
}
else
{
return EAST_POSITIVE_X;
}
}
/**
* Get the byte value represented in some directional blocks
*
* @return the byte value
*/
public byte byteValue()
{
switch(this)
{
case DOWN_NEGATIVE_Y:
return 0;
case EAST_POSITIVE_X:
return 5;
case NORTH_NEGATIVE_Z:
return 2;
case SOUTH_POSITIVE_Z:
return 3;
case UP_POSITIVE_Y:
return 1;
case WEST_NEGATIVE_X:
return 4;
default:
break;
}
return -1;
}
public static void calculatePermutations()
{
if(permute != null)
{
return;
}
permute = new KMap<GBiset<IrisDirection, IrisDirection>, DOP>();
for(IrisDirection i : udnews())
{
for(IrisDirection j : udnews())
{
GBiset<IrisDirection, IrisDirection> b = new GBiset<IrisDirection, IrisDirection>(i, j);
if(i.equals(j))
{
permute.put(b, new DOP("DIRECT")
{
@Override
public Vector op(Vector v)
{
return v;
}
});
}
else if(i.reverse().equals(j))
{
if(i.isVertical())
{
permute.put(b, new DOP("R180CCZ")
{
@Override
public Vector op(Vector v)
{
return VectorMath.rotate90CCZ(VectorMath.rotate90CCZ(v));
}
});
}
else
{
permute.put(b, new DOP("R180CCY")
{
@Override
public Vector op(Vector v)
{
return VectorMath.rotate90CCY(VectorMath.rotate90CCY(v));
}
});
}
}
else if(getDirection(VectorMath.rotate90CX(i.toVector())).equals(j))
{
permute.put(b, new DOP("R90CX")
{
@Override
public Vector op(Vector v)
{
return VectorMath.rotate90CX(v);
}
});
}
else if(getDirection(VectorMath.rotate90CCX(i.toVector())).equals(j))
{
permute.put(b, new DOP("R90CCX")
{
@Override
public Vector op(Vector v)
{
return VectorMath.rotate90CCX(v);
}
});
}
else if(getDirection(VectorMath.rotate90CY(i.toVector())).equals(j))
{
permute.put(b, new DOP("R90CY")
{
@Override
public Vector op(Vector v)
{
return VectorMath.rotate90CY(v);
}
});
}
else if(getDirection(VectorMath.rotate90CCY(i.toVector())).equals(j))
{
permute.put(b, new DOP("R90CCY")
{
@Override
public Vector op(Vector v)
{
return VectorMath.rotate90CCY(v);
}
});
}
else if(getDirection(VectorMath.rotate90CZ(i.toVector())).equals(j))
{
permute.put(b, new DOP("R90CZ")
{
@Override
public Vector op(Vector v)
{
return VectorMath.rotate90CZ(v);
}
});
}
else if(getDirection(VectorMath.rotate90CCZ(i.toVector())).equals(j))
{
permute.put(b, new DOP("R90CCZ")
{
@Override
public Vector op(Vector v)
{
return VectorMath.rotate90CCZ(v);
}
});
}
else
{
permute.put(b, new DOP("FAIL")
{
@Override
public Vector op(Vector v)
{
return v;
}
});
}
}
}
}
public BlockFace getFace()
{
switch(this)
{
case DOWN_NEGATIVE_Y:
return BlockFace.DOWN;
case EAST_POSITIVE_X:
return BlockFace.EAST;
case NORTH_NEGATIVE_Z:
return BlockFace.NORTH;
case SOUTH_POSITIVE_Z:
return BlockFace.SOUTH;
case UP_POSITIVE_Y:
return BlockFace.UP;
case WEST_NEGATIVE_X:
return BlockFace.WEST;
}
return null;
}
public Axis getAxis()
{
switch(this)
{
case DOWN_NEGATIVE_Y:
return Axis.Y;
case EAST_POSITIVE_X:
return Axis.X;
case NORTH_NEGATIVE_Z:
return Axis.Z;
case SOUTH_POSITIVE_Z:
return Axis.Z;
case UP_POSITIVE_Y:
return Axis.Y;
case WEST_NEGATIVE_X:
return Axis.X;
}
return null;
}
}

View File

@@ -1,13 +1,7 @@
package com.volmit.iris.object;
import org.bukkit.util.BlockVector;
import com.volmit.iris.util.Desc;
import com.volmit.iris.util.DontObfuscate;
import com.volmit.iris.util.MaxNumber;
import com.volmit.iris.util.MinNumber;
import com.volmit.iris.util.Required;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@@ -16,58 +10,19 @@ import lombok.experimental.Accessors;
@Accessors(chain = true)
@NoArgsConstructor
@AllArgsConstructor
@Desc("Translate objects")
@Desc("Represents a position")
@Data
public class IrisObjectTranslate
public class IrisPosition
{
@MinNumber(-128)
@MaxNumber(128)
@DontObfuscate
@Desc("The x shift in blocks")
@Desc("The x position")
private int x = 0;
@Required
@MinNumber(-256)
@MaxNumber(256)
@DontObfuscate
@Desc("The x shift in blocks")
@Desc("The y position")
private int y = 0;
@MinNumber(-128)
@MaxNumber(128)
@DontObfuscate
@Desc("Adds an additional amount of height randomly (translateY + rand(0 - yRandom))")
private int yRandom = 0;
@MinNumber(-128)
@MaxNumber(128)
@DontObfuscate
@Desc("The x shift in blocks")
@Desc("The z position")
private int z = 0;
public boolean canTranslate()
{
return x != 0 || y != 0 || z != 0;
}
public BlockVector translate(BlockVector i)
{
if(canTranslate())
{
return (BlockVector) i.clone().add(new BlockVector(x, y, z));
}
return i;
}
public BlockVector translate(BlockVector clone, IrisObjectRotation rotation, int sx, int sy, int sz)
{
if(canTranslate())
{
return (BlockVector) clone.clone().add(rotation.rotate(new BlockVector(x, y, z), sx, sy, sz));
}
return clone;
}
}

View File

@@ -1,16 +1,6 @@
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 com.volmit.iris.util.*;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
@@ -24,146 +14,17 @@ import lombok.experimental.Accessors;
@Desc("Represents a structure tile")
@Data
@EqualsAndHashCode(callSuper = false)
public class IrisStructureTile
public class IrisStructurePiece extends IrisRegistrant
{
@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<>();
@Desc("The object this piece represents")
private String object = "";
@Required
@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;
}
@ArrayType(type = IrisStructurePieceConnector.class, min = 1)
@Desc("The connectors this object contains")
private KList<IrisStructurePieceConnector> connectors = new KList<>();
}

View File

@@ -2,7 +2,6 @@ package com.volmit.iris.object;
import com.volmit.iris.util.Desc;
import com.volmit.iris.util.DontObfuscate;
import com.volmit.iris.util.RegistryListObject;
import com.volmit.iris.util.Required;
import lombok.AllArgsConstructor;
import lombok.Data;
@@ -17,11 +16,24 @@ import lombok.experimental.Accessors;
@Desc("Represents a structure tile")
@Data
@EqualsAndHashCode(callSuper = false)
public class IrisStructurePiece
public class IrisStructurePieceConnector
{
@RegistryListObject
@Required
@DontObfuscate
@Desc("The object this piece represents")
private String objects = "";
@Desc("The name of this connector, such as entry, or table node. This is a name for organization, it has no effect on generation.")
private String name = "";
@DontObfuscate
@Desc("Rotates the placed piece on this connector. If rotation is enabled, this connector will effectivley rotate, if this connector is facing the Z direction, then the connected piece would rotate in the X,Y direction in 90 degree segments.")
private boolean rotateConnector = false;
@DontObfuscate
@Desc("The relative position this connector is located at for connecting to other pieces")
@Required
private IrisPosition position = new IrisPosition(0,0,0);
@DontObfuscate
@Desc("The direction this connector is facing. If the direction is set to UP, then pieces will place ABOVE the connector.")
@Required
private IrisDirection direction = IrisDirection.UP_POSITIVE_Y;
}