Merge branch 'master' into future

# Conflicts:
#	gradle.properties
#	src/main/java/carpet/script/annotation/AnnotationParser.java
#	src/main/java/carpet/script/utils/BiomeInfo.java
#	src/main/resources/fabric.mod.json
This commit is contained in:
gnembon committed 2022-01-11 23:44:52 +01:00
commit 529a5b358d
38 files changed
+247 -381

No files matched your search

@@ -299,6 +299,9 @@ public class PlayerCommand
{
// Force override flying to true for spectator players, or they will fell out of the world.
flying = true;
} else if(mode.isSurvivalLike()){
// Force override flying to false for survival-like players, or they will fly too
flying = false;
}
String playerName = StringArgumentType.getString(context, "player");
if (playerName.length()>maxPlayerLength(source.getServer()))
@@ -51,10 +51,10 @@ public class TickCommand
then(literal("deep").executes( (c)-> setFreeze(c.getSource(), true, true)))).
then(literal("off").executes( (c) -> setFreeze(c.getSource(), false, false)))).
then(literal("step").
executes((c) -> step(1)).
executes((c) -> step(c.getSource(), 1)).
then(argument("ticks", integer(1,72000)).
suggests( (c, b) -> suggestMatching(new String[]{"20"},b)).
executes((c) -> step(getInteger(c,"ticks"))))).
executes((c) -> step(c.getSource(), getInteger(c,"ticks"))))).
then(literal("superHot").executes( (c)-> toggleSuperHot(c.getSource()))).
then(literal("health").
executes( (c) -> healthReport(c.getSource(), 100)).
@@ -130,9 +130,10 @@ public class TickCommand
return setFreeze(source, isDeep, !TickSpeed.isPaused());
}
private static int step(int advance)
private static int step(ServerCommandSource source, int advance)
{
TickSpeed.add_ticks_to_run_in_pause(advance);
Messenger.m(source, "gi Stepping " + advance + " tick" + (advance != 1 ? "s" : ""));
return 1;
}
@@ -1,12 +0,0 @@
package carpet.fakes;
import java.util.Optional;
public interface BiomeEffectsInterface
{
int getCMFogColor();
Optional<Integer> getCMFoliageColor();
int getCMSkyColor();
int getCMWaterColor();
int getCMWaterFogColor();
}
@@ -1,12 +0,0 @@
package carpet.fakes;
import net.minecraft.entity.ai.brain.Memory;
import net.minecraft.entity.ai.brain.MemoryModuleType;
import java.util.Map;
import java.util.Optional;
public interface BrainInterface
{
Map<MemoryModuleType<?>, Optional<? extends Memory<?>>> getMobMemories();
}
@@ -2,6 +2,5 @@ package carpet.fakes;
public interface ItemEntityInterface
{
int getAgeCM();
int getPickupDelayCM();
}
@@ -1,6 +0,0 @@
package carpet.fakes;
public interface MemoryInterface
{
long getScarpetExpiry();
}
@@ -1,53 +0,0 @@
package carpet.mixins;
import carpet.fakes.BiomeEffectsInterface;
import net.minecraft.world.biome.BiomeEffects;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import java.util.Optional;
@Mixin(BiomeEffects.class)
public class BiomeEffects_scarpetMixin implements BiomeEffectsInterface
{
@Shadow @Final private int fogColor;
@Shadow @Final private Optional<Integer> foliageColor;
@Shadow @Final private int skyColor;
@Shadow @Final private int waterColor;
@Shadow @Final private int waterFogColor;
@Override
public int getCMFogColor()
{
return fogColor;
}
@Override
public Optional<Integer> getCMFoliageColor()
{
return foliageColor;
}
@Override
public int getCMSkyColor()
{
return skyColor;
}
@Override
public int getCMWaterColor()
{
return waterColor;
}
@Override
public int getCMWaterFogColor()
{
return waterFogColor;
}
}
@@ -1,25 +0,0 @@
package carpet.mixins;
import carpet.fakes.BrainInterface;
import net.minecraft.entity.ai.brain.Brain;
import net.minecraft.entity.ai.brain.Memory;
import net.minecraft.entity.ai.brain.MemoryModuleType;
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.Optional;
@Mixin(Brain.class)
public class Brain_Mixin implements BrainInterface
{
@Shadow @Final private Map<MemoryModuleType<?>, Optional<? extends Memory<?>>> memories;
@Override
public Map<MemoryModuleType<?>, Optional<? extends Memory<?>>> getMobMemories()
{
return memories;
}
}
@@ -42,11 +42,6 @@ public abstract class ItemEntityMixin extends Entity implements ItemEntityInterf
}
}
@Override
public int getAgeCM() {
return this.itemAge;
}
@Override
public int getPickupDelayCM() {
return this.pickupDelay;
@@ -105,7 +100,7 @@ public abstract class ItemEntityMixin extends Entity implements ItemEntityInterf
self.setStack(selfStack);
this.pickupDelay = Math.max(((ItemEntityInterface)other).getPickupDelayCM(), this.pickupDelay);
this.itemAge = Math.min(((ItemEntityInterface)other).getAgeCM(), this.itemAge);
this.itemAge = Math.min(other.getItemAge(), this.itemAge);
otherStack.decrement(amount);
if (otherStack.isEmpty())
@@ -1,18 +0,0 @@
package carpet.mixins;
import carpet.fakes.MemoryInterface;
import net.minecraft.entity.ai.brain.Memory;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
@Mixin(Memory.class)
public class Memory_scarpetMixin implements MemoryInterface
{
@Shadow private long expiry;
@Override
public long getScarpetExpiry()
{
return expiry;
}
}
@@ -1,7 +1,5 @@
package carpet.mixins;
import carpet.fakes.BrainInterface;
import carpet.fakes.MemoryInterface;
import carpet.helpers.ParticleDisplay;
import carpet.utils.Messenger;
import carpet.utils.MobAI;
@@ -65,14 +63,14 @@ public abstract class VillagerEntity_aiMixin extends MerchantEntity
if (MobAI.isTracking(this, MobAI.TrackingType.IRON_GOLEM_SPAWNING))
{
long time;
Optional<? extends Memory<?>> last_seen = ((BrainInterface)this.brain).getMobMemories().get(MemoryModuleType.GOLEM_DETECTED_RECENTLY);
Optional<? extends Memory<?>> last_seen = this.brain.getMemories().get(MemoryModuleType.GOLEM_DETECTED_RECENTLY);
if (!last_seen.isPresent())
{
time = 0;
}
else
{
time = ((MemoryInterface)last_seen.get()).getScarpetExpiry();
time = last_seen.get().getExpiry();
}
boolean recentlySeen = time > 0;
Optional<Long> optional_11 = this.brain.getOptionalMemory(MemoryModuleType.LAST_SLEPT);
@@ -91,7 +91,7 @@ public class CarpetExpression
public Value scriptRunCommand(ScriptHost host, BlockPos pos)
{
if (CarpetServer.scriptServer.stopAll)
throw new CarpetExpressionException("SCRIPTING PAUSED", null);
throw new CarpetExpressionException("SCRIPTING PAUSED (unpause with /script resume)", null);
try
{
Context context = new CarpetContext(host, source, origin).
@@ -13,6 +13,7 @@ import carpet.script.exception.ExpressionException;
import carpet.script.exception.IntegrityException;
import carpet.script.exception.InternalExpressionException;
import carpet.script.exception.InvalidCallbackException;
import carpet.script.exception.LoadException;
import carpet.script.utils.AppStoreManager;
import carpet.script.value.EntityValue;
import carpet.script.value.FunctionValue;
@@ -37,6 +38,7 @@ import net.fabricmc.loader.api.ModContainer;
import net.fabricmc.loader.api.SemanticVersion;
import net.fabricmc.loader.api.Version;
import net.fabricmc.loader.api.VersionParsingException;
import net.fabricmc.loader.api.metadata.version.VersionPredicate;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityType;
import net.minecraft.nbt.NbtElement;
@@ -60,7 +62,6 @@ import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;
import java.util.function.BiPredicate;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.stream.Collectors;
@@ -119,8 +120,7 @@ public class CarpetScriptHost extends ScriptHost
String code = module.getCode();
if (code == null)
{
Messenger.m(source, "r Unable to load "+module.getName()+" app - code not found");
return null;
throw new LoadException("Code not found");
}
host.setChatErrorSnooper(source);
CarpetExpression ex = new CarpetExpression(host.main, code, source, new BlockPos(0, 0, 0));
@@ -131,13 +131,12 @@ public class CarpetScriptHost extends ScriptHost
catch (CarpetExpressionException e)
{
host.handleErrorWithStack("Error while evaluating expression", e);
host.resetErrorSnooper();
return null;
throw new LoadException();
}
catch (ArithmeticException ae)
catch (ArithmeticException ae) // is this branch ever reached? Seems like arithmetic exceptions are converted to CEEs earlier
{
host.handleErrorWithStack("Math doesn't compute", ae);
return null;
throw new LoadException();
}
catch (StackOverflowError soe)
{
@@ -314,7 +313,7 @@ public class CarpetScriptHost extends ScriptHost
{
Value reqResult = callNow((FunctionValue) loadRequirements, Collections.emptyList());
if (reqResult.getBoolean()) // != false or null
throw new InternalExpressionException(reqResult.getString());
throw new LoadException(reqResult.getString());
}
else
{
@@ -422,20 +421,6 @@ public class CarpetScriptHost extends ScriptHost
return addLegacyCommand(notifier);
}
// Prefixes based on FLoader's SemanticVersionPredicateParser's class prefixes under Apache 2.0, since that's not public API
private static final Map<String, BiPredicate<SemanticVersion, SemanticVersion>> VERSION_PREFIXES = new HashMap<String, BiPredicate<SemanticVersion, SemanticVersion>>() {{
put(">=", (target, source) -> source.compareTo(target) >= 0);
put("<=", (target, source) -> source.compareTo(target) <= 0);
put(">", (target, source) -> source.compareTo(target) > 0);
put("<", (target, source) -> source.compareTo(target) < 0);
put("=", (target, source) -> source.compareTo(target) == 0);
put("~", (target, source) -> source.compareTo(target) >= 0
&& source.getVersionComponent(0) == target.getVersionComponent(0)
&& source.getVersionComponent(1) == target.getVersionComponent(1));
put("^", (target, source) -> source.compareTo(target) >= 0
&& source.getVersionComponent(0) == target.getVersionComponent(0));
}};
public void checkModVersionRequirements(Value reqs) {
if (reqs == null)
return;
@@ -446,58 +431,25 @@ public class CarpetScriptHost extends ScriptHost
Map<Value, Value> requirements = ((MapValue)reqs).getMap();
for (Entry<Value, Value> requirement : requirements.entrySet())
{
boolean successful = false;
String requiredModId = requirement.getKey().getString();
String requirementString = requirement.getValue().getString();
String stringPredicate = requirement.getValue().getString();
VersionPredicate predicate;
try {
predicate = VersionPredicate.parse(stringPredicate);
} catch (VersionParsingException e) {
throw new InternalExpressionException("Failed to parse version conditions for '" + requiredModId + "' in 'requires': " + e.getMessage());
}
ModContainer mod = FabricLoader.getInstance().getModContainer(requiredModId).orElse(null);
if (mod != null)
{
if (requirementString.equals("*"))
continue;
Version presentVersion = mod.getMetadata().getVersion();
BiPredicate<SemanticVersion, SemanticVersion> tester = null;
String remainingRequirementString = requirementString;
for (Entry<String, BiPredicate<SemanticVersion, SemanticVersion>> s : VERSION_PREFIXES.entrySet())
{
if (requirementString.startsWith(s.getKey()))
{
tester = s.getValue();
remainingRequirementString = requirementString.substring(s.getKey().length());
}
}
if (tester == null)
tester = VERSION_PREFIXES.get("=");
if (presentVersion instanceof SemanticVersion)
{
SemanticVersion requiredVersion = null;
try {
requiredVersion = SemanticVersion.parse(remainingRequirementString);
}
catch (VersionParsingException e)
{
throw new InternalExpressionException("Failed to parse semantic version for '" + requiredModId + "' in 'requires': " + e.getMessage());
}
if (tester.test(requiredVersion, (SemanticVersion) presentVersion))
successful = true;
}
else
{
if (FabricLoader.getInstance().isDevelopmentEnvironment())
successful = true; // Autoversioning breaks semver in dev (loads as ${version})
else
{
if (!(tester == VERSION_PREFIXES.get("=")))
throw new InternalExpressionException("Mod '"+requiredModId+"' doesn't use semversion, thus can only check version equality");
if (presentVersion.getFriendlyString().equals(remainingRequirementString))
successful = true;
}
if (predicate.test(presentVersion) || (FabricLoader.getInstance().isDevelopmentEnvironment() && !(presentVersion instanceof SemanticVersion)))
{ // in a dev env, mod version is usually replaced with ${version}, and that isn't semantic
continue;
}
}
if (!successful)
{
throw new InternalExpressionException(getName()+" requires " + requiredModId + " version " + requirementString + " in order to load");
}
throw new LoadException(String.format("%s requires a version of mod '%s' matching '%s', which is missing!", getName(), requiredModId, stringPredicate));
}
}
@@ -732,10 +684,10 @@ public class CarpetScriptHost extends ScriptHost
public Value callLegacy(ServerCommandSource source, String call, List<Integer> coords, String arg)
{
if (CarpetServer.scriptServer.stopAll)
throw new CarpetExpressionException("SCARPET PAUSED", null);
throw new CarpetExpressionException("SCARPET PAUSED (unpause with /script resume)", null);
FunctionValue function = getFunction(call);
if (function == null)
throw new CarpetExpressionException("UNDEFINED", null);
throw new CarpetExpressionException("Couldn't find function '" + call + "' in app '" + this.getName() + "'", null);
List<LazyValue> argv = new ArrayList<>();
if (coords != null)
for (Integer i: coords)
@@ -832,7 +784,7 @@ public class CarpetScriptHost extends ScriptHost
public Value call(ServerCommandSource source, FunctionValue function, List<Value> argv)
{
if (CarpetServer.scriptServer.stopAll)
throw new CarpetExpressionException("SCARPET PAUSED", null);
throw new CarpetExpressionException("SCARPET PAUSED (unpause with /script resume)", null);
List<String> args = function.getArguments();
if (argv.size() != args.size())
@@ -13,6 +13,7 @@ import carpet.CarpetServer;
import carpet.script.bundled.FileModule;
import carpet.script.bundled.Module;
import carpet.script.exception.ExpressionException;
import carpet.script.exception.LoadException;
import carpet.script.language.Arithmetic;
import carpet.script.language.ControlFlow;
import carpet.script.language.DataStructures;
@@ -256,10 +257,14 @@ public class CarpetScriptServer
Messenger.m(source, "r Failed to add "+name+" app");
return false;
}
CarpetScriptHost newHost = CarpetScriptHost.create(this, module, perPlayer, source, commandValidator, isRuleApp, installer);
if (newHost == null)
CarpetScriptHost newHost;
try
{
Messenger.m(source, "r Failed to add "+name+" app");
newHost = CarpetScriptHost.create(this, module, perPlayer, source, commandValidator, isRuleApp, installer);
}
catch (LoadException e)
{
Messenger.m(source, "r Failed to add " + name + " app" + (e.getMessage() == null ? "" : ": " + e.getMessage()));
return false;
}
// config needs to be read as we load the app since some events use that info
+7 -4
View File
@@ -481,9 +481,9 @@ public class Expression
}
public void addLazyFunction(String name, int num_params, TriFunction<Context, Context.Type, List<LazyValue>, LazyValue> fun)
public void addLazyFunction(String name, int numParams, TriFunction<Context, Context.Type, List<LazyValue>, LazyValue> fun)
{
functions.put(name, new AbstractLazyFunction(num_params, name)
functions.put(name, new AbstractLazyFunction(numParams, name)
{
@Override
public boolean pure() {
@@ -499,8 +499,11 @@ public class Expression
public LazyValue lazyEval(Context c, Context.Type i, Expression e, Tokenizer.Token t, List<LazyValue> lazyParams)
{
ILazyFunction.checkInterrupts();
if (num_params >= 0 && lazyParams.size() != num_params)
throw new InternalExpressionException("'"+name+"' requires "+num_params+" parameters, "+lazyParams.size()+" provided.");
if (numParams >= 0 && lazyParams.size() != numParams)
{
String error = "Function '"+name+"' requires "+numParams+" arguments, got "+lazyParams.size()+". ";
throw new InternalExpressionException(error + (fun instanceof Fluff.UsageProvider up ? up.getUsage() : ""));
}
try
{
+2
View File
@@ -30,6 +30,8 @@ public abstract class Fluff
@FunctionalInterface
public interface SexFunction<A, B, C, D, E, F, R> { R apply(A a, B b, C c, D d, E e, F f);}
public interface UsageProvider { String getUsage();}
public interface EvalNode
{
/**
@@ -21,6 +21,7 @@ import carpet.script.Context;
import carpet.script.Expression;
import carpet.script.Fluff.AbstractLazyFunction;
import carpet.script.Fluff.TriFunction;
import carpet.script.Fluff.UsageProvider;
import carpet.script.exception.InternalExpressionException;
import carpet.script.LazyValue;
import carpet.script.value.Value;
@@ -73,6 +74,7 @@ import it.unimi.dsi.fastutil.objects.ObjectArrayList;
*/
public final class AnnotationParser
{
static final int UNDEFINED_PARAMS = -2;
private static final List<ParsedFunction> functionList = new ArrayList<>();
/**
@@ -90,8 +92,8 @@ public final class AnnotationParser
* {@link InternalExpressionException}).
* Basically, it's fine as long as you don't add a {@code throws} declaration to your methods.</li>
* <li>Varargs (or effectively varargs) annotated methods must explicitly declare a maximum number of parameters to ingest in the {@link ScarpetFunction}
* annotation. They can still declare an unlimited amount by setting that maximum to {@code -1}. "Effectively varargs" means a function that has
* a parameter using/requiring a {@link ValueConverter} that has declared {@link ValueConverter#consumesVariableArgs()}.</li>
* annotation. They can still declare an unlimited amount by setting that maximum to {@link ScarpetFunction#UNLIMITED_PARAMS}. "Effectively varargs"
* means a function that has at least a parameter requiring a {@link ValueConverter} that has declared {@link ValueConverter#consumesVariableArgs()}.</li>
* <li>Annotated methods must not have a parameter with generics as the varargs parameter. This is just because it was painful for me (altrisi) and
* didn't want to support it. Those will crash with a {@code ClassCastException}</li>
* </ul>
@@ -141,7 +143,7 @@ public final class AnnotationParser
expr.addLazyFunction(function.name, function.scarpetParamCount, function);
}
private static class ParsedFunction implements TriFunction<Context, Context.Type, List<LazyValue>, LazyValue>
private static class ParsedFunction implements TriFunction<Context, Context.Type, List<LazyValue>, LazyValue>, UsageProvider
{
private final String name;
private final boolean isMethodVarArgs;
@@ -186,10 +188,10 @@ public final class AnnotationParser
if (this.isEffectivelyVarArgs)
{
maxParams = method.getAnnotation(ScarpetFunction.class).maxParams();
if (maxParams == -2)
throw new IllegalArgumentException("No maximum number of params specified for " + name + ", use -1 for unlimited. "
if (maxParams == UNDEFINED_PARAMS)
throw new IllegalArgumentException("No maximum number of params specified for " + name + ", use ScarpetFunction.UNLIMITED_PARAMS for unlimited. "
+ "Provided in " + instance.getClass());
if (maxParams == -1)
if (maxParams == ScarpetFunction.UNLIMITED_PARAMS)
maxParams = Integer.MAX_VALUE;
if (maxParams < this.minParams)
throw new IllegalArgumentException("Provided maximum number of params for " + name + " is smaller than method's param count."
@@ -293,7 +295,8 @@ public final class AnnotationParser
return params;
}
private String getUsage()
@Override
public String getUsage()
{
// Possibility: More descriptive messages using param.getName()? Would need changing gradle setup to keep those
StringBuilder builder = new StringBuilder("Usage: '");
@@ -51,6 +51,11 @@ import carpet.script.value.Value;
@Retention(RUNTIME)
public @interface ScarpetFunction
{
/**
* <p>Used to define that this {@link ScarpetFunction} can accept an unlimited number of parameters</p>
*/
public static final int UNLIMITED_PARAMS = -1;
/**
* <p>If the function can accept a variable number of parameters, either by declaring its last parameter as a varargs parameter or by having one
* of their parameters use a converter that consumes a variable number of arguments, this must define the maximum number of parameters this
@@ -65,11 +70,11 @@ public @interface ScarpetFunction
* consider that those can take either a single triple of values or 3 independent values, that would be counted in the maximum number of
* parameters.</p>
*
* <p>Use -1 to specify an unlimited number of parameters.</p>
* <p>Use {@link ScarpetFunction#UNLIMITED_PARAMS} to allow an unlimited number of parameters.</p>
*
* @return The maximum number of parameters this function can accept
*/
int maxParams() default -2;
int maxParams() default AnnotationParser.UNDEFINED_PARAMS;
/**
* <p>Defines the Context Type that will be used when evaluating arguments to annotated methods.</p>
@@ -162,13 +162,13 @@ public interface ValueConverter<R>
* constraints as {@link #convert(Value)}</p>
* @param valueIterator An {@link Iterator} holding the {@link Value} to convert in next position
* @param context The {@link Context} this function has been called with. This was used when this passed lazy values instead in order to
* evaluate, now it's used to get the context. It is now ignored by the default implementation
* @param theLazyT The {@code t} that the original function was called with. It is ignored by the default implementation.
* evaluate, now it's used to get the context
* @param contextType The {@link Context.Type} that the original function was called with
* @return The next {@link Value} (s) converted to the type {@code <R>} of this {@link ValueConverter}
* @implNote This method's default implementation runs the {@link #convert(Value)} function in the next {@link Value} ignoring {@link Context} and
* {@code theLazyT}.
*/
default public R checkAndConvert(Iterator<Value> valueIterator, Context context, Context.Type theLazyT)
default public R checkAndConvert(Iterator<Value> valueIterator, Context context, Context.Type contextType)
{
if (!valueIterator.hasNext())
return null;
@@ -676,7 +676,7 @@ public class Auxiliary {
expression.addContextFunction("last_tick_times", -1, (c, t, lv) ->
{
c.host.issueDeprecation("last_tick_times()");
return SystemInfo.get("last_tick_times", (CarpetContext)c);
return SystemInfo.get("server_last_tick_times", (CarpetContext)c);
});
@@ -736,6 +736,7 @@ public class Auxiliary {
return Value.TRUE;
});
// Should this be deprecated for system_info('source_dimension')?
expression.addContextFunction("current_dimension", 0, (c, t, lv) ->
ValueConversions.of( ((CarpetContext)c).s.getWorld()));
+32 -44
View File
@@ -3,6 +3,7 @@ package carpet.script.api;
import carpet.script.CarpetContext;
import carpet.script.CarpetEventServer;
import carpet.script.CarpetScriptHost;
import carpet.script.Context;
import carpet.script.Expression;
import carpet.script.argument.FunctionArgument;
import carpet.script.argument.Vector3Argument;
@@ -36,9 +37,20 @@ import java.util.List;
import java.util.Locale;
import java.util.Set;
import java.util.UUID;
import java.util.function.Predicate;
import java.util.stream.Collectors;
public class Entities {
private static ListValue getPlayersFromWorldMatching(Context c, Predicate<ServerPlayerEntity> condition) {
List<Value> ret = new ArrayList<>();
for (ServerPlayerEntity player: ((CarpetContext) c).s.getWorld().getPlayers()) {
if (condition.test(player)) {
ret.add(new EntityValue(player));
}
}
return ListValue.wrap(ret);
}
public static void apply(Expression expression)
{
expression.addContextFunction("player", -1, (c, t, lv) ->
@@ -58,50 +70,26 @@ public class Entities {
return EntityValue.of(closestPlayer);
}
String playerName = lv.get(0).getString();
Value retval = Value.NULL;
if ("all".equalsIgnoreCase(playerName))
{
retval = ListValue.wrap(
((CarpetContext)c).s.getServer().getPlayerManager().getPlayerList().
stream().map(EntityValue::new).collect(Collectors.toList()));
}
else if ("*".equalsIgnoreCase(playerName))
{
retval = ListValue.wrap(
((CarpetContext)c).s.getWorld().getPlayers().
stream().map(EntityValue::new).collect(Collectors.toList()));
}
else if ("survival".equalsIgnoreCase(playerName))
{
retval = ListValue.wrap(
((CarpetContext)c).s.getWorld().getPlayers((p) -> p.interactionManager.isSurvivalLike()).
stream().map(EntityValue::new).collect(Collectors.toList()));
}
else if ("creative".equalsIgnoreCase(playerName))
{
retval = ListValue.wrap(
((CarpetContext)c).s.getWorld().getPlayers(PlayerEntity::isCreative).
stream().map(EntityValue::new).collect(Collectors.toList()));
}
else if ("spectating".equalsIgnoreCase(playerName))
{
retval = ListValue.wrap(
((CarpetContext)c).s.getWorld().getPlayers(PlayerEntity::isSpectator).
stream().map(EntityValue::new).collect(Collectors.toList()));
}
else if ("!spectating".equalsIgnoreCase(playerName))
{
retval = ListValue.wrap(
((CarpetContext)c).s.getWorld().getPlayers((p) -> !p.isSpectator()).
stream().map(EntityValue::new).collect(Collectors.toList()));
}
else
{
ServerPlayerEntity player = ((CarpetContext) c).s.getServer().getPlayerManager().getPlayer(playerName);
if (player != null)
retval = new EntityValue(player);
}
return retval;
return switch (playerName) {
case "all" -> {
List<Value> ret = new ArrayList<>();
for (ServerPlayerEntity player: ((CarpetContext)c).s.getServer().getPlayerManager().getPlayerList())
ret.add(new EntityValue(player));
yield ListValue.wrap(ret);
}
case "*" -> getPlayersFromWorldMatching(c, p -> true);
case "survival" -> getPlayersFromWorldMatching(c, p -> p.interactionManager.isSurvivalLike());
case "creative" -> getPlayersFromWorldMatching(c, PlayerEntity::isCreative);
case "spectating" -> getPlayersFromWorldMatching(c, PlayerEntity::isSpectator);
case "!spectating" -> getPlayersFromWorldMatching(c, p -> !p.isSpectator());
default -> {
ServerPlayerEntity player = ((CarpetContext) c).s.getServer().getPlayerManager().getPlayer(playerName);
if (player != null) {
yield new EntityValue(player);
}
yield Value.NULL;
}
};
});
expression.addContextFunction("spawn", -1, (c, t, lv) ->
@@ -0,0 +1,19 @@
package carpet.script.exception;
/**
* A Scarpet exception that indicates that load of the app has failed.
*
* Goes up the stack to the point of app load and gets caught there, preventing the app from loading with
* the given message.
*
*/
public class LoadException extends RuntimeException implements ResolvedException {
public LoadException() {
super();
}
public LoadException(String message) {
super(message);
}
}
@@ -8,9 +8,7 @@ import carpet.script.value.NumericValue;
import carpet.script.value.StringValue;
import carpet.script.value.Value;
import carpet.script.value.ValueConversions;
import net.minecraft.client.color.world.FoliageColors;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.registry.Registry;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.gen.feature.ConfiguredFeature;
@@ -27,11 +25,11 @@ public class BiomeInfo
//put("under_material", (w, b) -> new BlockValue( b.getGenerationSettings().getSurfaceConfig().getUnderMaterial(), null, null));
put("category", (w, b) -> StringValue.of(b.getCategory().getName()));
put("temperature", (w, b) -> NumericValue.of(b.getTemperature()));
put("fog_color", (w, b) -> ValueConversions.ofRGB(((BiomeEffectsInterface)b.getEffects()).getCMFogColor()));
put("foliage_color", (w, b) -> ValueConversions.ofRGB(((BiomeEffectsInterface)b.getEffects()).getCMFoliageColor().orElse(4764952))); // client Biome.getDefaultFoliageColor
put("sky_color", (w, b) -> ValueConversions.ofRGB(((BiomeEffectsInterface)b.getEffects()).getCMSkyColor()));
put("water_color", (w, b) -> ValueConversions.ofRGB(((BiomeEffectsInterface)b.getEffects()).getCMWaterColor()));
put("water_fog_color", (w, b) -> ValueConversions.ofRGB(((BiomeEffectsInterface)b.getEffects()).getCMWaterFogColor()));
put("fog_color", (w, b) -> ValueConversions.ofRGB(b.getEffects().getFogColor()));
put("foliage_color", (w, b) -> ValueConversions.ofRGB(b.getEffects().getFoliageColor().orElse(4764952))); // client Biome.getDefaultFoliageColor
put("sky_color", (w, b) -> ValueConversions.ofRGB(b.getEffects().getSkyColor()));
put("water_color", (w, b) -> ValueConversions.ofRGB(b.getEffects().getWaterColor()));
put("water_fog_color", (w, b) -> ValueConversions.ofRGB(b.getEffects().getWaterFogColor()));
put("humidity", (w, b) -> NumericValue.of(b.getDownfall()));
put("precipitation", (w, b) -> StringValue.of(b.getPrecipitation().getName()));
//put("depth", (w, b) -> NumericValue.of(b.getDepth()));
@@ -5,6 +5,7 @@ import carpet.CarpetSettings;
import carpet.script.CarpetContext;
import carpet.script.CarpetScriptHost;
import carpet.script.value.BooleanValue;
import carpet.script.value.EntityValue;
import carpet.script.value.ListValue;
import carpet.script.value.MapValue;
import carpet.script.value.NumericValue;
@@ -17,11 +18,9 @@ import com.sun.management.OperatingSystemMXBean;
import net.fabricmc.loader.api.FabricLoader;
import net.fabricmc.loader.api.ModContainer;
import net.minecraft.SharedConstants;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.WorldSavePath;
import net.minecraft.util.registry.RegistryKey;
import net.minecraft.util.math.Vec2f;
import net.minecraft.world.GameRules;
import net.minecraft.world.World;
import net.minecraft.world.WorldProperties;
import net.minecraft.world.border.WorldBorder;
@@ -74,7 +73,9 @@ public class SystemInfo {
return ListValue.fromTriple(worldBorder.getCenterX(), 0, worldBorder.getCenterZ());
});
put("world_size", c-> new NumericValue( c.s.getWorld().getWorldBorder().getMaxRadius()));
put("world_size", c -> new NumericValue(c.s.getWorld().getWorldBorder().getSize() / 2));
put("world_max_size", c-> new NumericValue( c.s.getWorld().getWorldBorder().getMaxRadius()));
put("world_time", c -> new NumericValue(c.s.getWorld().getTime()));
@@ -199,6 +200,15 @@ public class SystemInfo {
});
return MapValue.wrap(rules);
});
put("source_entity", c -> EntityValue.of(c.s.getEntity()));
put("source_position", c -> ValueConversions.of(c.s.getPosition()));
put("source_dimension", c -> ValueConversions.of(c.s.getWorld()));
put("source_rotation", c -> {
Vec2f rotation = c.s.getRotation();
return ListValue.of(new NumericValue(rotation.x), new NumericValue(rotation.y));
});
put("scarpet_version", c -> StringValue.of(CarpetSettings.carpetVersion));
}};
@@ -1,10 +1,8 @@
package carpet.script.value;
import carpet.fakes.BrainInterface;
import carpet.fakes.EntityInterface;
import carpet.fakes.ItemEntityInterface;
import carpet.fakes.LivingEntityInterface;
import carpet.fakes.MemoryInterface;
import carpet.fakes.MobEntityInterface;
import carpet.fakes.ServerPlayerEntityInterface;
import carpet.fakes.ServerPlayerInteractionManagerInterface;
@@ -633,11 +631,11 @@ public class EntityValue extends Value
if (e instanceof LivingEntity livingEntity)
{
Brain<?> brain = livingEntity.getBrain();
Map<MemoryModuleType<?>, Optional<? extends Memory<?>>> memories = ((BrainInterface)brain).getMobMemories();
Map<MemoryModuleType<?>, Optional<? extends Memory<?>>> memories = brain.getMemories();
Optional<? extends Memory<?>> optmemory = memories.get(moduleType);
if (optmemory==null || !optmemory.isPresent()) return Value.NULL;
Memory<?> memory = optmemory.get();
return ValueConversions.fromTimedMemory(e, ((MemoryInterface)memory).getScarpetExpiry(), memory.getValue());
return ValueConversions.fromTimedMemory(e, memory.getExpiry(), memory.getValue());
}
return Value.NULL;
});
@@ -1584,7 +1582,7 @@ public class EntityValue extends Value
});
put("absorption", (e, v) -> {
if (e instanceof PlayerEntity) ((PlayerEntity) e).setAbsorptionAmount((float) NumericValue.asNumber(v, "absorbtion").getLong());
if (e instanceof PlayerEntity) ((PlayerEntity) e).setAbsorptionAmount(NumericValue.asNumber(v, "absorbtion").getFloat());
});
put("add_xp", (e, v) -> {
@@ -19,18 +19,29 @@ public class ThreadValue extends Value
private final long id;
private static long sequence = 0L;
public ThreadValue(CompletableFuture<Value> taskFuture)
{
this.taskFuture = taskFuture;
this.id = sequence++;
}
public ThreadValue(Value pool, FunctionValue function, Expression expr, Tokenizer.Token token, Context ctx, List<Value> args)
{
id = sequence++;
this(getCompletableFutureFromFunction(pool, function, expr, token, ctx, args));
Thread.yield();
}
public static CompletableFuture<Value> getCompletableFutureFromFunction(Value pool, FunctionValue function, Expression expr, Tokenizer.Token token, Context ctx, List<Value> args)
{
ExecutorService executor = ctx.host.getExecutor(pool);
if (executor == null)
{
// app is shutting down - no more threads can be spawned.
taskFuture = CompletableFuture.completedFuture(Value.NULL);
return CompletableFuture.completedFuture(Value.NULL);
}
else
{
taskFuture = CompletableFuture.supplyAsync(
return CompletableFuture.supplyAsync(
() ->
{
try
@@ -52,7 +63,6 @@ public class ThreadValue extends Value
ctx.host.getExecutor(pool)
);
}
Thread.yield();
}
@Override
+37 -57
View File
@@ -103,23 +103,18 @@ public class Messenger
}
public static String creatureTypeColor(SpawnGroup type)
{
switch (type)
return switch (type)
{
case MONSTER:
return "n";
case CREATURE:
return "e";
case AMBIENT:
return "f";
case WATER_CREATURE:
return "v";
case WATER_AMBIENT:
return "q";
}
return "w";
case MONSTER -> "n";
case CREATURE -> "e";
case AMBIENT -> "f";
case WATER_CREATURE -> "v";
case WATER_AMBIENT -> "q";
default -> "w"; // missing MISC and UNDERGROUND_WATER_CREATURE
};
}
private static BaseText _getChatComponentFromDesc(String message, BaseText previous_message)
private static BaseText getChatComponentFromDesc(String message, BaseText previousMessage)
{
if (message.equalsIgnoreCase(""))
{
@@ -127,7 +122,7 @@ public class Messenger
}
if (Character.isWhitespace(message.charAt(0)))
{
message = "w"+message;
message = "w" + message;
}
int limit = message.indexOf(' ');
String desc = message;
@@ -137,52 +132,37 @@ public class Messenger
desc = message.substring(0, limit);
str = message.substring(limit+1);
}
if (desc.charAt(0) == '/') // deprecated
{
if (previous_message != null)
previous_message.setStyle(
previous_message.getStyle().withClickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, message))
);
return previous_message;
if (previousMessage == null) {
BaseText text = new LiteralText(str);
text.setStyle(parseStyle(desc));
return text;
}
if (desc.charAt(0) == '?')
{
if (previous_message != null)
previous_message.setStyle(
previous_message.getStyle().withClickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, message.substring(1)))
);
return previous_message;
}
if (desc.charAt(0) == '!')
{
if (previous_message != null)
previous_message.setStyle(
previous_message.getStyle().withClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, message.substring(1)))
);
return previous_message;
}
if (desc.charAt(0) == '^')
{
if (previous_message != null)
previous_message.setStyle(
previous_message.getStyle().withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, c(message.substring(1))))
);
return previous_message;
}
BaseText txt = new LiteralText(str);
txt.setStyle(parseStyle(desc));
return txt;
Style previousStyle = previousMessage.getStyle();
BaseText ret = previousMessage;
previousMessage.setStyle(switch (desc.charAt(0)) {
case '?' -> previousStyle.withClickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, message.substring(1)));
case '!' -> previousStyle.withClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, message.substring(1)));
case '^' -> previousStyle.withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, c(message.substring(1))));
case '@' -> previousStyle.withClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, message.substring(1)));
case '&' -> previousStyle.withClickEvent(new ClickEvent(ClickEvent.Action.COPY_TO_CLIPBOARD, message.substring(1)));
default -> { // Create a new component
ret = new LiteralText(str);
ret.setStyle(parseStyle(desc));
yield previousStyle; // no op for the previous style
}
});
return ret;
}
public static BaseText tp(String desc, Vec3d pos) { return tp(desc, pos.x, pos.y, pos.z); }
public static BaseText tp(String desc, BlockPos pos) { return tp(desc, pos.getX(), pos.getY(), pos.getZ()); }
public static BaseText tp(String desc, double x, double y, double z) { return tp(desc, (float)x, (float)y, (float)z);}
public static BaseText tp(String desc, float x, float y, float z)
{
return _getCoordsTextComponent(desc, x, y, z, false);
return getCoordsTextComponent(desc, x, y, z, false);
}
public static BaseText tp(String desc, int x, int y, int z)
{
return _getCoordsTextComponent(desc, (float)x, (float)y, (float)z, true);
return getCoordsTextComponent(desc, (float)x, (float)y, (float)z, true);
}
/// to be continued
@@ -232,7 +212,7 @@ public class Messenger
return c(components.toArray(new Object[0]));
}
private static BaseText _getCoordsTextComponent(String style, float x, float y, float z, boolean isInt)
private static BaseText getCoordsTextComponent(String style, float x, float y, float z, boolean isInt)
{
String text;
String command;
@@ -266,19 +246,19 @@ public class Messenger
public static BaseText c(Object ... fields)
{
BaseText message = new LiteralText("");
BaseText previous_component = null;
BaseText previousComponent = null;
for (Object o: fields)
{
if (o instanceof BaseText)
{
message.append((BaseText)o);
previous_component = (BaseText)o;
previousComponent = (BaseText)o;
continue;
}
String txt = o.toString();
BaseText comp = _getChatComponentFromDesc(txt,previous_component);
if (comp != previous_component) message.append(comp);
previous_component = comp;
BaseText comp = getChatComponentFromDesc(txt, previousComponent);
if (comp != previousComponent) message.append(comp);
previousComponent = comp;
}
return message;
}