Merge branch 'master' into 1.17

# Conflicts:
#	gradle.properties
#	src/main/java/carpet/script/value/ValueConversions.java
This commit is contained in:
gnembon committed 2020-11-29 01:23:22 -04:00
commit 973dd29739
17 files changed
+293 -21

No files matched your search

+22 -4
View File
@@ -3429,10 +3429,10 @@ If called with `false` value, it will disable AI in the mob. `true` will enable
Sets if the entity obeys any collisions, including collisions with the terrain and basic physics. Not affecting Sets if the entity obeys any collisions, including collisions with the terrain and basic physics. Not affecting
players, since they are controlled client side. players, since they are controlled client side.
### `modify(e, 'effect', name?, duration?, amplifier?, show_particles?, show_icon?)` ### `modify(e, 'effect', name?, duration?, amplifier?, show_particles?, show_icon?, ambient?)`
Applies status effect to the living entity. Takes several optional parameters, which default to `0`, `true` Applies status effect to the living entity. Takes several optional parameters, which default to `0`, `true`,
and `true`. If no duration is specified, or if it's null or 0, the effect is removed. If name is not specified, `true` and `false`. If no duration is specified, or if it's null or 0, the effect is removed. If name is not specified,
it clears all effects. it clears all effects.
### `modify(e, 'home', null), modify(e, 'home', block, distance?), modify(e, 'home', x, y, z, distance?)` ### `modify(e, 'home', null), modify(e, 'home', block, distance?), modify(e, 'home', x, y, z, distance?)`
@@ -4432,6 +4432,12 @@ Consult section about container operations in `Expression` to learn about possib
Excapes all the special characters in the string or nbt tag and returns a string that can be stored in nbt directly Excapes all the special characters in the string or nbt tag and returns a string that can be stored in nbt directly
as a string value. as a string value.
### `tag_matches(daddy_tag, baby_tag, match_lists?)`
Utility returning `true` if `baby_tag` is fully contained in `daddy_tag`. Anything matches `null` baby tag, and
Nothing is contained in a `null` daddy tag. If `match_lists` is specified and `false`, content of nested lists is ignored.
Default behaviour is to match them.
### `parse_nbt(tag)` ### `parse_nbt(tag)`
Converts NBT tag to a scarpet value, which you can navigate through much better. Converts NBT tag to a scarpet value, which you can navigate through much better.
@@ -4514,6 +4520,18 @@ Example usages:
// not a problem in apps // not a problem in apps
</pre> </pre>
### `display_title(players, type, title?, fadeInTicks?, stayTicks?, fadeOutTicks),`
Sends the player (or players if `players` is a list) a title of a specific type, with optionally some times.
* `players` is either an online player or a list of players. When sending a single player, it will throw if the player is invalid or offline.
* `type` is either `'title'`, `'subtitle'`, `actionbar` or `clear`.
Note: `subtitle` will only be displayed if there is a title being displayed (can be an empty one)
* `title` is what title to send to the player. It is required except for `clear` type. Can be a text formatted using `format()`
* `...Ticks` are the number of ticks the title will stay in that state.
If not specified, it will use current defaults (those defaults may have changed from a previous `/title times` execution).
Executing with those will set the times to the specified ones.
Note that `actionbar` type doesn't support changing times (vanilla bug, see [MC-106167](https://bugs.mojang.com/browse/MC-106167)).
### `logger(msg), logger(type, msg)` ### `logger(msg), logger(type, msg)`
Prints the message to system logs, and not to chat. By default prints an info, unless you specify otherwise in the `type` parameter. Prints the message to system logs, and not to chat. By default prints an info, unless you specify otherwise in the `type` parameter.
@@ -4738,7 +4756,7 @@ Available options in the scarpet app space:
* `world_seed` - a numeric seed of the world * `world_seed` - a numeric seed of the world
* `world_path` - full path to the world saves folder * `world_path` - full path to the world saves folder
* `world_folder` - name of the direct folder in the saves that holds world files * `world_folder` - name of the direct folder in the saves that holds world files
* `world_carpet_rules` - returns all Carpet rules in a map form (`rule`->`value`). Includes rules from extensions with their namespace (`namespace:rule`->`value`). You can later listen to rule changes with the `on_carpet_rule_change(rule, newValue)` event. * `world_carpet_rules` - returns all Carpet rules in a map form (`rule`->`value`). Note that the values are always returned as strings, so you can't do boolean comparisons directly. Includes rules from extensions with their namespace (`namespace:rule`->`value`). You can later listen to rule changes with the `on_carpet_rule_changes(rule, newValue)` event.
Relevant gameplay related properties Relevant gameplay related properties
* `game_difficulty` - current difficulty of the game: `'peacefu'`, `'easy'`, `'normal'`, or `'hard'` * `game_difficulty` - current difficulty of the game: `'peacefu'`, `'easy'`, `'normal'`, or `'hard'`
+19 -1
View File
@@ -163,6 +163,12 @@ Consult section about container operations in `Expression` to learn about possib
Excapes all the special characters in the string or nbt tag and returns a string that can be stored in nbt directly Excapes all the special characters in the string or nbt tag and returns a string that can be stored in nbt directly
as a string value. as a string value.
### `tag_matches(daddy_tag, baby_tag, match_lists?)`
Utility returning `true` if `baby_tag` is fully contained in `daddy_tag`. Anything matches `null` baby tag, and
Nothing is contained in a `null` daddy tag. If `match_lists` is specified and `false`, content of nested lists is ignored.
Default behaviour is to match them.
### `parse_nbt(tag)` ### `parse_nbt(tag)`
Converts NBT tag to a scarpet value, which you can navigate through much better. Converts NBT tag to a scarpet value, which you can navigate through much better.
@@ -245,6 +251,18 @@ Example usages:
// not a problem in apps // not a problem in apps
</pre> </pre>
### `display_title(players, type, title?, fadeInTicks?, stayTicks?, fadeOutTicks),`
Sends the player (or players if `players` is a list) a title of a specific type, with optionally some times.
* `players` is either an online player or a list of players. When sending a single player, it will throw if the player is invalid or offline.
* `type` is either `'title'`, `'subtitle'`, `actionbar` or `clear`.
Note: `subtitle` will only be displayed if there is a title being displayed (can be an empty one)
* `title` is what title to send to the player. It is required except for `clear` type. Can be a text formatted using `format()`
* `...Ticks` are the number of ticks the title will stay in that state.
If not specified, it will use current defaults (those defaults may have changed from a previous `/title times` execution).
Executing with those will set the times to the specified ones.
Note that `actionbar` type doesn't support changing times (vanilla bug, see [MC-106167](https://bugs.mojang.com/browse/MC-106167)).
### `logger(msg), logger(type, msg)` ### `logger(msg), logger(type, msg)`
Prints the message to system logs, and not to chat. By default prints an info, unless you specify otherwise in the `type` parameter. Prints the message to system logs, and not to chat. By default prints an info, unless you specify otherwise in the `type` parameter.
@@ -469,7 +487,7 @@ Available options in the scarpet app space:
* `world_seed` - a numeric seed of the world * `world_seed` - a numeric seed of the world
* `world_path` - full path to the world saves folder * `world_path` - full path to the world saves folder
* `world_folder` - name of the direct folder in the saves that holds world files * `world_folder` - name of the direct folder in the saves that holds world files
* `world_carpet_rules` - returns all Carpet rules in a map form (`rule`->`value`). Includes rules from extensions with their namespace (`namespace:rule`->`value`). You can later listen to rule changes with the `on_carpet_rule_change(rule, newValue)` event. * `world_carpet_rules` - returns all Carpet rules in a map form (`rule`->`value`). Note that the values are always returned as strings, so you can't do boolean comparisons directly. Includes rules from extensions with their namespace (`namespace:rule`->`value`). You can later listen to rule changes with the `on_carpet_rule_changes(rule, newValue)` event.
Relevant gameplay related properties Relevant gameplay related properties
* `game_difficulty` - current difficulty of the game: `'peacefu'`, `'easy'`, `'normal'`, or `'hard'` * `game_difficulty` - current difficulty of the game: `'peacefu'`, `'easy'`, `'normal'`, or `'hard'`
+3 -3
View File
@@ -641,10 +641,10 @@ If called with `false` value, it will disable AI in the mob. `true` will enable
Sets if the entity obeys any collisions, including collisions with the terrain and basic physics. Not affecting Sets if the entity obeys any collisions, including collisions with the terrain and basic physics. Not affecting
players, since they are controlled client side. players, since they are controlled client side.
### `modify(e, 'effect', name?, duration?, amplifier?, show_particles?, show_icon?)` ### `modify(e, 'effect', name?, duration?, amplifier?, show_particles?, show_icon?, ambient?)`
Applies status effect to the living entity. Takes several optional parameters, which default to `0`, `true` Applies status effect to the living entity. Takes several optional parameters, which default to `0`, `true`,
and `true`. If no duration is specified, or if it's null or 0, the effect is removed. If name is not specified, `true` and `false`. If no duration is specified, or if it's null or 0, the effect is removed. If name is not specified,
it clears all effects. it clears all effects.
### `modify(e, 'home', null), modify(e, 'home', block, distance?), modify(e, 'home', x, y, z, distance?)` ### `modify(e, 'home', null), modify(e, 'home', block, distance?), modify(e, 'home', x, y, z, distance?)`
+8 -1
View File
@@ -19,11 +19,14 @@ create_marker
current_dimension current_dimension
custom_dimension custom_dimension
day_time day_time
delete_file
destroy destroy
diamond diamond
display_title
draw_shape draw_shape
drop_item drop_item
emitted_light emitted_light
encode_nbt
entity_area entity_area
entity_event entity_event
entity_id entity_id
@@ -61,6 +64,7 @@ modify
nbt nbt
neighbours neighbours
opacity opacity
parse_nbt
particle particle
particle_line particle_line
particle_rect particle_rect
@@ -86,11 +90,13 @@ scoreboard
scoreboard_add scoreboard_add
scoreboard_remove scoreboard_remove
scoreboard_display scoreboard_display
tag_matches
team_add team_add
team_list team_list
team_remove team_remove
team_leave team_leave
team_property team_property
read_file
see_sky see_sky
set set
set_biome set_biome
@@ -118,4 +124,5 @@ update
view_distance view_distance
volume volume
without_updates without_updates
world_time world_time
write_file
@@ -58,6 +58,8 @@
structure_eligibility structures structure_references set_structure reset_chunk reload_chunk custom_dimension structure_eligibility structures structure_references set_structure reset_chunk reload_chunk custom_dimension
add_chunk_ticket add_chunk_ticket
display_title
scoreboard scoreboard_add scoreboard_remove scoreboard_display scoreboard scoreboard_add scoreboard_remove scoreboard_display
team_add team_list team_remove team_leave team_property team_add team_list team_remove team_leave team_property
@@ -78,7 +80,8 @@
plop harvest destroy schedule nbt draw_shape create_marker remove_all_markers plop harvest destroy schedule nbt draw_shape create_marker remove_all_markers
load_app_data store_app_data escape_nbt statistic load_app_data store_app_data read_file write_file delete_file
escape_nbt parse_nbt encode_nbt tag_matches statistic
</Keywords> </Keywords>
<Keywords name="Keywords3">euler pi null true false</Keywords> <Keywords name="Keywords3">euler pi null true false</Keywords>
<Keywords name="Keywords4">x y z p</Keywords> <Keywords name="Keywords4">x y z p</Keywords>
@@ -0,0 +1,17 @@
package carpet.fakes;
import carpet.script.value.Value;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.tag.Tag;
import java.util.Map;
public interface BlockPredicateInterface
{
BlockState getCMBlockState();
Tag<Block> getCMBlockTag();
Map<Value, Value> getCMProperties();
CompoundTag getCMDataTag();
}
@@ -0,0 +1,57 @@
package carpet.mixins;
import carpet.fakes.BlockPredicateInterface;
import carpet.script.value.StringValue;
import carpet.script.value.Value;
import carpet.script.value.ValueConversions;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.state.property.Property;
import net.minecraft.tag.Tag;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
@Mixin(targets = "net.minecraft.command.argument.BlockPredicateArgumentType$StatePredicate")
public class StatePredicate_scarpetMixin implements BlockPredicateInterface
{
@Shadow @Final private BlockState state;
@Shadow @Final /*@Nullable*/ private CompoundTag nbt;
@Shadow @Final private Set<Property<?>> properties;
@Override
public BlockState getCMBlockState()
{
return state;
}
@Override
public Tag<Block> getCMBlockTag()
{
return null;
}
@Override
public Map<Value, Value> getCMProperties()
{
return properties.stream().collect(Collectors.toMap(
p -> StringValue.of(p.getName()),
p -> ValueConversions.fromProperty(state, p),
(a, b) -> b
));
}
@Override
public CompoundTag getCMDataTag()
{
return nbt;
}
}
@@ -0,0 +1,52 @@
package carpet.mixins;
import carpet.fakes.BlockPredicateInterface;
import carpet.script.value.StringValue;
import carpet.script.value.Value;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.tag.Tag;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import java.util.Map;
import java.util.stream.Collectors;
@Mixin(targets = "net.minecraft.command.argument.BlockPredicateArgumentType$TagPredicate")
public class TagPredicate_scarpetMixin implements BlockPredicateInterface
{
@Shadow @Final private Tag<Block> tag;
@Shadow @Final private Map<String, String> properties;
@Shadow @Final /*@Nullable*/ private CompoundTag nbt;
@Override
public BlockState getCMBlockState()
{
return null;
}
@Override
public Tag<Block> getCMBlockTag()
{
return tag;
}
@Override
public Map<Value, Value> getCMProperties()
{
return properties.entrySet().stream().collect(Collectors.toMap(
e -> new StringValue(e.getKey()),
e -> new StringValue(e.getValue())
));
}
@Override
public CompoundTag getCMDataTag()
{
return nbt;
}
}
+78 -1
View File
@@ -40,13 +40,17 @@ import net.minecraft.entity.EquipmentSlot;
import net.minecraft.entity.decoration.ArmorStandEntity; import net.minecraft.entity.decoration.ArmorStandEntity;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NbtHelper;
import net.minecraft.nbt.StringTag; import net.minecraft.nbt.StringTag;
import net.minecraft.nbt.Tag; import net.minecraft.nbt.Tag;
import net.minecraft.network.packet.s2c.play.PlaySoundIdS2CPacket; import net.minecraft.network.packet.s2c.play.PlaySoundIdS2CPacket;
import net.minecraft.network.packet.s2c.play.TitleS2CPacket;
import net.minecraft.network.packet.s2c.play.TitleS2CPacket.Action;
import net.minecraft.particle.ParticleEffect; import net.minecraft.particle.ParticleEffect;
import net.minecraft.server.MinecraftServer; import net.minecraft.server.MinecraftServer;
import net.minecraft.server.command.CommandOutput; import net.minecraft.server.command.CommandOutput;
import net.minecraft.server.command.ServerCommandSource; import net.minecraft.server.command.ServerCommandSource;
import net.minecraft.server.network.ServerPlayNetworkHandler;
import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.server.world.ServerWorld; import net.minecraft.server.world.ServerWorld;
import net.minecraft.sound.SoundCategory; import net.minecraft.sound.SoundCategory;
@@ -73,7 +77,9 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream;
import static java.lang.Math.max; import static java.lang.Math.max;
import static java.lang.Math.min; import static java.lang.Math.min;
@@ -400,13 +406,23 @@ public class Auxiliary {
Value parsed = ((NBTSerializableValue) v).toValue(); Value parsed = ((NBTSerializableValue) v).toValue();
return (cc, tt) -> parsed; return (cc, tt) -> parsed;
} }
NBTSerializableValue ret = NBTSerializableValue.parseString(v.getString()); NBTSerializableValue ret = NBTSerializableValue.parseString(v.getString(), false);
if (ret == null) if (ret == null)
return LazyValue.NULL; return LazyValue.NULL;
Value parsed = ret.toValue(); Value parsed = ret.toValue();
return (cc, tt) -> parsed; return (cc, tt) -> parsed;
}); });
expression.addFunction("tag_matches", (lv) -> {
int numParam = lv.size();
if (numParam != 2 && numParam != 3) throw new InternalExpressionException("'tag_matches' requires 2 or 3 arguments");
if (lv.get(1).isNull()) return Value.TRUE;
if (lv.get(0).isNull()) return Value.FALSE;
Tag source = ((NBTSerializableValue)(NBTSerializableValue.fromValue(lv.get(0)))).getTag();
Tag match = ((NBTSerializableValue)(NBTSerializableValue.fromValue(lv.get(1)))).getTag();
return new NumericValue(NbtHelper.matches(match, source, numParam == 2 || lv.get(2).getBoolean()));
});
expression.addLazyFunction("encode_nbt", -1, (c, t, lv) -> { expression.addLazyFunction("encode_nbt", -1, (c, t, lv) -> {
int argSize = lv.size(); int argSize = lv.size();
if (argSize==0 || argSize > 2) throw new InternalExpressionException("'encode_nbt' requires 1 or 2 parameters"); if (argSize==0 || argSize > 2) throw new InternalExpressionException("'encode_nbt' requires 1 or 2 parameters");
@@ -434,6 +450,7 @@ public class Auxiliary {
if (lv.size() == 2) if (lv.size() == 2)
{ {
ServerPlayerEntity player = EntityValue.getPlayerByValue(s.getMinecraftServer(), res); ServerPlayerEntity player = EntityValue.getPlayerByValue(s.getMinecraftServer(), res);
if (player == null) return LazyValue.NULL;
s = player.getCommandSource(); s = player.getCommandSource();
res = lv.get(1).evalValue(c); res = lv.get(1).evalValue(c);
} }
@@ -455,6 +472,66 @@ public class Auxiliary {
Value finalRes = res; Value finalRes = res;
return (_c, _t) -> finalRes; // pass through for variables return (_c, _t) -> finalRes; // pass through for variables
}); });
expression.addLazyFunction("display_title", -1, (c, t, lv) -> {
if (lv.size() < 2) throw new InternalExpressionException("'display_title' needs at least a target, type and message, and optionally times");
Value pVal = lv.get(0).evalValue(c);
if (!(pVal instanceof ListValue)) pVal = ListValue.of(pVal);
MinecraftServer server = ((CarpetContext)c).s.getMinecraftServer();
Stream<ServerPlayerEntity> targets = ((ListValue) pVal).getItems().stream().map(v ->
{
ServerPlayerEntity player = EntityValue.getPlayerByValue(server, v);
if (player == null) throw new InternalExpressionException("'display_title' requires a valid online player or a list of players as first argument. "+v.getString()+" is not a player.");
return player;
});
TitleS2CPacket.Action action;
switch (lv.get(1).evalValue(c).getString().toLowerCase(Locale.ROOT))
{
case "title":
action = Action.TITLE;
break;
case "subtitle":
action = Action.SUBTITLE;
break;
case "actionbar":
action = Action.ACTIONBAR;
break;
case "clear":
action = Action.CLEAR;
break;
default:
throw new InternalExpressionException("'display_title' requires 'title', 'subtitle', 'actionbar' or 'clear' as second argument");
}
if (action != Action.CLEAR && lv.size() < 3)
throw new InternalExpressionException("Third argument of 'display_title' must be present except for 'clear' type");
Text title = null;
if (lv.size() > 2)
{
pVal = lv.get(2).evalValue(c);
if (pVal instanceof FormattedTextValue)
title = ((FormattedTextValue) pVal).getText();
else
title = Text.of(pVal.getString());
}
TitleS2CPacket timesPacket;
if (lv.size() > 3)
{
int in = NumericValue.asNumber(lv.get(3).evalValue(c),"fade in for display_title" ).getInt();
int stay = NumericValue.asNumber(lv.get(4).evalValue(c),"stay for display_title" ).getInt();
int out = NumericValue.asNumber(lv.get(5).evalValue(c),"fade out for display_title" ).getInt();
timesPacket = new TitleS2CPacket(Action.TIMES, null, in, stay, out);
}
else timesPacket = null;
TitleS2CPacket packet = new TitleS2CPacket(action, title);
AtomicInteger total = new AtomicInteger(0);
targets.forEach(p -> {
if (timesPacket != null) p.networkHandler.sendPacket(timesPacket);
p.networkHandler.sendPacket(packet);
total.getAndIncrement();
});
Value ret = NumericValue.of(total.get());
return (cc, tt) -> ret;
});
expression.addLazyFunction("format", -1, (c, t, lv) -> { expression.addLazyFunction("format", -1, (c, t, lv) -> {
if (lv.size() == 0 ) throw new InternalExpressionException("'format' requires at least one component"); if (lv.size() == 0 ) throw new InternalExpressionException("'format' requires at least one component");
@@ -137,7 +137,7 @@ public class Entities {
{ {
Value nbt = lv.get(position.offset).evalValue(c); Value nbt = lv.get(position.offset).evalValue(c);
NBTSerializableValue v = (nbt instanceof NBTSerializableValue) ? (NBTSerializableValue) nbt NBTSerializableValue v = (nbt instanceof NBTSerializableValue) ? (NBTSerializableValue) nbt
: NBTSerializableValue.parseString(nbt.getString()); : NBTSerializableValue.parseString(nbt.getString(), true);
hasTag = true; hasTag = true;
tag = v.getCompoundTag(); tag = v.getCompoundTag();
@@ -808,9 +808,7 @@ public class WorldAccess {
tag = ((NBTSerializableValue) tagValue).getCompoundTag(); tag = ((NBTSerializableValue) tagValue).getCompoundTag();
else else
{ {
NBTSerializableValue readTag = NBTSerializableValue.parseString(tagValue.getString()); NBTSerializableValue readTag = NBTSerializableValue.parseString(tagValue.getString(), true);
if (readTag == null)
throw new InternalExpressionException("Incorrect tag: "+tagValue.getString());
tag = readTag.getCompoundTag(); tag = readTag.getCompoundTag();
} }
} }
@@ -36,6 +36,7 @@ import net.minecraft.advancement.Advancement;
import net.minecraft.command.CommandSource; import net.minecraft.command.CommandSource;
import net.minecraft.command.argument.AngleArgumentType; import net.minecraft.command.argument.AngleArgumentType;
import net.minecraft.command.argument.BlockPosArgumentType; import net.minecraft.command.argument.BlockPosArgumentType;
import net.minecraft.command.argument.BlockPredicateArgumentType;
import net.minecraft.command.argument.BlockStateArgument; import net.minecraft.command.argument.BlockStateArgument;
import net.minecraft.command.argument.BlockStateArgumentType; import net.minecraft.command.argument.BlockStateArgumentType;
import net.minecraft.command.argument.ColorArgumentType; import net.minecraft.command.argument.ColorArgumentType;
@@ -126,6 +127,9 @@ public abstract class CommandArgument
}, },
false false
), ),
new VanillaUnconfigurableArgument( "blockpredicate", BlockPredicateArgumentType::blockPredicate,
(c, p) -> ValueConversions.ofBlockPredicate(c.getSource().getMinecraftServer().getTagManager(), BlockPredicateArgumentType.getBlockPredicate(c, p)), false
),
// block_predicate todo - not sure about the returned format. Needs to match block tags used in the API (future) // block_predicate todo - not sure about the returned format. Needs to match block tags used in the API (future)
new VanillaUnconfigurableArgument("teamcolor", ColorArgumentType::color, new VanillaUnconfigurableArgument("teamcolor", ColorArgumentType::color,
(c, p) -> { (c, p) -> {
@@ -1271,7 +1271,10 @@ public class EntityValue extends Value
boolean showIcon = true; boolean showIcon = true;
if (lv.size() > 4) if (lv.size() > 4)
showIcon = lv.get(4).getBoolean(); showIcon = lv.get(4).getBoolean();
le.addStatusEffect(new StatusEffectInstance(effect, duration, amplifier, showParticles, showIcon)); boolean ambient = false;
if (lv.size() > 5)
showIcon = lv.get(5).getBoolean();
le.addStatusEffect(new StatusEffectInstance(effect, duration, amplifier, ambient, showParticles, showIcon));
return; return;
} }
} }
@@ -1284,7 +1287,7 @@ public class EntityValue extends Value
le.removeStatusEffect(effect); le.removeStatusEffect(effect);
return; return;
} }
throw new InternalExpressionException("'effect' needs either no arguments (clear) or effect name, duration, and optional amplifier, show particles and show icon"); throw new InternalExpressionException("'effect' needs either no arguments (clear) or effect name, duration, and optional amplifier, show particles, show icon and ambient");
}); });
put("gamemode", (e,v)->{ put("gamemode", (e,v)->{
@@ -104,7 +104,7 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa
return id.toString(); return id.toString();
} }
public static NBTSerializableValue parseString(String nbtString) public static NBTSerializableValue parseString(String nbtString, boolean fail)
{ {
Tag tag; Tag tag;
try try
@@ -113,7 +113,8 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa
} }
catch (CommandSyntaxException e) catch (CommandSyntaxException e)
{ {
throw new InternalExpressionException("Incorrect NBT tag: nbtString"); if (fail) throw new InternalExpressionException("Incorrect NBT tag: "+ nbtString);
return null;
} }
NBTSerializableValue value = new NBTSerializableValue(tag); NBTSerializableValue value = new NBTSerializableValue(tag);
value.nbtString = null; value.nbtString = null;
@@ -331,7 +332,7 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa
return v; return v;
if (v instanceof NullValue) if (v instanceof NullValue)
return Value.NULL; return Value.NULL;
return NBTSerializableValue.parseString(v.getString()); return NBTSerializableValue.parseString(v.getString(), true);
} }
@@ -227,7 +227,7 @@ public class NumericValue extends Value
} }
public NumericValue(boolean boolval) public NumericValue(boolean boolval)
{ {
this(boolval?1.0D:0.0D); this(boolval?1L:0L);
} }
@Override @Override
@@ -1,9 +1,11 @@
package carpet.script.value; package carpet.script.value;
import carpet.fakes.BlockPredicateInterface;
import carpet.script.exception.InternalExpressionException; import carpet.script.exception.InternalExpressionException;
import carpet.utils.BlockInfo; import carpet.utils.BlockInfo;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.block.MapColor; import net.minecraft.block.MapColor;
import net.minecraft.block.pattern.CachedBlockPosition;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.ai.brain.LookTarget; import net.minecraft.entity.ai.brain.LookTarget;
import net.minecraft.entity.ai.brain.WalkTarget; import net.minecraft.entity.ai.brain.WalkTarget;
@@ -21,6 +23,7 @@ import net.minecraft.server.world.ServerWorld;
import net.minecraft.state.property.Property; import net.minecraft.state.property.Property;
import net.minecraft.structure.StructurePiece; import net.minecraft.structure.StructurePiece;
import net.minecraft.structure.StructureStart; import net.minecraft.structure.StructureStart;
import net.minecraft.tag.TagManager;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import net.minecraft.util.StringIdentifiable; import net.minecraft.util.StringIdentifiable;
@@ -40,6 +43,7 @@ import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
import java.util.function.Predicate;
import java.util.stream.Collectors; import java.util.stream.Collectors;
public class ValueConversions public class ValueConversions
@@ -379,4 +383,15 @@ public class ValueConversions
if (ret == null) return ListValue.of(Value.NULL, NumericValue.of(itemSlot)); if (ret == null) return ListValue.of(Value.NULL, NumericValue.of(itemSlot));
return ret; return ret;
} }
public static Value ofBlockPredicate(TagManager tagManager, Predicate<CachedBlockPosition> blockPredicate)
{
BlockPredicateInterface predicateData = (BlockPredicateInterface) blockPredicate;
return ListValue.of(
predicateData.getCMBlockState()==null?Value.NULL:of(Registry.BLOCK.getId(predicateData.getCMBlockState().getBlock())),
predicateData.getCMBlockTag()==null?Value.NULL:of(tagManager.getBlocks().getTagId(predicateData.getCMBlockTag())),
MapValue.wrap(predicateData.getCMProperties()),
predicateData.getCMDataTag() == null?Value.NULL:new NBTSerializableValue(predicateData.getCMDataTag())
);
}
} }
+2
View File
@@ -176,6 +176,8 @@
"RecipeManager_scarpetMixin", "RecipeManager_scarpetMixin",
"Ingredient_scarpetMixin", "Ingredient_scarpetMixin",
"BlockStateArgument_scarpetMixin", "BlockStateArgument_scarpetMixin",
"StatePredicate_scarpetMixin",
"TagPredicate_scarpetMixin",
"HorseBaseEntity_scarpetMixin", "HorseBaseEntity_scarpetMixin",
"PillagerEntity_scarpetMixin", "PillagerEntity_scarpetMixin",