diff --git a/src/main/java/carpet/script/CarpetExpression.java b/src/main/java/carpet/script/CarpetExpression.java index 0dbfa1fe..8fdaa0ca 100644 --- a/src/main/java/carpet/script/CarpetExpression.java +++ b/src/main/java/carpet/script/CarpetExpression.java @@ -18,6 +18,7 @@ import carpet.script.value.EntityValue; import carpet.script.value.FunctionValue; import carpet.script.value.LazyListValue; import carpet.script.value.ListValue; +import carpet.script.value.MapValue; import carpet.script.value.NBTSerializableValue; import carpet.script.value.NullValue; import carpet.script.value.NumericValue; @@ -74,6 +75,8 @@ import net.minecraft.stat.Stat; import net.minecraft.stat.StatType; import net.minecraft.state.StateFactory; import net.minecraft.state.property.Property; +import net.minecraft.structure.StructurePiece; +import net.minecraft.structure.StructureStart; import net.minecraft.text.LiteralText; import net.minecraft.util.Clearable; import net.minecraft.util.Identifier; @@ -83,6 +86,7 @@ import net.minecraft.util.math.Box; import net.minecraft.util.math.ChunkPos; import net.minecraft.util.math.Direction; import net.minecraft.util.math.EulerAngle; +import net.minecraft.util.math.MutableIntBoundingBox; import net.minecraft.util.math.Vec3d; import net.minecraft.util.registry.Registry; import net.minecraft.world.Heightmap; @@ -1225,6 +1229,48 @@ public class CarpetExpression this.forceChunkUpdate(pos, world); return LazyValue.NULL; }); + + this.expr.addLazyFunction("structures", -1, (c, t, lv) -> { + CarpetContext cc = (CarpetContext)c; + BlockValue.LocatorResult locator = BlockValue.fromParams(cc, lv, 0); + + ServerWorld world = cc.s.getWorld(); + BlockPos pos = locator.block.getPos(); + Map structures = world.getChunk(pos).getStructureStarts(); + if (lv.size() == locator.offset) + { + Map strucutureList = new HashMap<>(); + for (Map.Entry entry : structures.entrySet()) + { + StructureStart start = entry.getValue(); + if (start == StructureStart.DEFAULT) + continue; + MutableIntBoundingBox box = start.getBoundingBox(); + ListValue coord1 = ListValue.of(new NumericValue(box.minX), new NumericValue(box.minY), new NumericValue(box.minZ)); + ListValue coord2 = ListValue.of(new NumericValue(box.maxX), new NumericValue(box.maxY), new NumericValue(box.maxZ)); + strucutureList.put(new StringValue(entry.getKey()), ListValue.of(coord1, coord2)); + } + Value ret = MapValue.wrap(strucutureList); + return (_c, _t) -> ret; + } + String structureName = lv.get(locator.offset).evalValue(c).getString(); + StructureStart start = structures.get(structureName); + if (start == null || start == StructureStart.DEFAULT) + return (_c, _t) -> Value.NULL; + List pieces = new ArrayList<>(); + for (StructurePiece piece : start.getChildren()) + { + MutableIntBoundingBox 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; + }); // need get_biome } diff --git a/src/main/java/carpet/script/Expression.java b/src/main/java/carpet/script/Expression.java index 9fbdd1df..9bcc34e5 100644 --- a/src/main/java/carpet/script/Expression.java +++ b/src/main/java/carpet/script/Expression.java @@ -2311,17 +2311,23 @@ public class Expression return ListValue.wrap(toSort); }); - addLazyFunction("sort_key", 2, (c, t, lv) -> //get working with iterators + addLazyFunction("sort_key", -1, (c, t, lv) -> //get working with iterators { + if (lv.size() == 0) + throw new InternalExpressionException("First argument for 'sort_key' should be a List"); Value v = lv.get(0).evalValue(c); if (!(v instanceof ListValue)) throw new InternalExpressionException("First argument for 'sort_key' should be a List"); + List toSort = new ArrayList<>(((ListValue) v).getItems()); + if (lv.size()==1) + { + Collections.shuffle(toSort); + Value ret = ListValue.wrap(toSort); + return (_c, _t) -> ret; + } LazyValue sortKey = lv.get(1); //scoping LazyValue __ = c.getVariable("_"); - - List toSort = new ArrayList<>(((ListValue) v).getItems()); - Collections.sort(toSort,(v1, v2) -> { c.setVariable("_",(cc, tt) -> v1); Value ev1 = sortKey.evalValue(c); diff --git a/src/main/java/carpet/script/value/MapValue.java b/src/main/java/carpet/script/value/MapValue.java index fbd6d251..c79ca8a5 100644 --- a/src/main/java/carpet/script/value/MapValue.java +++ b/src/main/java/carpet/script/value/MapValue.java @@ -77,6 +77,11 @@ public class MapValue extends AbstractListValue implements ContainerValueInterfa map = other; } + public static MapValue wrap(Map other) + { + return new MapValue(other); + } + @Override public Value add(Value o) { diff --git a/src/main/java/carpet/script/value/NBTSerializableValue.java b/src/main/java/carpet/script/value/NBTSerializableValue.java index 19585081..b2d3198b 100644 --- a/src/main/java/carpet/script/value/NBTSerializableValue.java +++ b/src/main/java/carpet/script/value/NBTSerializableValue.java @@ -82,6 +82,8 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa public static String nameFromRegistryId(Identifier id) { + if (id == null) // should be Value.NULL + return ""; if (id.getNamespace().equals("minecraft")) return id.getPath(); return id.toString();