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:
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
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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()));
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user