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

@@ -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.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NbtHelper;
import net.minecraft.nbt.StringTag;
import net.minecraft.nbt.Tag;
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.server.MinecraftServer;
import net.minecraft.server.command.CommandOutput;
import net.minecraft.server.command.ServerCommandSource;
import net.minecraft.server.network.ServerPlayNetworkHandler;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.sound.SoundCategory;
@@ -73,7 +77,9 @@ import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static java.lang.Math.max;
import static java.lang.Math.min;
@@ -400,13 +406,23 @@ public class Auxiliary {
Value parsed = ((NBTSerializableValue) v).toValue();
return (cc, tt) -> parsed;
}
NBTSerializableValue ret = NBTSerializableValue.parseString(v.getString());
NBTSerializableValue ret = NBTSerializableValue.parseString(v.getString(), false);
if (ret == null)
return LazyValue.NULL;
Value parsed = ret.toValue();
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) -> {
int argSize = lv.size();
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)
{
ServerPlayerEntity player = EntityValue.getPlayerByValue(s.getMinecraftServer(), res);
if (player == null) return LazyValue.NULL;
s = player.getCommandSource();
res = lv.get(1).evalValue(c);
}
@@ -455,6 +472,66 @@ public class Auxiliary {
Value finalRes = res;
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) -> {
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);
NBTSerializableValue v = (nbt instanceof NBTSerializableValue) ? (NBTSerializableValue) nbt
: NBTSerializableValue.parseString(nbt.getString());
: NBTSerializableValue.parseString(nbt.getString(), true);
hasTag = true;
tag = v.getCompoundTag();
@@ -808,9 +808,7 @@ public class WorldAccess {
tag = ((NBTSerializableValue) tagValue).getCompoundTag();
else
{
NBTSerializableValue readTag = NBTSerializableValue.parseString(tagValue.getString());
if (readTag == null)
throw new InternalExpressionException("Incorrect tag: "+tagValue.getString());
NBTSerializableValue readTag = NBTSerializableValue.parseString(tagValue.getString(), true);
tag = readTag.getCompoundTag();
}
}
@@ -36,6 +36,7 @@ import net.minecraft.advancement.Advancement;
import net.minecraft.command.CommandSource;
import net.minecraft.command.argument.AngleArgumentType;
import net.minecraft.command.argument.BlockPosArgumentType;
import net.minecraft.command.argument.BlockPredicateArgumentType;
import net.minecraft.command.argument.BlockStateArgument;
import net.minecraft.command.argument.BlockStateArgumentType;
import net.minecraft.command.argument.ColorArgumentType;
@@ -126,6 +127,9 @@ public abstract class CommandArgument
},
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)
new VanillaUnconfigurableArgument("teamcolor", ColorArgumentType::color,
(c, p) -> {
@@ -1271,7 +1271,10 @@ public class EntityValue extends Value
boolean showIcon = true;
if (lv.size() > 4)
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;
}
}
@@ -1284,7 +1287,7 @@ public class EntityValue extends Value
le.removeStatusEffect(effect);
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)->{
@@ -104,7 +104,7 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa
return id.toString();
}
public static NBTSerializableValue parseString(String nbtString)
public static NBTSerializableValue parseString(String nbtString, boolean fail)
{
Tag tag;
try
@@ -113,7 +113,8 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa
}
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);
value.nbtString = null;
@@ -331,7 +332,7 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa
return v;
if (v instanceof NullValue)
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)
{
this(boolval?1.0D:0.0D);
this(boolval?1L:0L);
}
@Override
@@ -1,9 +1,11 @@
package carpet.script.value;
import carpet.fakes.BlockPredicateInterface;
import carpet.script.exception.InternalExpressionException;
import carpet.utils.BlockInfo;
import net.minecraft.block.BlockState;
import net.minecraft.block.MapColor;
import net.minecraft.block.pattern.CachedBlockPosition;
import net.minecraft.entity.Entity;
import net.minecraft.entity.ai.brain.LookTarget;
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.structure.StructurePiece;
import net.minecraft.structure.StructureStart;
import net.minecraft.tag.TagManager;
import net.minecraft.util.Identifier;
import net.minecraft.util.StringIdentifiable;
@@ -40,6 +43,7 @@ import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.function.Predicate;
import java.util.stream.Collectors;
public class ValueConversions
@@ -379,4 +383,15 @@ public class ValueConversions
if (ret == null) return ListValue.of(Value.NULL, NumericValue.of(itemSlot));
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())
);
}
}