unify structure info.

This commit is contained in:
gnembon committed 2020-05-04 15:48:45 -03:00
1 parent 15ac3edc19
commit ad43784ad6
6 files changed
+83 -45

No files matched your search

+19 -7
View File
@@ -689,15 +689,22 @@ number('3bar') => null
number('2')+number('2') => 4 number('2')+number('2') => 4
</pre> </pre>
### `str(expr, params? ... ), str(expr, param_list)` ### `str(expr)`,`str(expr, params? ... )`, `str(expr, param_list)`
Returns a formatted string representing expression. Accepts formatting style accepted by `String.format`. If called with one argument, returns string representation of such value.
Supported types (with `"%?"` syntax):
Otherwise, returns a formatted string representing the expression. Arguments for formatting can either be provided as
each consecutive parameter, or as a list which then would be the only extra parameter. To format one list argument
, you can use `str(list)`, or `str('foo %s', l(list))`.
Accepts formatting style accepted by `String.format`.
Supported types (with `"%<?>"` syntax):
* `d`, `o`, `x`: integers, octal, hex * `d`, `o`, `x`: integers, octal, hex
* `a`, `e`, `f`, `g`: floats * `a`, `e`, `f`, `g`: floats
* `b`: booleans * `b`: booleans
* `s`: strings * `s`: strings
* `%%`: '%' character
<pre> <pre>
str(null) => null str(null) => null
@@ -2069,13 +2076,17 @@ Returns spawn potential at a location (1.16+ only)
Checks wordgen eligibility for a structure in a given chunk. If no structure is given, or `null`, then it will check Checks wordgen eligibility for a structure in a given chunk. If no structure is given, or `null`, then it will check
for all structures. If bounding box of the structures is also requested, it will compute size of potential for all structures. If bounding box of the structures is also requested, it will compute size of potential
structures. This function, unlike other in the `structure*` category is not using world data nor accesses chunks structures. This function, unlike other in the `structure*` category is not using world data nor accesses chunks
making it preferred for scoping ungenerated terrain. making it preferred for scoping ungenerated terrain, but it takes some compute money to calculate the structure.
Unlike `'structure'` this will return a tentative structure location. Random factors in world generation may prevent
actual structure from forming.
If structure is specified, it will return `null` if a chunk is not eligible, `true` if the structure should appear, or If structure is specified, it will return `null` if a chunk is not eligible, `true` if the structure should appear, or
a pair of coordinates indicating bounding box of the structure. a map with two values: `'box'` for a pair of coordinates indicating bounding box of the structure, and `'pieces'` for
list of elements of the structure (as a tuple), with its name, direction, and box coordinates of the piece.
If structure is not specified, it will return a set of structure names that are eligible, or a map with structures If structure is not specified, it will return a set of structure names that are eligible, or a map with structures
as keys, and pair of bounding box coordinates as values. An empty set or an empty map would indicate that nothing as keys, and same type of map values as with a single structure call. An empty set or an empty map would indicate that nothing
should be generated there. should be generated there.
@@ -2085,7 +2096,8 @@ Returns structure information for a given block position. Note that structure in
blocks from the same chunk. `structures` function can be called with a block, or a block and a structure name. In blocks from the same chunk. `structures` function can be called with a block, or a block and a structure name. In
the first case it returns a map of structures at a given position, keyed by structure name, with values indicating the first case it returns a map of structures at a given position, keyed by structure name, with values indicating
the bounding box of the structure - a pair of two 3-value coords (see examples). When called with an extra structure the bounding box of the structure - a pair of two 3-value coords (see examples). When called with an extra structure
name, returns list of components for that structure, with their name, direction and two sets of coordinates name, returns a map with two values, `'box'` for bounding box of the structure, and `'pieces'` for a list of
components for that structure, with their name, direction and two sets of coordinates
indicating the bounding box of the structure piece. indicating the bounding box of the structure piece.
### `structure_references(pos), structure_references(pos, structure_name)` ### `structure_references(pos), structure_references(pos, structure_name)`
+9 -4
View File
@@ -532,13 +532,17 @@ Returns spawn potential at a location (1.16+ only)
Checks wordgen eligibility for a structure in a given chunk. If no structure is given, or `null`, then it will check Checks wordgen eligibility for a structure in a given chunk. If no structure is given, or `null`, then it will check
for all structures. If bounding box of the structures is also requested, it will compute size of potential for all structures. If bounding box of the structures is also requested, it will compute size of potential
structures. This function, unlike other in the `structure*` category is not using world data nor accesses chunks structures. This function, unlike other in the `structure*` category is not using world data nor accesses chunks
making it preferred for scoping ungenerated terrain. making it preferred for scoping ungenerated terrain, but it takes some compute money to calculate the structure.
Unlike `'structure'` this will return a tentative structure location. Random factors in world generation may prevent
actual structure from forming.
If structure is specified, it will return `null` if a chunk is not eligible, `true` if the structure should appear, or If structure is specified, it will return `null` if a chunk is not eligible, `true` if the structure should appear, or
a pair of coordinates indicating bounding box of the structure. a map with two values: `'box'` for a pair of coordinates indicating bounding box of the structure, and `'pieces'` for
list of elements of the structure (as a tuple), with its name, direction, and box coordinates of the piece.
If structure is not specified, it will return a set of structure names that are eligible, or a map with structures If structure is not specified, it will return a set of structure names that are eligible, or a map with structures
as keys, and pair of bounding box coordinates as values. An empty set or an empty map would indicate that nothing as keys, and same type of map values as with a single structure call. An empty set or an empty map would indicate that nothing
should be generated there. should be generated there.
@@ -548,7 +552,8 @@ Returns structure information for a given block position. Note that structure in
blocks from the same chunk. `structures` function can be called with a block, or a block and a structure name. In blocks from the same chunk. `structures` function can be called with a block, or a block and a structure name. In
the first case it returns a map of structures at a given position, keyed by structure name, with values indicating the first case it returns a map of structures at a given position, keyed by structure name, with values indicating
the bounding box of the structure - a pair of two 3-value coords (see examples). When called with an extra structure the bounding box of the structure - a pair of two 3-value coords (see examples). When called with an extra structure
name, returns list of components for that structure, with their name, direction and two sets of coordinates name, returns a map with two values, `'box'` for bounding box of the structure, and `'pieces'` for a list of
components for that structure, with their name, direction and two sets of coordinates
indicating the bounding box of the structure piece. indicating the bounding box of the structure piece.
### `structure_references(pos), structure_references(pos, structure_name)` ### `structure_references(pos), structure_references(pos, structure_name)`
@@ -147,10 +147,9 @@ public class FeatureGenerator
return null; return null;
} }
public static BlockBox DEFAULT_BOX = new BlockBox(0,0,0,1,1,1); public static StructureStart shouldStructureStartAt(ServerWorld world, BlockPos pos, StructureFeature<?> structure, boolean computeBox)
public static BlockBox shouldStructureStartAt(ServerWorld world, BlockPos pos, StructureFeature<?> structure, boolean computeBox)
{ {
ChunkGenerator generator = world.getChunkManager().getChunkGenerator(); ChunkGenerator<?> generator = world.getChunkManager().getChunkGenerator();
if (!generator.getBiomeSource().hasStructureFeature(structure)) if (!generator.getBiomeSource().hasStructureFeature(structure))
return null; return null;
BiomeAccess biomeAccess = world.getBiomeAccess().withSource(generator.getBiomeSource()); BiomeAccess biomeAccess = world.getBiomeAccess().withSource(generator.getBiomeSource());
@@ -159,12 +158,12 @@ public class FeatureGenerator
Biome biome = biomeAccess.getBiome(new BlockPos(chunkPos.getStartX() + 9, 0, chunkPos.getStartZ() + 9)); Biome biome = biomeAccess.getBiome(new BlockPos(chunkPos.getStartX() + 9, 0, chunkPos.getStartZ() + 9));
if (structure.shouldStartAt(biomeAccess, generator, chunkRandom, chunkPos.x, chunkPos.z, biome)) if (structure.shouldStartAt(biomeAccess, generator, chunkRandom, chunkPos.x, chunkPos.z, biome))
{ {
if (!computeBox) return DEFAULT_BOX; if (!computeBox) return StructureStart.DEFAULT;
StructureManager manager = world.getSaveHandler().getStructureManager(); StructureManager manager = world.getSaveHandler().getStructureManager();
StructureStart structureStart3 = structure.getStructureStartFactory().create(structure, chunkPos.x, chunkPos.z, BlockBox.empty(), 0, generator.getSeed()); StructureStart structureStart3 = structure.getStructureStartFactory().create(structure, chunkPos.x, chunkPos.z, BlockBox.empty(), 0, generator.getSeed());
structureStart3.initialize(generator, manager, chunkPos.x, chunkPos.z, biome); structureStart3.initialize(generator, manager, chunkPos.x, chunkPos.z, biome);
if (!structureStart3.hasChildren()) return null; if (!structureStart3.hasChildren()) return null;
return structureStart3.getBoundingBox(); return structureStart3;
} }
return null; return null;
} }
@@ -397,6 +397,32 @@ public class CarpetExpression
} }
} }
private static Value structureToValue(StructureStart structure)
{
if (structure == null || structure == StructureStart.DEFAULT) return Value.NULL;
List<Value> pieces = new ArrayList<>();
for (StructurePiece piece : structure.getChildren())
{
BlockBox box = piece.getBoundingBox();
pieces.add(ListValue.of(
new StringValue( NBTSerializableValue.nameFromRegistryId(Registry.STRUCTURE_PIECE.getId(piece.getType()))),
(piece.getFacing()== null)?Value.NULL: new StringValue(piece.getFacing().getName()),
ListValue.fromTriple(box.minX, box.minY, box.minZ),
ListValue.fromTriple(box.maxX, box.maxY, box.maxZ)
));
};
BlockBox boundingBox = structure.getBoundingBox();
Map<Value, Value> ret = new HashMap<>();
ret.put(new StringValue("box"), ListValue.of(
ListValue.fromTriple(boundingBox.minX, boundingBox.minY, boundingBox.minZ),
ListValue.fromTriple(boundingBox.maxX, boundingBox.maxY, boundingBox.maxZ)
));
ret.put(new StringValue("pieces"), ListValue.wrap(pieces));
return MapValue.wrap(ret);
}
private void API_BlockManipulation() private void API_BlockManipulation()
{ {
this.expr.addLazyFunction("block", -1, (c, t, lv) -> this.expr.addLazyFunction("block", -1, (c, t, lv) ->
@@ -1147,25 +1173,20 @@ public class CarpetExpression
} }
if (structure != null) if (structure != null)
{ {
BlockBox box = FeatureGenerator.shouldStructureStartAt(world, pos, structure, needSize); StructureStart start = FeatureGenerator.shouldStructureStartAt(world, pos, structure, needSize);
if (box == null) return LazyValue.NULL; if (start == null) return LazyValue.NULL;
if (!needSize) return LazyValue.TRUE; if (!needSize) return LazyValue.TRUE;
Value ret = ListValue.of( Value ret = structureToValue(start);
ListValue.of(new NumericValue(box.minX), new NumericValue(box.minY), new NumericValue(box.minZ)),
ListValue.of(new NumericValue(box.maxX), new NumericValue(box.maxY), new NumericValue(box.maxZ))
);
return (_c, _t) -> ret; return (_c, _t) -> ret;
} }
Map<Value, Value> ret = new HashMap<>(); Map<Value, Value> ret = new HashMap<>();
for(StructureFeature<?> str : Feature.STRUCTURES.values()) for(StructureFeature<?> str : Feature.STRUCTURES.values())
{ {
BlockBox box = FeatureGenerator.shouldStructureStartAt(world, pos, str, needSize); StructureStart start = FeatureGenerator.shouldStructureStartAt(world, pos, str, needSize);
if (box == null) continue; if (start == null) continue;
Value key = new StringValue(FeatureGenerator.structureToFeature.get(str.getName()).get(0)); Value key = new StringValue(FeatureGenerator.structureToFeature.get(str.getName()).get(0));
ret.put(key, (!needSize)?Value.NULL:ListValue.of( ret.put(key, (!needSize)?Value.NULL:structureToValue(start));
ListValue.of(new NumericValue(box.minX), new NumericValue(box.minY), new NumericValue(box.minZ)),
ListValue.of(new NumericValue(box.maxX), new NumericValue(box.maxY), new NumericValue(box.maxZ))
));
} }
Value retMap = MapValue.wrap(ret); Value retMap = MapValue.wrap(ret);
return (_c, _t) -> retMap; return (_c, _t) -> retMap;
@@ -1187,28 +1208,17 @@ public class CarpetExpression
if (start == StructureStart.DEFAULT) if (start == StructureStart.DEFAULT)
continue; continue;
BlockBox box = start.getBoundingBox(); BlockBox box = start.getBoundingBox();
ListValue coord1 = ListValue.of(new NumericValue(box.minX), new NumericValue(box.minY), new NumericValue(box.minZ)); structureList.put(
ListValue coord2 = ListValue.of(new NumericValue(box.maxX), new NumericValue(box.maxY), new NumericValue(box.maxZ)); new StringValue(FeatureGenerator.structureToFeature.get(entry.getKey()).get(0)),
structureList.put(new StringValue(FeatureGenerator.structureToFeature.get(entry.getKey()).get(0)), ListValue.of(coord1, coord2)); ListValue.of(ListValue.fromTriple(box.minX, box.minY, box.minZ), ListValue.fromTriple(box.maxX, box.maxY, box.maxZ))
);
} }
Value ret = MapValue.wrap(structureList); Value ret = MapValue.wrap(structureList);
return (_c, _t) -> ret; return (_c, _t) -> ret;
} }
String structureName = lv.get(locator.offset).evalValue(c).getString().toLowerCase(Locale.ROOT); String structureName = lv.get(locator.offset).evalValue(c).getString().toLowerCase(Locale.ROOT);
StructureStart start = structures.get(FeatureGenerator.featureToStructure.get(structureName)); StructureStart start = structures.get(FeatureGenerator.featureToStructure.get(structureName));
if (start == null || start == StructureStart.DEFAULT) return LazyValue.NULL; Value ret = structureToValue(start);
List<Value> pieces = new ArrayList<>();
for (StructurePiece piece : start.getChildren())
{
BlockBox box = piece.getBoundingBox();
pieces.add(ListValue.of(
new StringValue( NBTSerializableValue.nameFromRegistryId(Registry.STRUCTURE_PIECE.getId(piece.getType()))),
(piece.getFacing()== null)?Value.NULL: new StringValue(piece.getFacing().getName()),
ListValue.of(new NumericValue(box.minX), new NumericValue(box.minY), new NumericValue(box.minZ)),
ListValue.of(new NumericValue(box.maxX), new NumericValue(box.maxY), new NumericValue(box.maxZ))
));
}
Value ret = ListValue.wrap(pieces);
return (_c, _t) -> ret; return (_c, _t) -> ret;
}); });
@@ -75,6 +75,18 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
); );
} }
public static Value fromTriple(double a, double b, double c)
{
return ListValue.of(new NumericValue(a), new NumericValue(b), new NumericValue(c));
}
public static Value fromTriple(int a, int b, int c)
{
return fromTriple((double) a, b, c);
}
public static ListValue wrap(List<Value> list) public static ListValue wrap(List<Value> list)
{ {
@@ -89,7 +89,7 @@ __structure_renderer(player_name) ->
for (starts, l(position, name) = _; for (starts, l(position, name) = _;
structure_data = structures(position):name; structure_data = structures(position):name;
if (!structure_data, continue()); // messed up references - shouldn't happen if (!structure_data, continue()); // messed up references - shouldn't happen
structure_pieces = structures(position, name); structure_pieces = structures(position, name):'pieces';
if (!structure_pieces, continue()); // messed up references - shouldn't happen if (!structure_pieces, continue()); // messed up references - shouldn't happen
l(from, to) = structure_data; l(from, to) = structure_data;
total_size = _euclidean(from, to); total_size = _euclidean(from, to);