Merge branch 'master' into 1.17
This commit is contained in:
commit
95bac227a0
13 files changed
+177
-16
No files matched your search
@@ -1655,11 +1655,19 @@ join('-', 'foo', 'bar') => foo-bar
|
||||
Splits a string under `expr` by `delim` which can be a regular expression. If no delimiter is specified, it splits
|
||||
by characters.
|
||||
|
||||
If `expr` is a list, it will split the list into multiple sublists by the element (s) which equal `delim`, or which equal the empty string
|
||||
in case no delimiter is specified.
|
||||
|
||||
Splitting a `null` value will return an empty list.
|
||||
|
||||
<pre>
|
||||
split('foo') => [f, o, o]
|
||||
split('','foo') => [f, o, o]
|
||||
split('.','foo.bar') => []
|
||||
split('\\.','foo.bar') => [foo, bar]
|
||||
split(1,[2,5,1,2,3,1,5,6]) => [[2,5],[2,3],[5,6]]
|
||||
split(1,[1,2,3,1,4,5,1] => [[], [2,3], [4,5], []]
|
||||
split(null) => []
|
||||
</pre>
|
||||
|
||||
### `slice(expr, from, to?)`
|
||||
@@ -3138,6 +3146,10 @@ Boolean, true if the entity is silent.
|
||||
|
||||
Boolean, true if the entity is affected by gravity, like most entities are.
|
||||
|
||||
### `query(e, 'invulnerable')`
|
||||
|
||||
Boolean, true if the entity is invulnerable.
|
||||
|
||||
### `query(e, 'immune_to_fire')`
|
||||
|
||||
Boolean, true if the entity is immune to fire.
|
||||
@@ -3618,6 +3630,10 @@ Silences or unsilences the entity.
|
||||
|
||||
Toggles gravity for the entity.
|
||||
|
||||
### `modify(e, 'invulnerable', boolean)`
|
||||
|
||||
Toggles invulnerability for the entity.
|
||||
|
||||
### `modify(e, 'fire', ticks)`
|
||||
|
||||
Will set entity on fire for `ticks` ticks. Set to 0 to extinguish.
|
||||
@@ -5006,6 +5022,12 @@ Available options in the scarpet app space:
|
||||
|
||||
Scarpet related properties
|
||||
* `scarpet_version` - returns the version of the carpet your scarpet comes with.
|
||||
|
||||
## NBT Storage
|
||||
|
||||
### `nbt_storage()`, `nbt_storage(key)`, `nbt_storage(key, nbt)`
|
||||
Displays or modifies individual storage NBT tags. With no arguments, returns the list of current NBT storages. With specified `key`, returns the `nbt` associated with current `key`, or `null` if storage does not exist. With specified `key` and `nbt`, sets a new `nbt` value, returning previous value associated with the `key`.
|
||||
NOTE: This NBT storage is shared with all vanilla datapacks and scripts of the entire server and is persistent between restarts and reloads. You can also access this NBT storage with vanilla `/data <get|modify|merge> storage <key> ...` command.
|
||||
# `/script run` command
|
||||
|
||||
Primary way to input commands. The command executes in the context, position, and dimension of the executing player,
|
||||
|
||||
@@ -540,3 +540,9 @@ Available options in the scarpet app space:
|
||||
|
||||
Scarpet related properties
|
||||
* `scarpet_version` - returns the version of the carpet your scarpet comes with.
|
||||
|
||||
## NBT Storage
|
||||
|
||||
### `nbt_storage()`, `nbt_storage(key)`, `nbt_storage(key, nbt)`
|
||||
Displays or modifies individual storage NBT tags. With no arguments, returns the list of current NBT storages. With specified `key`, returns the `nbt` associated with current `key`, or `null` if storage does not exist. With specified `key` and `nbt`, sets a new `nbt` value, returning previous value associated with the `key`.
|
||||
NOTE: This NBT storage is shared with all vanilla datapacks and scripts of the entire server and is persistent between restarts and reloads. You can also access this NBT storage with vanilla `/data <get|modify|merge> storage <key> ...` command.
|
||||
@@ -160,11 +160,19 @@ join('-', 'foo', 'bar') => foo-bar
|
||||
Splits a string under `expr` by `delim` which can be a regular expression. If no delimiter is specified, it splits
|
||||
by characters.
|
||||
|
||||
If `expr` is a list, it will split the list into multiple sublists by the element (s) which equal `delim`, or which equal the empty string
|
||||
in case no delimiter is specified.
|
||||
|
||||
Splitting a `null` value will return an empty list.
|
||||
|
||||
<pre>
|
||||
split('foo') => [f, o, o]
|
||||
split('','foo') => [f, o, o]
|
||||
split('.','foo.bar') => []
|
||||
split('\\.','foo.bar') => [foo, bar]
|
||||
split(1,[2,5,1,2,3,1,5,6]) => [[2,5],[2,3],[5,6]]
|
||||
split(1,[1,2,3,1,4,5,1] => [[], [2,3], [4,5], []]
|
||||
split(null) => []
|
||||
</pre>
|
||||
|
||||
### `slice(expr, from, to?)`
|
||||
|
||||
@@ -67,6 +67,7 @@ map_colour
|
||||
material
|
||||
modify
|
||||
nbt
|
||||
nbt_storage
|
||||
neighbours
|
||||
opacity
|
||||
parse_nbt
|
||||
|
||||
@@ -86,6 +86,8 @@
|
||||
|
||||
load_app_data store_app_data read_file write_file delete_file list_files
|
||||
escape_nbt parse_nbt encode_nbt tag_matches statistic
|
||||
|
||||
nbt_storage
|
||||
</Keywords>
|
||||
<Keywords name="Keywords3">euler pi null true false</Keywords>
|
||||
<Keywords name="Keywords4">x y z p</Keywords>
|
||||
|
||||
@@ -19,6 +19,7 @@ import net.minecraft.world.World;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.Locale;
|
||||
|
||||
import static carpet.settings.RuleCategory.BUGFIX;
|
||||
@@ -642,6 +643,58 @@ public class CarpetSettings
|
||||
)
|
||||
public static int spawnChunksSize = 11;
|
||||
|
||||
public static class LightBatchValidator extends Validator<Integer> {
|
||||
public static void applyLightBatchSizes()
|
||||
{
|
||||
Iterator<ServerWorld> iterator = CarpetServer.minecraft_server.getWorlds().iterator();
|
||||
|
||||
while (iterator.hasNext())
|
||||
{
|
||||
ServerWorld serverWorld = iterator.next();
|
||||
serverWorld.getChunkManager().getLightingProvider().setTaskBatchSize(lightEngineMaxBatchSize);
|
||||
}
|
||||
}
|
||||
@Override public Integer validate(ServerCommandSource source, ParsedRule<Integer> currentRule, Integer newValue, String string) {
|
||||
if (source == null) return newValue;
|
||||
if (newValue < 0)
|
||||
{
|
||||
Messenger.m(source, "r light batch size has to be at least 0");
|
||||
return null;
|
||||
}
|
||||
if (currentRule.get().intValue() == newValue.intValue())
|
||||
{
|
||||
//must been some startup thing
|
||||
return newValue;
|
||||
}
|
||||
if (CarpetServer.minecraft_server == null) return newValue;
|
||||
|
||||
// Set the field before we apply.
|
||||
try
|
||||
{
|
||||
currentRule.field.set(null, newValue.intValue());
|
||||
}
|
||||
catch (IllegalAccessException e)
|
||||
{
|
||||
Messenger.m(source, "r Unable to access setting for "+currentRule.name);
|
||||
return null;
|
||||
}
|
||||
|
||||
applyLightBatchSizes(); // Apply new settings
|
||||
|
||||
return newValue;
|
||||
}
|
||||
}
|
||||
|
||||
@Rule(
|
||||
desc = "Changes maximum light tasks batch size",
|
||||
extra = {"Allows for a higher light suppression tolerance", "setting it to 5 - Default limit defined by the game"},
|
||||
category = {EXPERIMENTAL, OPTIMIZATION},
|
||||
strict = false,
|
||||
options = {"5", "50", "100", "200"},
|
||||
validate = LightBatchValidator.class
|
||||
)
|
||||
public static int lightEngineMaxBatchSize = 5;
|
||||
|
||||
@Rule(desc = "Coral structures will grow with bonemeal from coral plants", category = FEATURE)
|
||||
public static boolean renewableCoral = false;
|
||||
|
||||
|
||||
@@ -52,5 +52,7 @@ public abstract class MinecraftServer_coreMixin
|
||||
{
|
||||
if (CarpetSettings.spawnChunksSize != 11)
|
||||
CarpetSettings.ChangeSpawnChunksValidator.changeSpawnSize(CarpetSettings.spawnChunksSize);
|
||||
|
||||
CarpetSettings.LightBatchValidator.applyLightBatchSizes();
|
||||
}
|
||||
}
|
||||
@@ -36,12 +36,14 @@ import carpet.script.value.Value;
|
||||
import carpet.script.value.ValueConversions;
|
||||
import carpet.utils.Messenger;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.command.DataCommandStorage;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.entity.EquipmentSlot;
|
||||
import net.minecraft.entity.decoration.ArmorStandEntity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.NbtHelper;
|
||||
import net.minecraft.nbt.StringTag;
|
||||
import net.minecraft.nbt.Tag;
|
||||
@@ -86,6 +88,7 @@ import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static carpet.script.value.NBTSerializableValue.nameFromRegistryId;
|
||||
import static java.lang.Math.max;
|
||||
import static java.lang.Math.min;
|
||||
|
||||
@@ -1022,6 +1025,29 @@ public class Auxiliary {
|
||||
Value ret = new NumericValue(counts);
|
||||
return (c_, t_) -> ret;
|
||||
});
|
||||
|
||||
// nbt_storage()
|
||||
// nbt_storage(key)
|
||||
// nbt_storage(key, nbt)
|
||||
expression.addLazyFunction("nbt_storage", -1, (c, t, lv) -> {
|
||||
if (lv.size() > 2) throw new InternalExpressionException("'nbt_storage' requires 0, 1 or 2 arguments.");
|
||||
CarpetContext cc = (CarpetContext) c;
|
||||
DataCommandStorage storage = cc.s.getMinecraftServer().getDataCommandStorage();
|
||||
if (lv.size() == 0) {
|
||||
Value ret = ListValue.wrap(storage.getIds().map(i -> new StringValue(nameFromRegistryId(i))).collect(Collectors.toList()));
|
||||
return (_c, _t) -> ret;
|
||||
}
|
||||
String key = lv.get(0).evalValue(c).getString();
|
||||
CompoundTag old_nbt = storage.get(new Identifier(key));
|
||||
if (lv.size() == 2) {
|
||||
Value nbt = lv.get(1).evalValue(c);
|
||||
NBTSerializableValue new_nbt = (nbt instanceof NBTSerializableValue) ? (NBTSerializableValue) nbt
|
||||
: NBTSerializableValue.parseString(nbt.getString(), true);
|
||||
storage.set(new Identifier(key), new_nbt.getCompoundTag());
|
||||
}
|
||||
if (old_nbt == null) return LazyValue.NULL;
|
||||
return (_c, _t) -> new NBTSerializableValue(old_nbt);
|
||||
});
|
||||
}
|
||||
|
||||
private static <T> Stat<T> getStat(StatType<T> type, Identifier id)
|
||||
|
||||
@@ -14,10 +14,8 @@ import carpet.script.value.StringValue;
|
||||
import carpet.script.value.Value;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.regex.PatternSyntaxException;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class DataStructures {
|
||||
@@ -54,30 +52,23 @@ public class DataStructures {
|
||||
|
||||
expression.addFunction("split", (lv) ->
|
||||
{
|
||||
String delimiter;
|
||||
String hwat;
|
||||
Value delimiter;
|
||||
Value hwat;
|
||||
if (lv.size() == 1)
|
||||
{
|
||||
hwat = lv.get(0).getString();
|
||||
delimiter = "";
|
||||
hwat = lv.get(0);
|
||||
delimiter = StringValue.EMPTY;
|
||||
}
|
||||
else if (lv.size() == 2)
|
||||
{
|
||||
delimiter = lv.get(0).getString();
|
||||
hwat = lv.get(1).getString();
|
||||
delimiter = lv.get(0);
|
||||
hwat = lv.get(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new InternalExpressionException("'split' takes 1 or 2 arguments");
|
||||
}
|
||||
try
|
||||
{
|
||||
return ListValue.wrap(Arrays.stream(hwat.split(delimiter)).map(StringValue::new).collect(Collectors.toList()));
|
||||
}
|
||||
catch (PatternSyntaxException pse)
|
||||
{
|
||||
throw new InternalExpressionException("Incorrect pattern for 'split': "+pse.getMessage());
|
||||
}
|
||||
return hwat.split(delimiter);
|
||||
});
|
||||
|
||||
expression.addFunction("slice", (lv) ->
|
||||
|
||||
@@ -347,6 +347,24 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
|
||||
return new ListValue((Collection<? extends Value>) getItems().subList(from, to));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value split(Value delimiter) {
|
||||
ListValue result = new ListValue();
|
||||
int startIndex = 0;
|
||||
int index = 0;
|
||||
for (Value val : this.items)
|
||||
{
|
||||
index++;
|
||||
if (val.equals(delimiter))
|
||||
{
|
||||
result.items.add(ListValue.wrap(this.items.subList(startIndex, index-1)));
|
||||
startIndex = index;
|
||||
}
|
||||
}
|
||||
result.items.add(ListValue.wrap(this.items.subList(startIndex, length())));
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double readDoubleNumber()
|
||||
{
|
||||
|
||||
@@ -203,6 +203,11 @@ public class MapValue extends AbstractListValue implements ContainerValueInterfa
|
||||
throw new InternalExpressionException("Cannot slice a map value");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value split(Value delimiter) {
|
||||
throw new InternalExpressionException("Cannot split a map value");
|
||||
}
|
||||
|
||||
@Override
|
||||
public double readDoubleNumber()
|
||||
{
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package carpet.script.value;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonNull;
|
||||
import net.minecraft.nbt.StringTag;
|
||||
@@ -44,6 +46,11 @@ public class NullValue extends NumericValue // TODO check nonsingleton code
|
||||
return o instanceof NullValue ? 0 : -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value in(Value value) {
|
||||
return Value.NULL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTypeString()
|
||||
{
|
||||
@@ -63,6 +70,11 @@ public class NullValue extends NumericValue // TODO check nonsingleton code
|
||||
return StringTag.of("null");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value split(Value delimiter) {
|
||||
return ListValue.wrap(new ArrayList<Value>());
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonElement toJson()
|
||||
{
|
||||
|
||||
@@ -6,10 +6,12 @@ import com.google.gson.JsonPrimitive;
|
||||
import net.minecraft.nbt.Tag;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.regex.PatternSyntaxException;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public abstract class Value implements Comparable<Value>, Cloneable
|
||||
{
|
||||
@@ -188,6 +190,19 @@ public abstract class Value implements Comparable<Value>, Cloneable
|
||||
if (from > to) return StringValue.EMPTY;
|
||||
return new StringValue(value.substring(from, to));
|
||||
}
|
||||
|
||||
public Value split(Value delimiter)
|
||||
{
|
||||
try
|
||||
{
|
||||
return ListValue.wrap(Arrays.stream(getString().split(delimiter.getString())).map(StringValue::new).collect(Collectors.toList()));
|
||||
}
|
||||
catch (PatternSyntaxException pse)
|
||||
{
|
||||
throw new InternalExpressionException("Incorrect pattern for 'split': "+pse.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public double readDoubleNumber()
|
||||
{
|
||||
String s = getString();
|
||||
|
||||
Reference in new issue
Block a user