Merge branch 'master' into 1.17

This commit is contained in:
gnembon committed 2020-11-28 12:13:07 -04:00
commit 4f7ebdd9ff
23 files changed
+306 -172

No files matched your search

@@ -337,6 +337,14 @@ public class CarpetEventServer
handler.call( () -> Collections.singletonList(new EntityValue(player)), player::getCommandSource);
}
};
public static final Event PLAYER_ESCAPES_SLEEP = new Event("player_escapes_sleep", 1, false)
{
@Override
public void onPlayerEvent(ServerPlayerEntity player)
{
handler.call( () -> Collections.singletonList(new EntityValue(player)), player::getCommandSource);
}
};
public static final Event PLAYER_RIDES = new Event("player_rides", 5, false)
{
@Override
+4 -4
View File
@@ -658,18 +658,18 @@ public class Expression
case UNARY_OPERATOR:
{
final LazyValue value = stack.pop();
LazyValue result = (c, t) -> operators.get(token.surface).lazyEval(c, t, this, token, value, null).evalValue(c);
LazyValue result = (c, t) -> operators.get(token.surface).lazyEval(c, t, this, token, value, null).evalValue(c, t);
stack.push(result);
break;
}
case OPERATOR:
final LazyValue v1 = stack.pop();
final LazyValue v2 = stack.pop();
LazyValue result = (c,t) -> operators.get(token.surface).lazyEval(c, t,this, token, v2, v1).evalValue(c);
LazyValue result = (c,t) -> operators.get(token.surface).lazyEval(c, t,this, token, v2, v1).evalValue(c, t);
stack.push(result);
break;
case VARIABLE:
stack.push((c, t) -> getOrSetAnyVariable(c, token.surface).evalValue(c));
stack.push((c, t) -> getOrSetAnyVariable(c, token.surface).evalValue(c, t));
break;
case FUNCTION:
String name = token.surface;
@@ -700,7 +700,7 @@ public class Expression
stack.pop();
}
stack.push((c, t) -> f.lazyEval(c, t, this, token, p).evalValue(c));
stack.push((c, t) -> f.lazyEval(c, t, this, token, p).evalValue(c, t));
break;
case OPEN_PAREN:
stack.push(LazyValue.PARAMS_START);
+1 -1
View File
@@ -149,7 +149,7 @@ public abstract class Fluff
{
try
{
return (c, type_ignored) -> AbstractOperator.this.eval(v1.evalValue(c), v2.evalValue(c));
return (c, type_ignored) -> AbstractOperator.this.eval(v1.evalValue(c, type), v2.evalValue(c, type));
}
catch (RuntimeException exc)
{
+27 -17
View File
@@ -24,6 +24,7 @@ import carpet.script.value.EntityValue;
import carpet.script.value.FormattedTextValue;
import carpet.script.value.FunctionValue;
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;
@@ -60,6 +61,7 @@ import net.minecraft.util.math.ChunkPos;
import net.minecraft.util.math.EulerAngle;
import net.minecraft.util.math.Vec2f;
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.registry.DynamicRegistryManager;
import net.minecraft.util.registry.Registry;
import net.minecraft.world.World;
import org.apache.commons.lang3.tuple.Pair;
@@ -67,6 +69,7 @@ import org.apache.commons.lang3.tuple.Pair;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
@@ -304,7 +307,7 @@ public class Auxiliary {
pointLocator = Vector3Argument.findIn(cc, lv, 1, true);
if (lv.size()>pointLocator.offset)
{
BlockArgument blockLocator = BlockArgument.findIn(cc, lv, pointLocator.offset, true, true);
BlockArgument blockLocator = BlockArgument.findIn(cc, lv, pointLocator.offset, true, true, false);
if (blockLocator.block != null) targetBlock = blockLocator.block.getBlockState();
if (lv.size() > blockLocator.offset)
{
@@ -619,6 +622,29 @@ public class Auxiliary {
});
expression.addLazyFunction("plop", -1, (c, t, lv) ->{
if (lv.size() == 0)
{
Map<Value, Value> plopData = new HashMap<>();
CarpetContext cc = (CarpetContext)c;
DynamicRegistryManager registryManager = cc.s.getWorld().getRegistryManager();
plopData.put(StringValue.of("scarpet_custom"),
ListValue.wrap(FeatureGenerator.featureMap.keySet().stream().sorted().map(StringValue::of).collect(Collectors.toList()))
);
plopData.put(StringValue.of("features"),
ListValue.wrap(Registry.FEATURE.getIds().stream().sorted().map(ValueConversions::of).collect(Collectors.toList()))
);
plopData.put(StringValue.of("configured_features"),
ListValue.wrap(registryManager.get(Registry.CONFIGURED_FEATURE_WORLDGEN).getIds().stream().sorted().map(ValueConversions::of).collect(Collectors.toList()))
);
plopData.put(StringValue.of("structures"),
ListValue.wrap(Registry.STRUCTURE_FEATURE.getIds().stream().sorted().map(ValueConversions::of).collect(Collectors.toList()))
);
plopData.put(StringValue.of("configured_structures"),
ListValue.wrap(registryManager.get(Registry.CONFIGURED_STRUCTURE_FEATURE_WORLDGEN).getIds().stream().sorted().map(ValueConversions::of).collect(Collectors.toList()))
);
Value ret = MapValue.wrap(plopData);
return (_c, _t) -> ret;
}
BlockArgument locator = BlockArgument.findIn((CarpetContext)c, lv, 0);
if (lv.size() <= locator.offset)
throw new InternalExpressionException("'plop' needs extra argument indicating what to plop");
@@ -656,23 +682,7 @@ public class Auxiliary {
expression.addLazyFunction("logger", -1, (c, t, lv) ->
{
//CarpetSettings.LOG.error("Standard Structures:");
//CarpetSettings.LOG.error(Registry.STRUCTURE_FEATURE.getIds().stream().map(i -> "`'"+NBTSerializableValue.nameFromRegistryId(i)+"'`").sorted(). collect(Collectors.joining(", ")));
//CarpetSettings.LOG.error("");
//CarpetSettings.LOG.error("Configured Structures:");
//CarpetSettings.LOG.error(BuiltinRegistries.CONFIGURED_STRUCTURE_FEATURE.getIds().stream().map(i -> "`'"+NBTSerializableValue.nameFromRegistryId(i)+"'`").sorted().collect(Collectors.joining(", ")));
//CarpetSettings.LOG.error("");
//CarpetSettings.LOG.error("Features:");
//CarpetSettings.LOG.error(Registry.FEATURE.getIds().stream().map(i -> "`'"+NBTSerializableValue.nameFromRegistryId(i)+"'`").sorted().collect(Collectors.joining(", ")));
//CarpetSettings.LOG.error("");
//CarpetSettings.LOG.error("Configured Features:");
//CarpetSettings.LOG.error(BuiltinRegistries.CONFIGURED_FEATURE.getIds().stream().map(i -> "`'"+NBTSerializableValue.nameFromRegistryId(i)+"'`").sorted().collect(Collectors.joining(", ")));
//CarpetSettings.LOG.error("");
//CarpetSettings.LOG.error("Custom:");
//CarpetSettings.LOG.error(FeatureGenerator.featureMap.keySet().stream().map(i -> "`'"+i+"'`").sorted().collect(Collectors.joining(", ")));
//CarpetSettings.LOG.error(Registry.ENTITY_TYPE.getIds().stream().sorted().map(ValueConversions::simplify).collect(Collectors.joining("`, `")));
Value res;
if(lv.size()==1)
@@ -262,7 +262,7 @@ public class Scoreboards {
if(!(propertyVal instanceof StringValue)) throw new InternalExpressionException("'team_property' requires a string as the second argument");
switch (propertyVal.getString()) {
case "collision_rule":
case "collisionRule":
if(!modifying) {
Value ret = new StringValue(team.getCollisionRule().name);
return (_c, _t) -> ret;
@@ -287,7 +287,7 @@ public class Scoreboards {
team.setColor(color);
break;
case "death_message_visibility":
case "deathMessageVisibility":
if(!modifying) {
Value ret = new StringValue(team.getDeathMessageVisibilityRule().name);
return (_c, _t) -> ret;
@@ -300,7 +300,7 @@ public class Scoreboards {
team.setDeathMessageVisibilityRule(deathMessageVisibility);
break;
case "display_name":
case "displayName":
if(!modifying) {
Value ret = new FormattedTextValue(team.getDisplayName());
return (_c, _t) -> ret;
@@ -319,7 +319,7 @@ public class Scoreboards {
team.setDisplayName(displayName);
break;
case "friendly_fire":
case "friendlyFire":
if(!modifying) {
Value ret = new NumericValue(team.isFriendlyFireAllowed());
return (_c, _t) -> ret;
@@ -330,7 +330,7 @@ public class Scoreboards {
boolean friendlyFire = settingVal.getBoolean();
team.setFriendlyFireAllowed(friendlyFire);
break;
case "nametag_visibility":
case "nametagVisibility":
if(!modifying) {
Value ret = new StringValue(team.getNameTagVisibilityRule().name);
return (_c, _t) -> ret;
@@ -361,7 +361,7 @@ public class Scoreboards {
team.setPrefix(prefix);
break;
case "see_friendly_invisibles":
case "seeFriendlyInvisibles":
if(!modifying) {
Value ret = new NumericValue(team.shouldShowFriendlyInvisibles());
return (_c, _t) -> ret;
@@ -18,6 +18,7 @@ import carpet.script.LazyValue;
import carpet.script.argument.BlockArgument;
import carpet.script.argument.Vector3Argument;
import carpet.script.exception.InternalExpressionException;
import carpet.script.utils.BiomeInfo;
import carpet.script.utils.WorldTools;
import carpet.script.value.BlockValue;
import carpet.script.value.EntityValue;
@@ -66,6 +67,7 @@ import net.minecraft.sound.SoundCategory;
import net.minecraft.state.StateManager;
import net.minecraft.state.property.Property;
import net.minecraft.structure.StructureStart;
import net.minecraft.tag.TagManager;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Clearable;
import net.minecraft.util.Identifier;
@@ -101,6 +103,7 @@ import java.util.Locale;
import java.util.Map;
import java.util.Optional;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -997,7 +1000,7 @@ public class WorldAccess {
// block_state(block, property)
expression.addLazyFunction("block_state", -1, (c, t, lv) ->
{
BlockArgument locator = BlockArgument.findIn((CarpetContext) c, lv, 0);
BlockArgument locator = BlockArgument.findIn((CarpetContext) c, lv, 0, true);
BlockState state = locator.block.getBlockState();
StateManager<Block, BlockState> states = state.getBlock().getStateManager();
if (locator.offset == lv.size())
@@ -1018,16 +1021,71 @@ public class WorldAccess {
return (_c, _t) -> retval;
});
expression.addLazyFunction("block_list", -1, (c, t, lv) ->
{
if (lv.size() == 0)
{
Value ret = ListValue.wrap(Registry.BLOCK.getIds().stream().map(ValueConversions::of).collect(Collectors.toList()));
return (_c, _t) -> ret;
}
CarpetContext cc = (CarpetContext)c;
TagManager tagManager = cc.s.getMinecraftServer().getTagManager();
String tag = lv.get(0).evalValue(c).getString();
net.minecraft.tag.Tag<Block> blockTag = tagManager.getBlocks().getTag(new Identifier(tag));
if (blockTag == null) return LazyValue.NULL;
Value ret = ListValue.wrap(blockTag.values().stream().map(b -> ValueConversions.of(Registry.BLOCK.getId(b))).collect(Collectors.toList()));
return (_c, _t) -> ret;
});
expression.addLazyFunction("block_tags", -1, (c, t, lv) ->
{
CarpetContext cc = (CarpetContext)c;
TagManager tagManager = cc.s.getMinecraftServer().getTagManager();
if (lv.size() == 0)
{
Value ret = ListValue.wrap(tagManager.getBlocks().getTagIds().stream().map(ValueConversions::of).collect(Collectors.toList()));
return (_c, _t) -> ret;
}
BlockArgument blockLocator = BlockArgument.findIn(cc, lv, 0, true);
if (blockLocator.offset == lv.size())
{
Value ret = ListValue.wrap(tagManager.getBlocks().getTagsFor(blockLocator.block.getBlockState().getBlock()).stream().map(ValueConversions::of).collect(Collectors.toList()));
return (_c, _t) -> ret;
}
String tag = lv.get(blockLocator.offset).evalValue(c).getString();
net.minecraft.tag.Tag<Block> blockTag = tagManager.getBlocks().getTag(new Identifier(tag));
if (blockTag == null) return LazyValue.NULL;
return blockLocator.block.getBlockState().isIn(blockTag)?LazyValue.TRUE:LazyValue.FALSE;
});
expression.addLazyFunction("biome", -1, (c, t, lv) -> {
CarpetContext cc = (CarpetContext)c;
BlockArgument locator = BlockArgument.findIn(cc, lv, 0);
ServerWorld world = cc.s.getWorld();
BlockPos pos = locator.block.getPos();
Biome biome = world.getBiome(pos);
BlockArgument locator = BlockArgument.findIn(cc, lv, 0, false, false, true);
Biome biome;
if (locator.replacement != null)
{
biome = cc.s.getMinecraftServer().getRegistryManager().get(Registry.BIOME_KEY).get(new Identifier(locator.replacement));
if (biome == null) throw new InternalExpressionException("Unknown biome: "+locator.replacement);
}
else
{
ServerWorld world = cc.s.getWorld();
BlockPos pos = locator.block.getPos();
biome = world.getBiome(pos);
}
// in locatebiome
Identifier biomeId = cc.s.getMinecraftServer().getRegistryManager().get(Registry.BIOME_KEY).getId(biome);
Value res = new StringValue(NBTSerializableValue.nameFromRegistryId(biomeId));
return (_c, _t) -> res;
if (locator.offset == lv.size())
{
Identifier biomeId = cc.s.getMinecraftServer().getRegistryManager().get(Registry.BIOME_KEY).getId(biome);
Value res = new StringValue(NBTSerializableValue.nameFromRegistryId(biomeId));
return (_c, _t) -> res;
}
String biomeFeature = lv.get(locator.offset).evalValue(c).getString();
Function<Biome, Value> featureProvider = BiomeInfo.biomeFeatures.get(biomeFeature);
if (featureProvider == null) throw new InternalExpressionException("Unknown biome feature: "+biomeFeature);
Value ret = featureProvider.apply(biome);
return (_c, _t) -> ret;
});
expression.addLazyFunction("set_biome", -1, (c, t, lv) ->
@@ -1128,7 +1186,17 @@ public class WorldAccess {
Map<Value, Value> ret = new HashMap<>();
for(StructureFeature<?> str : StructureFeature.STRUCTURES.values())
{
StructureStart start = FeatureGenerator.shouldStructureStartAt(world, pos, str, needSize);
StructureStart<?> start;
try
{
start = FeatureGenerator.shouldStructureStartAt(world, pos, str, needSize);
}
catch (NullPointerException npe)
{
CarpetSettings.LOG.error("Failed to detect structure: "+str.getName());
start = null;
}
if (start == null) continue;
Value key = new StringValue(NBTSerializableValue.nameFromRegistryId(Registry.STRUCTURE_FEATURE.getId(str)));
@@ -16,22 +16,30 @@ import java.util.List;
public class BlockArgument extends Argument
{
public final BlockValue block;
public final String replacement;
private BlockArgument(BlockValue b, int o)
{
super(o);
block = b;
replacement = null;
}
private BlockArgument(BlockValue b, int o, String replacement)
{
super(o);
block = b;
this.replacement = replacement;
}
public static BlockArgument findIn(CarpetContext c, List<LazyValue> params, int offset)
{
return findIn(c, params,offset, false, false);
return findIn(c, params,offset, false, false, false);
}
public static BlockArgument findIn(CarpetContext c, List<LazyValue> params, int offset, boolean acceptString)
{
return findIn(c, params,offset, acceptString, false);
return findIn(c, params,offset, acceptString, false, false);
}
public static BlockArgument findIn(CarpetContext c, List<LazyValue> params, int offset, boolean acceptString, boolean optional)
public static BlockArgument findIn(CarpetContext c, List<LazyValue> params, int offset, boolean acceptString, boolean optional, boolean anyString)
{
try
{
@@ -41,6 +49,10 @@ public class BlockArgument extends Argument
{
return new BlockArgument(null, 1+offset);
}
if (anyString && v1 instanceof StringValue)
{
return new BlockArgument(null, 1+offset, v1.getString());
}
if (acceptString && v1 instanceof StringValue)
{
return new BlockArgument(BlockValue.fromString(v1.getString()), 1+offset);
@@ -45,11 +45,10 @@ public class Functions {
{
FunctionArgument<LazyValue> functionArgument = FunctionArgument.findIn(c, expression.module, lv, 0, false, true);
FunctionValue fun = functionArgument.function;
Value retval = fun.callInContext(expr, c, t, fun.getExpression(), fun.getToken(), functionArgument.args).evalValue(c);
return (cc, tt) -> retval; ///!!!! dono might need to store expr and token in statics? (e? t?)
return fun.callInContext(c, t, functionArgument.args);
}
// gimme signature
String name = lv.get(0).evalValue(c).getString();
String name = lv.get(0).evalValue(c, Context.NONE).getString();
List<String> args = new ArrayList<>();
List<String> globals = new ArrayList<>();
String varArgs = null;
@@ -70,7 +70,7 @@ public class Loops {
// expr receives bounded variable '_' indicating iteration
expression.addLazyFunction("loop", 2, (c, t, lv) ->
{
long limit = NumericValue.asNumber(lv.get(0).evalValue(c)).getLong();
long limit = NumericValue.asNumber(lv.get(0).evalValue(c, Context.NONE)).getLong();
Value lastOne = Value.NULL;
LazyValue expr = lv.get(1);
//scoping
@@ -99,7 +99,7 @@ public class Loops {
// receives bounded variable '_' with the expression
expression.addLazyFunction("map", 2, (c, t, lv) ->
{
Value rval= lv.get(0).evalValue(c);
Value rval= lv.get(0).evalValue(c, Context.NONE);
if (!(rval instanceof AbstractListValue))
throw new InternalExpressionException("First argument of 'map' function should be a list or iterator");
Iterator<Value> iterator = ((AbstractListValue) rval).iterator();
@@ -144,7 +144,7 @@ public class Loops {
// produces list of values for which the expression is true
expression.addLazyFunction("filter", 2, (c, t, lv) ->
{
Value rval= lv.get(0).evalValue(c);
Value rval= lv.get(0).evalValue(c, Context.NONE);
if (!(rval instanceof AbstractListValue))
throw new InternalExpressionException("First argument of 'filter' function should be a list or iterator");
Iterator<Value> iterator = ((AbstractListValue) rval).iterator();
@@ -191,7 +191,7 @@ public class Loops {
expression.addLazyFunction("first", 2, (c, t, lv) ->
{
Value rval= lv.get(0).evalValue(c);
Value rval= lv.get(0).evalValue(c, Context.NONE);
if (!(rval instanceof AbstractListValue))
throw new InternalExpressionException("First argument of 'first' function should be a list or iterator");
Iterator<Value> iterator = ((AbstractListValue) rval).iterator();
@@ -242,7 +242,7 @@ public class Loops {
// returns true if expr is true for all items
expression.addLazyFunction("all", 2, (c, t, lv) ->
{
Value rval= lv.get(0).evalValue(c);
Value rval= lv.get(0).evalValue(c, Context.NONE);
if (!(rval instanceof AbstractListValue))
throw new InternalExpressionException("First argument of 'all' function should be a list or iterator");
Iterator<Value> iterator = ((AbstractListValue) rval).iterator();
@@ -306,7 +306,7 @@ public class Loops {
// can be substituted for first and all, but first is more efficient and all doesn't require knowing list size
expression.addLazyFunction("for", 2, (c, t, lv) ->
{
Value rval= lv.get(0).evalValue(c);
Value rval= lv.get(0).evalValue(c, Context.NONE);
if (!(rval instanceof AbstractListValue))
throw new InternalExpressionException("First argument of 'for' function should be a list or iterator");
Iterator<Value> iterator = ((AbstractListValue) rval).iterator();
@@ -358,8 +358,8 @@ public class Loops {
{
LazyValue expr = lv.get(1);
Value acc = lv.get(2).evalValue(c);
Value rval= lv.get(0).evalValue(c);
Value acc = lv.get(2).evalValue(c, Context.NONE);
Value rval= lv.get(0).evalValue(c, Context.NONE);
if (!(rval instanceof AbstractListValue))
throw new InternalExpressionException("First argument of 'reduce' should be a list or iterator");
Iterator<Value> iterator = ((AbstractListValue) rval).iterator();
@@ -0,0 +1,32 @@
package carpet.script.utils;
import carpet.script.value.BlockValue;
import carpet.script.value.NumericValue;
import carpet.script.value.StringValue;
import carpet.script.value.Value;
import carpet.script.value.ValueConversions;
import net.minecraft.world.biome.Biome;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;
public class BiomeInfo
{
public final static Map<String, Function<Biome, Value>> biomeFeatures = new HashMap<String, Function<Biome, Value>>(){{
put("top_material", b -> new BlockValue( b.getGenerationSettings().getSurfaceConfig().getTopMaterial(), null, null));
put("under_material", b -> new BlockValue( b.getGenerationSettings().getSurfaceConfig().getUnderMaterial(), null, null));
put("category", b -> StringValue.of(b.getCategory().getName()));
put("temperature", b -> NumericValue.of(b.getTemperature()));
put("fog_color", b -> ValueConversions.ofRGB(b.getFogColor()));
put("foliage_color", b -> ValueConversions.ofRGB(b.getFoliageColor()));
put("sky_color", b -> ValueConversions.ofRGB(b.getSkyColor()));
put("water_color", b -> ValueConversions.ofRGB(b.getWaterColor()));
put("water_fog_color", b -> ValueConversions.ofRGB(b.getWaterFogColor()));
put("humidity", b -> NumericValue.of(b.getDownfall()));
put("precipitation", b -> StringValue.of(b.getPrecipitation().getName()));
put("depth", b -> NumericValue.of(b.getDepth()));
put("scale", b -> NumericValue.of(b.getScale()));
//put("features", b -> b.getGenerationSettings().getFeatures())
}};
}
@@ -150,11 +150,11 @@ public class FunctionValue extends Value implements Fluff.ILazyFunction
return varArgs != null;
}
public LazyValue callInContext(Expression callingExpression, Context c, Integer type, Expression e, Tokenizer.Token t, List<LazyValue> lazyParams)
public LazyValue callInContext(Context c, Integer type, List<LazyValue> lazyParams)
{
try
{
return lazyEval(c, type, e, t, lazyParams);
return lazyEval(c, type, expression, token, lazyParams);
}
catch (ExpressionException exc)
{
@@ -164,12 +164,12 @@ public class FunctionValue extends Value implements Fluff.ILazyFunction
catch (InternalExpressionException exc)
{
exc.stack.add(this);
throw new ExpressionException(c, e, t, exc.getMessage(), exc.stack);
throw new ExpressionException(c, expression, token, exc.getMessage(), exc.stack);
}
catch (ArithmeticException exc)
{
throw new ExpressionException(c, e, t, "Your math is wrong, "+exc.getMessage(), Collections.singletonList(this));
throw new ExpressionException(c, expression, token, "Your math is wrong, "+exc.getMessage(), Collections.singletonList(this));
}
}
@@ -41,6 +41,7 @@ public class NumericValue extends Value
{
if (value == null) return Value.NULL;
if (value.doubleValue() == value.longValue()) return new NumericValue(value.longValue());
if (value instanceof Float) return new NumericValue(0.000_001D * Math.round(1_000_000.0D*value.doubleValue()));
return new NumericValue(value.doubleValue());
}
@@ -299,23 +299,27 @@ public class ValueConversions
public static Value of(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();
if (boundingBox.maxX < boundingBox.minX || boundingBox.maxY < boundingBox.minY || boundingBox.maxZ < boundingBox.minZ) return Value.NULL;
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)
));
List<Value> pieces = new ArrayList<>();
for (StructurePiece piece : structure.getChildren())
{
BlockBox box = piece.getBoundingBox();
if (box.maxX >= box.minX && box.maxY >= box.minY && box.maxZ >= box.minZ)
{
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)
));
}
}
ret.put(new StringValue("pieces"), ListValue.wrap(pieces));
return MapValue.wrap(ret);
}