diff --git a/src/main/java/com/volmit/iris/generator/IrisEngine.java b/src/main/java/com/volmit/iris/generator/IrisEngine.java index aa9ddcb37..ea8de8c9b 100644 --- a/src/main/java/com/volmit/iris/generator/IrisEngine.java +++ b/src/main/java/com/volmit/iris/generator/IrisEngine.java @@ -4,7 +4,6 @@ import com.volmit.iris.Iris; import com.volmit.iris.IrisSettings; import com.volmit.iris.scaffold.engine.*; import com.volmit.iris.scaffold.hunk.Hunk; -import com.volmit.iris.scaffold.parallel.MultiBurst; import com.volmit.iris.util.J; import com.volmit.iris.util.PrecisionStopwatch; import com.volmit.iris.util.RNG; @@ -109,45 +108,21 @@ public class IrisEngine extends BlockPopulator implements Engine public void generate(int x, int z, Hunk vblocks, Hunk postblocks, Hunk vbiomes) { try { + boolean structures = postblocks != null; boolean multicore = !IrisSettings.get().isUseGleamPregenerator(); //TODO: LATER s.acquire(1); PrecisionStopwatch p = PrecisionStopwatch.start(); - Hunk biomes = vbiomes; Hunk blocks = vblocks.synchronize().listen((xx,y,zz,t) -> catchBlockUpdates(x+xx,y+getMinHeight(),z+zz, t)); - Hunk pblocks = postblocks.synchronize().listen((xx,y,zz,t) -> catchBlockUpdates(x+xx,y+getMinHeight(),z+zz, t)); - Hunk fringe = Hunk.fringe(blocks, pblocks); - - if(multicore) - { - MultiBurst.burst.burst( - () -> getFramework().getEngineParallax().generateParallaxArea(x, z), - () -> getFramework().getBiomeActuator().actuate(x, z, biomes), - () -> getFramework().getTerrainActuator().actuate(x, z, blocks) - ); - - - - MultiBurst.burst.burst( - () -> getFramework().getCaveModifier().modify(x, z, blocks), - () -> getFramework().getRavineModifier().modify(x, z, blocks), - () -> getFramework().getPostModifier().modify(x, z, blocks), - () -> getFramework().getDecorantActuator().actuate(x, z, fringe), - () -> getFramework().getEngineParallax().insertParallax(x, z, fringe) - ); - } - - else - { - getFramework().getEngineParallax().generateParallaxArea(x, z); - getFramework().getBiomeActuator().actuate(x, z, biomes); - getFramework().getTerrainActuator().actuate(x, z, blocks); - getFramework().getCaveModifier().modify(x, z, blocks); - getFramework().getRavineModifier().modify(x, z, blocks); - getFramework().getPostModifier().modify(x, z, blocks); - getFramework().getDecorantActuator().actuate(x, z, fringe); - getFramework().getEngineParallax().insertParallax(x, z, fringe); - } - + Hunk pblocks = structures ? postblocks.synchronize().listen((xx,y,zz,t) -> catchBlockUpdates(x+xx,y+getMinHeight(),z+zz, t)) : null; + Hunk fringe = structures ? Hunk.fringe(blocks, pblocks) : null; + getFramework().getEngineParallax().generateParallaxArea(x, z); + getFramework().getBiomeActuator().actuate(x, z, vbiomes); + getFramework().getTerrainActuator().actuate(x, z, blocks); + getFramework().getCaveModifier().modify(x, z, blocks); + getFramework().getRavineModifier().modify(x, z, blocks); + getFramework().getPostModifier().modify(x, z, blocks); + getFramework().getDecorantActuator().actuate(x, z, structures ? fringe : blocks); + getFramework().getEngineParallax().insertParallax(x, z, structures ? fringe : blocks); getFramework().getDepositModifier().modify(x, z, blocks); getMetrics().getTotal().put(p.getMilliseconds()); s.release(1); diff --git a/src/main/java/com/volmit/iris/generator/IrisEngineCompound.java b/src/main/java/com/volmit/iris/generator/IrisEngineCompound.java index d1dcf6c25..b72adc939 100644 --- a/src/main/java/com/volmit/iris/generator/IrisEngineCompound.java +++ b/src/main/java/com/volmit/iris/generator/IrisEngineCompound.java @@ -1,6 +1,7 @@ package com.volmit.iris.generator; import com.volmit.iris.Iris; +import com.volmit.iris.IrisSettings; import com.volmit.iris.manager.IrisDataManager; import com.volmit.iris.object.IrisDimension; import com.volmit.iris.object.IrisDimensionIndex; @@ -221,6 +222,7 @@ public class IrisEngineCompound implements EngineCompound { int offset = 0; BurstExecutor e = burster.burst(); Runnable[] insert = new Runnable[engines.length]; + boolean structures = getDefaultEngine().getDimension().isVanillaStructures() && !IrisSettings.get().isDisableNMS(); for(i = 0; i < engines.length; i++) { @@ -229,10 +231,15 @@ public class IrisEngineCompound implements EngineCompound { int doffset = offset; int height = engine.getTarget().getHeight(); AtomicReference> cblock = new AtomicReference<>(Hunk.newArrayHunk(16, height, 16)); - AtomicReference> cpblock = new AtomicReference<>(Hunk.newArrayHunk(16, height, 16)); + AtomicReference> cpblock = new AtomicReference<>(structures ? Hunk.newArrayHunk(16, height, 16) : null); AtomicReference> cbiome = new AtomicReference<>(Hunk.newArrayHunk(16, height, 16)); cblock.set(engine.getTarget().isInverted() ? cblock.get().invertY() : cblock.get()); - cpblock.set(engine.getTarget().isInverted() ? cpblock.get().invertY() : cpblock.get()); + + if(structures) + { + cpblock.set(engine.getTarget().isInverted() ? cpblock.get().invertY() : cpblock.get()); + } + cbiome.set(engine.getTarget().isInverted() ? cbiome.get().invertY() : cbiome.get()); e.queue(() -> { engine.generate(x, z, cblock.get(), cpblock.get(), cbiome.get()); @@ -240,7 +247,12 @@ public class IrisEngineCompound implements EngineCompound { { insert[index.get()] = () -> { blocks.insert(0, doffset, 0, cblock.get()); - postblocks.insert(0, doffset, 0, cpblock.get()); + + if(structures) + { + postblocks.insert(0, doffset, 0, cpblock.get()); + } + biomes.insert(0, doffset, 0, cbiome.get()); }; } diff --git a/src/main/java/com/volmit/iris/manager/IrisDataManager.java b/src/main/java/com/volmit/iris/manager/IrisDataManager.java index 2af9d3cba..8b238527e 100644 --- a/src/main/java/com/volmit/iris/manager/IrisDataManager.java +++ b/src/main/java/com/volmit/iris/manager/IrisDataManager.java @@ -19,6 +19,7 @@ public class IrisDataManager private ResourceLoader dimensionLoader; private ResourceLoader generatorLoader; private ResourceLoader structureLoader; + private ResourceLoader structurePieceLoader; private ResourceLoader entityLoader; private ResourceLoader blockLoader; private ObjectResourceLoader objectLoader; @@ -49,6 +50,7 @@ public class IrisDataManager this.biomeLoader = null; this.dimensionLoader = null; this.structureLoader = null; + this.structurePieceLoader = null; this.generatorLoader = null; this.blockLoader = null; this.objectLoader = null; @@ -78,6 +80,7 @@ public class IrisDataManager this.biomeLoader = new ResourceLoader<>(packs, this, "biomes", "Biome", IrisBiome.class); this.dimensionLoader = new ResourceLoader<>(packs, this, "dimensions", "Dimension", IrisDimension.class); this.structureLoader = new ResourceLoader<>(packs, this, "structures", "Structure", IrisStructure.class); + this.structurePieceLoader = new ResourceLoader<>(packs, this, "structure-pieces", "Structure Piece", IrisStructurePiece.class); this.generatorLoader = new ResourceLoader<>(packs, this, "generators", "Generator", IrisGenerator.class); this.blockLoader = new ResourceLoader<>(packs,this, "blocks", "Block", IrisBlockData.class); this.objectLoader = new ObjectResourceLoader(packs, this, "objects", "Object"); @@ -93,6 +96,7 @@ public class IrisDataManager blockLoader.clearCache(); lootLoader.clearCache(); objectLoader.clearCache(); + structurePieceLoader.clearCache(); regionLoader.clearCache(); dimensionLoader.clearCache(); entityLoader.clearCache(); @@ -115,6 +119,7 @@ public class IrisDataManager dimensionLoader.clearList(); generatorLoader.clearList(); structureLoader.clearList(); + structurePieceLoader.clearList(); objectLoader.clearList(); } @@ -133,6 +138,11 @@ public class IrisDataManager return loadAny(key, (dm) -> dm.getStructureLoader().load(key, false)); } + public static IrisStructurePiece loadAnyStructurePiece(String key) + { + return loadAny(key, (dm) -> dm.getStructurePieceLoader().load(key, false)); + } + public static IrisEntity loadAnyEntity(String key) { return loadAny(key, (dm) -> dm.getEntityLoader().load(key, false)); diff --git a/src/main/java/com/volmit/iris/manager/IrisProject.java b/src/main/java/com/volmit/iris/manager/IrisProject.java index 3b206a47e..a1cc91ac4 100644 --- a/src/main/java/com/volmit/iris/manager/IrisProject.java +++ b/src/main/java/com/volmit/iris/manager/IrisProject.java @@ -283,6 +283,7 @@ public class IrisProject schemas.put(getSchemaEntry(IrisRegion.class, dm, "/regions/*.json")); schemas.put(getSchemaEntry(IrisGenerator.class,dm, "/generators/*.json")); schemas.put(getSchemaEntry(IrisStructure.class, dm, "/structures/*.json")); + schemas.put(getSchemaEntry(IrisStructurePiece.class, dm, "/structure-pieces/*.json")); schemas.put(getSchemaEntry(IrisBlockData.class, dm, "/blocks/*.json")); schemas.put(getSchemaEntry(IrisLootTable.class, dm, "/loot/*.json")); settings.put("json.schemas", schemas); @@ -323,6 +324,7 @@ public class IrisProject blocks.add(dm.getBlockLoader().load(i)); } + //TODO: EXPORT STRUCTURE PIECES FROM STRUCTURES dimension.getRegions().forEach((i) -> regions.add(dm.getRegionLoader().load(i))); dimension.getLoot().getTables().forEach((i) -> loot.add(dm.getLootLoader().load(i))); regions.forEach((i) -> biomes.addAll(i.getAllBiomes(null))); diff --git a/src/main/java/com/volmit/iris/manager/SchemaBuilder.java b/src/main/java/com/volmit/iris/manager/SchemaBuilder.java index 92da5c164..07fc1ddcb 100644 --- a/src/main/java/com/volmit/iris/manager/SchemaBuilder.java +++ b/src/main/java/com/volmit/iris/manager/SchemaBuilder.java @@ -382,6 +382,22 @@ public class SchemaBuilder description.add(SYMBOL_TYPE__N + " Must be a valid Structure Tileset (use ctrl+space for auto complete!)"); } + else if(k.isAnnotationPresent(RegistryListStructurePiece.class)) + { + String key = "enum-reg-structure-piece"; + + if(!definitions.containsKey(key)) + { + JSONObject j = new JSONObject(); + j.put("enum", new JSONArray(data.getStructurePieceLoader().getPossibleKeys())); + definitions.put(key, j); + } + + fancyType = "Iris Structure Piece"; + prop.put("$ref", "#/definitions/" + key); + description.add(SYMBOL_TYPE__N + " Must be a valid Structure Piece (use ctrl+space for auto complete!)"); + } + else if(k.getType().equals(Enchantment.class)) { String key = "enum-enchantment"; @@ -765,6 +781,24 @@ public class SchemaBuilder description.add(SYMBOL_TYPE__N + " Must be a valid Structure Tileset (use ctrl+space for auto complete!)"); } + else if(k.isAnnotationPresent(RegistryListStructurePiece.class)) + { + fancyType = "List of Iris Structure Pieces"; + String key = "enum-reg-structure-piece"; + + if(!definitions.containsKey(key)) + { + JSONObject j = new JSONObject(); + j.put("enum", new JSONArray(data.getStructurePieceLoader().getPossibleKeys())); + definitions.put(key, j); + } + + JSONObject items = new JSONObject(); + items.put("$ref", "#/definitions/" + key); + prop.put("items", items); + description.add(SYMBOL_TYPE__N + " Must be a valid Structure Piece (use ctrl+space for auto complete!)"); + } + else if(t.type().equals(Enchantment.class)) { fancyType = "List of Enchantment Types"; diff --git a/src/main/java/com/volmit/iris/object/IrisDirection.java b/src/main/java/com/volmit/iris/object/IrisDirection.java index e69de29bb..32bbd1bc0 100644 --- a/src/main/java/com/volmit/iris/object/IrisDirection.java +++ b/src/main/java/com/volmit/iris/object/IrisDirection.java @@ -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, 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 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 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 news() + { + return new KList().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 udnews() + { + return new KList().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, DOP>(); + + for(IrisDirection i : udnews()) + { + for(IrisDirection j : udnews()) + { + GBiset b = new GBiset(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; + } +} diff --git a/src/main/java/com/volmit/iris/object/IrisPosition.java b/src/main/java/com/volmit/iris/object/IrisPosition.java index c89b4277f..d53a38d36 100644 --- a/src/main/java/com/volmit/iris/object/IrisPosition.java +++ b/src/main/java/com/volmit/iris/object/IrisPosition.java @@ -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; - } } diff --git a/src/main/java/com/volmit/iris/object/IrisStructurePiece.java b/src/main/java/com/volmit/iris/object/IrisStructurePiece.java index a21ee30cf..7ba6856fc 100644 --- a/src/main/java/com/volmit/iris/object/IrisStructurePiece.java +++ b/src/main/java/com/volmit/iris/object/IrisStructurePiece.java @@ -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 entitySpawnOverrides = new KList<>(); - - @DontObfuscate - @Desc("Entity spawns during generation") - @ArrayType(min = 1, type = IrisEntityInitialSpawn.class) - private KList 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 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 rareObjects = new KList<>(); - - private final transient KMap forceObjects = new KMap<>(); - private final transient AtomicCache minFaces = new AtomicCache<>(); - private final transient AtomicCache 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 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 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 connectors = new KList<>(); } diff --git a/src/main/java/com/volmit/iris/object/IrisStructurePieceConnector.java b/src/main/java/com/volmit/iris/object/IrisStructurePieceConnector.java index b6d55e135..a7883666d 100644 --- a/src/main/java/com/volmit/iris/object/IrisStructurePieceConnector.java +++ b/src/main/java/com/volmit/iris/object/IrisStructurePieceConnector.java @@ -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; } diff --git a/src/main/java/com/volmit/iris/scaffold/engine/EngineParallaxManager.java b/src/main/java/com/volmit/iris/scaffold/engine/EngineParallaxManager.java index 59cede8a4..c781f5bf3 100644 --- a/src/main/java/com/volmit/iris/scaffold/engine/EngineParallaxManager.java +++ b/src/main/java/com/volmit/iris/scaffold/engine/EngineParallaxManager.java @@ -15,6 +15,7 @@ import com.volmit.iris.util.*; import org.bukkit.block.data.BlockData; import org.bukkit.util.BlockVector; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; public interface EngineParallaxManager extends DataProvider, IObjectPlacer @@ -73,55 +74,78 @@ public interface EngineParallaxManager extends DataProvider, IObjectPlacer default void insertParallax(int x, int z, Hunk data) { - PrecisionStopwatch p = PrecisionStopwatch.start(); - ParallaxChunkMeta meta = getParallaxAccess().getMetaR(x>>4, z>>4); - - if(!meta.isObjects()) { - getEngine().getMetrics().getParallaxInsert().put(p.getMilliseconds()); - return; - } - - for(int i = x; i < x+ data.getWidth(); i++) + try { - for(int j= z; j < z + data.getDepth(); j++) - { - for(int k = 0; k < data.getHeight(); k++) - { - BlockData d = getParallaxAccess().getBlock(i, k, j); + PrecisionStopwatch p = PrecisionStopwatch.start(); + ParallaxChunkMeta meta = getParallaxAccess().getMetaR(x>>4, z>>4); - if(d != null) + if(!meta.isParallaxGenerated()) + { + Iris.warn("Chunk " + (x >> 4) + " " + (z >> 4) + " has no parallax data!"); + return; + } + + if(!meta.isObjects()) { + getEngine().getMetrics().getParallaxInsert().put(p.getMilliseconds()); + return; + } + + int min = Math.max(meta.getMinObject(), 0); + int max = meta.getMaxObject(); + max = max < 0 ? 255 : max; + + for(int i = x; i < x+ data.getWidth(); i++) + { + for(int j= z; j < z + data.getDepth(); j++) + { + for(int k = min; k < max; k++) { - data.set(i - x, k, j - z, d); + BlockData d = getParallaxAccess().getBlock(i, k, j); + + if(d != null) + { + data.set(i - x, k, j - z, d); + } } } } + + getEngine().getMetrics().getParallaxInsert().put(p.getMilliseconds()); } - getEngine().getMetrics().getParallaxInsert().put(p.getMilliseconds()); + catch(Throwable e) + { + Iris.error("Failed to insert parallax at chunk " + (x>>4) + " " + (z>>4)); + e.printStackTrace(); + } } default void generateParallaxArea(int x, int z) { - PrecisionStopwatch p = PrecisionStopwatch.start(); - int s = (int) Math.ceil(getParallaxSize() / 2D); - int j; - BurstExecutor e = MultiBurst.burst.burst(getParallaxSize() * getParallaxSize()); - - for(int i = -s; i <= s; i++) + try { - int ii = i; + PrecisionStopwatch p = PrecisionStopwatch.start(); + int s = (int) Math.ceil(getParallaxSize() / 2D); + int i,j; - for(j = -s; j <= s; j++) + for(i = -s; i <= s; i++) { - int jj = j; - e.queue(() -> generateParallaxLayer((ii*16)+x, (jj*16)+z)); + for(j = -s; j <= s; j++) + { + generateParallaxLayer((i*16)+x, (j*16)+z); + } } + + getParallaxAccess().setChunkGenerated(x>>4, z>>4); + p.end(); + getEngine().getMetrics().getParallax().put(p.getMilliseconds()); } - e.complete(); - getParallaxAccess().setChunkGenerated(x>>4, z>>4); - p.end(); - getEngine().getMetrics().getParallax().put(p.getMilliseconds()); + catch(Throwable e) + { + Iris.error("Failed to generate parallax in " + x + " " + z); + e.printStackTrace(); + } } default void generateParallaxLayer(int x, int z) @@ -313,12 +337,31 @@ public interface EngineParallaxManager extends DataProvider, IObjectPlacer int xx = rng.i(x, x+16); int zz = rng.i(z, z+16); int id = rng.i(0, Integer.MAX_VALUE); + int maxf = 10000; + AtomicBoolean pl = new AtomicBoolean(false); + AtomicInteger max = new AtomicInteger(-1); + AtomicInteger min = new AtomicInteger(maxf); v.place(xx, forceY, zz, this, objectPlacement, rng, (b) -> { - getParallaxAccess().setObject(b.getX(), b.getY(), b.getZ(), v.getLoadKey() + "@" + id); - ParallaxChunkMeta meta = getParallaxAccess().getMetaRW(b.getX() >> 4, b.getZ() >> 4); + int xf = b.getX(); + int yf = b.getY(); + int zf = b.getZ(); + getParallaxAccess().setObject(xf, yf, zf, v.getLoadKey() + "@" + id); + ParallaxChunkMeta meta = getParallaxAccess().getMetaRW(xf>>4, zf>>4); meta.setObjects(true); - meta.setMaxObject(Math.max(b.getY(), meta.getMaxObject())); - meta.setMinObject(Math.min(b.getY(), Math.max(meta.getMinObject(), 0))); + if(meta.getMinObject() == -1) + { + meta.setMinObject(yf); + } + + if(meta.getMinObject() > yf) + { + meta.setMinObject(yf); + } + + if(meta.getMaxObject() < yf) + { + meta.setMaxObject(yf); + } }, null, getData()); } } diff --git a/src/main/java/com/volmit/iris/scaffold/engine/EnginePlayer.java b/src/main/java/com/volmit/iris/scaffold/engine/EnginePlayer.java index 8ae890b45..1dbad0e09 100644 --- a/src/main/java/com/volmit/iris/scaffold/engine/EnginePlayer.java +++ b/src/main/java/com/volmit/iris/scaffold/engine/EnginePlayer.java @@ -38,20 +38,21 @@ public class EnginePlayer { { try { j.apply(player, getEngine()); - } catch (NullPointerException e) { - player.sendMessage("Unable to play Engine"); - e.printStackTrace(); + } catch (Throwable e) { + } } } if(biome != null) { - try { - j.apply(player, getEngine()); - } catch (NullPointerException e) { - player.sendMessage("Unable to play Engine"); - e.printStackTrace(); + for(IrisEffect j : biome.getEffects()) + { + try { + j.apply(player, getEngine()); + } catch (Throwable e) { + + } } } });