warning cleanup
This commit is contained in:
1 parent
5ab4a9e442
commit
277872b33c
106 files changed
+4495
-4345
No files matched your search
@@ -18,12 +18,12 @@ public class CarpetContext extends Context
|
||||
public CommandSourceStack s;
|
||||
private final BlockPos origin;
|
||||
|
||||
public CarpetContext(final CarpetScriptHost host, final CommandSourceStack source)
|
||||
public CarpetContext(CarpetScriptHost host, CommandSourceStack source)
|
||||
{
|
||||
this(host, source, BlockPos.ZERO);
|
||||
}
|
||||
|
||||
public CarpetContext(final ScriptHost host, final CommandSourceStack source, final BlockPos origin)
|
||||
public CarpetContext(ScriptHost host, CommandSourceStack source, BlockPos origin)
|
||||
{
|
||||
super(host);
|
||||
s = source;
|
||||
@@ -60,7 +60,7 @@ public class CarpetContext extends Context
|
||||
return s.getLevel().registryAccess();
|
||||
}
|
||||
|
||||
public <T> Registry<T> registry(final ResourceKey<? extends Registry<? extends T>> resourceKey)
|
||||
public <T> Registry<T> registry(ResourceKey<? extends Registry<? extends T>> resourceKey)
|
||||
{
|
||||
return registryAccess().registryOrThrow(resourceKey);
|
||||
}
|
||||
@@ -75,7 +75,7 @@ public class CarpetContext extends Context
|
||||
return origin;
|
||||
}
|
||||
|
||||
public void swapSource(final CommandSourceStack source)
|
||||
public void swapSource(CommandSourceStack source)
|
||||
{
|
||||
s = source;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -42,7 +42,7 @@ public class CarpetExpression
|
||||
return origin;
|
||||
}
|
||||
|
||||
public CarpetExpression(final Module module, final String expression, final CommandSourceStack source, final BlockPos origin)
|
||||
public CarpetExpression(Module module, String expression, CommandSourceStack source, BlockPos origin)
|
||||
{
|
||||
this.origin = origin;
|
||||
this.source = source;
|
||||
@@ -61,7 +61,7 @@ public class CarpetExpression
|
||||
Carpet.handleExtensionsAPI(this);
|
||||
}
|
||||
|
||||
public boolean fillAndScanCommand(final ScriptHost host, final int x, final int y, final int z)
|
||||
public boolean fillAndScanCommand(ScriptHost host, int x, int y, int z)
|
||||
{
|
||||
CarpetScriptServer scriptServer = (CarpetScriptServer) host.scriptServer();
|
||||
if (scriptServer.stopAll)
|
||||
@@ -70,39 +70,39 @@ public class CarpetExpression
|
||||
}
|
||||
try
|
||||
{
|
||||
final Context context = new CarpetContext(host, source, origin).
|
||||
Context context = new CarpetContext(host, source, origin).
|
||||
with("x", (c, t) -> new NumericValue(x - origin.getX()).bindTo("x")).
|
||||
with("y", (c, t) -> new NumericValue(y - origin.getY()).bindTo("y")).
|
||||
with("z", (c, t) -> new NumericValue(z - origin.getZ()).bindTo("z")).
|
||||
with("_", (c, t) -> new BlockValue(null, source.getLevel(), new BlockPos(x, y, z)).bindTo("_"));
|
||||
final Entity e = source.getEntity();
|
||||
Entity e = source.getEntity();
|
||||
if (e == null)
|
||||
{
|
||||
final Value nullPlayer = Value.NULL.reboundedTo("p");
|
||||
Value nullPlayer = Value.NULL.reboundedTo("p");
|
||||
context.with("p", (cc, tt) -> nullPlayer);
|
||||
}
|
||||
else
|
||||
{
|
||||
final Value playerValue = new EntityValue(e).bindTo("p");
|
||||
Value playerValue = new EntityValue(e).bindTo("p");
|
||||
context.with("p", (cc, tt) -> playerValue);
|
||||
}
|
||||
return scriptServer.events.handleEvents.getWhileDisabled(() -> this.expr.eval(context).getBoolean());
|
||||
}
|
||||
catch (final ExpressionException e)
|
||||
catch (ExpressionException e)
|
||||
{
|
||||
throw new CarpetExpressionException(e.getMessage(), e.stack);
|
||||
}
|
||||
catch (final ArithmeticException ae)
|
||||
catch (ArithmeticException ae)
|
||||
{
|
||||
throw new CarpetExpressionException("Math doesn't compute... " + ae.getMessage(), null);
|
||||
}
|
||||
catch (final StackOverflowError soe)
|
||||
catch (StackOverflowError soe)
|
||||
{
|
||||
throw new CarpetExpressionException("Your thoughts are too deep", null);
|
||||
}
|
||||
}
|
||||
|
||||
public Value scriptRunCommand(final ScriptHost host, final BlockPos pos)
|
||||
public Value scriptRunCommand(ScriptHost host, BlockPos pos)
|
||||
{
|
||||
CarpetScriptServer scriptServer = (CarpetScriptServer) host.scriptServer();
|
||||
if (scriptServer.stopAll)
|
||||
@@ -111,32 +111,32 @@ public class CarpetExpression
|
||||
}
|
||||
try
|
||||
{
|
||||
final Context context = new CarpetContext(host, source, origin).
|
||||
Context context = new CarpetContext(host, source, origin).
|
||||
with("x", (c, t) -> new NumericValue(pos.getX() - origin.getX()).bindTo("x")).
|
||||
with("y", (c, t) -> new NumericValue(pos.getY() - origin.getY()).bindTo("y")).
|
||||
with("z", (c, t) -> new NumericValue(pos.getZ() - origin.getZ()).bindTo("z"));
|
||||
final Entity e = source.getEntity();
|
||||
Entity e = source.getEntity();
|
||||
if (e == null)
|
||||
{
|
||||
final Value nullPlayer = Value.NULL.reboundedTo("p");
|
||||
Value nullPlayer = Value.NULL.reboundedTo("p");
|
||||
context.with("p", (cc, tt) -> nullPlayer);
|
||||
}
|
||||
else
|
||||
{
|
||||
final Value playerValue = new EntityValue(e).bindTo("p");
|
||||
Value playerValue = new EntityValue(e).bindTo("p");
|
||||
context.with("p", (cc, tt) -> playerValue);
|
||||
}
|
||||
return scriptServer.events.handleEvents.getWhileDisabled(() -> this.expr.eval(context));
|
||||
}
|
||||
catch (final ExpressionException e)
|
||||
catch (ExpressionException e)
|
||||
{
|
||||
throw new CarpetExpressionException(e.getMessage(), e.stack);
|
||||
}
|
||||
catch (final ArithmeticException ae)
|
||||
catch (ArithmeticException ae)
|
||||
{
|
||||
throw new CarpetExpressionException("Math doesn't compute... " + ae.getMessage(), null);
|
||||
}
|
||||
catch (final StackOverflowError soe)
|
||||
catch (StackOverflowError soe)
|
||||
{
|
||||
throw new CarpetExpressionException("Your thoughts are too deep", null);
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -32,6 +32,7 @@ import net.minecraft.world.level.storage.LevelResource;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.FileVisitOption;
|
||||
import java.nio.file.Files;
|
||||
@@ -73,7 +74,7 @@ public class CarpetScriptServer extends ScriptServer
|
||||
* @param app The {@link Module} of the app
|
||||
* @see Module#fromJarPath(String, String, boolean)
|
||||
*/
|
||||
public static void registerBuiltInApp(final Module app)
|
||||
public static void registerBuiltInApp(Module app)
|
||||
{
|
||||
bundledModuleData.add(app);
|
||||
}
|
||||
@@ -85,7 +86,7 @@ public class CarpetScriptServer extends ScriptServer
|
||||
* @param app The {@link Module} of the app.
|
||||
* @see Module#fromJarPath(String, String, boolean)
|
||||
*/
|
||||
public static void registerSettingsApp(final Module app)
|
||||
public static void registerSettingsApp(Module app)
|
||||
{
|
||||
ruleModuleData.add(app);
|
||||
}
|
||||
@@ -104,7 +105,7 @@ public class CarpetScriptServer extends ScriptServer
|
||||
registerBuiltInApp(Module.carpetNative("distance_beta", false));
|
||||
}
|
||||
|
||||
public CarpetScriptServer(final MinecraftServer server)
|
||||
public CarpetScriptServer(MinecraftServer server)
|
||||
{
|
||||
this.server = server;
|
||||
init();
|
||||
@@ -125,7 +126,7 @@ public class CarpetScriptServer extends ScriptServer
|
||||
{
|
||||
if (Vanilla.MinecraftServer_doScriptsAutoload(server))
|
||||
{
|
||||
for (final String moduleName : listAvailableModules(false))
|
||||
for (String moduleName : listAvailableModules(false))
|
||||
{
|
||||
addScriptHost(server.createCommandSourceStack(), moduleName, null, true, true, false, null);
|
||||
}
|
||||
@@ -133,18 +134,18 @@ public class CarpetScriptServer extends ScriptServer
|
||||
CarpetEventServer.Event.START.onTick(server);
|
||||
}
|
||||
|
||||
public Module getModule(final String name, final boolean allowLibraries)
|
||||
public Module getModule(String name, boolean allowLibraries)
|
||||
{
|
||||
try
|
||||
{
|
||||
final Path folder = server.getWorldPath(LevelResource.ROOT).resolve("scripts");
|
||||
Path folder = server.getWorldPath(LevelResource.ROOT).resolve("scripts");
|
||||
if (!Files.exists(folder))
|
||||
{
|
||||
Files.createDirectories(folder);
|
||||
}
|
||||
try (final Stream<Path> folderLister = Files.list(folder))
|
||||
try (Stream<Path> folderLister = Files.list(folder))
|
||||
{
|
||||
final Optional<Path> scriptPath = folderLister
|
||||
Optional<Path> scriptPath = folderLister
|
||||
.filter(script ->
|
||||
script.getFileName().toString().equalsIgnoreCase(name + ".sc") ||
|
||||
(allowLibraries && script.getFileName().toString().equalsIgnoreCase(name + ".scl"))
|
||||
@@ -157,14 +158,14 @@ public class CarpetScriptServer extends ScriptServer
|
||||
|
||||
if (FabricLoader.getInstance().getEnvironmentType() == EnvType.CLIENT)
|
||||
{
|
||||
final Path globalFolder = FabricLoader.getInstance().getConfigDir().resolve("carpet/scripts");
|
||||
Path globalFolder = FabricLoader.getInstance().getConfigDir().resolve("carpet/scripts");
|
||||
if (!Files.exists(globalFolder))
|
||||
{
|
||||
Files.createDirectories(globalFolder);
|
||||
}
|
||||
try (final Stream<Path> folderWalker = Files.walk(globalFolder))
|
||||
try (Stream<Path> folderWalker = Files.walk(globalFolder))
|
||||
{
|
||||
final Optional<Path> scriptPath = folderWalker
|
||||
Optional<Path> scriptPath = folderWalker
|
||||
.filter(script -> script.getFileName().toString().equalsIgnoreCase(name + ".sc") ||
|
||||
(allowLibraries && script.getFileName().toString().equalsIgnoreCase(name + ".scl")))
|
||||
.findFirst();
|
||||
@@ -175,11 +176,11 @@ public class CarpetScriptServer extends ScriptServer
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (final IOException e)
|
||||
catch (IOException e)
|
||||
{
|
||||
LOG.error("Exception while loading the app: ", e);
|
||||
}
|
||||
for (final Module moduleData : bundledModuleData)
|
||||
for (Module moduleData : bundledModuleData)
|
||||
{
|
||||
if (moduleData.name().equalsIgnoreCase(name) && (allowLibraries || !moduleData.library()))
|
||||
{
|
||||
@@ -189,9 +190,9 @@ public class CarpetScriptServer extends ScriptServer
|
||||
return null;
|
||||
}
|
||||
|
||||
public Module getRuleModule(final String name)
|
||||
public Module getRuleModule(String name)
|
||||
{
|
||||
for (final Module moduleData : ruleModuleData)
|
||||
for (Module moduleData : ruleModuleData)
|
||||
{
|
||||
if (moduleData.name().equalsIgnoreCase(name))
|
||||
{
|
||||
@@ -201,12 +202,12 @@ public class CarpetScriptServer extends ScriptServer
|
||||
return null;
|
||||
}
|
||||
|
||||
public List<String> listAvailableModules(final boolean includeBuiltIns)
|
||||
public List<String> listAvailableModules(boolean includeBuiltIns)
|
||||
{
|
||||
final List<String> moduleNames = new ArrayList<>();
|
||||
List<String> moduleNames = new ArrayList<>();
|
||||
if (includeBuiltIns)
|
||||
{
|
||||
for (final Module mi : bundledModuleData)
|
||||
for (Module mi : bundledModuleData)
|
||||
{
|
||||
if (!mi.library() && !mi.name().endsWith("_beta"))
|
||||
{
|
||||
@@ -216,12 +217,12 @@ public class CarpetScriptServer extends ScriptServer
|
||||
}
|
||||
try
|
||||
{
|
||||
final Path worldScripts = server.getWorldPath(LevelResource.ROOT).resolve("scripts");
|
||||
Path worldScripts = server.getWorldPath(LevelResource.ROOT).resolve("scripts");
|
||||
if (!Files.exists(worldScripts))
|
||||
{
|
||||
Files.createDirectories(worldScripts);
|
||||
}
|
||||
try (final Stream<Path> folderLister = Files.list(worldScripts))
|
||||
try (Stream<Path> folderLister = Files.list(worldScripts))
|
||||
{
|
||||
folderLister
|
||||
.filter(f -> f.toString().endsWith(".sc"))
|
||||
@@ -230,12 +231,12 @@ public class CarpetScriptServer extends ScriptServer
|
||||
|
||||
if (includeBuiltIns && (FabricLoader.getInstance().getEnvironmentType() == EnvType.CLIENT))
|
||||
{
|
||||
final Path globalScripts = FabricLoader.getInstance().getConfigDir().resolve("carpet/scripts");
|
||||
Path globalScripts = FabricLoader.getInstance().getConfigDir().resolve("carpet/scripts");
|
||||
if (!Files.exists(globalScripts))
|
||||
{
|
||||
Files.createDirectories(globalScripts);
|
||||
}
|
||||
try (final Stream<Path> folderWalker = Files.walk(globalScripts, FileVisitOption.FOLLOW_LINKS))
|
||||
try (Stream<Path> folderWalker = Files.walk(globalScripts, FileVisitOption.FOLLOW_LINKS))
|
||||
{
|
||||
folderWalker
|
||||
.filter(f -> f.toString().endsWith(".sc"))
|
||||
@@ -243,27 +244,27 @@ public class CarpetScriptServer extends ScriptServer
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (final IOException e)
|
||||
catch (IOException e)
|
||||
{
|
||||
LOG.error("Exception while searching for apps: ", e);
|
||||
}
|
||||
return moduleNames;
|
||||
}
|
||||
|
||||
public CarpetScriptHost getAppHostByName(final String name)
|
||||
public CarpetScriptHost getAppHostByName(String name)
|
||||
{
|
||||
return name == null ? globalHost : modules.get(name);
|
||||
}
|
||||
|
||||
public boolean addScriptHost(final CommandSourceStack source, String name, Predicate<CommandSourceStack> commandValidator,
|
||||
final boolean perPlayer, final boolean autoload, final boolean isRuleApp, final AppStoreManager.StoreNode installer)
|
||||
public boolean addScriptHost(CommandSourceStack source, String name, @Nullable Predicate<CommandSourceStack> commandValidator,
|
||||
boolean perPlayer, boolean autoload, boolean isRuleApp, AppStoreManager.StoreNode installer)
|
||||
{
|
||||
final Runnable token = Carpet.startProfilerSection("Scarpet load");
|
||||
Runnable token = Carpet.startProfilerSection("Scarpet load");
|
||||
if (commandValidator == null)
|
||||
{
|
||||
commandValidator = p -> true;
|
||||
}
|
||||
final long start = System.nanoTime();
|
||||
long start = System.nanoTime();
|
||||
name = name.toLowerCase(Locale.ROOT);
|
||||
boolean reload = false;
|
||||
if (modules.containsKey(name))
|
||||
@@ -275,18 +276,18 @@ public class CarpetScriptServer extends ScriptServer
|
||||
removeScriptHost(source, name, false, isRuleApp);
|
||||
reload = true;
|
||||
}
|
||||
final Module module = isRuleApp ? getRuleModule(name) : getModule(name, false);
|
||||
Module module = isRuleApp ? getRuleModule(name) : getModule(name, false);
|
||||
if (module == null)
|
||||
{
|
||||
Carpet.Messenger_message(source, "r Failed to add " + name + " app: App not found");
|
||||
return false;
|
||||
}
|
||||
final CarpetScriptHost newHost;
|
||||
CarpetScriptHost newHost;
|
||||
try
|
||||
{
|
||||
newHost = CarpetScriptHost.create(this, module, perPlayer, source, commandValidator, isRuleApp, installer);
|
||||
}
|
||||
catch (final LoadException e)
|
||||
catch (LoadException e)
|
||||
{
|
||||
Carpet.Messenger_message(source, "r Failed to add " + name + " app" + (e.getMessage() == null ? "" : ": " + e.getMessage()));
|
||||
return false;
|
||||
@@ -303,10 +304,10 @@ public class CarpetScriptServer extends ScriptServer
|
||||
removeScriptHost(source, name, false, false);
|
||||
return false;
|
||||
}
|
||||
final String action = (installer != null) ? (reload ? "reinstalled" : "installed") : (reload ? "reloaded" : "loaded");
|
||||
String action = (installer != null) ? (reload ? "reinstalled" : "installed") : (reload ? "reloaded" : "loaded");
|
||||
|
||||
final String finalName = name;
|
||||
final Boolean isCommandAdded = newHost.addAppCommands(s -> {
|
||||
String finalName = name;
|
||||
Boolean isCommandAdded = newHost.addAppCommands(s -> {
|
||||
if (!isRuleApp)
|
||||
{
|
||||
Carpet.Messenger_message(source, "r Failed to add app '" + finalName + "': ", s);
|
||||
@@ -336,7 +337,7 @@ public class CarpetScriptServer extends ScriptServer
|
||||
if (newHost.isPerUser())
|
||||
{
|
||||
// that will provide player hosts right at the startup
|
||||
for (final ServerPlayer player : source.getServer().getPlayerList().getPlayers())
|
||||
for (ServerPlayer player : source.getServer().getPlayerList().getPlayers())
|
||||
{
|
||||
newHost.retrieveForExecution(player.createCommandSourceStack(), player);
|
||||
}
|
||||
@@ -344,25 +345,25 @@ public class CarpetScriptServer extends ScriptServer
|
||||
else
|
||||
{
|
||||
// global app - calling start now.
|
||||
final FunctionValue onStart = newHost.getFunction("__on_start");
|
||||
FunctionValue onStart = newHost.getFunction("__on_start");
|
||||
if (onStart != null)
|
||||
{
|
||||
newHost.callNow(onStart, Collections.emptyList());
|
||||
}
|
||||
}
|
||||
token.run();
|
||||
final long end = System.nanoTime();
|
||||
long end = System.nanoTime();
|
||||
LOG.info("App " + name + " loaded in " + (end - start) / 1000000 + " ms");
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean isInvalidCommandRoot(final String appName)
|
||||
public boolean isInvalidCommandRoot(String appName)
|
||||
{
|
||||
return holyMoly.contains(appName);
|
||||
}
|
||||
|
||||
|
||||
public boolean removeScriptHost(final CommandSourceStack source, String name, final boolean notifySource, final boolean isRuleApp)
|
||||
public boolean removeScriptHost(CommandSourceStack source, String name, boolean notifySource, boolean isRuleApp)
|
||||
{
|
||||
name = name.toLowerCase(Locale.ROOT);
|
||||
if (!modules.containsKey(name) || (!isRuleApp && !unloadableModules.contains(name)))
|
||||
@@ -374,7 +375,7 @@ public class CarpetScriptServer extends ScriptServer
|
||||
return false;
|
||||
}
|
||||
// stop all events associated with name
|
||||
final CarpetScriptHost host = modules.remove(name);
|
||||
CarpetScriptHost host = modules.remove(name);
|
||||
events.removeAllHostEvents(host);
|
||||
host.onClose();
|
||||
if (host.hasCommand)
|
||||
@@ -393,12 +394,12 @@ public class CarpetScriptServer extends ScriptServer
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean uninstallApp(final CommandSourceStack source, String name)
|
||||
public boolean uninstallApp(CommandSourceStack source, String name)
|
||||
{
|
||||
try
|
||||
{
|
||||
name = name.toLowerCase(Locale.ROOT);
|
||||
final Path folder = server.getWorldPath(LevelResource.ROOT).resolve("scripts/trash");
|
||||
Path folder = server.getWorldPath(LevelResource.ROOT).resolve("scripts/trash");
|
||||
if (!Files.exists(folder))
|
||||
{
|
||||
Files.createDirectories(folder);
|
||||
@@ -413,7 +414,7 @@ public class CarpetScriptServer extends ScriptServer
|
||||
Carpet.Messenger_message(source, "gi Removed " + name + " app");
|
||||
return true;
|
||||
}
|
||||
catch (final IOException exc)
|
||||
catch (IOException exc)
|
||||
{
|
||||
Carpet.Messenger_message(source, "rb Failed to uninstall the app");
|
||||
}
|
||||
@@ -430,7 +431,7 @@ public class CarpetScriptServer extends ScriptServer
|
||||
});
|
||||
token.run();
|
||||
token = Carpet.startProfilerSection("Scarpet app data");
|
||||
for (final CarpetScriptHost host : modules.values())
|
||||
for (CarpetScriptHost host : modules.values())
|
||||
{
|
||||
host.tick();
|
||||
}
|
||||
@@ -440,7 +441,7 @@ public class CarpetScriptServer extends ScriptServer
|
||||
public void onClose()
|
||||
{
|
||||
CarpetEventServer.Event.SHUTDOWN.onTick(server);
|
||||
for (final CarpetScriptHost host : modules.values())
|
||||
for (CarpetScriptHost host : modules.values())
|
||||
{
|
||||
host.onClose();
|
||||
events.removeAllHostEvents(host);
|
||||
@@ -448,7 +449,7 @@ public class CarpetScriptServer extends ScriptServer
|
||||
stopAll = true;
|
||||
}
|
||||
|
||||
public void onPlayerJoin(final ServerPlayer player)
|
||||
public void onPlayerJoin(ServerPlayer player)
|
||||
{
|
||||
modules.values().forEach(h ->
|
||||
{
|
||||
@@ -458,7 +459,7 @@ public class CarpetScriptServer extends ScriptServer
|
||||
{
|
||||
h.retrieveOwnForExecution(player.createCommandSourceStack());
|
||||
}
|
||||
catch (final CommandSyntaxException ignored)
|
||||
catch (CommandSyntaxException ignored)
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -466,7 +467,7 @@ public class CarpetScriptServer extends ScriptServer
|
||||
}
|
||||
|
||||
@Override
|
||||
public Path resolveResource(final String suffix)
|
||||
public Path resolveResource(String suffix)
|
||||
{
|
||||
return server.getWorldPath(LevelResource.ROOT).resolve("scripts/" + suffix);
|
||||
}
|
||||
@@ -474,15 +475,15 @@ public class CarpetScriptServer extends ScriptServer
|
||||
private record TransferData(boolean perUser, Predicate<CommandSourceStack> commandValidator,
|
||||
boolean isRuleApp)
|
||||
{
|
||||
private TransferData(final CarpetScriptHost host)
|
||||
private TransferData(CarpetScriptHost host)
|
||||
{
|
||||
this(host.perUser, host.commandValidator, host.isRuleApp);
|
||||
}
|
||||
}
|
||||
|
||||
public void reload(final MinecraftServer server)
|
||||
public void reload(MinecraftServer server)
|
||||
{
|
||||
final Map<String, TransferData> apps = new HashMap<>();
|
||||
Map<String, TransferData> apps = new HashMap<>();
|
||||
modules.forEach((s, h) -> apps.put(s, new TransferData(h)));
|
||||
apps.keySet().forEach(s -> removeScriptHost(server.createCommandSourceStack(), s, false, false));
|
||||
CarpetEventServer.Event.clearAllBuiltinEvents();
|
||||
|
||||
@@ -30,32 +30,32 @@ public class Context
|
||||
|
||||
public final ScriptHost host;
|
||||
|
||||
public Context(final ScriptHost host)
|
||||
public Context(ScriptHost host)
|
||||
{
|
||||
this.host = host;
|
||||
}
|
||||
|
||||
public LazyValue getVariable(final String name)
|
||||
public LazyValue getVariable(String name)
|
||||
{
|
||||
return variables.get(name);
|
||||
}
|
||||
|
||||
public void setVariable(final String name, final LazyValue lv)
|
||||
public void setVariable(String name, LazyValue lv)
|
||||
{
|
||||
variables.put(name, lv);
|
||||
}
|
||||
|
||||
public void delVariable(final String variable)
|
||||
public void delVariable(String variable)
|
||||
{
|
||||
variables.remove(variable);
|
||||
}
|
||||
|
||||
public void removeVariablesMatching(final String varname)
|
||||
public void removeVariablesMatching(String varname)
|
||||
{
|
||||
variables.entrySet().removeIf(e -> e.getKey().startsWith(varname));
|
||||
}
|
||||
|
||||
public Context with(final String variable, final LazyValue lv)
|
||||
public Context with(String variable, LazyValue lv)
|
||||
{
|
||||
variables.put(variable, lv);
|
||||
return this;
|
||||
@@ -68,7 +68,7 @@ public class Context
|
||||
|
||||
public Context recreate()
|
||||
{
|
||||
final Context ctx = duplicate();
|
||||
Context ctx = duplicate();
|
||||
ctx.initialize();
|
||||
return ctx;
|
||||
}
|
||||
@@ -104,7 +104,7 @@ public class Context
|
||||
{
|
||||
public ScriptHost.ErrorSnooper optmizerEerrorSnooper;
|
||||
|
||||
public ContextForErrorReporting(final Context parent)
|
||||
public ContextForErrorReporting(Context parent)
|
||||
{
|
||||
super(null);
|
||||
optmizerEerrorSnooper = parent.host.errorSnooper;
|
||||
@@ -125,32 +125,32 @@ public class Context
|
||||
}
|
||||
|
||||
@Override
|
||||
public LazyValue getVariable(final String name)
|
||||
public LazyValue getVariable(String name)
|
||||
{
|
||||
badProgrammer();
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setVariable(final String name, final LazyValue lv)
|
||||
public void setVariable(String name, LazyValue lv)
|
||||
{
|
||||
badProgrammer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delVariable(final String variable)
|
||||
public void delVariable(String variable)
|
||||
{
|
||||
badProgrammer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeVariablesMatching(final String varname)
|
||||
public void removeVariablesMatching(String varname)
|
||||
{
|
||||
badProgrammer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Context with(final String variable, final LazyValue lv)
|
||||
public Context with(String variable, LazyValue lv)
|
||||
{
|
||||
badProgrammer();
|
||||
return this;
|
||||
|
||||
@@ -29,33 +29,33 @@ public class EntityEventsGroup
|
||||
private final Map<Event, Map<EventKey, CarpetEventServer.Callback>> actions;
|
||||
private final Entity entity;
|
||||
|
||||
public EntityEventsGroup(final Entity e)
|
||||
public EntityEventsGroup(Entity e)
|
||||
{
|
||||
actions = new HashMap<>();
|
||||
entity = e;
|
||||
}
|
||||
|
||||
public void onEvent(final Event type, final Object... args)
|
||||
public void onEvent(Event type, Object... args)
|
||||
{
|
||||
if (actions.isEmpty())
|
||||
{
|
||||
return; // most of the cases, trying to be nice
|
||||
}
|
||||
final Map<EventKey, CarpetEventServer.Callback> actionSet = actions.get(type);
|
||||
Map<EventKey, CarpetEventServer.Callback> actionSet = actions.get(type);
|
||||
if (actionSet == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
final CarpetScriptServer scriptServer = Vanilla.MinecraftServer_getScriptServer(entity.getServer());
|
||||
CarpetScriptServer scriptServer = Vanilla.MinecraftServer_getScriptServer(entity.getServer());
|
||||
if (scriptServer.stopAll)
|
||||
{
|
||||
return; // executed after world is closin down
|
||||
}
|
||||
for (final Iterator<Map.Entry<EventKey, CarpetEventServer.Callback>> iterator = actionSet.entrySet().iterator(); iterator.hasNext(); )
|
||||
for (Iterator<Map.Entry<EventKey, CarpetEventServer.Callback>> iterator = actionSet.entrySet().iterator(); iterator.hasNext(); )
|
||||
{
|
||||
final Map.Entry<EventKey, CarpetEventServer.Callback> action = iterator.next();
|
||||
final EventKey key = action.getKey();
|
||||
final ScriptHost host = scriptServer.getAppHostByName(key.host());
|
||||
Map.Entry<EventKey, CarpetEventServer.Callback> action = iterator.next();
|
||||
EventKey key = action.getKey();
|
||||
ScriptHost host = scriptServer.getAppHostByName(key.host());
|
||||
if (host == null)
|
||||
{
|
||||
iterator.remove();
|
||||
@@ -77,12 +77,12 @@ public class EntityEventsGroup
|
||||
}
|
||||
}
|
||||
|
||||
public void addEvent(final Event type, final ScriptHost host, final FunctionValue fun, final List<Value> extraargs)
|
||||
public void addEvent(Event type, ScriptHost host, FunctionValue fun, List<Value> extraargs)
|
||||
{
|
||||
final EventKey key = new EventKey(host.getName(), host.user);
|
||||
EventKey key = new EventKey(host.getName(), host.user);
|
||||
if (fun != null)
|
||||
{
|
||||
final CarpetEventServer.Callback call = type.create(key, fun, extraargs, (CarpetScriptServer) host.scriptServer());
|
||||
CarpetEventServer.Callback call = type.create(key, fun, extraargs, (CarpetScriptServer) host.scriptServer());
|
||||
if (call == null)
|
||||
{
|
||||
throw new InternalExpressionException("wrong number of arguments for callback, required " + type.argcount);
|
||||
@@ -106,7 +106,7 @@ public class EntityEventsGroup
|
||||
public static final Event ON_DEATH = new Event("on_death", 1)
|
||||
{
|
||||
@Override
|
||||
public List<Value> makeArgs(final Entity entity, final Object... providedArgs)
|
||||
public List<Value> makeArgs(Entity entity, Object... providedArgs)
|
||||
{
|
||||
return Arrays.asList(
|
||||
new EntityValue(entity),
|
||||
@@ -119,10 +119,10 @@ public class EntityEventsGroup
|
||||
public static final Event ON_DAMAGE = new Event("on_damaged", 3)
|
||||
{
|
||||
@Override
|
||||
public List<Value> makeArgs(final Entity entity, final Object... providedArgs)
|
||||
public List<Value> makeArgs(Entity entity, Object... providedArgs)
|
||||
{
|
||||
final float amount = (Float) providedArgs[0];
|
||||
final DamageSource source = (DamageSource) providedArgs[1];
|
||||
float amount = (Float) providedArgs[0];
|
||||
DamageSource source = (DamageSource) providedArgs[1];
|
||||
return Arrays.asList(
|
||||
new EntityValue(entity),
|
||||
new NumericValue(amount),
|
||||
@@ -134,7 +134,7 @@ public class EntityEventsGroup
|
||||
public static final Event ON_MOVE = new Event("on_move", 3)
|
||||
{
|
||||
@Override
|
||||
public List<Value> makeArgs(final Entity entity, final Object... providedArgs)
|
||||
public List<Value> makeArgs(Entity entity, Object... providedArgs)
|
||||
{
|
||||
return Arrays.asList(
|
||||
new EntityValue(entity),
|
||||
@@ -148,14 +148,14 @@ public class EntityEventsGroup
|
||||
public final int argcount;
|
||||
public final String id;
|
||||
|
||||
public Event(final String identifier, final int args)
|
||||
public Event(String identifier, int args)
|
||||
{
|
||||
id = identifier;
|
||||
argcount = args + 1; // entity is not extra
|
||||
byName.put(identifier, this);
|
||||
}
|
||||
|
||||
public CarpetEventServer.Callback create(final EventKey key, final FunctionValue function, final List<Value> extraArgs, final CarpetScriptServer scriptServer)
|
||||
public CarpetEventServer.Callback create(EventKey key, FunctionValue function, List<Value> extraArgs, CarpetScriptServer scriptServer)
|
||||
{
|
||||
if ((function.getArguments().size() - (extraArgs == null ? 0 : extraArgs.size())) != argcount)
|
||||
{
|
||||
@@ -164,13 +164,13 @@ public class EntityEventsGroup
|
||||
return new CarpetEventServer.Callback(key.host(), key.user(), function, extraArgs, scriptServer);
|
||||
}
|
||||
|
||||
public CarpetEventServer.CallbackResult call(final CarpetEventServer.Callback tickCall, final Entity entity, final Object... args)
|
||||
public CarpetEventServer.CallbackResult call(CarpetEventServer.Callback tickCall, Entity entity, Object... args)
|
||||
{
|
||||
assert args.length == argcount - 1;
|
||||
return tickCall.execute(entity.createCommandSourceStack(), makeArgs(entity, args));
|
||||
}
|
||||
|
||||
protected List<Value> makeArgs(final Entity entity, final Object... args)
|
||||
protected List<Value> makeArgs(Entity entity, Object... args)
|
||||
{
|
||||
return Collections.singletonList(new EntityValue(entity));
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -57,7 +57,7 @@ public abstract class Fluff
|
||||
/**
|
||||
* @return required argument eval type in case its evaluated statically without context but with a given context type
|
||||
*/
|
||||
default Context.Type staticType(final Context.Type outerType)
|
||||
default Context.Type staticType(Context.Type outerType)
|
||||
{
|
||||
return transitive() ? outerType : Context.NONE;
|
||||
}
|
||||
@@ -106,7 +106,7 @@ public abstract class Fluff
|
||||
protected String name;
|
||||
int numParams;
|
||||
|
||||
public AbstractLazyFunction(final int numParams, final String name)
|
||||
public AbstractLazyFunction(int numParams, String name)
|
||||
{
|
||||
super();
|
||||
this.numParams = numParams;
|
||||
@@ -131,12 +131,12 @@ public abstract class Fluff
|
||||
return numParams < 0;
|
||||
}
|
||||
|
||||
public static List<Value> unpackLazy(final List<LazyValue> lzargs, final Context c, final Context.Type contextType)
|
||||
public static List<Value> unpackLazy(List<LazyValue> lzargs, Context c, Context.Type contextType)
|
||||
{
|
||||
final List<Value> args = new ArrayList<>();
|
||||
for (final LazyValue lv : lzargs)
|
||||
List<Value> args = new ArrayList<>();
|
||||
for (LazyValue lv : lzargs)
|
||||
{
|
||||
final Value arg = lv.evalValue(c, contextType);
|
||||
Value arg = lv.evalValue(c, contextType);
|
||||
if (arg instanceof FunctionUnpackedArgumentsValue)
|
||||
{
|
||||
args.addAll(((ListValue) arg).getItems());
|
||||
@@ -149,9 +149,9 @@ public abstract class Fluff
|
||||
return args;
|
||||
}
|
||||
|
||||
public List<Value> unpackArgs(final List<LazyValue> lzargs, final Context c, final Context.Type contextType)
|
||||
public List<Value> unpackArgs(List<LazyValue> lzargs, Context c, Context.Type contextType)
|
||||
{
|
||||
final List<Value> args = unpackLazy(lzargs, c, contextType);
|
||||
List<Value> args = unpackLazy(lzargs, c, contextType);
|
||||
if (!numParamsVaries() && getNumParams() != args.size())
|
||||
{
|
||||
throw new InternalExpressionException("Function " + getName() + " expected " + getNumParams() + " parameters, got " + args.size());
|
||||
@@ -159,9 +159,9 @@ public abstract class Fluff
|
||||
return args;
|
||||
}
|
||||
|
||||
public static List<LazyValue> lazify(final List<Value> args)
|
||||
public static List<LazyValue> lazify(List<Value> args)
|
||||
{
|
||||
final List<LazyValue> lzargs = new ArrayList<>(args.size());
|
||||
List<LazyValue> lzargs = new ArrayList<>(args.size());
|
||||
args.forEach(v -> lzargs.add((c, t) -> v));
|
||||
return lzargs;
|
||||
}
|
||||
@@ -169,7 +169,7 @@ public abstract class Fluff
|
||||
|
||||
public abstract static class AbstractFunction extends AbstractLazyFunction implements IFunction
|
||||
{
|
||||
AbstractFunction(final int numParams, final String name)
|
||||
AbstractFunction(int numParams, String name)
|
||||
{
|
||||
super(numParams, name);
|
||||
}
|
||||
@@ -187,7 +187,7 @@ public abstract class Fluff
|
||||
}
|
||||
|
||||
@Override
|
||||
public LazyValue lazyEval(final Context cc, final Context.Type type, final Expression e, final Tokenizer.Token t, final List<LazyValue> lazyParams)
|
||||
public LazyValue lazyEval(Context cc, Context.Type type, Expression e, Tokenizer.Token t, List<LazyValue> lazyParams)
|
||||
{
|
||||
|
||||
return new LazyValue()
|
||||
@@ -195,20 +195,20 @@ public abstract class Fluff
|
||||
private List<Value> params;
|
||||
|
||||
@Override
|
||||
public Value evalValue(final Context c, final Context.Type type)
|
||||
public Value evalValue(Context c, Context.Type type)
|
||||
{
|
||||
ILazyFunction.checkInterrupts();
|
||||
try
|
||||
{
|
||||
return AbstractFunction.this.eval(getParams(c));
|
||||
}
|
||||
catch (final RuntimeException exc)
|
||||
catch (RuntimeException exc)
|
||||
{
|
||||
throw Expression.handleCodeException(cc, exc, e, t);
|
||||
}
|
||||
}
|
||||
|
||||
private List<Value> getParams(final Context c)
|
||||
private List<Value> getParams(Context c)
|
||||
{
|
||||
if (params == null)
|
||||
{
|
||||
@@ -231,7 +231,7 @@ public abstract class Fluff
|
||||
|
||||
boolean leftAssoc;
|
||||
|
||||
AbstractLazyOperator(final int precedence, final boolean leftAssoc)
|
||||
AbstractLazyOperator(int precedence, boolean leftAssoc)
|
||||
{
|
||||
super();
|
||||
this.precedence = precedence;
|
||||
@@ -255,7 +255,7 @@ public abstract class Fluff
|
||||
public abstract static class AbstractOperator extends AbstractLazyOperator implements IOperator
|
||||
{
|
||||
|
||||
AbstractOperator(final int precedence, final boolean leftAssoc)
|
||||
AbstractOperator(int precedence, boolean leftAssoc)
|
||||
{
|
||||
super(precedence, leftAssoc);
|
||||
}
|
||||
@@ -273,14 +273,14 @@ public abstract class Fluff
|
||||
}
|
||||
|
||||
@Override
|
||||
public LazyValue lazyEval(final Context cc, final Context.Type type, final Expression e, final Tokenizer.Token t, final LazyValue v1, final LazyValue v2)
|
||||
public LazyValue lazyEval(Context cc, Context.Type type, Expression e, Tokenizer.Token t, LazyValue v1, LazyValue v2)
|
||||
{
|
||||
return (c, typeIgnored) -> {
|
||||
try
|
||||
{
|
||||
return AbstractOperator.this.eval(v1.evalValue(c, Context.Type.NONE), v2.evalValue(c, Context.Type.NONE));
|
||||
}
|
||||
catch (final RuntimeException exc)
|
||||
catch (RuntimeException exc)
|
||||
{
|
||||
throw Expression.handleCodeException(cc, exc, e, t);
|
||||
}
|
||||
@@ -290,7 +290,7 @@ public abstract class Fluff
|
||||
|
||||
public abstract static class AbstractUnaryOperator extends AbstractOperator
|
||||
{
|
||||
AbstractUnaryOperator(final int precedence, final boolean leftAssoc)
|
||||
AbstractUnaryOperator(int precedence, boolean leftAssoc)
|
||||
{
|
||||
super(precedence, leftAssoc);
|
||||
}
|
||||
@@ -308,7 +308,7 @@ public abstract class Fluff
|
||||
}
|
||||
|
||||
@Override
|
||||
public LazyValue lazyEval(final Context cc, final Context.Type type, final Expression e, final Tokenizer.Token t, final LazyValue v1, final LazyValue v2)
|
||||
public LazyValue lazyEval(Context cc, Context.Type type, Expression e, Tokenizer.Token t, LazyValue v1, LazyValue v2)
|
||||
{
|
||||
if (v2 != null)
|
||||
{
|
||||
@@ -319,7 +319,7 @@ public abstract class Fluff
|
||||
{
|
||||
return AbstractUnaryOperator.this.evalUnary(v1.evalValue(c, Context.Type.NONE));
|
||||
}
|
||||
catch (final RuntimeException exc)
|
||||
catch (RuntimeException exc)
|
||||
{
|
||||
throw Expression.handleCodeException(cc, exc, e, t);
|
||||
}
|
||||
@@ -327,7 +327,7 @@ public abstract class Fluff
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value eval(final Value v1, final Value v2)
|
||||
public Value eval(Value v1, Value v2)
|
||||
{
|
||||
throw new IllegalStateException("Shouldn't end up here");
|
||||
}
|
||||
|
||||
@@ -13,14 +13,14 @@ public interface LazyValue
|
||||
LazyValue NULL = (c, t) -> Value.NULL;
|
||||
LazyValue ZERO = (c, t) -> Value.ZERO;
|
||||
|
||||
static LazyValue ofConstant(final Value val)
|
||||
static LazyValue ofConstant(Value val)
|
||||
{
|
||||
return new Constant(val);
|
||||
}
|
||||
|
||||
Value evalValue(Context c, Context.Type type);
|
||||
|
||||
default Value evalValue(final Context c)
|
||||
default Value evalValue(Context c)
|
||||
{
|
||||
return evalValue(c, Context.Type.NONE);
|
||||
}
|
||||
@@ -32,7 +32,7 @@ public interface LazyValue
|
||||
Value evalType(Context.Type type);
|
||||
|
||||
@Override
|
||||
default Value evalValue(final Context c, final Context.Type type)
|
||||
default Value evalValue(Context c, Context.Type type)
|
||||
{
|
||||
return evalType(type);
|
||||
}
|
||||
@@ -43,7 +43,7 @@ public interface LazyValue
|
||||
{
|
||||
Value result;
|
||||
|
||||
public Constant(final Value value)
|
||||
public Constant(Value value)
|
||||
{
|
||||
result = value;
|
||||
}
|
||||
@@ -54,14 +54,14 @@ public interface LazyValue
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value evalType(final Context.Type type)
|
||||
public Value evalType(Context.Type type)
|
||||
{
|
||||
|
||||
return result.fromConstant();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value evalValue(final Context c, final Context.Type type)
|
||||
public Value evalValue(Context c, Context.Type type)
|
||||
{
|
||||
return result.fromConstant();
|
||||
}
|
||||
|
||||
@@ -20,16 +20,16 @@ public record Module(String name, String code, boolean library)
|
||||
Objects.requireNonNull(code);
|
||||
}
|
||||
|
||||
public static Module fromPath(final Path path)
|
||||
public static Module fromPath(Path path)
|
||||
{
|
||||
final boolean library = path.getFileName().toString().endsWith(".scl");
|
||||
boolean library = path.getFileName().toString().endsWith(".scl");
|
||||
try
|
||||
{
|
||||
final String name = path.getFileName().toString().replaceFirst("\\.scl?", "").toLowerCase(Locale.ROOT);
|
||||
final String code = new String(Files.readAllBytes(path), StandardCharsets.UTF_8);
|
||||
String name = path.getFileName().toString().replaceFirst("\\.scl?", "").toLowerCase(Locale.ROOT);
|
||||
String code = new String(Files.readAllBytes(path), StandardCharsets.UTF_8);
|
||||
return new Module(name, code, library);
|
||||
}
|
||||
catch (final IOException e)
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new IllegalArgumentException("Failed to load scarpet module", e);
|
||||
}
|
||||
@@ -42,7 +42,7 @@ public record Module(String name, String code, boolean library)
|
||||
* @param isLibrary A {@link boolean} indicating whether or not the script is a library
|
||||
* @return The created {@link BundledModule}
|
||||
*/
|
||||
public static Module carpetNative(final String scriptName, final boolean isLibrary)
|
||||
public static Module carpetNative(String scriptName, boolean isLibrary)
|
||||
{
|
||||
return fromJarPath("assets/carpet/scripts/", scriptName, isLibrary);
|
||||
}
|
||||
@@ -56,7 +56,7 @@ public record Module(String name, String code, boolean library)
|
||||
* @return The created {@link BundledModule}
|
||||
* @see #fromJarPathWithCustomName(String, String, boolean)
|
||||
*/
|
||||
public static Module fromJarPath(final String path, final String scriptName, final boolean isLibrary)
|
||||
public static Module fromJarPath(String path, String scriptName, boolean isLibrary)
|
||||
{
|
||||
return fromJarPathWithCustomName(path + scriptName + (isLibrary ? ".scl" : ".sc"), scriptName, isLibrary);
|
||||
}
|
||||
@@ -70,26 +70,26 @@ public record Module(String name, String code, boolean library)
|
||||
* @return The created {@link Module}
|
||||
* @see #fromJarPath(String, String, boolean)
|
||||
*/
|
||||
public static Module fromJarPathWithCustomName(final String fullPath, final String customName, final boolean isLibrary)
|
||||
public static Module fromJarPathWithCustomName(String fullPath, String customName, boolean isLibrary)
|
||||
{
|
||||
try
|
||||
{
|
||||
final String name = customName.toLowerCase(Locale.ROOT);
|
||||
final String code = IOUtils.toString(
|
||||
String name = customName.toLowerCase(Locale.ROOT);
|
||||
String code = IOUtils.toString(
|
||||
Module.class.getClassLoader().getResourceAsStream(fullPath),
|
||||
StandardCharsets.UTF_8
|
||||
);
|
||||
return new Module(name, code, isLibrary);
|
||||
}
|
||||
catch (final IOException e)
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new IllegalArgumentException("Failed to load bundled module", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static Tag getData(final Module module, final ScriptServer scriptServer)
|
||||
public static Tag getData(Module module, ScriptServer scriptServer)
|
||||
{
|
||||
final Path dataFile = resolveResource(module, scriptServer);
|
||||
Path dataFile = resolveResource(module, scriptServer);
|
||||
if (dataFile == null || !Files.exists(dataFile) || !(Files.isRegularFile(dataFile)))
|
||||
{
|
||||
return null;
|
||||
@@ -100,9 +100,9 @@ public record Module(String name, String code, boolean library)
|
||||
}
|
||||
}
|
||||
|
||||
public static void saveData(final Module module, final Tag globalState, final ScriptServer scriptServer)
|
||||
public static void saveData(Module module, Tag globalState, ScriptServer scriptServer)
|
||||
{
|
||||
final Path dataFile = resolveResource(module, scriptServer);
|
||||
Path dataFile = resolveResource(module, scriptServer);
|
||||
if (dataFile == null)
|
||||
{
|
||||
return;
|
||||
@@ -113,7 +113,7 @@ public record Module(String name, String code, boolean library)
|
||||
{
|
||||
Files.createDirectories(dataFile.getParent());
|
||||
}
|
||||
catch (final IOException e)
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
@@ -124,7 +124,7 @@ public record Module(String name, String code, boolean library)
|
||||
}
|
||||
}
|
||||
|
||||
private static Path resolveResource(final Module module, final ScriptServer scriptServer)
|
||||
private static Path resolveResource(Module module, ScriptServer scriptServer)
|
||||
{
|
||||
return module == null ? null : scriptServer.resolveResource(module.name() + ".data.nbt");
|
||||
}
|
||||
|
||||
@@ -53,22 +53,22 @@ public class ScriptCommand
|
||||
|
||||
static
|
||||
{
|
||||
final Set<String> allFunctions = (new CarpetExpression(null, "null", null, null)).getExpr().getFunctionNames();
|
||||
Set<String> allFunctions = (new CarpetExpression(null, "null", null, null)).getExpr().getFunctionNames();
|
||||
scarpetFunctions = new TreeSet<>(Expression.none.getFunctionNames());
|
||||
APIFunctions = allFunctions.stream().filter(s -> !scarpetFunctions.contains(s)).collect(Collectors.toCollection(TreeSet::new));
|
||||
}
|
||||
|
||||
public static List<String> suggestFunctions(final ScriptHost host, String previous, final String prefix)
|
||||
public static List<String> suggestFunctions(ScriptHost host, String previous, String prefix)
|
||||
{
|
||||
previous = previous.replace("\\'", "");
|
||||
final int quoteCount = StringUtils.countMatches(previous, '\'');
|
||||
int quoteCount = StringUtils.countMatches(previous, '\'');
|
||||
if (quoteCount % 2 == 1)
|
||||
{
|
||||
return Collections.emptyList();
|
||||
}
|
||||
final int maxLen = prefix.length() < 3 ? (prefix.length() * 2 + 1) : 1234;
|
||||
final String eventPrefix = prefix.startsWith("__on_") ? prefix.substring(5) : null;
|
||||
final List<String> scarpetMatches = scarpetFunctions.stream().
|
||||
int maxLen = prefix.length() < 3 ? (prefix.length() * 2 + 1) : 1234;
|
||||
String eventPrefix = prefix.startsWith("__on_") ? prefix.substring(5) : null;
|
||||
List<String> scarpetMatches = scarpetFunctions.stream().
|
||||
filter(s -> s.startsWith(prefix) && s.length() <= maxLen).map(s -> s + "(").collect(Collectors.toList());
|
||||
scarpetMatches.addAll(APIFunctions.stream().
|
||||
filter(s -> s.startsWith(prefix) && s.length() <= maxLen).map(s -> s + "(").toList());
|
||||
@@ -84,17 +84,17 @@ public class ScriptCommand
|
||||
}
|
||||
|
||||
private static CompletableFuture<Suggestions> suggestCode(
|
||||
final CommandContext<CommandSourceStack> context,
|
||||
final SuggestionsBuilder suggestionsBuilder
|
||||
CommandContext<CommandSourceStack> context,
|
||||
SuggestionsBuilder suggestionsBuilder
|
||||
) throws CommandSyntaxException
|
||||
{
|
||||
final CarpetScriptHost currentHost = getHost(context);
|
||||
final String previous = suggestionsBuilder.getRemaining();
|
||||
final int strlen = previous.length();
|
||||
final StringBuilder lastToken = new StringBuilder();
|
||||
CarpetScriptHost currentHost = getHost(context);
|
||||
String previous = suggestionsBuilder.getRemaining();
|
||||
int strlen = previous.length();
|
||||
StringBuilder lastToken = new StringBuilder();
|
||||
for (int idx = strlen - 1; idx >= 0; idx--)
|
||||
{
|
||||
final char ch = previous.charAt(idx);
|
||||
char ch = previous.charAt(idx);
|
||||
if (Character.isLetterOrDigit(ch) || ch == '_')
|
||||
{
|
||||
lastToken.append(ch);
|
||||
@@ -108,8 +108,8 @@ public class ScriptCommand
|
||||
{
|
||||
return suggestionsBuilder.buildFuture();
|
||||
}
|
||||
final String prefix = lastToken.reverse().toString();
|
||||
final String previousString = previous.substring(0, previous.length() - prefix.length());
|
||||
String prefix = lastToken.reverse().toString();
|
||||
String previousString = previous.substring(0, previous.length() - prefix.length());
|
||||
suggestFunctions(currentHost, previousString, prefix).forEach(text -> suggestionsBuilder.suggest(previousString + text));
|
||||
return suggestionsBuilder.buildFuture();
|
||||
}
|
||||
@@ -119,18 +119,18 @@ public class ScriptCommand
|
||||
* variable.
|
||||
*/
|
||||
private static CompletableFuture<Suggestions> suggestDownloadableApps(
|
||||
final CommandContext<CommandSourceStack> context,
|
||||
final SuggestionsBuilder suggestionsBuilder
|
||||
CommandContext<CommandSourceStack> context,
|
||||
SuggestionsBuilder suggestionsBuilder
|
||||
) throws CommandSyntaxException
|
||||
{
|
||||
|
||||
return CompletableFuture.supplyAsync(() -> {
|
||||
final String previous = suggestionsBuilder.getRemaining();
|
||||
String previous = suggestionsBuilder.getRemaining();
|
||||
try
|
||||
{
|
||||
AppStoreManager.suggestionsFromPath(previous).forEach(suggestionsBuilder::suggest);
|
||||
}
|
||||
catch (final IOException e)
|
||||
catch (IOException e)
|
||||
{
|
||||
CarpetScriptServer.LOG.warn("Exception when fetching app store structure", e);
|
||||
}
|
||||
@@ -138,33 +138,33 @@ public class ScriptCommand
|
||||
});
|
||||
}
|
||||
|
||||
private static CarpetScriptServer ss(final CommandContext<CommandSourceStack> context)
|
||||
private static CarpetScriptServer ss(CommandContext<CommandSourceStack> context)
|
||||
{
|
||||
return Vanilla.MinecraftServer_getScriptServer(context.getSource().getServer());
|
||||
}
|
||||
|
||||
public static void register(final CommandDispatcher<CommandSourceStack> dispatcher, final CommandBuildContext commandBuildContext)
|
||||
public static void register(CommandDispatcher<CommandSourceStack> dispatcher, CommandBuildContext commandBuildContext)
|
||||
{
|
||||
final LiteralArgumentBuilder<CommandSourceStack> b = literal("globals").
|
||||
LiteralArgumentBuilder<CommandSourceStack> b = literal("globals").
|
||||
executes(context -> listGlobals(context, false)).
|
||||
then(literal("all").executes(context -> listGlobals(context, true)));
|
||||
final LiteralArgumentBuilder<CommandSourceStack> o = literal("stop").
|
||||
LiteralArgumentBuilder<CommandSourceStack> o = literal("stop").
|
||||
executes((cc) -> {
|
||||
ss(cc).stopAll = true;
|
||||
return 1;
|
||||
});
|
||||
final LiteralArgumentBuilder<CommandSourceStack> u = literal("resume").
|
||||
LiteralArgumentBuilder<CommandSourceStack> u = literal("resume").
|
||||
executes((cc) -> {
|
||||
ss(cc).stopAll = false;
|
||||
return 1;
|
||||
});
|
||||
final LiteralArgumentBuilder<CommandSourceStack> l = literal("run").
|
||||
LiteralArgumentBuilder<CommandSourceStack> l = literal("run").
|
||||
requires(Vanilla::ServerPlayer_canScriptACE).
|
||||
then(argument("expr", StringArgumentType.greedyString()).suggests(ScriptCommand::suggestCode).
|
||||
executes((cc) -> compute(
|
||||
cc,
|
||||
StringArgumentType.getString(cc, "expr"))));
|
||||
final LiteralArgumentBuilder<CommandSourceStack> s = literal("invoke").
|
||||
LiteralArgumentBuilder<CommandSourceStack> s = literal("invoke").
|
||||
then(argument("call", StringArgumentType.word()).suggests((cc, bb) -> suggest(suggestFunctionCalls(cc), bb)).
|
||||
executes((cc) -> invoke(
|
||||
cc,
|
||||
@@ -181,7 +181,7 @@ public class ScriptCommand
|
||||
null,
|
||||
StringArgumentType.getString(cc, "arguments")
|
||||
))));
|
||||
final LiteralArgumentBuilder<CommandSourceStack> c = literal("invokepoint").
|
||||
LiteralArgumentBuilder<CommandSourceStack> c = literal("invokepoint").
|
||||
then(argument("call", StringArgumentType.word()).suggests((cc, bb) -> suggest(suggestFunctionCalls(cc), bb)).
|
||||
then(argument("origin", BlockPosArgument.blockPos()).
|
||||
executes((cc) -> invoke(
|
||||
@@ -199,7 +199,7 @@ public class ScriptCommand
|
||||
null,
|
||||
StringArgumentType.getString(cc, "arguments")
|
||||
)))));
|
||||
final LiteralArgumentBuilder<CommandSourceStack> h = literal("invokearea").
|
||||
LiteralArgumentBuilder<CommandSourceStack> h = literal("invokearea").
|
||||
then(argument("call", StringArgumentType.word()).suggests((cc, bb) -> suggest(suggestFunctionCalls(cc), bb)).
|
||||
then(argument("from", BlockPosArgument.blockPos()).
|
||||
then(argument("to", BlockPosArgument.blockPos()).
|
||||
@@ -218,7 +218,7 @@ public class ScriptCommand
|
||||
BlockPosArgument.getSpawnablePos(cc, "to"),
|
||||
StringArgumentType.getString(cc, "arguments")
|
||||
))))));
|
||||
final LiteralArgumentBuilder<CommandSourceStack> i = literal("scan").requires((player) -> player.hasPermission(2)).
|
||||
LiteralArgumentBuilder<CommandSourceStack> i = literal("scan").requires((player) -> player.hasPermission(2)).
|
||||
then(argument("origin", BlockPosArgument.blockPos()).
|
||||
then(argument("from", BlockPosArgument.blockPos()).
|
||||
then(argument("to", BlockPosArgument.blockPos()).
|
||||
@@ -231,7 +231,7 @@ public class ScriptCommand
|
||||
BlockPosArgument.getSpawnablePos(cc, "to"),
|
||||
StringArgumentType.getString(cc, "expr")
|
||||
))))));
|
||||
final LiteralArgumentBuilder<CommandSourceStack> e = literal("fill").requires((player) -> player.hasPermission(2)).
|
||||
LiteralArgumentBuilder<CommandSourceStack> e = literal("fill").requires((player) -> player.hasPermission(2)).
|
||||
then(argument("origin", BlockPosArgument.blockPos()).
|
||||
then(argument("from", BlockPosArgument.blockPos()).
|
||||
then(argument("to", BlockPosArgument.blockPos()).
|
||||
@@ -258,7 +258,7 @@ public class ScriptCommand
|
||||
BlockPredicateArgument.getBlockPredicate(cc, "filter"),
|
||||
"solid"
|
||||
)))))))));
|
||||
final LiteralArgumentBuilder<CommandSourceStack> t = literal("outline").requires((player) -> player.hasPermission(2)).
|
||||
LiteralArgumentBuilder<CommandSourceStack> t = literal("outline").requires((player) -> player.hasPermission(2)).
|
||||
then(argument("origin", BlockPosArgument.blockPos()).
|
||||
then(argument("from", BlockPosArgument.blockPos()).
|
||||
then(argument("to", BlockPosArgument.blockPos()).
|
||||
@@ -285,33 +285,33 @@ public class ScriptCommand
|
||||
BlockPredicateArgument.getBlockPredicate(cc, "filter"),
|
||||
"outline"
|
||||
)))))))));
|
||||
final LiteralArgumentBuilder<CommandSourceStack> a = literal("load").requires(Vanilla::ServerPlayer_canScriptACE).
|
||||
LiteralArgumentBuilder<CommandSourceStack> a = literal("load").requires(Vanilla::ServerPlayer_canScriptACE).
|
||||
then(argument("app", StringArgumentType.word()).
|
||||
suggests((cc, bb) -> suggest(ss(cc).listAvailableModules(true), bb)).
|
||||
executes((cc) ->
|
||||
{
|
||||
final boolean success = ss(cc).addScriptHost(cc.getSource(), StringArgumentType.getString(cc, "app"), null, true, false, false, null);
|
||||
boolean success = ss(cc).addScriptHost(cc.getSource(), StringArgumentType.getString(cc, "app"), null, true, false, false, null);
|
||||
return success ? 1 : 0;
|
||||
}).
|
||||
then(literal("global").
|
||||
executes((cc) ->
|
||||
{
|
||||
final boolean success = ss(cc).addScriptHost(cc.getSource(), StringArgumentType.getString(cc, "app"), null, false, false, false, null);
|
||||
boolean success = ss(cc).addScriptHost(cc.getSource(), StringArgumentType.getString(cc, "app"), null, false, false, false, null);
|
||||
return success ? 1 : 0;
|
||||
}
|
||||
)
|
||||
)
|
||||
);
|
||||
final LiteralArgumentBuilder<CommandSourceStack> f = literal("unload").requires(Vanilla::ServerPlayer_canScriptACE).
|
||||
LiteralArgumentBuilder<CommandSourceStack> f = literal("unload").requires(Vanilla::ServerPlayer_canScriptACE).
|
||||
then(argument("app", StringArgumentType.word()).
|
||||
suggests((cc, bb) -> suggest(ss(cc).unloadableModules, bb)).
|
||||
executes((cc) ->
|
||||
{
|
||||
final boolean success = ss(cc).removeScriptHost(cc.getSource(), StringArgumentType.getString(cc, "app"), true, false);
|
||||
boolean success = ss(cc).removeScriptHost(cc.getSource(), StringArgumentType.getString(cc, "app"), true, false);
|
||||
return success ? 1 : 0;
|
||||
}));
|
||||
|
||||
final LiteralArgumentBuilder<CommandSourceStack> q = literal("event").requires(Vanilla::ServerPlayer_canScriptACE).
|
||||
LiteralArgumentBuilder<CommandSourceStack> q = literal("event").requires(Vanilla::ServerPlayer_canScriptACE).
|
||||
executes(ScriptCommand::listEvents).
|
||||
then(literal("add_to").
|
||||
then(argument("event", StringArgumentType.word()).
|
||||
@@ -346,16 +346,16 @@ public class ScriptCommand
|
||||
StringArgumentType.getString(cc, "call")
|
||||
) ? 1 : 0))));
|
||||
|
||||
final LiteralArgumentBuilder<CommandSourceStack> d = literal("download").requires(Vanilla::ServerPlayer_canScriptACE).
|
||||
LiteralArgumentBuilder<CommandSourceStack> d = literal("download").requires(Vanilla::ServerPlayer_canScriptACE).
|
||||
then(argument("path", StringArgumentType.greedyString()).
|
||||
suggests(ScriptCommand::suggestDownloadableApps).
|
||||
executes(cc -> AppStoreManager.downloadScript(cc.getSource(), StringArgumentType.getString(cc, "path"))));
|
||||
final LiteralArgumentBuilder<CommandSourceStack> r = literal("remove").requires(Vanilla::ServerPlayer_canScriptACE).
|
||||
LiteralArgumentBuilder<CommandSourceStack> r = literal("remove").requires(Vanilla::ServerPlayer_canScriptACE).
|
||||
then(argument("app", StringArgumentType.word()).
|
||||
suggests((cc, bb) -> suggest(ss(cc).unloadableModules, bb)).
|
||||
executes((cc) ->
|
||||
{
|
||||
final boolean success = ss(cc).uninstallApp(cc.getSource(), StringArgumentType.getString(cc, "app"));
|
||||
boolean success = ss(cc).uninstallApp(cc.getSource(), StringArgumentType.getString(cc, "app"));
|
||||
return success ? 1 : 0;
|
||||
}));
|
||||
|
||||
@@ -370,17 +370,17 @@ public class ScriptCommand
|
||||
then(b).then(u).then(o).then(l).then(s).then(c).then(h).then(i).then(e).then(t))));
|
||||
}
|
||||
|
||||
private static CarpetScriptHost getHost(final CommandContext<CommandSourceStack> context) throws CommandSyntaxException
|
||||
private static CarpetScriptHost getHost(CommandContext<CommandSourceStack> context) throws CommandSyntaxException
|
||||
{
|
||||
CarpetScriptHost host;
|
||||
final CarpetScriptServer scriptServer = ss(context);
|
||||
CarpetScriptServer scriptServer = ss(context);
|
||||
try
|
||||
{
|
||||
final String name = StringArgumentType.getString(context, "app").toLowerCase(Locale.ROOT);
|
||||
final CarpetScriptHost parentHost = scriptServer.modules.getOrDefault(name, scriptServer.globalHost);
|
||||
String name = StringArgumentType.getString(context, "app").toLowerCase(Locale.ROOT);
|
||||
CarpetScriptHost parentHost = scriptServer.modules.getOrDefault(name, scriptServer.globalHost);
|
||||
host = parentHost.retrieveOwnForExecution(context.getSource());
|
||||
}
|
||||
catch (final IllegalArgumentException ignored)
|
||||
catch (IllegalArgumentException ignored)
|
||||
{
|
||||
host = scriptServer.globalHost;
|
||||
}
|
||||
@@ -388,21 +388,21 @@ public class ScriptCommand
|
||||
return host;
|
||||
}
|
||||
|
||||
private static Collection<String> suggestFunctionCalls(final CommandContext<CommandSourceStack> c) throws CommandSyntaxException
|
||||
private static Collection<String> suggestFunctionCalls(CommandContext<CommandSourceStack> c) throws CommandSyntaxException
|
||||
{
|
||||
final CarpetScriptHost host = getHost(c);
|
||||
CarpetScriptHost host = getHost(c);
|
||||
return host.globalFunctionNames(host.main, s -> !s.startsWith("_")).sorted().collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private static int listEvents(final CommandContext<CommandSourceStack> context)
|
||||
private static int listEvents(CommandContext<CommandSourceStack> context)
|
||||
{
|
||||
CarpetScriptServer scriptServer = ss(context);
|
||||
CommandSourceStack source = context.getSource();
|
||||
Carpet.Messenger_message(source, "w Lists ALL event handlers:");
|
||||
for (final CarpetEventServer.Event event : CarpetEventServer.Event.getAllEvents(scriptServer, null))
|
||||
for (CarpetEventServer.Event event : CarpetEventServer.Event.getAllEvents(scriptServer, null))
|
||||
{
|
||||
boolean shownEvent = false;
|
||||
for (final CarpetEventServer.Callback c : event.handler.inspectCurrentCalls())
|
||||
for (CarpetEventServer.Callback c : event.handler.inspectCurrentCalls())
|
||||
{
|
||||
if (!shownEvent)
|
||||
{
|
||||
@@ -415,26 +415,26 @@ public class ScriptCommand
|
||||
return 1;
|
||||
}
|
||||
|
||||
private static int listGlobals(final CommandContext<CommandSourceStack> context, final boolean all) throws CommandSyntaxException
|
||||
private static int listGlobals(CommandContext<CommandSourceStack> context, boolean all) throws CommandSyntaxException
|
||||
{
|
||||
final CarpetScriptHost host = getHost(context);
|
||||
final CommandSourceStack source = context.getSource();
|
||||
final CarpetScriptServer scriptServer = ss(context);
|
||||
CarpetScriptHost host = getHost(context);
|
||||
CommandSourceStack source = context.getSource();
|
||||
CarpetScriptServer scriptServer = ss(context);
|
||||
|
||||
Carpet.Messenger_message(source, "lb Stored functions" + ((host == scriptServer.globalHost) ? ":" : " in " + host.getName() + ":"));
|
||||
host.globalFunctionNames(host.main, (str) -> all || !str.startsWith("__")).sorted().forEach((s) -> {
|
||||
final FunctionValue fun = host.getFunction(s);
|
||||
FunctionValue fun = host.getFunction(s);
|
||||
if (fun == null)
|
||||
{
|
||||
Carpet.Messenger_message(source, "gb " + s, "g - unused import");
|
||||
Carpet.Messenger_message(source, "gi ----------------");
|
||||
return;
|
||||
}
|
||||
final Expression expr = fun.getExpression();
|
||||
final Tokenizer.Token tok = fun.getToken();
|
||||
final List<String> snippet = expr.getExpressionSnippet(tok);
|
||||
Expression expr = fun.getExpression();
|
||||
Tokenizer.Token tok = fun.getToken();
|
||||
List<String> snippet = expr.getExpressionSnippet(tok);
|
||||
Carpet.Messenger_message(source, "wb " + fun.fullName(), "t defined at: line " + (tok.lineno + 1) + " pos " + (tok.linepos + 1));
|
||||
for (final String snippetLine : snippet)
|
||||
for (String snippetLine : snippet)
|
||||
{
|
||||
Carpet.Messenger_message(source, "w " + snippetLine);
|
||||
}
|
||||
@@ -444,7 +444,7 @@ public class ScriptCommand
|
||||
Carpet.Messenger_message(source, "w ");
|
||||
Carpet.Messenger_message(source, "lb Global variables" + ((host == scriptServer.globalHost) ? ":" : " in " + host.getName() + ":"));
|
||||
host.globalVariableNames(host.main, (s) -> s.startsWith("global_")).sorted().forEach((s) -> {
|
||||
final LazyValue variable = host.getGlobalVariable(s);
|
||||
LazyValue variable = host.getGlobalVariable(s);
|
||||
if (variable == null)
|
||||
{
|
||||
Carpet.Messenger_message(source, "gb " + s, "g - unused import");
|
||||
@@ -457,14 +457,14 @@ public class ScriptCommand
|
||||
return 1;
|
||||
}
|
||||
|
||||
public static int handleCall(final CommandSourceStack source, final CarpetScriptHost host, final Supplier<Value> call)
|
||||
public static int handleCall(CommandSourceStack source, CarpetScriptHost host, Supplier<Value> call)
|
||||
{
|
||||
try
|
||||
{
|
||||
final Runnable token = Carpet.startProfilerSection("Scarpet run");
|
||||
Runnable token = Carpet.startProfilerSection("Scarpet run");
|
||||
host.setChatErrorSnooper(source);
|
||||
final long start = System.nanoTime();
|
||||
final Value result = call.get();
|
||||
long start = System.nanoTime();
|
||||
Value result = call.get();
|
||||
long time = ((System.nanoTime() - start) / 1000);
|
||||
String metric = "\u00B5s";
|
||||
if (time > 5000)
|
||||
@@ -478,19 +478,19 @@ public class ScriptCommand
|
||||
metric = "s";
|
||||
}
|
||||
Carpet.Messenger_message(source, "wi = ", "wb " + result.getString(), "gi (" + time + metric + ")");
|
||||
final int intres = (int) result.readInteger();
|
||||
int intres = (int) result.readInteger();
|
||||
token.run();
|
||||
return intres;
|
||||
}
|
||||
catch (final CarpetExpressionException e)
|
||||
catch (CarpetExpressionException e)
|
||||
{
|
||||
host.handleErrorWithStack("Error while evaluating expression", e);
|
||||
}
|
||||
catch (final ArithmeticException ae)
|
||||
catch (ArithmeticException ae)
|
||||
{
|
||||
host.handleErrorWithStack("Math doesn't compute", ae);
|
||||
}
|
||||
catch (final StackOverflowError soe)
|
||||
catch (StackOverflowError soe)
|
||||
{
|
||||
host.handleErrorWithStack("Your thoughts are too deep", soe);
|
||||
}
|
||||
@@ -498,16 +498,16 @@ public class ScriptCommand
|
||||
//host.resetErrorSnooper(); // lets say no need to reset the snooper in case something happens on the way
|
||||
}
|
||||
|
||||
private static int invoke(final CommandContext<CommandSourceStack> context, final String call, final BlockPos pos1, final BlockPos pos2, final String args) throws CommandSyntaxException
|
||||
private static int invoke(CommandContext<CommandSourceStack> context, String call, BlockPos pos1, BlockPos pos2, String args) throws CommandSyntaxException
|
||||
{
|
||||
final CommandSourceStack source = context.getSource();
|
||||
final CarpetScriptHost host = getHost(context);
|
||||
CommandSourceStack source = context.getSource();
|
||||
CarpetScriptHost host = getHost(context);
|
||||
if (call.startsWith("__"))
|
||||
{
|
||||
Carpet.Messenger_message(source, "r Hidden functions are only callable in scripts");
|
||||
return 0;
|
||||
}
|
||||
final List<Integer> positions = new ArrayList<>();
|
||||
List<Integer> positions = new ArrayList<>();
|
||||
if (pos1 != null)
|
||||
{
|
||||
positions.add(pos1.getX());
|
||||
@@ -526,23 +526,23 @@ public class ScriptCommand
|
||||
}
|
||||
|
||||
|
||||
private static int compute(final CommandContext<CommandSourceStack> context, final String expr) throws CommandSyntaxException
|
||||
private static int compute(CommandContext<CommandSourceStack> context, String expr) throws CommandSyntaxException
|
||||
{
|
||||
final CommandSourceStack source = context.getSource();
|
||||
final CarpetScriptHost host = getHost(context);
|
||||
CommandSourceStack source = context.getSource();
|
||||
CarpetScriptHost host = getHost(context);
|
||||
return handleCall(source, host, () -> {
|
||||
final CarpetExpression ex = new CarpetExpression(host.main, expr, source, new BlockPos(0, 0, 0));
|
||||
CarpetExpression ex = new CarpetExpression(host.main, expr, source, new BlockPos(0, 0, 0));
|
||||
return ex.scriptRunCommand(host, new BlockPos(source.getPosition()));
|
||||
});
|
||||
}
|
||||
|
||||
private static int scriptScan(final CommandContext<CommandSourceStack> context, final BlockPos origin, final BlockPos a, final BlockPos b, final String expr) throws CommandSyntaxException
|
||||
private static int scriptScan(CommandContext<CommandSourceStack> context, BlockPos origin, BlockPos a, BlockPos b, String expr) throws CommandSyntaxException
|
||||
{
|
||||
final CommandSourceStack source = context.getSource();
|
||||
final CarpetScriptHost host = getHost(context);
|
||||
final BoundingBox area = BoundingBox.fromCorners(a, b);
|
||||
final CarpetExpression cexpr = new CarpetExpression(host.main, expr, source, origin);
|
||||
final int int_1 = area.getXSpan() * area.getYSpan() * area.getZSpan(); // X Y Z
|
||||
CommandSourceStack source = context.getSource();
|
||||
CarpetScriptHost host = getHost(context);
|
||||
BoundingBox area = BoundingBox.fromCorners(a, b);
|
||||
CarpetExpression cexpr = new CarpetExpression(host.main, expr, source, origin);
|
||||
int int_1 = area.getXSpan() * area.getYSpan() * area.getZSpan(); // X Y Z
|
||||
if (int_1 > Vanilla.MinecraftServer_getFillLimit(source.getServer()) )
|
||||
{
|
||||
Carpet.Messenger_message(source, "r too many blocks to evaluate: " + int_1);
|
||||
@@ -565,14 +565,14 @@ public class ScriptCommand
|
||||
successCount++;
|
||||
}
|
||||
}
|
||||
catch (final ArithmeticException ignored)
|
||||
catch (ArithmeticException ignored)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (final CarpetExpressionException exc)
|
||||
catch (CarpetExpressionException exc)
|
||||
{
|
||||
host.handleErrorWithStack("Error while processing command", exc);
|
||||
return 0;
|
||||
@@ -587,14 +587,14 @@ public class ScriptCommand
|
||||
}
|
||||
|
||||
|
||||
private static int scriptFill(final CommandContext<CommandSourceStack> context, final BlockPos origin, final BlockPos a, final BlockPos b, final String expr,
|
||||
final BlockInput block, final Predicate<BlockInWorld> replacement, final String mode) throws CommandSyntaxException
|
||||
private static int scriptFill(CommandContext<CommandSourceStack> context, BlockPos origin, BlockPos a, BlockPos b, String expr,
|
||||
BlockInput block, Predicate<BlockInWorld> replacement, String mode) throws CommandSyntaxException
|
||||
{
|
||||
final CommandSourceStack source = context.getSource();
|
||||
final CarpetScriptHost host = getHost(context);
|
||||
final BoundingBox area = BoundingBox.fromCorners(a, b);
|
||||
final CarpetExpression cexpr = new CarpetExpression(host.main, expr, source, origin);
|
||||
final int int_1 = area.getXSpan() * area.getYSpan() * area.getZSpan();
|
||||
CommandSourceStack source = context.getSource();
|
||||
CarpetScriptHost host = getHost(context);
|
||||
BoundingBox area = BoundingBox.fromCorners(a, b);
|
||||
CarpetExpression cexpr = new CarpetExpression(host.main, expr, source, origin);
|
||||
int int_1 = area.getXSpan() * area.getYSpan() * area.getZSpan();
|
||||
if (int_1 > Vanilla.MinecraftServer_getFillLimit(source.getServer()))
|
||||
{
|
||||
Carpet.Messenger_message(source, "r too many blocks to evaluate: " + int_1);
|
||||
@@ -603,8 +603,8 @@ public class ScriptCommand
|
||||
|
||||
boolean[][][] volume = new boolean[area.getXSpan()][area.getYSpan()][area.getZSpan()]; //X then Y then Z got messedup
|
||||
|
||||
final BlockPos.MutableBlockPos mbpos = origin.mutable();
|
||||
final ServerLevel world = source.getLevel();
|
||||
BlockPos.MutableBlockPos mbpos = origin.mutable();
|
||||
ServerLevel world = source.getLevel();
|
||||
|
||||
for (int x = area.minX(); x <= area.maxX(); x++)
|
||||
{
|
||||
@@ -619,23 +619,23 @@ public class ScriptCommand
|
||||
volume[x - area.minX()][y - area.minY()][z - area.minZ()] = true;
|
||||
}
|
||||
}
|
||||
catch (final CarpetExpressionException e)
|
||||
catch (CarpetExpressionException e)
|
||||
{
|
||||
host.handleErrorWithStack("Exception while filling the area", e);
|
||||
return 0;
|
||||
}
|
||||
catch (final ArithmeticException e)
|
||||
catch (ArithmeticException e)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
final int maxx = area.getXSpan() - 1;
|
||||
final int maxy = area.getYSpan() - 1;
|
||||
final int maxz = area.getZSpan() - 1;
|
||||
int maxx = area.getXSpan() - 1;
|
||||
int maxy = area.getYSpan() - 1;
|
||||
int maxz = area.getZSpan() - 1;
|
||||
if ("outline".equalsIgnoreCase(mode))
|
||||
{
|
||||
final boolean[][][] newVolume = new boolean[area.getXSpan()][area.getYSpan()][area.getZSpan()];
|
||||
boolean[][][] newVolume = new boolean[area.getXSpan()][area.getYSpan()][area.getZSpan()];
|
||||
for (int x = 0; x <= maxx; x++)
|
||||
{
|
||||
for (int y = 0; y <= maxy; y++)
|
||||
@@ -675,7 +675,7 @@ public class ScriptCommand
|
||||
if (replacement == null || replacement.test(
|
||||
new BlockInWorld(world, mbpos, true)))
|
||||
{
|
||||
final BlockEntity tileentity = world.getBlockEntity(mbpos);
|
||||
BlockEntity tileentity = world.getBlockEntity(mbpos);
|
||||
Clearable.tryClear(tileentity);
|
||||
|
||||
if (block.place(world, mbpos, 2))
|
||||
@@ -700,7 +700,7 @@ public class ScriptCommand
|
||||
if (volume[x][y][z])
|
||||
{
|
||||
mbpos.set(x + area.minX(), y + area.minY(), z + area.minZ());
|
||||
final Block blokc = world.getBlockState(mbpos).getBlock();
|
||||
Block blokc = world.getBlockState(mbpos).getBlock();
|
||||
world.blockUpdated(mbpos, blokc);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ public abstract class ScriptHost
|
||||
|
||||
private final Set<String> deprecations = new HashSet<>();
|
||||
|
||||
public Random getRandom(final long aLong)
|
||||
public Random getRandom(long aLong)
|
||||
{
|
||||
if (randomizers.size() > 65536)
|
||||
{
|
||||
@@ -48,12 +48,12 @@ public abstract class ScriptHost
|
||||
return randomizers.computeIfAbsent(aLong, Random::new);
|
||||
}
|
||||
|
||||
public boolean resetRandom(final long aLong)
|
||||
public boolean resetRandom(long aLong)
|
||||
{
|
||||
return randomizers.remove(aLong) != null;
|
||||
}
|
||||
|
||||
public Path resolveScriptFile(final String suffix)
|
||||
public Path resolveScriptFile(String suffix)
|
||||
{
|
||||
return scriptServer.resolveResource(suffix);
|
||||
}
|
||||
@@ -67,7 +67,7 @@ public abstract class ScriptHost
|
||||
public final Map<String, ModuleData> globalsImports = new Object2ObjectOpenHashMap<>(); // imported global variables string to module
|
||||
public final Map<String, ModuleData> futureImports = new Object2ObjectOpenHashMap<>(); // imports not known before used
|
||||
|
||||
public ModuleData(final Module parent, final ModuleData other)
|
||||
public ModuleData(Module parent, ModuleData other)
|
||||
{
|
||||
super();
|
||||
// imports are just pointers, but they still point to the wrong modules (point to the parent)
|
||||
@@ -75,14 +75,14 @@ public abstract class ScriptHost
|
||||
globalFunctions.putAll(other.globalFunctions);
|
||||
other.globalVariables.forEach((key, value) ->
|
||||
{
|
||||
final Value var = value.evalValue(null);
|
||||
final Value copy = var.deepcopy();
|
||||
Value var = value.evalValue(null);
|
||||
Value copy = var.deepcopy();
|
||||
copy.boundVariable = var.boundVariable;
|
||||
globalVariables.put(key, (c, t) -> copy);
|
||||
});
|
||||
}
|
||||
|
||||
public void setImportsBasedOn(final ScriptHost host, final ModuleData other)
|
||||
public void setImportsBasedOn(ScriptHost host, ModuleData other)
|
||||
{
|
||||
// fixing imports
|
||||
other.functionImports.forEach((name, targetData) -> {
|
||||
@@ -97,7 +97,7 @@ public abstract class ScriptHost
|
||||
|
||||
}
|
||||
|
||||
public ModuleData(final Module parent)
|
||||
public ModuleData(Module parent)
|
||||
{
|
||||
this.parent = parent;
|
||||
}
|
||||
@@ -126,7 +126,7 @@ public abstract class ScriptHost
|
||||
|
||||
public ErrorSnooper errorSnooper = null;
|
||||
|
||||
protected ScriptHost(final Module code, final ScriptServer scriptServer, final boolean perUser, final ScriptHost parent)
|
||||
protected ScriptHost(Module code, ScriptServer scriptServer, boolean perUser, ScriptHost parent)
|
||||
{
|
||||
this.parent = parent;
|
||||
this.main = code;
|
||||
@@ -134,30 +134,30 @@ public abstract class ScriptHost
|
||||
this.user = null;
|
||||
this.strict = false;
|
||||
this.scriptServer = scriptServer;
|
||||
final ModuleData moduleData = new ModuleData(code);
|
||||
ModuleData moduleData = new ModuleData(code);
|
||||
initializeModuleGlobals(moduleData);
|
||||
this.moduleData.put(code, moduleData);
|
||||
this.modules.put(code == null ? null : code.name(), code);
|
||||
mainThread = Thread.currentThread();
|
||||
}
|
||||
|
||||
void initializeModuleGlobals(final ModuleData md)
|
||||
void initializeModuleGlobals(ModuleData md)
|
||||
{
|
||||
}
|
||||
|
||||
public void importModule(final Context c, final String moduleName)
|
||||
public void importModule(Context c, String moduleName)
|
||||
{
|
||||
if (modules.containsKey(moduleName.toLowerCase(Locale.ROOT)))
|
||||
{
|
||||
return; // aready imported
|
||||
}
|
||||
final Module module = getModuleOrLibraryByName(moduleName);
|
||||
Module module = getModuleOrLibraryByName(moduleName);
|
||||
if (modules.containsKey(module.name()))
|
||||
{
|
||||
return; // aready imported, once again, in case some discrepancies in names?
|
||||
}
|
||||
modules.put(module.name(), module);
|
||||
final ModuleData data = new ModuleData(module);
|
||||
ModuleData data = new ModuleData(module);
|
||||
initializeModuleGlobals(data);
|
||||
moduleData.put(module, data);
|
||||
runModuleCode(c, module);
|
||||
@@ -166,20 +166,20 @@ public abstract class ScriptHost
|
||||
//throw new InternalExpressionException("Failed to import a module "+moduleName);
|
||||
}
|
||||
|
||||
public void importNames(final Context c, final Module targetModule, final String sourceModuleName, final List<String> identifiers)
|
||||
public void importNames(Context c, Module targetModule, String sourceModuleName, List<String> identifiers)
|
||||
{
|
||||
if (!moduleData.containsKey(targetModule))
|
||||
{
|
||||
throw new InternalExpressionException("Cannot import to module that doesn't exist");
|
||||
}
|
||||
final Module source = modules.get(sourceModuleName);
|
||||
final ModuleData sourceData = moduleData.get(source);
|
||||
final ModuleData targetData = moduleData.get(targetModule);
|
||||
Module source = modules.get(sourceModuleName);
|
||||
ModuleData sourceData = moduleData.get(source);
|
||||
ModuleData targetData = moduleData.get(targetModule);
|
||||
if (sourceData == null || targetData == null)
|
||||
{
|
||||
throw new InternalExpressionException("Cannot import from module that is not imported");
|
||||
}
|
||||
for (final String identifier : identifiers)
|
||||
for (String identifier : identifiers)
|
||||
{
|
||||
if (sourceData.globalFunctions.containsKey(identifier))
|
||||
{
|
||||
@@ -196,10 +196,10 @@ public abstract class ScriptHost
|
||||
}
|
||||
}
|
||||
|
||||
public Stream<String> availableImports(final String moduleName)
|
||||
public Stream<String> availableImports(String moduleName)
|
||||
{
|
||||
final Module source = modules.get(moduleName);
|
||||
final ModuleData sourceData = moduleData.get(source);
|
||||
Module source = modules.get(moduleName);
|
||||
ModuleData sourceData = moduleData.get(source);
|
||||
if (sourceData == null)
|
||||
{
|
||||
throw new InternalExpressionException("Cannot import from module that is not imported");
|
||||
@@ -214,14 +214,14 @@ public abstract class ScriptHost
|
||||
|
||||
protected abstract void runModuleCode(Context c, Module module); // this should be shell out in the executor
|
||||
|
||||
public FunctionValue getFunction(final String name)
|
||||
public FunctionValue getFunction(String name)
|
||||
{
|
||||
return getFunction(main, name);
|
||||
}
|
||||
|
||||
public FunctionValue getAssertFunction(final Module module, final String name)
|
||||
public FunctionValue getAssertFunction(Module module, String name)
|
||||
{
|
||||
final FunctionValue ret = getFunction(module, name);
|
||||
FunctionValue ret = getFunction(module, name);
|
||||
if (ret == null)
|
||||
{
|
||||
if (module == main)
|
||||
@@ -236,9 +236,9 @@ public abstract class ScriptHost
|
||||
return ret;
|
||||
}
|
||||
|
||||
private FunctionValue getFunction(final Module module, final String name)
|
||||
private FunctionValue getFunction(Module module, String name)
|
||||
{
|
||||
final ModuleData local = getModuleData(module);
|
||||
ModuleData local = getModuleData(module);
|
||||
FunctionValue ret = local.globalFunctions.get(name); // most uses would be from local scope anyways
|
||||
if (ret != null)
|
||||
{
|
||||
@@ -269,7 +269,7 @@ public abstract class ScriptHost
|
||||
return target.globalFunctions.get(name);
|
||||
}
|
||||
|
||||
private ModuleData findModuleDataFromFunctionImports(final String name, final ModuleData source, final int ttl)
|
||||
private ModuleData findModuleDataFromFunctionImports(String name, ModuleData source, int ttl)
|
||||
{
|
||||
if (ttl > 64)
|
||||
{
|
||||
@@ -290,14 +290,14 @@ public abstract class ScriptHost
|
||||
return null;
|
||||
}
|
||||
|
||||
public LazyValue getGlobalVariable(final String name)
|
||||
public LazyValue getGlobalVariable(String name)
|
||||
{
|
||||
return getGlobalVariable(main, name);
|
||||
}
|
||||
|
||||
public LazyValue getGlobalVariable(final Module module, final String name)
|
||||
public LazyValue getGlobalVariable(Module module, String name)
|
||||
{
|
||||
final ModuleData local = getModuleData(module);
|
||||
ModuleData local = getModuleData(module);
|
||||
LazyValue ret = local.globalVariables.get(name); // most uses would be from local scope anyways
|
||||
if (ret != null)
|
||||
{
|
||||
@@ -328,7 +328,7 @@ public abstract class ScriptHost
|
||||
return target.globalVariables.get(name);
|
||||
}
|
||||
|
||||
private ModuleData findModuleDataFromGlobalImports(final String name, final ModuleData source, final int ttl)
|
||||
private ModuleData findModuleDataFromGlobalImports(String name, ModuleData source, int ttl)
|
||||
{
|
||||
if (ttl > 64)
|
||||
{
|
||||
@@ -349,37 +349,37 @@ public abstract class ScriptHost
|
||||
return null;
|
||||
}
|
||||
|
||||
public void delFunctionWithPrefix(final Module module, final String prefix)
|
||||
public void delFunctionWithPrefix(Module module, String prefix)
|
||||
{
|
||||
final ModuleData data = getModuleData(module);
|
||||
ModuleData data = getModuleData(module);
|
||||
data.globalFunctions.entrySet().removeIf(e -> e.getKey().startsWith(prefix));
|
||||
data.functionImports.entrySet().removeIf(e -> e.getKey().startsWith(prefix));
|
||||
}
|
||||
|
||||
public void delFunction(final Module module, final String funName)
|
||||
public void delFunction(Module module, String funName)
|
||||
{
|
||||
final ModuleData data = getModuleData(module);
|
||||
ModuleData data = getModuleData(module);
|
||||
data.globalFunctions.remove(funName);
|
||||
data.functionImports.remove(funName);
|
||||
}
|
||||
|
||||
public void delGlobalVariableWithPrefix(final Module module, final String prefix)
|
||||
public void delGlobalVariableWithPrefix(Module module, String prefix)
|
||||
{
|
||||
final ModuleData data = getModuleData(module);
|
||||
ModuleData data = getModuleData(module);
|
||||
data.globalVariables.entrySet().removeIf(e -> e.getKey().startsWith(prefix));
|
||||
data.globalsImports.entrySet().removeIf(e -> e.getKey().startsWith(prefix));
|
||||
}
|
||||
|
||||
public void delGlobalVariable(final Module module, final String varName)
|
||||
public void delGlobalVariable(Module module, String varName)
|
||||
{
|
||||
final ModuleData data = getModuleData(module);
|
||||
ModuleData data = getModuleData(module);
|
||||
data.globalFunctions.remove(varName);
|
||||
data.functionImports.remove(varName);
|
||||
}
|
||||
|
||||
private ModuleData getModuleData(final Module module)
|
||||
private ModuleData getModuleData(Module module)
|
||||
{
|
||||
final ModuleData data = moduleData.get(module);
|
||||
ModuleData data = moduleData.get(module);
|
||||
if (data == null)
|
||||
{
|
||||
throw new IntegrityException("Module structure changed for the app. Did you reload the app with tasks running?");
|
||||
@@ -387,22 +387,22 @@ public abstract class ScriptHost
|
||||
return data;
|
||||
}
|
||||
|
||||
protected void assertAppIntegrity(final Module module)
|
||||
protected void assertAppIntegrity(Module module)
|
||||
{
|
||||
getModuleData(module);
|
||||
}
|
||||
|
||||
public void addUserDefinedFunction(final Context ctx, final Module module, final String name, final FunctionValue fun)
|
||||
public void addUserDefinedFunction(Context ctx, Module module, String name, FunctionValue fun)
|
||||
{
|
||||
getModuleData(module).globalFunctions.put(name, fun);
|
||||
}
|
||||
|
||||
public void setGlobalVariable(final Module module, final String name, final LazyValue lv)
|
||||
public void setGlobalVariable(Module module, String name, LazyValue lv)
|
||||
{
|
||||
getModuleData(module).globalVariables.put(name, lv);
|
||||
}
|
||||
|
||||
public Stream<String> globalVariableNames(final Module module, final Predicate<String> predicate)
|
||||
public Stream<String> globalVariableNames(Module module, Predicate<String> predicate)
|
||||
{
|
||||
return Stream.concat(Stream.concat(
|
||||
getModuleData(module).globalVariables.keySet().stream(),
|
||||
@@ -410,7 +410,7 @@ public abstract class ScriptHost
|
||||
), getModuleData(module).futureImports.keySet().stream().filter(s -> s.startsWith("global_"))).filter(predicate);
|
||||
}
|
||||
|
||||
public Stream<String> globalFunctionNames(final Module module, final Predicate<String> predicate)
|
||||
public Stream<String> globalFunctionNames(Module module, Predicate<String> predicate)
|
||||
{
|
||||
return Stream.concat(Stream.concat(
|
||||
getModuleData(module).globalFunctions.keySet().stream(),
|
||||
@@ -418,25 +418,25 @@ public abstract class ScriptHost
|
||||
), getModuleData(module).futureImports.keySet().stream().filter(s -> !s.startsWith("global_"))).filter(predicate);
|
||||
}
|
||||
|
||||
public ScriptHost retrieveForExecution(final String /*Nullable*/ user)
|
||||
public ScriptHost retrieveForExecution(String /*Nullable*/ user)
|
||||
{
|
||||
if (!perUser)
|
||||
{
|
||||
return this;
|
||||
}
|
||||
final ScriptHost oldUserHost = userHosts.get(user);
|
||||
ScriptHost oldUserHost = userHosts.get(user);
|
||||
if (oldUserHost != null)
|
||||
{
|
||||
return oldUserHost;
|
||||
}
|
||||
final ScriptHost userHost = this.duplicate();
|
||||
ScriptHost userHost = this.duplicate();
|
||||
userHost.user = user;
|
||||
this.setupUserHost(userHost);
|
||||
userHosts.put(user, userHost);
|
||||
return userHost;
|
||||
}
|
||||
|
||||
protected void setupUserHost(final ScriptHost host)
|
||||
protected void setupUserHost(ScriptHost host)
|
||||
{
|
||||
// adding imports
|
||||
host.modules.putAll(this.modules);
|
||||
@@ -445,19 +445,19 @@ public abstract class ScriptHost
|
||||
host.moduleData.forEach((module, data) -> data.setImportsBasedOn(host, this.moduleData.get(data.parent)));
|
||||
}
|
||||
|
||||
public synchronized void handleExpressionException(final String msg, final ExpressionException exc)
|
||||
public synchronized void handleExpressionException(String msg, ExpressionException exc)
|
||||
{
|
||||
System.out.println(msg + ": " + exc);
|
||||
}
|
||||
|
||||
protected abstract ScriptHost duplicate();
|
||||
|
||||
public Object getLock(final Value name)
|
||||
public Object getLock(Value name)
|
||||
{
|
||||
return locks.computeIfAbsent(name, n -> new Object());
|
||||
}
|
||||
|
||||
public ThreadPoolExecutor getExecutor(final Value pool)
|
||||
public ThreadPoolExecutor getExecutor(Value pool)
|
||||
{
|
||||
if (inTermination)
|
||||
{
|
||||
@@ -471,7 +471,7 @@ public abstract class ScriptHost
|
||||
return executorServices.values().stream().map(ThreadPoolExecutor::getActiveCount).reduce(0, Integer::sum);
|
||||
}
|
||||
|
||||
public int taskCount(final Value pool)
|
||||
public int taskCount(Value pool)
|
||||
{
|
||||
return executorServices.containsKey(pool) ? executorServices.get(pool).getActiveCount() : 0;
|
||||
}
|
||||
@@ -480,14 +480,14 @@ public abstract class ScriptHost
|
||||
{
|
||||
inTermination = true;
|
||||
executorServices.values().forEach(ThreadPoolExecutor::shutdown);
|
||||
for (final ScriptHost uh : userHosts.values())
|
||||
for (ScriptHost uh : userHosts.values())
|
||||
{
|
||||
uh.onClose();
|
||||
}
|
||||
if (taskCount() > 0)
|
||||
{
|
||||
executorServices.values().forEach(e -> {
|
||||
final ExecutorService stopper = Executors.newSingleThreadExecutor();
|
||||
ExecutorService stopper = Executors.newSingleThreadExecutor();
|
||||
stopper.submit(() -> {
|
||||
try
|
||||
{
|
||||
@@ -502,7 +502,7 @@ public abstract class ScriptHost
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (final InterruptedException ie)
|
||||
catch (InterruptedException ie)
|
||||
{
|
||||
// (Re-)Cancel if current thread also interrupted
|
||||
e.shutdownNow();
|
||||
@@ -516,7 +516,7 @@ public abstract class ScriptHost
|
||||
}
|
||||
}
|
||||
|
||||
public void setPerPlayer(final boolean isPerUser)
|
||||
public void setPerPlayer(boolean isPerUser)
|
||||
{
|
||||
perUser = isPerUser;
|
||||
}
|
||||
@@ -539,7 +539,7 @@ public abstract class ScriptHost
|
||||
|
||||
public static final Logger DEPRECATION_LOG = LoggerFactory.getLogger("Scarpet Deprecation Warnings");
|
||||
|
||||
public boolean issueDeprecation(final String feature)
|
||||
public boolean issueDeprecation(String feature)
|
||||
{
|
||||
if (deprecations.contains(feature))
|
||||
{
|
||||
|
||||
@@ -11,5 +11,5 @@ public abstract class ScriptServer
|
||||
{
|
||||
public final Map<Value, Value> systemGlobals = new ConcurrentHashMap<>();
|
||||
|
||||
public abstract Path resolveResource(final String suffix);
|
||||
public abstract Path resolveResource(String suffix);
|
||||
}
|
||||
@@ -44,7 +44,7 @@ public class Tokenizer implements Iterator<Tokenizer.Token>
|
||||
private final Expression expression;
|
||||
private final Context context;
|
||||
|
||||
Tokenizer(final Context c, final Expression expr, final String input, final boolean allowComments, final boolean allowNewLineMakers)
|
||||
Tokenizer(Context c, Expression expr, String input, boolean allowComments, boolean allowNewLineMakers)
|
||||
{
|
||||
this.input = input;
|
||||
this.expression = expr;
|
||||
@@ -55,13 +55,13 @@ public class Tokenizer implements Iterator<Tokenizer.Token>
|
||||
|
||||
public List<Token> postProcess()
|
||||
{
|
||||
final Iterable<Token> iterable = () -> this;
|
||||
final List<Token> originalTokens = StreamSupport.stream(iterable.spliterator(), false).collect(Collectors.toList());
|
||||
final List<Token> cleanedTokens = new ArrayList<>();
|
||||
Iterable<Token> iterable = () -> this;
|
||||
List<Token> originalTokens = StreamSupport.stream(iterable.spliterator(), false).collect(Collectors.toList());
|
||||
List<Token> cleanedTokens = new ArrayList<>();
|
||||
Token last = null;
|
||||
while (!originalTokens.isEmpty())
|
||||
{
|
||||
final Token current = originalTokens.remove(originalTokens.size() - 1);
|
||||
Token current = originalTokens.remove(originalTokens.size() - 1);
|
||||
if (current.type == Token.TokenType.MARKER && current.surface.startsWith("//"))
|
||||
{
|
||||
continue;
|
||||
@@ -120,22 +120,22 @@ public class Tokenizer implements Iterator<Tokenizer.Token>
|
||||
return (pos < (input.length() - 1)) ? input.charAt(pos + 1) : 0;
|
||||
}
|
||||
|
||||
private boolean isHexDigit(final char ch)
|
||||
private boolean isHexDigit(char ch)
|
||||
{
|
||||
return ch == 'x' || ch == 'X' || (ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'f')
|
||||
|| (ch >= 'A' && ch <= 'F');
|
||||
}
|
||||
|
||||
private static boolean isSemicolon(final Token tok)
|
||||
private static boolean isSemicolon(Token tok)
|
||||
{
|
||||
return (tok.type == Token.TokenType.OPERATOR && tok.surface.equals(";"))
|
||||
|| (tok.type == Token.TokenType.UNARY_OPERATOR && tok.surface.equals(";u"));
|
||||
}
|
||||
|
||||
public static List<Token> simplepass(final String input)
|
||||
public static List<Token> simplepass(String input)
|
||||
{
|
||||
final Tokenizer tok = new Tokenizer(null, null, input, false, false);
|
||||
final List<Token> res = new ArrayList<>();
|
||||
Tokenizer tok = new Tokenizer(null, null, input, false, false);
|
||||
List<Token> res = new ArrayList<>();
|
||||
while (tok.hasNext())
|
||||
{
|
||||
res.add(tok.next());
|
||||
@@ -146,7 +146,7 @@ public class Tokenizer implements Iterator<Tokenizer.Token>
|
||||
@Override
|
||||
public Token next()
|
||||
{
|
||||
final Token token = new Token();
|
||||
Token token = new Token();
|
||||
|
||||
if (pos >= input.length())
|
||||
{
|
||||
@@ -208,7 +208,7 @@ public class Tokenizer implements Iterator<Tokenizer.Token>
|
||||
{
|
||||
if (ch == '\\')
|
||||
{
|
||||
final char nextChar = peekNextChar();
|
||||
char nextChar = peekNextChar();
|
||||
if (nextChar == 'n')
|
||||
{
|
||||
token.append('\n');
|
||||
@@ -324,8 +324,8 @@ public class Tokenizer implements Iterator<Tokenizer.Token>
|
||||
else
|
||||
{
|
||||
String greedyMatch = "";
|
||||
final int initialPos = pos;
|
||||
final int initialLinePos = linepos;
|
||||
int initialPos = pos;
|
||||
int initialLinePos = linepos;
|
||||
ch = input.charAt(pos);
|
||||
int validOperatorSeenUntil = -1;
|
||||
while (!Character.isLetter(ch) && !Character.isDigit(ch) && "_".indexOf(ch) < 0
|
||||
@@ -433,7 +433,7 @@ public class Tokenizer implements Iterator<Tokenizer.Token>
|
||||
final boolean functional;
|
||||
final boolean constant;
|
||||
|
||||
TokenType(final boolean functional, final boolean constant)
|
||||
TokenType(boolean functional, boolean constant)
|
||||
{
|
||||
this.functional = functional;
|
||||
this.constant = constant;
|
||||
@@ -457,9 +457,9 @@ public class Tokenizer implements Iterator<Tokenizer.Token>
|
||||
public int lineno;
|
||||
public static final Token NONE = new Token();
|
||||
|
||||
public Token morphedInto(final TokenType newType, final String newSurface)
|
||||
public Token morphedInto(TokenType newType, String newSurface)
|
||||
{
|
||||
final Token created = new Token();
|
||||
Token created = new Token();
|
||||
created.surface = newSurface;
|
||||
created.type = newType;
|
||||
created.pos = pos;
|
||||
@@ -468,23 +468,23 @@ public class Tokenizer implements Iterator<Tokenizer.Token>
|
||||
return created;
|
||||
}
|
||||
|
||||
public void morph(final TokenType type, final String s)
|
||||
public void morph(TokenType type, String s)
|
||||
{
|
||||
this.type = type;
|
||||
this.surface = s;
|
||||
}
|
||||
|
||||
public void append(final char c)
|
||||
public void append(char c)
|
||||
{
|
||||
surface += c;
|
||||
}
|
||||
|
||||
public void append(final String s)
|
||||
public void append(String s)
|
||||
{
|
||||
surface += s;
|
||||
}
|
||||
|
||||
public char charAt(final int pos)
|
||||
public char charAt(int pos)
|
||||
{
|
||||
return surface.charAt(pos);
|
||||
}
|
||||
|
||||
@@ -104,10 +104,10 @@ public final class AnnotationParser
|
||||
* @see ScarpetFunction
|
||||
* @param clazz The class to parse
|
||||
*/
|
||||
public static void parseFunctionClass(final Class<?> clazz)
|
||||
public static void parseFunctionClass(Class<?> clazz)
|
||||
{
|
||||
// Only try to instantiate or require concrete classes if there are non-static annotated methods
|
||||
final Supplier<Object> instanceSupplier = Suppliers.memoize(() -> {
|
||||
Supplier<Object> instanceSupplier = Suppliers.memoize(() -> {
|
||||
if (Modifier.isAbstract(clazz.getModifiers()))
|
||||
{
|
||||
throw new IllegalArgumentException("Function class must be concrete to support non-static methods! Class: " + clazz.getSimpleName());
|
||||
@@ -116,14 +116,14 @@ public final class AnnotationParser
|
||||
{
|
||||
return clazz.getConstructor().newInstance();
|
||||
}
|
||||
catch (final ReflectiveOperationException e)
|
||||
catch (ReflectiveOperationException e)
|
||||
{
|
||||
throw new IllegalArgumentException(
|
||||
"Couldn't create instance of given " + clazz + ". This is needed for non-static methods. Make sure default constructor is available", e);
|
||||
}
|
||||
});
|
||||
final Method[] methodz = clazz.getDeclaredMethods();
|
||||
for (final Method method : methodz)
|
||||
Method[] methodz = clazz.getDeclaredMethods();
|
||||
for (Method method : methodz)
|
||||
{
|
||||
if (!method.isAnnotationPresent(ScarpetFunction.class))
|
||||
{
|
||||
@@ -135,7 +135,7 @@ public final class AnnotationParser
|
||||
throw new IllegalArgumentException("Annotated method '" + method.getName() +"', provided in '"+clazz+"' must not declare checked exceptions");
|
||||
}
|
||||
|
||||
final ParsedFunction function = new ParsedFunction(method, clazz, instanceSupplier);
|
||||
ParsedFunction function = new ParsedFunction(method, clazz, instanceSupplier);
|
||||
functionList.add(function);
|
||||
}
|
||||
}
|
||||
@@ -146,9 +146,9 @@ public final class AnnotationParser
|
||||
*
|
||||
* @param expr The expression to add every function to
|
||||
*/
|
||||
public static void apply(final Expression expr)
|
||||
public static void apply(Expression expr)
|
||||
{
|
||||
for (final ParsedFunction function : functionList)
|
||||
for (ParsedFunction function : functionList)
|
||||
{
|
||||
expr.addLazyFunction(function.name, function.scarpetParamCount, function);
|
||||
}
|
||||
@@ -171,52 +171,52 @@ public final class AnnotationParser
|
||||
private final int scarpetParamCount;
|
||||
private final Context.Type contextType;
|
||||
|
||||
private ParsedFunction(final Method method, final Class<?> originClass, final Supplier<Object> instance)
|
||||
private ParsedFunction(Method method, Class<?> originClass, Supplier<Object> instance)
|
||||
{
|
||||
this.name = method.getName();
|
||||
this.isMethodVarArgs = method.isVarArgs();
|
||||
this.methodParamCount = method.getParameterCount();
|
||||
|
||||
final Parameter[] methodParameters = method.getParameters();
|
||||
Parameter[] methodParameters = method.getParameters();
|
||||
this.valueConverters = new ValueConverter[isMethodVarArgs ? methodParamCount - 1 : methodParamCount];
|
||||
for (int i = 0; i < this.methodParamCount; i++)
|
||||
{
|
||||
final Parameter param = methodParameters[i];
|
||||
Parameter param = methodParameters[i];
|
||||
if (!isMethodVarArgs || i != this.methodParamCount - 1) // Varargs converter is separate
|
||||
{
|
||||
this.valueConverters[i] = ValueConverter.fromAnnotatedType(param.getAnnotatedType());
|
||||
}
|
||||
}
|
||||
final Class<?> originalVarArgsType = isMethodVarArgs ? methodParameters[methodParamCount - 1].getType().getComponentType() : null;
|
||||
Class<?> originalVarArgsType = isMethodVarArgs ? methodParameters[methodParamCount - 1].getType().getComponentType() : null;
|
||||
this.varArgsType = ClassUtils.primitiveToWrapper(originalVarArgsType); // Primitive array cannot be cast to Obj[]
|
||||
this.primitiveVarArgs = originalVarArgsType != null && originalVarArgsType.isPrimitive();
|
||||
this.varArgsConverter = isMethodVarArgs ? ValueConverter.fromAnnotatedType(methodParameters[methodParamCount - 1].getAnnotatedType()) : null;
|
||||
@SuppressWarnings("unchecked") final // Yes. Making a T is not worth
|
||||
@SuppressWarnings("unchecked") // Yes. Making a T is not worth
|
||||
OutputConverter<Object> converter = OutputConverter.get((Class<Object>) method.getReturnType());
|
||||
this.outputConverter = converter;
|
||||
|
||||
this.isEffectivelyVarArgs = isMethodVarArgs || Arrays.stream(valueConverters).anyMatch(ValueConverter::consumesVariableArgs);
|
||||
this.minParams = Arrays.stream(valueConverters).mapToInt(ValueConverter::valueConsumption).sum(); // Note: In !varargs, this is params
|
||||
int maxParams = this.minParams; // Unlimited == Integer.MAX_VALUE
|
||||
int setMaxParams = this.minParams; // Unlimited == Integer.MAX_VALUE
|
||||
if (this.isEffectivelyVarArgs)
|
||||
{
|
||||
maxParams = method.getAnnotation(ScarpetFunction.class).maxParams();
|
||||
if (maxParams == UNDEFINED_PARAMS)
|
||||
setMaxParams = method.getAnnotation(ScarpetFunction.class).maxParams();
|
||||
if (setMaxParams == UNDEFINED_PARAMS)
|
||||
{
|
||||
throw new IllegalArgumentException("No maximum number of params specified for " + name + ", use ScarpetFunction.UNLIMITED_PARAMS for unlimited. "
|
||||
+ "Provided in " + originClass);
|
||||
}
|
||||
if (maxParams == ScarpetFunction.UNLIMITED_PARAMS)
|
||||
if (setMaxParams == ScarpetFunction.UNLIMITED_PARAMS)
|
||||
{
|
||||
maxParams = Integer.MAX_VALUE;
|
||||
setMaxParams = Integer.MAX_VALUE;
|
||||
}
|
||||
if (maxParams < this.minParams)
|
||||
if (setMaxParams < this.minParams)
|
||||
{
|
||||
throw new IllegalArgumentException("Provided maximum number of params for " + name + " is smaller than method's param count."
|
||||
+ "Provided in " + originClass);
|
||||
}
|
||||
}
|
||||
this.maxParams = maxParams;
|
||||
this.maxParams = setMaxParams;
|
||||
|
||||
// Why MethodHandles?
|
||||
// MethodHandles are blazing fast (in some situations they can even compile to a single invokeVirtual), but slightly complex to work with.
|
||||
@@ -242,9 +242,9 @@ public final class AnnotationParser
|
||||
}
|
||||
|
||||
@Override
|
||||
public LazyValue apply(final Context context, final Context.Type t, final List<LazyValue> lazyValues)
|
||||
public LazyValue apply(Context context, Context.Type t, List<LazyValue> lazyValues)
|
||||
{
|
||||
final List<Value> lv = AbstractLazyFunction.unpackLazy(lazyValues, context, contextType);
|
||||
List<Value> lv = AbstractLazyFunction.unpackLazy(lazyValues, context, contextType);
|
||||
if (isEffectivelyVarArgs)
|
||||
{
|
||||
if (lv.size() < minParams)
|
||||
@@ -258,12 +258,12 @@ public final class AnnotationParser
|
||||
+ getUsage());
|
||||
}
|
||||
}
|
||||
final Object[] params = getMethodParams(lv, context, t);
|
||||
Object[] params = getMethodParams(lv, context, t);
|
||||
try
|
||||
{
|
||||
return outputConverter.convert(handle.invokeExact(params));
|
||||
}
|
||||
catch (final Throwable e)
|
||||
catch (Throwable e)
|
||||
{
|
||||
if (e instanceof RuntimeException re)
|
||||
{
|
||||
@@ -274,12 +274,12 @@ public final class AnnotationParser
|
||||
}
|
||||
|
||||
// Hot code: Must be optimized
|
||||
private Object[] getMethodParams(final List<Value> lv, final Context context, final Context.Type theLazyT)
|
||||
private Object[] getMethodParams(List<Value> lv, Context context, Context.Type theLazyT)
|
||||
{
|
||||
final Object[] params = new Object[methodParamCount];
|
||||
final ListIterator<Value> lvIterator = lv.listIterator();
|
||||
Object[] params = new Object[methodParamCount];
|
||||
ListIterator<Value> lvIterator = lv.listIterator();
|
||||
|
||||
final int regularArgs = isMethodVarArgs ? methodParamCount - 1 : methodParamCount;
|
||||
int regularArgs = isMethodVarArgs ? methodParamCount - 1 : methodParamCount;
|
||||
for (int i = 0; i < regularArgs; i++)
|
||||
{
|
||||
params[i] = valueConverters[i].checkAndConvert(lvIterator, context, theLazyT);
|
||||
@@ -290,14 +290,14 @@ public final class AnnotationParser
|
||||
}
|
||||
if (isMethodVarArgs)
|
||||
{
|
||||
final int remaining = lv.size() - lvIterator.nextIndex();
|
||||
final Object[] varArgs;
|
||||
int remaining = lv.size() - lvIterator.nextIndex();
|
||||
Object[] varArgs;
|
||||
if (varArgsConverter.consumesVariableArgs())
|
||||
{
|
||||
final List<Object> varArgsList = new ArrayList<>(); // fastutil's is extremely slow in toArray, and we use that
|
||||
List<Object> varArgsList = new ArrayList<>(); // fastutil's is extremely slow in toArray, and we use that
|
||||
while (lvIterator.hasNext())
|
||||
{
|
||||
final Object obj = varArgsConverter.checkAndConvert(lvIterator, context, theLazyT);
|
||||
Object obj = varArgsConverter.checkAndConvert(lvIterator, context, theLazyT);
|
||||
if (obj == null)
|
||||
{
|
||||
throw new InternalExpressionException("Incorrect argument passsed to '" + name + "' function.\n" + getUsage());
|
||||
@@ -326,7 +326,7 @@ public final class AnnotationParser
|
||||
public String getUsage()
|
||||
{
|
||||
// Possibility: More descriptive messages using param.getName()? Would need changing gradle setup to keep those
|
||||
final StringBuilder builder = new StringBuilder("Usage: '");
|
||||
StringBuilder builder = new StringBuilder("Usage: '");
|
||||
builder.append(name);
|
||||
builder.append('(');
|
||||
builder.append(Arrays.stream(valueConverters).map(ValueConverter::getTypeName).filter(Objects::nonNull).collect(Collectors.joining(", ")));
|
||||
|
||||
@@ -10,6 +10,8 @@ import carpet.script.Context;
|
||||
import carpet.script.value.ListValue;
|
||||
import carpet.script.value.Value;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* <p>Converts a given {@link ListValue} into a {@link List} of values converted to {@code <T>}.</p>
|
||||
*
|
||||
@@ -32,18 +34,20 @@ final class ListConverter<T> implements ValueConverter<List<T>>
|
||||
return (allowSingletonCreation ? itemConverter.getTypeName() + " or " : "") + "list of " + itemConverter.getTypeName() + "s";
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public List<T> convert(final Value value, final Context context)
|
||||
public List<T> convert(Value value, @Nullable Context context)
|
||||
{
|
||||
return value instanceof ListValue ? convertListValue((ListValue) value, context) : allowSingletonCreation ? convertSingleton(value, context) : null;
|
||||
}
|
||||
|
||||
private List<T> convertListValue(final ListValue values, final Context context)
|
||||
@Nullable
|
||||
private List<T> convertListValue(ListValue values, @Nullable Context context)
|
||||
{
|
||||
final List<T> list = new ArrayList<>(values.getItems().size());
|
||||
for (final Value value : values)
|
||||
List<T> list = new ArrayList<>(values.getItems().size());
|
||||
for (Value value : values)
|
||||
{
|
||||
final T converted = itemConverter.convert(value, context);
|
||||
T converted = itemConverter.convert(value, context);
|
||||
if (converted == null)
|
||||
{
|
||||
return null;
|
||||
@@ -53,9 +57,10 @@ final class ListConverter<T> implements ValueConverter<List<T>>
|
||||
return list;
|
||||
}
|
||||
|
||||
private List<T> convertSingleton(final Value val, final Context context)
|
||||
@Nullable
|
||||
private List<T> convertSingleton(Value val, @Nullable Context context)
|
||||
{
|
||||
final T converted = itemConverter.convert(val, context);
|
||||
T converted = itemConverter.convert(val, context);
|
||||
if (converted == null)
|
||||
{
|
||||
return null;
|
||||
@@ -64,7 +69,7 @@ final class ListConverter<T> implements ValueConverter<List<T>>
|
||||
|
||||
}
|
||||
|
||||
private ListConverter(final AnnotatedType itemType, final boolean allowSingletonCreation)
|
||||
private ListConverter(AnnotatedType itemType, boolean allowSingletonCreation)
|
||||
{
|
||||
itemConverter = ValueConverter.fromAnnotatedType(itemType);
|
||||
this.allowSingletonCreation = allowSingletonCreation;
|
||||
@@ -84,11 +89,11 @@ final class ListConverter<T> implements ValueConverter<List<T>>
|
||||
* @param annotatedType The type to get generics information from
|
||||
* @return A new {@link ListConverter} for the data specified in the {@link AnnotatedType}
|
||||
*/
|
||||
static ListConverter<?> fromAnnotatedType(final AnnotatedType annotatedType)
|
||||
static ListConverter<?> fromAnnotatedType(AnnotatedType annotatedType)
|
||||
{
|
||||
final AnnotatedParameterizedType paramType = (AnnotatedParameterizedType) annotatedType;
|
||||
final AnnotatedType itemType = paramType.getAnnotatedActualTypeArguments()[0];
|
||||
final boolean allowSingletonCreation = annotatedType.isAnnotationPresent(Param.AllowSingleton.class);
|
||||
AnnotatedParameterizedType paramType = (AnnotatedParameterizedType) annotatedType;
|
||||
AnnotatedType itemType = paramType.getAnnotatedActualTypeArguments()[0];
|
||||
boolean allowSingletonCreation = annotatedType.isAnnotationPresent(Param.AllowSingleton.class);
|
||||
return new ListConverter<>(itemType, allowSingletonCreation);
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,8 @@ import carpet.script.value.BlockValue;
|
||||
import carpet.script.value.FunctionValue;
|
||||
import carpet.script.value.Value;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import static java.lang.annotation.ElementType.PARAMETER;
|
||||
import static java.lang.annotation.ElementType.TYPE_USE;
|
||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||
@@ -122,7 +124,7 @@ public interface Locator
|
||||
super();
|
||||
}
|
||||
|
||||
static <R> ValueConverter<R> fromAnnotatedType(final AnnotatedType annoType, final Class<R> type)
|
||||
static <R> ValueConverter<R> fromAnnotatedType(AnnotatedType annoType, Class<R> type)
|
||||
{
|
||||
if (annoType.isAnnotationPresent(Block.class))
|
||||
{
|
||||
@@ -146,7 +148,7 @@ public interface Locator
|
||||
private final boolean anyString;
|
||||
private final boolean optional;
|
||||
|
||||
public BlockLocator(final Block annotation, final Class<R> type)
|
||||
public BlockLocator(Block annotation, Class<R> type)
|
||||
{
|
||||
super();
|
||||
this.acceptString = annotation.acceptString();
|
||||
@@ -163,8 +165,9 @@ public interface Locator
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@SuppressWarnings("unchecked")
|
||||
private static <R> java.util.function.Function<BlockArgument, R> getReturnFunction(final Class<R> type)
|
||||
private static <R> java.util.function.Function<BlockArgument, R> getReturnFunction(Class<R> type)
|
||||
{
|
||||
if (type == BlockArgument.class)
|
||||
{
|
||||
@@ -192,9 +195,9 @@ public interface Locator
|
||||
}
|
||||
|
||||
@Override
|
||||
public R checkAndConvert(final Iterator<Value> valueIterator, final Context context, final Context.Type theLazyT)
|
||||
public R checkAndConvert(Iterator<Value> valueIterator, Context context, Context.Type theLazyT)
|
||||
{
|
||||
final BlockArgument locator = BlockArgument.findIn((CarpetContext) context, valueIterator, 0, acceptString, optional, anyString);
|
||||
BlockArgument locator = BlockArgument.findIn((CarpetContext) context, valueIterator, 0, acceptString, optional, anyString);
|
||||
return returnFunction.apply(locator);
|
||||
}
|
||||
}
|
||||
@@ -205,7 +208,7 @@ public interface Locator
|
||||
private final boolean optionalEntity;
|
||||
private final boolean returnVec3d;
|
||||
|
||||
public Vec3dLocator(final Vec3d annotation, final Class<R> type)
|
||||
public Vec3dLocator(Vec3d annotation, Class<R> type)
|
||||
{
|
||||
this.optionalDirection = annotation.optionalDirection();
|
||||
this.optionalEntity = annotation.optionalEntity();
|
||||
@@ -227,10 +230,10 @@ public interface Locator
|
||||
}
|
||||
|
||||
@Override
|
||||
public R checkAndConvert(final Iterator<Value> valueIterator, final Context context, final Context.Type theLazyT)
|
||||
public R checkAndConvert(Iterator<Value> valueIterator, Context context, Context.Type theLazyT)
|
||||
{
|
||||
final Vector3Argument locator = Vector3Argument.findIn(valueIterator, 0, optionalDirection, optionalEntity);
|
||||
@SuppressWarnings("unchecked") final R ret = (R) (returnVec3d ? locator.vec : locator);
|
||||
Vector3Argument locator = Vector3Argument.findIn(valueIterator, 0, optionalDirection, optionalEntity);
|
||||
@SuppressWarnings("unchecked") R ret = (R) (returnVec3d ? locator.vec : locator);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
@@ -241,7 +244,7 @@ public interface Locator
|
||||
private final boolean allowNone;
|
||||
private final boolean checkArgs;
|
||||
|
||||
FunctionLocator(final Function annotation, final Class<R> type)
|
||||
FunctionLocator(Function annotation, Class<R> type)
|
||||
{
|
||||
super();
|
||||
this.returnFunctionValue = type == FunctionValue.class;
|
||||
@@ -258,11 +261,11 @@ public interface Locator
|
||||
}
|
||||
|
||||
@Override
|
||||
public R checkAndConvert(final Iterator<Value> valueIterator, final Context context, final Context.Type theLazyT)
|
||||
public R checkAndConvert(Iterator<Value> valueIterator, Context context, Context.Type theLazyT)
|
||||
{
|
||||
final Module module = context.host.main;
|
||||
final FunctionArgument locator = FunctionArgument.findIn(context, module, Lists.newArrayList(valueIterator), 0, allowNone, checkArgs);
|
||||
@SuppressWarnings("unchecked") final R ret = (R) (returnFunctionValue ? locator.function : locator);
|
||||
Module module = context.host.main;
|
||||
FunctionArgument locator = FunctionArgument.findIn(context, module, Lists.newArrayList(valueIterator), 0, allowNone, checkArgs);
|
||||
@SuppressWarnings("unchecked") R ret = (R) (returnFunctionValue ? locator.function : locator);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -276,7 +279,7 @@ public interface Locator
|
||||
private abstract static class AbstractLocator<R> implements ValueConverter<R>, Locator
|
||||
{
|
||||
@Override
|
||||
public R convert(final Value value, final Context context)
|
||||
public R convert(Value value, @Nullable Context context)
|
||||
{
|
||||
throw new UnsupportedOperationException("Cannot call a locator in a parameter that doesn't contain a context!");
|
||||
}
|
||||
|
||||
@@ -13,6 +13,8 @@ import carpet.script.value.ListValue;
|
||||
import carpet.script.value.MapValue;
|
||||
import carpet.script.value.Value;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* <p>Converts a {@link MapValue} to a {@link Map}, converting all of its contents to their respective types.</p>
|
||||
*
|
||||
@@ -37,15 +39,15 @@ class MapConverter<K, V> implements ValueConverter<Map<K, V>>
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<K, V> convert(final Value value, final Context context)
|
||||
public Map<K, V> convert(Value value, @Nullable Context context)
|
||||
{
|
||||
final Map<K, V> result = new HashMap<>();
|
||||
Map<K, V> result = new HashMap<>();
|
||||
if (value instanceof MapValue)
|
||||
{
|
||||
for (final Entry<Value, Value> entry : ((MapValue) value).getMap().entrySet())
|
||||
for (Entry<Value, Value> entry : ((MapValue) value).getMap().entrySet())
|
||||
{
|
||||
final K key = keyConverter.convert(entry.getKey(), context);
|
||||
final V val = valueConverter.convert(entry.getValue(), context);
|
||||
K key = keyConverter.convert(entry.getKey(), context);
|
||||
V val = valueConverter.convert(entry.getValue(), context);
|
||||
if (key == null || val == null)
|
||||
{
|
||||
return null;
|
||||
@@ -57,7 +59,7 @@ class MapConverter<K, V> implements ValueConverter<Map<K, V>>
|
||||
return null;
|
||||
}
|
||||
|
||||
private MapConverter(final AnnotatedType keyType, final AnnotatedType valueType)
|
||||
private MapConverter(AnnotatedType keyType, AnnotatedType valueType)
|
||||
{
|
||||
super();
|
||||
keyConverter = ValueConverter.fromAnnotatedType(keyType);
|
||||
@@ -80,9 +82,9 @@ class MapConverter<K, V> implements ValueConverter<Map<K, V>>
|
||||
* @param annotatedType The type to get generics information from
|
||||
* @return A new {@link MapConverter} for the data specified in the {@link AnnotatedType}
|
||||
*/
|
||||
static MapConverter<?, ?> fromAnnotatedType(final AnnotatedType annotatedType)
|
||||
static MapConverter<?, ?> fromAnnotatedType(AnnotatedType annotatedType)
|
||||
{
|
||||
final AnnotatedType[] annotatedGenerics = ((AnnotatedParameterizedType) annotatedType).getAnnotatedActualTypeArguments();
|
||||
AnnotatedType[] annotatedGenerics = ((AnnotatedParameterizedType) annotatedType).getAnnotatedActualTypeArguments();
|
||||
return annotatedType.isAnnotationPresent(Param.KeyValuePairs.class)
|
||||
? new PairConverter<>(annotatedGenerics[0], annotatedGenerics[1], annotatedType.getAnnotation(Param.KeyValuePairs.class))
|
||||
: new MapConverter<>(annotatedGenerics[0], annotatedGenerics[1]);
|
||||
@@ -92,7 +94,7 @@ class MapConverter<K, V> implements ValueConverter<Map<K, V>>
|
||||
{
|
||||
private final boolean acceptMultiParam;
|
||||
|
||||
private PairConverter(final AnnotatedType keyType, final AnnotatedType valueType, final Param.KeyValuePairs config)
|
||||
private PairConverter(AnnotatedType keyType, AnnotatedType valueType, Param.KeyValuePairs config)
|
||||
{
|
||||
super(keyType, valueType);
|
||||
acceptMultiParam = config.allowMultiparam();
|
||||
@@ -104,26 +106,28 @@ class MapConverter<K, V> implements ValueConverter<Map<K, V>>
|
||||
return acceptMultiParam;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Map<K, V> convert(final Value value, final Context context) {
|
||||
public Map<K, V> convert(Value value, @Nullable Context context) {
|
||||
return value instanceof MapValue ? super.convert(value, context)
|
||||
: value instanceof ListValue ? convertList(((ListValue)value).getItems(), context)
|
||||
: null; // Multiparam mode can only be used in evalAndConvert
|
||||
}
|
||||
|
||||
|
||||
private Map<K, V> convertList(final List<Value> valueList, final Context context)
|
||||
@Nullable
|
||||
private Map<K, V> convertList(List<Value> valueList, @Nullable Context context)
|
||||
{
|
||||
if (valueList.size() % 2 == 1)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
final Map<K, V> map = new HashMap<>();
|
||||
final Iterator<Value> val = valueList.iterator();
|
||||
Map<K, V> map = new HashMap<>();
|
||||
Iterator<Value> val = valueList.iterator();
|
||||
while (val.hasNext())
|
||||
{
|
||||
final K key = keyConverter.convert(val.next(), context);
|
||||
final V value = valueConverter.convert(val.next(), context);
|
||||
K key = keyConverter.convert(val.next(), context);
|
||||
V value = valueConverter.convert(val.next(), context);
|
||||
if (key == null || value == null)
|
||||
{
|
||||
return null;
|
||||
@@ -133,20 +137,21 @@ class MapConverter<K, V> implements ValueConverter<Map<K, V>>
|
||||
return map;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Map<K, V> checkAndConvert(final Iterator<Value> valueIterator, final Context context, final Context.Type theLazyT)
|
||||
public Map<K, V> checkAndConvert(Iterator<Value> valueIterator, Context context, Context.Type theLazyT)
|
||||
{
|
||||
if (!valueIterator.hasNext())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
final Value val = valueIterator.next();
|
||||
Value val = valueIterator.next();
|
||||
if (!acceptMultiParam || val instanceof MapValue || (val instanceof ListValue && !(keyConverter instanceof ListConverter)))
|
||||
{
|
||||
return convert(val, context); // @KeyValuePairs Map<List<Something>, Boolean> will not support list consumption
|
||||
}
|
||||
|
||||
final Map<K, V> map = new HashMap<>();
|
||||
Map<K, V> map = new HashMap<>();
|
||||
K key = keyConverter.convert(val, context); //First pair is manual since we got it to check for a different conversion mode
|
||||
V value = valueConverter.checkAndConvert(valueIterator, context, theLazyT);
|
||||
if (key == null || value == null)
|
||||
|
||||
@@ -9,6 +9,8 @@ import java.util.Optional;
|
||||
import carpet.script.Context;
|
||||
import carpet.script.value.Value;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* <p>{@link ValueConverter} that accepts a parameter to not be present on function call.</p>
|
||||
*
|
||||
@@ -49,14 +51,15 @@ final class OptionalConverter<R> implements ValueConverter<Optional<R>>
|
||||
* @implNote Unlike most other converters, {@link OptionalConverter} will not call this method from
|
||||
* {@link #checkAndConvert(Iterator, Context, Context.Type)} and is only used as a fallback in types that don't support it.
|
||||
*/
|
||||
@Nullable
|
||||
@Override
|
||||
public Optional<R> convert(final Value value, final Context context)
|
||||
public Optional<R> convert(Value value, @Nullable Context context)
|
||||
{
|
||||
if (value.isNull())
|
||||
{
|
||||
return Optional.empty();
|
||||
}
|
||||
final R converted = typeConverter.convert(value, context);
|
||||
R converted = typeConverter.convert(value, context);
|
||||
if (converted == null)
|
||||
{
|
||||
return null;
|
||||
@@ -64,15 +67,16 @@ final class OptionalConverter<R> implements ValueConverter<Optional<R>>
|
||||
return Optional.of(converted);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Optional<R> checkAndConvert(final Iterator<Value> valueIterator, final Context context, final Context.Type theLazyT)
|
||||
public Optional<R> checkAndConvert(Iterator<Value> valueIterator, Context context, Context.Type theLazyT)
|
||||
{
|
||||
if (!valueIterator.hasNext() || valueIterator.next().isNull())
|
||||
{
|
||||
return Optional.empty();
|
||||
}
|
||||
((ListIterator<Value>) valueIterator).previous();
|
||||
final R converted = typeConverter.checkAndConvert(valueIterator, context, theLazyT);
|
||||
R converted = typeConverter.checkAndConvert(valueIterator, context, theLazyT);
|
||||
if (converted == null)
|
||||
{
|
||||
return null;
|
||||
@@ -106,10 +110,10 @@ final class OptionalConverter<R> implements ValueConverter<Optional<R>>
|
||||
* @param annotatedType The type to get generics information from
|
||||
* @return A new {@link OptionalConverter} for the data specified in the {@link AnnotatedType}
|
||||
*/
|
||||
static OptionalConverter<?> fromAnnotatedType(final AnnotatedType annotatedType)
|
||||
static OptionalConverter<?> fromAnnotatedType(AnnotatedType annotatedType)
|
||||
{
|
||||
final AnnotatedParameterizedType paramType = (AnnotatedParameterizedType) annotatedType;
|
||||
final AnnotatedType wrappedType = paramType.getAnnotatedActualTypeArguments()[0];
|
||||
AnnotatedParameterizedType paramType = (AnnotatedParameterizedType) annotatedType;
|
||||
AnnotatedType wrappedType = paramType.getAnnotatedActualTypeArguments()[0];
|
||||
return new OptionalConverter<>(wrappedType);
|
||||
}
|
||||
}
|
||||
@@ -23,6 +23,8 @@ import carpet.script.value.StringValue;
|
||||
import carpet.script.value.Value;
|
||||
import carpet.script.value.ValueConversions;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* <p>A converter from a given {@link Object} of type T into a {@link LazyValue}, used in order to convert the outputs of methods into usable Scarpet
|
||||
* values.</p>
|
||||
@@ -57,7 +59,7 @@ public final class OutputConverter<T>
|
||||
|
||||
private final Function<T, LazyValue> converter;
|
||||
|
||||
private OutputConverter(final Function<T, LazyValue> converter)
|
||||
private OutputConverter(Function<T, LazyValue> converter)
|
||||
{
|
||||
this.converter = converter;
|
||||
}
|
||||
@@ -90,7 +92,7 @@ public final class OutputConverter<T>
|
||||
* @param input The value to convert
|
||||
* @return The converted value
|
||||
*/
|
||||
public LazyValue convert(final T input)
|
||||
public LazyValue convert(@Nullable T input)
|
||||
{
|
||||
return input == null ? LazyValue.NULL : converter.apply(input);
|
||||
}
|
||||
@@ -103,9 +105,9 @@ public final class OutputConverter<T>
|
||||
* @param inputType The class of T
|
||||
* @param converter The function that converts the an instance of T to a {@link LazyValue}
|
||||
*/
|
||||
public static <T> void register(final Class<T> inputType, final Function<T, LazyValue> converter)
|
||||
public static <T> void register(Class<T> inputType, Function<T, LazyValue> converter)
|
||||
{
|
||||
final OutputConverter<T> instance = new OutputConverter<>(converter);
|
||||
OutputConverter<T> instance = new OutputConverter<>(converter);
|
||||
if (byResult.containsKey(inputType))
|
||||
{
|
||||
throw new IllegalArgumentException(inputType + " already has a registered OutputConverter");
|
||||
@@ -122,9 +124,9 @@ public final class OutputConverter<T>
|
||||
* @param inputType The class of T
|
||||
* @param converter The function that converts an instance of T to a {@link Value}
|
||||
*/
|
||||
public static <T> void registerToValue(final Class<T> inputType, final Function<T, Value> converter)
|
||||
public static <T> void registerToValue(Class<T> inputType, Function<T, Value> converter)
|
||||
{
|
||||
final OutputConverter<T> instance = new OutputConverter<>(converter.andThen(v -> (c, t) -> v));
|
||||
OutputConverter<T> instance = new OutputConverter<>(converter.andThen(v -> (c, t) -> v));
|
||||
if (byResult.containsKey(inputType))
|
||||
{
|
||||
throw new IllegalArgumentException(inputType + " already has a registered OutputConverter");
|
||||
|
||||
@@ -24,6 +24,8 @@ import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import static java.lang.annotation.ElementType.PARAMETER;
|
||||
import static java.lang.annotation.ElementType.TYPE_USE;
|
||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||
@@ -143,18 +145,23 @@ public interface Param
|
||||
* <p>A {@link ValueConverter} that outputs the {@link Context} in which the function has been called, and throws {@link UnsupportedOperationException} when trying to convert a {@link Value}
|
||||
* directly.</p>
|
||||
*/
|
||||
static final ValueConverter<Context> CONTEXT_PROVIDER = new ValueConverter<Context>()
|
||||
static final ValueConverter<Context> CONTEXT_PROVIDER = new ValueConverter<>()
|
||||
{
|
||||
@Override public String getTypeName() { return null; }
|
||||
@Nullable
|
||||
@Override
|
||||
public String getTypeName()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Context convert(final Value value, final Context context)
|
||||
public Context convert(Value value, @Nullable Context context)
|
||||
{
|
||||
throw new UnsupportedOperationException("Called convert() with Value in Context Provider converter, where only checkAndConvert is supported");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Context checkAndConvert(final Iterator<Value> valueIterator, final Context context, final Context.Type theLazyT)
|
||||
public Context checkAndConvert(Iterator<Value> valueIterator, Context context, Context.Type theLazyT)
|
||||
{
|
||||
return context;
|
||||
}
|
||||
@@ -170,18 +177,23 @@ public interface Param
|
||||
* <p>A {@link ValueConverter} that outputs the {@link Context.Type} which the function has been called, or throws {@link UnsupportedOperationException} when trying to convert a {@link Value}
|
||||
* directly.</p>
|
||||
*/
|
||||
static final ValueConverter<Context.Type> CONTEXT_TYPE_PROVIDER = new ValueConverter<Context.Type>()
|
||||
static final ValueConverter<Context.Type> CONTEXT_TYPE_PROVIDER = new ValueConverter<>()
|
||||
{
|
||||
@Override public String getTypeName() { return null; }
|
||||
@Nullable
|
||||
@Override
|
||||
public String getTypeName()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Context.Type convert(final Value value, final Context context)
|
||||
public Context.Type convert(Value value, @Nullable Context context)
|
||||
{
|
||||
throw new UnsupportedOperationException("Called convert() with a Value in TheLazyT Provider, where only checkAndConvert is supported");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Context.Type checkAndConvert(final Iterator<Value> valueIterator, final Context context, final Context.Type theLazyT)
|
||||
public Context.Type checkAndConvert(Iterator<Value> valueIterator, Context context, Context.Type theLazyT)
|
||||
{
|
||||
return theLazyT;
|
||||
}
|
||||
@@ -214,12 +226,12 @@ public interface Param
|
||||
* @throws IllegalArgumentException If the type doesn't accept the {@link Strict} annotation or if it has been used incorrectly (shallow in
|
||||
* unsupported places)
|
||||
*/
|
||||
static ValueConverter<?> getStrictConverter(final AnnotatedType type)
|
||||
static ValueConverter<?> getStrictConverter(AnnotatedType type)
|
||||
{
|
||||
final boolean shallow = type.getAnnotation(Strict.class).shallow();
|
||||
final Class<?> clazz = (Class<?>) type.getType();
|
||||
final StrictConverterInfo key = new StrictConverterInfo(clazz, shallow);
|
||||
final ValueConverter<?> converter = strictParamsByClassAndShallowness.get(key);
|
||||
boolean shallow = type.getAnnotation(Strict.class).shallow();
|
||||
Class<?> clazz = (Class<?>) type.getType();
|
||||
StrictConverterInfo key = new StrictConverterInfo(clazz, shallow);
|
||||
ValueConverter<?> converter = strictParamsByClassAndShallowness.get(key);
|
||||
if (converter != null)
|
||||
{
|
||||
return converter;
|
||||
@@ -239,9 +251,9 @@ public interface Param
|
||||
* @param shallow {@code true} if you are registering a shallow-strict parameter, {@code false} if a "fully" strict one
|
||||
* @param converter The {@link ValueConverter} for the given type and shallowness.
|
||||
*/
|
||||
public static <T> void registerStrictConverter(final Class<T> type, final boolean shallow, final ValueConverter<T> converter)
|
||||
public static <T> void registerStrictConverter(Class<T> type, boolean shallow, ValueConverter<T> converter)
|
||||
{
|
||||
final StrictConverterInfo key = new StrictConverterInfo(type, shallow);
|
||||
StrictConverterInfo key = new StrictConverterInfo(type, shallow);
|
||||
if (strictParamsByClassAndShallowness.containsKey(key))
|
||||
{
|
||||
throw new IllegalArgumentException(type + " already has a registered " + (shallow ? "" : "non-") + "shallow StrictConverter");
|
||||
@@ -271,16 +283,16 @@ public interface Param
|
||||
* avoid possible collisions with other extensions.
|
||||
*/
|
||||
@SuppressWarnings("unchecked") // this makes no sense... But I guess its preferable to enforce typesafety in callers
|
||||
public static <T> void registerCustomConverterFactory(final BiFunction<AnnotatedType, Class<T>, ValueConverter<T>> factory)
|
||||
public static <T> void registerCustomConverterFactory(BiFunction<AnnotatedType, Class<T>, ValueConverter<T>> factory)
|
||||
{
|
||||
customFactories.add((BiFunction<AnnotatedType, Class<?>, ValueConverter<?>>) (Object) factory);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked") // Stored correctly
|
||||
static <R> ValueConverter<R> getCustomConverter(final AnnotatedType annoType, final Class<R> type)
|
||||
static <R> ValueConverter<R> getCustomConverter(AnnotatedType annoType, Class<R> type)
|
||||
{
|
||||
ValueConverter<R> result;
|
||||
for (final BiFunction<AnnotatedType, Class<?>, ValueConverter<?>> factory : customFactories)
|
||||
for (BiFunction<AnnotatedType, Class<?>, ValueConverter<?>> factory : customFactories)
|
||||
{
|
||||
if ((result = (ValueConverter<R>) factory.apply(annoType, type)) != null)
|
||||
{
|
||||
|
||||
@@ -18,6 +18,8 @@ import carpet.script.value.NumericValue;
|
||||
import carpet.script.value.Value;
|
||||
import carpet.script.value.ValueConversions;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* <p>A simple {@link ValueConverter} implementation that converts from a specified subclass of {@link Value} into {@code <R>} by using a given
|
||||
* function.</p>
|
||||
@@ -61,7 +63,7 @@ public final class SimpleTypeConverter<T extends Value, R> implements ValueConve
|
||||
*
|
||||
* @see #SimpleTypeConverter(Class, BiFunction, String)
|
||||
*/
|
||||
public SimpleTypeConverter(final Class<T> inputType, final Function<T, R> converter, final String typeName)
|
||||
public SimpleTypeConverter(Class<T> inputType, Function<T, R> converter, String typeName)
|
||||
{
|
||||
this(inputType, (v, c) -> converter.apply(v), typeName);
|
||||
}
|
||||
@@ -77,7 +79,7 @@ public final class SimpleTypeConverter<T extends Value, R> implements ValueConve
|
||||
* @param converter The function to convert an instance of inputType into R, with the context of the call.
|
||||
* @param typeName The name of the type for error messages
|
||||
*/
|
||||
public SimpleTypeConverter(final Class<T> inputType, final BiFunction<T, Context, R> converter, final String typeName)
|
||||
public SimpleTypeConverter(Class<T> inputType, BiFunction<T, Context, R> converter, String typeName)
|
||||
{
|
||||
super();
|
||||
this.converter = converter;
|
||||
@@ -99,14 +101,15 @@ public final class SimpleTypeConverter<T extends Value, R> implements ValueConve
|
||||
* @return The {@link SimpleTypeConverter} for the specified outputType
|
||||
*/
|
||||
@SuppressWarnings("unchecked") // T always extends Value, R is always the same as map's key, since map is private.
|
||||
static <R> SimpleTypeConverter<Value, R> get(final Class<R> outputType)
|
||||
static <R> SimpleTypeConverter<Value, R> get(Class<R> outputType)
|
||||
{
|
||||
return (SimpleTypeConverter<Value, R>) byResult.get(outputType);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
@SuppressWarnings("unchecked") // more than checked. not using class.cast because then "method is too big" for inlining, because javac is useless
|
||||
public R convert(final Value value, final Context context) // and adds millions of casts. This one is even removed
|
||||
public R convert(Value value, @Nullable Context context) // and adds millions of casts. This one is even removed
|
||||
{
|
||||
return valueClass.isInstance(value) ? converter.apply((T)value, context) : null;
|
||||
}
|
||||
@@ -125,8 +128,8 @@ public final class SimpleTypeConverter<T extends Value, R> implements ValueConve
|
||||
*
|
||||
* @see #registerType(Class, Class, BiFunction, String)
|
||||
*/
|
||||
public static <T extends Value, R> void registerType(final Class<T> requiredInputType, final Class<R> outputType,
|
||||
final Function<T, R> converter, final String typeName)
|
||||
public static <T extends Value, R> void registerType(Class<T> requiredInputType, Class<R> outputType,
|
||||
Function<T, R> converter, String typeName)
|
||||
{
|
||||
registerType(requiredInputType, outputType, (val, ctx) -> converter.apply(val), typeName);
|
||||
}
|
||||
@@ -143,10 +146,10 @@ public final class SimpleTypeConverter<T extends Value, R> implements ValueConve
|
||||
* can also throw an {@link InternalExpressionException} by itself if really necessary.
|
||||
* @param typeName The name of the type, following the conventions of {@link ValueConverter#getTypeName()}
|
||||
*/
|
||||
public static <T extends Value, R> void registerType(final Class<T> requiredInputType, final Class<R> outputType,
|
||||
final BiFunction<T, Context, R> converter, final String typeName)
|
||||
public static <T extends Value, R> void registerType(Class<T> requiredInputType, Class<R> outputType,
|
||||
BiFunction<T, Context, R> converter, String typeName)
|
||||
{
|
||||
final SimpleTypeConverter<T, R> type = new SimpleTypeConverter<>(requiredInputType, converter, typeName);
|
||||
SimpleTypeConverter<T, R> type = new SimpleTypeConverter<>(requiredInputType, converter, typeName);
|
||||
byResult.put(outputType, type);
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,8 @@ import carpet.script.value.StringValue;
|
||||
import carpet.script.value.ThreadValue;
|
||||
import carpet.script.value.Value;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* <p>Simple {@link ValueConverter} implementation that casts a {@link Value} into one of its subclasses, either for use directly in parameters or
|
||||
* converters, or as an already working middle step.</p>
|
||||
@@ -51,7 +53,7 @@ public final class ValueCaster<R> implements ValueConverter<R> // R always exten
|
||||
private final Class<R> outputType;
|
||||
private final String typeName;
|
||||
|
||||
private ValueCaster(final Class<R> outputType, final String typeName)
|
||||
private ValueCaster(Class<R> outputType, String typeName)
|
||||
{
|
||||
super();
|
||||
this.outputType = outputType;
|
||||
@@ -73,14 +75,15 @@ public final class ValueCaster<R> implements ValueConverter<R> // R always exten
|
||||
*/
|
||||
@SuppressWarnings("unchecked") // Casters are stored with their exact class, for sure since the map is private (&& class has same generic as
|
||||
// caster)
|
||||
public static <R> ValueCaster<R> get(final Class<R> outputType)
|
||||
public static <R> ValueCaster<R> get(Class<R> outputType)
|
||||
{
|
||||
return (ValueCaster<R>) byResult.get(outputType);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
@SuppressWarnings("unchecked") // more than checked, see SimpleTypeConverter#converter for reasoning
|
||||
public R convert(final Value value, final Context context)
|
||||
public R convert(Value value, @Nullable Context context)
|
||||
{
|
||||
if (!outputType.isInstance(value))
|
||||
{
|
||||
@@ -98,9 +101,9 @@ public final class ValueCaster<R> implements ValueConverter<R> // R always exten
|
||||
* required<!--, with the form //Outdated concept <code>(function name) requires a (typeName) to be passed as (argName, if
|
||||
* available)</code>-->
|
||||
*/
|
||||
public static <R extends Value> void register(final Class<R> valueClass, final String typeName)
|
||||
public static <R extends Value> void register(Class<R> valueClass, String typeName)
|
||||
{
|
||||
final ValueCaster<R> caster = new ValueCaster<>(valueClass, typeName);
|
||||
ValueCaster<R> caster = new ValueCaster<>(valueClass, typeName);
|
||||
byResult.putIfAbsent(valueClass, caster);
|
||||
}
|
||||
}
|
||||
@@ -9,12 +9,13 @@ import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.apache.commons.lang3.ClassUtils;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import carpet.script.Context;
|
||||
import carpet.script.annotation.Param.Params;
|
||||
import carpet.script.value.Value;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* <p>Classes implementing this interface are able to convert {@link Value} instances into {@code <R>}, in order to easily use them in parameters for
|
||||
* Scarpet functions created using the {@link ScarpetFunction} annotation.</p>
|
||||
@@ -37,6 +38,7 @@ public interface ValueConverter<R>
|
||||
* @apiNote This method is intended to only be called when an error has occurred and therefore there is a need to print a stacktrace with some
|
||||
* helpful usage instructions.
|
||||
*/
|
||||
@Nullable
|
||||
String getTypeName();
|
||||
|
||||
/**
|
||||
@@ -63,7 +65,7 @@ public interface ValueConverter<R>
|
||||
* <p>Even with the above reasons, {@link ValueConverter} users should try to implement {@link #convert(Value, Context)} whenever possible instead of
|
||||
* {@link #checkAndConvert(Iterator, Context, Context.Type)}, since it allows its usage in generics of lists and maps.</p>
|
||||
*/
|
||||
@Nullable R convert(Value value, final Context context);
|
||||
@Nullable R convert(Value value, @Nullable Context context);
|
||||
|
||||
/**
|
||||
* Old version of {@link #convert(Value)} without taking a {@link Context}.<p>
|
||||
@@ -75,8 +77,9 @@ public interface ValueConverter<R>
|
||||
* @return A converted value
|
||||
* @deprecated Calling this method instead of {@link #convert(Value, Context)} may not return values for some converters
|
||||
*/
|
||||
@Nullable
|
||||
@Deprecated(forRemoval = true)
|
||||
default R convert(final Value value)
|
||||
default R convert(Value value)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -130,7 +133,7 @@ public interface ValueConverter<R>
|
||||
* @return A usable {@link ValueConverter} to convert from a {@link Value} to {@code <R>}
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
static <R> ValueConverter<R> fromAnnotatedType(final AnnotatedType annoType)
|
||||
static <R> ValueConverter<R> fromAnnotatedType(AnnotatedType annoType)
|
||||
{
|
||||
Class<R> type = annoType.getType() instanceof ParameterizedType ? // We are defining R here.
|
||||
(Class<R>) ((ParameterizedType) annoType.getType()).getRawType() :
|
||||
@@ -208,7 +211,8 @@ public interface ValueConverter<R>
|
||||
* @implNote This method's default implementation runs the {@link #convert(Value, Context)} function in the next {@link Value} ignoring {@link Context} and
|
||||
* {@code theLazyT}.
|
||||
*/
|
||||
default R checkAndConvert(final Iterator<Value> valueIterator, final Context context, final Context.Type contextType)
|
||||
@Nullable
|
||||
default R checkAndConvert(Iterator<Value> valueIterator, Context context, Context.Type contextType)
|
||||
{
|
||||
return !valueIterator.hasNext() ? null : convert(valueIterator.next(), context);
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -31,7 +31,7 @@ import static java.lang.Math.min;
|
||||
|
||||
public class BlockIterators
|
||||
{
|
||||
public static void apply(final Expression expression)
|
||||
public static void apply(Expression expression)
|
||||
{
|
||||
// lazy cause of lazy expression
|
||||
expression.addLazyFunction("scan", (c, t, llv) ->
|
||||
@@ -40,12 +40,12 @@ public class BlockIterators
|
||||
{
|
||||
throw new InternalExpressionException("'scan' needs many more arguments");
|
||||
}
|
||||
final List<Value> lv = Fluff.AbstractFunction.unpackLazy(llv.subList(0, llv.size() - 1), c, Context.NONE);
|
||||
final CarpetContext cc = (CarpetContext) c;
|
||||
final BlockArgument centerLocator = BlockArgument.findIn(cc, lv, 0);
|
||||
List<Value> lv = Fluff.AbstractFunction.unpackLazy(llv.subList(0, llv.size() - 1), c, Context.NONE);
|
||||
CarpetContext cc = (CarpetContext) c;
|
||||
BlockArgument centerLocator = BlockArgument.findIn(cc, lv, 0);
|
||||
Vector3Argument rangeLocator = Vector3Argument.findIn(lv, centerLocator.offset);
|
||||
final BlockPos center = centerLocator.block.getPos();
|
||||
final Vec3i range;
|
||||
BlockPos center = centerLocator.block.getPos();
|
||||
Vec3i range;
|
||||
|
||||
if (rangeLocator.fromBlock)
|
||||
{
|
||||
@@ -80,50 +80,50 @@ public class BlockIterators
|
||||
{
|
||||
throw new InternalExpressionException("'scan' takes two, or three block positions, and an expression: " + lv.size() + " " + rangeLocator.offset);
|
||||
}
|
||||
final LazyValue expr = llv.get(rangeLocator.offset);
|
||||
LazyValue expr = llv.get(rangeLocator.offset);
|
||||
|
||||
final int cx = center.getX();
|
||||
final int cy = center.getY();
|
||||
final int cz = center.getZ();
|
||||
final int xrange = range.getX();
|
||||
final int yrange = range.getY();
|
||||
final int zrange = range.getZ();
|
||||
final int xprange = upperRange.getX();
|
||||
final int yprange = upperRange.getY();
|
||||
final int zprange = upperRange.getZ();
|
||||
int cx = center.getX();
|
||||
int cy = center.getY();
|
||||
int cz = center.getZ();
|
||||
int xrange = range.getX();
|
||||
int yrange = range.getY();
|
||||
int zrange = range.getZ();
|
||||
int xprange = upperRange.getX();
|
||||
int yprange = upperRange.getY();
|
||||
int zprange = upperRange.getZ();
|
||||
|
||||
//saving outer scope
|
||||
final LazyValue _x = c.getVariable("_x");
|
||||
final LazyValue _y = c.getVariable("_y");
|
||||
final LazyValue _z = c.getVariable("_z");
|
||||
final LazyValue __ = c.getVariable("_");
|
||||
LazyValue xVal = c.getVariable("_x");
|
||||
LazyValue yVal = c.getVariable("_y");
|
||||
LazyValue zVal = c.getVariable("_z");
|
||||
LazyValue defaultVal = c.getVariable("_");
|
||||
int sCount = 0;
|
||||
outer:
|
||||
for (int y = cy - yrange; y <= cy + yprange; y++)
|
||||
{
|
||||
final int yFinal = y;
|
||||
c.setVariable("_y", (c_, t_) -> new NumericValue(yFinal).bindTo("_y"));
|
||||
int yFinal = y;
|
||||
c.setVariable("_y", (ct, tt) -> new NumericValue(yFinal).bindTo("_y"));
|
||||
for (int x = cx - xrange; x <= cx + xprange; x++)
|
||||
{
|
||||
final int xFinal = x;
|
||||
c.setVariable("_x", (c_, t_) -> new NumericValue(xFinal).bindTo("_x"));
|
||||
int xFinal = x;
|
||||
c.setVariable("_x", (ct, tt) -> new NumericValue(xFinal).bindTo("_x"));
|
||||
for (int z = cz - zrange; z <= cz + zprange; z++)
|
||||
{
|
||||
final int zFinal = z;
|
||||
int zFinal = z;
|
||||
|
||||
c.setVariable("_z", (c_, t_) -> new NumericValue(zFinal).bindTo("_z"));
|
||||
final Value blockValue = BlockValue.fromCoords(((CarpetContext) c), xFinal, yFinal, zFinal).bindTo("_");
|
||||
c.setVariable("_", (cc_, t_c) -> blockValue);
|
||||
c.setVariable("_z", (ct, tt) -> new NumericValue(zFinal).bindTo("_z"));
|
||||
Value blockValue = BlockValue.fromCoords(((CarpetContext) c), xFinal, yFinal, zFinal).bindTo("_");
|
||||
c.setVariable("_", (ct, tt) -> blockValue);
|
||||
Value result;
|
||||
try
|
||||
{
|
||||
result = expr.evalValue(c, t);
|
||||
}
|
||||
catch (final ContinueStatement notIgnored)
|
||||
catch (ContinueStatement notIgnored)
|
||||
{
|
||||
result = notIgnored.retval;
|
||||
}
|
||||
catch (final BreakStatement notIgnored)
|
||||
catch (BreakStatement notIgnored)
|
||||
{
|
||||
break outer;
|
||||
}
|
||||
@@ -135,74 +135,74 @@ public class BlockIterators
|
||||
}
|
||||
}
|
||||
//restoring outer scope
|
||||
c.setVariable("_x", _x);
|
||||
c.setVariable("_y", _y);
|
||||
c.setVariable("_z", _z);
|
||||
c.setVariable("_", __);
|
||||
final int finalSCount = sCount;
|
||||
return (c_, t_) -> new NumericValue(finalSCount);
|
||||
c.setVariable("_x", xVal);
|
||||
c.setVariable("_y", yVal);
|
||||
c.setVariable("_z", zVal);
|
||||
c.setVariable("_", defaultVal);
|
||||
int finalSCount = sCount;
|
||||
return (ct, tt) -> new NumericValue(finalSCount);
|
||||
});
|
||||
|
||||
// must be lazy
|
||||
expression.addLazyFunction("volume", (c, t, llv) ->
|
||||
{
|
||||
final CarpetContext cc = (CarpetContext) c;
|
||||
CarpetContext cc = (CarpetContext) c;
|
||||
if (llv.size() < 3)
|
||||
{
|
||||
throw new InternalExpressionException("'volume' needs many more arguments");
|
||||
}
|
||||
final List<Value> lv = Fluff.AbstractFunction.unpackLazy(llv.subList(0, llv.size() - 1), c, Context.NONE);
|
||||
List<Value> lv = Fluff.AbstractFunction.unpackLazy(llv.subList(0, llv.size() - 1), c, Context.NONE);
|
||||
|
||||
final BlockArgument pos1Locator = BlockArgument.findIn(cc, lv, 0);
|
||||
final BlockArgument pos2Locator = BlockArgument.findIn(cc, lv, pos1Locator.offset);
|
||||
final BlockPos pos1 = pos1Locator.block.getPos();
|
||||
final BlockPos pos2 = pos2Locator.block.getPos();
|
||||
BlockArgument pos1Locator = BlockArgument.findIn(cc, lv, 0);
|
||||
BlockArgument pos2Locator = BlockArgument.findIn(cc, lv, pos1Locator.offset);
|
||||
BlockPos pos1 = pos1Locator.block.getPos();
|
||||
BlockPos pos2 = pos2Locator.block.getPos();
|
||||
|
||||
final int x1 = pos1.getX();
|
||||
final int y1 = pos1.getY();
|
||||
final int z1 = pos1.getZ();
|
||||
final int x2 = pos2.getX();
|
||||
final int y2 = pos2.getY();
|
||||
final int z2 = pos2.getZ();
|
||||
final int minx = min(x1, x2);
|
||||
final int miny = min(y1, y2);
|
||||
final int minz = min(z1, z2);
|
||||
final int maxx = max(x1, x2);
|
||||
final int maxy = max(y1, y2);
|
||||
final int maxz = max(z1, z2);
|
||||
final LazyValue expr = llv.get(pos2Locator.offset);
|
||||
int x1 = pos1.getX();
|
||||
int y1 = pos1.getY();
|
||||
int z1 = pos1.getZ();
|
||||
int x2 = pos2.getX();
|
||||
int y2 = pos2.getY();
|
||||
int z2 = pos2.getZ();
|
||||
int minx = min(x1, x2);
|
||||
int miny = min(y1, y2);
|
||||
int minz = min(z1, z2);
|
||||
int maxx = max(x1, x2);
|
||||
int maxy = max(y1, y2);
|
||||
int maxz = max(z1, z2);
|
||||
LazyValue expr = llv.get(pos2Locator.offset);
|
||||
|
||||
//saving outer scope
|
||||
final LazyValue _x = c.getVariable("_x");
|
||||
final LazyValue _y = c.getVariable("_y");
|
||||
final LazyValue _z = c.getVariable("_z");
|
||||
final LazyValue __ = c.getVariable("_");
|
||||
LazyValue xVal = c.getVariable("_x");
|
||||
LazyValue yVal = c.getVariable("_y");
|
||||
LazyValue zVal = c.getVariable("_z");
|
||||
LazyValue defaultVal = c.getVariable("_");
|
||||
int sCount = 0;
|
||||
outer:
|
||||
for (int y = miny; y <= maxy; y++)
|
||||
{
|
||||
final int yFinal = y;
|
||||
c.setVariable("_y", (c_, t_) -> new NumericValue(yFinal).bindTo("_y"));
|
||||
int yFinal = y;
|
||||
c.setVariable("_y", (ct, tt) -> new NumericValue(yFinal).bindTo("_y"));
|
||||
for (int x = minx; x <= maxx; x++)
|
||||
{
|
||||
final int xFinal = x;
|
||||
c.setVariable("_x", (c_, t_) -> new NumericValue(xFinal).bindTo("_x"));
|
||||
int xFinal = x;
|
||||
c.setVariable("_x", (ct, tt) -> new NumericValue(xFinal).bindTo("_x"));
|
||||
for (int z = minz; z <= maxz; z++)
|
||||
{
|
||||
final int zFinal = z;
|
||||
c.setVariable("_z", (c_, t_) -> new NumericValue(zFinal).bindTo("_z"));
|
||||
final Value blockValue = BlockValue.fromCoords(((CarpetContext) c), xFinal, yFinal, zFinal).bindTo("_");
|
||||
c.setVariable("_", (cc_, t_c) -> blockValue);
|
||||
int zFinal = z;
|
||||
c.setVariable("_z", (ct, tt) -> new NumericValue(zFinal).bindTo("_z"));
|
||||
Value blockValue = BlockValue.fromCoords(((CarpetContext) c), xFinal, yFinal, zFinal).bindTo("_");
|
||||
c.setVariable("_", (ct, tt) -> blockValue);
|
||||
Value result;
|
||||
try
|
||||
{
|
||||
result = expr.evalValue(c, t);
|
||||
}
|
||||
catch (final ContinueStatement notIgnored)
|
||||
catch (ContinueStatement notIgnored)
|
||||
{
|
||||
result = notIgnored.retval;
|
||||
}
|
||||
catch (final BreakStatement notIgnored)
|
||||
catch (BreakStatement notIgnored)
|
||||
{
|
||||
break outer;
|
||||
}
|
||||
@@ -214,49 +214,49 @@ public class BlockIterators
|
||||
}
|
||||
}
|
||||
//restoring outer scope
|
||||
c.setVariable("_x", _x);
|
||||
c.setVariable("_y", _y);
|
||||
c.setVariable("_z", _z);
|
||||
c.setVariable("_", __);
|
||||
final int finalSCount = sCount;
|
||||
return (c_, t_) -> new NumericValue(finalSCount);
|
||||
c.setVariable("_x", xVal);
|
||||
c.setVariable("_y", yVal);
|
||||
c.setVariable("_z", zVal);
|
||||
c.setVariable("_", defaultVal);
|
||||
int finalSCount = sCount;
|
||||
return (ct, tt) -> new NumericValue(finalSCount);
|
||||
});
|
||||
|
||||
expression.addContextFunction("neighbours", -1, (c, t, lv) ->
|
||||
{
|
||||
final BlockPos center = BlockArgument.findIn((CarpetContext) c, lv, 0).block.getPos();
|
||||
final ServerLevel world = ((CarpetContext) c).level();
|
||||
BlockPos center = BlockArgument.findIn((CarpetContext) c, lv, 0).block.getPos();
|
||||
ServerLevel world = ((CarpetContext) c).level();
|
||||
|
||||
final List<Value> neighbours = new ArrayList<>();
|
||||
neighbours.add(new BlockValue(null, world, center.above()));
|
||||
neighbours.add(new BlockValue(null, world, center.below()));
|
||||
neighbours.add(new BlockValue(null, world, center.north()));
|
||||
neighbours.add(new BlockValue(null, world, center.south()));
|
||||
neighbours.add(new BlockValue(null, world, center.east()));
|
||||
neighbours.add(new BlockValue(null, world, center.west()));
|
||||
List<Value> neighbours = new ArrayList<>();
|
||||
neighbours.add(new BlockValue(world, center.above()));
|
||||
neighbours.add(new BlockValue(world, center.below()));
|
||||
neighbours.add(new BlockValue(world, center.north()));
|
||||
neighbours.add(new BlockValue(world, center.south()));
|
||||
neighbours.add(new BlockValue(world, center.east()));
|
||||
neighbours.add(new BlockValue(world, center.west()));
|
||||
return ListValue.wrap(neighbours);
|
||||
});
|
||||
|
||||
expression.addContextFunction("rect", -1, (c, t, lv) ->
|
||||
{
|
||||
final CarpetContext cc = (CarpetContext) c;
|
||||
final int cx;
|
||||
final int cy;
|
||||
final int cz;
|
||||
final int sminx;
|
||||
final int sminy;
|
||||
final int sminz;
|
||||
final int smaxx;
|
||||
final int smaxy;
|
||||
final int smaxz;
|
||||
final BlockArgument cposLocator = BlockArgument.findIn(cc, lv, 0);
|
||||
final BlockPos cpos = cposLocator.block.getPos();
|
||||
CarpetContext cc = (CarpetContext) c;
|
||||
int cx;
|
||||
int cy;
|
||||
int cz;
|
||||
int sminx;
|
||||
int sminy;
|
||||
int sminz;
|
||||
int smaxx;
|
||||
int smaxy;
|
||||
int smaxz;
|
||||
BlockArgument cposLocator = BlockArgument.findIn(cc, lv, 0);
|
||||
BlockPos cpos = cposLocator.block.getPos();
|
||||
cx = cpos.getX();
|
||||
cy = cpos.getY();
|
||||
cz = cpos.getZ();
|
||||
if (lv.size() > cposLocator.offset)
|
||||
{
|
||||
final Vector3Argument diffLocator = Vector3Argument.findIn(lv, cposLocator.offset);
|
||||
Vector3Argument diffLocator = Vector3Argument.findIn(lv, cposLocator.offset);
|
||||
if (diffLocator.fromBlock)
|
||||
{
|
||||
sminx = Mth.floor(abs(diffLocator.vec.x - cx));
|
||||
@@ -271,7 +271,7 @@ public class BlockIterators
|
||||
}
|
||||
if (lv.size() > diffLocator.offset)
|
||||
{
|
||||
final Vector3Argument posDiff = Vector3Argument.findIn(lv, diffLocator.offset);
|
||||
Vector3Argument posDiff = Vector3Argument.findIn(lv, diffLocator.offset);
|
||||
if (posDiff.fromBlock)
|
||||
{
|
||||
smaxx = Mth.floor(abs(posDiff.vec.x - cx));
|
||||
@@ -328,7 +328,7 @@ public class BlockIterators
|
||||
@Override
|
||||
public Value next()
|
||||
{
|
||||
final Value r = BlockValue.fromCoords(cc, x, y, z);
|
||||
Value r = BlockValue.fromCoords(cc, x, y, z);
|
||||
//possibly reroll context
|
||||
x++;
|
||||
if (x > maxx)
|
||||
@@ -371,16 +371,16 @@ public class BlockIterators
|
||||
|
||||
expression.addContextFunction("diamond", -1, (c, t, lv) ->
|
||||
{
|
||||
final CarpetContext cc = (CarpetContext) c;
|
||||
CarpetContext cc = (CarpetContext) c;
|
||||
|
||||
final BlockArgument cposLocator = BlockArgument.findIn((CarpetContext) c, lv, 0);
|
||||
final BlockPos cpos = cposLocator.block.getPos();
|
||||
BlockArgument cposLocator = BlockArgument.findIn((CarpetContext) c, lv, 0);
|
||||
BlockPos cpos = cposLocator.block.getPos();
|
||||
|
||||
final int cx;
|
||||
final int cy;
|
||||
final int cz;
|
||||
final int width;
|
||||
final int height;
|
||||
int cx;
|
||||
int cy;
|
||||
int cz;
|
||||
int width;
|
||||
int height;
|
||||
try
|
||||
{
|
||||
cx = cpos.getX();
|
||||
@@ -414,7 +414,7 @@ public class BlockIterators
|
||||
throw new InternalExpressionException("Incorrect number of arguments for 'diamond'");
|
||||
}
|
||||
}
|
||||
catch (final ClassCastException ignored)
|
||||
catch (ClassCastException ignored)
|
||||
{
|
||||
throw new InternalExpressionException("Attempted to pass a non-number to 'diamond'");
|
||||
}
|
||||
@@ -445,7 +445,7 @@ public class BlockIterators
|
||||
}
|
||||
// x = 3-|i-6|
|
||||
// z = |( (i-3)%12-6|-3
|
||||
final Value block = BlockValue.fromCoords(cc, cx + (curradius - abs(curpos - 2 * curradius)), cy, cz - curradius + abs(abs(curpos - curradius) % (4 * curradius) - 2 * curradius));
|
||||
Value block = BlockValue.fromCoords(cc, cx + (curradius - abs(curpos - 2 * curradius)), cy, cz - curradius + abs(abs(curpos - curradius) % (4 * curradius) - 2 * curradius));
|
||||
curpos++;
|
||||
if (curpos >= curradius * 4)
|
||||
{
|
||||
@@ -503,7 +503,7 @@ public class BlockIterators
|
||||
// x = 3-|i-6|
|
||||
// z = |( (i-3)%12-6|-3
|
||||
|
||||
final Value block = BlockValue.fromCoords(cc, cx + (curradius - abs(curpos - 2 * curradius)), cy + curheight, cz - curradius + abs(abs(curpos - curradius) % (4 * curradius) - 2 * curradius));
|
||||
Value block = BlockValue.fromCoords(cc, cx + (curradius - abs(curpos - 2 * curradius)), cy + curheight, cz - curradius + abs(abs(curpos - curradius) % (4 * curradius) - 2 * curradius));
|
||||
curpos++;
|
||||
if (curpos >= curradius * 4)
|
||||
{
|
||||
|
||||
@@ -42,10 +42,10 @@ import net.minecraft.world.phys.Vec3;
|
||||
|
||||
public class Entities
|
||||
{
|
||||
private static ListValue getPlayersFromWorldMatching(final Context c, final Predicate<ServerPlayer> condition)
|
||||
private static ListValue getPlayersFromWorldMatching(Context c, Predicate<ServerPlayer> condition)
|
||||
{
|
||||
final List<Value> ret = new ArrayList<>();
|
||||
for (final ServerPlayer player : ((CarpetContext) c).level().players())
|
||||
List<Value> ret = new ArrayList<>();
|
||||
for (ServerPlayer player : ((CarpetContext) c).level().players())
|
||||
{
|
||||
if (condition.test(player))
|
||||
{
|
||||
@@ -55,45 +55,45 @@ public class Entities
|
||||
return ListValue.wrap(ret);
|
||||
}
|
||||
|
||||
public static void apply(final Expression expression)
|
||||
public static void apply(Expression expression)
|
||||
{
|
||||
expression.addContextFunction("player", -1, (c, t, lv) ->
|
||||
{
|
||||
if (lv.size() == 0)
|
||||
if (lv.isEmpty())
|
||||
{
|
||||
final CarpetContext cc = (CarpetContext) c;
|
||||
CarpetContext cc = (CarpetContext) c;
|
||||
if (cc.host.user != null)
|
||||
{
|
||||
final ServerPlayer player = cc.server().getPlayerList().getPlayerByName(cc.host.user);
|
||||
ServerPlayer player = cc.server().getPlayerList().getPlayerByName(cc.host.user);
|
||||
return EntityValue.of(player);
|
||||
}
|
||||
final Entity callingEntity = cc.source().getEntity();
|
||||
Entity callingEntity = cc.source().getEntity();
|
||||
if (callingEntity instanceof Player)
|
||||
{
|
||||
return EntityValue.of(callingEntity);
|
||||
}
|
||||
final Vec3 pos = ((CarpetContext) c).source().getPosition();
|
||||
final Player closestPlayer = ((CarpetContext) c).level().getNearestPlayer(pos.x, pos.y, pos.z, -1.0, EntitySelector.ENTITY_STILL_ALIVE);
|
||||
Vec3 pos = ((CarpetContext) c).source().getPosition();
|
||||
Player closestPlayer = ((CarpetContext) c).level().getNearestPlayer(pos.x, pos.y, pos.z, -1.0, EntitySelector.ENTITY_STILL_ALIVE);
|
||||
return EntityValue.of(closestPlayer);
|
||||
}
|
||||
final String playerName = lv.get(0).getString();
|
||||
String playerName = lv.get(0).getString();
|
||||
return switch (playerName)
|
||||
{
|
||||
case "all" -> {
|
||||
final List<Value> ret = new ArrayList<>();
|
||||
for (final ServerPlayer player : ((CarpetContext) c).server().getPlayerList().getPlayers())
|
||||
List<Value> ret = new ArrayList<>();
|
||||
for (ServerPlayer player : ((CarpetContext) c).server().getPlayerList().getPlayers())
|
||||
{
|
||||
ret.add(new EntityValue(player));
|
||||
}
|
||||
yield ListValue.wrap(ret);
|
||||
}
|
||||
case "*" -> getPlayersFromWorldMatching(c, p -> true);
|
||||
case "survival" -> getPlayersFromWorldMatching(c, p -> p.gameMode.isSurvival()); // todo assert correct
|
||||
case "survival" -> getPlayersFromWorldMatching(c, p -> p.gameMode.isSurvival()); // includes adventure
|
||||
case "creative" -> getPlayersFromWorldMatching(c, ServerPlayer::isCreative);
|
||||
case "spectating" -> getPlayersFromWorldMatching(c, ServerPlayer::isSpectator);
|
||||
case "!spectating" -> getPlayersFromWorldMatching(c, p -> !p.isSpectator());
|
||||
default -> {
|
||||
final ServerPlayer player = ((CarpetContext) c).server().getPlayerList().getPlayerByName(playerName);
|
||||
ServerPlayer player = ((CarpetContext) c).server().getPlayerList().getPlayerByName(playerName);
|
||||
yield player != null ? new EntityValue(player) : Value.NULL;
|
||||
}
|
||||
};
|
||||
@@ -101,28 +101,28 @@ public class Entities
|
||||
|
||||
expression.addContextFunction("spawn", -1, (c, t, lv) ->
|
||||
{
|
||||
final CarpetContext cc = (CarpetContext) c;
|
||||
CarpetContext cc = (CarpetContext) c;
|
||||
if (lv.size() < 2)
|
||||
{
|
||||
throw new InternalExpressionException("'spawn' function takes mob name, and position to spawn");
|
||||
}
|
||||
final String entityString = lv.get(0).getString();
|
||||
final ResourceLocation entityId;
|
||||
String entityString = lv.get(0).getString();
|
||||
ResourceLocation entityId;
|
||||
try
|
||||
{
|
||||
entityId = ResourceLocation.read(new StringReader(entityString));
|
||||
final EntityType<? extends Entity> type = cc.registry(Registries.ENTITY_TYPE).getOptional(entityId).orElse(null);
|
||||
EntityType<? extends Entity> type = cc.registry(Registries.ENTITY_TYPE).getOptional(entityId).orElse(null);
|
||||
if (type == null || !type.canSummon())
|
||||
{
|
||||
return Value.NULL;
|
||||
}
|
||||
}
|
||||
catch (final CommandSyntaxException ignored)
|
||||
catch (CommandSyntaxException ignored)
|
||||
{
|
||||
return Value.NULL;
|
||||
}
|
||||
|
||||
final Vector3Argument position = Vector3Argument.findIn(lv, 1);
|
||||
Vector3Argument position = Vector3Argument.findIn(lv, 1);
|
||||
if (position.fromBlock)
|
||||
{
|
||||
position.vec = position.vec.subtract(0, 0.5, 0);
|
||||
@@ -131,20 +131,20 @@ public class Entities
|
||||
boolean hasTag = false;
|
||||
if (lv.size() > position.offset)
|
||||
{
|
||||
final Value nbt = lv.get(position.offset);
|
||||
final NBTSerializableValue v = (nbt instanceof final NBTSerializableValue nbtsv)
|
||||
Value nbt = lv.get(position.offset);
|
||||
NBTSerializableValue v = (nbt instanceof final NBTSerializableValue nbtsv)
|
||||
? nbtsv
|
||||
: NBTSerializableValue.parseString(nbt.getString(), true);
|
||||
: NBTSerializableValue.parseStringOrFail(nbt.getString());
|
||||
hasTag = true;
|
||||
tag = v.getCompoundTag();
|
||||
}
|
||||
tag.putString("id", entityId.toString());
|
||||
final Vec3 vec3d = position.vec;
|
||||
Vec3 vec3d = position.vec;
|
||||
|
||||
final ServerLevel serverWorld = cc.level();
|
||||
final Entity entity = EntityType.loadEntityRecursive(tag, serverWorld, e -> {
|
||||
ServerLevel serverWorld = cc.level();
|
||||
Entity entity = EntityType.loadEntityRecursive(tag, serverWorld, e -> {
|
||||
e.moveTo(vec3d.x, vec3d.y, vec3d.z, e.getYRot(), e.getXRot());
|
||||
return !serverWorld.addWithUUID(e) ? null : e;
|
||||
return e;
|
||||
});
|
||||
if (entity == null)
|
||||
{
|
||||
@@ -154,12 +154,17 @@ public class Entities
|
||||
{
|
||||
mob.finalizeSpawn(serverWorld, serverWorld.getCurrentDifficultyAt(entity.blockPosition()), MobSpawnType.COMMAND, null, null);
|
||||
}
|
||||
if (!serverWorld.tryAddFreshEntityWithPassengers(entity))
|
||||
{
|
||||
entity.discard();
|
||||
return Value.NULL;
|
||||
}
|
||||
return new EntityValue(entity);
|
||||
});
|
||||
|
||||
expression.addContextFunction("entity_id", 1, (c, t, lv) ->
|
||||
{
|
||||
final Value who = lv.get(0);
|
||||
Value who = lv.get(0);
|
||||
if (who instanceof final NumericValue numericValue)
|
||||
{
|
||||
return EntityValue.of(((CarpetContext) c).level().getEntity((int) numericValue.getLong()));
|
||||
@@ -169,10 +174,10 @@ public class Entities
|
||||
|
||||
expression.addContextFunction("entity_list", 1, (c, t, lv) ->
|
||||
{
|
||||
final String who = lv.get(0).getString();
|
||||
final CommandSourceStack source = ((CarpetContext) c).source();
|
||||
final EntityValue.EntityClassDescriptor eDesc = EntityValue.getEntityDescriptor(who, source.getServer());
|
||||
final List<? extends Entity> entityList = source.getLevel().getEntities(eDesc.directType, eDesc.filteringPredicate);
|
||||
String who = lv.get(0).getString();
|
||||
CommandSourceStack source = ((CarpetContext) c).source();
|
||||
EntityValue.EntityClassDescriptor eDesc = EntityValue.getEntityDescriptor(who, source.getServer());
|
||||
List<? extends Entity> entityList = source.getLevel().getEntities(eDesc.directType, eDesc.filteringPredicate);
|
||||
return ListValue.wrap(entityList.stream().map(EntityValue::new));
|
||||
});
|
||||
|
||||
@@ -182,41 +187,41 @@ public class Entities
|
||||
{
|
||||
throw new InternalExpressionException("'entity_area' requires entity type, center and range arguments");
|
||||
}
|
||||
final String who = lv.get(0).getString();
|
||||
final CarpetContext cc = (CarpetContext) c;
|
||||
final Vector3Argument centerLocator = Vector3Argument.findIn(lv, 1, false, true);
|
||||
String who = lv.get(0).getString();
|
||||
CarpetContext cc = (CarpetContext) c;
|
||||
Vector3Argument centerLocator = Vector3Argument.findIn(lv, 1, false, true);
|
||||
|
||||
final AABB centerBox;
|
||||
AABB centerBox;
|
||||
if (centerLocator.entity != null)
|
||||
{
|
||||
centerBox = centerLocator.entity.getBoundingBox();
|
||||
}
|
||||
else
|
||||
{
|
||||
final Vec3 center = centerLocator.vec;
|
||||
Vec3 center = centerLocator.vec;
|
||||
if (centerLocator.fromBlock)
|
||||
{
|
||||
center.add(0.5, 0.5, 0.5);
|
||||
}
|
||||
centerBox = new AABB(center, center);
|
||||
}
|
||||
final Vector3Argument rangeLocator = Vector3Argument.findIn(lv, centerLocator.offset);
|
||||
Vector3Argument rangeLocator = Vector3Argument.findIn(lv, centerLocator.offset);
|
||||
if (rangeLocator.fromBlock)
|
||||
{
|
||||
throw new InternalExpressionException("Range of 'entity_area' cannot come from a block argument");
|
||||
}
|
||||
final Vec3 range = rangeLocator.vec;
|
||||
final AABB area = centerBox.inflate(range.x, range.y, range.z);
|
||||
final EntityValue.EntityClassDescriptor eDesc = EntityValue.getEntityDescriptor(who, cc.server());
|
||||
final List<? extends Entity> entityList = cc.level().getEntities(eDesc.directType, area, eDesc.filteringPredicate);
|
||||
Vec3 range = rangeLocator.vec;
|
||||
AABB area = centerBox.inflate(range.x, range.y, range.z);
|
||||
EntityValue.EntityClassDescriptor eDesc = EntityValue.getEntityDescriptor(who, cc.server());
|
||||
List<? extends Entity> entityList = cc.level().getEntities(eDesc.directType, area, eDesc.filteringPredicate);
|
||||
return ListValue.wrap(entityList.stream().map(EntityValue::new));
|
||||
});
|
||||
|
||||
expression.addContextFunction("entity_selector", -1, (c, t, lv) ->
|
||||
{
|
||||
final String selector = lv.get(0).getString();
|
||||
final List<Value> retlist = new ArrayList<>();
|
||||
for (final Entity e : EntityValue.getEntitiesFromSelector(((CarpetContext) c).source(), selector))
|
||||
String selector = lv.get(0).getString();
|
||||
List<Value> retlist = new ArrayList<>();
|
||||
for (Entity e : EntityValue.getEntitiesFromSelector(((CarpetContext) c).source(), selector))
|
||||
{
|
||||
retlist.add(new EntityValue(e));
|
||||
}
|
||||
@@ -229,12 +234,12 @@ public class Entities
|
||||
{
|
||||
throw new InternalExpressionException("'query' takes entity as a first argument, and queried feature as a second");
|
||||
}
|
||||
final Value v = lv.get(0);
|
||||
Value v = lv.get(0);
|
||||
if (!(v instanceof final EntityValue ev))
|
||||
{
|
||||
throw new InternalExpressionException("First argument to query should be an entity");
|
||||
}
|
||||
final String what = lv.get(1).getString().toLowerCase(Locale.ROOT);
|
||||
String what = lv.get(1).getString().toLowerCase(Locale.ROOT);
|
||||
if (what.equals("tags"))
|
||||
{
|
||||
c.host.issueDeprecation("'tags' for entity querying");
|
||||
@@ -254,12 +259,12 @@ public class Entities
|
||||
{
|
||||
throw new InternalExpressionException("'modify' takes entity as a first argument, and queried feature as a second");
|
||||
}
|
||||
final Value v = lv.get(0);
|
||||
Value v = lv.get(0);
|
||||
if (!(v instanceof final EntityValue ev))
|
||||
{
|
||||
throw new InternalExpressionException("First argument to modify should be an entity");
|
||||
}
|
||||
final String what = lv.get(1).getString();
|
||||
String what = lv.get(1).getString();
|
||||
switch (lv.size())
|
||||
{
|
||||
case 2 -> ev.set(what, null);
|
||||
@@ -275,7 +280,7 @@ public class Entities
|
||||
{
|
||||
throw new InternalExpressionException("'entity_types' requires one or no arguments");
|
||||
}
|
||||
final String desc = (lv.size() == 1) ? lv.get(0).getString() : "*";
|
||||
String desc = (lv.size() == 1) ? lv.get(0).getString() : "*";
|
||||
return EntityValue.getEntityDescriptor(desc, ((CarpetContext) c).server()).listValue(((CarpetContext) c).registryAccess());
|
||||
});
|
||||
|
||||
@@ -285,14 +290,14 @@ public class Entities
|
||||
{
|
||||
throw new InternalExpressionException("'entity_load_handler' required the entity type, and a function to call");
|
||||
}
|
||||
final Value entityValue = lv.get(0);
|
||||
final List<String> descriptors = (entityValue instanceof final ListValue list)
|
||||
Value entityValue = lv.get(0);
|
||||
List<String> descriptors = (entityValue instanceof final ListValue list)
|
||||
? list.getItems().stream().map(Value::getString).toList()
|
||||
: Collections.singletonList(entityValue.getString());
|
||||
final Set<EntityType<? extends Entity>> types = new HashSet<>();
|
||||
Set<EntityType<? extends Entity>> types = new HashSet<>();
|
||||
descriptors.forEach(s -> types.addAll(EntityValue.getEntityDescriptor(s, ((CarpetContext) c).server()).types));
|
||||
final FunctionArgument funArg = FunctionArgument.findIn(c, expression.module, lv, 1, true, false);
|
||||
final CarpetEventServer events = ((CarpetScriptHost) c.host).scriptServer().events;
|
||||
FunctionArgument funArg = FunctionArgument.findIn(c, expression.module, lv, 1, true, false);
|
||||
CarpetEventServer events = ((CarpetScriptHost) c.host).scriptServer().events;
|
||||
if (funArg.function == null)
|
||||
{
|
||||
types.forEach(et -> events.removeBuiltInEvent(CarpetEventServer.Event.getEntityLoadEventName(et), (CarpetScriptHost) c.host));
|
||||
@@ -301,7 +306,7 @@ public class Entities
|
||||
else
|
||||
{
|
||||
///compat
|
||||
final int numberOfArguments = funArg.function.getArguments().size() - funArg.args.size();
|
||||
int numberOfArguments = funArg.function.getArguments().size() - funArg.args.size();
|
||||
if (numberOfArguments == 1)
|
||||
{
|
||||
c.host.issueDeprecation("entity_load_handler() with single argument callback");
|
||||
@@ -322,14 +327,14 @@ public class Entities
|
||||
{
|
||||
throw new InternalExpressionException("'entity_event' requires at least 3 arguments, entity, event to be handled, and function name, with optional arguments");
|
||||
}
|
||||
final Value v = lv.get(0);
|
||||
Value v = lv.get(0);
|
||||
if (!(v instanceof final EntityValue ev))
|
||||
{
|
||||
throw new InternalExpressionException("First argument to entity_event should be an entity");
|
||||
}
|
||||
final String what = lv.get(1).getString();
|
||||
String what = lv.get(1).getString();
|
||||
|
||||
final FunctionArgument funArg = FunctionArgument.findIn(c, expression.module, lv, 2, true, false);
|
||||
FunctionArgument funArg = FunctionArgument.findIn(c, expression.module, lv, 2, true, false);
|
||||
|
||||
ev.setEvent((CarpetContext) c, what, funArg.function, funArg.args);
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
@@ -54,7 +55,7 @@ import net.minecraft.world.phys.Vec3;
|
||||
|
||||
public class Inventories
|
||||
{
|
||||
public static void apply(final Expression expression)
|
||||
public static void apply(Expression expression)
|
||||
{
|
||||
expression.addContextFunction("stack_limit", 1, (c, t, lv) ->
|
||||
new NumericValue(NBTSerializableValue.parseItem(lv.get(0).getString(), ((CarpetContext) c).registryAccess()).getItem().getMaxStackSize()));
|
||||
@@ -66,78 +67,82 @@ public class Inventories
|
||||
|
||||
expression.addContextFunction("item_list", -1, (c, t, lv) ->
|
||||
{
|
||||
final CarpetContext cc = (CarpetContext) c;
|
||||
final Registry<Item> items = cc.registry(Registries.ITEM);
|
||||
if (lv.size() == 0)
|
||||
CarpetContext cc = (CarpetContext) c;
|
||||
Registry<Item> items = cc.registry(Registries.ITEM);
|
||||
if (lv.isEmpty())
|
||||
{
|
||||
return ListValue.wrap(items.keySet().stream().map(ValueConversions::of));
|
||||
}
|
||||
final String tag = lv.get(0).getString();
|
||||
final Optional<HolderSet.Named<Item>> itemTag = items.getTag(TagKey.create(Registries.ITEM, InputValidator.identifierOf(tag)));
|
||||
return itemTag.isEmpty() ? Value.NULL : ListValue.wrap(itemTag.get().stream().map(b -> ValueConversions.of(items.getKey(b.value()))));
|
||||
String tag = lv.get(0).getString();
|
||||
Optional<HolderSet.Named<Item>> itemTag = items.getTag(TagKey.create(Registries.ITEM, InputValidator.identifierOf(tag)));
|
||||
return itemTag.isEmpty() ? Value.NULL : ListValue.wrap(itemTag.get().stream().map(b -> items.getKey(b.value())).filter(Objects::nonNull).map(ValueConversions::of));
|
||||
});
|
||||
|
||||
expression.addContextFunction("item_tags", -1, (c, t, lv) ->
|
||||
{
|
||||
final CarpetContext cc = (CarpetContext) c;
|
||||
CarpetContext cc = (CarpetContext) c;
|
||||
|
||||
final Registry<Item> blocks = cc.registry(Registries.ITEM);
|
||||
if (lv.size() == 0)
|
||||
Registry<Item> blocks = cc.registry(Registries.ITEM);
|
||||
if (lv.isEmpty())
|
||||
{
|
||||
return ListValue.wrap(blocks.getTagNames().map(ValueConversions::of));
|
||||
}
|
||||
final Item item = NBTSerializableValue.parseItem(lv.get(0).getString(), cc.registryAccess()).getItem();
|
||||
Item item = NBTSerializableValue.parseItem(lv.get(0).getString(), cc.registryAccess()).getItem();
|
||||
if (lv.size() == 1)
|
||||
{
|
||||
return ListValue.wrap(blocks.getTags().filter(e -> e.getSecond().stream().anyMatch(h -> (h.value() == item))).map(e -> ValueConversions.of(e.getFirst())));
|
||||
}
|
||||
final String tag = lv.get(1).getString();
|
||||
final Optional<HolderSet.Named<Item>> tagSet = blocks.getTag(TagKey.create(Registries.ITEM, InputValidator.identifierOf(tag)));
|
||||
String tag = lv.get(1).getString();
|
||||
Optional<HolderSet.Named<Item>> tagSet = blocks.getTag(TagKey.create(Registries.ITEM, InputValidator.identifierOf(tag)));
|
||||
return tagSet.isEmpty() ? Value.NULL : BooleanValue.of(tagSet.get().stream().anyMatch(h -> h.value() == item));
|
||||
});
|
||||
|
||||
expression.addContextFunction("recipe_data", -1, (c, t, lv) ->
|
||||
{
|
||||
final CarpetContext cc = (CarpetContext) c;
|
||||
CarpetContext cc = (CarpetContext) c;
|
||||
if (lv.size() < 1)
|
||||
{
|
||||
throw new InternalExpressionException("'recipe_data' requires at least one argument");
|
||||
}
|
||||
final String recipeName = lv.get(0).getString();
|
||||
String recipeName = lv.get(0).getString();
|
||||
RecipeType<?> type = RecipeType.CRAFTING;
|
||||
if (lv.size() > 1)
|
||||
{
|
||||
final String recipeType = lv.get(1).getString();
|
||||
String recipeType = lv.get(1).getString();
|
||||
type = cc.registry(Registries.RECIPE_TYPE).get(InputValidator.identifierOf(recipeType));
|
||||
if (type == null)
|
||||
{
|
||||
throw new InternalExpressionException("Unknown recipe type: "+recipeType);
|
||||
}
|
||||
}
|
||||
final List<Recipe<?>> recipes = Vanilla.RecipeManager_getAllMatching(cc.server().getRecipeManager(), type, InputValidator.identifierOf(recipeName), cc.registryAccess());
|
||||
List<Recipe<?>> recipes = Vanilla.RecipeManager_getAllMatching(cc.server().getRecipeManager(), type, InputValidator.identifierOf(recipeName), cc.registryAccess());
|
||||
if (recipes.isEmpty())
|
||||
{
|
||||
return Value.NULL;
|
||||
}
|
||||
final List<Value> recipesOutput = new ArrayList<>();
|
||||
final RegistryAccess regs = cc.registryAccess();
|
||||
for (final Recipe<?> recipe : recipes)
|
||||
List<Value> recipesOutput = new ArrayList<>();
|
||||
RegistryAccess regs = cc.registryAccess();
|
||||
for (Recipe<?> recipe : recipes)
|
||||
{
|
||||
final ItemStack result = recipe.getResultItem(regs);
|
||||
final List<Value> ingredientValue = new ArrayList<>();
|
||||
ItemStack result = recipe.getResultItem(regs);
|
||||
List<Value> ingredientValue = new ArrayList<>();
|
||||
recipe.getIngredients().forEach( ingredient -> {
|
||||
// I am flattening ingredient lists per slot.
|
||||
// consider recipe_data('wooden_sword','crafting') and ('iron_nugget', 'blasting') and notice difference
|
||||
// in depths of lists.
|
||||
final List<Collection<ItemStack>> stacks = Vanilla.Ingredient_getRecipeStacks(ingredient);
|
||||
List<Collection<ItemStack>> stacks = Vanilla.Ingredient_getRecipeStacks(ingredient);
|
||||
if (stacks.isEmpty())
|
||||
{
|
||||
ingredientValue.add(Value.NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
final List<Value> alternatives = new ArrayList<>();
|
||||
List<Value> alternatives = new ArrayList<>();
|
||||
stacks.forEach(col -> col.stream().map(is -> ValueConversions.of(is, regs)).forEach(alternatives::add));
|
||||
ingredientValue.add(ListValue.wrap(alternatives));
|
||||
}
|
||||
});
|
||||
final Value recipeSpec;
|
||||
Value recipeSpec;
|
||||
if (recipe instanceof final ShapedRecipe shapedRecipe)
|
||||
{
|
||||
recipeSpec = ListValue.of(
|
||||
@@ -178,42 +183,41 @@ public class Inventories
|
||||
|
||||
expression.addContextFunction("crafting_remaining_item", 1, (c, t, v) ->
|
||||
{
|
||||
final String itemStr = v.get(0).getString();
|
||||
final ResourceLocation id = InputValidator.identifierOf(itemStr);
|
||||
final Registry<Item> registry = ((CarpetContext) c).registry(Registries.ITEM);
|
||||
final Item item = registry.getOptional(id).orElseThrow(() -> new ThrowStatement(itemStr, Throwables.UNKNOWN_ITEM));
|
||||
return !item.hasCraftingRemainingItem()
|
||||
? Value.NULL
|
||||
: new StringValue(NBTSerializableValue.nameFromRegistryId(registry.getKey(item.getCraftingRemainingItem())));
|
||||
String itemStr = v.get(0).getString();
|
||||
ResourceLocation id = InputValidator.identifierOf(itemStr);
|
||||
Registry<Item> registry = ((CarpetContext) c).registry(Registries.ITEM);
|
||||
Item item = registry.getOptional(id).orElseThrow(() -> new ThrowStatement(itemStr, Throwables.UNKNOWN_ITEM));
|
||||
Item reminder = item.getCraftingRemainingItem();
|
||||
return reminder == null ? Value.NULL : NBTSerializableValue.nameFromRegistryId(registry.getKey(reminder));
|
||||
});
|
||||
|
||||
expression.addContextFunction("inventory_size", -1, (c, t, lv) ->
|
||||
{
|
||||
final CarpetContext cc = (CarpetContext) c;
|
||||
final NBTSerializableValue.InventoryLocator inventoryLocator = NBTSerializableValue.locateInventory(cc, lv, 0);
|
||||
CarpetContext cc = (CarpetContext) c;
|
||||
NBTSerializableValue.InventoryLocator inventoryLocator = NBTSerializableValue.locateInventory(cc, lv, 0);
|
||||
return inventoryLocator == null ? Value.NULL : new NumericValue(inventoryLocator.inventory().getContainerSize());
|
||||
});
|
||||
|
||||
expression.addContextFunction("inventory_has_items", -1, (c, t, lv) ->
|
||||
{
|
||||
final CarpetContext cc = (CarpetContext) c;
|
||||
final NBTSerializableValue.InventoryLocator inventoryLocator = NBTSerializableValue.locateInventory(cc, lv, 0);
|
||||
CarpetContext cc = (CarpetContext) c;
|
||||
NBTSerializableValue.InventoryLocator inventoryLocator = NBTSerializableValue.locateInventory(cc, lv, 0);
|
||||
return inventoryLocator == null ? Value.NULL : BooleanValue.of(!inventoryLocator.inventory().isEmpty());
|
||||
});
|
||||
|
||||
//inventory_get(<b, e>, <n>) -> item_triple
|
||||
expression.addContextFunction("inventory_get", -1, (c, t, lv) ->
|
||||
{
|
||||
final CarpetContext cc = (CarpetContext) c;
|
||||
final NBTSerializableValue.InventoryLocator inventoryLocator = NBTSerializableValue.locateInventory(cc, lv, 0);
|
||||
CarpetContext cc = (CarpetContext) c;
|
||||
NBTSerializableValue.InventoryLocator inventoryLocator = NBTSerializableValue.locateInventory(cc, lv, 0);
|
||||
if (inventoryLocator == null)
|
||||
{
|
||||
return Value.NULL;
|
||||
}
|
||||
final RegistryAccess regs = cc.registryAccess();
|
||||
RegistryAccess regs = cc.registryAccess();
|
||||
if (lv.size() == inventoryLocator.offset())
|
||||
{
|
||||
final List<Value> fullInventory = new ArrayList<>();
|
||||
List<Value> fullInventory = new ArrayList<>();
|
||||
for (int i = 0, maxi = inventoryLocator.inventory().getContainerSize(); i < maxi; i++)
|
||||
{
|
||||
fullInventory.add(ValueConversions.of(inventoryLocator.inventory().getItem(i), regs));
|
||||
@@ -230,8 +234,8 @@ public class Inventories
|
||||
//inventory_set(<b,e>, <n>, <count>, <item>, <nbt>)
|
||||
expression.addContextFunction("inventory_set", -1, (c, t, lv) ->
|
||||
{
|
||||
final CarpetContext cc = (CarpetContext) c;
|
||||
final NBTSerializableValue.InventoryLocator inventoryLocator = NBTSerializableValue.locateInventory(cc, lv, 0);
|
||||
CarpetContext cc = (CarpetContext) c;
|
||||
NBTSerializableValue.InventoryLocator inventoryLocator = NBTSerializableValue.locateInventory(cc, lv, 0);
|
||||
if (inventoryLocator == null)
|
||||
{
|
||||
return Value.NULL;
|
||||
@@ -240,25 +244,25 @@ public class Inventories
|
||||
{
|
||||
throw new InternalExpressionException("'inventory_set' requires at least slot number and new stack size, and optional new item");
|
||||
}
|
||||
int slot = (int) NumericValue.asNumber(lv.get(inventoryLocator.offset() + 0)).getLong();
|
||||
int slot = (int) NumericValue.asNumber(lv.get(inventoryLocator.offset())).getLong();
|
||||
slot = NBTSerializableValue.validateSlot(slot, inventoryLocator.inventory());
|
||||
if (slot == inventoryLocator.inventory().getContainerSize())
|
||||
{
|
||||
return Value.NULL;
|
||||
}
|
||||
final int count = (int) NumericValue.asNumber(lv.get(inventoryLocator.offset() + 1)).getLong();
|
||||
final RegistryAccess regs = cc.registryAccess();
|
||||
int count = (int) NumericValue.asNumber(lv.get(inventoryLocator.offset() + 1)).getLong();
|
||||
RegistryAccess regs = cc.registryAccess();
|
||||
if (count == 0)
|
||||
{
|
||||
// clear slot
|
||||
final ItemStack removedStack = inventoryLocator.inventory().removeItemNoUpdate(slot);
|
||||
ItemStack removedStack = inventoryLocator.inventory().removeItemNoUpdate(slot);
|
||||
syncPlayerInventory(inventoryLocator, slot);
|
||||
return ValueConversions.of(removedStack, regs);
|
||||
}
|
||||
if (lv.size() < inventoryLocator.offset() + 3)
|
||||
{
|
||||
final ItemStack previousStack = inventoryLocator.inventory().getItem(slot);
|
||||
final ItemStack newStack = previousStack.copy();
|
||||
ItemStack previousStack = inventoryLocator.inventory().getItem(slot);
|
||||
ItemStack newStack = previousStack.copy();
|
||||
newStack.setCount(count);
|
||||
inventoryLocator.inventory().setItem(slot, newStack);
|
||||
syncPlayerInventory(inventoryLocator, slot);
|
||||
@@ -267,28 +271,24 @@ public class Inventories
|
||||
CompoundTag nbt = null; // skipping one argument
|
||||
if (lv.size() > inventoryLocator.offset() + 3)
|
||||
{
|
||||
final Value nbtValue = lv.get(inventoryLocator.offset() + 3);
|
||||
Value nbtValue = lv.get(inventoryLocator.offset() + 3);
|
||||
if (nbtValue instanceof final NBTSerializableValue nbtsv)
|
||||
{
|
||||
nbt = nbtsv.getCompoundTag();
|
||||
}
|
||||
else if (nbtValue.isNull())
|
||||
{
|
||||
nbt = null;
|
||||
}
|
||||
else
|
||||
else if (!nbtValue.isNull())
|
||||
{
|
||||
nbt = new NBTSerializableValue(nbtValue.getString()).getCompoundTag();
|
||||
}
|
||||
}
|
||||
final ItemInput newitem = NBTSerializableValue.parseItem(lv.get(inventoryLocator.offset() + 2).getString(), nbt, cc.registryAccess());
|
||||
final ItemStack previousStack = inventoryLocator.inventory().getItem(slot);
|
||||
ItemInput newitem = NBTSerializableValue.parseItem(lv.get(inventoryLocator.offset() + 2).getString(), nbt, cc.registryAccess());
|
||||
ItemStack previousStack = inventoryLocator.inventory().getItem(slot);
|
||||
try
|
||||
{
|
||||
inventoryLocator.inventory().setItem(slot, newitem.createItemStack(count, false));
|
||||
syncPlayerInventory(inventoryLocator, slot);
|
||||
}
|
||||
catch (final CommandSyntaxException e)
|
||||
catch (CommandSyntaxException e)
|
||||
{
|
||||
throw new InternalExpressionException(e.getMessage());
|
||||
}
|
||||
@@ -298,8 +298,8 @@ public class Inventories
|
||||
//inventory_find(<b, e>, <item> or null (first empty slot), <start_from=0> ) -> <N> or null
|
||||
expression.addContextFunction("inventory_find", -1, (c, t, lv) ->
|
||||
{
|
||||
final CarpetContext cc = (CarpetContext) c;
|
||||
final NBTSerializableValue.InventoryLocator inventoryLocator = NBTSerializableValue.locateInventory(cc, lv, 0);
|
||||
CarpetContext cc = (CarpetContext) c;
|
||||
NBTSerializableValue.InventoryLocator inventoryLocator = NBTSerializableValue.locateInventory(cc, lv, 0);
|
||||
if (inventoryLocator == null)
|
||||
{
|
||||
return Value.NULL;
|
||||
@@ -307,7 +307,7 @@ public class Inventories
|
||||
ItemInput itemArg = null;
|
||||
if (lv.size() > inventoryLocator.offset())
|
||||
{
|
||||
final Value secondArg = lv.get(inventoryLocator.offset() + 0);
|
||||
Value secondArg = lv.get(inventoryLocator.offset());
|
||||
if (!secondArg.isNull())
|
||||
{
|
||||
itemArg = NBTSerializableValue.parseItem(secondArg.getString(), cc.registryAccess());
|
||||
@@ -321,7 +321,7 @@ public class Inventories
|
||||
startIndex = NBTSerializableValue.validateSlot(startIndex, inventoryLocator.inventory());
|
||||
for (int i = startIndex, maxi = inventoryLocator.inventory().getContainerSize(); i < maxi; i++)
|
||||
{
|
||||
final ItemStack stack = inventoryLocator.inventory().getItem(i);
|
||||
ItemStack stack = inventoryLocator.inventory().getItem(i);
|
||||
if ((itemArg == null && stack.isEmpty()) || (itemArg != null && itemArg.getItem().equals(stack.getItem())))
|
||||
{
|
||||
return new NumericValue(i);
|
||||
@@ -333,8 +333,8 @@ public class Inventories
|
||||
//inventory_remove(<b, e>, <item>, <amount=1>) -> bool
|
||||
expression.addContextFunction("inventory_remove", -1, (c, t, lv) ->
|
||||
{
|
||||
final CarpetContext cc = (CarpetContext) c;
|
||||
final NBTSerializableValue.InventoryLocator inventoryLocator = NBTSerializableValue.locateInventory(cc, lv, 0);
|
||||
CarpetContext cc = (CarpetContext) c;
|
||||
NBTSerializableValue.InventoryLocator inventoryLocator = NBTSerializableValue.locateInventory(cc, lv, 0);
|
||||
if (inventoryLocator == null)
|
||||
{
|
||||
return Value.NULL;
|
||||
@@ -343,7 +343,7 @@ public class Inventories
|
||||
{
|
||||
throw new InternalExpressionException("'inventory_remove' requires at least an item to be removed");
|
||||
}
|
||||
final ItemInput searchItem = NBTSerializableValue.parseItem(lv.get(inventoryLocator.offset()).getString(), cc.registryAccess());
|
||||
ItemInput searchItem = NBTSerializableValue.parseItem(lv.get(inventoryLocator.offset()).getString(), cc.registryAccess());
|
||||
int amount = 1;
|
||||
if (lv.size() > inventoryLocator.offset() + 1)
|
||||
{
|
||||
@@ -357,12 +357,12 @@ public class Inventories
|
||||
}
|
||||
for (int i = 0, maxi = inventoryLocator.inventory().getContainerSize(); i < maxi; i++)
|
||||
{
|
||||
final ItemStack stack = inventoryLocator.inventory().getItem(i);
|
||||
ItemStack stack = inventoryLocator.inventory().getItem(i);
|
||||
if (stack.isEmpty() || !stack.getItem().equals(searchItem.getItem()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
final int left = stack.getCount() - amount;
|
||||
int left = stack.getCount() - amount;
|
||||
if (left > 0)
|
||||
{
|
||||
stack.setCount(left);
|
||||
@@ -384,8 +384,8 @@ public class Inventories
|
||||
//inventory_drop(<b, e>, <n>, <amount=1, 0-whatever's there>) -> entity_item (and sets slot) or null if cannot
|
||||
expression.addContextFunction("drop_item", -1, (c, t, lv) ->
|
||||
{
|
||||
final CarpetContext cc = (CarpetContext) c;
|
||||
final NBTSerializableValue.InventoryLocator inventoryLocator = NBTSerializableValue.locateInventory(cc, lv, 0);
|
||||
CarpetContext cc = (CarpetContext) c;
|
||||
NBTSerializableValue.InventoryLocator inventoryLocator = NBTSerializableValue.locateInventory(cc, lv, 0);
|
||||
if (inventoryLocator == null)
|
||||
{
|
||||
return Value.NULL;
|
||||
@@ -409,7 +409,7 @@ public class Inventories
|
||||
{
|
||||
throw new InternalExpressionException("Cannot throw negative number of items");
|
||||
}
|
||||
final ItemStack stack = inventoryLocator.inventory().getItem(slot);
|
||||
ItemStack stack = inventoryLocator.inventory().getItem(slot);
|
||||
if (stack == null || stack.isEmpty())
|
||||
{
|
||||
return Value.ZERO;
|
||||
@@ -418,30 +418,34 @@ public class Inventories
|
||||
{
|
||||
amount = stack.getCount();
|
||||
}
|
||||
final ItemStack droppedStack = inventoryLocator.inventory().removeItem(slot, amount);
|
||||
ItemStack droppedStack = inventoryLocator.inventory().removeItem(slot, amount);
|
||||
if (droppedStack.isEmpty())
|
||||
{
|
||||
return Value.ZERO;
|
||||
}
|
||||
final Object owner = inventoryLocator.owner();
|
||||
final ItemEntity item;
|
||||
Object owner = inventoryLocator.owner();
|
||||
ItemEntity item;
|
||||
if (owner instanceof final Player player)
|
||||
{
|
||||
item = player.drop(droppedStack, false, true);
|
||||
if (item == null)
|
||||
{
|
||||
return Value.ZERO;
|
||||
}
|
||||
}
|
||||
else if (owner instanceof LivingEntity livingEntity)
|
||||
{
|
||||
// stolen from LookTargetUtil.give((VillagerEntity)owner, droppedStack, (LivingEntity) owner);
|
||||
double double_1 = livingEntity.getY() - 0.30000001192092896D + livingEntity.getEyeHeight();
|
||||
item = new ItemEntity(livingEntity.level, livingEntity.getX(), double_1, livingEntity.getZ(), droppedStack);
|
||||
final Vec3 vec3d = livingEntity.getViewVector(1.0F).normalize().scale(0.3);// new Vec3d(0, 0.3, 0);
|
||||
double dropY = livingEntity.getY() - 0.30000001192092896D + livingEntity.getEyeHeight();
|
||||
item = new ItemEntity(livingEntity.level, livingEntity.getX(), dropY, livingEntity.getZ(), droppedStack);
|
||||
Vec3 vec3d = livingEntity.getViewVector(1.0F).normalize().scale(0.3);// new Vec3d(0, 0.3, 0);
|
||||
item.setDeltaMovement(vec3d);
|
||||
item.setDefaultPickUpDelay();
|
||||
cc.level().addFreshEntity(item);
|
||||
}
|
||||
else
|
||||
{
|
||||
final Vec3 point = Vec3.atCenterOf(inventoryLocator.position()); //pos+0.5v
|
||||
Vec3 point = Vec3.atCenterOf(inventoryLocator.position()); //pos+0.5v
|
||||
item = new ItemEntity(cc.level(), point.x, point.y, point.z, droppedStack);
|
||||
item.setDefaultPickUpDelay();
|
||||
cc.level().addFreshEntity(item);
|
||||
@@ -455,14 +459,14 @@ public class Inventories
|
||||
{
|
||||
throw new InternalExpressionException("'create_screen' requires at least three arguments");
|
||||
}
|
||||
final Value playerValue = lv.get(0);
|
||||
final ServerPlayer player = EntityValue.getPlayerByValue(((CarpetContext) c).server(), playerValue);
|
||||
Value playerValue = lv.get(0);
|
||||
ServerPlayer player = EntityValue.getPlayerByValue(((CarpetContext) c).server(), playerValue);
|
||||
if (player == null)
|
||||
{
|
||||
throw new InternalExpressionException("'create_screen' requires a valid online player as the first argument.");
|
||||
}
|
||||
final String type = lv.get(1).getString();
|
||||
final Component name = FormattedTextValue.getTextByValue(lv.get(2));
|
||||
String type = lv.get(1).getString();
|
||||
Component name = FormattedTextValue.getTextByValue(lv.get(2));
|
||||
FunctionValue function = null;
|
||||
if (lv.size() > 3)
|
||||
{
|
||||
@@ -474,7 +478,7 @@ public class Inventories
|
||||
|
||||
expression.addContextFunction("close_screen", 1, (c, t, lv) ->
|
||||
{
|
||||
final Value value = lv.get(0);
|
||||
Value value = lv.get(0);
|
||||
if (!(value instanceof final ScreenValue screenValue))
|
||||
{
|
||||
throw new InternalExpressionException("'close_screen' requires a screen value as the first argument.");
|
||||
@@ -497,21 +501,21 @@ public class Inventories
|
||||
{
|
||||
throw new InternalExpressionException("'screen_property' requires a screen value as the first argument");
|
||||
}
|
||||
final String propertyName = lv.get(1).getString();
|
||||
String propertyName = lv.get(1).getString();
|
||||
return lv.size() >= 3
|
||||
? screenValue.modifyProperty(propertyName, lv.subList(2, lv.size()))
|
||||
: screenValue.queryProperty(propertyName);
|
||||
});
|
||||
}
|
||||
|
||||
private static void syncPlayerInventory(final NBTSerializableValue.InventoryLocator inventory, final int int_1)
|
||||
private static void syncPlayerInventory(NBTSerializableValue.InventoryLocator inventory, int slot)
|
||||
{
|
||||
if (inventory.owner() instanceof final ServerPlayer player && !inventory.isEnder() && !(inventory.inventory() instanceof ScreenValue.ScreenHandlerInventory))
|
||||
{
|
||||
player.connection.send(new ClientboundContainerSetSlotPacket(
|
||||
-2, 0, // resolve mystery argument
|
||||
int_1,
|
||||
inventory.inventory().getItem(int_1)
|
||||
slot,
|
||||
inventory.inventory().getItem(slot)
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,18 +27,18 @@ public class Monitoring
|
||||
{
|
||||
private static final Map<String, MobCategory> MOB_CATEGORY_MAP = Arrays.stream(MobCategory.values()).collect(Collectors.toMap(MobCategory::getName, Function.identity()));
|
||||
|
||||
public static void apply(final Expression expression)
|
||||
public static void apply(Expression expression)
|
||||
{
|
||||
expression.addContextFunction("system_info", -1, (c, t, lv) ->
|
||||
{
|
||||
if (lv.size() == 0)
|
||||
if (lv.isEmpty())
|
||||
{
|
||||
return SystemInfo.getAll();
|
||||
}
|
||||
if (lv.size() == 1)
|
||||
{
|
||||
final String what = lv.get(0).getString();
|
||||
final Value res = SystemInfo.get(what, (CarpetContext) c);
|
||||
String what = lv.get(0).getString();
|
||||
Value res = SystemInfo.get(what, (CarpetContext) c);
|
||||
if (res == null)
|
||||
{
|
||||
throw new InternalExpressionException("Unknown option for 'system_info': " + what);
|
||||
@@ -50,21 +50,21 @@ public class Monitoring
|
||||
// game processed snooper functions
|
||||
expression.addContextFunction("get_mob_counts", -1, (c, t, lv) ->
|
||||
{
|
||||
final CarpetContext cc = (CarpetContext) c;
|
||||
final ServerLevel world = cc.level();
|
||||
final NaturalSpawner.SpawnState info = world.getChunkSource().getLastSpawnState();
|
||||
CarpetContext cc = (CarpetContext) c;
|
||||
ServerLevel world = cc.level();
|
||||
NaturalSpawner.SpawnState info = world.getChunkSource().getLastSpawnState();
|
||||
if (info == null)
|
||||
{
|
||||
return Value.NULL;
|
||||
}
|
||||
final Object2IntMap<MobCategory> mobcounts = info.getMobCategoryCounts();
|
||||
final int chunks = info.getSpawnableChunkCount();
|
||||
if (lv.size() == 0)
|
||||
Object2IntMap<MobCategory> mobcounts = info.getMobCategoryCounts();
|
||||
int chunks = info.getSpawnableChunkCount();
|
||||
if (lv.isEmpty())
|
||||
{
|
||||
final Map<Value, Value> retDict = new HashMap<>();
|
||||
for (final MobCategory category : mobcounts.keySet())
|
||||
Map<Value, Value> retDict = new HashMap<>();
|
||||
for (MobCategory category : mobcounts.keySet())
|
||||
{
|
||||
final int currentCap = category.getMaxInstancesPerChunk() * chunks / Vanilla.NaturalSpawner_MAGIC_NUMBER();
|
||||
int currentCap = category.getMaxInstancesPerChunk() * chunks / Vanilla.NaturalSpawner_MAGIC_NUMBER();
|
||||
retDict.put(
|
||||
new StringValue(category.getSerializedName().toLowerCase(Locale.ROOT)),
|
||||
ListValue.of(
|
||||
@@ -74,15 +74,15 @@ public class Monitoring
|
||||
}
|
||||
return MapValue.wrap(retDict);
|
||||
}
|
||||
final String catString = lv.get(0).getString();
|
||||
final MobCategory cat = MOB_CATEGORY_MAP.get(catString.toLowerCase(Locale.ROOT));
|
||||
String catString = lv.get(0).getString();
|
||||
MobCategory cat = MOB_CATEGORY_MAP.get(catString.toLowerCase(Locale.ROOT));
|
||||
if (cat == null)
|
||||
{
|
||||
throw new InternalExpressionException("Unreconized mob category: " + catString);
|
||||
}
|
||||
return ListValue.of(
|
||||
new NumericValue(mobcounts.getInt(cat)),
|
||||
new NumericValue((int) (cat.getMaxInstancesPerChunk() * chunks / Vanilla.NaturalSpawner_MAGIC_NUMBER()))
|
||||
new NumericValue((long) cat.getMaxInstancesPerChunk() * chunks / Vanilla.NaturalSpawner_MAGIC_NUMBER())
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -38,30 +38,30 @@ import net.minecraft.world.scores.criteria.ObjectiveCriteria;
|
||||
|
||||
public class Scoreboards
|
||||
{
|
||||
private static String getScoreboardKeyFromValue(final Value keyValue)
|
||||
private static String getScoreboardKeyFromValue(Value keyValue)
|
||||
{
|
||||
if (keyValue instanceof final EntityValue ev)
|
||||
{
|
||||
final Entity e = ev.getEntity();
|
||||
Entity e = ev.getEntity();
|
||||
return e instanceof Player ? e.getName().getString() : e.getStringUUID();
|
||||
}
|
||||
return keyValue.getString();
|
||||
}
|
||||
|
||||
public static void apply(final Expression expression)
|
||||
public static void apply(Expression expression)
|
||||
{
|
||||
// scoreboard(player,'objective')
|
||||
// scoreboard(player, objective, newValue)
|
||||
expression.addContextFunction("scoreboard", -1, (c, t, lv) ->
|
||||
{
|
||||
final CarpetContext cc = (CarpetContext) c;
|
||||
final Scoreboard scoreboard = cc.server().getScoreboard();
|
||||
if (lv.size() == 0)
|
||||
CarpetContext cc = (CarpetContext) c;
|
||||
Scoreboard scoreboard = cc.server().getScoreboard();
|
||||
if (lv.isEmpty())
|
||||
{
|
||||
return ListValue.wrap(scoreboard.getObjectiveNames().stream().map(StringValue::new));
|
||||
}
|
||||
final String objectiveName = lv.get(0).getString();
|
||||
final Objective objective = scoreboard.getOrCreateObjective(objectiveName);
|
||||
String objectiveName = lv.get(0).getString();
|
||||
Objective objective = scoreboard.getOrCreateObjective(objectiveName);
|
||||
if (objective == null)
|
||||
{
|
||||
return Value.NULL;
|
||||
@@ -70,7 +70,7 @@ public class Scoreboards
|
||||
{
|
||||
return ListValue.wrap(scoreboard.getPlayerScores(objective).stream().map(s -> new StringValue(s.getOwner())));
|
||||
}
|
||||
final String key = getScoreboardKeyFromValue(lv.get(1));
|
||||
String key = getScoreboardKeyFromValue(lv.get(1));
|
||||
if (lv.size() == 2)
|
||||
{
|
||||
return !scoreboard.hasPlayerScore(key, objective)
|
||||
@@ -78,16 +78,16 @@ public class Scoreboards
|
||||
: NumericValue.of(scoreboard.getOrCreatePlayerScore(key, objective).getScore());
|
||||
}
|
||||
|
||||
final Value value = lv.get(2);
|
||||
Value value = lv.get(2);
|
||||
if (value.isNull())
|
||||
{
|
||||
final Score score = scoreboard.getOrCreatePlayerScore(key, objective);
|
||||
Score score = scoreboard.getOrCreatePlayerScore(key, objective);
|
||||
scoreboard.resetPlayerScore(key, objective);
|
||||
return NumericValue.of(score.getScore());
|
||||
}
|
||||
if (value instanceof NumericValue)
|
||||
{
|
||||
final Score score = scoreboard.getOrCreatePlayerScore(key, objective);
|
||||
Score score = scoreboard.getOrCreatePlayerScore(key, objective);
|
||||
score.setScore(NumericValue.asNumber(value).getInt());
|
||||
return NumericValue.of(score.getScore());
|
||||
}
|
||||
@@ -96,14 +96,14 @@ public class Scoreboards
|
||||
|
||||
expression.addContextFunction("scoreboard_remove", -1, (c, t, lv) ->
|
||||
{
|
||||
if (lv.size() == 0)
|
||||
if (lv.isEmpty())
|
||||
{
|
||||
throw new InternalExpressionException("'scoreboard_remove' requires at least one parameter");
|
||||
}
|
||||
final CarpetContext cc = (CarpetContext) c;
|
||||
final Scoreboard scoreboard = cc.server().getScoreboard();
|
||||
final String objectiveName = lv.get(0).getString();
|
||||
final Objective objective = scoreboard.getOrCreateObjective(objectiveName);
|
||||
CarpetContext cc = (CarpetContext) c;
|
||||
Scoreboard scoreboard = cc.server().getScoreboard();
|
||||
String objectiveName = lv.get(0).getString();
|
||||
Objective objective = scoreboard.getOrCreateObjective(objectiveName);
|
||||
if (objective == null)
|
||||
{
|
||||
return Value.FALSE;
|
||||
@@ -113,13 +113,13 @@ public class Scoreboards
|
||||
scoreboard.removeObjective(objective);
|
||||
return Value.TRUE;
|
||||
}
|
||||
final String key = getScoreboardKeyFromValue(lv.get(1));
|
||||
String key = getScoreboardKeyFromValue(lv.get(1));
|
||||
if (!scoreboard.hasPlayerScore(key, objective))
|
||||
{
|
||||
return Value.NULL;
|
||||
}
|
||||
final Score scoreboardPlayerScore = scoreboard.getOrCreatePlayerScore(key, objective);
|
||||
final Value previous = new NumericValue(scoreboardPlayerScore.getScore());
|
||||
Score scoreboardPlayerScore = scoreboard.getOrCreatePlayerScore(key, objective);
|
||||
Value previous = new NumericValue(scoreboardPlayerScore.getScore());
|
||||
scoreboard.resetPlayerScore(key, objective);
|
||||
return previous;
|
||||
});
|
||||
@@ -129,21 +129,21 @@ public class Scoreboards
|
||||
|
||||
expression.addContextFunction("scoreboard_add", -1, (c, t, lv) ->
|
||||
{
|
||||
final CarpetContext cc = (CarpetContext) c;
|
||||
final Scoreboard scoreboard = cc.server().getScoreboard();
|
||||
if (lv.size() == 0 || lv.size() > 2)
|
||||
CarpetContext cc = (CarpetContext) c;
|
||||
Scoreboard scoreboard = cc.server().getScoreboard();
|
||||
if (lv.isEmpty() || lv.size() > 2)
|
||||
{
|
||||
throw new InternalExpressionException("'scoreboard_add' should have one or two parameters");
|
||||
}
|
||||
final String objectiveName = lv.get(0).getString();
|
||||
final ObjectiveCriteria criterion;
|
||||
String objectiveName = lv.get(0).getString();
|
||||
ObjectiveCriteria criterion;
|
||||
if (lv.size() == 1)
|
||||
{
|
||||
criterion = ObjectiveCriteria.DUMMY;
|
||||
}
|
||||
else
|
||||
{
|
||||
final String critetionName = lv.get(1).getString();
|
||||
String critetionName = lv.get(1).getString();
|
||||
criterion = ObjectiveCriteria.byName(critetionName).orElse(null);
|
||||
if (criterion == null)
|
||||
{
|
||||
@@ -151,7 +151,7 @@ public class Scoreboards
|
||||
}
|
||||
}
|
||||
|
||||
final Objective objective = scoreboard.getOrCreateObjective(objectiveName);
|
||||
Objective objective = scoreboard.getOrCreateObjective(objectiveName);
|
||||
if (objective != null)
|
||||
{
|
||||
c.host.issueDeprecation("reading or modifying an objective's criterion with scoreboard_add");
|
||||
@@ -165,7 +165,7 @@ public class Scoreboards
|
||||
}
|
||||
Vanilla.Scoreboard_getObjectivesByCriterion(scoreboard).get(objective.getCriteria()).remove(objective);
|
||||
Vanilla.Objective_setCriterion(objective, criterion);
|
||||
(Vanilla.Scoreboard_getObjectivesByCriterion(scoreboard).computeIfAbsent(criterion, (criterion1) -> Lists.newArrayList())).add(objective);
|
||||
(Vanilla.Scoreboard_getObjectivesByCriterion(scoreboard).computeIfAbsent(criterion, cr -> Lists.newArrayList())).add(objective);
|
||||
scoreboard.onObjectiveAdded(objective);
|
||||
return Value.FALSE;
|
||||
}
|
||||
@@ -179,27 +179,27 @@ public class Scoreboards
|
||||
{
|
||||
throw new InternalExpressionException("'scoreboard_property' requires at least two parameters");
|
||||
}
|
||||
final CarpetContext cc = (CarpetContext) c;
|
||||
final Scoreboard scoreboard = cc.server().getScoreboard();
|
||||
final Objective objective = scoreboard.getOrCreateObjective(lv.get(0).getString());
|
||||
CarpetContext cc = (CarpetContext) c;
|
||||
Scoreboard scoreboard = cc.server().getScoreboard();
|
||||
Objective objective = scoreboard.getOrCreateObjective(lv.get(0).getString());
|
||||
if (objective == null)
|
||||
{
|
||||
return Value.NULL;
|
||||
}
|
||||
|
||||
final boolean modify = lv.size() > 2;
|
||||
boolean modify = lv.size() > 2;
|
||||
Value setValue = null;
|
||||
if (modify)
|
||||
{
|
||||
setValue = lv.get(2);
|
||||
}
|
||||
final String property = lv.get(1).getString();
|
||||
String property = lv.get(1).getString();
|
||||
switch (property)
|
||||
{
|
||||
case "criterion" -> {
|
||||
if (modify)
|
||||
{
|
||||
final ObjectiveCriteria criterion = ObjectiveCriteria.byName(setValue.getString()).orElse(null);
|
||||
ObjectiveCriteria criterion = ObjectiveCriteria.byName(setValue.getString()).orElse(null);
|
||||
if (criterion == null)
|
||||
{
|
||||
throw new InternalExpressionException("Unknown scoreboard criterion: " + setValue.getString());
|
||||
@@ -210,7 +210,7 @@ public class Scoreboards
|
||||
}
|
||||
Vanilla.Scoreboard_getObjectivesByCriterion(scoreboard).get(objective.getCriteria()).remove(objective);
|
||||
Vanilla.Objective_setCriterion(objective, criterion);
|
||||
(Vanilla.Scoreboard_getObjectivesByCriterion(scoreboard).computeIfAbsent(criterion, (criterion1) -> Lists.newArrayList())).add(objective);
|
||||
(Vanilla.Scoreboard_getObjectivesByCriterion(scoreboard).computeIfAbsent(criterion, cr -> Lists.newArrayList())).add(objective);
|
||||
scoreboard.onObjectiveAdded(objective);
|
||||
return Value.TRUE;
|
||||
}
|
||||
@@ -219,7 +219,7 @@ public class Scoreboards
|
||||
case "display_name" -> {
|
||||
if (modify)
|
||||
{
|
||||
final Component text = FormattedTextValue.getTextByValue(setValue);
|
||||
Component text = FormattedTextValue.getTextByValue(setValue);
|
||||
objective.setDisplayName(text);
|
||||
return Value.TRUE;
|
||||
}
|
||||
@@ -228,7 +228,7 @@ public class Scoreboards
|
||||
case "display_slot" -> {
|
||||
if (modify)
|
||||
{
|
||||
final int slotId = Scoreboard.getDisplaySlotByName(setValue.getString());
|
||||
int slotId = Scoreboard.getDisplaySlotByName(setValue.getString());
|
||||
if (slotId == -1)
|
||||
{
|
||||
throw new InternalExpressionException("Unknown scoreboard display slot: " + setValue.getString());
|
||||
@@ -240,12 +240,12 @@ public class Scoreboards
|
||||
scoreboard.setDisplayObjective(slotId, objective);
|
||||
return Value.TRUE;
|
||||
}
|
||||
final List<Value> slots = new ArrayList<>();
|
||||
List<Value> slots = new ArrayList<>();
|
||||
for (int i = 0; i < 19; i++)
|
||||
{
|
||||
if (scoreboard.getDisplayObjective(i) == objective)
|
||||
{
|
||||
final String slotName = Scoreboard.getDisplaySlotName(i);
|
||||
String slotName = Scoreboard.getDisplaySlotName(i);
|
||||
slots.add(StringValue.of(slotName));
|
||||
}
|
||||
}
|
||||
@@ -254,7 +254,7 @@ public class Scoreboards
|
||||
case "render_type" -> {
|
||||
if (modify)
|
||||
{
|
||||
final ObjectiveCriteria.RenderType renderType = ObjectiveCriteria.RenderType.byId(setValue.getString().toLowerCase());
|
||||
ObjectiveCriteria.RenderType renderType = ObjectiveCriteria.RenderType.byId(setValue.getString().toLowerCase());
|
||||
if (objective.getRenderType().equals(renderType))
|
||||
{
|
||||
return Value.FALSE;
|
||||
@@ -270,22 +270,22 @@ public class Scoreboards
|
||||
|
||||
expression.addContextFunction("scoreboard_display", 2, (c, t, lv) ->
|
||||
{
|
||||
final CarpetContext cc = (CarpetContext) c;
|
||||
final Scoreboard scoreboard = cc.server().getScoreboard();
|
||||
final String location = lv.get(0).getString();
|
||||
final int slot = Scoreboard.getDisplaySlotByName(location);
|
||||
CarpetContext cc = (CarpetContext) c;
|
||||
Scoreboard scoreboard = cc.server().getScoreboard();
|
||||
String location = lv.get(0).getString();
|
||||
int slot = Scoreboard.getDisplaySlotByName(location);
|
||||
if (slot < 0)
|
||||
{
|
||||
throw new InternalExpressionException("Invalid objective slot: " + location);
|
||||
}
|
||||
final Value target = lv.get(1);
|
||||
Value target = lv.get(1);
|
||||
if (target.isNull())
|
||||
{
|
||||
scoreboard.setDisplayObjective(slot, null);
|
||||
return new NumericValue(slot);
|
||||
}
|
||||
final String objectiveString = target.getString();
|
||||
final Objective objective = scoreboard.getOrCreateObjective(objectiveString);
|
||||
String objectiveString = target.getString();
|
||||
Objective objective = scoreboard.getOrCreateObjective(objectiveString);
|
||||
if (objective == null)
|
||||
{
|
||||
return Value.NULL;
|
||||
@@ -300,9 +300,9 @@ public class Scoreboards
|
||||
{
|
||||
throw new InternalExpressionException("'team_list' requires zero or one parameters");
|
||||
}
|
||||
final CarpetContext cc = (CarpetContext) c;
|
||||
final ServerScoreboard scoreboard = cc.server().getScoreboard();
|
||||
if (lv.size() == 0)
|
||||
CarpetContext cc = (CarpetContext) c;
|
||||
ServerScoreboard scoreboard = cc.server().getScoreboard();
|
||||
if (lv.isEmpty())
|
||||
{
|
||||
return ListValue.wrap(scoreboard.getTeamNames().stream().map(StringValue::of));
|
||||
}
|
||||
@@ -310,21 +310,21 @@ public class Scoreboards
|
||||
{
|
||||
return Value.NULL;
|
||||
}
|
||||
final PlayerTeam team = scoreboard.getPlayerTeam(lv.get(0).getString());
|
||||
PlayerTeam team = scoreboard.getPlayerTeam(lv.get(0).getString());
|
||||
return team == null ? Value.NULL : ListValue.wrap(team.getPlayers().stream().map(StringValue::of));
|
||||
});
|
||||
|
||||
|
||||
expression.addContextFunction("team_add", -1, (c, t, lv) ->
|
||||
{
|
||||
if (!(lv.size() < 3 && lv.size() > 0))
|
||||
if (!(lv.size() < 3 && !lv.isEmpty()))
|
||||
{
|
||||
throw new InternalExpressionException("'team_add' requires one or two parameters");
|
||||
}
|
||||
|
||||
final CarpetContext cc = (CarpetContext) c;
|
||||
final ServerScoreboard scoreboard = cc.server().getScoreboard();
|
||||
final String teamName = lv.get(0).getString();
|
||||
CarpetContext cc = (CarpetContext) c;
|
||||
ServerScoreboard scoreboard = cc.server().getScoreboard();
|
||||
String teamName = lv.get(0).getString();
|
||||
|
||||
if (lv.size() == 1)
|
||||
{
|
||||
@@ -339,13 +339,13 @@ public class Scoreboards
|
||||
{
|
||||
return Value.NULL;
|
||||
}
|
||||
final Value playerVal = lv.get(1);
|
||||
final String player = EntityValue.getPlayerNameByValue(playerVal);
|
||||
Value playerVal = lv.get(1);
|
||||
String player = EntityValue.getPlayerNameByValue(playerVal);
|
||||
if (player == null)
|
||||
{
|
||||
return Value.NULL;
|
||||
}
|
||||
final PlayerTeam team = scoreboard.getPlayerTeam(teamName);
|
||||
PlayerTeam team = scoreboard.getPlayerTeam(teamName);
|
||||
if (team == null)
|
||||
{
|
||||
return Value.NULL;
|
||||
@@ -354,44 +354,44 @@ public class Scoreboards
|
||||
{
|
||||
return Value.FALSE;
|
||||
}
|
||||
scoreboard.addPlayerToTeam(player, scoreboard.getPlayerTeam(teamName));
|
||||
scoreboard.addPlayerToTeam(player, team);
|
||||
return Value.TRUE;
|
||||
});
|
||||
|
||||
expression.addContextFunction("team_remove", 1, (c, t, lv) ->
|
||||
{
|
||||
final CarpetContext cc = (CarpetContext) c;
|
||||
final ServerScoreboard scoreboard = cc.server().getScoreboard();
|
||||
final Value teamVal = lv.get(0);
|
||||
final String team = teamVal.getString();
|
||||
if (scoreboard.getPlayerTeam(team) == null)
|
||||
CarpetContext cc = (CarpetContext) c;
|
||||
ServerScoreboard scoreboard = cc.server().getScoreboard();
|
||||
Value teamVal = lv.get(0);
|
||||
PlayerTeam team = scoreboard.getPlayerTeam(teamVal.getString());
|
||||
if (team == null)
|
||||
{
|
||||
return Value.NULL;
|
||||
}
|
||||
scoreboard.removePlayerTeam(scoreboard.getPlayerTeam(team));
|
||||
scoreboard.removePlayerTeam(team);
|
||||
return Value.TRUE;
|
||||
});
|
||||
|
||||
|
||||
expression.addContextFunction("team_leave", 1, (c, t, lv) ->
|
||||
{
|
||||
final CarpetContext cc = (CarpetContext) c;
|
||||
final ServerScoreboard scoreboard = cc.server().getScoreboard();
|
||||
final Value playerVal = lv.get(0);
|
||||
final String player = EntityValue.getPlayerNameByValue(playerVal);
|
||||
CarpetContext cc = (CarpetContext) c;
|
||||
ServerScoreboard scoreboard = cc.server().getScoreboard();
|
||||
Value playerVal = lv.get(0);
|
||||
String player = EntityValue.getPlayerNameByValue(playerVal);
|
||||
return player == null ? Value.NULL : BooleanValue.of(scoreboard.removePlayerFromTeam(player));
|
||||
});
|
||||
|
||||
expression.addContextFunction("team_property", -1, (c, t, lv) ->
|
||||
{
|
||||
final CarpetContext cc = (CarpetContext) c;
|
||||
final ServerScoreboard scoreboard = cc.server().getScoreboard();
|
||||
CarpetContext cc = (CarpetContext) c;
|
||||
ServerScoreboard scoreboard = cc.server().getScoreboard();
|
||||
if (lv.size() < 2 || lv.size() > 3)
|
||||
{
|
||||
throw new InternalExpressionException("'team_property' requires two or three arguments");
|
||||
}
|
||||
final Value teamVal = lv.get(0);
|
||||
final Value propertyVal = lv.get(1);
|
||||
Value teamVal = lv.get(0);
|
||||
Value propertyVal = lv.get(1);
|
||||
|
||||
Value settingVal = null;
|
||||
boolean modifying = false;
|
||||
@@ -401,7 +401,7 @@ public class Scoreboards
|
||||
settingVal = lv.get(2);
|
||||
}
|
||||
|
||||
final PlayerTeam team = scoreboard.getPlayerTeam(teamVal.getString());
|
||||
PlayerTeam team = scoreboard.getPlayerTeam(teamVal.getString());
|
||||
if (team == null)
|
||||
{
|
||||
return Value.NULL;
|
||||
@@ -423,7 +423,7 @@ public class Scoreboards
|
||||
{
|
||||
throw new InternalExpressionException("'team_property' requires a string as the third argument for the property " + propertyVal.getString());
|
||||
}
|
||||
final Team.CollisionRule collisionRule = Team.CollisionRule.byName(settingVal.getString());
|
||||
Team.CollisionRule collisionRule = Team.CollisionRule.byName(settingVal.getString());
|
||||
if (collisionRule == null)
|
||||
{
|
||||
throw new InternalExpressionException("Unknown value for property " + propertyVal.getString() + ": " + settingVal.getString());
|
||||
@@ -439,7 +439,7 @@ public class Scoreboards
|
||||
{
|
||||
throw new InternalExpressionException("'team_property' requires a string as the third argument for the property " + propertyVal.getString());
|
||||
}
|
||||
final ChatFormatting color = ChatFormatting.getByName(settingVal.getString().toUpperCase());
|
||||
ChatFormatting color = ChatFormatting.getByName(settingVal.getString().toUpperCase());
|
||||
if (color == null || !color.isColor())
|
||||
{
|
||||
throw new InternalExpressionException("Unknown value for property " + propertyVal.getString() + ": " + settingVal.getString());
|
||||
@@ -455,7 +455,7 @@ public class Scoreboards
|
||||
{
|
||||
throw new InternalExpressionException("'team_property' requires a string as the third argument for the property " + propertyVal.getString());
|
||||
}
|
||||
final Team.Visibility deathMessageVisibility = Team.Visibility.byName(settingVal.getString());
|
||||
Team.Visibility deathMessageVisibility = Team.Visibility.byName(settingVal.getString());
|
||||
if (deathMessageVisibility == null)
|
||||
{
|
||||
throw new InternalExpressionException("Unknown value for property " + propertyVal.getString() + ": " + settingVal.getString());
|
||||
@@ -493,7 +493,7 @@ public class Scoreboards
|
||||
{
|
||||
throw new InternalExpressionException("'team_property' requires a string as the third argument for the property " + propertyVal.getString());
|
||||
}
|
||||
final Team.Visibility nametagVisibility = Team.Visibility.byName(settingVal.getString());
|
||||
Team.Visibility nametagVisibility = Team.Visibility.byName(settingVal.getString());
|
||||
if (nametagVisibility == null)
|
||||
{
|
||||
throw new InternalExpressionException("Unknown value for property " + propertyVal.getString() + ": " + settingVal.getString());
|
||||
@@ -540,19 +540,19 @@ public class Scoreboards
|
||||
|
||||
expression.addContextFunction("bossbar", -1, (c, t, lv) ->
|
||||
{
|
||||
final CustomBossEvents bossBarManager = ((CarpetContext) c).server().getCustomBossEvents();
|
||||
CustomBossEvents bossBarManager = ((CarpetContext) c).server().getCustomBossEvents();
|
||||
if (lv.size() > 3)
|
||||
{
|
||||
throw new InternalExpressionException("'bossbar' accepts max three arguments");
|
||||
}
|
||||
|
||||
if (lv.size() == 0)
|
||||
if (lv.isEmpty())
|
||||
{
|
||||
return ListValue.wrap(bossBarManager.getEvents().stream().map(CustomBossEvent::getTextId).map(ResourceLocation::toString).map(StringValue::of));
|
||||
}
|
||||
|
||||
final String id = lv.get(0).getString();
|
||||
final ResourceLocation identifier = InputValidator.identifierOf(id);
|
||||
String id = lv.get(0).getString();
|
||||
ResourceLocation identifier = InputValidator.identifierOf(id);
|
||||
|
||||
if (lv.size() == 1)
|
||||
{
|
||||
@@ -563,25 +563,25 @@ public class Scoreboards
|
||||
return StringValue.of(bossBarManager.create(identifier, Component.literal(id)).getTextId().toString());
|
||||
}
|
||||
|
||||
final String property = lv.get(1).getString();
|
||||
String property = lv.get(1).getString();
|
||||
|
||||
final CustomBossEvent bossBar = bossBarManager.get(identifier);
|
||||
CustomBossEvent bossBar = bossBarManager.get(identifier);
|
||||
if (bossBar == null)
|
||||
{
|
||||
return Value.NULL;
|
||||
}
|
||||
|
||||
final Value propertyValue = (lv.size() == 3) ? lv.get(2) : null;
|
||||
Value propertyValue = (lv.size() == 3) ? lv.get(2) : null;
|
||||
|
||||
switch (property)
|
||||
{
|
||||
case "color" -> {
|
||||
if (propertyValue == null)
|
||||
{
|
||||
final BossEvent.BossBarColor color = (bossBar).getColor();
|
||||
BossEvent.BossBarColor color = (bossBar).getColor();
|
||||
return color == null ? Value.NULL : StringValue.of(color.getName());
|
||||
}
|
||||
final BossEvent.BossBarColor color = BossEvent.BossBarColor.byName(propertyValue.getString());
|
||||
BossEvent.BossBarColor color = BossEvent.BossBarColor.byName(propertyValue.getString());
|
||||
if (color == null)
|
||||
{
|
||||
return Value.NULL;
|
||||
@@ -616,8 +616,8 @@ public class Scoreboards
|
||||
}
|
||||
if (propertyValue instanceof final ListValue list)
|
||||
{
|
||||
list.getItems().forEach((v) -> {
|
||||
final ServerPlayer player = EntityValue.getPlayerByValue(((CarpetContext) c).server(), propertyValue);
|
||||
list.getItems().forEach(v -> {
|
||||
ServerPlayer player = EntityValue.getPlayerByValue(((CarpetContext) c).server(), propertyValue);
|
||||
if (player != null)
|
||||
{
|
||||
bossBar.addPlayer(player);
|
||||
@@ -625,7 +625,7 @@ public class Scoreboards
|
||||
});
|
||||
return Value.TRUE;
|
||||
}
|
||||
final ServerPlayer player = EntityValue.getPlayerByValue(((CarpetContext) c).server(), propertyValue);
|
||||
ServerPlayer player = EntityValue.getPlayerByValue(((CarpetContext) c).server(), propertyValue);
|
||||
if (player != null)
|
||||
{
|
||||
bossBar.addPlayer(player);
|
||||
@@ -650,7 +650,7 @@ public class Scoreboards
|
||||
});
|
||||
return Value.TRUE;
|
||||
}
|
||||
final ServerPlayer p = EntityValue.getPlayerByValue(((CarpetContext) c).server(), propertyValue);
|
||||
ServerPlayer p = EntityValue.getPlayerByValue(((CarpetContext) c).server(), propertyValue);
|
||||
bossBar.removeAllPlayers();
|
||||
if (p != null)
|
||||
{
|
||||
@@ -664,7 +664,7 @@ public class Scoreboards
|
||||
{
|
||||
return StringValue.of(bossBar.getOverlay().getName());
|
||||
}
|
||||
final BossEvent.BossBarOverlay style = BossEvent.BossBarOverlay.byName(propertyValue.getString());
|
||||
BossEvent.BossBarOverlay style = BossEvent.BossBarOverlay.byName(propertyValue.getString());
|
||||
if (style == null)
|
||||
{
|
||||
throw new InternalExpressionException("'" + propertyValue.getString() + "' is not a valid value for property " + property);
|
||||
|
||||
@@ -14,13 +14,13 @@ public class Threading
|
||||
{
|
||||
public static void apply(Expression expression)
|
||||
{
|
||||
//"overidden" native call to cancel if on main thread
|
||||
//"overridden" native call to cancel if on main thread
|
||||
expression.addContextFunction("task_join", 1, (c, t, lv) -> {
|
||||
if (((CarpetContext) c).server().isSameThread())
|
||||
{
|
||||
throw new InternalExpressionException("'task_join' cannot be called from main thread to avoid deadlocks");
|
||||
}
|
||||
final Value v = lv.get(0);
|
||||
Value v = lv.get(0);
|
||||
if (!(v instanceof final ThreadValue tv))
|
||||
{
|
||||
throw new InternalExpressionException("'task_join' could only be used with a task value");
|
||||
@@ -30,14 +30,14 @@ public class Threading
|
||||
|
||||
// has to be lazy due to deferred execution of the expression
|
||||
expression.addLazyFunctionWithDelegation("task_dock", 1, false, true, (c, t, expr, tok, lv) -> {
|
||||
final CarpetContext cc = (CarpetContext) c;
|
||||
final MinecraftServer server = cc.server();
|
||||
CarpetContext cc = (CarpetContext) c;
|
||||
MinecraftServer server = cc.server();
|
||||
if (server.isSameThread())
|
||||
{
|
||||
return lv.get(0); // pass through for on thread tasks
|
||||
}
|
||||
final Value[] result = new Value[]{Value.NULL};
|
||||
final RuntimeException[] internal = new RuntimeException[]{null};
|
||||
Value[] result = new Value[]{Value.NULL};
|
||||
RuntimeException[] internal = new RuntimeException[]{null};
|
||||
try
|
||||
{
|
||||
((CarpetContext) c).server().executeBlocking(() ->
|
||||
@@ -46,22 +46,22 @@ public class Threading
|
||||
{
|
||||
result[0] = lv.get(0).evalValue(c, t);
|
||||
}
|
||||
catch (final ExpressionException exc)
|
||||
catch (ExpressionException exc)
|
||||
{
|
||||
internal[0] = exc;
|
||||
}
|
||||
catch (final InternalExpressionException exc)
|
||||
catch (InternalExpressionException exc)
|
||||
{
|
||||
internal[0] = new ExpressionException(c, expr, tok, exc.getMessage(), exc.stack);
|
||||
}
|
||||
|
||||
catch (final ArithmeticException exc)
|
||||
catch (ArithmeticException exc)
|
||||
{
|
||||
internal[0] = new ExpressionException(c, expr, tok, "Your math is wrong, " + exc.getMessage());
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (final CompletionException exc)
|
||||
catch (CompletionException exc)
|
||||
{
|
||||
throw new InternalExpressionException("Error while executing docked task section, internal stack trace is gone");
|
||||
}
|
||||
@@ -69,8 +69,8 @@ public class Threading
|
||||
{
|
||||
throw internal[0];
|
||||
}
|
||||
final Value ret = result[0]; // preventing from lazy evaluating of the result in case a future completes later
|
||||
return (_c, _t) -> ret;
|
||||
Value ret = result[0]; // preventing from lazy evaluating of the result in case a future completes later
|
||||
return (ct, tt) -> ret;
|
||||
// pass through placeholder
|
||||
// implmenetation should dock the task on the main thread.
|
||||
});
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -2,7 +2,7 @@ package carpet.script.argument;
|
||||
|
||||
public abstract class Argument
|
||||
{
|
||||
public int offset;
|
||||
public final int offset;
|
||||
|
||||
protected Argument(int offset)
|
||||
{
|
||||
|
||||
@@ -14,53 +14,55 @@ import java.util.NoSuchElementException;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class BlockArgument extends Argument
|
||||
{
|
||||
public final BlockValue block;
|
||||
public final String replacement;
|
||||
@Nullable public final String replacement;
|
||||
|
||||
private BlockArgument(final BlockValue b, final int o)
|
||||
private BlockArgument(BlockValue b, int o)
|
||||
{
|
||||
super(o);
|
||||
block = b;
|
||||
replacement = null;
|
||||
}
|
||||
|
||||
private BlockArgument(final BlockValue b, final int o, final String replacement)
|
||||
private BlockArgument(BlockValue b, int o, @Nullable String replacement)
|
||||
{
|
||||
super(o);
|
||||
block = b;
|
||||
this.replacement = replacement;
|
||||
}
|
||||
|
||||
public static BlockArgument findIn(final CarpetContext c, final List<Value> params, final int offset)
|
||||
public static BlockArgument findIn(CarpetContext c, List<Value> params, int offset)
|
||||
{
|
||||
return findIn(c, params, offset, false, false, false);
|
||||
}
|
||||
|
||||
public static BlockArgument findIn(final CarpetContext c, final List<Value> params, final int offset, final boolean acceptString)
|
||||
public static BlockArgument findIn(CarpetContext c, List<Value> params, int offset, boolean acceptString)
|
||||
{
|
||||
return findIn(c, params, offset, acceptString, false, false);
|
||||
}
|
||||
|
||||
public static BlockArgument findIn(final CarpetContext c, final List<Value> params, final int offset, final boolean acceptString, final boolean optional, final boolean anyString)
|
||||
public static BlockArgument findIn(CarpetContext c, List<Value> params, int offset, boolean acceptString, boolean optional, boolean anyString)
|
||||
{
|
||||
return findIn(c, params.listIterator(offset), offset, acceptString, optional, anyString);
|
||||
}
|
||||
|
||||
public static BlockArgument findIn(final CarpetContext c, final Iterator<Value> params, final int offset, final boolean acceptString, final boolean optional, final boolean anyString)
|
||||
public static BlockArgument findIn(CarpetContext c, Iterator<Value> params, int offset, boolean acceptString, boolean optional, boolean anyString)
|
||||
{
|
||||
try
|
||||
{
|
||||
final Value v1 = params.next();
|
||||
Value v1 = params.next();
|
||||
//add conditional from string name
|
||||
if (optional && v1.isNull())
|
||||
{
|
||||
return new BlockArgument(null, 1 + offset);
|
||||
return new MissingBlockArgument(1 + offset, null);
|
||||
}
|
||||
if (anyString && v1 instanceof StringValue)
|
||||
{
|
||||
return new BlockArgument(null, 1 + offset, v1.getString());
|
||||
return new MissingBlockArgument(1 + offset, v1.getString());
|
||||
}
|
||||
if (acceptString && v1 instanceof StringValue)
|
||||
{
|
||||
@@ -70,28 +72,26 @@ public class BlockArgument extends Argument
|
||||
{
|
||||
return new BlockArgument(((BlockValue) v1), 1 + offset);
|
||||
}
|
||||
final BlockPos pos = c.origin();
|
||||
BlockPos pos = c.origin();
|
||||
if (v1 instanceof ListValue)
|
||||
{
|
||||
final List<Value> args = ((ListValue) v1).getItems();
|
||||
final int xpos = (int) NumericValue.asNumber(args.get(0)).getLong();
|
||||
final int ypos = (int) NumericValue.asNumber(args.get(1)).getLong();
|
||||
final int zpos = (int) NumericValue.asNumber(args.get(2)).getLong();
|
||||
List<Value> args = ((ListValue) v1).getItems();
|
||||
int xpos = (int) NumericValue.asNumber(args.get(0)).getLong();
|
||||
int ypos = (int) NumericValue.asNumber(args.get(1)).getLong();
|
||||
int zpos = (int) NumericValue.asNumber(args.get(2)).getLong();
|
||||
|
||||
return new BlockArgument(
|
||||
new BlockValue(
|
||||
null,
|
||||
c.level(),
|
||||
new BlockPos(pos.getX() + xpos, pos.getY() + ypos, pos.getZ() + zpos)
|
||||
),
|
||||
1 + offset);
|
||||
}
|
||||
final int xpos = (int) NumericValue.asNumber(v1).getLong();
|
||||
final int ypos = (int) NumericValue.asNumber(params.next()).getLong();
|
||||
final int zpos = (int) NumericValue.asNumber(params.next()).getLong();
|
||||
int xpos = (int) NumericValue.asNumber(v1).getLong();
|
||||
int ypos = (int) NumericValue.asNumber(params.next()).getLong();
|
||||
int zpos = (int) NumericValue.asNumber(params.next()).getLong();
|
||||
return new BlockArgument(
|
||||
new BlockValue(
|
||||
null,
|
||||
c.level(),
|
||||
new BlockPos(pos.getX() + xpos, pos.getY() + ypos, pos.getZ() + zpos)
|
||||
),
|
||||
@@ -104,7 +104,15 @@ public class BlockArgument extends Argument
|
||||
}
|
||||
}
|
||||
|
||||
private static InternalExpressionException handleError(final boolean optional, final boolean acceptString)
|
||||
public static class MissingBlockArgument extends BlockArgument
|
||||
{
|
||||
public MissingBlockArgument(int o, @Nullable String replacement)
|
||||
{
|
||||
super(BlockValue.NONE, o, replacement);
|
||||
}
|
||||
}
|
||||
|
||||
private static InternalExpressionException handleError(boolean optional, boolean acceptString)
|
||||
{
|
||||
String message = "Block-type argument should be defined either by three coordinates (a triple or by three arguments), or a block value";
|
||||
if (acceptString)
|
||||
|
||||
@@ -22,6 +22,7 @@ import net.minecraft.nbt.TagTypes;
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.BufferedWriter;
|
||||
@@ -50,15 +51,15 @@ import java.util.stream.Stream;
|
||||
|
||||
public class FileArgument
|
||||
{
|
||||
public String resource;
|
||||
public Type type;
|
||||
public String zipContainer;
|
||||
public boolean isFolder;
|
||||
public boolean isShared;
|
||||
public Reason reason;
|
||||
public final String resource;
|
||||
public final Type type;
|
||||
public final String zipContainer;
|
||||
public final boolean isFolder;
|
||||
public final boolean isShared;
|
||||
public final Reason reason;
|
||||
private FileSystem zfs;
|
||||
private Path zipPath;
|
||||
private ScriptHost host;
|
||||
private final ScriptHost host;
|
||||
|
||||
public static final Object writeIOSync = new Object();
|
||||
|
||||
@@ -70,7 +71,7 @@ public class FileArgument
|
||||
{
|
||||
zfs.close();
|
||||
}
|
||||
catch (final IOException e)
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new InternalExpressionException("Unable to close zip container: " + zipContainer);
|
||||
}
|
||||
@@ -90,9 +91,9 @@ public class FileArgument
|
||||
private final String id;
|
||||
private final String extension;
|
||||
|
||||
public static Map<String, Type> of = Arrays.stream(values()).collect(Collectors.toMap(t -> t.id, t -> t));
|
||||
private static final Map<String, Type> of = Arrays.stream(values()).collect(Collectors.toMap(t -> t.id, t -> t));
|
||||
|
||||
Type(final String id, final String extension)
|
||||
Type(String id, String extension)
|
||||
{
|
||||
this.id = id;
|
||||
this.extension = extension;
|
||||
@@ -104,7 +105,7 @@ public class FileArgument
|
||||
READ, CREATE, DELETE
|
||||
}
|
||||
|
||||
public FileArgument(final String resource, final Type type, final String zipContainer, final boolean isFolder, final boolean isShared, final Reason reason, final ScriptHost host)
|
||||
public FileArgument(@Nullable String resource, Type type, @Nullable String zipContainer, boolean isFolder, boolean isShared, Reason reason, ScriptHost host)
|
||||
{
|
||||
this.resource = resource;
|
||||
this.type = type;
|
||||
@@ -120,24 +121,24 @@ public class FileArgument
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return "path: " + resource + " zip: " + zipContainer + " type: " + type.id + " folder: " + isFolder + " shared: " + isShared + " reason: " + reason.toString();
|
||||
return "path: " + resource + " zip: " + zipContainer + " type: " + type.id + " folder: " + isFolder + " shared: " + isShared + " reason: " + reason;
|
||||
}
|
||||
|
||||
public static FileArgument from(final Context context, final List<Value> lv, final boolean isFolder, final Reason reason)
|
||||
public static FileArgument from(Context context, List<Value> lv, boolean isFolder, Reason reason)
|
||||
{
|
||||
if (lv.size() < 2)
|
||||
{
|
||||
throw new InternalExpressionException("File functions require path and type as first two arguments");
|
||||
}
|
||||
final String origtype = lv.get(1).getString().toLowerCase(Locale.ROOT);
|
||||
final boolean shared = origtype.startsWith("shared_");
|
||||
final String typeString = shared ? origtype.substring(7) : origtype; //len(shared_)
|
||||
final Type type = Type.of.get(typeString);
|
||||
final Pair<String, String> resource = recognizeResource(lv.get(0).getString(), isFolder, type);
|
||||
String origtype = lv.get(1).getString().toLowerCase(Locale.ROOT);
|
||||
boolean shared = origtype.startsWith("shared_");
|
||||
String typeString = shared ? origtype.substring(7) : origtype; //len(shared_)
|
||||
Type type = Type.of.get(typeString);
|
||||
if (type == null)
|
||||
{
|
||||
throw new InternalExpressionException("Unsupported file type: " + origtype);
|
||||
}
|
||||
Pair<String, String> resource = recognizeResource(lv.get(0).getString(), isFolder, type);
|
||||
if (type == Type.FOLDER && !isFolder)
|
||||
{
|
||||
throw new InternalExpressionException("Folder types are no supported for this IO function");
|
||||
@@ -146,21 +147,21 @@ public class FileArgument
|
||||
|
||||
}
|
||||
|
||||
public static FileArgument resourceFromPath(final ScriptHost host, final String path, final Reason reason, final boolean shared)
|
||||
public static FileArgument resourceFromPath(ScriptHost host, String path, Reason reason, boolean shared)
|
||||
{
|
||||
final Pair<String, String> resource = recognizeResource(path, false, Type.ANY);
|
||||
Pair<String, String> resource = recognizeResource(path, false, Type.ANY);
|
||||
return new FileArgument(resource.getLeft(), Type.ANY, resource.getRight(), false, shared, reason, host);
|
||||
}
|
||||
|
||||
public static Pair<String, String> recognizeResource(final String origfile, final boolean isFolder, final Type type)
|
||||
public static Pair<String, String> recognizeResource(String origfile, boolean isFolder, Type type)
|
||||
{
|
||||
final String[] pathElements = origfile.split("[/\\\\]+");
|
||||
final List<String> path = new ArrayList<>();
|
||||
String[] pathElements = origfile.split("[/\\\\]+");
|
||||
List<String> path = new ArrayList<>();
|
||||
String zipPath = null;
|
||||
for (int i = 0; i < pathElements.length; i++)
|
||||
{
|
||||
String token = pathElements[i];
|
||||
final boolean isZip = token.endsWith(".zip") && (isFolder || (i < pathElements.length - 1));
|
||||
boolean isZip = token.endsWith(".zip") && (isFolder || (i < pathElements.length - 1));
|
||||
if (zipPath != null && isZip)
|
||||
{
|
||||
throw new InternalExpressionException(token + " indicates zip access in an already zipped location " + zipPath);
|
||||
@@ -196,12 +197,13 @@ public class FileArgument
|
||||
return Pair.of(String.join("/", path), zipPath);
|
||||
}
|
||||
|
||||
private Path resolve(final String suffix)
|
||||
private Path resolve(String suffix)
|
||||
{
|
||||
return host.resolveScriptFile(suffix);
|
||||
}
|
||||
|
||||
private Path toPath(final Module module)
|
||||
@Nullable
|
||||
private Path toPath(@Nullable Module module)
|
||||
{
|
||||
if (!isShared && module == null)
|
||||
{
|
||||
@@ -215,7 +217,7 @@ public class FileArgument
|
||||
{
|
||||
if (zfs == null)
|
||||
{
|
||||
final Map<String, String> env = new HashMap<>();
|
||||
Map<String, String> env = new HashMap<>();
|
||||
if (reason == Reason.CREATE)
|
||||
{
|
||||
env.put("create", "true");
|
||||
@@ -233,7 +235,7 @@ public class FileArgument
|
||||
}
|
||||
zfs = FileSystems.newFileSystem(URI.create("jar:" + zipPath.toUri()), env);
|
||||
}
|
||||
catch (final FileSystemNotFoundException | IOException e)
|
||||
catch (FileSystemNotFoundException | IOException e)
|
||||
{
|
||||
CarpetScriptServer.LOG.warn("Exception when opening zip file", e);
|
||||
throw new ThrowStatement("Unable to open zip file: " + zipContainer, Throwables.IO_EXCEPTION);
|
||||
@@ -243,7 +245,8 @@ public class FileArgument
|
||||
}
|
||||
}
|
||||
|
||||
private Path moduleRootPath(final Module module)
|
||||
@Nullable
|
||||
private Path moduleRootPath(@Nullable Module module)
|
||||
{
|
||||
return !isShared && module == null
|
||||
? null
|
||||
@@ -255,7 +258,7 @@ public class FileArgument
|
||||
return (isShared ? "shared/" : "") + (zipContainer != null ? zipContainer + "/" : "") + resource + type.extension;
|
||||
}
|
||||
|
||||
private String getDescriptor(final Module module, final String res)
|
||||
private String getDescriptor(@Nullable Module module, @Nullable String res)
|
||||
{
|
||||
if (isShared)
|
||||
{
|
||||
@@ -269,13 +272,13 @@ public class FileArgument
|
||||
}
|
||||
|
||||
|
||||
public boolean findPathAndApply(final Module module, final Consumer<Path> action)
|
||||
public boolean findPathAndApply(Module module, Consumer<Path> action)
|
||||
{
|
||||
try
|
||||
{
|
||||
synchronized (writeIOSync)
|
||||
{
|
||||
final Path dataFile = toPath(module);//, resourceName, supportedTypes.get(type), isShared);
|
||||
Path dataFile = toPath(module);//, resourceName, supportedTypes.get(type), isShared);
|
||||
if (dataFile == null)
|
||||
{
|
||||
return false;
|
||||
@@ -291,14 +294,15 @@ public class FileArgument
|
||||
return true;
|
||||
}
|
||||
|
||||
public Stream<Path> listFiles(final Module module)
|
||||
@Nullable
|
||||
public Stream<Path> listFiles(Module module)
|
||||
{
|
||||
final Path dir = toPath(module);
|
||||
Path dir = toPath(module);
|
||||
if (dir == null || !Files.exists(dir))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
final String ext = type.extension;
|
||||
String ext = type.extension;
|
||||
try
|
||||
{
|
||||
return Files.list(dir).filter(path -> (type == Type.FOLDER)
|
||||
@@ -306,16 +310,17 @@ public class FileArgument
|
||||
: (Files.isRegularFile(path) && path.toString().endsWith(ext))
|
||||
);
|
||||
}
|
||||
catch (final IOException ignored)
|
||||
catch (IOException ignored)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public Stream<String> listFolder(final Module module)
|
||||
@Nullable
|
||||
public Stream<String> listFolder(Module module)
|
||||
{
|
||||
Stream<String> strings;
|
||||
try (final Stream<Path> result = listFiles(module))
|
||||
try (Stream<Path> result = listFiles(module))
|
||||
{
|
||||
synchronized (writeIOSync)
|
||||
{
|
||||
@@ -323,12 +328,12 @@ public class FileArgument
|
||||
{
|
||||
return null;
|
||||
}
|
||||
final Path rootPath = moduleRootPath(module);
|
||||
Path rootPath = moduleRootPath(module);
|
||||
if (rootPath == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
final String zipComponent = (zipContainer != null) ? rootPath.relativize(zipPath).toString() : null;
|
||||
String zipComponent = (zipContainer != null) ? rootPath.relativize(zipPath).toString() : null;
|
||||
// need to evaluate the stream before exiting try-with-resources else there'll be no data to stream
|
||||
strings = (zipContainer == null)
|
||||
? result.map(p -> rootPath.relativize(p).toString().replaceAll("[\\\\/]+", "/")).toList().stream()
|
||||
@@ -345,7 +350,7 @@ public class FileArgument
|
||||
: strings.map(FilenameUtils::removeExtension);
|
||||
}
|
||||
|
||||
private void createPaths(final Path file)
|
||||
private void createPaths(Path file)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -357,29 +362,29 @@ public class FileArgument
|
||||
throw new IOException();
|
||||
}
|
||||
}
|
||||
catch (final IOException e)
|
||||
catch (IOException e)
|
||||
{
|
||||
CarpetScriptServer.LOG.warn("IOException when creating paths", e);
|
||||
throw new ThrowStatement("Unable to create paths for " + file, Throwables.IO_EXCEPTION);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean appendToTextFile(final Module module, final List<String> message)
|
||||
public boolean appendToTextFile(Module module, List<String> message)
|
||||
{
|
||||
try
|
||||
{
|
||||
synchronized (writeIOSync)
|
||||
{
|
||||
final Path dataFile = toPath(module);
|
||||
Path dataFile = toPath(module);
|
||||
if (dataFile == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
createPaths(dataFile);
|
||||
final OutputStream out = Files.newOutputStream(dataFile, StandardOpenOption.APPEND, StandardOpenOption.CREATE);
|
||||
try (final BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out, StandardCharsets.UTF_8)))
|
||||
OutputStream out = Files.newOutputStream(dataFile, StandardOpenOption.APPEND, StandardOpenOption.CREATE);
|
||||
try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out, StandardCharsets.UTF_8)))
|
||||
{
|
||||
for (final String line : message)
|
||||
for (String line : message)
|
||||
{
|
||||
writer.append(line);
|
||||
if (type == Type.TEXT)
|
||||
@@ -390,7 +395,7 @@ public class FileArgument
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (final IOException e)
|
||||
catch (IOException e)
|
||||
{
|
||||
CarpetScriptServer.LOG.warn("IOException when appending to text file", e);
|
||||
throw new ThrowStatement("Error when writing to the file: " + e, Throwables.IO_EXCEPTION);
|
||||
@@ -402,13 +407,14 @@ public class FileArgument
|
||||
return true;
|
||||
}
|
||||
|
||||
public Tag getNbtData(final Module module) // aka getData
|
||||
@Nullable
|
||||
public Tag getNbtData(Module module) // aka getData
|
||||
{
|
||||
try
|
||||
{
|
||||
synchronized (writeIOSync)
|
||||
{
|
||||
final Path dataFile = toPath(module);
|
||||
Path dataFile = toPath(module);
|
||||
if (dataFile == null || !Files.exists(dataFile))
|
||||
{
|
||||
return null;
|
||||
@@ -424,29 +430,30 @@ public class FileArgument
|
||||
|
||||
//copied private method from net.minecraft.nbt.NbtIo.read()
|
||||
// to read non-compound tags - these won't be compressed
|
||||
public static Tag readTag(final Path path)
|
||||
@Nullable
|
||||
public static Tag readTag(Path path)
|
||||
{
|
||||
try
|
||||
{
|
||||
return NbtIo.readCompressed(Files.newInputStream(path));
|
||||
}
|
||||
catch (final IOException e)
|
||||
catch (IOException e)
|
||||
{
|
||||
// Copy of NbtIo.read(File) because that's now client-side only
|
||||
if (!Files.exists(path))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
try (final DataInputStream in = new DataInputStream(new BufferedInputStream(Files.newInputStream(path))))
|
||||
try (DataInputStream in = new DataInputStream(new BufferedInputStream(Files.newInputStream(path))))
|
||||
{
|
||||
return NbtIo.read(in);
|
||||
}
|
||||
catch (final IOException ioException)
|
||||
catch (IOException ioException)
|
||||
{
|
||||
// not compressed compound tag neither uncompressed compound tag - trying any type of a tag
|
||||
try (final DataInputStream dataInputStream = new DataInputStream(new BufferedInputStream(Files.newInputStream(path))))
|
||||
try (DataInputStream dataInputStream = new DataInputStream(new BufferedInputStream(Files.newInputStream(path))))
|
||||
{
|
||||
final byte b = dataInputStream.readByte();
|
||||
byte b = dataInputStream.readByte();
|
||||
if (b == 0)
|
||||
{
|
||||
return null;
|
||||
@@ -457,7 +464,7 @@ public class FileArgument
|
||||
return TagTypes.getType(b).load(dataInputStream, 0, NbtAccounter.UNLIMITED);
|
||||
}
|
||||
}
|
||||
catch (final IOException secondIO)
|
||||
catch (IOException secondIO)
|
||||
{
|
||||
CarpetScriptServer.LOG.warn("IOException when trying to read nbt file, something may have gone wrong with the fs", e);
|
||||
CarpetScriptServer.LOG.warn("", ioException);
|
||||
@@ -466,19 +473,19 @@ public class FileArgument
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (final ReportedException e)
|
||||
catch (ReportedException e)
|
||||
{
|
||||
throw new ThrowStatement("Error when reading NBT file " + path.toString(), Throwables.NBT_ERROR);
|
||||
throw new ThrowStatement("Error when reading NBT file " + path, Throwables.NBT_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean saveNbtData(final Module module, final Tag tag) // aka saveData
|
||||
public boolean saveNbtData(Module module, Tag tag) // aka saveData
|
||||
{
|
||||
try
|
||||
{
|
||||
synchronized (writeIOSync)
|
||||
{
|
||||
final Path dataFile = toPath(module);
|
||||
Path dataFile = toPath(module);
|
||||
if (dataFile == null)
|
||||
{
|
||||
return false;
|
||||
@@ -494,9 +501,9 @@ public class FileArgument
|
||||
}
|
||||
|
||||
//copied private method from net.minecraft.nbt.NbtIo.write() and client method safe_write
|
||||
public static boolean writeTagDisk(final Tag tag, Path path, final boolean zipped)
|
||||
public static boolean writeTagDisk(Tag tag, Path path, boolean zipped)
|
||||
{
|
||||
final Path original = path;
|
||||
Path original = path;
|
||||
try
|
||||
{
|
||||
if (!zipped)
|
||||
@@ -511,7 +518,7 @@ public class FileArgument
|
||||
}
|
||||
else
|
||||
{
|
||||
try (final DataOutputStream dataOutputStream = new DataOutputStream(Files.newOutputStream(path)))
|
||||
try (DataOutputStream dataOutputStream = new DataOutputStream(Files.newOutputStream(path)))
|
||||
{
|
||||
dataOutputStream.writeByte(tag.getId());
|
||||
if (tag.getId() != 0)
|
||||
@@ -528,20 +535,20 @@ public class FileArgument
|
||||
}
|
||||
return true;
|
||||
}
|
||||
catch (final IOException e)
|
||||
catch (IOException e)
|
||||
{
|
||||
CarpetScriptServer.LOG.warn("IO Exception when writing nbt file", e);
|
||||
throw new ThrowStatement("Unable to write tag to " + original, Throwables.IO_EXCEPTION);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean dropExistingFile(final Module module)
|
||||
public boolean dropExistingFile(Module module)
|
||||
{
|
||||
try
|
||||
{
|
||||
synchronized (writeIOSync)
|
||||
{
|
||||
final Path dataFile = toPath(module);
|
||||
Path dataFile = toPath(module);
|
||||
if (dataFile == null)
|
||||
{
|
||||
return false;
|
||||
@@ -549,7 +556,7 @@ public class FileArgument
|
||||
return Files.deleteIfExists(dataFile);
|
||||
}
|
||||
}
|
||||
catch (final IOException e)
|
||||
catch (IOException e)
|
||||
{
|
||||
CarpetScriptServer.LOG.warn("IOException when removing file", e);
|
||||
throw new ThrowStatement("Error while removing file: " + getDisplayPath(), Throwables.IO_EXCEPTION);
|
||||
@@ -560,13 +567,14 @@ public class FileArgument
|
||||
}
|
||||
}
|
||||
|
||||
public List<String> listFile(final Module module)
|
||||
@Nullable
|
||||
public List<String> listFile(Module module)
|
||||
{
|
||||
try
|
||||
{
|
||||
synchronized (writeIOSync)
|
||||
{
|
||||
final Path dataFile = toPath(module);
|
||||
Path dataFile = toPath(module);
|
||||
if (dataFile == null)
|
||||
{
|
||||
return null;
|
||||
@@ -584,14 +592,14 @@ public class FileArgument
|
||||
}
|
||||
}
|
||||
|
||||
public static List<String> listFileContent(final Path filePath)
|
||||
public static List<String> listFileContent(Path filePath)
|
||||
{
|
||||
try (final BufferedReader reader = Files.newBufferedReader(filePath, StandardCharsets.UTF_8))
|
||||
try (BufferedReader reader = Files.newBufferedReader(filePath, StandardCharsets.UTF_8))
|
||||
{
|
||||
final List<String> result = new ArrayList<>();
|
||||
List<String> result = new ArrayList<>();
|
||||
for (; ; )
|
||||
{
|
||||
final String line = reader.readLine();
|
||||
String line = reader.readLine();
|
||||
if (line == null)
|
||||
{
|
||||
break;
|
||||
@@ -600,20 +608,21 @@ public class FileArgument
|
||||
}
|
||||
return result;
|
||||
}
|
||||
catch (final IOException e)
|
||||
catch (IOException e)
|
||||
{
|
||||
CarpetScriptServer.LOG.warn("IOException when reading text file", e);
|
||||
throw new ThrowStatement("Failed to read text file " + filePath, Throwables.IO_EXCEPTION);
|
||||
}
|
||||
}
|
||||
|
||||
public JsonElement readJsonFile(final Module module)
|
||||
@Nullable
|
||||
public JsonElement readJsonFile(Module module)
|
||||
{
|
||||
try
|
||||
{
|
||||
synchronized (writeIOSync)
|
||||
{
|
||||
final Path dataFile = toPath(module);
|
||||
Path dataFile = toPath(module);
|
||||
if (dataFile == null || !Files.exists(dataFile))
|
||||
{
|
||||
return null;
|
||||
@@ -627,13 +636,13 @@ public class FileArgument
|
||||
}
|
||||
}
|
||||
|
||||
public static JsonElement readJsonContent(final Path filePath)
|
||||
public static JsonElement readJsonContent(Path filePath)
|
||||
{
|
||||
try (final BufferedReader reader = Files.newBufferedReader(filePath, StandardCharsets.UTF_8))
|
||||
try (BufferedReader reader = Files.newBufferedReader(filePath, StandardCharsets.UTF_8))
|
||||
{
|
||||
return JsonParser.parseReader(reader);
|
||||
}
|
||||
catch (final JsonParseException e)
|
||||
catch (JsonParseException e)
|
||||
{
|
||||
Throwable exc = e;
|
||||
if (e.getCause() != null)
|
||||
@@ -645,7 +654,7 @@ public class FileArgument
|
||||
StringValue.of("path"), StringValue.of(filePath.toString())
|
||||
)), Throwables.JSON_ERROR);
|
||||
}
|
||||
catch (final IOException e)
|
||||
catch (IOException e)
|
||||
{
|
||||
CarpetScriptServer.LOG.warn("IOException when reading JSON file", e);
|
||||
throw new ThrowStatement("Failed to read json file content " + filePath, Throwables.IO_EXCEPTION);
|
||||
|
||||
@@ -10,16 +10,17 @@ import carpet.script.value.ListValue;
|
||||
import carpet.script.value.Value;
|
||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class FunctionArgument extends Argument
|
||||
{
|
||||
public FunctionValue function;
|
||||
public List<Value> args;
|
||||
public final FunctionValue function;
|
||||
public final List<Value> args;
|
||||
|
||||
private FunctionArgument(final FunctionValue function, final int offset, final List<Value> args)
|
||||
private FunctionArgument(@Nullable FunctionValue function, int offset, List<Value> args)
|
||||
{
|
||||
super(offset);
|
||||
this.function = function;
|
||||
@@ -38,12 +39,12 @@ public class FunctionArgument extends Argument
|
||||
* @return argument data
|
||||
*/
|
||||
public static FunctionArgument findIn(
|
||||
final Context c,
|
||||
final Module module,
|
||||
final List<Value> params,
|
||||
final int offset,
|
||||
final boolean allowNone,
|
||||
final boolean checkArgs)
|
||||
Context c,
|
||||
Module module,
|
||||
List<Value> params,
|
||||
int offset,
|
||||
boolean allowNone,
|
||||
boolean checkArgs)
|
||||
{
|
||||
Value functionValue = params.get(offset);
|
||||
if (functionValue.isNull())
|
||||
@@ -56,14 +57,14 @@ public class FunctionArgument extends Argument
|
||||
}
|
||||
if (!(functionValue instanceof FunctionValue))
|
||||
{
|
||||
final String name = functionValue.getString();
|
||||
String name = functionValue.getString();
|
||||
functionValue = c.host.getAssertFunction(module, name);
|
||||
}
|
||||
final FunctionValue fun = (FunctionValue) functionValue;
|
||||
final int argsize = fun.getArguments().size();
|
||||
FunctionValue fun = (FunctionValue) functionValue;
|
||||
int argsize = fun.getArguments().size();
|
||||
if (checkArgs)
|
||||
{
|
||||
final int extraargs = params.size() - argsize - offset - 1;
|
||||
int extraargs = params.size() - argsize - offset - 1;
|
||||
if (extraargs < 0)
|
||||
{
|
||||
throw new InternalExpressionException("Function " + fun.getPrettyString() + " requires at least " + fun.getArguments().size() + " arguments");
|
||||
@@ -73,7 +74,7 @@ public class FunctionArgument extends Argument
|
||||
throw new InternalExpressionException("Function " + fun.getPrettyString() + " requires " + fun.getArguments().size() + " arguments");
|
||||
}
|
||||
}
|
||||
final List<Value> lvargs = new ArrayList<>();
|
||||
List<Value> lvargs = new ArrayList<>();
|
||||
for (int i = offset + 1, mx = params.size(); i < mx; i++)
|
||||
{
|
||||
lvargs.add(params.get(i));
|
||||
@@ -81,27 +82,27 @@ public class FunctionArgument extends Argument
|
||||
return new FunctionArgument(fun, offset + 1 + argsize, lvargs);
|
||||
}
|
||||
|
||||
public static FunctionArgument fromCommandSpec(final ScriptHost host, Value funSpec) throws CommandSyntaxException
|
||||
public static FunctionArgument fromCommandSpec(ScriptHost host, Value funSpec) throws CommandSyntaxException
|
||||
{
|
||||
final FunctionValue function;
|
||||
FunctionValue function;
|
||||
List<Value> args = Collections.emptyList();
|
||||
if (!(funSpec instanceof ListValue))
|
||||
{
|
||||
funSpec = ListValue.of(funSpec);
|
||||
}
|
||||
final List<Value> params = ((ListValue) funSpec).getItems();
|
||||
List<Value> params = ((ListValue) funSpec).getItems();
|
||||
if (params.isEmpty())
|
||||
{
|
||||
throw CommandArgument.error("Function has empty spec");
|
||||
}
|
||||
final Value first = params.get(0);
|
||||
Value first = params.get(0);
|
||||
if (first instanceof FunctionValue)
|
||||
{
|
||||
function = (FunctionValue) first;
|
||||
}
|
||||
else
|
||||
{
|
||||
final String name = first.getString();
|
||||
String name = first.getString();
|
||||
function = host.getFunction(name);
|
||||
if (function == null)
|
||||
{
|
||||
|
||||
@@ -14,15 +14,18 @@ import java.util.NoSuchElementException;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class Vector3Argument extends Argument
|
||||
{
|
||||
public Vec3 vec;
|
||||
public final double yaw;
|
||||
public final double pitch;
|
||||
public boolean fromBlock = false;
|
||||
@Nullable
|
||||
public Entity entity = null;
|
||||
|
||||
private Vector3Argument(final Vec3 v, final int o)
|
||||
private Vector3Argument(Vec3 v, int o)
|
||||
{
|
||||
super(o);
|
||||
this.vec = v;
|
||||
@@ -30,7 +33,7 @@ public class Vector3Argument extends Argument
|
||||
this.pitch = 0.0D;
|
||||
}
|
||||
|
||||
private Vector3Argument(final Vec3 v, final int o, final double y, final double p)
|
||||
private Vector3Argument(Vec3 v, int o, double y, double p)
|
||||
{
|
||||
super(o);
|
||||
this.vec = v;
|
||||
@@ -44,40 +47,40 @@ public class Vector3Argument extends Argument
|
||||
return this;
|
||||
}
|
||||
|
||||
private Vector3Argument withEntity(final Entity e)
|
||||
private Vector3Argument withEntity(Entity e)
|
||||
{
|
||||
entity = e;
|
||||
return this;
|
||||
}
|
||||
|
||||
public static Vector3Argument findIn(final List<Value> params, final int offset)
|
||||
public static Vector3Argument findIn(List<Value> params, int offset)
|
||||
{
|
||||
return findIn(params, offset, false, false);
|
||||
}
|
||||
|
||||
public static Vector3Argument findIn(final List<Value> params, final int offset, final boolean optionalDirection, final boolean optionalEntity)
|
||||
public static Vector3Argument findIn(List<Value> params, int offset, boolean optionalDirection, boolean optionalEntity)
|
||||
{
|
||||
return findIn(params.listIterator(offset), offset, optionalDirection, optionalEntity);
|
||||
}
|
||||
|
||||
public static Vector3Argument findIn(final Iterator<Value> params, final int offset, final boolean optionalDirection, final boolean optionalEntity)
|
||||
public static Vector3Argument findIn(Iterator<Value> params, int offset, boolean optionalDirection, boolean optionalEntity)
|
||||
{
|
||||
try
|
||||
{
|
||||
final Value v1 = params.next();
|
||||
Value v1 = params.next();
|
||||
if (v1 instanceof BlockValue)
|
||||
{
|
||||
return (new Vector3Argument(Vec3.atCenterOf(((BlockValue) v1).getPos()), 1 + offset)).fromBlock();
|
||||
}
|
||||
if (optionalEntity && v1 instanceof EntityValue)
|
||||
{
|
||||
final Entity e = ((EntityValue) v1).getEntity();
|
||||
Entity e = ((EntityValue) v1).getEntity();
|
||||
return new Vector3Argument(e.position(), 1 + offset).withEntity(e);
|
||||
}
|
||||
if (v1 instanceof ListValue)
|
||||
{
|
||||
final List<Value> args = ((ListValue) v1).getItems();
|
||||
final Vec3 pos = new Vec3(
|
||||
List<Value> args = ((ListValue) v1).getItems();
|
||||
Vec3 pos = new Vec3(
|
||||
NumericValue.asNumber(args.get(0)).getDouble(),
|
||||
NumericValue.asNumber(args.get(1)).getDouble(),
|
||||
NumericValue.asNumber(args.get(2)).getDouble());
|
||||
@@ -90,7 +93,7 @@ public class Vector3Argument extends Argument
|
||||
}
|
||||
return new Vector3Argument(pos, offset + 1, yaw, pitch);
|
||||
}
|
||||
final Vec3 pos = new Vec3(
|
||||
Vec3 pos = new Vec3(
|
||||
NumericValue.asNumber(v1).getDouble(),
|
||||
NumericValue.asNumber(params.next()).getDouble(),
|
||||
NumericValue.asNumber(params.next()).getDouble());
|
||||
@@ -106,7 +109,7 @@ public class Vector3Argument extends Argument
|
||||
|
||||
return new Vector3Argument(pos, offset + eatenLength, yaw, pitch);
|
||||
}
|
||||
catch (final IndexOutOfBoundsException | NoSuchElementException e)
|
||||
catch (IndexOutOfBoundsException | NoSuchElementException e)
|
||||
{
|
||||
throw new InternalExpressionException("Position argument should be defined either by three coordinates (a triple or by three arguments), or a positioned block value");
|
||||
}
|
||||
|
||||
@@ -107,11 +107,13 @@ import net.minecraft.world.level.biome.Biome;
|
||||
import net.minecraft.world.phys.Vec2;
|
||||
import net.minecraft.world.scores.Scoreboard;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import static net.minecraft.commands.Commands.argument;
|
||||
|
||||
public abstract class CommandArgument
|
||||
{
|
||||
public static CommandSyntaxException error(final String text)
|
||||
public static CommandSyntaxException error(String text)
|
||||
{
|
||||
return new SimpleCommandExceptionType(Component.literal(text)).create();
|
||||
}
|
||||
@@ -133,7 +135,7 @@ public abstract class CommandArgument
|
||||
new VanillaUnconfigurableArgument("block", BlockStateArgument::block,
|
||||
(c, p) -> {
|
||||
BlockInput result = BlockStateArgument.getBlock(c, p);
|
||||
return new BlockValue(result.getState(), c.getSource().getLevel(), null, Vanilla.BlockInput_getTag(result));
|
||||
return new BlockValue(result.getState(), c.getSource().getLevel(), Vanilla.BlockInput_getTag(result));
|
||||
},
|
||||
param -> (ctx, builder) -> ctx.getArgument(param, BlockStateArgument.class).listSuggestions(ctx, builder)
|
||||
),
|
||||
@@ -219,7 +221,7 @@ public abstract class CommandArgument
|
||||
(c, p) -> ValueConversions.of(ResourceLocationArgument.getId(c, p)), BossBarCommands.SUGGEST_BOSS_BAR
|
||||
),
|
||||
|
||||
new VanillaUnconfigurableArgument("biome", (c) -> ResourceOrTagArgument.resourceOrTag(c, Registries.BIOME),
|
||||
new VanillaUnconfigurableArgument("biome", c -> ResourceOrTagArgument.resourceOrTag(c, Registries.BIOME),
|
||||
(c, p) -> {
|
||||
ResourceOrTagArgument.Result<Biome> result = ResourceOrTagArgument.getResourceOrTag(c, "biome", Registries.BIOME);
|
||||
Either<Holder.Reference<Biome>, HolderSet.Named<Biome>> res = result.unwrap();
|
||||
@@ -270,7 +272,7 @@ public abstract class CommandArgument
|
||||
new VanillaUnconfigurableArgument("uuid", UuidArgument::uuid,
|
||||
(c, p) -> StringValue.of(UuidArgument.getUuid(c, p).toString()), false
|
||||
),
|
||||
new VanillaUnconfigurableArgument("surfacelocation", () -> Vec2Argument.vec2(), // vec2
|
||||
new VanillaUnconfigurableArgument("surfacelocation", Vec2Argument::vec2,
|
||||
(c, p) -> {
|
||||
Vec2 res = Vec2Argument.getVec2(c, p);
|
||||
return ListValue.of(NumericValue.of(res.x), NumericValue.of(res.y));
|
||||
@@ -284,13 +286,13 @@ public abstract class CommandArgument
|
||||
|
||||
public static final CommandArgument DEFAULT = baseTypes.get(0);
|
||||
|
||||
public static CommandArgument getTypeForArgument(final String argument, final CarpetScriptHost host)
|
||||
public static CommandArgument getTypeForArgument(String argument, CarpetScriptHost host)
|
||||
{
|
||||
final String[] components = argument.split("_");
|
||||
String[] components = argument.split("_");
|
||||
CommandArgument arg;
|
||||
for (int i = 0; i < components.length; i++)
|
||||
{
|
||||
final String candidate = String.join("_", Arrays.asList(components).subList(i, components.length));
|
||||
String candidate = String.join("_", Arrays.asList(components).subList(i, components.length));
|
||||
arg = host.appArgTypes.get(candidate);
|
||||
if (arg != null)
|
||||
{
|
||||
@@ -305,9 +307,9 @@ public abstract class CommandArgument
|
||||
return DEFAULT;
|
||||
}
|
||||
|
||||
public static RequiredArgumentBuilder<CommandSourceStack, ?> argumentNode(final String param, final CarpetScriptHost host) throws CommandSyntaxException
|
||||
public static RequiredArgumentBuilder<CommandSourceStack, ?> argumentNode(String param, CarpetScriptHost host) throws CommandSyntaxException
|
||||
{
|
||||
final CommandArgument arg = getTypeForArgument(param, host);
|
||||
CommandArgument arg = getTypeForArgument(param, host);
|
||||
if (arg.suggestionProvider != null)
|
||||
{
|
||||
return argument(param, arg.getArgumentType(host)).suggests(arg.suggestionProvider.apply(param));
|
||||
@@ -316,15 +318,16 @@ public abstract class CommandArgument
|
||||
{
|
||||
return argument(param, arg.getArgumentType(host));
|
||||
}
|
||||
final String hostName = host.getName();
|
||||
final CarpetScriptServer scriptServer = host.scriptServer();
|
||||
String hostName = host.getName();
|
||||
CarpetScriptServer scriptServer = host.scriptServer();
|
||||
return argument(param, arg.getArgumentType(host)).suggests((ctx, b) -> {
|
||||
final CarpetScriptHost cHost = scriptServer.modules.get(hostName).retrieveOwnForExecution(ctx.getSource());
|
||||
CarpetScriptHost cHost = scriptServer.modules.get(hostName).retrieveOwnForExecution(ctx.getSource());
|
||||
return arg.suggest(ctx, b, cHost);
|
||||
});
|
||||
}
|
||||
|
||||
protected String suffix;
|
||||
@Nullable
|
||||
protected Collection<String> examples;
|
||||
protected boolean needsMatching;
|
||||
protected boolean caseSensitive = true;
|
||||
@@ -333,9 +336,9 @@ public abstract class CommandArgument
|
||||
|
||||
|
||||
protected CommandArgument(
|
||||
final String suffix,
|
||||
final Collection<String> examples,
|
||||
final boolean suggestFromExamples)
|
||||
String suffix,
|
||||
@Nullable Collection<String> examples,
|
||||
boolean suggestFromExamples)
|
||||
{
|
||||
this.suffix = suffix;
|
||||
this.examples = examples;
|
||||
@@ -345,7 +348,7 @@ public abstract class CommandArgument
|
||||
protected abstract ArgumentType<?> getArgumentType(CarpetScriptHost host) throws CommandSyntaxException;
|
||||
|
||||
|
||||
public static Value getValue(final CommandContext<CommandSourceStack> context, final String param, final CarpetScriptHost host) throws CommandSyntaxException
|
||||
public static Value getValue(CommandContext<CommandSourceStack> context, String param, CarpetScriptHost host) throws CommandSyntaxException
|
||||
{
|
||||
return getTypeForArgument(param, host).getValueFromContext(context, param);
|
||||
}
|
||||
@@ -357,24 +360,24 @@ public abstract class CommandArgument
|
||||
return suffix;
|
||||
}
|
||||
|
||||
public static CommandArgument buildFromConfig(final String suffix, final Map<String, Value> config, final CarpetScriptHost host) throws CommandSyntaxException
|
||||
public static CommandArgument buildFromConfig(String suffix, Map<String, Value> config, CarpetScriptHost host) throws CommandSyntaxException
|
||||
{
|
||||
if (!config.containsKey("type"))
|
||||
{
|
||||
throw CommandArgument.error("Custom type " + suffix + " should at least specify the type");
|
||||
}
|
||||
final String baseType = config.get("type").getString();
|
||||
String baseType = config.get("type").getString();
|
||||
if (!builtIns.containsKey(baseType))
|
||||
{
|
||||
throw CommandArgument.error("Unknown base type " + baseType + " for custom type " + suffix);
|
||||
}
|
||||
final CommandArgument variant = builtIns.get(baseType).factory(host.scriptServer().server).get();
|
||||
CommandArgument variant = builtIns.get(baseType).factory(host.scriptServer().server).get();
|
||||
variant.suffix = suffix;
|
||||
variant.configure(config, host);
|
||||
return variant;
|
||||
}
|
||||
|
||||
protected void configure(final Map<String, Value> config, final CarpetScriptHost host) throws CommandSyntaxException
|
||||
protected void configure(Map<String, Value> config, CarpetScriptHost host) throws CommandSyntaxException
|
||||
{
|
||||
caseSensitive = config.getOrDefault("case_sensitive", Value.TRUE).getBoolean();
|
||||
if (config.containsKey("suggester"))
|
||||
@@ -387,7 +390,7 @@ public abstract class CommandArgument
|
||||
{
|
||||
throw error("Attempted to provide 'suggest' list while 'suggester' is present" + " for custom type " + suffix);
|
||||
}
|
||||
final Value suggestionValue = config.get("suggest");
|
||||
Value suggestionValue = config.get("suggest");
|
||||
if (!(suggestionValue instanceof ListValue))
|
||||
{
|
||||
throw error("Argument suggestions needs to be a list" + " for custom type " + suffix);
|
||||
@@ -403,9 +406,9 @@ public abstract class CommandArgument
|
||||
}
|
||||
|
||||
public CompletableFuture<Suggestions> suggest(
|
||||
final CommandContext<CommandSourceStack> context,
|
||||
final SuggestionsBuilder suggestionsBuilder,
|
||||
final CarpetScriptHost host
|
||||
CommandContext<CommandSourceStack> context,
|
||||
SuggestionsBuilder suggestionsBuilder,
|
||||
CarpetScriptHost host
|
||||
) throws CommandSyntaxException
|
||||
{
|
||||
String prefix = suggestionsBuilder.getRemaining();
|
||||
@@ -417,41 +420,41 @@ public abstract class CommandArgument
|
||||
return suggestionsBuilder.buildFuture();
|
||||
}
|
||||
|
||||
protected List<String> suggestFor(final CommandContext<CommandSourceStack> context, final String prefix, final CarpetScriptHost host) throws CommandSyntaxException
|
||||
protected List<String> suggestFor(CommandContext<CommandSourceStack> context, String prefix, CarpetScriptHost host) throws CommandSyntaxException
|
||||
{
|
||||
return getOptions(context, host).stream().filter(s -> optionMatchesPrefix(prefix, s)).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
protected Collection<String> getOptions(final CommandContext<CommandSourceStack> context, final CarpetScriptHost host) throws CommandSyntaxException
|
||||
protected Collection<String> getOptions(CommandContext<CommandSourceStack> context, CarpetScriptHost host) throws CommandSyntaxException
|
||||
{
|
||||
if (customSuggester != null)
|
||||
{
|
||||
final Runnable currentSection = Carpet.startProfilerSection("Scarpet command");
|
||||
final Map<Value, Value> params = new HashMap<>();
|
||||
for (final ParsedCommandNode<CommandSourceStack> pnode : context.getNodes())
|
||||
Runnable currentSection = Carpet.startProfilerSection("Scarpet command");
|
||||
Map<Value, Value> params = new HashMap<>();
|
||||
for (ParsedCommandNode<CommandSourceStack> pnode : context.getNodes())
|
||||
{
|
||||
final CommandNode<CommandSourceStack> node = pnode.getNode();
|
||||
CommandNode<CommandSourceStack> node = pnode.getNode();
|
||||
if (node instanceof ArgumentCommandNode)
|
||||
{
|
||||
params.put(StringValue.of(node.getName()), CommandArgument.getValue(context, node.getName(), host));
|
||||
}
|
||||
}
|
||||
final List<Value> args = new ArrayList<>(customSuggester.args.size() + 1);
|
||||
List<Value> args = new ArrayList<>(customSuggester.args.size() + 1);
|
||||
args.add(MapValue.wrap(params));
|
||||
args.addAll(customSuggester.args);
|
||||
final Value response = host.handleCommand(context.getSource(), customSuggester.function, args);
|
||||
Value response = host.handleCommand(context.getSource(), customSuggester.function, args);
|
||||
if (!(response instanceof ListValue))
|
||||
{
|
||||
throw error("Custom suggester should return a list of options" + " for custom type " + suffix);
|
||||
}
|
||||
final Collection<String> res = ((ListValue) response).getItems().stream().map(Value::getString).collect(Collectors.toList());
|
||||
Collection<String> res = ((ListValue) response).getItems().stream().map(Value::getString).collect(Collectors.toList());
|
||||
currentSection.run();
|
||||
return res;
|
||||
}
|
||||
return needsMatching ? examples : Collections.singletonList("... " + getTypeSuffix());
|
||||
}
|
||||
|
||||
protected boolean optionMatchesPrefix(final String prefix, String option)
|
||||
protected boolean optionMatchesPrefix(String prefix, String option)
|
||||
{
|
||||
if (!caseSensitive)
|
||||
{
|
||||
@@ -480,13 +483,13 @@ public abstract class CommandArgument
|
||||
}
|
||||
|
||||
@Override
|
||||
public ArgumentType<?> getArgumentType(final CarpetScriptHost host)
|
||||
public ArgumentType<?> getArgumentType(CarpetScriptHost host)
|
||||
{
|
||||
return StringArgumentType.string();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value getValueFromContext(final CommandContext<CommandSourceStack> context, final String param) throws CommandSyntaxException
|
||||
public Value getValueFromContext(CommandContext<CommandSourceStack> context, String param) throws CommandSyntaxException
|
||||
{
|
||||
String choseValue = StringArgumentType.getString(context, param);
|
||||
if (!caseSensitive)
|
||||
@@ -501,12 +504,12 @@ public abstract class CommandArgument
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure(final Map<String, Value> config, final CarpetScriptHost host) throws CommandSyntaxException
|
||||
protected void configure(Map<String, Value> config, CarpetScriptHost host) throws CommandSyntaxException
|
||||
{
|
||||
super.configure(config, host);
|
||||
if (config.containsKey("options"))
|
||||
{
|
||||
final Value optionsValue = config.get("options");
|
||||
Value optionsValue = config.get("options");
|
||||
if (!(optionsValue instanceof ListValue))
|
||||
{
|
||||
throw error("Custom string type requires options passed as a list" + " for custom type " + suffix);
|
||||
@@ -518,13 +521,13 @@ public abstract class CommandArgument
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Collection<String> getOptions(final CommandContext<CommandSourceStack> context, final CarpetScriptHost host) throws CommandSyntaxException
|
||||
protected Collection<String> getOptions(CommandContext<CommandSourceStack> context, CarpetScriptHost host) throws CommandSyntaxException
|
||||
{
|
||||
return validOptions.isEmpty() ? super.getOptions(context, host) : validOptions;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Supplier<CommandArgument> factory(final MinecraftServer server)
|
||||
protected Supplier<CommandArgument> factory(MinecraftServer server)
|
||||
{
|
||||
return StringArgument::new;
|
||||
}
|
||||
@@ -540,13 +543,13 @@ public abstract class CommandArgument
|
||||
}
|
||||
|
||||
@Override
|
||||
public ArgumentType<?> getArgumentType(final CarpetScriptHost host)
|
||||
public ArgumentType<?> getArgumentType(CarpetScriptHost host)
|
||||
{
|
||||
return StringArgumentType.word();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Supplier<CommandArgument> factory(final MinecraftServer server)
|
||||
protected Supplier<CommandArgument> factory(MinecraftServer server)
|
||||
{
|
||||
return WordArgument::new;
|
||||
}
|
||||
@@ -562,13 +565,13 @@ public abstract class CommandArgument
|
||||
}
|
||||
|
||||
@Override
|
||||
public ArgumentType<?> getArgumentType(final CarpetScriptHost host)
|
||||
public ArgumentType<?> getArgumentType(CarpetScriptHost host)
|
||||
{
|
||||
return StringArgumentType.greedyString();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Supplier<CommandArgument> factory(final MinecraftServer server)
|
||||
protected Supplier<CommandArgument> factory(MinecraftServer server)
|
||||
{
|
||||
return GreedyStringArgument::new;
|
||||
}
|
||||
@@ -584,29 +587,29 @@ public abstract class CommandArgument
|
||||
}
|
||||
|
||||
@Override
|
||||
public ArgumentType<?> getArgumentType(final CarpetScriptHost host)
|
||||
public ArgumentType<?> getArgumentType(CarpetScriptHost host)
|
||||
{
|
||||
return net.minecraft.commands.arguments.coordinates.BlockPosArgument.blockPos();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value getValueFromContext(final CommandContext<CommandSourceStack> context, final String param) throws CommandSyntaxException
|
||||
public Value getValueFromContext(CommandContext<CommandSourceStack> context, String param) throws CommandSyntaxException
|
||||
{
|
||||
final BlockPos pos = mustBeLoaded
|
||||
BlockPos pos = mustBeLoaded
|
||||
? net.minecraft.commands.arguments.coordinates.BlockPosArgument.getLoadedBlockPos(context, param)
|
||||
: net.minecraft.commands.arguments.coordinates.BlockPosArgument.getSpawnablePos(context, param);
|
||||
return ValueConversions.of(pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure(final Map<String, Value> config, final CarpetScriptHost host) throws CommandSyntaxException
|
||||
protected void configure(Map<String, Value> config, CarpetScriptHost host) throws CommandSyntaxException
|
||||
{
|
||||
super.configure(config, host);
|
||||
mustBeLoaded = config.getOrDefault("loaded", Value.FALSE).getBoolean();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Supplier<CommandArgument> factory(final MinecraftServer server)
|
||||
protected Supplier<CommandArgument> factory(MinecraftServer server)
|
||||
{
|
||||
return BlockPosArgument::new;
|
||||
}
|
||||
@@ -623,26 +626,26 @@ public abstract class CommandArgument
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ArgumentType<?> getArgumentType(final CarpetScriptHost host)
|
||||
protected ArgumentType<?> getArgumentType(CarpetScriptHost host)
|
||||
{
|
||||
return Vec3Argument.vec3(blockCentered);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Value getValueFromContext(final CommandContext<CommandSourceStack> context, final String param) throws CommandSyntaxException
|
||||
protected Value getValueFromContext(CommandContext<CommandSourceStack> context, String param)
|
||||
{
|
||||
return ValueConversions.of(Vec3Argument.getVec3(context, param));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure(final Map<String, Value> config, final CarpetScriptHost host) throws CommandSyntaxException
|
||||
protected void configure(Map<String, Value> config, CarpetScriptHost host) throws CommandSyntaxException
|
||||
{
|
||||
super.configure(config, host);
|
||||
blockCentered = config.getOrDefault("block_centered", Value.TRUE).getBoolean();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Supplier<CommandArgument> factory(final MinecraftServer server)
|
||||
protected Supplier<CommandArgument> factory(MinecraftServer server)
|
||||
{
|
||||
return LocationArgument::new;
|
||||
}
|
||||
@@ -661,7 +664,7 @@ public abstract class CommandArgument
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ArgumentType<?> getArgumentType(final CarpetScriptHost host)
|
||||
protected ArgumentType<?> getArgumentType(CarpetScriptHost host)
|
||||
{
|
||||
if (onlyFans)
|
||||
{
|
||||
@@ -671,14 +674,14 @@ public abstract class CommandArgument
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Value getValueFromContext(final CommandContext<CommandSourceStack> context, final String param) throws CommandSyntaxException
|
||||
protected Value getValueFromContext(CommandContext<CommandSourceStack> context, String param) throws CommandSyntaxException
|
||||
{
|
||||
final Collection<? extends Entity> founds = net.minecraft.commands.arguments.EntityArgument.getOptionalEntities(context, param);
|
||||
Collection<? extends Entity> founds = net.minecraft.commands.arguments.EntityArgument.getOptionalEntities(context, param);
|
||||
if (!single)
|
||||
{
|
||||
return ListValue.wrap(founds.stream().map(EntityValue::new));
|
||||
}
|
||||
if (founds.size() == 0)
|
||||
if (founds.isEmpty())
|
||||
{
|
||||
return Value.NULL;
|
||||
}
|
||||
@@ -690,7 +693,7 @@ public abstract class CommandArgument
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure(final Map<String, Value> config, final CarpetScriptHost host) throws CommandSyntaxException
|
||||
protected void configure(Map<String, Value> config, CarpetScriptHost host) throws CommandSyntaxException
|
||||
{
|
||||
super.configure(config, host);
|
||||
onlyFans = config.getOrDefault("players", Value.FALSE).getBoolean();
|
||||
@@ -698,7 +701,7 @@ public abstract class CommandArgument
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Supplier<CommandArgument> factory(final MinecraftServer server)
|
||||
protected Supplier<CommandArgument> factory(MinecraftServer server)
|
||||
{
|
||||
return EntityArgument::new;
|
||||
}
|
||||
@@ -715,20 +718,20 @@ public abstract class CommandArgument
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ArgumentType<?> getArgumentType(final CarpetScriptHost host)
|
||||
protected ArgumentType<?> getArgumentType(CarpetScriptHost host)
|
||||
{
|
||||
return GameProfileArgument.gameProfile();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Value getValueFromContext(final CommandContext<CommandSourceStack> context, final String param) throws CommandSyntaxException
|
||||
protected Value getValueFromContext(CommandContext<CommandSourceStack> context, String param) throws CommandSyntaxException
|
||||
{
|
||||
final Collection<GameProfile> profiles = GameProfileArgument.getGameProfiles(context, param);
|
||||
Collection<GameProfile> profiles = GameProfileArgument.getGameProfiles(context, param);
|
||||
if (!single)
|
||||
{
|
||||
return ListValue.wrap(profiles.stream().map(p -> StringValue.of(p.getName())));
|
||||
}
|
||||
final int size = profiles.size();
|
||||
int size = profiles.size();
|
||||
if (size == 0)
|
||||
{
|
||||
return Value.NULL;
|
||||
@@ -741,14 +744,14 @@ public abstract class CommandArgument
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure(final Map<String, Value> config, final CarpetScriptHost host) throws CommandSyntaxException
|
||||
protected void configure(Map<String, Value> config, CarpetScriptHost host) throws CommandSyntaxException
|
||||
{
|
||||
super.configure(config, host);
|
||||
single = config.getOrDefault("single", Value.FALSE).getBoolean();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Supplier<CommandArgument> factory(final MinecraftServer server)
|
||||
protected Supplier<CommandArgument> factory(MinecraftServer server)
|
||||
{
|
||||
return PlayerProfileArgument::new;
|
||||
}
|
||||
@@ -766,20 +769,20 @@ public abstract class CommandArgument
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ArgumentType<?> getArgumentType(final CarpetScriptHost host)
|
||||
protected ArgumentType<?> getArgumentType(CarpetScriptHost host)
|
||||
{
|
||||
return single ? ScoreHolderArgument.scoreHolder() : ScoreHolderArgument.scoreHolders();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Value getValueFromContext(final CommandContext<CommandSourceStack> context, final String param) throws CommandSyntaxException
|
||||
protected Value getValueFromContext(CommandContext<CommandSourceStack> context, String param) throws CommandSyntaxException
|
||||
{
|
||||
final Collection<String> holders = ScoreHolderArgument.getNames(context, param);
|
||||
Collection<String> holders = ScoreHolderArgument.getNames(context, param);
|
||||
if (!single)
|
||||
{
|
||||
return ListValue.wrap(holders.stream().map(StringValue::of));
|
||||
}
|
||||
final int size = holders.size();
|
||||
int size = holders.size();
|
||||
if (size == 0)
|
||||
{
|
||||
return Value.NULL;
|
||||
@@ -792,14 +795,14 @@ public abstract class CommandArgument
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure(final Map<String, Value> config, final CarpetScriptHost host) throws CommandSyntaxException
|
||||
protected void configure(Map<String, Value> config, CarpetScriptHost host) throws CommandSyntaxException
|
||||
{
|
||||
super.configure(config, host);
|
||||
single = config.getOrDefault("single", Value.FALSE).getBoolean();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Supplier<CommandArgument> factory(final MinecraftServer server)
|
||||
protected Supplier<CommandArgument> factory(MinecraftServer server)
|
||||
{
|
||||
return PlayerProfileArgument::new;
|
||||
}
|
||||
@@ -816,13 +819,13 @@ public abstract class CommandArgument
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ArgumentType<?> getArgumentType(final CarpetScriptHost host)
|
||||
protected ArgumentType<?> getArgumentType(CarpetScriptHost host)
|
||||
{
|
||||
return mapRequired ? CompoundTagArgument.compoundTag() : NbtTagArgument.nbtTag();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Value getValueFromContext(final CommandContext<CommandSourceStack> context, final String param) throws CommandSyntaxException
|
||||
protected Value getValueFromContext(CommandContext<CommandSourceStack> context, String param)
|
||||
{
|
||||
return mapRequired
|
||||
? new NBTSerializableValue(CompoundTagArgument.getCompoundTag(context, param))
|
||||
@@ -830,14 +833,14 @@ public abstract class CommandArgument
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure(final Map<String, Value> config, final CarpetScriptHost host) throws CommandSyntaxException
|
||||
protected void configure(Map<String, Value> config, CarpetScriptHost host) throws CommandSyntaxException
|
||||
{
|
||||
super.configure(config, host);
|
||||
mapRequired = !config.getOrDefault("allow_element", Value.FALSE).getBoolean();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Supplier<CommandArgument> factory(final MinecraftServer server)
|
||||
protected Supplier<CommandArgument> factory(MinecraftServer server)
|
||||
{
|
||||
return TagArgument::new;
|
||||
}
|
||||
@@ -853,15 +856,15 @@ public abstract class CommandArgument
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ArgumentType<?> getArgumentType(final CarpetScriptHost host)
|
||||
protected ArgumentType<?> getArgumentType(CarpetScriptHost host)
|
||||
{
|
||||
return ResourceLocationArgument.id();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Value getValueFromContext(final CommandContext<CommandSourceStack> context, final String param) throws CommandSyntaxException
|
||||
protected Value getValueFromContext(CommandContext<CommandSourceStack> context, String param) throws CommandSyntaxException
|
||||
{
|
||||
final ResourceLocation choseValue = ResourceLocationArgument.getId(context, param);
|
||||
ResourceLocation choseValue = ResourceLocationArgument.getId(context, param);
|
||||
if (!validOptions.isEmpty() && !validOptions.contains(choseValue))
|
||||
{
|
||||
throw new SimpleCommandExceptionType(Component.literal("Incorrect value for " + param + ": " + choseValue + " for custom type " + suffix)).create();
|
||||
@@ -870,18 +873,18 @@ public abstract class CommandArgument
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Supplier<CommandArgument> factory(final MinecraftServer server)
|
||||
protected Supplier<CommandArgument> factory(MinecraftServer server)
|
||||
{
|
||||
return CustomIdentifierArgument::new;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure(final Map<String, Value> config, final CarpetScriptHost host) throws CommandSyntaxException
|
||||
protected void configure(Map<String, Value> config, CarpetScriptHost host) throws CommandSyntaxException
|
||||
{
|
||||
super.configure(config, host);
|
||||
if (config.containsKey("options"))
|
||||
{
|
||||
final Value optionsValue = config.get("options");
|
||||
Value optionsValue = config.get("options");
|
||||
if (!(optionsValue instanceof ListValue))
|
||||
{
|
||||
throw error("Custom sting type requires options passed as a list" + " for custom type " + suffix);
|
||||
@@ -902,7 +905,7 @@ public abstract class CommandArgument
|
||||
}
|
||||
|
||||
@Override
|
||||
public ArgumentType<?> getArgumentType(final CarpetScriptHost host)
|
||||
public ArgumentType<?> getArgumentType(CarpetScriptHost host)
|
||||
{
|
||||
if (min != null)
|
||||
{
|
||||
@@ -916,13 +919,13 @@ public abstract class CommandArgument
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value getValueFromContext(final CommandContext<CommandSourceStack> context, final String param) throws CommandSyntaxException
|
||||
public Value getValueFromContext(CommandContext<CommandSourceStack> context, String param)
|
||||
{
|
||||
return new NumericValue(DoubleArgumentType.getDouble(context, param));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure(final Map<String, Value> config, final CarpetScriptHost host) throws CommandSyntaxException
|
||||
protected void configure(Map<String, Value> config, CarpetScriptHost host) throws CommandSyntaxException
|
||||
{
|
||||
super.configure(config, host);
|
||||
if (config.containsKey("min"))
|
||||
@@ -940,7 +943,7 @@ public abstract class CommandArgument
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Supplier<CommandArgument> factory(final MinecraftServer server)
|
||||
protected Supplier<CommandArgument> factory(MinecraftServer server)
|
||||
{
|
||||
return FloatArgument::new;
|
||||
}
|
||||
@@ -957,7 +960,7 @@ public abstract class CommandArgument
|
||||
}
|
||||
|
||||
@Override
|
||||
public ArgumentType<?> getArgumentType(final CarpetScriptHost host)
|
||||
public ArgumentType<?> getArgumentType(CarpetScriptHost host)
|
||||
{
|
||||
if (min != null)
|
||||
{
|
||||
@@ -971,13 +974,13 @@ public abstract class CommandArgument
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value getValueFromContext(final CommandContext<CommandSourceStack> context, final String param) throws CommandSyntaxException
|
||||
public Value getValueFromContext(CommandContext<CommandSourceStack> context, String param)
|
||||
{
|
||||
return new NumericValue(LongArgumentType.getLong(context, param));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure(final Map<String, Value> config, final CarpetScriptHost host) throws CommandSyntaxException
|
||||
protected void configure(Map<String, Value> config, CarpetScriptHost host) throws CommandSyntaxException
|
||||
{
|
||||
super.configure(config, host);
|
||||
if (config.containsKey("min"))
|
||||
@@ -995,7 +998,7 @@ public abstract class CommandArgument
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Supplier<CommandArgument> factory(final MinecraftServer server)
|
||||
protected Supplier<CommandArgument> factory(MinecraftServer server)
|
||||
{
|
||||
return IntArgument::new;
|
||||
}
|
||||
@@ -1011,7 +1014,7 @@ public abstract class CommandArgument
|
||||
private static final Map<String, ContainerIds> RESTRICTED_CONTAINERS = new HashMap<>()
|
||||
{{
|
||||
int i;
|
||||
for (final String source : Arrays.asList("player", "enderchest", "equipment", "armor", "weapon", "container", "villager", "horse"))
|
||||
for (String source : Arrays.asList("player", "enderchest", "equipment", "armor", "weapon", "container", "villager", "horse"))
|
||||
{
|
||||
put(source, new ContainerIds(new IntOpenHashSet(), new HashSet<>()));
|
||||
}
|
||||
@@ -1031,13 +1034,13 @@ public abstract class CommandArgument
|
||||
{
|
||||
get("player").commandIds().add("inventory." + i);
|
||||
}
|
||||
for (final String place : Arrays.asList("weapon", "weapon.mainhand", "weapon.offhand"))
|
||||
for (String place : Arrays.asList("weapon", "weapon.mainhand", "weapon.offhand"))
|
||||
{
|
||||
get("player").commandIds().add(place);
|
||||
get("equipment").commandIds().add(place);
|
||||
get("weapon").commandIds().add(place);
|
||||
}
|
||||
for (final String place : Arrays.asList("armor.feet", "armor.legs", "armor.chest", "armor.head"))
|
||||
for (String place : Arrays.asList("armor.feet", "armor.legs", "armor.chest", "armor.head"))
|
||||
{
|
||||
get("player").commandIds().add(place);
|
||||
get("equipment").commandIds().add(place);
|
||||
@@ -1106,15 +1109,15 @@ public abstract class CommandArgument
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ArgumentType<?> getArgumentType(final CarpetScriptHost host) throws CommandSyntaxException
|
||||
protected ArgumentType<?> getArgumentType(CarpetScriptHost host)
|
||||
{
|
||||
return net.minecraft.commands.arguments.SlotArgument.slot();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Value getValueFromContext(final CommandContext<CommandSourceStack> context, final String param) throws CommandSyntaxException
|
||||
protected Value getValueFromContext(CommandContext<CommandSourceStack> context, String param) throws CommandSyntaxException
|
||||
{
|
||||
final int slot = net.minecraft.commands.arguments.SlotArgument.getSlot(context, param);
|
||||
int slot = net.minecraft.commands.arguments.SlotArgument.getSlot(context, param);
|
||||
if (restrict != null && !RESTRICTED_CONTAINERS.get(restrict).numericalIds().contains(slot))
|
||||
{
|
||||
throw new SimpleCommandExceptionType(Component.literal("Incorrect slot restricted to " + restrict + " for custom type " + suffix)).create();
|
||||
@@ -1123,7 +1126,7 @@ public abstract class CommandArgument
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure(final Map<String, Value> config, final CarpetScriptHost host) throws CommandSyntaxException
|
||||
protected void configure(Map<String, Value> config, CarpetScriptHost host) throws CommandSyntaxException
|
||||
{
|
||||
super.configure(config, host);
|
||||
if (config.containsKey("restrict"))
|
||||
@@ -1138,13 +1141,13 @@ public abstract class CommandArgument
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Collection<String> getOptions(final CommandContext<CommandSourceStack> context, final CarpetScriptHost host) throws CommandSyntaxException
|
||||
protected Collection<String> getOptions(CommandContext<CommandSourceStack> context, CarpetScriptHost host) throws CommandSyntaxException
|
||||
{
|
||||
return restrict == null ? super.getOptions(context, host) : RESTRICTED_CONTAINERS.get(restrict).commandIds();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Supplier<CommandArgument> factory(final MinecraftServer server)
|
||||
protected Supplier<CommandArgument> factory(MinecraftServer server)
|
||||
{
|
||||
return SlotArgument::new;
|
||||
}
|
||||
@@ -1176,10 +1179,10 @@ public abstract class CommandArgument
|
||||
private final boolean providesExamples;
|
||||
|
||||
public VanillaUnconfigurableArgument(
|
||||
final String suffix,
|
||||
final ArgumentProvider argumentTypeSupplier,
|
||||
final ValueExtractor valueExtractor,
|
||||
final boolean suggestFromExamples
|
||||
String suffix,
|
||||
ArgumentProvider argumentTypeSupplier,
|
||||
ValueExtractor valueExtractor,
|
||||
boolean suggestFromExamples
|
||||
)
|
||||
{
|
||||
super(suffix, null, suggestFromExamples);
|
||||
@@ -1187,7 +1190,7 @@ public abstract class CommandArgument
|
||||
{
|
||||
this.examples = argumentTypeSupplier.get().getExamples();
|
||||
}
|
||||
catch (final CommandSyntaxException e)
|
||||
catch (CommandSyntaxException e)
|
||||
{
|
||||
this.examples = Collections.emptyList();
|
||||
}
|
||||
@@ -1198,10 +1201,10 @@ public abstract class CommandArgument
|
||||
}
|
||||
|
||||
public VanillaUnconfigurableArgument(
|
||||
final String suffix,
|
||||
final ArgumentProvider argumentTypeSupplier,
|
||||
final ValueExtractor valueExtractor,
|
||||
final SuggestionProvider<CommandSourceStack> suggester
|
||||
String suffix,
|
||||
ArgumentProvider argumentTypeSupplier,
|
||||
ValueExtractor valueExtractor,
|
||||
SuggestionProvider<CommandSourceStack> suggester
|
||||
)
|
||||
{
|
||||
super(suffix, Collections.emptyList(), false);
|
||||
@@ -1213,19 +1216,19 @@ public abstract class CommandArgument
|
||||
}
|
||||
|
||||
public VanillaUnconfigurableArgument(
|
||||
final String suffix,
|
||||
final ArgumentProviderEx argumentTypeSupplier,
|
||||
final ValueExtractor valueExtractor,
|
||||
final boolean suggestFromExamples,
|
||||
final MinecraftServer server)
|
||||
String suffix,
|
||||
ArgumentProviderEx argumentTypeSupplier,
|
||||
ValueExtractor valueExtractor,
|
||||
boolean suggestFromExamples,
|
||||
MinecraftServer server)
|
||||
{
|
||||
super(suffix, null, suggestFromExamples);
|
||||
try
|
||||
{
|
||||
final CommandBuildContext context = CommandBuildContext.simple(server.registryAccess(), server.getWorldData().enabledFeatures());
|
||||
CommandBuildContext context = CommandBuildContext.simple(server.registryAccess(), server.getWorldData().enabledFeatures());
|
||||
this.examples = argumentTypeSupplier.get(context).getExamples();
|
||||
}
|
||||
catch (final CommandSyntaxException e)
|
||||
catch (CommandSyntaxException e)
|
||||
{
|
||||
this.examples = Collections.emptyList();
|
||||
}
|
||||
@@ -1236,10 +1239,10 @@ public abstract class CommandArgument
|
||||
}
|
||||
|
||||
public VanillaUnconfigurableArgument(
|
||||
final String suffix,
|
||||
final ArgumentProviderEx argumentTypeSupplier,
|
||||
final ValueExtractor valueExtractor,
|
||||
final SuggestionProvider<CommandSourceStack> suggester
|
||||
String suffix,
|
||||
ArgumentProviderEx argumentTypeSupplier,
|
||||
ValueExtractor valueExtractor,
|
||||
SuggestionProvider<CommandSourceStack> suggester
|
||||
)
|
||||
{
|
||||
super(suffix, Collections.emptyList(), false);
|
||||
@@ -1251,10 +1254,10 @@ public abstract class CommandArgument
|
||||
}
|
||||
|
||||
public VanillaUnconfigurableArgument(
|
||||
final String suffix,
|
||||
final ArgumentProviderEx argumentTypeSupplier,
|
||||
final ValueExtractor valueExtractor,
|
||||
final Function<String, SuggestionProvider<CommandSourceStack>> suggesterGen
|
||||
String suffix,
|
||||
ArgumentProviderEx argumentTypeSupplier,
|
||||
ValueExtractor valueExtractor,
|
||||
Function<String, SuggestionProvider<CommandSourceStack>> suggesterGen
|
||||
)
|
||||
{
|
||||
super(suffix, Collections.emptyList(), false);
|
||||
@@ -1266,20 +1269,20 @@ public abstract class CommandArgument
|
||||
}
|
||||
|
||||
public <T> VanillaUnconfigurableArgument(
|
||||
final String suffix,
|
||||
final ResourceKey<Registry<T>> registry
|
||||
String suffix,
|
||||
ResourceKey<Registry<T>> registry
|
||||
)
|
||||
{
|
||||
this(
|
||||
suffix,
|
||||
(c) -> ResourceArgument.resource(c, registry),
|
||||
c -> ResourceArgument.resource(c, registry),
|
||||
(c, p) -> ValueConversions.of(ResourceArgument.getResource(c, p, registry).key()),
|
||||
(c, b) -> SharedSuggestionProvider.suggestResource(c.getSource().getServer().registryAccess().registryOrThrow(registry).keySet(), b)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ArgumentType<?> getArgumentType(final CarpetScriptHost host) throws CommandSyntaxException
|
||||
protected ArgumentType<?> getArgumentType(CarpetScriptHost host) throws CommandSyntaxException
|
||||
{
|
||||
return argumentTypeSupplier != null
|
||||
? argumentTypeSupplier.get()
|
||||
@@ -1287,13 +1290,13 @@ public abstract class CommandArgument
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Value getValueFromContext(final CommandContext<CommandSourceStack> context, final String param) throws CommandSyntaxException
|
||||
protected Value getValueFromContext(CommandContext<CommandSourceStack> context, String param) throws CommandSyntaxException
|
||||
{
|
||||
return valueExtractor.apply(context, param);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Supplier<CommandArgument> factory(final MinecraftServer server)
|
||||
protected Supplier<CommandArgument> factory(MinecraftServer server)
|
||||
{
|
||||
return argumentTypeSupplier != null
|
||||
? (() -> new VanillaUnconfigurableArgument(getTypeSuffix(), argumentTypeSupplier, valueExtractor, providesExamples))
|
||||
|
||||
@@ -14,22 +14,26 @@ import java.util.Objects;
|
||||
|
||||
import net.minecraft.commands.CommandSourceStack;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import static net.minecraft.commands.Commands.literal;
|
||||
|
||||
public class CommandToken implements Comparable<CommandToken>
|
||||
{
|
||||
public String surface;
|
||||
public boolean isArgument;
|
||||
public CommandArgument type;
|
||||
public final String surface;
|
||||
public final boolean isArgument;
|
||||
@Nullable
|
||||
public final CommandArgument type;
|
||||
|
||||
private CommandToken(final String surface, final CommandArgument type)
|
||||
private CommandToken(String surface, @Nullable CommandArgument type)
|
||||
{
|
||||
this.surface = surface;
|
||||
this.type = type;
|
||||
isArgument = type != null;
|
||||
}
|
||||
|
||||
public static CommandToken getToken(String source, final CarpetScriptHost host)
|
||||
@Nullable
|
||||
public static CommandToken getToken(String source, CarpetScriptHost host)
|
||||
{
|
||||
// todo add more type checking and return null
|
||||
if (!source.startsWith("<"))
|
||||
@@ -40,18 +44,18 @@ public class CommandToken implements Comparable<CommandToken>
|
||||
return source.matches("[_a-zA-Z]+") ? new CommandToken(source, CommandArgument.getTypeForArgument(source, host)) : null;
|
||||
}
|
||||
|
||||
public static List<CommandToken> parseSpec(String spec, final CarpetScriptHost host) throws CommandSyntaxException
|
||||
public static List<CommandToken> parseSpec(String spec, CarpetScriptHost host) throws CommandSyntaxException
|
||||
{
|
||||
spec = spec.trim();
|
||||
if (spec.isEmpty())
|
||||
{
|
||||
return Collections.emptyList();
|
||||
}
|
||||
final List<CommandToken> elements = new ArrayList<>();
|
||||
final HashSet<String> seenArgs = new HashSet<>();
|
||||
for (final String el : spec.split("\\s+"))
|
||||
List<CommandToken> elements = new ArrayList<>();
|
||||
HashSet<String> seenArgs = new HashSet<>();
|
||||
for (String el : spec.split("\\s+"))
|
||||
{
|
||||
final CommandToken tok = CommandToken.getToken(el, host);
|
||||
CommandToken tok = CommandToken.getToken(el, host);
|
||||
if (tok == null)
|
||||
{
|
||||
throw CommandArgument.error("Unrecognized command token: " + el);
|
||||
@@ -69,23 +73,23 @@ public class CommandToken implements Comparable<CommandToken>
|
||||
return elements;
|
||||
}
|
||||
|
||||
public static String specFromSignature(final FunctionValue function)
|
||||
public static String specFromSignature(FunctionValue function)
|
||||
{
|
||||
final List<String> tokens = Lists.newArrayList(function.getString());
|
||||
for (final String arg : function.getArguments())
|
||||
List<String> tokens = Lists.newArrayList(function.getString());
|
||||
for (String arg : function.getArguments())
|
||||
{
|
||||
tokens.add("<" + arg + ">");
|
||||
}
|
||||
return String.join(" ", tokens);
|
||||
}
|
||||
|
||||
public ArgumentBuilder<CommandSourceStack, ?> getCommandNode(final CarpetScriptHost host) throws CommandSyntaxException
|
||||
public ArgumentBuilder<CommandSourceStack, ?> getCommandNode(CarpetScriptHost host) throws CommandSyntaxException
|
||||
{
|
||||
return isArgument ? CommandArgument.argumentNode(surface, host) : literal(surface);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object o)
|
||||
public boolean equals(Object o)
|
||||
{
|
||||
if (this == o)
|
||||
{
|
||||
@@ -95,7 +99,7 @@ public class CommandToken implements Comparable<CommandToken>
|
||||
{
|
||||
return false;
|
||||
}
|
||||
final CommandToken that = (CommandToken) o;
|
||||
CommandToken that = (CommandToken) o;
|
||||
return surface.equals(that.surface) &&
|
||||
Objects.equals(type, that.type);
|
||||
}
|
||||
@@ -107,7 +111,7 @@ public class CommandToken implements Comparable<CommandToken>
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(final CommandToken o)
|
||||
public int compareTo(CommandToken o)
|
||||
{
|
||||
if (isArgument && !o.isArgument)
|
||||
{
|
||||
|
||||
@@ -2,9 +2,11 @@ package carpet.script.exception;
|
||||
|
||||
import carpet.script.value.Value;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class BreakStatement extends ExitStatement
|
||||
{
|
||||
public BreakStatement(final Value value)
|
||||
public BreakStatement(@Nullable Value value)
|
||||
{
|
||||
super(value);
|
||||
}
|
||||
|
||||
@@ -11,17 +11,17 @@ public class CarpetExpressionException extends StacklessRuntimeException impleme
|
||||
{
|
||||
public final List<FunctionValue> stack;
|
||||
|
||||
public CarpetExpressionException(final String message, final List<FunctionValue> stack)
|
||||
public CarpetExpressionException(String message, List<FunctionValue> stack)
|
||||
{
|
||||
super(message);
|
||||
this.stack = stack;
|
||||
}
|
||||
|
||||
public void printStack(final CommandSourceStack source)
|
||||
public void printStack(CommandSourceStack source)
|
||||
{
|
||||
if (stack != null && !stack.isEmpty())
|
||||
{
|
||||
for (final FunctionValue fun : stack)
|
||||
for (FunctionValue fun : stack)
|
||||
{
|
||||
Carpet.Messenger_message(source, "e ... in " + fun.fullName(), "e /" + (fun.getToken().lineno + 1) + ":" + (fun.getToken().linepos + 1));
|
||||
}
|
||||
|
||||
@@ -2,9 +2,11 @@ package carpet.script.exception;
|
||||
|
||||
import carpet.script.value.Value;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class ContinueStatement extends ExitStatement
|
||||
{
|
||||
public ContinueStatement(final Value value)
|
||||
public ContinueStatement(@Nullable Value value)
|
||||
{
|
||||
super(value);
|
||||
}
|
||||
|
||||
@@ -2,12 +2,15 @@ package carpet.script.exception;
|
||||
|
||||
import carpet.script.value.Value;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/* Exception thrown to terminate execution mid expression (aka return statement) */
|
||||
public class ExitStatement extends StacklessRuntimeException
|
||||
{
|
||||
@Nullable
|
||||
public final Value retval;
|
||||
|
||||
public ExitStatement(final Value value)
|
||||
public ExitStatement(@Nullable Value value)
|
||||
{
|
||||
retval = value;
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import carpet.script.Tokenizer;
|
||||
import carpet.script.external.Carpet;
|
||||
import carpet.script.value.FunctionValue;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
@@ -25,17 +26,17 @@ public class ExpressionException extends StacklessRuntimeException implements Re
|
||||
Carpet.Messenger_compose("foo bar");
|
||||
}
|
||||
|
||||
public ExpressionException(final Context c, final Expression e, final String message)
|
||||
public ExpressionException(Context c, Expression e, String message)
|
||||
{
|
||||
this(c, e, Tokenizer.Token.NONE, message);
|
||||
}
|
||||
|
||||
public ExpressionException(final Context c, final Expression e, final Tokenizer.Token t, final String message)
|
||||
public ExpressionException(Context c, Expression e, Tokenizer.Token t, String message)
|
||||
{
|
||||
this(c, e, t, message, Collections.emptyList());
|
||||
}
|
||||
|
||||
public ExpressionException(final Context c, final Expression e, final Tokenizer.Token t, final String message, final List<FunctionValue> stack)
|
||||
public ExpressionException(Context c, Expression e, Tokenizer.Token t, String message, List<FunctionValue> stack)
|
||||
{
|
||||
super("Error");
|
||||
this.stack.addAll(stack);
|
||||
@@ -44,7 +45,7 @@ public class ExpressionException extends StacklessRuntimeException implements Re
|
||||
context = c;
|
||||
}
|
||||
|
||||
public ExpressionException(final Context c, final Expression e, final Tokenizer.Token t, final Supplier<String> messageSupplier, final List<FunctionValue> stack)
|
||||
public ExpressionException(Context c, Expression e, Tokenizer.Token t, Supplier<String> messageSupplier, List<FunctionValue> stack)
|
||||
{
|
||||
super("Error");
|
||||
this.stack.addAll(stack);
|
||||
@@ -53,13 +54,13 @@ public class ExpressionException extends StacklessRuntimeException implements Re
|
||||
context = c;
|
||||
}
|
||||
|
||||
private static List<String> makeError(final Expression expr, /*Nullable*/final Tokenizer.Token token, String errmessage)
|
||||
private static List<String> makeError(Expression expr, @Nullable Tokenizer.Token token, String errmessage)
|
||||
{
|
||||
final List<String> errMsg = new ArrayList<>();
|
||||
List<String> errMsg = new ArrayList<>();
|
||||
errmessage += expr.getModuleName() == null ? "" : (" in " + expr.getModuleName());
|
||||
if (token != null)
|
||||
{
|
||||
final List<String> snippet = expr.getExpressionSnippet(token);
|
||||
List<String> snippet = expr.getExpressionSnippet(token);
|
||||
errMsg.addAll(snippet);
|
||||
|
||||
if (snippet.size() != 1)
|
||||
@@ -75,11 +76,11 @@ public class ExpressionException extends StacklessRuntimeException implements Re
|
||||
return errMsg;
|
||||
}
|
||||
|
||||
static synchronized String makeMessage(final Context c, final Expression e, final Tokenizer.Token t, final String message) throws ExpressionException
|
||||
static synchronized String makeMessage(Context c, Expression e, Tokenizer.Token t, String message) throws ExpressionException
|
||||
{
|
||||
if (c.getErrorSnooper() != null)
|
||||
{
|
||||
final List<String> alternative = c.getErrorSnooper().apply(e, t, c, message);
|
||||
List<String> alternative = c.getErrorSnooper().apply(e, t, c, message);
|
||||
if (alternative != null)
|
||||
{
|
||||
return String.join("\n", alternative);
|
||||
|
||||
@@ -2,7 +2,7 @@ package carpet.script.exception;
|
||||
|
||||
public class IntegrityException extends RuntimeException
|
||||
{
|
||||
public IntegrityException(final String message)
|
||||
public IntegrityException(String message)
|
||||
{
|
||||
super(message);
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ public class InternalExpressionException extends StacklessRuntimeException
|
||||
{
|
||||
public List<FunctionValue> stack = new ArrayList<>();
|
||||
|
||||
public InternalExpressionException(final String message)
|
||||
public InternalExpressionException(String message)
|
||||
{
|
||||
super(message);
|
||||
}
|
||||
@@ -30,7 +30,7 @@ public class InternalExpressionException extends StacklessRuntimeException
|
||||
* @return The new {@link ExpressionException} (or {@link ProcessedThrowStatement}),
|
||||
* depending on the implementation.
|
||||
*/
|
||||
public ExpressionException promote(final Context c, final Expression e, final Tokenizer.Token token)
|
||||
public ExpressionException promote(Context c, Expression e, Tokenizer.Token token)
|
||||
{
|
||||
return new ExpressionException(c, e, token, getMessage(), stack);
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ public class LoadException extends RuntimeException implements ResolvedException
|
||||
{
|
||||
super();
|
||||
}
|
||||
public LoadException(final String message)
|
||||
public LoadException(String message)
|
||||
{
|
||||
super(message);
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ public class ProcessedThrowStatement extends ExpressionException
|
||||
public final Throwables thrownExceptionType;
|
||||
public final Value data;
|
||||
|
||||
public ProcessedThrowStatement(final Context c, final Expression e, final Token token, final List<FunctionValue> stack, final Throwables thrownExceptionType, final Value data)
|
||||
public ProcessedThrowStatement(Context c, Expression e, Token token, List<FunctionValue> stack, Throwables thrownExceptionType, Value data)
|
||||
{
|
||||
super(c, e, token, () -> "Unhandled " + thrownExceptionType.getId() + " exception: " + data.getString(), stack);
|
||||
this.thrownExceptionType = thrownExceptionType;
|
||||
|
||||
@@ -4,7 +4,7 @@ import carpet.script.value.Value;
|
||||
|
||||
public class ReturnStatement extends ExitStatement
|
||||
{
|
||||
public ReturnStatement(final Value value)
|
||||
public ReturnStatement(Value value)
|
||||
{
|
||||
super(value);
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ public abstract class StacklessRuntimeException extends RuntimeException
|
||||
super();
|
||||
}
|
||||
|
||||
public StacklessRuntimeException(final String message)
|
||||
public StacklessRuntimeException(String message)
|
||||
{
|
||||
super(message);
|
||||
}
|
||||
|
||||
@@ -18,14 +18,14 @@ public class ThrowStatement extends InternalExpressionException
|
||||
* @param data The value to pass
|
||||
* @param type Exception type
|
||||
*/
|
||||
public ThrowStatement(final Value data, final Throwables type)
|
||||
public ThrowStatement(Value data, Throwables type)
|
||||
{
|
||||
super(type.getId());
|
||||
this.data = data;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public ThrowStatement(final Value data, final Throwables parent, final String subtype)
|
||||
public ThrowStatement(Value data, Throwables parent, String subtype)
|
||||
{
|
||||
super(subtype);
|
||||
this.data = data;
|
||||
@@ -42,7 +42,7 @@ public class ThrowStatement extends InternalExpressionException
|
||||
* for this exception. When throwing from Java,
|
||||
* those exceptions should be pre-registered.
|
||||
*/
|
||||
public ThrowStatement(final String message, final Throwables type)
|
||||
public ThrowStatement(String message, Throwables type)
|
||||
{
|
||||
super(type.getId());
|
||||
this.data = StringValue.of(message);
|
||||
@@ -50,7 +50,7 @@ public class ThrowStatement extends InternalExpressionException
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExpressionException promote(final Context c, final Expression e, final Token token)
|
||||
public ExpressionException promote(Context c, Expression e, Token token)
|
||||
{
|
||||
return new ProcessedThrowStatement(c, e, token, stack, type, data);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package carpet.script.exception;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -10,6 +11,7 @@ import java.util.Map;
|
||||
public class Throwables
|
||||
{
|
||||
private final String id;
|
||||
@Nullable
|
||||
private final Throwables parent;
|
||||
|
||||
private static final Map<String, Throwables> byId = new HashMap<>();
|
||||
@@ -41,9 +43,9 @@ public class Throwables
|
||||
* @param parent The parent of the exception being created, or <code>null</code> if top-level
|
||||
* @return The created exception
|
||||
*/
|
||||
public static Throwables register(final String id, final Throwables parent)
|
||||
public static Throwables register(String id, @Nullable Throwables parent)
|
||||
{
|
||||
final Throwables exc = new Throwables(id, parent);
|
||||
Throwables exc = new Throwables(id, parent);
|
||||
byId.put(id, exc);
|
||||
return exc;
|
||||
}
|
||||
@@ -55,15 +57,15 @@ public class Throwables
|
||||
*
|
||||
* @param id The exception's value as a {@link String}
|
||||
*/
|
||||
public Throwables(final String id, final Throwables parent)
|
||||
public Throwables(String id, @Nullable Throwables parent)
|
||||
{
|
||||
this.id = id;
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public static Throwables getTypeForException(final String type)
|
||||
public static Throwables getTypeForException(String type)
|
||||
{
|
||||
final Throwables properType = byId.get(type);
|
||||
Throwables properType = byId.get(type);
|
||||
if (properType == null)
|
||||
{
|
||||
throw new InternalExpressionException("Unknown exception type: " + type);
|
||||
@@ -78,7 +80,7 @@ public class Throwables
|
||||
* @param filter The type to check against
|
||||
* @return Whether or not the given value matches this exception's hierarchy
|
||||
*/
|
||||
public boolean isRelevantFor(final String filter)
|
||||
public boolean isRelevantFor(String filter)
|
||||
{
|
||||
return (id.equals(filter) || (parent != null && parent.isRelevantFor(filter)));
|
||||
}
|
||||
|
||||
+14
-14
@@ -46,17 +46,17 @@ public class Carpet
|
||||
return HUDController.scarpet_footers;
|
||||
}
|
||||
|
||||
public static void updateScarpetHUDs(final MinecraftServer server, final List<ServerPlayer> players)
|
||||
public static void updateScarpetHUDs(MinecraftServer server, List<ServerPlayer> players)
|
||||
{
|
||||
HUDController.update_hud(server, players);
|
||||
}
|
||||
|
||||
public static Component Messenger_compose(final Object... messages)
|
||||
public static Component Messenger_compose(Object... messages)
|
||||
{
|
||||
return Messenger.c(messages);
|
||||
}
|
||||
|
||||
public static void Messenger_message(final CommandSourceStack source, final Object... messages)
|
||||
public static void Messenger_message(CommandSourceStack source, Object... messages)
|
||||
{
|
||||
Messenger.m(source, messages);
|
||||
}
|
||||
@@ -81,34 +81,34 @@ public class Carpet
|
||||
return BlockInfo.materialName;
|
||||
}
|
||||
|
||||
public static Runnable startProfilerSection(final String name)
|
||||
public static Runnable startProfilerSection(String name)
|
||||
{
|
||||
final CarpetProfiler.ProfilerToken token = CarpetProfiler.start_section(null, name, CarpetProfiler.TYPE.GENERAL);
|
||||
CarpetProfiler.ProfilerToken token = CarpetProfiler.start_section(null, name, CarpetProfiler.TYPE.GENERAL);
|
||||
return () -> CarpetProfiler.end_current_section(token);
|
||||
}
|
||||
|
||||
public static void MinecraftServer_addScriptServer(final MinecraftServer server, final CarpetScriptServer scriptServer)
|
||||
public static void MinecraftServer_addScriptServer(MinecraftServer server, CarpetScriptServer scriptServer)
|
||||
{
|
||||
((MinecraftServerInterface) server).addScriptServer(scriptServer);
|
||||
}
|
||||
|
||||
public static boolean isValidCarpetPlayer(final ServerPlayer player)
|
||||
public static boolean isValidCarpetPlayer(ServerPlayer player)
|
||||
{
|
||||
return ServerNetworkHandler.isValidCarpetPlayer(player);
|
||||
}
|
||||
|
||||
public static String getPlayerStatus(final ServerPlayer player)
|
||||
public static String getPlayerStatus(ServerPlayer player)
|
||||
{
|
||||
return ServerNetworkHandler.getPlayerStatus(player);
|
||||
}
|
||||
|
||||
public static MapValue getAllCarpetRules()
|
||||
{
|
||||
final Collection<CarpetRule<?>> rules = CarpetServer.settingsManager.getCarpetRules();
|
||||
final MapValue carpetRules = new MapValue(Collections.emptyList());
|
||||
Collection<CarpetRule<?>> rules = CarpetServer.settingsManager.getCarpetRules();
|
||||
MapValue carpetRules = new MapValue(Collections.emptyList());
|
||||
rules.forEach(rule -> carpetRules.put(new StringValue(rule.name()), new StringValue(RuleHelper.toRuleString(rule.value()))));
|
||||
CarpetServer.extensions.forEach(e -> {
|
||||
final SettingsManager manager = e.extensionSettingsManager();
|
||||
SettingsManager manager = e.extensionSettingsManager();
|
||||
if (manager == null)
|
||||
{
|
||||
return;
|
||||
@@ -124,7 +124,7 @@ public class Carpet
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static String isModdedPlayer(final Player p)
|
||||
public static String isModdedPlayer(Player p)
|
||||
{
|
||||
if (p instanceof final EntityPlayerMPFake fake)
|
||||
{
|
||||
@@ -138,7 +138,7 @@ public class Carpet
|
||||
return !TickSpeed.process_entities;
|
||||
}
|
||||
|
||||
public static void handleExtensionsAPI(final CarpetExpression expression)
|
||||
public static void handleExtensionsAPI(CarpetExpression expression)
|
||||
{
|
||||
CarpetServer.extensions.forEach(e -> e.scarpetApi(expression));
|
||||
}
|
||||
@@ -151,7 +151,7 @@ public class Carpet
|
||||
public static class ScarpetAppStoreValidator extends Validator<String>
|
||||
{
|
||||
@Override
|
||||
public String validate(final CommandSourceStack source, final CarpetRule<String> currentRule, String newValue, final String stringInput)
|
||||
public String validate(@Nullable CommandSourceStack source, CarpetRule<String> currentRule, String newValue, String stringInput)
|
||||
{
|
||||
if (newValue.equals(currentRule.value()))
|
||||
{
|
||||
|
||||
+53
-53
@@ -93,27 +93,27 @@ import java.util.function.Predicate;
|
||||
|
||||
public class Vanilla
|
||||
{
|
||||
public static void MinecraftServer_forceTick(final MinecraftServer server, final BooleanSupplier sup)
|
||||
public static void MinecraftServer_forceTick(MinecraftServer server, BooleanSupplier sup)
|
||||
{
|
||||
((MinecraftServerInterface) server).forceTick(sup);
|
||||
}
|
||||
|
||||
public static void ChunkMap_relightChunk(final ChunkMap chunkMap, final ChunkPos pos)
|
||||
public static void ChunkMap_relightChunk(ChunkMap chunkMap, ChunkPos pos)
|
||||
{
|
||||
((ThreadedAnvilChunkStorageInterface) chunkMap).relightChunk(pos);
|
||||
}
|
||||
|
||||
public static Map<String, Integer> ChunkMap_regenerateChunkRegion(final ChunkMap chunkMap, final List<ChunkPos> requestedChunks)
|
||||
public static Map<String, Integer> ChunkMap_regenerateChunkRegion(ChunkMap chunkMap, List<ChunkPos> requestedChunks)
|
||||
{
|
||||
return ((ThreadedAnvilChunkStorageInterface) chunkMap).regenerateChunkRegion(requestedChunks);
|
||||
}
|
||||
|
||||
public static List<Collection<ItemStack>> Ingredient_getRecipeStacks(final Ingredient ingredient)
|
||||
public static List<Collection<ItemStack>> Ingredient_getRecipeStacks(Ingredient ingredient)
|
||||
{
|
||||
return ((IngredientInterface) (Object) ingredient).getRecipeStacks();
|
||||
}
|
||||
|
||||
public static List<Recipe<?>> RecipeManager_getAllMatching(final RecipeManager recipeManager, final RecipeType<?> type, final ResourceLocation output, final RegistryAccess registryAccess)
|
||||
public static List<Recipe<?>> RecipeManager_getAllMatching(RecipeManager recipeManager, RecipeType<?> type, ResourceLocation output, RegistryAccess registryAccess)
|
||||
{
|
||||
return ((RecipeManagerInterface) recipeManager).getAllMatching(type, output, registryAccess);
|
||||
}
|
||||
@@ -123,72 +123,72 @@ public class Vanilla
|
||||
return SpawnReporter.MAGIC_NUMBER;
|
||||
}
|
||||
|
||||
public static PotentialCalculator SpawnState_getPotentialCalculator(final NaturalSpawner.SpawnState spawnState)
|
||||
public static PotentialCalculator SpawnState_getPotentialCalculator(NaturalSpawner.SpawnState spawnState)
|
||||
{
|
||||
return ((SpawnHelperInnerInterface) spawnState).getPotentialCalculator();
|
||||
}
|
||||
|
||||
public static void Objective_setCriterion(final Objective objective, final ObjectiveCriteria criterion)
|
||||
public static void Objective_setCriterion(Objective objective, ObjectiveCriteria criterion)
|
||||
{
|
||||
((Objective_scarpetMixin) objective).setCriterion(criterion);
|
||||
}
|
||||
|
||||
public static Map<ObjectiveCriteria, List<Objective>> Scoreboard_getObjectivesByCriterion(final Scoreboard scoreboard)
|
||||
public static Map<ObjectiveCriteria, List<Objective>> Scoreboard_getObjectivesByCriterion(Scoreboard scoreboard)
|
||||
{
|
||||
return ((Scoreboard_scarpetMixin) scoreboard).getObjectivesByCriterion();
|
||||
}
|
||||
|
||||
public static ServerLevelData ServerLevel_getWorldProperties(final ServerLevel world)
|
||||
public static ServerLevelData ServerLevel_getWorldProperties(ServerLevel world)
|
||||
{
|
||||
return ((ServerWorldInterface) world).getWorldPropertiesCM();
|
||||
}
|
||||
|
||||
public static DistanceManager ServerChunkCache_getCMTicketManager(final ServerChunkCache chunkCache)
|
||||
public static DistanceManager ServerChunkCache_getCMTicketManager(ServerChunkCache chunkCache)
|
||||
{
|
||||
return ((ServerChunkManagerInterface) chunkCache).getCMTicketManager();
|
||||
}
|
||||
|
||||
public static Long2ObjectOpenHashMap<SortedArraySet<Ticket<?>>> ChunkTicketManager_getTicketsByPosition(final DistanceManager ticketManager)
|
||||
public static Long2ObjectOpenHashMap<SortedArraySet<Ticket<?>>> ChunkTicketManager_getTicketsByPosition(DistanceManager ticketManager)
|
||||
{
|
||||
return ((ChunkTicketManagerInterface) ticketManager).getTicketsByPosition();
|
||||
}
|
||||
|
||||
public static DensityFunction.Visitor RandomState_getVisitor(final RandomState randomState)
|
||||
public static DensityFunction.Visitor RandomState_getVisitor(RandomState randomState)
|
||||
{
|
||||
return ((RandomStateVisitorAccessor) (Object) randomState).getVisitor();
|
||||
}
|
||||
|
||||
public static CompoundTag BlockInput_getTag(final BlockInput blockInput)
|
||||
public static CompoundTag BlockInput_getTag(BlockInput blockInput)
|
||||
{
|
||||
return ((BlockStateArgumentInterface) blockInput).getCMTag();
|
||||
}
|
||||
|
||||
public static CarpetScriptServer MinecraftServer_getScriptServer(final MinecraftServer server)
|
||||
public static CarpetScriptServer MinecraftServer_getScriptServer(MinecraftServer server)
|
||||
{
|
||||
return ((MinecraftServerInterface) server).getScriptServer();
|
||||
}
|
||||
|
||||
public static Biome.ClimateSettings Biome_getClimateSettings(final Biome biome)
|
||||
public static Biome.ClimateSettings Biome_getClimateSettings(Biome biome)
|
||||
{
|
||||
return ((BiomeInterface) (Object) biome).getClimateSettings();
|
||||
}
|
||||
|
||||
public static ThreadLocal<Boolean> skipGenerationChecks(final ServerLevel level)
|
||||
public static ThreadLocal<Boolean> skipGenerationChecks(ServerLevel level)
|
||||
{ // not sure does vanilla care at all - needs checking
|
||||
return CarpetSettings.skipGenerationChecks;
|
||||
}
|
||||
|
||||
public static void sendScarpetShapesDataToPlayer(final ServerPlayer player, final Tag data)
|
||||
public static void sendScarpetShapesDataToPlayer(ServerPlayer player, Tag data)
|
||||
{ // dont forget to add the packet to vanilla packed handler and call ShapesRenderer.addShape to handle on client
|
||||
ServerNetworkHandler.sendCustomCommand(player, "scShapes", data);
|
||||
}
|
||||
|
||||
public static int MinecraftServer_getRunPermissionLevel(final MinecraftServer server)
|
||||
public static int MinecraftServer_getRunPermissionLevel(MinecraftServer server)
|
||||
{
|
||||
return CarpetSettings.runPermissionLevel;
|
||||
}
|
||||
|
||||
public static String MinecraftServer_getReleaseTarget(final MinecraftServer server)
|
||||
public static String MinecraftServer_getReleaseTarget(MinecraftServer server)
|
||||
{
|
||||
return CarpetSettings.releaseTarget;
|
||||
}
|
||||
@@ -198,165 +198,165 @@ public class Vanilla
|
||||
return FabricLoader.getInstance().isDevelopmentEnvironment();
|
||||
}
|
||||
|
||||
public static MapValue getServerMods(final MinecraftServer server)
|
||||
public static MapValue getServerMods(MinecraftServer server)
|
||||
{
|
||||
final Map<Value, Value> ret = new HashMap<>();
|
||||
for (final ModContainer mod : FabricLoader.getInstance().getAllMods())
|
||||
Map<Value, Value> ret = new HashMap<>();
|
||||
for (ModContainer mod : FabricLoader.getInstance().getAllMods())
|
||||
{
|
||||
ret.put(new StringValue(mod.getMetadata().getId()), new StringValue(mod.getMetadata().getVersion().getFriendlyString()));
|
||||
}
|
||||
return MapValue.wrap(ret);
|
||||
}
|
||||
|
||||
public static LevelStorageSource.LevelStorageAccess MinecraftServer_storageSource(final MinecraftServer server)
|
||||
public static LevelStorageSource.LevelStorageAccess MinecraftServer_storageSource(MinecraftServer server)
|
||||
{
|
||||
return ((MinecraftServerInterface) server).getCMSession();
|
||||
}
|
||||
|
||||
public static BlockPos ServerPlayerGameMode_getCurrentBlockPosition(final ServerPlayerGameMode gameMode)
|
||||
public static BlockPos ServerPlayerGameMode_getCurrentBlockPosition(ServerPlayerGameMode gameMode)
|
||||
{
|
||||
return ((ServerPlayerInteractionManagerInterface) gameMode).getCurrentBreakingBlock();
|
||||
}
|
||||
|
||||
public static int ServerPlayerGameMode_getCurrentBlockBreakingProgress(final ServerPlayerGameMode gameMode)
|
||||
public static int ServerPlayerGameMode_getCurrentBlockBreakingProgress(ServerPlayerGameMode gameMode)
|
||||
{
|
||||
return ((ServerPlayerInteractionManagerInterface) gameMode).getCurrentBlockBreakingProgress();
|
||||
}
|
||||
|
||||
public static void ServerPlayerGameMode_setBlockBreakingProgress(final ServerPlayerGameMode gameMode, final int progress)
|
||||
public static void ServerPlayerGameMode_setBlockBreakingProgress(ServerPlayerGameMode gameMode, int progress)
|
||||
{
|
||||
((ServerPlayerInteractionManagerInterface) gameMode).setBlockBreakingProgress(progress);
|
||||
}
|
||||
|
||||
public static boolean ServerPlayer_isInvalidEntityObject(final ServerPlayer player)
|
||||
public static boolean ServerPlayer_isInvalidEntityObject(ServerPlayer player)
|
||||
{
|
||||
return ((ServerPlayerInterface) player).isInvalidEntityObject();
|
||||
}
|
||||
|
||||
public static String ServerPlayer_getLanguage(final ServerPlayer player)
|
||||
public static String ServerPlayer_getLanguage(ServerPlayer player)
|
||||
{
|
||||
return ((ServerPlayerInterface) player).getLanguage();
|
||||
}
|
||||
|
||||
public static GoalSelector Mob_getAI(final Mob mob, final boolean target)
|
||||
public static GoalSelector Mob_getAI(Mob mob, boolean target)
|
||||
{
|
||||
return ((MobEntityInterface) mob).getAI(target);
|
||||
}
|
||||
|
||||
public static Map<String, Goal> Mob_getTemporaryTasks(final Mob mob)
|
||||
public static Map<String, Goal> Mob_getTemporaryTasks(Mob mob)
|
||||
{
|
||||
return ((MobEntityInterface) mob).getTemporaryTasks();
|
||||
}
|
||||
|
||||
public static void Mob_setPersistence(final Mob mob, final boolean what)
|
||||
public static void Mob_setPersistence(Mob mob, boolean what)
|
||||
{
|
||||
((MobEntityInterface) mob).setPersistence(what);
|
||||
}
|
||||
|
||||
public static EntityEventsGroup Entity_getEventContainer(final Entity entity)
|
||||
public static EntityEventsGroup Entity_getEventContainer(Entity entity)
|
||||
{
|
||||
return ((EntityInterface) entity).getEventContainer();
|
||||
}
|
||||
|
||||
public static boolean Entity_isPermanentVehicle(final Entity entity)
|
||||
public static boolean Entity_isPermanentVehicle(Entity entity)
|
||||
{
|
||||
return ((EntityInterface) entity).isPermanentVehicle();
|
||||
}
|
||||
|
||||
public static void Entity_setPermanentVehicle(final Entity entity, final boolean permanent)
|
||||
public static void Entity_setPermanentVehicle(Entity entity, boolean permanent)
|
||||
{
|
||||
((EntityInterface) entity).setPermanentVehicle(permanent);
|
||||
}
|
||||
|
||||
public static int Entity_getPortalTimer(final Entity entity)
|
||||
public static int Entity_getPortalTimer(Entity entity)
|
||||
{
|
||||
return ((EntityInterface) entity).getPortalTimer();
|
||||
}
|
||||
|
||||
public static void Entity_setPortalTimer(final Entity entity, final int amount)
|
||||
public static void Entity_setPortalTimer(Entity entity, int amount)
|
||||
{
|
||||
((EntityInterface) entity).setPortalTimer(amount);
|
||||
}
|
||||
|
||||
public static int Entity_getPublicNetherPortalCooldown(final Entity entity)
|
||||
public static int Entity_getPublicNetherPortalCooldown(Entity entity)
|
||||
{
|
||||
return ((EntityInterface) entity).getPublicNetherPortalCooldown();
|
||||
}
|
||||
|
||||
public static void Entity_setPublicNetherPortalCooldown(final Entity entity, final int what)
|
||||
public static void Entity_setPublicNetherPortalCooldown(Entity entity, int what)
|
||||
{
|
||||
((EntityInterface) entity).setPublicNetherPortalCooldown(what);
|
||||
}
|
||||
|
||||
public static int ItemEntity_getPickupDelay(final ItemEntity entity)
|
||||
public static int ItemEntity_getPickupDelay(ItemEntity entity)
|
||||
{
|
||||
return ((ItemEntityInterface) entity).getPickupDelayCM();
|
||||
}
|
||||
|
||||
public static boolean LivingEntity_isJumping(final LivingEntity entity)
|
||||
public static boolean LivingEntity_isJumping(LivingEntity entity)
|
||||
{
|
||||
return ((LivingEntityInterface) entity).isJumpingCM();
|
||||
}
|
||||
|
||||
public static void LivingEntity_setJumping(final LivingEntity entity)
|
||||
public static void LivingEntity_setJumping(LivingEntity entity)
|
||||
{
|
||||
((LivingEntityInterface) entity).doJumpCM();
|
||||
}
|
||||
|
||||
public static Container AbstractHorse_getInventory(final AbstractHorse horse)
|
||||
public static Container AbstractHorse_getInventory(AbstractHorse horse)
|
||||
{
|
||||
return ((InventoryBearerInterface) horse).getCMInventory();
|
||||
}
|
||||
|
||||
public static DataSlot AbstractContainerMenu_getDataSlot(final AbstractContainerMenu handler, final int index)
|
||||
public static DataSlot AbstractContainerMenu_getDataSlot(AbstractContainerMenu handler, int index)
|
||||
{
|
||||
return ((AbstractContainerMenuInterface) handler).getDataSlot(index);
|
||||
}
|
||||
|
||||
public static void CommandDispatcher_unregisterCommand(final CommandDispatcher<CommandSourceStack> dispatcher, final String name)
|
||||
public static void CommandDispatcher_unregisterCommand(CommandDispatcher<CommandSourceStack> dispatcher, String name)
|
||||
{
|
||||
((CommandDispatcherInterface) dispatcher).carpet$unregister(name);
|
||||
}
|
||||
|
||||
public static boolean MinecraftServer_doScriptsAutoload(final MinecraftServer server)
|
||||
public static boolean MinecraftServer_doScriptsAutoload(MinecraftServer server)
|
||||
{
|
||||
return CarpetSettings.scriptsAutoload;
|
||||
}
|
||||
|
||||
public static void MinecraftServer_notifyPlayersCommandsChanged(final MinecraftServer server)
|
||||
public static void MinecraftServer_notifyPlayersCommandsChanged(MinecraftServer server)
|
||||
{
|
||||
CommandHelper.notifyPlayersCommandsChanged(server);
|
||||
}
|
||||
|
||||
public static boolean ScriptServer_scriptOptimizations(final MinecraftServer scriptServer)
|
||||
public static boolean ScriptServer_scriptOptimizations(MinecraftServer scriptServer)
|
||||
{
|
||||
return CarpetSettings.scriptsOptimization;
|
||||
}
|
||||
|
||||
public static boolean ScriptServer_scriptDebugging(final MinecraftServer server)
|
||||
public static boolean ScriptServer_scriptDebugging(MinecraftServer server)
|
||||
{
|
||||
return CarpetSettings.scriptsDebugging;
|
||||
}
|
||||
|
||||
public static boolean ServerPlayer_canScriptACE(final CommandSourceStack player)
|
||||
public static boolean ServerPlayer_canScriptACE(CommandSourceStack player)
|
||||
{
|
||||
return CommandHelper.canUseCommand(player, CarpetSettings.commandScriptACE);
|
||||
}
|
||||
|
||||
public static boolean ServerPlayer_canScriptGeneral(final CommandSourceStack player)
|
||||
public static boolean ServerPlayer_canScriptGeneral(CommandSourceStack player)
|
||||
{
|
||||
return CommandHelper.canUseCommand(player, CarpetSettings.commandScript);
|
||||
}
|
||||
|
||||
public static int MinecraftServer_getFillLimit(final MinecraftServer server)
|
||||
public static int MinecraftServer_getFillLimit(MinecraftServer server)
|
||||
{
|
||||
return Math.max(server.getGameRules().getInt(GameRules.RULE_COMMAND_MODIFICATION_BLOCK_LIMIT), CarpetSettings.fillLimit);
|
||||
}
|
||||
|
||||
public record BlockPredicatePayload(BlockState state, TagKey<Block> tagKey, Map<Value, Value> properties, CompoundTag tag) {
|
||||
public static BlockPredicatePayload of(final Predicate<BlockInWorld> blockPredicate)
|
||||
public static BlockPredicatePayload of(Predicate<BlockInWorld> blockPredicate)
|
||||
{
|
||||
final BlockPredicateInterface predicateData = (BlockPredicateInterface) blockPredicate;
|
||||
BlockPredicateInterface predicateData = (BlockPredicateInterface) blockPredicate;
|
||||
return new BlockPredicatePayload(predicateData.getCMBlockState(), predicateData.getCMBlockTagKey(), predicateData.getCMProperties(), predicateData.getCMDataTag());
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@ import net.minecraft.world.level.block.entity.ShulkerBoxBlockEntity;
|
||||
|
||||
public class VanillaClient
|
||||
{
|
||||
public static ShulkerModel<?> ShulkerBoxRenderer_model(final BlockEntityRenderer<ShulkerBoxBlockEntity> shulkerBoxRenderer) {
|
||||
public static ShulkerModel<?> ShulkerBoxRenderer_model(BlockEntityRenderer<ShulkerBoxBlockEntity> shulkerBoxRenderer) {
|
||||
return ((ShulkerBoxAccessMixin)shulkerBoxRenderer).getModel();
|
||||
}
|
||||
}
|
||||
@@ -13,12 +13,12 @@ public class Arithmetic
|
||||
public static final Value PI = new NumericValue(Math.PI);
|
||||
public static final Value euler = new NumericValue(Math.E);
|
||||
|
||||
public static void apply(final Expression expression)
|
||||
public static void apply(Expression expression)
|
||||
{
|
||||
expression.addTypedContextFunction("not", 1, Context.Type.BOOLEAN, (c, t, lv) -> BooleanValue.of(lv.get(0).getBoolean()));
|
||||
expression.addUnaryFunction("fact", (v) ->
|
||||
expression.addUnaryFunction("fact", v ->
|
||||
{
|
||||
final long number = NumericValue.asNumber(v).getLong();
|
||||
long number = NumericValue.asNumber(v).getLong();
|
||||
if (number < 21)
|
||||
{
|
||||
long factorial = 1;
|
||||
@@ -82,26 +82,26 @@ public class Arithmetic
|
||||
expression.addMathematicalUnaryIntFunction("ceil", n -> (long) Math.ceil(n));
|
||||
|
||||
expression.addContextFunction("mandelbrot", 3, (c, t, lv) -> {
|
||||
final double a0 = NumericValue.asNumber(lv.get(0)).getDouble();
|
||||
final double b0 = NumericValue.asNumber(lv.get(1)).getDouble();
|
||||
final long maxiter = NumericValue.asNumber(lv.get(2)).getLong();
|
||||
double a0 = NumericValue.asNumber(lv.get(0)).getDouble();
|
||||
double b0 = NumericValue.asNumber(lv.get(1)).getDouble();
|
||||
long maxiter = NumericValue.asNumber(lv.get(2)).getLong();
|
||||
double a = 0.0D;
|
||||
double b = 0.0D;
|
||||
long iter = 0;
|
||||
while (a * a + b * b < 4 && iter < maxiter)
|
||||
{
|
||||
final double temp = a * a - b * b + a0;
|
||||
double temp = a * a - b * b + a0;
|
||||
b = 2 * a * b + b0;
|
||||
a = temp;
|
||||
iter++;
|
||||
}
|
||||
final long iFinal = iter;
|
||||
long iFinal = iter;
|
||||
return new NumericValue(iFinal);
|
||||
});
|
||||
|
||||
expression.addFunction("max", (lv) ->
|
||||
expression.addFunction("max", lv ->
|
||||
{
|
||||
if (lv.size() == 0)
|
||||
if (lv.isEmpty())
|
||||
{
|
||||
throw new InternalExpressionException("'max' requires at least one parameter");
|
||||
}
|
||||
@@ -110,7 +110,7 @@ public class Arithmetic
|
||||
{
|
||||
lv = ((ListValue) lv.get(0)).getItems();
|
||||
}
|
||||
for (final Value parameter : lv)
|
||||
for (Value parameter : lv)
|
||||
{
|
||||
if (max == null || parameter.compareTo(max) > 0)
|
||||
{
|
||||
@@ -120,9 +120,9 @@ public class Arithmetic
|
||||
return max;
|
||||
});
|
||||
|
||||
expression.addFunction("min", (lv) ->
|
||||
expression.addFunction("min", lv ->
|
||||
{
|
||||
if (lv.size() == 0)
|
||||
if (lv.isEmpty())
|
||||
{
|
||||
throw new InternalExpressionException("'min' requires at least one parameter");
|
||||
}
|
||||
@@ -131,7 +131,7 @@ public class Arithmetic
|
||||
{
|
||||
lv = ((ListValue) lv.get(0)).getItems();
|
||||
}
|
||||
for (final Value parameter : lv)
|
||||
for (Value parameter : lv)
|
||||
{
|
||||
if (min == null || parameter.compareTo(min) < 0)
|
||||
{
|
||||
|
||||
@@ -19,23 +19,23 @@ import java.util.stream.Collectors;
|
||||
|
||||
public class ControlFlow
|
||||
{
|
||||
public static void apply(final Expression expression) // public just to get the javadoc right
|
||||
public static void apply(Expression expression) // public just to get the javadoc right
|
||||
{
|
||||
// needs to be lazy cause of custom contextualization
|
||||
expression.addLazyBinaryOperator(";", Operators.precedence.get("nextop;"), true, true, t -> Context.Type.VOID, (c, t, lv1, lv2) ->
|
||||
{
|
||||
lv1.evalValue(c, Context.VOID);
|
||||
final Value v2 = lv2.evalValue(c, t);
|
||||
Value v2 = lv2.evalValue(c, t);
|
||||
return (cc, tt) -> v2;
|
||||
});
|
||||
|
||||
expression.addPureLazyFunction("then", -1, t -> Context.Type.VOID, (c, t, lv) -> {
|
||||
final int imax = lv.size() - 1;
|
||||
int imax = lv.size() - 1;
|
||||
for (int i = 0; i < imax; i++)
|
||||
{
|
||||
lv.get(i).evalValue(c, Context.VOID);
|
||||
}
|
||||
final Value v = lv.get(imax).evalValue(c, t);
|
||||
Value v = lv.get(imax).evalValue(c, t);
|
||||
return (cc, tt) -> v;
|
||||
});
|
||||
expression.addFunctionalEquivalence(";", "then");
|
||||
@@ -52,20 +52,20 @@ public class ControlFlow
|
||||
{
|
||||
if (lv.get(i).evalValue(c, Context.BOOLEAN).getBoolean())
|
||||
{
|
||||
final Value ret = lv.get(i + 1).evalValue(c, t);
|
||||
Value ret = lv.get(i + 1).evalValue(c, t);
|
||||
return (cc, tt) -> ret;
|
||||
}
|
||||
}
|
||||
if (lv.size() % 2 == 1)
|
||||
{
|
||||
final Value ret = lv.get(lv.size() - 1).evalValue(c, t);
|
||||
Value ret = lv.get(lv.size() - 1).evalValue(c, t);
|
||||
return (cc, tt) -> ret;
|
||||
}
|
||||
return (cc, tt) -> Value.NULL;
|
||||
});
|
||||
|
||||
expression.addImpureFunction("exit", (lv) -> {
|
||||
throw new ExitStatement(lv.size() == 0 ? Value.NULL : lv.get(0));
|
||||
expression.addImpureFunction("exit", lv -> {
|
||||
throw new ExitStatement(lv.isEmpty() ? Value.NULL : lv.get(0));
|
||||
});
|
||||
|
||||
expression.addImpureFunction("throw", lv ->
|
||||
@@ -83,16 +83,16 @@ public class ControlFlow
|
||||
// needs to be lazy since execution of parameters but first one are conditional
|
||||
expression.addLazyFunction("try", (c, t, lv) ->
|
||||
{
|
||||
if (lv.size() == 0)
|
||||
if (lv.isEmpty())
|
||||
{
|
||||
throw new InternalExpressionException("'try' needs at least an expression block, and either a catch_epr, or a number of pairs of filters and catch_expr");
|
||||
}
|
||||
try
|
||||
{
|
||||
final Value retval = lv.get(0).evalValue(c, t);
|
||||
return (c_, t_) -> retval;
|
||||
Value retval = lv.get(0).evalValue(c, t);
|
||||
return (ct, tt) -> retval;
|
||||
}
|
||||
catch (final ProcessedThrowStatement ret)
|
||||
catch (ProcessedThrowStatement ret)
|
||||
{
|
||||
if (lv.size() == 1)
|
||||
{
|
||||
@@ -100,7 +100,7 @@ public class ControlFlow
|
||||
{
|
||||
throw ret;
|
||||
}
|
||||
return (c_, t_) -> Value.NULL;
|
||||
return (ct, tt) -> Value.NULL;
|
||||
}
|
||||
if (lv.size() > 3 && lv.size() % 2 == 0)
|
||||
{
|
||||
@@ -109,10 +109,10 @@ public class ControlFlow
|
||||
|
||||
Value val = null; // This is always assigned at some point, just the compiler doesn't know
|
||||
|
||||
final LazyValue __ = c.getVariable("_");
|
||||
c.setVariable("_", (__c, __t) -> ret.data.reboundedTo("_"));
|
||||
final LazyValue _trace = c.getVariable("_trace");
|
||||
c.setVariable("_trace", (__c, __t) -> MapValue.wrap(Map.of(
|
||||
LazyValue defaultVal = c.getVariable("_");
|
||||
c.setVariable("_", (ct, tt) -> ret.data.reboundedTo("_"));
|
||||
LazyValue trace = c.getVariable("_trace");
|
||||
c.setVariable("_trace", (ct, tt) -> MapValue.wrap(Map.of(
|
||||
StringValue.of("stack"), ListValue.wrap(ret.stack.stream().map(f -> ListValue.of(
|
||||
StringValue.of(f.getModule().name()),
|
||||
StringValue.of(f.getString()),
|
||||
@@ -151,10 +151,10 @@ public class ControlFlow
|
||||
pointer += 2;
|
||||
}
|
||||
}
|
||||
c.setVariable("_", __);
|
||||
if (_trace != null)
|
||||
c.setVariable("_", defaultVal);
|
||||
if (trace != null)
|
||||
{
|
||||
c.setVariable("_trace", _trace);
|
||||
c.setVariable("_trace", trace);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -164,8 +164,8 @@ public class ControlFlow
|
||||
{
|
||||
throw ret;
|
||||
}
|
||||
final Value retval = val;
|
||||
return (c_, t_) -> retval;
|
||||
Value retval = val;
|
||||
return (ct, tt) -> retval;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -27,21 +27,21 @@ import java.util.stream.Collectors;
|
||||
|
||||
public class DataStructures
|
||||
{
|
||||
public static void apply(final Expression expression)
|
||||
public static void apply(Expression expression)
|
||||
{
|
||||
expression.addFunction("l", lv ->
|
||||
lv.size() == 1 && lv.get(0) instanceof final LazyListValue llv
|
||||
? ListValue.wrap(llv.unroll())
|
||||
: new ListValue.ListConstructorValue(lv));
|
||||
|
||||
expression.addFunction("join", (lv) ->
|
||||
expression.addFunction("join", lv ->
|
||||
{
|
||||
if (lv.size() < 2)
|
||||
{
|
||||
throw new InternalExpressionException("'join' takes at least 2 arguments");
|
||||
}
|
||||
final String delimiter = lv.get(0).getString();
|
||||
final List<Value> toJoin;
|
||||
String delimiter = lv.get(0).getString();
|
||||
List<Value> toJoin;
|
||||
if (lv.size() == 2 && lv.get(1) instanceof final LazyListValue llv)
|
||||
{
|
||||
toJoin = llv.unroll();
|
||||
@@ -57,10 +57,10 @@ public class DataStructures
|
||||
return new StringValue(toJoin.stream().map(Value::getString).collect(Collectors.joining(delimiter)));
|
||||
});
|
||||
|
||||
expression.addFunction("split", (lv) ->
|
||||
expression.addFunction("split", lv ->
|
||||
{
|
||||
final Value delimiter;
|
||||
final Value hwat;
|
||||
Value delimiter;
|
||||
Value hwat;
|
||||
if (lv.size() == 1)
|
||||
{
|
||||
hwat = lv.get(0);
|
||||
@@ -78,14 +78,14 @@ public class DataStructures
|
||||
return hwat.split(delimiter);
|
||||
});
|
||||
|
||||
expression.addFunction("slice", (lv) ->
|
||||
expression.addFunction("slice", lv ->
|
||||
{
|
||||
if (lv.size() != 2 && lv.size() != 3)
|
||||
{
|
||||
throw new InternalExpressionException("'slice' takes 2 or 3 arguments");
|
||||
}
|
||||
final Value hwat = lv.get(0);
|
||||
final long from = NumericValue.asNumber(lv.get(1)).getLong();
|
||||
Value hwat = lv.get(0);
|
||||
long from = NumericValue.asNumber(lv.get(1)).getLong();
|
||||
Long to = null;
|
||||
if (lv.size() == 3)
|
||||
{
|
||||
@@ -94,7 +94,7 @@ public class DataStructures
|
||||
return hwat.slice(from, to);
|
||||
});
|
||||
|
||||
expression.addFunction("sort", (lv) ->
|
||||
expression.addFunction("sort", lv ->
|
||||
{
|
||||
List<Value> toSort = lv;
|
||||
if (lv.size() == 1 && lv.get(0) instanceof final ListValue llv)
|
||||
@@ -108,44 +108,44 @@ public class DataStructures
|
||||
// needs lazy cause sort function is reused
|
||||
expression.addLazyFunction("sort_key", (c, t, lv) -> //get working with iterators
|
||||
{
|
||||
if (lv.size() == 0)
|
||||
if (lv.isEmpty())
|
||||
{
|
||||
throw new InternalExpressionException("First argument for 'sort_key' should be a List");
|
||||
}
|
||||
final Value v = lv.get(0).evalValue(c);
|
||||
Value v = lv.get(0).evalValue(c);
|
||||
if (!(v instanceof final ListValue list))
|
||||
{
|
||||
throw new InternalExpressionException("First argument for 'sort_key' should be a List");
|
||||
}
|
||||
final List<Value> toSort = new ArrayList<>(list.getItems());
|
||||
List<Value> toSort = new ArrayList<>(list.getItems());
|
||||
if (lv.size() == 1)
|
||||
{
|
||||
Collections.shuffle(toSort);
|
||||
final Value ret = ListValue.wrap(toSort);
|
||||
return (_c, _t) -> ret;
|
||||
Value ret = ListValue.wrap(toSort);
|
||||
return (ct, tt) -> ret;
|
||||
}
|
||||
final LazyValue sortKey = lv.get(1);
|
||||
LazyValue sortKey = lv.get(1);
|
||||
//scoping
|
||||
final LazyValue __ = c.getVariable("_");
|
||||
LazyValue defaultVal = c.getVariable("_");
|
||||
toSort.sort((v1, v2) -> {
|
||||
c.setVariable("_", (cc, tt) -> v1);
|
||||
final Value ev1 = sortKey.evalValue(c);
|
||||
Value ev1 = sortKey.evalValue(c);
|
||||
c.setVariable("_", (cc, tt) -> v2);
|
||||
final Value ev2 = sortKey.evalValue(c);
|
||||
Value ev2 = sortKey.evalValue(c);
|
||||
return ev1.compareTo(ev2);
|
||||
});
|
||||
//revering scope
|
||||
c.setVariable("_", __);
|
||||
final Value ret = ListValue.wrap(toSort);
|
||||
c.setVariable("_", defaultVal);
|
||||
Value ret = ListValue.wrap(toSort);
|
||||
return (cc, tt) -> ret;
|
||||
});
|
||||
|
||||
expression.addFunction("range", (lv) ->
|
||||
expression.addFunction("range", lv ->
|
||||
{
|
||||
NumericValue from = Value.ZERO;
|
||||
NumericValue to;
|
||||
NumericValue step = Value.ONE;
|
||||
final int argsize = lv.size();
|
||||
int argsize = lv.size();
|
||||
if (argsize == 0 || argsize > 3)
|
||||
{
|
||||
throw new InternalExpressionException("'range' accepts from 1 to 3 arguments, not " + argsize);
|
||||
@@ -192,7 +192,7 @@ public class DataStructures
|
||||
{
|
||||
if (container instanceof final LContainerValue lcv)
|
||||
{
|
||||
final ContainerValueInterface outerContainer = lcv.container();
|
||||
ContainerValueInterface outerContainer = lcv.container();
|
||||
if (outerContainer == null)
|
||||
{
|
||||
return LContainerValue.NULL_CONTAINER;
|
||||
@@ -211,23 +211,23 @@ public class DataStructures
|
||||
// lazy cause conditional typing - questionable
|
||||
expression.addLazyFunction("get", (c, t, lv) ->
|
||||
{
|
||||
if (lv.size() == 0)
|
||||
if (lv.isEmpty())
|
||||
{
|
||||
throw new InternalExpressionException("'get' requires parameters");
|
||||
}
|
||||
if (lv.size() == 1)
|
||||
{
|
||||
final Value v = lv.get(0).evalValue(c, Context.LVALUE);
|
||||
Value v = lv.get(0).evalValue(c, Context.LVALUE);
|
||||
if (!(v instanceof final LContainerValue lcv))
|
||||
{
|
||||
return LazyValue.NULL;
|
||||
}
|
||||
final ContainerValueInterface container = lcv.container();
|
||||
ContainerValueInterface container = lcv.container();
|
||||
if (container == null)
|
||||
{
|
||||
return LazyValue.NULL;
|
||||
}
|
||||
final Value ret = container.get(lcv.address());
|
||||
Value ret = container.get(lcv.address());
|
||||
return (cc, tt) -> ret;
|
||||
}
|
||||
Value container = lv.get(0).evalValue(c);
|
||||
@@ -243,30 +243,30 @@ public class DataStructures
|
||||
{
|
||||
return (cc, tt) -> Value.NULL;
|
||||
}
|
||||
final Value finalContainer = container;
|
||||
Value finalContainer = container;
|
||||
return (cc, tt) -> finalContainer;
|
||||
});
|
||||
|
||||
// same as `get`
|
||||
expression.addLazyFunction("has", (c, t, lv) ->
|
||||
{
|
||||
if (lv.size() == 0)
|
||||
if (lv.isEmpty())
|
||||
{
|
||||
throw new InternalExpressionException("'has' requires parameters");
|
||||
}
|
||||
if (lv.size() == 1)
|
||||
{
|
||||
final Value v = lv.get(0).evalValue(c, Context.LVALUE);
|
||||
Value v = lv.get(0).evalValue(c, Context.LVALUE);
|
||||
if (!(v instanceof final LContainerValue lcv))
|
||||
{
|
||||
return LazyValue.NULL;
|
||||
}
|
||||
final ContainerValueInterface container = lcv.container();
|
||||
ContainerValueInterface container = lcv.container();
|
||||
if (container == null)
|
||||
{
|
||||
return LazyValue.NULL;
|
||||
}
|
||||
final Value ret = BooleanValue.of(container.has(lcv.address()));
|
||||
Value ret = BooleanValue.of(container.has(lcv.address()));
|
||||
return (cc, tt) -> ret;
|
||||
}
|
||||
Value container = lv.get(0).evalValue(c);
|
||||
@@ -282,7 +282,7 @@ public class DataStructures
|
||||
{
|
||||
return LazyValue.NULL;
|
||||
}
|
||||
final Value ret = BooleanValue.of(cvi.has(lv.get(lv.size() - 1).evalValue(c)));
|
||||
Value ret = BooleanValue.of(cvi.has(lv.get(lv.size() - 1).evalValue(c)));
|
||||
return (cc, tt) -> ret;
|
||||
});
|
||||
|
||||
@@ -293,17 +293,17 @@ public class DataStructures
|
||||
{
|
||||
throw new InternalExpressionException("'put' takes at least three arguments, a container, address, and values to insert at that index");
|
||||
}
|
||||
final Value container = lv.get(0).evalValue(c, Context.LVALUE);
|
||||
Value container = lv.get(0).evalValue(c, Context.LVALUE);
|
||||
if (container instanceof final LContainerValue lcv)
|
||||
{
|
||||
final ContainerValueInterface internalContainer = lcv.container();
|
||||
ContainerValueInterface internalContainer = lcv.container();
|
||||
if (internalContainer == null)
|
||||
{
|
||||
return LazyValue.NULL;
|
||||
}
|
||||
final Value address = lcv.address();
|
||||
final Value what = lv.get(1).evalValue(c);
|
||||
final Value retVal = BooleanValue.of((lv.size() > 2)
|
||||
Value address = lcv.address();
|
||||
Value what = lv.get(1).evalValue(c);
|
||||
Value retVal = BooleanValue.of((lv.size() > 2)
|
||||
? internalContainer.put(address, what, lv.get(2).evalValue(c))
|
||||
: internalContainer.put(address, what));
|
||||
return (cc, tt) -> retVal;
|
||||
@@ -317,9 +317,9 @@ public class DataStructures
|
||||
{
|
||||
return LazyValue.NULL;
|
||||
}
|
||||
final Value where = lv.get(1).evalValue(c);
|
||||
final Value what = lv.get(2).evalValue(c);
|
||||
final Value retVal = BooleanValue.of((lv.size() > 3)
|
||||
Value where = lv.get(1).evalValue(c);
|
||||
Value what = lv.get(2).evalValue(c);
|
||||
Value retVal = BooleanValue.of((lv.size() > 3)
|
||||
? cvi.put(where, what, lv.get(3).evalValue(c))
|
||||
: cvi.put(where, what));
|
||||
return (cc, tt) -> retVal;
|
||||
@@ -328,23 +328,23 @@ public class DataStructures
|
||||
// same as `get`
|
||||
expression.addLazyFunction("delete", (c, t, lv) ->
|
||||
{
|
||||
if (lv.size() == 0)
|
||||
if (lv.isEmpty())
|
||||
{
|
||||
throw new InternalExpressionException("'delete' requires parameters");
|
||||
}
|
||||
if (lv.size() == 1)
|
||||
{
|
||||
final Value v = lv.get(0).evalValue(c, Context.LVALUE);
|
||||
Value v = lv.get(0).evalValue(c, Context.LVALUE);
|
||||
if (!(v instanceof final LContainerValue lcv))
|
||||
{
|
||||
return LazyValue.NULL;
|
||||
}
|
||||
final ContainerValueInterface container = lcv.container();
|
||||
ContainerValueInterface container = lcv.container();
|
||||
if (container == null)
|
||||
{
|
||||
return LazyValue.NULL;
|
||||
}
|
||||
final Value ret = BooleanValue.of(container.delete(lcv.address()));
|
||||
Value ret = BooleanValue.of(container.delete(lcv.address()));
|
||||
return (cc, tt) -> ret;
|
||||
}
|
||||
Value container = lv.get(0).evalValue(c);
|
||||
@@ -360,7 +360,7 @@ public class DataStructures
|
||||
{
|
||||
return LazyValue.NULL;
|
||||
}
|
||||
final Value ret = BooleanValue.of(cvi.delete(lv.get(lv.size() - 1).evalValue(c)));
|
||||
Value ret = BooleanValue.of(cvi.delete(lv.get(lv.size() - 1).evalValue(c)));
|
||||
return (cc, tt) -> ret;
|
||||
});
|
||||
|
||||
@@ -370,7 +370,7 @@ public class DataStructures
|
||||
{
|
||||
return StringValue.of(new String(Base64.getDecoder().decode(v.getString()), StandardCharsets.UTF_8));
|
||||
}
|
||||
catch (final IllegalArgumentException iae)
|
||||
catch (IllegalArgumentException iae)
|
||||
{
|
||||
throw new ThrowStatement("Invalid b64 string: " + v.getString(), Throwables.B64_ERROR);
|
||||
}
|
||||
@@ -382,7 +382,7 @@ public class DataStructures
|
||||
{
|
||||
return Auxiliary.GSON.fromJson(v.getString(), Value.class);
|
||||
}
|
||||
catch (final JsonParseException jpe)
|
||||
catch (JsonParseException jpe)
|
||||
{
|
||||
throw new ThrowStatement("Invalid json string: " + v.getString(), Throwables.JSON_ERROR);
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ import java.util.Locale;
|
||||
|
||||
public class Functions
|
||||
{
|
||||
public static void apply(final Expression expression) // public just to get the javadoc right
|
||||
public static void apply(Expression expression) // public just to get the javadoc right
|
||||
{
|
||||
// artificial construct to handle user defined functions and function definitions
|
||||
expression.addContextFunction("import", -1, (c, t, lv) ->
|
||||
@@ -45,28 +45,28 @@ public class Functions
|
||||
expression.addCustomFunction("call", new Fluff.AbstractLazyFunction(-1, "call")
|
||||
{
|
||||
@Override
|
||||
public LazyValue lazyEval(final Context c, final Context.Type t, final Expression expr, final Tokenizer.Token tok, final List<LazyValue> lv)
|
||||
public LazyValue lazyEval(Context c, Context.Type t, Expression expr, Tokenizer.Token tok, List<LazyValue> lv)
|
||||
{
|
||||
if (lv.size() == 0)
|
||||
if (lv.isEmpty())
|
||||
{
|
||||
throw new InternalExpressionException("'call' expects at least function name to call");
|
||||
}
|
||||
//lv.remove(lv.size()-1); // aint gonna cut it // maybe it will because of the eager eval changes
|
||||
if (t != Context.SIGNATURE) // just call the function
|
||||
{
|
||||
final List<Value> args = Fluff.AbstractFunction.unpackLazy(lv, c, Context.NONE);
|
||||
final FunctionArgument functionArgument = FunctionArgument.findIn(c, expression.module, args, 0, false, true);
|
||||
final FunctionValue fun = functionArgument.function;
|
||||
List<Value> args = Fluff.AbstractFunction.unpackLazy(lv, c, Context.NONE);
|
||||
FunctionArgument functionArgument = FunctionArgument.findIn(c, expression.module, args, 0, false, true);
|
||||
FunctionValue fun = functionArgument.function;
|
||||
return fun.callInContext(c, t, functionArgument.args);
|
||||
}
|
||||
// gimme signature
|
||||
final String name = lv.get(0).evalValue(c, Context.NONE).getString();
|
||||
final List<String> args = new ArrayList<>();
|
||||
final List<String> globals = new ArrayList<>();
|
||||
String name = lv.get(0).evalValue(c, Context.NONE).getString();
|
||||
List<String> args = new ArrayList<>();
|
||||
List<String> globals = new ArrayList<>();
|
||||
String varArgs = null;
|
||||
for (int i = 1; i < lv.size(); i++)
|
||||
{
|
||||
final Value v = lv.get(i).evalValue(c, Context.LOCALIZATION);
|
||||
Value v = lv.get(i).evalValue(c, Context.LOCALIZATION);
|
||||
if (!v.isBound())
|
||||
{
|
||||
throw new InternalExpressionException("Only variables can be used in function signature, not " + v.getString());
|
||||
@@ -91,7 +91,7 @@ public class Functions
|
||||
args.add(v.boundVariable);
|
||||
}
|
||||
}
|
||||
final Value retval = new FunctionSignatureValue(name, args, varArgs, globals);
|
||||
Value retval = new FunctionSignatureValue(name, args, varArgs, globals);
|
||||
return (cc, tt) -> retval;
|
||||
}
|
||||
|
||||
@@ -108,7 +108,7 @@ public class Functions
|
||||
}
|
||||
|
||||
@Override
|
||||
public Context.Type staticType(final Context.Type outerType)
|
||||
public Context.Type staticType(Context.Type outerType)
|
||||
{
|
||||
return outerType == Context.SIGNATURE ? Context.LOCALIZATION : Context.NONE;
|
||||
}
|
||||
@@ -130,19 +130,19 @@ public class Functions
|
||||
{
|
||||
if (type == Context.MAPDEF)
|
||||
{
|
||||
final Value result = ListValue.of(lv1.evalValue(c), lv2.evalValue(c));
|
||||
Value result = ListValue.of(lv1.evalValue(c), lv2.evalValue(c));
|
||||
return (cc, tt) -> result;
|
||||
}
|
||||
final Value v1 = lv1.evalValue(c, Context.SIGNATURE);
|
||||
Value v1 = lv1.evalValue(c, Context.SIGNATURE);
|
||||
if (!(v1 instanceof final FunctionSignatureValue sign))
|
||||
{
|
||||
throw new InternalExpressionException("'->' operator requires a function signature on the LHS");
|
||||
}
|
||||
final Value result = expression.createUserDefinedFunction(c, sign.identifier(), e, t, sign.arguments(), sign.varArgs(), sign.globals(), lv2);
|
||||
Value result = expression.createUserDefinedFunction(c, sign.identifier(), e, t, sign.arguments(), sign.varArgs(), sign.globals(), lv2);
|
||||
return (cc, tt) -> result;
|
||||
});
|
||||
|
||||
expression.addImpureFunction("return", (lv) -> {
|
||||
expression.addImpureFunction("return", lv -> {
|
||||
throw new ReturnStatement(lv.size() == 0 ? Value.NULL : lv.get(0));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -17,14 +17,14 @@ import java.util.List;
|
||||
|
||||
public class Loops
|
||||
{
|
||||
public static void apply(final Expression expression)
|
||||
public static void apply(Expression expression)
|
||||
{
|
||||
// condition and expression will get a bound '_i'
|
||||
// returns last successful expression or false
|
||||
// while(cond, limit, expr) => ??
|
||||
expression.addImpureFunction("break", lv ->
|
||||
{
|
||||
if (lv.size() == 0)
|
||||
if (lv.isEmpty())
|
||||
{
|
||||
throw new BreakStatement(null);
|
||||
}
|
||||
@@ -37,7 +37,7 @@ public class Loops
|
||||
|
||||
expression.addImpureFunction("continue", lv ->
|
||||
{
|
||||
if (lv.size() == 0)
|
||||
if (lv.isEmpty())
|
||||
{
|
||||
throw new ContinueStatement(null);
|
||||
}
|
||||
@@ -51,13 +51,13 @@ public class Loops
|
||||
// lazy
|
||||
expression.addLazyFunction("while", 3, (c, t, lv) ->
|
||||
{
|
||||
final long limit = NumericValue.asNumber(lv.get(1).evalValue(c)).getLong();
|
||||
final LazyValue condition = lv.get(0);
|
||||
final LazyValue expr = lv.get(2);
|
||||
long limit = NumericValue.asNumber(lv.get(1).evalValue(c)).getLong();
|
||||
LazyValue condition = lv.get(0);
|
||||
LazyValue expr = lv.get(2);
|
||||
long i = 0;
|
||||
Value lastOne = Value.NULL;
|
||||
//scoping
|
||||
final LazyValue _val = c.getVariable("_");
|
||||
LazyValue defaultVal = c.getVariable("_");
|
||||
c.setVariable("_", (cc, tt) -> new NumericValue(0).bindTo("_"));
|
||||
while (i < limit && condition.evalValue(c, Context.BOOLEAN).getBoolean())
|
||||
{
|
||||
@@ -65,7 +65,7 @@ public class Loops
|
||||
{
|
||||
lastOne = expr.evalValue(c, t);
|
||||
}
|
||||
catch (final BreakStatement | ContinueStatement stmt)
|
||||
catch (BreakStatement | ContinueStatement stmt)
|
||||
{
|
||||
if (stmt.retval != null)
|
||||
{
|
||||
@@ -77,33 +77,33 @@ public class Loops
|
||||
}
|
||||
}
|
||||
i++;
|
||||
final long seriously = i;
|
||||
long seriously = i;
|
||||
c.setVariable("_", (cc, tt) -> new NumericValue(seriously).bindTo("_"));
|
||||
}
|
||||
//revering scope
|
||||
c.setVariable("_", _val);
|
||||
final Value lastValueNoKidding = lastOne;
|
||||
c.setVariable("_", defaultVal);
|
||||
Value lastValueNoKidding = lastOne;
|
||||
return (cc, tt) -> lastValueNoKidding;
|
||||
});
|
||||
|
||||
// loop(Num, expr) => last_value
|
||||
// loop(Num, expr) => lastdefaultValue
|
||||
// expr receives bounded variable '_' indicating iteration
|
||||
expression.addLazyFunction("loop", 2, (c, t, lv) ->
|
||||
{
|
||||
final long limit = NumericValue.asNumber(lv.get(0).evalValue(c, Context.NONE)).getLong();
|
||||
long limit = NumericValue.asNumber(lv.get(0).evalValue(c, Context.NONE)).getLong();
|
||||
Value lastOne = Value.NULL;
|
||||
final LazyValue expr = lv.get(1);
|
||||
LazyValue expr = lv.get(1);
|
||||
//scoping
|
||||
final LazyValue _val = c.getVariable("_");
|
||||
LazyValue defaultVal = c.getVariable("_");
|
||||
for (long i = 0; i < limit; i++)
|
||||
{
|
||||
final long whyYouAsk = i;
|
||||
long whyYouAsk = i;
|
||||
c.setVariable("_", (cc, tt) -> new NumericValue(whyYouAsk).bindTo("_"));
|
||||
try
|
||||
{
|
||||
lastOne = expr.evalValue(c, t);
|
||||
}
|
||||
catch (final BreakStatement | ContinueStatement stmt)
|
||||
catch (BreakStatement | ContinueStatement stmt)
|
||||
{
|
||||
if (stmt.retval != null)
|
||||
{
|
||||
@@ -116,8 +116,8 @@ public class Loops
|
||||
}
|
||||
}
|
||||
//revering scope
|
||||
c.setVariable("_", _val);
|
||||
final Value trulyLastOne = lastOne;
|
||||
c.setVariable("_", defaultVal);
|
||||
Value trulyLastOne = lastOne;
|
||||
return (cc, tt) -> trulyLastOne;
|
||||
});
|
||||
|
||||
@@ -125,7 +125,7 @@ public class Loops
|
||||
// receives bounded variable '_' with the expression
|
||||
expression.addLazyFunction("map", 2, (c, t, lv) ->
|
||||
{
|
||||
final Value rval = lv.get(0).evalValue(c, Context.NONE);
|
||||
Value rval = lv.get(0).evalValue(c, Context.NONE);
|
||||
if (rval.isNull())
|
||||
{
|
||||
return ListValue.lazyEmpty();
|
||||
@@ -134,25 +134,25 @@ public class Loops
|
||||
{
|
||||
throw new InternalExpressionException("First argument of 'map' function should be a list or iterator");
|
||||
}
|
||||
final Iterator<Value> iterator = alv.iterator();
|
||||
final LazyValue expr = lv.get(1);
|
||||
Iterator<Value> iterator = alv.iterator();
|
||||
LazyValue expr = lv.get(1);
|
||||
//scoping
|
||||
final LazyValue _val = c.getVariable("_");
|
||||
final LazyValue _iter = c.getVariable("_i");
|
||||
final List<Value> result = new ArrayList<>();
|
||||
LazyValue defaultVal = c.getVariable("_");
|
||||
LazyValue iterVal = c.getVariable("_i");
|
||||
List<Value> result = new ArrayList<>();
|
||||
for (int i = 0; iterator.hasNext(); i++)
|
||||
{
|
||||
final Value next = iterator.next();
|
||||
final String var = next.boundVariable;
|
||||
Value next = iterator.next();
|
||||
String variable = next.boundVariable;
|
||||
next.bindTo("_");
|
||||
final int doYouReally = i;
|
||||
int doYouReally = i;
|
||||
c.setVariable("_", (cc, tt) -> next);
|
||||
c.setVariable("_i", (cc, tt) -> new NumericValue(doYouReally).bindTo("_i"));
|
||||
try
|
||||
{
|
||||
result.add(expr.evalValue(c, t));
|
||||
}
|
||||
catch (final BreakStatement | ContinueStatement stmt)
|
||||
catch (BreakStatement | ContinueStatement stmt)
|
||||
{
|
||||
if (stmt.retval != null)
|
||||
{
|
||||
@@ -160,17 +160,17 @@ public class Loops
|
||||
}
|
||||
if (stmt instanceof BreakStatement)
|
||||
{
|
||||
next.boundVariable = var;
|
||||
next.boundVariable = variable;
|
||||
break;
|
||||
}
|
||||
}
|
||||
next.boundVariable = var;
|
||||
next.boundVariable = variable;
|
||||
}
|
||||
((AbstractListValue) rval).fatality();
|
||||
final Value ret = ListValue.wrap(result);
|
||||
Value ret = ListValue.wrap(result);
|
||||
//revering scope
|
||||
c.setVariable("_", _val);
|
||||
c.setVariable("_i", _iter);
|
||||
c.setVariable("_", defaultVal);
|
||||
c.setVariable("_i", iterVal);
|
||||
return (cc, tt) -> ret;
|
||||
});
|
||||
|
||||
@@ -179,7 +179,7 @@ public class Loops
|
||||
// produces list of values for which the expression is true
|
||||
expression.addLazyFunction("filter", 2, (c, t, lv) ->
|
||||
{
|
||||
final Value rval = lv.get(0).evalValue(c, Context.NONE);
|
||||
Value rval = lv.get(0).evalValue(c, Context.NONE);
|
||||
if (rval.isNull())
|
||||
{
|
||||
return ListValue.lazyEmpty();
|
||||
@@ -188,18 +188,18 @@ public class Loops
|
||||
{
|
||||
throw new InternalExpressionException("First argument of 'filter' function should be a list or iterator");
|
||||
}
|
||||
final Iterator<Value> iterator = alv.iterator();
|
||||
final LazyValue expr = lv.get(1);
|
||||
Iterator<Value> iterator = alv.iterator();
|
||||
LazyValue expr = lv.get(1);
|
||||
//scoping
|
||||
final LazyValue _val = c.getVariable("_");
|
||||
final LazyValue _iter = c.getVariable("_i");
|
||||
final List<Value> result = new ArrayList<>();
|
||||
LazyValue defaultVal = c.getVariable("_");
|
||||
LazyValue iterVal = c.getVariable("_i");
|
||||
List<Value> result = new ArrayList<>();
|
||||
for (int i = 0; iterator.hasNext(); i++)
|
||||
{
|
||||
final Value next = iterator.next();
|
||||
final String var = next.boundVariable;
|
||||
Value next = iterator.next();
|
||||
String veriable = next.boundVariable;
|
||||
next.bindTo("_");
|
||||
final int seriously = i;
|
||||
int seriously = i;
|
||||
c.setVariable("_", (cc, tt) -> next);
|
||||
c.setVariable("_i", (cc, tt) -> new NumericValue(seriously).bindTo("_i"));
|
||||
try
|
||||
@@ -209,7 +209,7 @@ public class Loops
|
||||
result.add(next);
|
||||
}
|
||||
}
|
||||
catch (final BreakStatement | ContinueStatement stmt)
|
||||
catch (BreakStatement | ContinueStatement stmt)
|
||||
{
|
||||
if (stmt.retval != null && stmt.retval.getBoolean())
|
||||
{
|
||||
@@ -217,17 +217,17 @@ public class Loops
|
||||
}
|
||||
if (stmt instanceof BreakStatement)
|
||||
{
|
||||
next.boundVariable = var;
|
||||
next.boundVariable = veriable;
|
||||
break;
|
||||
}
|
||||
}
|
||||
next.boundVariable = var;
|
||||
next.boundVariable = veriable;
|
||||
}
|
||||
((AbstractListValue) rval).fatality();
|
||||
final Value ret = ListValue.wrap(result);
|
||||
Value ret = ListValue.wrap(result);
|
||||
//revering scope
|
||||
c.setVariable("_", _val);
|
||||
c.setVariable("_i", _iter);
|
||||
c.setVariable("_", defaultVal);
|
||||
c.setVariable("_i", iterVal);
|
||||
return (cc, tt) -> ret;
|
||||
});
|
||||
|
||||
@@ -236,7 +236,7 @@ public class Loops
|
||||
// returns first element on the list for which the expr is true
|
||||
expression.addLazyFunction("first", 2, (c, t, lv) ->
|
||||
{
|
||||
final Value rval = lv.get(0).evalValue(c, Context.NONE);
|
||||
Value rval = lv.get(0).evalValue(c, Context.NONE);
|
||||
if (rval.isNull())
|
||||
{
|
||||
return LazyValue.NULL;
|
||||
@@ -245,18 +245,18 @@ public class Loops
|
||||
{
|
||||
throw new InternalExpressionException("First argument of 'first' function should be a list or iterator");
|
||||
}
|
||||
final Iterator<Value> iterator = alv.iterator();
|
||||
final LazyValue expr = lv.get(1);
|
||||
Iterator<Value> iterator = alv.iterator();
|
||||
LazyValue expr = lv.get(1);
|
||||
//scoping
|
||||
final LazyValue _val = c.getVariable("_");
|
||||
final LazyValue _iter = c.getVariable("_i");
|
||||
LazyValue defaultVal = c.getVariable("_");
|
||||
LazyValue iterVal = c.getVariable("_i");
|
||||
Value result = Value.NULL;
|
||||
for (int i = 0; iterator.hasNext(); i++)
|
||||
{
|
||||
final Value next = iterator.next();
|
||||
final String var = next.boundVariable;
|
||||
Value next = iterator.next();
|
||||
String variable = next.boundVariable;
|
||||
next.bindTo("_");
|
||||
final int seriously = i;
|
||||
int seriously = i;
|
||||
c.setVariable("_", (cc, tt) -> next);
|
||||
c.setVariable("_i", (cc, tt) -> new NumericValue(seriously).bindTo("_i"));
|
||||
try
|
||||
@@ -264,27 +264,27 @@ public class Loops
|
||||
if (expr.evalValue(c, Context.BOOLEAN).getBoolean())
|
||||
{
|
||||
result = next;
|
||||
next.boundVariable = var;
|
||||
next.boundVariable = variable;
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (final BreakStatement stmt)
|
||||
catch (BreakStatement stmt)
|
||||
{
|
||||
result = stmt.retval == null ? next : stmt.retval;
|
||||
next.boundVariable = var;
|
||||
next.boundVariable = variable;
|
||||
break;
|
||||
}
|
||||
catch (final ContinueStatement ignored)
|
||||
catch (ContinueStatement ignored)
|
||||
{
|
||||
throw new InternalExpressionException("'continue' inside 'first' function has no sense");
|
||||
}
|
||||
next.boundVariable = var;
|
||||
next.boundVariable = variable;
|
||||
}
|
||||
//revering scope
|
||||
((AbstractListValue) rval).fatality();
|
||||
final Value whyWontYouTrustMeJava = result;
|
||||
c.setVariable("_", _val);
|
||||
c.setVariable("_i", _iter);
|
||||
Value whyWontYouTrustMeJava = result;
|
||||
c.setVariable("_", defaultVal);
|
||||
c.setVariable("_i", iterVal);
|
||||
return (cc, tt) -> whyWontYouTrustMeJava;
|
||||
});
|
||||
|
||||
@@ -293,7 +293,7 @@ public class Loops
|
||||
// returns true if expr is true for all items
|
||||
expression.addLazyFunction("all", 2, (c, t, lv) ->
|
||||
{
|
||||
final Value rval = lv.get(0).evalValue(c, Context.NONE);
|
||||
Value rval = lv.get(0).evalValue(c, Context.NONE);
|
||||
if (rval.isNull())
|
||||
{
|
||||
return LazyValue.TRUE;
|
||||
@@ -302,42 +302,42 @@ public class Loops
|
||||
{
|
||||
throw new InternalExpressionException("First argument of 'all' function should be a list or iterator");
|
||||
}
|
||||
final Iterator<Value> iterator = alv.iterator();
|
||||
final LazyValue expr = lv.get(1);
|
||||
Iterator<Value> iterator = alv.iterator();
|
||||
LazyValue expr = lv.get(1);
|
||||
//scoping
|
||||
final LazyValue _val = c.getVariable("_");
|
||||
final LazyValue _iter = c.getVariable("_i");
|
||||
LazyValue defaultVal = c.getVariable("_");
|
||||
LazyValue iterVal = c.getVariable("_i");
|
||||
LazyValue result = LazyValue.TRUE;
|
||||
for (int i = 0; iterator.hasNext(); i++)
|
||||
{
|
||||
final Value next = iterator.next();
|
||||
final String var = next.boundVariable;
|
||||
Value next = iterator.next();
|
||||
String variable = next.boundVariable;
|
||||
next.bindTo("_");
|
||||
final int seriously = i;
|
||||
int seriously = i;
|
||||
c.setVariable("_", (cc, tt) -> next);
|
||||
c.setVariable("_i", (cc, tt) -> new NumericValue(seriously).bindTo("_i"));
|
||||
if (!expr.evalValue(c, Context.BOOLEAN).getBoolean())
|
||||
{
|
||||
result = LazyValue.FALSE;
|
||||
next.boundVariable = var;
|
||||
next.boundVariable = variable;
|
||||
break;
|
||||
}
|
||||
next.boundVariable = var;
|
||||
next.boundVariable = variable;
|
||||
}
|
||||
//revering scope
|
||||
((AbstractListValue) rval).fatality();
|
||||
c.setVariable("_", _val);
|
||||
c.setVariable("_i", _iter);
|
||||
c.setVariable("_", defaultVal);
|
||||
c.setVariable("_i", iterVal);
|
||||
return result;
|
||||
});
|
||||
|
||||
// runs traditional for(init, condition, increment, body) tri-argument for loop with body in between
|
||||
expression.addLazyFunction("c_for", 4, (c, t, lv) ->
|
||||
{
|
||||
final LazyValue initial = lv.get(0);
|
||||
final LazyValue condition = lv.get(1);
|
||||
final LazyValue increment = lv.get(2);
|
||||
final LazyValue body = lv.get(3);
|
||||
LazyValue initial = lv.get(0);
|
||||
LazyValue condition = lv.get(1);
|
||||
LazyValue increment = lv.get(2);
|
||||
LazyValue body = lv.get(3);
|
||||
int iterations = 0;
|
||||
for (initial.evalValue(c, Context.VOID); condition.evalValue(c, Context.BOOLEAN).getBoolean(); increment.evalValue(c, Context.VOID))
|
||||
{
|
||||
@@ -345,16 +345,16 @@ public class Loops
|
||||
{
|
||||
body.evalValue(c, Context.VOID);
|
||||
}
|
||||
catch (final BreakStatement stmt)
|
||||
catch (BreakStatement stmt)
|
||||
{
|
||||
break;
|
||||
}
|
||||
catch (final ContinueStatement ignored)
|
||||
catch (ContinueStatement ignored)
|
||||
{
|
||||
}
|
||||
iterations++;
|
||||
}
|
||||
final int finalIterations = iterations;
|
||||
int finalIterations = iterations;
|
||||
return (cc, tt) -> new NumericValue(finalIterations);
|
||||
});
|
||||
|
||||
@@ -363,7 +363,7 @@ public class Loops
|
||||
// can be substituted for first and all, but first is more efficient and all doesn't require knowing list size
|
||||
expression.addLazyFunction("for", 2, (c, t, lv) ->
|
||||
{
|
||||
final Value rval = lv.get(0).evalValue(c, Context.NONE);
|
||||
Value rval = lv.get(0).evalValue(c, Context.NONE);
|
||||
if (rval.isNull())
|
||||
{
|
||||
return LazyValue.ZERO;
|
||||
@@ -372,18 +372,18 @@ public class Loops
|
||||
{
|
||||
throw new InternalExpressionException("First argument of 'for' function should be a list or iterator");
|
||||
}
|
||||
final Iterator<Value> iterator = alv.iterator();
|
||||
final LazyValue expr = lv.get(1);
|
||||
Iterator<Value> iterator = alv.iterator();
|
||||
LazyValue expr = lv.get(1);
|
||||
//scoping
|
||||
final LazyValue _val = c.getVariable("_");
|
||||
final LazyValue _ite = c.getVariable("_i");
|
||||
LazyValue defaultVal = c.getVariable("_");
|
||||
LazyValue iterVal = c.getVariable("_i");
|
||||
int successCount = 0;
|
||||
for (int i = 0; iterator.hasNext(); i++)
|
||||
{
|
||||
final Value next = iterator.next();
|
||||
final String var = next.boundVariable;
|
||||
Value next = iterator.next();
|
||||
String variable = next.boundVariable;
|
||||
next.bindTo("_");
|
||||
final int seriously = i;
|
||||
int seriously = i;
|
||||
c.setVariable("_", (cc, tt) -> next);
|
||||
c.setVariable("_i", (cc, tt) -> new NumericValue(seriously).bindTo("_i"));
|
||||
Value result = Value.FALSE;
|
||||
@@ -391,7 +391,7 @@ public class Loops
|
||||
{
|
||||
result = expr.evalValue(c, t);
|
||||
}
|
||||
catch (final BreakStatement | ContinueStatement stmt)
|
||||
catch (BreakStatement | ContinueStatement stmt)
|
||||
{
|
||||
if (stmt.retval != null)
|
||||
{
|
||||
@@ -399,7 +399,7 @@ public class Loops
|
||||
}
|
||||
if (stmt instanceof BreakStatement)
|
||||
{
|
||||
next.boundVariable = var;
|
||||
next.boundVariable = variable;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -407,13 +407,13 @@ public class Loops
|
||||
{
|
||||
successCount++;
|
||||
}
|
||||
next.boundVariable = var;
|
||||
next.boundVariable = variable;
|
||||
}
|
||||
//revering scope
|
||||
((AbstractListValue) rval).fatality();
|
||||
c.setVariable("_", _val);
|
||||
c.setVariable("_i", _ite);
|
||||
final long promiseWontChange = successCount;
|
||||
c.setVariable("_", defaultVal);
|
||||
c.setVariable("_i", iterVal);
|
||||
long promiseWontChange = successCount;
|
||||
return (cc, tt) -> new NumericValue(promiseWontChange);
|
||||
});
|
||||
|
||||
@@ -425,7 +425,7 @@ public class Loops
|
||||
expression.addLazyFunction("reduce", 3, (c, t, lv) ->
|
||||
{
|
||||
|
||||
final Value rval = lv.get(0).evalValue(c, Context.NONE);
|
||||
Value rval = lv.get(0).evalValue(c, Context.NONE);
|
||||
if (rval.isNull())
|
||||
{
|
||||
return ListValue.lazyEmpty();
|
||||
@@ -434,28 +434,28 @@ public class Loops
|
||||
{
|
||||
throw new InternalExpressionException("First argument of 'reduce' should be a list or iterator");
|
||||
}
|
||||
final LazyValue expr = lv.get(1);
|
||||
LazyValue expr = lv.get(1);
|
||||
Value acc = lv.get(2).evalValue(c, Context.NONE);
|
||||
final Iterator<Value> iterator = alv.iterator();
|
||||
Iterator<Value> iterator = alv.iterator();
|
||||
|
||||
if (!iterator.hasNext())
|
||||
{
|
||||
final Value seriouslyWontChange = acc;
|
||||
Value seriouslyWontChange = acc;
|
||||
return (cc, tt) -> seriouslyWontChange;
|
||||
}
|
||||
|
||||
//scoping
|
||||
final LazyValue _val = c.getVariable("_");
|
||||
final LazyValue _acc = c.getVariable("_a");
|
||||
final LazyValue _ite = c.getVariable("_i");
|
||||
LazyValue defaultVal = c.getVariable("_");
|
||||
LazyValue accumulatorVal = c.getVariable("_a");
|
||||
LazyValue iterVal = c.getVariable("_i");
|
||||
|
||||
for (int i = 0; iterator.hasNext(); i++)
|
||||
{
|
||||
final Value next = iterator.next();
|
||||
final String var = next.boundVariable;
|
||||
Value next = iterator.next();
|
||||
String variable = next.boundVariable;
|
||||
next.bindTo("_");
|
||||
final Value promiseWontChangeYou = acc;
|
||||
final int seriously = i;
|
||||
Value promiseWontChangeYou = acc;
|
||||
int seriously = i;
|
||||
c.setVariable("_a", (cc, tt) -> promiseWontChangeYou.bindTo("_a"));
|
||||
c.setVariable("_", (cc, tt) -> next);
|
||||
c.setVariable("_i", (cc, tt) -> new NumericValue(seriously).bindTo("_i"));
|
||||
@@ -463,7 +463,7 @@ public class Loops
|
||||
{
|
||||
acc = expr.evalValue(c, t);
|
||||
}
|
||||
catch (final BreakStatement | ContinueStatement stmt)
|
||||
catch (BreakStatement | ContinueStatement stmt)
|
||||
{
|
||||
if (stmt.retval != null)
|
||||
{
|
||||
@@ -471,19 +471,19 @@ public class Loops
|
||||
}
|
||||
if (stmt instanceof BreakStatement)
|
||||
{
|
||||
next.boundVariable = var;
|
||||
next.boundVariable = variable;
|
||||
break;
|
||||
}
|
||||
}
|
||||
next.boundVariable = var;
|
||||
next.boundVariable = variable;
|
||||
}
|
||||
//reverting scope
|
||||
((AbstractListValue) rval).fatality();
|
||||
c.setVariable("_a", _acc);
|
||||
c.setVariable("_", _val);
|
||||
c.setVariable("_i", _ite);
|
||||
c.setVariable("_a", accumulatorVal);
|
||||
c.setVariable("_", defaultVal);
|
||||
c.setVariable("_i", iterVal);
|
||||
|
||||
final Value hopeItsEnoughPromise = acc;
|
||||
Value hopeItsEnoughPromise = acc;
|
||||
return (cc, tt) -> hopeItsEnoughPromise;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -39,17 +39,17 @@ public class Operators
|
||||
put("nextop;", 1);
|
||||
}};
|
||||
|
||||
public static void apply(final Expression expression)
|
||||
public static void apply(Expression expression)
|
||||
{
|
||||
expression.addBinaryOperator("+", precedence.get("addition+-"), true, Value::add);
|
||||
expression.addFunction("sum", lv -> {
|
||||
final int size = lv.size();
|
||||
int size = lv.size();
|
||||
if (size == 0)
|
||||
{
|
||||
return Value.NULL;
|
||||
}
|
||||
Value accumulator = lv.get(0);
|
||||
for (final Value v : lv.subList(1, size))
|
||||
for (Value v : lv.subList(1, size))
|
||||
{
|
||||
accumulator = accumulator.add(v);
|
||||
}
|
||||
@@ -59,13 +59,13 @@ public class Operators
|
||||
|
||||
expression.addBinaryOperator("-", precedence.get("addition+-"), true, Value::subtract);
|
||||
expression.addFunction("difference", lv -> {
|
||||
final int size = lv.size();
|
||||
int size = lv.size();
|
||||
if (size == 0)
|
||||
{
|
||||
return Value.NULL;
|
||||
}
|
||||
Value accumulator = lv.get(0);
|
||||
for (final Value v : lv.subList(1, size))
|
||||
for (Value v : lv.subList(1, size))
|
||||
{
|
||||
accumulator = accumulator.subtract(v);
|
||||
}
|
||||
@@ -75,13 +75,13 @@ public class Operators
|
||||
|
||||
expression.addBinaryOperator("*", precedence.get("multiplication*/%"), true, Value::multiply);
|
||||
expression.addFunction("product", lv -> {
|
||||
final int size = lv.size();
|
||||
int size = lv.size();
|
||||
if (size == 0)
|
||||
{
|
||||
return Value.NULL;
|
||||
}
|
||||
Value accumulator = lv.get(0);
|
||||
for (final Value v : lv.subList(1, size))
|
||||
for (Value v : lv.subList(1, size))
|
||||
{
|
||||
accumulator = accumulator.multiply(v);
|
||||
}
|
||||
@@ -91,13 +91,13 @@ public class Operators
|
||||
|
||||
expression.addBinaryOperator("/", precedence.get("multiplication*/%"), true, Value::divide);
|
||||
expression.addFunction("quotient", lv -> {
|
||||
final int size = lv.size();
|
||||
int size = lv.size();
|
||||
if (size == 0)
|
||||
{
|
||||
return Value.NULL;
|
||||
}
|
||||
Value accumulator = lv.get(0);
|
||||
for (final Value v : lv.subList(1, size))
|
||||
for (Value v : lv.subList(1, size))
|
||||
{
|
||||
accumulator = accumulator.divide(v);
|
||||
}
|
||||
@@ -111,13 +111,13 @@ public class Operators
|
||||
new NumericValue(java.lang.Math.pow(NumericValue.asNumber(v1).getDouble(), NumericValue.asNumber(v2).getDouble())));
|
||||
|
||||
expression.addFunction("bitwise_and", lv -> {
|
||||
final int size = lv.size();
|
||||
int size = lv.size();
|
||||
if (size == 0)
|
||||
{
|
||||
return Value.NULL;
|
||||
}
|
||||
long accumulator = NumericValue.asNumber(lv.get(0)).getLong();
|
||||
for (final Value v : lv.subList(1, size))
|
||||
for (Value v : lv.subList(1, size))
|
||||
{
|
||||
accumulator = accumulator & NumericValue.asNumber(v).getLong();
|
||||
}
|
||||
@@ -125,13 +125,13 @@ public class Operators
|
||||
});
|
||||
|
||||
expression.addFunction("bitwise_xor", lv -> {
|
||||
final int size = lv.size();
|
||||
int size = lv.size();
|
||||
if (size == 0)
|
||||
{
|
||||
return Value.NULL;
|
||||
}
|
||||
long accumulator = NumericValue.asNumber(lv.get(0)).getLong();
|
||||
for (final Value v : lv.subList(1, size))
|
||||
for (Value v : lv.subList(1, size))
|
||||
{
|
||||
accumulator = accumulator ^ NumericValue.asNumber(v).getLong();
|
||||
}
|
||||
@@ -139,13 +139,13 @@ public class Operators
|
||||
});
|
||||
|
||||
expression.addFunction("bitwise_or", lv -> {
|
||||
final int size = lv.size();
|
||||
int size = lv.size();
|
||||
if (size == 0)
|
||||
{
|
||||
return Value.NULL;
|
||||
}
|
||||
long accumulator = NumericValue.asNumber(lv.get(0)).getLong();
|
||||
for (final Value v : lv.subList(1, size))
|
||||
for (Value v : lv.subList(1, size))
|
||||
{
|
||||
accumulator = accumulator | NumericValue.asNumber(v).getLong();
|
||||
}
|
||||
@@ -155,22 +155,22 @@ public class Operators
|
||||
// lazy cause RHS is only conditional
|
||||
expression.addLazyBinaryOperator("&&", precedence.get("and&&"), false, true, t -> Context.Type.BOOLEAN, (c, t, lv1, lv2) ->
|
||||
{ // todo check how is optimizations going
|
||||
final Value v1 = lv1.evalValue(c, Context.BOOLEAN);
|
||||
Value v1 = lv1.evalValue(c, Context.BOOLEAN);
|
||||
return v1.getBoolean() ? lv2 : ((cc, tt) -> v1);
|
||||
});
|
||||
|
||||
expression.addPureLazyFunction("and", -1, t -> Context.Type.BOOLEAN, (c, t, lv) -> {
|
||||
final int last = lv.size() - 1;
|
||||
int last = lv.size() - 1;
|
||||
if (last == -1)
|
||||
{
|
||||
return LazyValue.TRUE;
|
||||
}
|
||||
for (final LazyValue l : lv.subList(0, last))
|
||||
for (LazyValue l : lv.subList(0, last))
|
||||
{
|
||||
final Value val = l.evalValue(c, Context.Type.BOOLEAN);
|
||||
Value val = l.evalValue(c, Context.Type.BOOLEAN);
|
||||
if (val instanceof final FunctionUnpackedArgumentsValue fuav)
|
||||
{
|
||||
for (final Value it : fuav)
|
||||
for (Value it : fuav)
|
||||
{
|
||||
if (!it.getBoolean())
|
||||
{
|
||||
@@ -193,22 +193,22 @@ public class Operators
|
||||
// lazy cause RHS is only conditional
|
||||
expression.addLazyBinaryOperator("||", precedence.get("or||"), false, true, t -> Context.Type.BOOLEAN, (c, t, lv1, lv2) ->
|
||||
{
|
||||
final Value v1 = lv1.evalValue(c, Context.BOOLEAN);
|
||||
Value v1 = lv1.evalValue(c, Context.BOOLEAN);
|
||||
return v1.getBoolean() ? ((cc, tt) -> v1) : lv2;
|
||||
});
|
||||
|
||||
expression.addPureLazyFunction("or", -1, t -> Context.Type.BOOLEAN, (c, t, lv) -> {
|
||||
final int last = lv.size() - 1;
|
||||
int last = lv.size() - 1;
|
||||
if (last == -1)
|
||||
{
|
||||
return LazyValue.FALSE;
|
||||
}
|
||||
for (final LazyValue l : lv.subList(0, last))
|
||||
for (LazyValue l : lv.subList(0, last))
|
||||
{
|
||||
final Value val = l.evalValue(c, Context.Type.BOOLEAN);
|
||||
Value val = l.evalValue(c, Context.Type.BOOLEAN);
|
||||
if (val instanceof final FunctionUnpackedArgumentsValue fuav)
|
||||
{
|
||||
for (final Value it : fuav)
|
||||
for (Value it : fuav)
|
||||
{
|
||||
if (it.getBoolean())
|
||||
{
|
||||
@@ -233,13 +233,13 @@ public class Operators
|
||||
expression.addBinaryOperator(">", precedence.get("compare>=><=<"), false, (v1, v2) ->
|
||||
BooleanValue.of(v1.compareTo(v2) > 0));
|
||||
expression.addFunction("decreasing", lv -> {
|
||||
final int size = lv.size();
|
||||
int size = lv.size();
|
||||
if (size < 2)
|
||||
{
|
||||
return Value.TRUE;
|
||||
}
|
||||
Value prev = lv.get(0);
|
||||
for (final Value next : lv.subList(1, size))
|
||||
for (Value next : lv.subList(1, size))
|
||||
{
|
||||
if (prev.compareTo(next) <= 0)
|
||||
{
|
||||
@@ -254,13 +254,13 @@ public class Operators
|
||||
expression.addBinaryOperator(">=", precedence.get("compare>=><=<"), false, (v1, v2) ->
|
||||
BooleanValue.of(v1.compareTo(v2) >= 0));
|
||||
expression.addFunction("nonincreasing", lv -> {
|
||||
final int size = lv.size();
|
||||
int size = lv.size();
|
||||
if (size < 2)
|
||||
{
|
||||
return Value.TRUE;
|
||||
}
|
||||
Value prev = lv.get(0);
|
||||
for (final Value next : lv.subList(1, size))
|
||||
for (Value next : lv.subList(1, size))
|
||||
{
|
||||
if (prev.compareTo(next) < 0)
|
||||
{
|
||||
@@ -275,13 +275,13 @@ public class Operators
|
||||
expression.addBinaryOperator("<", precedence.get("compare>=><=<"), false, (v1, v2) ->
|
||||
BooleanValue.of(v1.compareTo(v2) < 0));
|
||||
expression.addFunction("increasing", lv -> {
|
||||
final int size = lv.size();
|
||||
int size = lv.size();
|
||||
if (size < 2)
|
||||
{
|
||||
return Value.TRUE;
|
||||
}
|
||||
Value prev = lv.get(0);
|
||||
for (final Value next : lv.subList(1, size))
|
||||
for (Value next : lv.subList(1, size))
|
||||
{
|
||||
if (prev.compareTo(next) >= 0)
|
||||
{
|
||||
@@ -296,13 +296,13 @@ public class Operators
|
||||
expression.addBinaryOperator("<=", precedence.get("compare>=><=<"), false, (v1, v2) ->
|
||||
BooleanValue.of(v1.compareTo(v2) <= 0));
|
||||
expression.addFunction("nondecreasing", lv -> {
|
||||
final int size = lv.size();
|
||||
int size = lv.size();
|
||||
if (size < 2)
|
||||
{
|
||||
return Value.TRUE;
|
||||
}
|
||||
Value prev = lv.get(0);
|
||||
for (final Value next : lv.subList(1, size))
|
||||
for (Value next : lv.subList(1, size))
|
||||
{
|
||||
if (prev.compareTo(next) > 0)
|
||||
{
|
||||
@@ -316,21 +316,21 @@ public class Operators
|
||||
expression.addMathematicalBinaryIntFunction("bitwise_shift_left", (num, amount) -> num << amount);
|
||||
expression.addMathematicalBinaryIntFunction("bitwise_shift_right", (num, amount) -> num >> amount);
|
||||
expression.addMathematicalBinaryIntFunction("bitwise_roll_left", (num, num2) -> {
|
||||
final long amount = num2 % 64;
|
||||
final long amountToRoll = 64 - amount;
|
||||
final long rolledBits = ((-1L) >> amountToRoll) << amountToRoll;
|
||||
final long rolledAmount = (num & rolledBits) >> amountToRoll;
|
||||
long amount = num2 % 64;
|
||||
long amountToRoll = 64 - amount;
|
||||
long rolledBits = ((-1L) >> amountToRoll) << amountToRoll;
|
||||
long rolledAmount = (num & rolledBits) >> amountToRoll;
|
||||
return num << amount | rolledAmount;
|
||||
});
|
||||
expression.addMathematicalBinaryIntFunction("bitwise_roll_right", (num, num2) -> {
|
||||
final long amount = num2 % 64;
|
||||
final long amountToRoll = 64 - amount;
|
||||
final long rolledBits = ((-1L) << amountToRoll) >> amountToRoll;
|
||||
final long rolledAmount = (num & rolledBits) << amountToRoll;
|
||||
long amount = num2 % 64;
|
||||
long amountToRoll = 64 - amount;
|
||||
long rolledBits = ((-1L) << amountToRoll) >> amountToRoll;
|
||||
long rolledAmount = (num & rolledBits) << amountToRoll;
|
||||
return num >> amount | rolledAmount;
|
||||
});
|
||||
expression.addMathematicalUnaryIntFunction("bitwise_not", d -> {
|
||||
final long num = (long) d;
|
||||
long num = (long) d;
|
||||
return ~num;
|
||||
});
|
||||
expression.addMathematicalUnaryIntFunction("bitwise_popcount", d -> (long) Long.bitCount((long)d));
|
||||
@@ -340,13 +340,13 @@ public class Operators
|
||||
expression.addBinaryOperator("==", precedence.get("equal==!="), false, (v1, v2) ->
|
||||
v1.equals(v2) ? Value.TRUE : Value.FALSE);
|
||||
expression.addFunction("equal", lv -> {
|
||||
final int size = lv.size();
|
||||
int size = lv.size();
|
||||
if (size < 2)
|
||||
{
|
||||
return Value.TRUE;
|
||||
}
|
||||
Value prev = lv.get(0);
|
||||
for (final Value next : lv.subList(1, size))
|
||||
for (Value next : lv.subList(1, size))
|
||||
{
|
||||
if (!prev.equals(next))
|
||||
{
|
||||
@@ -360,7 +360,7 @@ public class Operators
|
||||
expression.addBinaryOperator("!=", precedence.get("equal==!="), false, (v1, v2) ->
|
||||
v1.equals(v2) ? Value.FALSE : Value.TRUE);
|
||||
expression.addFunction("unique", lv -> {
|
||||
final int size = lv.size();
|
||||
int size = lv.size();
|
||||
if (size < 2)
|
||||
{
|
||||
return Value.TRUE;
|
||||
@@ -368,7 +368,7 @@ public class Operators
|
||||
// need to order them so same obejects will be next to each other.
|
||||
lv.sort(Comparator.comparingInt(Value::hashCode));
|
||||
Value prev = lv.get(0);
|
||||
for (final Value next : lv.subList(1, size))
|
||||
for (Value next : lv.subList(1, size))
|
||||
{
|
||||
if (prev.equals(next))
|
||||
{
|
||||
@@ -383,12 +383,12 @@ public class Operators
|
||||
// lazy cause of assignment which is non-trivial
|
||||
expression.addLazyBinaryOperator("=", precedence.get("assign=<>"), false, false, t -> Context.Type.LVALUE, (c, t, lv1, lv2) ->
|
||||
{
|
||||
final Value v1 = lv1.evalValue(c, Context.LVALUE);
|
||||
final Value v2 = lv2.evalValue(c);
|
||||
Value v1 = lv1.evalValue(c, Context.LVALUE);
|
||||
Value v2 = lv2.evalValue(c);
|
||||
if (v1 instanceof final ListValue.ListConstructorValue lcv && v2 instanceof final ListValue list)
|
||||
{
|
||||
final List<Value> ll = lcv.getItems();
|
||||
final List<Value> rl = list.getItems();
|
||||
List<Value> ll = lcv.getItems();
|
||||
List<Value> rl = list.getItems();
|
||||
if (ll.size() < rl.size())
|
||||
{
|
||||
throw new InternalExpressionException("Too many values to unpack");
|
||||
@@ -397,28 +397,28 @@ public class Operators
|
||||
{
|
||||
throw new InternalExpressionException("Too few values to unpack");
|
||||
}
|
||||
for (final Value v : ll)
|
||||
for (Value v : ll)
|
||||
{
|
||||
v.assertAssignable();
|
||||
}
|
||||
final Iterator<Value> li = ll.iterator();
|
||||
final Iterator<Value> ri = rl.iterator();
|
||||
Iterator<Value> li = ll.iterator();
|
||||
Iterator<Value> ri = rl.iterator();
|
||||
while (li.hasNext())
|
||||
{
|
||||
final String lname = li.next().getVariable();
|
||||
final Value vval = ri.next().reboundedTo(lname);
|
||||
String lname = li.next().getVariable();
|
||||
Value vval = ri.next().reboundedTo(lname);
|
||||
expression.setAnyVariable(c, lname, (cc, tt) -> vval);
|
||||
}
|
||||
return (cc, tt) -> Value.TRUE;
|
||||
}
|
||||
if (v1 instanceof final LContainerValue lcv)
|
||||
{
|
||||
final ContainerValueInterface container = lcv.container();
|
||||
ContainerValueInterface container = lcv.container();
|
||||
if (container == null)
|
||||
{
|
||||
return (cc, tt) -> Value.NULL;
|
||||
}
|
||||
final Value address = lcv.address();
|
||||
Value address = lcv.address();
|
||||
if (!(container.put(address, v2)))
|
||||
{
|
||||
return (cc, tt) -> Value.NULL;
|
||||
@@ -426,9 +426,9 @@ public class Operators
|
||||
return (cc, tt) -> v2;
|
||||
}
|
||||
v1.assertAssignable();
|
||||
final String varname = v1.getVariable();
|
||||
final Value copy = v2.reboundedTo(varname);
|
||||
final LazyValue boundedLHS = (cc, tt) -> copy;
|
||||
String varname = v1.getVariable();
|
||||
Value copy = v2.reboundedTo(varname);
|
||||
LazyValue boundedLHS = (cc, tt) -> copy;
|
||||
expression.setAnyVariable(c, varname, boundedLHS);
|
||||
return boundedLHS;
|
||||
});
|
||||
@@ -436,12 +436,12 @@ public class Operators
|
||||
// lazy due to assignment
|
||||
expression.addLazyBinaryOperator("+=", precedence.get("assign=<>"), false, false, t -> Context.Type.LVALUE, (c, t, lv1, lv2) ->
|
||||
{
|
||||
final Value v1 = lv1.evalValue(c, Context.LVALUE);
|
||||
final Value v2 = lv2.evalValue(c);
|
||||
Value v1 = lv1.evalValue(c, Context.LVALUE);
|
||||
Value v2 = lv2.evalValue(c);
|
||||
if (v1 instanceof final ListValue.ListConstructorValue lcv && v2 instanceof final ListValue list)
|
||||
{
|
||||
final List<Value> ll = lcv.getItems();
|
||||
final List<Value> rl = list.getItems();
|
||||
List<Value> ll = lcv.getItems();
|
||||
List<Value> rl = list.getItems();
|
||||
if (ll.size() < rl.size())
|
||||
{
|
||||
throw new InternalExpressionException("Too many values to unpack");
|
||||
@@ -450,30 +450,30 @@ public class Operators
|
||||
{
|
||||
throw new InternalExpressionException("Too few values to unpack");
|
||||
}
|
||||
for (final Value v : ll)
|
||||
for (Value v : ll)
|
||||
{
|
||||
v.assertAssignable();
|
||||
}
|
||||
final Iterator<Value> li = ll.iterator();
|
||||
final Iterator<Value> ri = rl.iterator();
|
||||
Iterator<Value> li = ll.iterator();
|
||||
Iterator<Value> ri = rl.iterator();
|
||||
while (li.hasNext())
|
||||
{
|
||||
final Value lval = li.next();
|
||||
final String lname = lval.getVariable();
|
||||
final Value result = lval.add(ri.next()).bindTo(lname);
|
||||
Value lval = li.next();
|
||||
String lname = lval.getVariable();
|
||||
Value result = lval.add(ri.next()).bindTo(lname);
|
||||
expression.setAnyVariable(c, lname, (cc, tt) -> result);
|
||||
}
|
||||
return (cc, tt) -> Value.TRUE;
|
||||
}
|
||||
if (v1 instanceof final LContainerValue lcv)
|
||||
{
|
||||
final ContainerValueInterface cvi = lcv.container();
|
||||
ContainerValueInterface cvi = lcv.container();
|
||||
if (cvi == null)
|
||||
{
|
||||
throw new InternalExpressionException("Failed to resolve left hand side of the += operation");
|
||||
}
|
||||
final Value key = lcv.address();
|
||||
final Value value = cvi.get(key);
|
||||
Value key = lcv.address();
|
||||
Value value = cvi.get(key);
|
||||
if (value instanceof ListValue || value instanceof MapValue)
|
||||
{
|
||||
((AbstractListValue) value).append(v2);
|
||||
@@ -481,14 +481,14 @@ public class Operators
|
||||
}
|
||||
else
|
||||
{
|
||||
final Value res = value.add(v2);
|
||||
Value res = value.add(v2);
|
||||
cvi.put(key, res);
|
||||
return (cc, tt) -> res;
|
||||
}
|
||||
}
|
||||
v1.assertAssignable();
|
||||
final String varname = v1.getVariable();
|
||||
final LazyValue boundedLHS;
|
||||
String varname = v1.getVariable();
|
||||
LazyValue boundedLHS;
|
||||
if (v1 instanceof ListValue || v1 instanceof MapValue)
|
||||
{
|
||||
((AbstractListValue) v1).append(v2);
|
||||
@@ -496,7 +496,7 @@ public class Operators
|
||||
}
|
||||
else
|
||||
{
|
||||
final Value result = v1.add(v2).bindTo(varname);
|
||||
Value result = v1.add(v2).bindTo(varname);
|
||||
boundedLHS = (cc, tt) -> result;
|
||||
}
|
||||
expression.setAnyVariable(c, varname, boundedLHS);
|
||||
@@ -507,8 +507,8 @@ public class Operators
|
||||
{
|
||||
if (v1 instanceof final ListValue.ListConstructorValue lcv1 && v2 instanceof final ListValue.ListConstructorValue lcv2)
|
||||
{
|
||||
final List<Value> ll = lcv1.getItems();
|
||||
final List<Value> rl = lcv2.getItems();
|
||||
List<Value> ll = lcv1.getItems();
|
||||
List<Value> rl = lcv2.getItems();
|
||||
if (ll.size() < rl.size())
|
||||
{
|
||||
throw new InternalExpressionException("Too many values to unpack");
|
||||
@@ -517,22 +517,22 @@ public class Operators
|
||||
{
|
||||
throw new InternalExpressionException("Too few values to unpack");
|
||||
}
|
||||
for (final Value v : ll)
|
||||
for (Value v : ll)
|
||||
{
|
||||
v.assertAssignable();
|
||||
}
|
||||
for (final Value v : rl)
|
||||
for (Value v : rl)
|
||||
{
|
||||
v.assertAssignable();
|
||||
}
|
||||
final Iterator<Value> li = ll.iterator();
|
||||
final Iterator<Value> ri = rl.iterator();
|
||||
Iterator<Value> li = ll.iterator();
|
||||
Iterator<Value> ri = rl.iterator();
|
||||
while (li.hasNext())
|
||||
{
|
||||
final Value lval = li.next();
|
||||
final Value rval = ri.next();
|
||||
final String lname = lval.getVariable();
|
||||
final String rname = rval.getVariable();
|
||||
Value lval = li.next();
|
||||
Value rval = ri.next();
|
||||
String lname = lval.getVariable();
|
||||
String rname = rval.getVariable();
|
||||
lval.reboundedTo(rname);
|
||||
rval.reboundedTo(lname);
|
||||
expression.setAnyVariable(c, lname, (cc, tt) -> rval);
|
||||
@@ -542,10 +542,10 @@ public class Operators
|
||||
}
|
||||
v1.assertAssignable();
|
||||
v2.assertAssignable();
|
||||
final String lvalvar = v1.getVariable();
|
||||
final String rvalvar = v2.getVariable();
|
||||
final Value lval = v2.reboundedTo(lvalvar);
|
||||
final Value rval = v1.reboundedTo(rvalvar);
|
||||
String lvalvar = v1.getVariable();
|
||||
String rvalvar = v2.getVariable();
|
||||
Value lval = v2.reboundedTo(lvalvar);
|
||||
Value rval = v1.reboundedTo(rvalvar);
|
||||
expression.setAnyVariable(c, lvalvar, (cc, tt) -> lval);
|
||||
expression.setAnyVariable(c, rvalvar, (cc, tt) -> rval);
|
||||
return lval;
|
||||
@@ -571,7 +571,7 @@ public class Operators
|
||||
{
|
||||
throw new InternalExpressionException("Unable to unpack a non-list");
|
||||
}
|
||||
final FunctionUnpackedArgumentsValue fuaval = new FunctionUnpackedArgumentsValue(alv.unpack());
|
||||
FunctionUnpackedArgumentsValue fuaval = new FunctionUnpackedArgumentsValue(alv.unpack());
|
||||
return (cc, tt) -> fuaval;
|
||||
});
|
||||
|
||||
|
||||
@@ -13,7 +13,6 @@ import carpet.script.value.MapValue;
|
||||
import carpet.script.value.NumericValue;
|
||||
import carpet.script.value.StringValue;
|
||||
import carpet.script.value.Value;
|
||||
import org.apache.commons.lang3.text.WordUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
@@ -32,7 +31,7 @@ public class Sys
|
||||
// %[argument_index$][flags][width][.precision][t]conversion
|
||||
private static final Pattern formatPattern = Pattern.compile("%(\\d+\\$)?([-#+ 0,(<]*)?(\\d+)?(\\.\\d+)?([tT])?([a-zA-Z%])");
|
||||
|
||||
public static void apply(final Expression expression)
|
||||
public static void apply(Expression expression)
|
||||
{
|
||||
expression.addUnaryFunction("hash_code", v -> new NumericValue(v.hashCode()));
|
||||
|
||||
@@ -40,10 +39,10 @@ public class Sys
|
||||
|
||||
expression.addTypedContextFunction("bool", 1, Context.BOOLEAN, (c, t, lv) ->
|
||||
{
|
||||
final Value v = lv.get(0);
|
||||
Value v = lv.get(0);
|
||||
if (v instanceof StringValue)
|
||||
{
|
||||
final String str = v.getString().toLowerCase(Locale.ROOT);
|
||||
String str = v.getString().toLowerCase(Locale.ROOT);
|
||||
if ("false".equals(str) || "null".equals(str))
|
||||
{
|
||||
return Value.FALSE;
|
||||
@@ -66,7 +65,7 @@ public class Sys
|
||||
{
|
||||
return new NumericValue(v.getString());
|
||||
}
|
||||
catch (final NumberFormatException format)
|
||||
catch (NumberFormatException format)
|
||||
{
|
||||
return Value.NULL;
|
||||
}
|
||||
@@ -74,11 +73,11 @@ public class Sys
|
||||
|
||||
expression.addFunction("str", lv ->
|
||||
{
|
||||
if (lv.size() == 0)
|
||||
if (lv.isEmpty())
|
||||
{
|
||||
throw new InternalExpressionException("'str' requires at least one argument");
|
||||
}
|
||||
final String format = lv.get(0).getString();
|
||||
String format = lv.get(0).getString();
|
||||
if (lv.size() == 1)
|
||||
{
|
||||
return new StringValue(format);
|
||||
@@ -89,8 +88,8 @@ public class Sys
|
||||
lv = list.getItems();
|
||||
argIndex = 0;
|
||||
}
|
||||
final List<Object> args = new ArrayList<>();
|
||||
final Matcher m = formatPattern.matcher(format);
|
||||
List<Object> args = new ArrayList<>();
|
||||
Matcher m = formatPattern.matcher(format);
|
||||
|
||||
for (int i = 0, len = format.length(); i < len; )
|
||||
{
|
||||
@@ -100,7 +99,7 @@ public class Sys
|
||||
// of the format specifier is either fixed text or contains
|
||||
// an invalid format string.
|
||||
// [[scarpet]] but we skip it and let the String.format fail
|
||||
final char fmt = m.group(6).toLowerCase().charAt(0);
|
||||
char fmt = m.group(6).toLowerCase().charAt(0);
|
||||
if (fmt == 's')
|
||||
{
|
||||
if (argIndex >= lv.size())
|
||||
@@ -137,11 +136,7 @@ public class Sys
|
||||
args.add(lv.get(argIndex).getBoolean());
|
||||
argIndex++;
|
||||
}
|
||||
else if (fmt == '%')
|
||||
{
|
||||
//skip /%%
|
||||
}
|
||||
else
|
||||
else if (fmt != '%')
|
||||
{
|
||||
throw new InternalExpressionException("Format not supported: " + m.group(6));
|
||||
}
|
||||
@@ -160,7 +155,7 @@ public class Sys
|
||||
{
|
||||
return new StringValue(String.format(Locale.ROOT, format, args.toArray()));
|
||||
}
|
||||
catch (final IllegalFormatException ife)
|
||||
catch (IllegalFormatException ife)
|
||||
{
|
||||
throw new InternalExpressionException("Illegal string format: " + ife.getMessage());
|
||||
}
|
||||
@@ -170,16 +165,16 @@ public class Sys
|
||||
|
||||
expression.addUnaryFunction("upper", v -> new StringValue(v.getString().toUpperCase(Locale.ROOT)));
|
||||
|
||||
expression.addUnaryFunction("title", v -> new StringValue(WordUtils.capitalizeFully(v.getString())));
|
||||
expression.addUnaryFunction("title", v -> new StringValue(titleCase(v.getString())));
|
||||
|
||||
expression.addFunction("replace", (lv) ->
|
||||
expression.addFunction("replace", lv ->
|
||||
{
|
||||
if (lv.size() != 3 && lv.size() != 2)
|
||||
{
|
||||
throw new InternalExpressionException("'replace' expects string to read, pattern regex, and optional replacement string");
|
||||
}
|
||||
final String data = lv.get(0).getString();
|
||||
final String regex = lv.get(1).getString();
|
||||
String data = lv.get(0).getString();
|
||||
String regex = lv.get(1).getString();
|
||||
String replacement = "";
|
||||
if (lv.size() == 3)
|
||||
{
|
||||
@@ -189,20 +184,20 @@ public class Sys
|
||||
{
|
||||
return new StringValue(data.replaceAll(regex, replacement));
|
||||
}
|
||||
catch (final PatternSyntaxException pse)
|
||||
catch (PatternSyntaxException pse)
|
||||
{
|
||||
throw new InternalExpressionException("Incorrect pattern for 'replace': " + pse.getMessage());
|
||||
}
|
||||
});
|
||||
|
||||
expression.addFunction("replace_first", (lv) ->
|
||||
expression.addFunction("replace_first", lv ->
|
||||
{
|
||||
if (lv.size() != 3 && lv.size() != 2)
|
||||
{
|
||||
throw new InternalExpressionException("'replace_first' expects string to read, pattern regex, and optional replacement string");
|
||||
}
|
||||
final String data = lv.get(0).getString();
|
||||
final String regex = lv.get(1).getString();
|
||||
String data = lv.get(0).getString();
|
||||
String regex = lv.get(1).getString();
|
||||
String replacement = "";
|
||||
if (lv.size() == 3)
|
||||
{
|
||||
@@ -215,7 +210,7 @@ public class Sys
|
||||
expression.addUnaryFunction("length", v -> new NumericValue(v.length()));
|
||||
expression.addContextFunction("rand", -1, (c, t, lv) ->
|
||||
{
|
||||
final int argsize = lv.size();
|
||||
int argsize = lv.size();
|
||||
Random randomizer = Sys.randomizer;
|
||||
if (argsize != 1 && argsize != 2)
|
||||
{
|
||||
@@ -225,24 +220,24 @@ public class Sys
|
||||
{
|
||||
randomizer = c.host.getRandom(NumericValue.asNumber(lv.get(1)).getLong());
|
||||
}
|
||||
final Value argument = lv.get(0);
|
||||
Value argument = lv.get(0);
|
||||
if (argument instanceof final ListValue listValue)
|
||||
{
|
||||
final List<Value> list = listValue.getItems();
|
||||
List<Value> list = listValue.getItems();
|
||||
return list.get(randomizer.nextInt(list.size()));
|
||||
}
|
||||
final double value = NumericValue.asNumber(argument).getDouble() * randomizer.nextDouble();
|
||||
double value = NumericValue.asNumber(argument).getDouble() * randomizer.nextDouble();
|
||||
return t == Context.BOOLEAN ? BooleanValue.of(value >= 1.0D) : new NumericValue(value);
|
||||
});
|
||||
expression.addContextFunction("reset_seed", 1, (c, t, lv) -> {
|
||||
final boolean gotIt = c.host.resetRandom(NumericValue.asNumber(lv.get(0)).getLong());
|
||||
boolean gotIt = c.host.resetRandom(NumericValue.asNumber(lv.get(0)).getLong());
|
||||
return BooleanValue.of(gotIt);
|
||||
});
|
||||
|
||||
expression.addFunction("perlin", lv ->
|
||||
{
|
||||
final PerlinNoiseSampler sampler;
|
||||
final Value x;
|
||||
PerlinNoiseSampler sampler;
|
||||
Value x;
|
||||
Value y;
|
||||
Value z;
|
||||
|
||||
@@ -258,7 +253,7 @@ public class Sys
|
||||
sampler = PerlinNoiseSampler.instance;
|
||||
y = Value.NULL;
|
||||
z = Value.NULL;
|
||||
if (lv.size() == 0)
|
||||
if (lv.isEmpty())
|
||||
{
|
||||
throw new InternalExpressionException("'perlin' requires at least one dimension to sample from");
|
||||
}
|
||||
@@ -273,7 +268,7 @@ public class Sys
|
||||
}
|
||||
}
|
||||
|
||||
final double result;
|
||||
double result;
|
||||
|
||||
if (z.isNull())
|
||||
{
|
||||
@@ -293,9 +288,9 @@ public class Sys
|
||||
|
||||
expression.addFunction("simplex", lv ->
|
||||
{
|
||||
final SimplexNoiseSampler sampler;
|
||||
final Value x;
|
||||
final Value y;
|
||||
SimplexNoiseSampler sampler;
|
||||
Value x;
|
||||
Value y;
|
||||
Value z;
|
||||
|
||||
if (lv.size() >= 4)
|
||||
@@ -320,7 +315,7 @@ public class Sys
|
||||
z = NumericValue.asNumber(lv.get(2));
|
||||
}
|
||||
}
|
||||
final double result;
|
||||
double result;
|
||||
|
||||
if (z.isNull())
|
||||
{
|
||||
@@ -336,7 +331,7 @@ public class Sys
|
||||
return new NumericValue(result);
|
||||
});
|
||||
|
||||
expression.addUnaryFunction("print", (v) ->
|
||||
expression.addUnaryFunction("print", v ->
|
||||
{
|
||||
System.out.println(v.getString());
|
||||
return v; // pass through for variables
|
||||
@@ -351,14 +346,14 @@ public class Sys
|
||||
expression.addFunction("convert_date", lv ->
|
||||
{
|
||||
int argsize = lv.size();
|
||||
if (lv.size() == 0)
|
||||
if (lv.isEmpty())
|
||||
{
|
||||
throw new InternalExpressionException("'convert_date' requires at least one parameter");
|
||||
}
|
||||
final Value value = lv.get(0);
|
||||
Value value = lv.get(0);
|
||||
if (argsize == 1 && !(value instanceof ListValue))
|
||||
{
|
||||
final Calendar cal = new GregorianCalendar(Locale.ROOT);
|
||||
Calendar cal = new GregorianCalendar(Locale.ROOT);
|
||||
cal.setTimeInMillis(NumericValue.asNumber(value, "timestamp").getLong());
|
||||
int weekday = cal.get(Calendar.DAY_OF_WEEK) - 1;
|
||||
if (weekday == 0)
|
||||
@@ -382,7 +377,7 @@ public class Sys
|
||||
lv = list.getItems();
|
||||
argsize = lv.size();
|
||||
}
|
||||
final Calendar cal = new GregorianCalendar(0, 0, 0, 0, 0, 0);
|
||||
Calendar cal = new GregorianCalendar(0, Calendar.JANUARY, 1, 0, 0, 0);
|
||||
|
||||
if (argsize == 3)
|
||||
{
|
||||
@@ -413,15 +408,15 @@ public class Sys
|
||||
// lazy cause evaluates expression multiple times
|
||||
expression.addLazyFunction("profile_expr", 1, (c, t, lv) ->
|
||||
{
|
||||
final LazyValue lazy = lv.get(0);
|
||||
final long end = System.nanoTime() + 50000000L;
|
||||
LazyValue lazy = lv.get(0);
|
||||
long end = System.nanoTime() + 50000000L;
|
||||
long it = 0;
|
||||
while (System.nanoTime() < end)
|
||||
{
|
||||
lazy.evalValue(c);
|
||||
it++;
|
||||
}
|
||||
final Value res = new NumericValue(it);
|
||||
Value res = new NumericValue(it);
|
||||
return (cc, tt) -> res;
|
||||
});
|
||||
|
||||
@@ -430,14 +425,14 @@ public class Sys
|
||||
|
||||
expression.addContextFunction("undef", 1, (c, t, lv) ->
|
||||
{
|
||||
final Value remove = lv.get(0);
|
||||
Value remove = lv.get(0);
|
||||
if (remove instanceof FunctionValue)
|
||||
{
|
||||
c.host.delFunction(expression.module, remove.getString());
|
||||
return Value.NULL;
|
||||
}
|
||||
String varname = remove.getString();
|
||||
final boolean isPrefix = varname.endsWith("*");
|
||||
boolean isPrefix = varname.endsWith("*");
|
||||
if (isPrefix)
|
||||
{
|
||||
varname = varname.replaceAll("\\*+$", "");
|
||||
@@ -472,11 +467,11 @@ public class Sys
|
||||
//deprecate
|
||||
expression.addContextFunction("vars", 1, (c, t, lv) ->
|
||||
{
|
||||
final String prefix = lv.get(0).getString();
|
||||
final List<Value> values = new ArrayList<>();
|
||||
String prefix = lv.get(0).getString();
|
||||
List<Value> values = new ArrayList<>();
|
||||
if (prefix.startsWith("global"))
|
||||
{
|
||||
c.host.globalVariableNames(expression.module, (s) -> s.startsWith(prefix)).forEach(s -> values.add(new StringValue(s)));
|
||||
c.host.globalVariableNames(expression.module, s -> s.startsWith(prefix)).forEach(s -> values.add(new StringValue(s)));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -488,23 +483,43 @@ public class Sys
|
||||
// lazy cause default expression may not be executed if not needed
|
||||
expression.addLazyFunction("system_variable_get", (c, t, lv) ->
|
||||
{
|
||||
if (lv.size() == 0)
|
||||
if (lv.isEmpty())
|
||||
{
|
||||
throw new InternalExpressionException("'system_variable_get' expects at least a key to be fetched");
|
||||
}
|
||||
final Value key = lv.get(0).evalValue(c);
|
||||
Value key = lv.get(0).evalValue(c);
|
||||
if (lv.size() > 1)
|
||||
{
|
||||
c.host.scriptServer().systemGlobals.computeIfAbsent(key, k -> lv.get(1).evalValue(c));
|
||||
}
|
||||
final Value res = c.host.scriptServer().systemGlobals.get(key);
|
||||
Value res = c.host.scriptServer().systemGlobals.get(key);
|
||||
return res == null ? LazyValue.NULL : ((cc, tt) -> res);
|
||||
});
|
||||
|
||||
expression.addContextFunction("system_variable_set", 2, (c, t, lv) ->
|
||||
{
|
||||
final Value res = c.host.scriptServer().systemGlobals.put(lv.get(0), lv.get(1));
|
||||
Value res = c.host.scriptServer().systemGlobals.put(lv.get(0), lv.get(1));
|
||||
return res == null ? Value.NULL : res;
|
||||
});
|
||||
}
|
||||
|
||||
public static String titleCase(String str) {
|
||||
if (str.isEmpty()) {
|
||||
return str;
|
||||
}
|
||||
str = str.toLowerCase();
|
||||
char[] buffer = str.toCharArray();
|
||||
boolean capitalizeNext = true;
|
||||
for (int i = 0; i < buffer.length; i++) {
|
||||
char ch = buffer[i];
|
||||
if (Character.isWhitespace(ch)) {
|
||||
capitalizeNext = true;
|
||||
} else if (capitalizeNext) {
|
||||
buffer[i] = Character.toTitleCase(ch);
|
||||
capitalizeNext = false;
|
||||
}
|
||||
}
|
||||
return new String(buffer);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -11,16 +11,16 @@ import carpet.script.value.Value;
|
||||
|
||||
public class Threading
|
||||
{
|
||||
public static void apply(final Expression expression)
|
||||
public static void apply(Expression expression)
|
||||
{
|
||||
expression.addFunctionWithDelegation("task", -1, false, false, (c, t, expr, tok, lv) ->
|
||||
{
|
||||
if (lv.size() == 0)
|
||||
if (lv.isEmpty())
|
||||
{
|
||||
throw new InternalExpressionException("'task' requires at least function to call as a parameter");
|
||||
}
|
||||
final FunctionArgument functionArgument = FunctionArgument.findIn(c, expression.module, lv, 0, false, true);
|
||||
final ThreadValue thread = new ThreadValue(Value.NULL, functionArgument.function, expr, tok, c, functionArgument.checkedArgs());
|
||||
FunctionArgument functionArgument = FunctionArgument.findIn(c, expression.module, lv, 0, false, true);
|
||||
ThreadValue thread = new ThreadValue(Value.NULL, functionArgument.function, expr, tok, c, functionArgument.checkedArgs());
|
||||
Thread.yield();
|
||||
return thread;
|
||||
});
|
||||
@@ -31,18 +31,18 @@ public class Threading
|
||||
{
|
||||
throw new InternalExpressionException("'task' requires at least function to call as a parameter");
|
||||
}
|
||||
final Value queue = lv.get(0);
|
||||
final FunctionArgument functionArgument = FunctionArgument.findIn(c, expression.module, lv, 1, false, true);
|
||||
final ThreadValue thread = new ThreadValue(queue, functionArgument.function, expr, tok, c, functionArgument.checkedArgs());
|
||||
Value queue = lv.get(0);
|
||||
FunctionArgument functionArgument = FunctionArgument.findIn(c, expression.module, lv, 1, false, true);
|
||||
ThreadValue thread = new ThreadValue(queue, functionArgument.function, expr, tok, c, functionArgument.checkedArgs());
|
||||
Thread.yield();
|
||||
return thread;
|
||||
});
|
||||
|
||||
|
||||
expression.addContextFunction("task_count", -1, (c, t, lv) ->
|
||||
(lv.size() > 0) ? new NumericValue(c.host.taskCount(lv.get(0))) : new NumericValue(c.host.taskCount()));
|
||||
(!lv.isEmpty()) ? new NumericValue(c.host.taskCount(lv.get(0))) : new NumericValue(c.host.taskCount()));
|
||||
|
||||
expression.addUnaryFunction("task_value", (v) ->
|
||||
expression.addUnaryFunction("task_value", v ->
|
||||
{
|
||||
if (!(v instanceof final ThreadValue tv))
|
||||
{
|
||||
@@ -51,7 +51,7 @@ public class Threading
|
||||
return tv.getValue();
|
||||
});
|
||||
|
||||
expression.addUnaryFunction("task_join", (v) ->
|
||||
expression.addUnaryFunction("task_join", v ->
|
||||
{
|
||||
if (!(v instanceof final ThreadValue tv))
|
||||
{
|
||||
@@ -61,13 +61,12 @@ public class Threading
|
||||
});
|
||||
|
||||
expression.addLazyFunction("task_dock", 1, (c, t, lv) ->
|
||||
{
|
||||
// pass through placeholder
|
||||
// implmenetation should dock the task on the main thread.
|
||||
return lv.get(0);
|
||||
});
|
||||
lv.get(0)
|
||||
);
|
||||
|
||||
expression.addUnaryFunction("task_completed", (v) ->
|
||||
expression.addUnaryFunction("task_completed", v ->
|
||||
{
|
||||
if (!(v instanceof final ThreadValue tv))
|
||||
{
|
||||
@@ -79,7 +78,7 @@ public class Threading
|
||||
// lazy cause expr is evaluated in the same type
|
||||
expression.addLazyFunction("synchronize", (c, t, lv) ->
|
||||
{
|
||||
if (lv.size() == 0)
|
||||
if (lv.isEmpty())
|
||||
{
|
||||
throw new InternalExpressionException("'synchronize' require at least an expression to synchronize");
|
||||
}
|
||||
@@ -92,15 +91,15 @@ public class Threading
|
||||
}
|
||||
synchronized (c.host.getLock(lockValue))
|
||||
{
|
||||
final Value ret = lv.get(ind).evalValue(c, t);
|
||||
return (_c, _t) -> ret;
|
||||
Value ret = lv.get(ind).evalValue(c, t);
|
||||
return (ct, tt) -> ret;
|
||||
}
|
||||
});
|
||||
|
||||
// lazy since exception expression is very conditional
|
||||
expression.addLazyFunction("sleep", (c, t, lv) ->
|
||||
{
|
||||
final long time = lv.isEmpty() ? 0L : NumericValue.asNumber(lv.get(0).evalValue(c)).getLong();
|
||||
long time = lv.isEmpty() ? 0L : NumericValue.asNumber(lv.get(0).evalValue(c)).getLong();
|
||||
boolean interrupted = false;
|
||||
try
|
||||
{
|
||||
@@ -114,7 +113,7 @@ public class Threading
|
||||
}
|
||||
Thread.yield();
|
||||
}
|
||||
catch (final InterruptedException ignored)
|
||||
catch (InterruptedException ignored)
|
||||
{
|
||||
interrupted = true;
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ public class AppStoreManager
|
||||
*/
|
||||
private static String scarpetRepoLink = "https://api.github.com/repos/gnembon/scarpet/contents/programs/";
|
||||
|
||||
public static void setScarpetRepoLink(@Nullable final String link)
|
||||
public static void setScarpetRepoLink(@Nullable String link)
|
||||
{
|
||||
APP_STORE_ROOT = AppStoreManager.StoreNode.folder(null, "");
|
||||
scarpetRepoLink = link;
|
||||
@@ -66,23 +66,24 @@ public class AppStoreManager
|
||||
public static class StoreNode
|
||||
{
|
||||
public String name;
|
||||
@Nullable
|
||||
public StoreNode parent;
|
||||
public Map<String, StoreNode> children;
|
||||
public boolean sealed;
|
||||
public String value;
|
||||
|
||||
public static StoreNode folder(final StoreNode parent, final String name)
|
||||
public static StoreNode folder(@Nullable StoreNode parent, String name)
|
||||
{
|
||||
final StoreNode node = new StoreNode(parent, name);
|
||||
StoreNode node = new StoreNode(parent, name);
|
||||
node.children = new HashMap<>();
|
||||
node.value = null;
|
||||
node.sealed = false;
|
||||
return node;
|
||||
}
|
||||
|
||||
public static StoreNode scriptFile(final StoreNode parent, final String name, final String value)
|
||||
public static StoreNode scriptFile(StoreNode parent, String name, String value)
|
||||
{
|
||||
final StoreNode node = new StoreNode(parent, name);
|
||||
StoreNode node = new StoreNode(parent, name);
|
||||
node.children = null;
|
||||
node.value = value;
|
||||
node.sealed = true;
|
||||
@@ -109,7 +110,7 @@ public class AppStoreManager
|
||||
return this == APP_STORE_ROOT ? new StringBuilder() : parent.createPrePath().append(pathElement());
|
||||
}
|
||||
|
||||
private StoreNode(final StoreNode parent, final String name)
|
||||
private StoreNode(@Nullable StoreNode parent, String name)
|
||||
{
|
||||
this.parent = parent;
|
||||
this.name = name;
|
||||
@@ -127,43 +128,40 @@ public class AppStoreManager
|
||||
throw new IOException("Accessing scarpet app repo is disabled");
|
||||
}
|
||||
|
||||
final String queryPath = scarpetRepoLink + getPath();
|
||||
final String response;
|
||||
String queryPath = scarpetRepoLink + getPath();
|
||||
String response;
|
||||
try
|
||||
{
|
||||
response = IOUtils.toString(new URL(queryPath), StandardCharsets.UTF_8);
|
||||
}
|
||||
catch (final IOException e)
|
||||
catch (IOException e)
|
||||
{
|
||||
// Not sealing to allow retrying
|
||||
throw new IOException("Problems fetching " + queryPath, e);
|
||||
}
|
||||
final JsonArray files = JsonParser.parseString(response).getAsJsonArray();
|
||||
for (final JsonElement je : files)
|
||||
JsonArray files = JsonParser.parseString(response).getAsJsonArray();
|
||||
for (JsonElement je : files)
|
||||
{
|
||||
final JsonObject jo = je.getAsJsonObject();
|
||||
final String name = jo.get("name").getAsString();
|
||||
JsonObject jo = je.getAsJsonObject();
|
||||
String elementName = jo.get("name").getAsString();
|
||||
if (jo.get("type").getAsString().equals("dir"))
|
||||
{
|
||||
children.put(name, folder(this, name));
|
||||
children.put(elementName, folder(this, elementName));
|
||||
}
|
||||
else// if (name.matches("(\\w+\\.scl?)"))
|
||||
{
|
||||
final String value = jo.get("download_url").getAsString();
|
||||
children.put(name, scriptFile(this, name, value));
|
||||
String url = jo.get("download_url").getAsString();
|
||||
children.put(elementName, scriptFile(this, elementName, url));
|
||||
}
|
||||
}
|
||||
sealed = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if doing down the directory structire cannot continue since the matching element is either a leaf or
|
||||
* Returns true if doing down the directory structure cannot continue since the matching element is either a leaf or
|
||||
* a string not matching of any node.
|
||||
*
|
||||
* @param pathElement
|
||||
* @return
|
||||
*/
|
||||
public boolean cannotContinueFor(final String pathElement) throws IOException
|
||||
public boolean cannotContinueFor(String pathElement) throws IOException
|
||||
{
|
||||
if (isLeaf())
|
||||
{
|
||||
@@ -180,14 +178,13 @@ public class AppStoreManager
|
||||
return name.endsWith(".sc") ? Collections.singletonList(getPath()) : Collections.emptyList();
|
||||
}
|
||||
fillChildren();
|
||||
final String prefix = getPath();
|
||||
String prefix = getPath();
|
||||
return children.values().stream().
|
||||
filter(n -> (!n.isLeaf() || n.name.endsWith(".sc"))).
|
||||
map(s -> prefix + s.pathElement().replaceAll("/$", "")).
|
||||
collect(Collectors.toList());
|
||||
map(s -> prefix + s.pathElement().replaceAll("/$", "")).toList();
|
||||
}
|
||||
|
||||
public StoreNode drillDown(final String pathElement) throws IOException
|
||||
public StoreNode drillDown(String pathElement) throws IOException
|
||||
{
|
||||
if (isLeaf())
|
||||
{
|
||||
@@ -201,9 +198,9 @@ public class AppStoreManager
|
||||
return children.get(pathElement);
|
||||
}
|
||||
|
||||
public String getValue(final String file) throws IOException
|
||||
public String getValue(String file) throws IOException
|
||||
{
|
||||
final StoreNode leaf = drillDown(file);
|
||||
StoreNode leaf = drillDown(file);
|
||||
if (!leaf.isLeaf())
|
||||
{
|
||||
throw new IOException(file + " is not a file");
|
||||
@@ -220,11 +217,11 @@ public class AppStoreManager
|
||||
* @param currentPath The path down which we want to search for files
|
||||
* @return A pair of the current valid path, as well as the set of all the file/directory names at the end of that path
|
||||
*/
|
||||
public static List<String> suggestionsFromPath(final String currentPath) throws IOException
|
||||
public static List<String> suggestionsFromPath(String currentPath) throws IOException
|
||||
{
|
||||
final String[] path = currentPath.split("/");
|
||||
String[] path = currentPath.split("/");
|
||||
StoreNode appKiosk = APP_STORE_ROOT;
|
||||
for (final String pathElement : path)
|
||||
for (String pathElement : path)
|
||||
{
|
||||
if (appKiosk.cannotContinueFor(pathElement))
|
||||
{
|
||||
@@ -232,13 +229,10 @@ public class AppStoreManager
|
||||
}
|
||||
appKiosk = appKiosk.children.get(pathElement);
|
||||
}
|
||||
final List<String> filteredSuggestions = appKiosk.createPathSuggestions().stream().filter(s -> s.startsWith(currentPath)).collect(Collectors.toList());
|
||||
if (filteredSuggestions.size() == 1)
|
||||
List<String> filteredSuggestions = appKiosk.createPathSuggestions().stream().filter(s -> s.startsWith(currentPath)).toList();
|
||||
if (filteredSuggestions.size() == 1 && !appKiosk.isLeaf())
|
||||
{
|
||||
if (!appKiosk.isLeaf())
|
||||
{
|
||||
return suggestionsFromPath(filteredSuggestions.get(0)); // Start suggesting directory contents
|
||||
}
|
||||
return suggestionsFromPath(filteredSuggestions.get(0)); // Start suggesting directory contents
|
||||
}
|
||||
return filteredSuggestions;
|
||||
}
|
||||
@@ -251,20 +245,20 @@ public class AppStoreManager
|
||||
* @return {@code 1} if we succesfully saved the script, {@code 0} otherwise
|
||||
*/
|
||||
|
||||
public static int downloadScript(final CommandSourceStack source, final String path)
|
||||
public static int downloadScript(CommandSourceStack source, String path)
|
||||
{
|
||||
final AppInfo nodeInfo = getFileNode(path);
|
||||
AppInfo nodeInfo = getFileNode(path);
|
||||
return downloadScript(source, path, nodeInfo, false);
|
||||
}
|
||||
|
||||
private static int downloadScript(final CommandSourceStack source, final String path, final AppInfo nodeInfo, final boolean useTrash)
|
||||
private static int downloadScript(CommandSourceStack source, String path, AppInfo nodeInfo, boolean useTrash)
|
||||
{
|
||||
final String code;
|
||||
String code;
|
||||
try
|
||||
{
|
||||
code = IOUtils.toString(new URL(nodeInfo.url()), StandardCharsets.UTF_8);
|
||||
}
|
||||
catch (final IOException e)
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new CommandRuntimeException(Carpet.Messenger_compose("rb Failed to obtain app file content: " + e.getMessage()));
|
||||
}
|
||||
@@ -272,7 +266,7 @@ public class AppStoreManager
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
final boolean success = Vanilla.MinecraftServer_getScriptServer(source.getServer()).addScriptHost(source, nodeInfo.name().replaceFirst("\\.sc$", ""), null, true, false, false, nodeInfo.source());
|
||||
boolean success = Vanilla.MinecraftServer_getScriptServer(source.getServer()).addScriptHost(source, nodeInfo.name().replaceFirst("\\.sc$", ""), null, true, false, false, nodeInfo.source());
|
||||
return success ? 1 : 0;
|
||||
}
|
||||
|
||||
@@ -282,35 +276,35 @@ public class AppStoreManager
|
||||
* @param appPath The user inputted path to the scarpet script
|
||||
* @return Pair of app file name and content
|
||||
*/
|
||||
public static AppInfo getFileNode(final String appPath)
|
||||
public static AppInfo getFileNode(String appPath)
|
||||
{
|
||||
return getFileNodeFrom(APP_STORE_ROOT, appPath);
|
||||
}
|
||||
|
||||
public static AppInfo getFileNodeFrom(final StoreNode start, final String appPath)
|
||||
public static AppInfo getFileNodeFrom(StoreNode start, String appPath)
|
||||
{
|
||||
final String[] path = appPath.split("/");
|
||||
String[] path = appPath.split("/");
|
||||
StoreNode appKiosk = start;
|
||||
try
|
||||
{
|
||||
for (final String pathElement : Arrays.copyOfRange(path, 0, path.length - 1))
|
||||
for (String pathElement : Arrays.copyOfRange(path, 0, path.length - 1))
|
||||
{
|
||||
appKiosk = appKiosk.drillDown(pathElement);
|
||||
}
|
||||
final String appName = path[path.length - 1];
|
||||
String appName = path[path.length - 1];
|
||||
appKiosk.getValue(appName);
|
||||
return new AppInfo(appName, appKiosk.getValue(appName), appKiosk);
|
||||
}
|
||||
catch (final IOException e)
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new CommandRuntimeException(Carpet.Messenger_compose("rb '" + appPath + "' is not a valid path to a scarpet app: " + e.getMessage()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static boolean saveScriptToFile(final CommandSourceStack source, final String path, final String appFileName, final String code, final boolean globalSavePath, final boolean useTrash)
|
||||
public static boolean saveScriptToFile(CommandSourceStack source, String path, String appFileName, String code, boolean globalSavePath, boolean useTrash)
|
||||
{
|
||||
final Path scriptLocation;
|
||||
Path scriptLocation;
|
||||
if (globalSavePath && !source.getServer().isDedicatedServer()) // never happens, this is always called with globalSavePath being false
|
||||
{ //cos config folder only is in clients
|
||||
scriptLocation = FabricLoader.getInstance().getConfigDir().resolve("carpet/scripts/appstore").toAbsolutePath().resolve(path);
|
||||
@@ -331,8 +325,8 @@ public class AppStoreManager
|
||||
int i = 0;
|
||||
while (Files.exists(trashPath))
|
||||
{
|
||||
final String[] nameAndExtension = appFileName.split("\\.");
|
||||
final String newFileName = String.format(nameAndExtension[0] + "%02d." + nameAndExtension[1], i);
|
||||
String[] nameAndExtension = appFileName.split("\\.");
|
||||
String newFileName = String.format(nameAndExtension[0] + "%02d." + nameAndExtension[1], i);
|
||||
trashPath = trashPath.getParent().resolve(newFileName);
|
||||
i++;
|
||||
}
|
||||
@@ -340,11 +334,11 @@ public class AppStoreManager
|
||||
}
|
||||
Carpet.Messenger_message(source, String.format("gi Note: replaced existing app '%s'" + (useTrash ? " (old moved to /trash folder)" : ""), appFileName));
|
||||
}
|
||||
final BufferedWriter writer = Files.newBufferedWriter(scriptLocation);
|
||||
BufferedWriter writer = Files.newBufferedWriter(scriptLocation);
|
||||
writer.write(code);
|
||||
writer.close();
|
||||
}
|
||||
catch (final IOException e)
|
||||
catch (IOException e)
|
||||
{
|
||||
Carpet.Messenger_message(source, "r Error while downloading app: " + e);
|
||||
CarpetScriptServer.LOG.warn("Error while downloading app", e);
|
||||
@@ -353,15 +347,15 @@ public class AppStoreManager
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void writeUrlToFile(final String url, final Path destination) throws IOException
|
||||
public static void writeUrlToFile(String url, Path destination) throws IOException
|
||||
{
|
||||
try (final InputStream in = new URL(url).openStream())
|
||||
try (InputStream in = new URL(url).openStream())
|
||||
{
|
||||
Files.copy(in, destination, StandardCopyOption.REPLACE_EXISTING);
|
||||
}
|
||||
}
|
||||
|
||||
private static String getFullContentUrl(final String original, final StoreNode storeSource)
|
||||
private static String getFullContentUrl(String original, StoreNode storeSource)
|
||||
{
|
||||
if (original.matches("^https?://.*$")) // We've got a full url here: Just use it
|
||||
{
|
||||
@@ -374,28 +368,28 @@ public class AppStoreManager
|
||||
return getFileNodeFrom(storeSource, original).url(); // Relative path: Use download location
|
||||
}
|
||||
|
||||
public static void addResource(final CarpetScriptHost carpetScriptHost, final StoreNode storeSource, final Value resource)
|
||||
public static void addResource(CarpetScriptHost carpetScriptHost, StoreNode storeSource, Value resource)
|
||||
{
|
||||
if (!(resource instanceof final MapValue map))
|
||||
{
|
||||
throw new InternalExpressionException("This is not a valid resource map: " + resource.getString());
|
||||
}
|
||||
final Map<String, Value> resourceMap = map.getMap().entrySet().stream().collect(Collectors.toMap(e -> e.getKey().getString(), Map.Entry::getValue));
|
||||
Map<String, Value> resourceMap = map.getMap().entrySet().stream().collect(Collectors.toMap(e -> e.getKey().getString(), Map.Entry::getValue));
|
||||
if (!resourceMap.containsKey("source"))
|
||||
{
|
||||
throw new InternalExpressionException("Missing 'source' field in resource descriptor: " + resource.getString());
|
||||
}
|
||||
final String source = resourceMap.get("source").getString();
|
||||
final String contentUrl = getFullContentUrl(source, storeSource);
|
||||
final String target = resourceMap.computeIfAbsent("target", k -> new StringValue(contentUrl.substring(contentUrl.lastIndexOf('/') + 1))).getString();
|
||||
final boolean shared = resourceMap.getOrDefault("shared", Value.FALSE).getBoolean();
|
||||
String source = resourceMap.get("source").getString();
|
||||
String contentUrl = getFullContentUrl(source, storeSource);
|
||||
String target = resourceMap.computeIfAbsent("target", k -> new StringValue(contentUrl.substring(contentUrl.lastIndexOf('/') + 1))).getString();
|
||||
boolean shared = resourceMap.getOrDefault("shared", Value.FALSE).getBoolean();
|
||||
|
||||
if (!carpetScriptHost.applyActionForResource(target, shared, p -> {
|
||||
try
|
||||
{
|
||||
writeUrlToFile(contentUrl, p);
|
||||
}
|
||||
catch (final IOException e)
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new InternalExpressionException("Unable to write resource " + target + ": " + e);
|
||||
}
|
||||
@@ -414,7 +408,8 @@ public class AppStoreManager
|
||||
* @param contentUrl The full content URL, from {@link #getFullContentUrl(String, StoreNode)}
|
||||
* @return A {@link StoreNode} that can be used in an app that came from the provided source
|
||||
*/
|
||||
private static StoreNode getNewStoreNode(final StoreNode originalSource, String sourceString, final String contentUrl)
|
||||
@Nullable
|
||||
private static StoreNode getNewStoreNode(StoreNode originalSource, String sourceString, String contentUrl)
|
||||
{
|
||||
StoreNode next = originalSource;
|
||||
if (sourceString == contentUrl) // External URL (check getFullUrlContent)
|
||||
@@ -426,7 +421,7 @@ public class AppStoreManager
|
||||
next = APP_STORE_ROOT;
|
||||
sourceString = sourceString.substring(1);
|
||||
}
|
||||
final String[] dirs = sourceString.split("/");
|
||||
String[] dirs = sourceString.split("/");
|
||||
try
|
||||
{
|
||||
for (int i = 0; i < dirs.length - 1; i++)
|
||||
@@ -434,23 +429,23 @@ public class AppStoreManager
|
||||
next = next.drillDown(dirs[i]);
|
||||
}
|
||||
}
|
||||
catch (final IOException e)
|
||||
catch (IOException e)
|
||||
{
|
||||
return null; // Should never happen, but let's not give a potentially incorrect node just in case
|
||||
}
|
||||
return next;
|
||||
}
|
||||
|
||||
public static void addLibrary(final CarpetScriptHost carpetScriptHost, final StoreNode storeSource, final Value library)
|
||||
public static void addLibrary(CarpetScriptHost carpetScriptHost, StoreNode storeSource, Value library)
|
||||
{
|
||||
if (!(library instanceof final MapValue map))
|
||||
{
|
||||
throw new InternalExpressionException("This is not a valid library map: " + library.getString());
|
||||
}
|
||||
final Map<String, String> libraryMap = map.getMap().entrySet().stream().collect(Collectors.toMap(e -> e.getKey().getString(), e -> e.getValue().getString()));
|
||||
final String source = libraryMap.get("source");
|
||||
final String contentUrl = getFullContentUrl(source, storeSource);
|
||||
final String target = libraryMap.computeIfAbsent("target", k -> contentUrl.substring(contentUrl.lastIndexOf('/') + 1));
|
||||
Map<String, String> libraryMap = map.getMap().entrySet().stream().collect(Collectors.toMap(e -> e.getKey().getString(), e -> e.getValue().getString()));
|
||||
String source = libraryMap.get("source");
|
||||
String contentUrl = getFullContentUrl(source, storeSource);
|
||||
String target = libraryMap.computeIfAbsent("target", k -> contentUrl.substring(contentUrl.lastIndexOf('/') + 1));
|
||||
if (!(contentUrl.endsWith(".sc") || contentUrl.endsWith(".scl")))
|
||||
{
|
||||
throw new InternalExpressionException("App resource type must download a scarpet app or library.");
|
||||
@@ -463,7 +458,7 @@ public class AppStoreManager
|
||||
{
|
||||
downloadScript(carpetScriptHost.responsibleSource, target, new AppInfo(target, contentUrl, getNewStoreNode(storeSource, source, contentUrl)), true);
|
||||
}
|
||||
catch (final CommandRuntimeException e)
|
||||
catch (CommandRuntimeException e)
|
||||
{
|
||||
throw new InternalExpressionException("Error when installing app dependencies: " + e);
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ public class BiomeInfo
|
||||
put("humidity", (w, b) -> NumericValue.of(Vanilla.Biome_getClimateSettings(b).downfall()));
|
||||
put("precipitation", (w, b) -> StringValue.of(b.getPrecipitationAt(new BlockPos(0, w.getSeaLevel(), 0)).name().toLowerCase(Locale.ROOT)));
|
||||
put("features", (w, b) -> {
|
||||
final Registry<ConfiguredFeature<?, ?>> registry = w.registryAccess().registryOrThrow(Registries.CONFIGURED_FEATURE);
|
||||
Registry<ConfiguredFeature<?, ?>> registry = w.registryAccess().registryOrThrow(Registries.CONFIGURED_FEATURE);
|
||||
return ListValue.wrap(
|
||||
b.getGenerationSettings().features().stream().map(step ->
|
||||
ListValue.wrap(step.stream().map(cfp ->
|
||||
|
||||
@@ -9,24 +9,22 @@ public class EntityTools
|
||||
{
|
||||
/**
|
||||
* Not a replacement for living entity jump() - this barely is to allow other entities that can't jump in vanilla to 'jump'
|
||||
*
|
||||
* @param e
|
||||
*/
|
||||
public static void genericJump(final Entity e)
|
||||
public static void genericJump(Entity e)
|
||||
{
|
||||
if (!e.isOnGround() && !e.isInWaterOrBubble() && !e.isInLava())
|
||||
{
|
||||
return;
|
||||
}
|
||||
final float m = e.level.getBlockState(e.blockPosition()).getBlock().getJumpFactor();
|
||||
final float g = e.level.getBlockState(new BlockPos(e.getX(), e.getBoundingBox().minY - 0.5000001D, e.getZ())).getBlock().getJumpFactor();
|
||||
final float jumpVelocityMultiplier = m == 1.0D ? g : m;
|
||||
final float jumpStrength = (0.42F * jumpVelocityMultiplier);
|
||||
final Vec3 vec3d = e.getDeltaMovement();
|
||||
float m = e.level.getBlockState(e.blockPosition()).getBlock().getJumpFactor();
|
||||
float g = e.level.getBlockState(new BlockPos(e.getX(), e.getBoundingBox().minY - 0.5000001D, e.getZ())).getBlock().getJumpFactor();
|
||||
float jumpVelocityMultiplier = m == 1.0D ? g : m;
|
||||
float jumpStrength = (0.42F * jumpVelocityMultiplier);
|
||||
Vec3 vec3d = e.getDeltaMovement();
|
||||
e.setDeltaMovement(vec3d.x, jumpStrength, vec3d.z);
|
||||
if (e.isSprinting())
|
||||
{
|
||||
final float u = e.getYRot() * 0.017453292F; // yaw
|
||||
float u = e.getYRot() * 0.017453292F; // yaw
|
||||
e.setDeltaMovement(e.getDeltaMovement().add((-Mth.sin(g) * 0.2F), 0.0D, (Mth.cos(u) * 0.2F)));
|
||||
}
|
||||
e.hasImpulse = true;
|
||||
|
||||
@@ -19,7 +19,7 @@ public class EquipmentInventory implements Container
|
||||
|
||||
LivingEntity mob;
|
||||
|
||||
public EquipmentInventory(final LivingEntity mob)
|
||||
public EquipmentInventory(LivingEntity mob)
|
||||
{
|
||||
this.mob = mob;
|
||||
}
|
||||
@@ -33,7 +33,7 @@ public class EquipmentInventory implements Container
|
||||
@Override
|
||||
public boolean isEmpty()
|
||||
{
|
||||
for (final EquipmentSlot slot : slotToSlot)
|
||||
for (EquipmentSlot slot : slotToSlot)
|
||||
{
|
||||
if (!mob.getItemBySlot(slot).isEmpty())
|
||||
{
|
||||
@@ -44,14 +44,14 @@ public class EquipmentInventory implements Container
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getItem(final int slot)
|
||||
public ItemStack getItem(int slot)
|
||||
{
|
||||
final EquipmentSlot slotSlot;
|
||||
EquipmentSlot slotSlot;
|
||||
try
|
||||
{
|
||||
slotSlot = slotToSlot.get(slot);
|
||||
}
|
||||
catch (final IndexOutOfBoundsException ignored)
|
||||
catch (IndexOutOfBoundsException ignored)
|
||||
{
|
||||
//going out of the index should be really exceptional
|
||||
return ItemStack.EMPTY;
|
||||
@@ -60,14 +60,14 @@ public class EquipmentInventory implements Container
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack removeItem(final int slot, final int amount)
|
||||
public ItemStack removeItem(int slot, int amount)
|
||||
{
|
||||
final EquipmentSlot slotSlot;
|
||||
EquipmentSlot slotSlot;
|
||||
try
|
||||
{
|
||||
slotSlot = slotToSlot.get(slot);
|
||||
}
|
||||
catch (final IndexOutOfBoundsException ignored)
|
||||
catch (IndexOutOfBoundsException ignored)
|
||||
{
|
||||
//going out of the index should be really exceptional
|
||||
return ItemStack.EMPTY;
|
||||
@@ -76,32 +76,32 @@ public class EquipmentInventory implements Container
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack removeItemNoUpdate(final int slot)
|
||||
public ItemStack removeItemNoUpdate(int slot)
|
||||
{
|
||||
final EquipmentSlot slotSlot;
|
||||
EquipmentSlot slotSlot;
|
||||
try
|
||||
{
|
||||
slotSlot = slotToSlot.get(slot);
|
||||
}
|
||||
catch (final IndexOutOfBoundsException ignored)
|
||||
catch (IndexOutOfBoundsException ignored)
|
||||
{
|
||||
//going out of the index should be really exceptional
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
final ItemStack previous = mob.getItemBySlot(slotSlot);
|
||||
ItemStack previous = mob.getItemBySlot(slotSlot);
|
||||
mob.setItemSlot(slotSlot, ItemStack.EMPTY);
|
||||
return previous;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setItem(final int slot, final ItemStack stack)
|
||||
public void setItem(int slot, ItemStack stack)
|
||||
{
|
||||
final EquipmentSlot slotSlot;
|
||||
EquipmentSlot slotSlot;
|
||||
try
|
||||
{
|
||||
slotSlot = slotToSlot.get(slot);
|
||||
}
|
||||
catch (final IndexOutOfBoundsException ignored)
|
||||
catch (IndexOutOfBoundsException ignored)
|
||||
{
|
||||
//going out of the index should be really exceptional
|
||||
return;
|
||||
@@ -116,7 +116,7 @@ public class EquipmentInventory implements Container
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean stillValid(final Player player)
|
||||
public boolean stillValid(Player player)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -124,7 +124,7 @@ public class EquipmentInventory implements Container
|
||||
@Override
|
||||
public void clearContent()
|
||||
{
|
||||
for (final EquipmentSlot slot : slotToSlot)
|
||||
for (EquipmentSlot slot : slotToSlot)
|
||||
{
|
||||
mob.setItemSlot(slot, ItemStack.EMPTY);
|
||||
}
|
||||
|
||||
@@ -68,24 +68,24 @@ import javax.annotation.Nullable;
|
||||
public class FeatureGenerator
|
||||
{
|
||||
@Nullable
|
||||
public static synchronized Boolean plop(final String featureName, final ServerLevel world, final BlockPos pos)
|
||||
public static synchronized Boolean plop(String featureName, ServerLevel world, BlockPos pos)
|
||||
{
|
||||
final Function<ServerLevel, Thing> custom = featureMap.get(featureName);
|
||||
Function<ServerLevel, Thing> custom = featureMap.get(featureName);
|
||||
if (custom != null)
|
||||
{
|
||||
return custom.apply(world).plop(world, pos);
|
||||
}
|
||||
final ResourceLocation id = new ResourceLocation(featureName);
|
||||
final Structure structure = world.registryAccess().registryOrThrow(Registries.STRUCTURE).get(id);
|
||||
ResourceLocation id = new ResourceLocation(featureName);
|
||||
Structure structure = world.registryAccess().registryOrThrow(Registries.STRUCTURE).get(id);
|
||||
if (structure != null)
|
||||
{
|
||||
return plopAnywhere(structure, world, pos, world.getChunkSource().getGenerator(), false);
|
||||
}
|
||||
|
||||
final ConfiguredFeature<?, ?> configuredFeature = world.registryAccess().registryOrThrow(Registries.CONFIGURED_FEATURE).get(id);
|
||||
ConfiguredFeature<?, ?> configuredFeature = world.registryAccess().registryOrThrow(Registries.CONFIGURED_FEATURE).get(id);
|
||||
if (configuredFeature != null)
|
||||
{
|
||||
final ThreadLocal<Boolean> checks = Vanilla.skipGenerationChecks(world);
|
||||
ThreadLocal<Boolean> checks = Vanilla.skipGenerationChecks(world);
|
||||
checks.set(true);
|
||||
try
|
||||
{
|
||||
@@ -96,22 +96,22 @@ public class FeatureGenerator
|
||||
checks.set(false);
|
||||
}
|
||||
}
|
||||
final Optional<StructureType<?>> structureType = world.registryAccess().registryOrThrow(Registries.STRUCTURE_TYPE).getOptional(id);
|
||||
Optional<StructureType<?>> structureType = world.registryAccess().registryOrThrow(Registries.STRUCTURE_TYPE).getOptional(id);
|
||||
if (structureType.isPresent())
|
||||
{
|
||||
final Structure configuredStandard = getDefaultFeature(structureType.get(), world, pos);
|
||||
Structure configuredStandard = getDefaultFeature(structureType.get(), world, pos);
|
||||
if (configuredStandard != null)
|
||||
{
|
||||
return plopAnywhere(configuredStandard, world, pos, world.getChunkSource().getGenerator(), false);
|
||||
}
|
||||
}
|
||||
final Feature<?> feature = world.registryAccess().registryOrThrow(Registries.FEATURE).get(id);
|
||||
Feature<?> feature = world.registryAccess().registryOrThrow(Registries.FEATURE).get(id);
|
||||
if (feature != null)
|
||||
{
|
||||
final ConfiguredFeature<?, ?> configuredStandard = getDefaultFeature(feature, world, pos, true);
|
||||
ConfiguredFeature<?, ?> configuredStandard = getDefaultFeature(feature, world, pos, true);
|
||||
if (configuredStandard != null)
|
||||
{
|
||||
final ThreadLocal<Boolean> checks = Vanilla.skipGenerationChecks(world);
|
||||
ThreadLocal<Boolean> checks = Vanilla.skipGenerationChecks(world);
|
||||
checks.set(true);
|
||||
try
|
||||
{
|
||||
@@ -126,15 +126,16 @@ public class FeatureGenerator
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Structure resolveConfiguredStructure(final String name, final ServerLevel world, final BlockPos pos)
|
||||
@Nullable
|
||||
public static Structure resolveConfiguredStructure(String name, ServerLevel world, BlockPos pos)
|
||||
{
|
||||
final ResourceLocation id = new ResourceLocation(name);
|
||||
final Structure configuredStructureFeature = world.registryAccess().registryOrThrow(Registries.STRUCTURE).get(id);
|
||||
ResourceLocation id = new ResourceLocation(name);
|
||||
Structure configuredStructureFeature = world.registryAccess().registryOrThrow(Registries.STRUCTURE).get(id);
|
||||
if (configuredStructureFeature != null)
|
||||
{
|
||||
return configuredStructureFeature;
|
||||
}
|
||||
final StructureType<?> structureFeature = world.registryAccess().registryOrThrow(Registries.STRUCTURE_TYPE).get(id);
|
||||
StructureType<?> structureFeature = world.registryAccess().registryOrThrow(Registries.STRUCTURE_TYPE).get(id);
|
||||
if (structureFeature == null)
|
||||
{
|
||||
return null;
|
||||
@@ -142,7 +143,7 @@ public class FeatureGenerator
|
||||
return getDefaultFeature(structureFeature, world, pos);
|
||||
}
|
||||
|
||||
public static synchronized Boolean plopGrid(final Structure structureFeature, final ServerLevel world, final BlockPos pos)
|
||||
public static synchronized boolean plopGrid(Structure structureFeature, ServerLevel world, BlockPos pos)
|
||||
{
|
||||
return plopAnywhere(structureFeature, world, pos, world.getChunkSource().getGenerator(), true);
|
||||
}
|
||||
@@ -153,10 +154,10 @@ public class FeatureGenerator
|
||||
Boolean plop(ServerLevel world, BlockPos pos);
|
||||
}
|
||||
|
||||
private static Thing simplePlop(final ConfiguredFeature<?, ?> feature)
|
||||
private static Thing simplePlop(ConfiguredFeature<?, ?> feature)
|
||||
{
|
||||
return (w, p) -> {
|
||||
final ThreadLocal<Boolean> checks = Vanilla.skipGenerationChecks(w);
|
||||
ThreadLocal<Boolean> checks = Vanilla.skipGenerationChecks(w);
|
||||
checks.set(true);
|
||||
try
|
||||
{
|
||||
@@ -169,34 +170,34 @@ public class FeatureGenerator
|
||||
};
|
||||
}
|
||||
|
||||
private static <FC extends FeatureConfiguration, F extends Feature<FC>> Thing simplePlop(final F feature, final FC config)
|
||||
private static <FC extends FeatureConfiguration, F extends Feature<FC>> Thing simplePlop(F feature, FC config)
|
||||
{
|
||||
return simplePlop(new ConfiguredFeature<>(feature, config));
|
||||
}
|
||||
|
||||
private static Thing simpleTree(final TreeConfiguration config)
|
||||
private static Thing simpleTree(TreeConfiguration config)
|
||||
{
|
||||
//config.ignoreFluidCheck();
|
||||
return simplePlop(new ConfiguredFeature<>(Feature.TREE, config));
|
||||
}
|
||||
|
||||
private static Thing spawnCustomStructure(final Structure structure)
|
||||
private static Thing spawnCustomStructure(Structure structure)
|
||||
{
|
||||
return setupCustomStructure(structure, false);
|
||||
}
|
||||
|
||||
private static Thing setupCustomStructure(final Structure structure, final boolean wireOnly)
|
||||
private static Thing setupCustomStructure(Structure structure, boolean wireOnly)
|
||||
{
|
||||
return (w, p) -> plopAnywhere(structure, w, p, w.getChunkSource().getGenerator(), wireOnly);
|
||||
}
|
||||
|
||||
private static Structure getDefaultFeature(final StructureType<?> structure, final ServerLevel world, final BlockPos pos)
|
||||
private static Structure getDefaultFeature(StructureType<?> structure, ServerLevel world, BlockPos pos)
|
||||
{
|
||||
// would be nice to have a way to grab structures of this type for position
|
||||
// TODO allow old types, like vaillage, or bastion
|
||||
final Holder<Biome> existingBiome = world.getBiome(pos);
|
||||
Holder<Biome> existingBiome = world.getBiome(pos);
|
||||
Structure result = null;
|
||||
for (final Structure confstr : world.registryAccess().registryOrThrow(Registries.STRUCTURE).entrySet().stream().
|
||||
for (Structure confstr : world.registryAccess().registryOrThrow(Registries.STRUCTURE).entrySet().stream().
|
||||
filter(cS -> cS.getValue().type() == structure).map(Map.Entry::getValue).toList())
|
||||
{
|
||||
result = confstr;
|
||||
@@ -208,12 +209,12 @@ public class FeatureGenerator
|
||||
return result;
|
||||
}
|
||||
|
||||
private static ConfiguredFeature<?, ?> getDefaultFeature(final Feature<?> feature, final ServerLevel world, final BlockPos pos, final boolean tryHard)
|
||||
private static ConfiguredFeature<?, ?> getDefaultFeature(Feature<?> feature, ServerLevel world, BlockPos pos, boolean tryHard)
|
||||
{
|
||||
final List<HolderSet<PlacedFeature>> configuredStepFeatures = world.getBiome(pos).value().getGenerationSettings().features();
|
||||
for (final HolderSet<PlacedFeature> step : configuredStepFeatures)
|
||||
List<HolderSet<PlacedFeature>> configuredStepFeatures = world.getBiome(pos).value().getGenerationSettings().features();
|
||||
for (HolderSet<PlacedFeature> step : configuredStepFeatures)
|
||||
{
|
||||
for (final Holder<PlacedFeature> provider : step)
|
||||
for (Holder<PlacedFeature> provider : step)
|
||||
{
|
||||
if (provider.value().feature().value().feature() == feature)
|
||||
{
|
||||
@@ -230,21 +231,22 @@ public class FeatureGenerator
|
||||
findFirst().map(Map.Entry::getValue).orElse(null);
|
||||
}
|
||||
|
||||
public static <T extends FeatureConfiguration> StructureStart shouldStructureStartAt(final ServerLevel world, final BlockPos pos, final Structure structure, final boolean computeBox)
|
||||
|
||||
public static <T extends FeatureConfiguration> StructureStart shouldStructureStartAt(ServerLevel world, BlockPos pos, Structure structure, boolean computeBox)
|
||||
{
|
||||
final ServerChunkCache chunkSource = world.getChunkSource();
|
||||
final RandomState seed = chunkSource.randomState();
|
||||
final ChunkGenerator generator = chunkSource.getGenerator();
|
||||
final ChunkGeneratorStructureState structureState = chunkSource.getGeneratorState();
|
||||
final List<StructurePlacement> structureConfig = structureState.getPlacementsForStructure(Holder.direct(structure));
|
||||
final ChunkPos chunkPos = new ChunkPos(pos);
|
||||
final boolean couldPlace = structureConfig.stream().anyMatch(p -> p.isStructureChunk(structureState, chunkPos.x, chunkPos.z));
|
||||
ServerChunkCache chunkSource = world.getChunkSource();
|
||||
RandomState seed = chunkSource.randomState();
|
||||
ChunkGenerator generator = chunkSource.getGenerator();
|
||||
ChunkGeneratorStructureState structureState = chunkSource.getGeneratorState();
|
||||
List<StructurePlacement> structureConfig = structureState.getPlacementsForStructure(Holder.direct(structure));
|
||||
ChunkPos chunkPos = new ChunkPos(pos);
|
||||
boolean couldPlace = structureConfig.stream().anyMatch(p -> p.isStructureChunk(structureState, chunkPos.x, chunkPos.z));
|
||||
if (!couldPlace)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
final HolderSet<Biome> structureBiomes = structure.biomes();
|
||||
HolderSet<Biome> structureBiomes = structure.biomes();
|
||||
|
||||
if (!computeBox)
|
||||
{
|
||||
@@ -259,7 +261,7 @@ public class FeatureGenerator
|
||||
}
|
||||
else
|
||||
{
|
||||
final StructureStart filledStructure = structure.generate(
|
||||
StructureStart filledStructure = structure.generate(
|
||||
world.registryAccess(), generator, generator.getBiomeSource(), seed, world.getStructureManager(),
|
||||
world.getSeed(), chunkPos, 0, world, structureBiomes::contains);
|
||||
if (filledStructure != null && filledStructure.isValid())
|
||||
@@ -270,7 +272,7 @@ public class FeatureGenerator
|
||||
return null;
|
||||
}
|
||||
|
||||
private static TreeConfiguration.TreeConfigurationBuilder createTree(final Block block, final Block block2, final int i, final int j, final int k, final int l)
|
||||
private static TreeConfiguration.TreeConfigurationBuilder createTree(Block block, Block block2, int i, int j, int k, int l)
|
||||
{
|
||||
return new TreeConfiguration.TreeConfigurationBuilder(BlockStateProvider.simple(block), new StraightTrunkPlacer(i, j, k), BlockStateProvider.simple(block2), new BlobFoliagePlacer(ConstantInt.of(l), ConstantInt.of(0), 3), new TwoLayersFeatureSize(1, 0, 1));
|
||||
}
|
||||
@@ -292,13 +294,13 @@ public class FeatureGenerator
|
||||
PlacementUtils.inlinePlaced(Feature.CORAL_MUSHROOM, FeatureConfiguration.NONE)
|
||||
))));
|
||||
put("bastion_remnant_units", l -> {
|
||||
final RegistryAccess regs = l.registryAccess();
|
||||
RegistryAccess regs = l.registryAccess();
|
||||
|
||||
final HolderGetter<StructureProcessorList> processorLists = regs.lookupOrThrow(Registries.PROCESSOR_LIST);
|
||||
final Holder<StructureProcessorList> bastionGenericDegradation = processorLists.getOrThrow(ProcessorLists.BASTION_GENERIC_DEGRADATION);
|
||||
HolderGetter<StructureProcessorList> processorLists = regs.lookupOrThrow(Registries.PROCESSOR_LIST);
|
||||
Holder<StructureProcessorList> bastionGenericDegradation = processorLists.getOrThrow(ProcessorLists.BASTION_GENERIC_DEGRADATION);
|
||||
|
||||
final HolderGetter<StructureTemplatePool> pools = regs.lookupOrThrow(Registries.TEMPLATE_POOL);
|
||||
final Holder<StructureTemplatePool> empty = pools.getOrThrow(Pools.EMPTY);
|
||||
HolderGetter<StructureTemplatePool> pools = regs.lookupOrThrow(Registries.TEMPLATE_POOL);
|
||||
Holder<StructureTemplatePool> empty = pools.getOrThrow(Pools.EMPTY);
|
||||
|
||||
|
||||
return spawnCustomStructure(
|
||||
@@ -322,13 +324,13 @@ public class FeatureGenerator
|
||||
);
|
||||
});
|
||||
put("bastion_remnant_hoglin_stable", l -> {
|
||||
final RegistryAccess regs = l.registryAccess();
|
||||
RegistryAccess regs = l.registryAccess();
|
||||
|
||||
final HolderGetter<StructureProcessorList> processorLists = regs.lookupOrThrow(Registries.PROCESSOR_LIST);
|
||||
final Holder<StructureProcessorList> bastionGenericDegradation = processorLists.getOrThrow(ProcessorLists.BASTION_GENERIC_DEGRADATION);
|
||||
HolderGetter<StructureProcessorList> processorLists = regs.lookupOrThrow(Registries.PROCESSOR_LIST);
|
||||
Holder<StructureProcessorList> bastionGenericDegradation = processorLists.getOrThrow(ProcessorLists.BASTION_GENERIC_DEGRADATION);
|
||||
|
||||
final HolderGetter<StructureTemplatePool> pools = regs.lookupOrThrow(Registries.TEMPLATE_POOL);
|
||||
final Holder<StructureTemplatePool> empty = pools.getOrThrow(Pools.EMPTY);
|
||||
HolderGetter<StructureTemplatePool> pools = regs.lookupOrThrow(Registries.TEMPLATE_POOL);
|
||||
Holder<StructureTemplatePool> empty = pools.getOrThrow(Pools.EMPTY);
|
||||
|
||||
return spawnCustomStructure(
|
||||
new JigsawStructure(new Structure.StructureSettings(
|
||||
@@ -351,13 +353,13 @@ public class FeatureGenerator
|
||||
);
|
||||
});
|
||||
put("bastion_remnant_treasure", l -> {
|
||||
final RegistryAccess regs = l.registryAccess();
|
||||
RegistryAccess regs = l.registryAccess();
|
||||
|
||||
final HolderGetter<StructureProcessorList> processorLists = regs.lookupOrThrow(Registries.PROCESSOR_LIST);
|
||||
final Holder<StructureProcessorList> bastionGenericDegradation = processorLists.getOrThrow(ProcessorLists.BASTION_GENERIC_DEGRADATION);
|
||||
HolderGetter<StructureProcessorList> processorLists = regs.lookupOrThrow(Registries.PROCESSOR_LIST);
|
||||
Holder<StructureProcessorList> bastionGenericDegradation = processorLists.getOrThrow(ProcessorLists.BASTION_GENERIC_DEGRADATION);
|
||||
|
||||
final HolderGetter<StructureTemplatePool> pools = regs.lookupOrThrow(Registries.TEMPLATE_POOL);
|
||||
final Holder<StructureTemplatePool> empty = pools.getOrThrow(Pools.EMPTY);
|
||||
HolderGetter<StructureTemplatePool> pools = regs.lookupOrThrow(Registries.TEMPLATE_POOL);
|
||||
Holder<StructureTemplatePool> empty = pools.getOrThrow(Pools.EMPTY);
|
||||
|
||||
return spawnCustomStructure(
|
||||
new JigsawStructure(new Structure.StructureSettings(
|
||||
@@ -380,13 +382,13 @@ public class FeatureGenerator
|
||||
);
|
||||
});
|
||||
put("bastion_remnant_bridge", l -> {
|
||||
final RegistryAccess regs = l.registryAccess();
|
||||
RegistryAccess regs = l.registryAccess();
|
||||
|
||||
final HolderGetter<StructureProcessorList> processorLists = regs.lookupOrThrow(Registries.PROCESSOR_LIST);
|
||||
final Holder<StructureProcessorList> bastionGenericDegradation = processorLists.getOrThrow(ProcessorLists.BASTION_GENERIC_DEGRADATION);
|
||||
HolderGetter<StructureProcessorList> processorLists = regs.lookupOrThrow(Registries.PROCESSOR_LIST);
|
||||
Holder<StructureProcessorList> bastionGenericDegradation = processorLists.getOrThrow(ProcessorLists.BASTION_GENERIC_DEGRADATION);
|
||||
|
||||
final HolderGetter<StructureTemplatePool> pools = regs.lookupOrThrow(Registries.TEMPLATE_POOL);
|
||||
final Holder<StructureTemplatePool> empty = pools.getOrThrow(Pools.EMPTY);
|
||||
HolderGetter<StructureTemplatePool> pools = regs.lookupOrThrow(Registries.TEMPLATE_POOL);
|
||||
Holder<StructureTemplatePool> empty = pools.getOrThrow(Pools.EMPTY);
|
||||
|
||||
return spawnCustomStructure(
|
||||
new JigsawStructure(new Structure.StructureSettings(
|
||||
@@ -411,29 +413,29 @@ public class FeatureGenerator
|
||||
}};
|
||||
|
||||
|
||||
public static boolean plopAnywhere(final Structure structure, final ServerLevel world, final BlockPos pos, final ChunkGenerator generator, final boolean wireOnly)
|
||||
public static boolean plopAnywhere(Structure structure, ServerLevel world, BlockPos pos, ChunkGenerator generator, boolean wireOnly)
|
||||
{
|
||||
final ThreadLocal<Boolean> checks = Vanilla.skipGenerationChecks(world);
|
||||
ThreadLocal<Boolean> checks = Vanilla.skipGenerationChecks(world);
|
||||
checks.set(true);
|
||||
try
|
||||
{
|
||||
final StructureStart start = structure.generate(world.registryAccess(), generator, generator.getBiomeSource(), world.getChunkSource().randomState(), world.getStructureManager(), world.getSeed(), new ChunkPos(pos), 0, world, b -> true);
|
||||
StructureStart start = structure.generate(world.registryAccess(), generator, generator.getBiomeSource(), world.getChunkSource().randomState(), world.getStructureManager(), world.getSeed(), new ChunkPos(pos), 0, world, b -> true);
|
||||
if (start == StructureStart.INVALID_START)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
final RandomSource rand = RandomSource.create(world.getRandom().nextInt());
|
||||
final int j = pos.getX() >> 4;
|
||||
final int k = pos.getZ() >> 4;
|
||||
final long chId = ChunkPos.asLong(j, k);
|
||||
RandomSource rand = RandomSource.create(world.getRandom().nextInt());
|
||||
int j = pos.getX() >> 4;
|
||||
int k = pos.getZ() >> 4;
|
||||
long chId = ChunkPos.asLong(j, k);
|
||||
world.getChunk(j, k).setStartForStructure(structure, start);
|
||||
world.getChunk(j, k).addReferenceForStructure(structure, chId);
|
||||
|
||||
final BoundingBox box = start.getBoundingBox();
|
||||
BoundingBox box = start.getBoundingBox();
|
||||
|
||||
if (!wireOnly)
|
||||
{
|
||||
final Registry<Structure> registry3 = world.registryAccess().registryOrThrow(Registries.STRUCTURE);
|
||||
Registry<Structure> registry3 = world.registryAccess().registryOrThrow(Registries.STRUCTURE);
|
||||
world.setCurrentlyGenerating(() -> {
|
||||
Objects.requireNonNull(structure);
|
||||
return registry3.getResourceKey(structure).map(Object::toString).orElseGet(structure::toString);
|
||||
@@ -441,7 +443,7 @@ public class FeatureGenerator
|
||||
start.placeInChunk(world, world.structureManager(), generator, rand, box, new ChunkPos(j, k));
|
||||
}
|
||||
//structurestart.notifyPostProcessAt(new ChunkPos(j, k));
|
||||
final int i = Math.max(box.getXSpan(), box.getZSpan()) / 16 + 1;
|
||||
int i = Math.max(box.getXSpan(), box.getZSpan()) / 16 + 1;
|
||||
|
||||
//int i = getRadius();
|
||||
for (int k1 = j - i; k1 <= j + i; ++k1)
|
||||
@@ -459,7 +461,7 @@ public class FeatureGenerator
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (final Exception booboo)
|
||||
catch (Exception booboo)
|
||||
{
|
||||
CarpetScriptServer.LOG.error("Unknown Exception while plopping structure: " + booboo, booboo);
|
||||
return false;
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
package carpet.script.utils;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class GlocalFlag extends ThreadLocal<Boolean>
|
||||
{
|
||||
private final boolean initial;
|
||||
|
||||
public GlocalFlag(final boolean initial)
|
||||
public GlocalFlag(boolean initial)
|
||||
{
|
||||
this.initial = initial;
|
||||
}
|
||||
@@ -24,15 +25,15 @@ public class GlocalFlag extends ThreadLocal<Boolean>
|
||||
* @param <T> - returned value of that action, whatever that might be
|
||||
* @return result of the action
|
||||
*/
|
||||
public <T> T getWhileDisabled(final Supplier<T> action)
|
||||
public <T> T getWhileDisabled(Supplier<T> action)
|
||||
{
|
||||
return whileValueReturn(!initial, action);
|
||||
}
|
||||
|
||||
private <T> T whileValueReturn(final boolean what, final Supplier<T> action)
|
||||
private <T> T whileValueReturn(boolean what, Supplier<T> action)
|
||||
{
|
||||
T result;
|
||||
final boolean previous;
|
||||
boolean previous;
|
||||
synchronized (this)
|
||||
{
|
||||
previous = get();
|
||||
@@ -49,7 +50,8 @@ public class GlocalFlag extends ThreadLocal<Boolean>
|
||||
return result;
|
||||
}
|
||||
|
||||
public <T> T runIfEnabled(final Supplier<T> action)
|
||||
@Nullable
|
||||
public <T> T runIfEnabled(Supplier<T> action)
|
||||
{
|
||||
synchronized (this)
|
||||
{
|
||||
|
||||
@@ -9,9 +9,9 @@ import net.minecraft.resources.ResourceLocation;
|
||||
|
||||
public class InputValidator
|
||||
{
|
||||
public static String validateSimpleString(final String input, final boolean strict)
|
||||
public static String validateSimpleString(String input, boolean strict)
|
||||
{
|
||||
final String simplified = input.toLowerCase(Locale.ROOT).replaceAll("[^A-Za-z0-9+_]", "");
|
||||
String simplified = input.toLowerCase(Locale.ROOT).replaceAll("[^A-Za-z0-9+_]", "");
|
||||
if (simplified.isEmpty() || (strict && !simplified.equals(input)))
|
||||
{
|
||||
throw new InternalExpressionException("simple name can only contain numbers, letter and _");
|
||||
@@ -19,13 +19,13 @@ public class InputValidator
|
||||
return simplified;
|
||||
}
|
||||
|
||||
public static ResourceLocation identifierOf(final String string)
|
||||
public static ResourceLocation identifierOf(String string)
|
||||
{
|
||||
try
|
||||
{
|
||||
return new ResourceLocation(string);
|
||||
}
|
||||
catch (final ResourceLocationException iie)
|
||||
catch (ResourceLocationException iie)
|
||||
{
|
||||
throw new InternalExpressionException("Incorrect identifier format '" + string + "': " + iie.getMessage());
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import net.minecraft.core.HolderLookup;
|
||||
import net.minecraft.core.particles.ParticleOptions;
|
||||
import net.minecraft.core.particles.ParticleType;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -14,19 +15,20 @@ public class ParticleParser
|
||||
{
|
||||
private static final Map<String, ParticleOptions> particleCache = new HashMap<>(); // we reset this on reloads, but probably need something better
|
||||
|
||||
private static ParticleOptions parseParticle(final String name, final HolderLookup<ParticleType<?>> lookup)
|
||||
private static ParticleOptions parseParticle(String name, HolderLookup<ParticleType<?>> lookup)
|
||||
{
|
||||
try
|
||||
{
|
||||
return ParticleArgument.readParticle(new StringReader(name), lookup);
|
||||
}
|
||||
catch (final CommandSyntaxException e)
|
||||
catch (CommandSyntaxException e)
|
||||
{
|
||||
throw new IllegalArgumentException("No such particle: " + name);
|
||||
}
|
||||
}
|
||||
|
||||
public static ParticleOptions getEffect(final String name, final HolderLookup<ParticleType<?>> lookup)
|
||||
@Nullable
|
||||
public static ParticleOptions getEffect(@Nullable String name, HolderLookup<ParticleType<?>> lookup)
|
||||
{
|
||||
if (name == null)
|
||||
{
|
||||
|
||||
@@ -24,7 +24,7 @@ public class PerlinNoiseSampler
|
||||
public static PerlinNoiseSampler instance = new PerlinNoiseSampler(new Random(0));
|
||||
public static Map<Long, PerlinNoiseSampler> samplers = new Long2ObjectOpenHashMap<>();
|
||||
|
||||
public static PerlinNoiseSampler getPerlin(final long aLong)
|
||||
public static PerlinNoiseSampler getPerlin(long aLong)
|
||||
{
|
||||
if (samplers.size() > 256)
|
||||
{
|
||||
@@ -33,7 +33,7 @@ public class PerlinNoiseSampler
|
||||
return samplers.computeIfAbsent(aLong, seed -> new PerlinNoiseSampler(new Random(seed)));
|
||||
}
|
||||
|
||||
public PerlinNoiseSampler(final Random random)
|
||||
public PerlinNoiseSampler(Random random)
|
||||
{
|
||||
this.originX = random.nextDouble() * 256.0D;
|
||||
this.originY = random.nextDouble() * 256.0D;
|
||||
@@ -47,27 +47,27 @@ public class PerlinNoiseSampler
|
||||
}
|
||||
for (j = 0; j < 256; ++j)
|
||||
{
|
||||
final int k = random.nextInt(256 - j);
|
||||
final byte b = this.permutations[j];
|
||||
int k = random.nextInt(256 - j);
|
||||
byte b = this.permutations[j];
|
||||
this.permutations[j] = this.permutations[j + k];
|
||||
this.permutations[j + k] = b;
|
||||
}
|
||||
}
|
||||
//3D
|
||||
public double sample3d(final double x, final double y, final double z)
|
||||
public double sample3d(double x, double y, double z)
|
||||
{//, double d, double e) {
|
||||
final double f = x + this.originX;
|
||||
final double g = y + this.originY;
|
||||
final double h = z + this.originZ;
|
||||
final int i = floor(f);
|
||||
final int j = floor(g);
|
||||
final int k = floor(h);
|
||||
final double l = f - (double) i;
|
||||
final double m = g - (double) j;
|
||||
final double n = h - (double) k;
|
||||
final double o = perlinFade(l);
|
||||
final double p = perlinFade(m);
|
||||
final double q = perlinFade(n);
|
||||
double f = x + this.originX;
|
||||
double g = y + this.originY;
|
||||
double h = z + this.originZ;
|
||||
int i = floor(f);
|
||||
int j = floor(g);
|
||||
int k = floor(h);
|
||||
double l = f - (double) i;
|
||||
double m = g - (double) j;
|
||||
double n = h - (double) k;
|
||||
double o = perlinFade(l);
|
||||
double p = perlinFade(m);
|
||||
double q = perlinFade(n);
|
||||
//double t;
|
||||
/*
|
||||
if (d != 0.0D) {
|
||||
@@ -80,124 +80,124 @@ public class PerlinNoiseSampler
|
||||
return this.sample3d(i, j, k, l, m, n, o, p, q) / 2 + 0.5;
|
||||
}
|
||||
|
||||
private double sample3d(final int sectionX, final int sectionY, final int sectionZ, final double localX, final double localY, final double localZ, final double fadeLocalX, final double fadeLocalY, final double fadeLocalZ)
|
||||
private double sample3d(int sectionX, int sectionY, int sectionZ, double localX, double localY, double localZ, double fadeLocalX, double fadeLocalY, double fadeLocalZ)
|
||||
{
|
||||
final int i = this.getGradient(sectionX) + sectionY;
|
||||
final int j = this.getGradient(i) + sectionZ;
|
||||
final int k = this.getGradient(i + 1) + sectionZ;
|
||||
final int l = this.getGradient(sectionX + 1) + sectionY;
|
||||
final int m = this.getGradient(l) + sectionZ;
|
||||
final int n = this.getGradient(l + 1) + sectionZ;
|
||||
final double d = grad3d(this.getGradient(j), localX, localY, localZ);
|
||||
final double e = grad3d(this.getGradient(m), localX - 1.0D, localY, localZ);
|
||||
final double f = grad3d(this.getGradient(k), localX, localY - 1.0D, localZ);
|
||||
final double g = grad3d(this.getGradient(n), localX - 1.0D, localY - 1.0D, localZ);
|
||||
final double h = grad3d(this.getGradient(j + 1), localX, localY, localZ - 1.0D);
|
||||
final double o = grad3d(this.getGradient(m + 1), localX - 1.0D, localY, localZ - 1.0D);
|
||||
final double p = grad3d(this.getGradient(k + 1), localX, localY - 1.0D, localZ - 1.0D);
|
||||
final double q = grad3d(this.getGradient(n + 1), localX - 1.0D, localY - 1.0D, localZ - 1.0D);
|
||||
int i = this.getGradient(sectionX) + sectionY;
|
||||
int j = this.getGradient(i) + sectionZ;
|
||||
int k = this.getGradient(i + 1) + sectionZ;
|
||||
int l = this.getGradient(sectionX + 1) + sectionY;
|
||||
int m = this.getGradient(l) + sectionZ;
|
||||
int n = this.getGradient(l + 1) + sectionZ;
|
||||
double d = grad3d(this.getGradient(j), localX, localY, localZ);
|
||||
double e = grad3d(this.getGradient(m), localX - 1.0D, localY, localZ);
|
||||
double f = grad3d(this.getGradient(k), localX, localY - 1.0D, localZ);
|
||||
double g = grad3d(this.getGradient(n), localX - 1.0D, localY - 1.0D, localZ);
|
||||
double h = grad3d(this.getGradient(j + 1), localX, localY, localZ - 1.0D);
|
||||
double o = grad3d(this.getGradient(m + 1), localX - 1.0D, localY, localZ - 1.0D);
|
||||
double p = grad3d(this.getGradient(k + 1), localX, localY - 1.0D, localZ - 1.0D);
|
||||
double q = grad3d(this.getGradient(n + 1), localX - 1.0D, localY - 1.0D, localZ - 1.0D);
|
||||
return lerp3(fadeLocalX, fadeLocalY, fadeLocalZ, d, e, f, g, h, o, p, q);
|
||||
}
|
||||
|
||||
private static double grad3d(final int hash, final double x, final double y, final double z)
|
||||
private static double grad3d(int hash, double x, double y, double z)
|
||||
{
|
||||
final int i = hash & 15;
|
||||
int i = hash & 15;
|
||||
return dot3d(gradients3d[i], x, y, z);
|
||||
}
|
||||
|
||||
protected static double dot3d(final int[] gArr, final double x, final double y, final double z)
|
||||
protected static double dot3d(int[] gArr, double x, double y, double z)
|
||||
{
|
||||
return gArr[0] * x + gArr[1] * y + gArr[2] * z;
|
||||
}
|
||||
|
||||
public static double lerp3(final double deltaX, final double deltaY, final double deltaZ, final double d, final double e, final double f, final double g, final double h, final double i, final double j, final double k)
|
||||
public static double lerp3(double deltaX, double deltaY, double deltaZ, double d, double e, double f, double g, double h, double i, double j, double k)
|
||||
{
|
||||
return lerp(deltaZ, lerp2(deltaX, deltaY, d, e, f, g), lerp2(deltaX, deltaY, h, i, j, k));
|
||||
}
|
||||
|
||||
//2D
|
||||
public double sample2d(final double x, final double y)
|
||||
public double sample2d(double x, double y)
|
||||
{
|
||||
final double f = x + this.originX;
|
||||
final double g = y + this.originY;
|
||||
final int i = floor(f);
|
||||
final int j = floor(g);
|
||||
final double l = f - (double) i;
|
||||
final double m = g - (double) j;
|
||||
final double o = perlinFade(l);
|
||||
final double p = perlinFade(m);
|
||||
double f = x + this.originX;
|
||||
double g = y + this.originY;
|
||||
int i = floor(f);
|
||||
int j = floor(g);
|
||||
double l = f - (double) i;
|
||||
double m = g - (double) j;
|
||||
double o = perlinFade(l);
|
||||
double p = perlinFade(m);
|
||||
return this.sample2d(i, j, l, m, o, p) / 2 + 0.5;
|
||||
}
|
||||
|
||||
private double sample2d(final int sectionX, final int sectionY, final double localX, final double localY, final double fadeLocalX, final double fadeLocalY)
|
||||
private double sample2d(int sectionX, int sectionY, double localX, double localY, double fadeLocalX, double fadeLocalY)
|
||||
{
|
||||
final int j = this.getGradient(sectionX) + sectionY;
|
||||
final int m = this.getGradient(sectionX + 1) + sectionY;
|
||||
final double d = grad2d(this.getGradient(j), localX, localY);
|
||||
final double e = grad2d(this.getGradient(m), localX - 1.0D, localY);
|
||||
final double f = grad2d(this.getGradient(j + 1), localX, localY - 1.0D);
|
||||
final double g = grad2d(this.getGradient(m + 1), localX - 1.0D, localY - 1.0D);
|
||||
int j = this.getGradient(sectionX) + sectionY;
|
||||
int m = this.getGradient(sectionX + 1) + sectionY;
|
||||
double d = grad2d(this.getGradient(j), localX, localY);
|
||||
double e = grad2d(this.getGradient(m), localX - 1.0D, localY);
|
||||
double f = grad2d(this.getGradient(j + 1), localX, localY - 1.0D);
|
||||
double g = grad2d(this.getGradient(m + 1), localX - 1.0D, localY - 1.0D);
|
||||
|
||||
return lerp2(fadeLocalX, fadeLocalY, d, e, f, g);
|
||||
}
|
||||
|
||||
private static double grad2d(final int hash, final double x, final double y)
|
||||
private static double grad2d(int hash, double x, double y)
|
||||
{
|
||||
final int i = hash & 3;
|
||||
int i = hash & 3;
|
||||
return dot2d(gradients2d[i], x, y);
|
||||
}
|
||||
|
||||
protected static double dot2d(final int[] gArr, final double x, final double y)
|
||||
protected static double dot2d(int[] gArr, double x, double y)
|
||||
{
|
||||
return gArr[0] * x + gArr[1] * y;
|
||||
}
|
||||
|
||||
public static double lerp2(final double deltaX, final double deltaY, final double d, final double e, final double f, final double g)
|
||||
public static double lerp2(double deltaX, double deltaY, double d, double e, double f, double g)
|
||||
{
|
||||
return lerp(deltaY, lerp(deltaX, d, e), lerp(deltaX, f, g));
|
||||
}
|
||||
|
||||
// 1D
|
||||
public double sample1d(final double x)
|
||||
public double sample1d(double x)
|
||||
{
|
||||
final double f = x + this.originX;
|
||||
final int i = floor(f);
|
||||
final double l = f - i;
|
||||
final double o = perlinFade(l);
|
||||
double f = x + this.originX;
|
||||
int i = floor(f);
|
||||
double l = f - i;
|
||||
double o = perlinFade(l);
|
||||
return this.sample1d(i, l, o) + 0.5;
|
||||
}
|
||||
|
||||
private double sample1d(final int sectionX, final double localX, final double fadeLocalX)
|
||||
private double sample1d(int sectionX, double localX, double fadeLocalX)
|
||||
{
|
||||
final double d = grad1d(this.getGradient(sectionX), localX);
|
||||
final double e = grad1d(this.getGradient(sectionX + 1), localX - 1.0D);
|
||||
double d = grad1d(this.getGradient(sectionX), localX);
|
||||
double e = grad1d(this.getGradient(sectionX + 1), localX - 1.0D);
|
||||
return lerp(fadeLocalX, d, e);
|
||||
}
|
||||
|
||||
private static double grad1d(final int hash, final double x)
|
||||
private static double grad1d(int hash, double x)
|
||||
{
|
||||
return ((hash & 1) == 0) ? x : -x;
|
||||
}
|
||||
|
||||
public static double lerp(final double delta, final double first, final double second)
|
||||
public static double lerp(double delta, double first, double second)
|
||||
{
|
||||
return first + delta * (second - first);
|
||||
}
|
||||
|
||||
// shared
|
||||
public int getGradient(final int hash)
|
||||
public int getGradient(int hash)
|
||||
{
|
||||
return this.permutations[hash & 255] & 255;
|
||||
}
|
||||
|
||||
public static double perlinFade(final double d)
|
||||
public static double perlinFade(double d)
|
||||
{
|
||||
return d * d * d * (d * (d * 6.0D - 15.0D) + 10.0D);
|
||||
}
|
||||
|
||||
public static int floor(final double d)
|
||||
public static int floor(double d)
|
||||
{
|
||||
final int i = (int) d;
|
||||
int i = (int) d;
|
||||
return d < i ? i - 1 : i;
|
||||
}
|
||||
}
|
||||
@@ -24,12 +24,12 @@ public class ScarpetJsonDeserializer implements JsonDeserializer<Value>
|
||||
{
|
||||
|
||||
@Override
|
||||
public Value deserialize(final JsonElement json, final Type typeOfT, final JsonDeserializationContext context) throws JsonParseException
|
||||
public Value deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException
|
||||
{
|
||||
return parseElement(json);
|
||||
}
|
||||
|
||||
private Value parseElement(final JsonElement element) throws JsonParseException
|
||||
private Value parseElement(JsonElement element) throws JsonParseException
|
||||
{
|
||||
if (element.isJsonObject())
|
||||
{
|
||||
@@ -46,21 +46,21 @@ public class ScarpetJsonDeserializer implements JsonDeserializer<Value>
|
||||
return Value.NULL;
|
||||
}
|
||||
|
||||
private Value parseMap(final JsonObject jsonMap) throws JsonParseException
|
||||
private Value parseMap(JsonObject jsonMap) throws JsonParseException
|
||||
{
|
||||
final Map<Value, Value> map = new HashMap<>();
|
||||
Map<Value, Value> map = new HashMap<>();
|
||||
jsonMap.entrySet().forEach(entry -> map.put(new StringValue(entry.getKey()), parseElement(entry.getValue())));
|
||||
return MapValue.wrap(map);
|
||||
}
|
||||
|
||||
private Value parseList(final JsonArray jsonList) throws JsonParseException
|
||||
private Value parseList(JsonArray jsonList) throws JsonParseException
|
||||
{
|
||||
final List<Value> list = new ArrayList<>();
|
||||
List<Value> list = new ArrayList<>();
|
||||
jsonList.forEach(elem -> list.add(parseElement(elem)));
|
||||
return new ListValue(list);
|
||||
}
|
||||
|
||||
private Value parsePrimitive(final JsonPrimitive primitive) throws JsonParseException
|
||||
private Value parsePrimitive(JsonPrimitive primitive) throws JsonParseException
|
||||
{
|
||||
if (primitive.isString())
|
||||
{
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -73,25 +73,25 @@ public class ShapesRenderer
|
||||
put("item", (c, s) -> new RenderedSprite(c, s, true));
|
||||
}};
|
||||
|
||||
public ShapesRenderer(final Minecraft minecraftClient)
|
||||
public ShapesRenderer(Minecraft minecraftClient)
|
||||
{
|
||||
this.client = minecraftClient;
|
||||
shapes = new HashMap<>();
|
||||
labels = new HashMap<>();
|
||||
}
|
||||
|
||||
public void render(final PoseStack matrices, final Camera camera, final float partialTick)
|
||||
public void render(PoseStack matrices, Camera camera, float partialTick)
|
||||
{
|
||||
final Runnable token = Carpet.startProfilerSection("Scarpet client");
|
||||
Runnable token = Carpet.startProfilerSection("Scarpet client");
|
||||
//Camera camera = this.client.gameRenderer.getCamera();
|
||||
final ClientLevel iWorld = this.client.level;
|
||||
final ResourceKey<Level> dimensionType = iWorld.dimension();
|
||||
ClientLevel iWorld = this.client.level;
|
||||
ResourceKey<Level> dimensionType = iWorld.dimension();
|
||||
if ((shapes.get(dimensionType) == null || shapes.get(dimensionType).isEmpty()) &&
|
||||
(labels.get(dimensionType) == null || labels.get(dimensionType).isEmpty()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
final long currentTime = client.level.getGameTime();
|
||||
long currentTime = client.level.getGameTime();
|
||||
RenderSystem.enableDepthTest();
|
||||
RenderSystem.setShader(GameRenderer::getPositionColorShader);
|
||||
RenderSystem.depthFunc(515);
|
||||
@@ -107,21 +107,21 @@ public class ShapesRenderer
|
||||
//RenderSystem.polygonOffset(-3f, -3f);
|
||||
//RenderSystem.enablePolygonOffset();
|
||||
|
||||
final Tesselator tessellator = Tesselator.getInstance();
|
||||
final BufferBuilder bufferBuilder = tessellator.getBuilder();
|
||||
Tesselator tessellator = Tesselator.getInstance();
|
||||
BufferBuilder bufferBuilder = tessellator.getBuilder();
|
||||
|
||||
// render
|
||||
final double cameraX = camera.getPosition().x;
|
||||
final double cameraY = camera.getPosition().y;
|
||||
final double cameraZ = camera.getPosition().z;
|
||||
final boolean entityBoxes = client.getEntityRenderDispatcher().shouldRenderHitBoxes();
|
||||
double cameraX = camera.getPosition().x;
|
||||
double cameraY = camera.getPosition().y;
|
||||
double cameraZ = camera.getPosition().z;
|
||||
boolean entityBoxes = client.getEntityRenderDispatcher().shouldRenderHitBoxes();
|
||||
|
||||
if (shapes.size() != 0)
|
||||
if (!shapes.isEmpty())
|
||||
{
|
||||
shapes.get(dimensionType).long2ObjectEntrySet().removeIf(
|
||||
entry -> entry.getValue().isExpired(currentTime)
|
||||
);
|
||||
final PoseStack matrixStack = RenderSystem.getModelViewStack();
|
||||
PoseStack matrixStack = RenderSystem.getModelViewStack();
|
||||
matrixStack.pushPose();
|
||||
matrixStack.mulPoseMatrix(matrices.last().pose());
|
||||
RenderSystem.applyModelViewMatrix();
|
||||
@@ -147,7 +147,7 @@ public class ShapesRenderer
|
||||
RenderSystem.applyModelViewMatrix();
|
||||
|
||||
}
|
||||
if (labels.size() != 0)
|
||||
if (!labels.isEmpty())
|
||||
{
|
||||
labels.get(dimensionType).long2ObjectEntrySet().removeIf(
|
||||
entry -> entry.getValue().isExpired(currentTime)
|
||||
@@ -166,9 +166,9 @@ public class ShapesRenderer
|
||||
token.run();
|
||||
}
|
||||
|
||||
public void addShapes(final ListTag tag)
|
||||
public void addShapes(ListTag tag)
|
||||
{
|
||||
final Runnable token = Carpet.startProfilerSection("Scarpet client");
|
||||
Runnable token = Carpet.startProfilerSection("Scarpet client");
|
||||
for (int i = 0, count = tag.size(); i < count; i++)
|
||||
{
|
||||
addShape(tag.getCompound(i));
|
||||
@@ -176,14 +176,14 @@ public class ShapesRenderer
|
||||
token.run();
|
||||
}
|
||||
|
||||
public void addShape(final CompoundTag tag)
|
||||
public void addShape(CompoundTag tag)
|
||||
{
|
||||
final ShapeDispatcher.ExpiringShape shape = ShapeDispatcher.fromTag(tag, client.level);
|
||||
ShapeDispatcher.ExpiringShape shape = ShapeDispatcher.fromTag(tag, client.level);
|
||||
if (shape == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
final BiFunction<Minecraft, ShapeDispatcher.ExpiringShape, RenderedShape<? extends ShapeDispatcher.ExpiringShape>> shapeFactory;
|
||||
BiFunction<Minecraft, ShapeDispatcher.ExpiringShape, RenderedShape<? extends ShapeDispatcher.ExpiringShape>> shapeFactory;
|
||||
shapeFactory = renderedShapes.get(tag.getString("shape"));
|
||||
if (shapeFactory == null)
|
||||
{
|
||||
@@ -191,12 +191,12 @@ public class ShapesRenderer
|
||||
}
|
||||
else
|
||||
{
|
||||
final RenderedShape<?> rshape = shapeFactory.apply(client, shape);
|
||||
final ResourceKey<Level> dim = shape.shapeDimension;
|
||||
final long key = rshape.key();
|
||||
final Map<ResourceKey<Level>, Long2ObjectOpenHashMap<RenderedShape<? extends ShapeDispatcher.ExpiringShape>>> container =
|
||||
RenderedShape<?> rshape = shapeFactory.apply(client, shape);
|
||||
ResourceKey<Level> dim = shape.shapeDimension;
|
||||
long key = rshape.key();
|
||||
Map<ResourceKey<Level>, Long2ObjectOpenHashMap<RenderedShape<? extends ShapeDispatcher.ExpiringShape>>> container =
|
||||
rshape.stageDeux() ? labels : shapes;
|
||||
final RenderedShape<?> existing = container.computeIfAbsent(dim, d -> new Long2ObjectOpenHashMap<>()).get(key);
|
||||
RenderedShape<?> existing = container.computeIfAbsent(dim, d -> new Long2ObjectOpenHashMap<>()).get(key);
|
||||
if (existing != null)
|
||||
{ // promoting previous shape
|
||||
existing.promoteWith(rshape);
|
||||
@@ -217,7 +217,7 @@ public class ShapesRenderer
|
||||
|
||||
public void renewShapes()
|
||||
{
|
||||
final Runnable token = Carpet.startProfilerSection("Scarpet client");
|
||||
Runnable token = Carpet.startProfilerSection("Scarpet client");
|
||||
shapes.values().forEach(el -> el.values().forEach(shape -> shape.expiryTick++));
|
||||
labels.values().forEach(el -> el.values().forEach(shape -> shape.expiryTick++));
|
||||
|
||||
@@ -229,15 +229,15 @@ public class ShapesRenderer
|
||||
protected T shape;
|
||||
protected Minecraft client;
|
||||
long expiryTick;
|
||||
double renderEpsilon = 0;
|
||||
double renderEpsilon;
|
||||
|
||||
public abstract void renderLines(PoseStack matrices, Tesselator tessellator, BufferBuilder builder, double cx, double cy, double cz, float partialTick);
|
||||
|
||||
public void renderFaces(final Tesselator tessellator, final BufferBuilder builder, final double cx, final double cy, final double cz, final float partialTick)
|
||||
public void renderFaces(Tesselator tessellator, BufferBuilder builder, double cx, double cy, double cz, float partialTick)
|
||||
{
|
||||
}
|
||||
|
||||
protected RenderedShape(final Minecraft client, final T shape)
|
||||
protected RenderedShape(Minecraft client, T shape)
|
||||
{
|
||||
this.shape = shape;
|
||||
this.client = client;
|
||||
@@ -245,7 +245,7 @@ public class ShapesRenderer
|
||||
renderEpsilon = (3 + ((double) key()) / Long.MAX_VALUE) / 1000;
|
||||
}
|
||||
|
||||
public boolean isExpired(final long currentTick)
|
||||
public boolean isExpired(long currentTick)
|
||||
{
|
||||
return expiryTick < currentTick;
|
||||
}
|
||||
@@ -255,7 +255,7 @@ public class ShapesRenderer
|
||||
return shape.key(client.level.registryAccess());
|
||||
}
|
||||
|
||||
public boolean shouldRender(final ResourceKey<Level> dim)
|
||||
public boolean shouldRender(ResourceKey<Level> dim)
|
||||
{
|
||||
if (shape.followEntity <= 0)
|
||||
{
|
||||
@@ -277,7 +277,7 @@ public class ShapesRenderer
|
||||
return false;
|
||||
}
|
||||
|
||||
public void promoteWith(final RenderedShape<?> rshape)
|
||||
public void promoteWith(RenderedShape<?> rshape)
|
||||
{
|
||||
expiryTick = rshape.expiryTick;
|
||||
}
|
||||
@@ -293,7 +293,7 @@ public class ShapesRenderer
|
||||
private BlockState blockState;
|
||||
private BlockEntity BlockEntity = null;
|
||||
|
||||
protected RenderedSprite(final Minecraft client, final ShapeDispatcher.ExpiringShape shape, final boolean isitem)
|
||||
protected RenderedSprite(Minecraft client, ShapeDispatcher.ExpiringShape shape, boolean isitem)
|
||||
{
|
||||
super(client, (ShapeDispatcher.DisplayedSprite) shape);
|
||||
this.isitem = isitem;
|
||||
@@ -304,16 +304,16 @@ public class ShapesRenderer
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderLines(final PoseStack matrices, final Tesselator tessellator, final BufferBuilder builder, final double cx, final double cy,
|
||||
final double cz, final float partialTick)
|
||||
public void renderLines(PoseStack matrices, Tesselator tessellator, BufferBuilder builder, double cx, double cy,
|
||||
double cz, float partialTick)
|
||||
{
|
||||
if (shape.a == 0.0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final Vec3 v1 = shape.relativiseRender(client.level, shape.pos, partialTick);
|
||||
final Camera camera1 = client.gameRenderer.getMainCamera();
|
||||
Vec3 v1 = shape.relativiseRender(client.level, shape.pos, partialTick);
|
||||
Camera camera1 = client.gameRenderer.getMainCamera();
|
||||
|
||||
matrices.pushPose();
|
||||
if (!isitem)// blocks should use its center as the origin
|
||||
@@ -364,20 +364,20 @@ public class ShapesRenderer
|
||||
|
||||
blockState = shape.blockState;
|
||||
|
||||
final MultiBufferSource.BufferSource immediate = client.renderBuffers().bufferSource();
|
||||
MultiBufferSource.BufferSource immediate = client.renderBuffers().bufferSource();
|
||||
if (!isitem)
|
||||
{
|
||||
// draw the block itself
|
||||
if (blockState.getRenderShape() == RenderShape.MODEL)
|
||||
{
|
||||
|
||||
final var bakedModel = client.getBlockRenderer().getBlockModel(blockState);
|
||||
final int color = client.getBlockColors().getColor(blockState, client.level, blockPos, 0);
|
||||
var bakedModel = client.getBlockRenderer().getBlockModel(blockState);
|
||||
int color = client.getBlockColors().getColor(blockState, client.level, blockPos, 0);
|
||||
//dont know why there is a 0.
|
||||
//see https://github.com/senseiwells/EssentialClient/blob/4db1f291936f502304791ee323f369c206b3021d/src/main/java/me/senseiwells/essentialclient/utils/render/RenderHelper.java#L464
|
||||
final float red = (color >> 16 & 0xFF) / 255.0F;
|
||||
final float green = (color >> 8 & 0xFF) / 255.0F;
|
||||
final float blue = (color & 0xFF) / 255.0F;
|
||||
float red = (color >> 16 & 0xFF) / 255.0F;
|
||||
float green = (color >> 8 & 0xFF) / 255.0F;
|
||||
float blue = (color & 0xFF) / 255.0F;
|
||||
client.getBlockRenderer().getModelRenderer().renderModel(matrices.last(), immediate.getBuffer(ItemBlockRenderTypes.getRenderType(blockState, false)), blockState, bakedModel, red, green, blue, light, OverlayTexture.NO_OVERLAY);
|
||||
}
|
||||
|
||||
@@ -406,7 +406,7 @@ public class ShapesRenderer
|
||||
{
|
||||
if (BlockEntity != null)
|
||||
{
|
||||
final BlockEntityRenderer<BlockEntity> blockEntityRenderer = client.getBlockEntityRenderDispatcher().getRenderer(BlockEntity);
|
||||
BlockEntityRenderer<BlockEntity> blockEntityRenderer = client.getBlockEntityRenderDispatcher().getRenderer(BlockEntity);
|
||||
if (blockEntityRenderer != null)
|
||||
{
|
||||
blockEntityRenderer.render(BlockEntity, partialTick,
|
||||
@@ -440,19 +440,19 @@ public class ShapesRenderer
|
||||
}
|
||||
|
||||
// copy and modifiy a bit from net.minecraft.client.renderer.blockentity.ShulkerBoxRenderer.render
|
||||
public void sbrender(final ShulkerBoxBlockEntity shulkerBoxBlockEntity, final float f, final PoseStack poseStack, final MultiBufferSource multiBufferSource, final int i, final int j)
|
||||
public void sbrender(ShulkerBoxBlockEntity shulkerBoxBlockEntity, float f, PoseStack poseStack, MultiBufferSource multiBufferSource, int i, int j)
|
||||
{
|
||||
Direction direction = Direction.UP;
|
||||
if (shulkerBoxBlockEntity.hasLevel())
|
||||
{
|
||||
final BlockState blockState = shulkerBoxBlockEntity.getBlockState();
|
||||
BlockState blockState = shulkerBoxBlockEntity.getBlockState();
|
||||
if (blockState.getBlock() instanceof ShulkerBoxBlock)
|
||||
{
|
||||
direction = blockState.getValue(ShulkerBoxBlock.FACING);
|
||||
}
|
||||
}
|
||||
final DyeColor dyeColor = shulkerBoxBlockEntity.getColor();
|
||||
final Material material;
|
||||
DyeColor dyeColor = shulkerBoxBlockEntity.getColor();
|
||||
Material material;
|
||||
if (dyeColor == null)
|
||||
{
|
||||
material = Sheets.DEFAULT_SHULKER_TEXTURE_LOCATION;
|
||||
@@ -468,11 +468,11 @@ public class ShapesRenderer
|
||||
poseStack.mulPose(direction.getRotation());
|
||||
poseStack.scale(1.0F, -1.0F, -1.0F);
|
||||
poseStack.translate(0.0, -1.0, 0.0);
|
||||
final ShulkerModel<?> model = VanillaClient.ShulkerBoxRenderer_model(client.getBlockEntityRenderDispatcher().getRenderer(shulkerBoxBlockEntity));
|
||||
final ModelPart modelPart = model.getLid();
|
||||
ShulkerModel<?> model = VanillaClient.ShulkerBoxRenderer_model(client.getBlockEntityRenderDispatcher().getRenderer(shulkerBoxBlockEntity));
|
||||
ModelPart modelPart = model.getLid();
|
||||
modelPart.setPos(0.0F, 24.0F - shulkerBoxBlockEntity.getProgress(f) * 0.5F * 16.0F, 0.0F);
|
||||
modelPart.yRot = 270.0F * shulkerBoxBlockEntity.getProgress(f) * (float) (Math.PI / 180.0);
|
||||
final VertexConsumer vertexConsumer = material.buffer(multiBufferSource, RenderType::entityCutoutNoCull);
|
||||
VertexConsumer vertexConsumer = material.buffer(multiBufferSource, RenderType::entityCutoutNoCull);
|
||||
model.renderToBuffer(poseStack, vertexConsumer, i, j, 1.0F, 1.0F, 1.0F, 1.0F);
|
||||
poseStack.popPose();
|
||||
}
|
||||
@@ -482,21 +482,21 @@ public class ShapesRenderer
|
||||
public static class RenderedText extends RenderedShape<ShapeDispatcher.DisplayedText>
|
||||
{
|
||||
|
||||
protected RenderedText(final Minecraft client, final ShapeDispatcher.ExpiringShape shape)
|
||||
protected RenderedText(Minecraft client, ShapeDispatcher.ExpiringShape shape)
|
||||
{
|
||||
super(client, (ShapeDispatcher.DisplayedText) shape);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderLines(final PoseStack matrices, final Tesselator tessellator, final BufferBuilder builder, final double cx, final double cy, final double cz, final float partialTick)
|
||||
public void renderLines(PoseStack matrices, Tesselator tessellator, BufferBuilder builder, double cx, double cy, double cz, float partialTick)
|
||||
{
|
||||
if (shape.a == 0.0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
final Vec3 v1 = shape.relativiseRender(client.level, shape.pos, partialTick);
|
||||
final Camera camera1 = client.gameRenderer.getMainCamera();
|
||||
final Font textRenderer = client.font;
|
||||
Vec3 v1 = shape.relativiseRender(client.level, shape.pos, partialTick);
|
||||
Camera camera1 = client.gameRenderer.getMainCamera();
|
||||
Font textRenderer = client.font;
|
||||
if (shape.doublesided)
|
||||
{
|
||||
RenderSystem.disableCull();
|
||||
@@ -538,7 +538,7 @@ public class ShapesRenderer
|
||||
{
|
||||
text_x = (float) (-textRenderer.width(shape.value.getString()));
|
||||
}
|
||||
final MultiBufferSource.BufferSource immediate = MultiBufferSource.immediate(builder);
|
||||
MultiBufferSource.BufferSource immediate = MultiBufferSource.immediate(builder);
|
||||
textRenderer.drawInBatch(shape.value, text_x, 0.0F, shape.textcolor, false, matrices.last().pose(), immediate, false, shape.textbck, 15728880);
|
||||
immediate.endBatch();
|
||||
matrices.popPose();
|
||||
@@ -552,14 +552,14 @@ public class ShapesRenderer
|
||||
}
|
||||
|
||||
@Override
|
||||
public void promoteWith(final RenderedShape<?> rshape)
|
||||
public void promoteWith(RenderedShape<?> rshape)
|
||||
{
|
||||
super.promoteWith(rshape);
|
||||
try
|
||||
{
|
||||
this.shape.value = ((ShapeDispatcher.DisplayedText) rshape.shape).value;
|
||||
}
|
||||
catch (final ClassCastException ignored)
|
||||
catch (ClassCastException ignored)
|
||||
{
|
||||
CarpetScriptServer.LOG.error("shape " + rshape.shape.getClass() + " cannot cast to a Label");
|
||||
}
|
||||
@@ -569,20 +569,20 @@ public class ShapesRenderer
|
||||
public static class RenderedBox extends RenderedShape<ShapeDispatcher.Box>
|
||||
{
|
||||
|
||||
private RenderedBox(final Minecraft client, final ShapeDispatcher.ExpiringShape shape)
|
||||
private RenderedBox(Minecraft client, ShapeDispatcher.ExpiringShape shape)
|
||||
{
|
||||
super(client, (ShapeDispatcher.Box) shape);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderLines(final PoseStack matrices, final Tesselator tessellator, final BufferBuilder bufferBuilder, final double cx, final double cy, final double cz, final float partialTick)
|
||||
public void renderLines(PoseStack matrices, Tesselator tessellator, BufferBuilder bufferBuilder, double cx, double cy, double cz, float partialTick)
|
||||
{
|
||||
if (shape.a == 0.0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
final Vec3 v1 = shape.relativiseRender(client.level, shape.from, partialTick);
|
||||
final Vec3 v2 = shape.relativiseRender(client.level, shape.to, partialTick);
|
||||
Vec3 v1 = shape.relativiseRender(client.level, shape.from, partialTick);
|
||||
Vec3 v2 = shape.relativiseRender(client.level, shape.to, partialTick);
|
||||
drawBoxWireGLLines(tessellator, bufferBuilder,
|
||||
(float) (v1.x - cx - renderEpsilon), (float) (v1.y - cy - renderEpsilon), (float) (v1.z - cz - renderEpsilon),
|
||||
(float) (v2.x - cx + renderEpsilon), (float) (v2.y - cy + renderEpsilon), (float) (v2.z - cz + renderEpsilon),
|
||||
@@ -592,14 +592,14 @@ public class ShapesRenderer
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderFaces(final Tesselator tessellator, final BufferBuilder bufferBuilder, final double cx, final double cy, final double cz, final float partialTick)
|
||||
public void renderFaces(Tesselator tessellator, BufferBuilder bufferBuilder, double cx, double cy, double cz, float partialTick)
|
||||
{
|
||||
if (shape.fa == 0.0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
final Vec3 v1 = shape.relativiseRender(client.level, shape.from, partialTick);
|
||||
final Vec3 v2 = shape.relativiseRender(client.level, shape.to, partialTick);
|
||||
Vec3 v1 = shape.relativiseRender(client.level, shape.from, partialTick);
|
||||
Vec3 v2 = shape.relativiseRender(client.level, shape.to, partialTick);
|
||||
// consider using built-ins
|
||||
//DebugRenderer.drawBox(new Box(v1.x, v1.y, v1.z, v2.x, v2.y, v2.z), 0.5f, 0.5f, 0.5f, 0.5f);//shape.r, shape.g, shape.b, shape.a);
|
||||
drawBoxFaces(tessellator, bufferBuilder,
|
||||
@@ -613,16 +613,16 @@ public class ShapesRenderer
|
||||
|
||||
public static class RenderedLine extends RenderedShape<ShapeDispatcher.Line>
|
||||
{
|
||||
public RenderedLine(final Minecraft client, final ShapeDispatcher.ExpiringShape shape)
|
||||
public RenderedLine(Minecraft client, ShapeDispatcher.ExpiringShape shape)
|
||||
{
|
||||
super(client, (ShapeDispatcher.Line) shape);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderLines(final PoseStack matrices, final Tesselator tessellator, final BufferBuilder bufferBuilder, final double cx, final double cy, final double cz, final float partialTick)
|
||||
public void renderLines(PoseStack matrices, Tesselator tessellator, BufferBuilder bufferBuilder, double cx, double cy, double cz, float partialTick)
|
||||
{
|
||||
final Vec3 v1 = shape.relativiseRender(client.level, shape.from, partialTick);
|
||||
final Vec3 v2 = shape.relativiseRender(client.level, shape.to, partialTick);
|
||||
Vec3 v1 = shape.relativiseRender(client.level, shape.from, partialTick);
|
||||
Vec3 v2 = shape.relativiseRender(client.level, shape.to, partialTick);
|
||||
drawLine(tessellator, bufferBuilder,
|
||||
(float) (v1.x - cx - renderEpsilon), (float) (v1.y - cy - renderEpsilon), (float) (v1.z - cz - renderEpsilon),
|
||||
(float) (v2.x - cx + renderEpsilon), (float) (v2.y - cy + renderEpsilon), (float) (v2.z - cz + renderEpsilon),
|
||||
@@ -636,13 +636,13 @@ public class ShapesRenderer
|
||||
private static final VertexFormat.Mode[] faceIndices = new VertexFormat.Mode[]{
|
||||
Mode.LINES, Mode.LINE_STRIP, Mode.DEBUG_LINES, Mode.DEBUG_LINE_STRIP, Mode.TRIANGLES, Mode.TRIANGLE_STRIP, Mode.TRIANGLE_FAN, Mode.QUADS};
|
||||
|
||||
public RenderedPolyface(final Minecraft client, final ShapeDispatcher.ExpiringShape shape)
|
||||
public RenderedPolyface(Minecraft client, ShapeDispatcher.ExpiringShape shape)
|
||||
{
|
||||
super(client, (ShapeDispatcher.Polyface) shape);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderFaces(final Tesselator tessellator, final BufferBuilder bufferBuilder, final double cx, final double cy, final double cz, final float partialTick)
|
||||
public void renderFaces(Tesselator tessellator, BufferBuilder bufferBuilder, double cx, double cy, double cz, float partialTick)
|
||||
{
|
||||
if (shape.fa == 0)
|
||||
{
|
||||
@@ -659,9 +659,9 @@ public class ShapesRenderer
|
||||
}
|
||||
|
||||
bufferBuilder.begin(faceIndices[shape.mode], DefaultVertexFormat.POSITION_COLOR);
|
||||
for (int i = 0; i < shape.vertex_list.size(); i++)
|
||||
for (int i = 0; i < shape.vertexList.size(); i++)
|
||||
{
|
||||
Vec3 vec = shape.vertex_list.get(i);
|
||||
Vec3 vec = shape.vertexList.get(i);
|
||||
if (shape.relative.get(i))
|
||||
{
|
||||
vec = shape.relativiseRender(client.level, vec, partialTick);
|
||||
@@ -678,8 +678,8 @@ public class ShapesRenderer
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderLines(final PoseStack matrices, final Tesselator tessellator, final BufferBuilder builder, final double cx, final double cy,
|
||||
final double cz, final float partialTick)
|
||||
public void renderLines(PoseStack matrices, Tesselator tessellator, BufferBuilder builder, double cx, double cy,
|
||||
double cz, float partialTick)
|
||||
{
|
||||
if (shape.a == 0)
|
||||
{
|
||||
@@ -690,9 +690,9 @@ public class ShapesRenderer
|
||||
{
|
||||
builder.begin(VertexFormat.Mode.DEBUG_LINE_STRIP, DefaultVertexFormat.POSITION_COLOR);
|
||||
Vec3 vec0 = null;
|
||||
for (int i = 0; i < shape.vertex_list.size(); i++)
|
||||
for (int i = 0; i < shape.vertexList.size(); i++)
|
||||
{
|
||||
Vec3 vec = shape.vertex_list.get(i);
|
||||
Vec3 vec = shape.vertexList.get(i);
|
||||
if (shape.relative.get(i))
|
||||
{
|
||||
vec = shape.relativiseRender(client.level, vec, partialTick);
|
||||
@@ -708,9 +708,9 @@ public class ShapesRenderer
|
||||
if (shape.inneredges)
|
||||
{
|
||||
builder.begin(VertexFormat.Mode.DEBUG_LINES, DefaultVertexFormat.POSITION_COLOR);
|
||||
for (int i = 1; i < shape.vertex_list.size() - 1; i++)
|
||||
for (int i = 1; i < shape.vertexList.size() - 1; i++)
|
||||
{
|
||||
Vec3 vec = shape.vertex_list.get(i);
|
||||
Vec3 vec = shape.vertexList.get(i);
|
||||
if (shape.relative.get(i))
|
||||
{
|
||||
vec = shape.relativiseRender(client.level, vec, partialTick);
|
||||
@@ -726,26 +726,26 @@ public class ShapesRenderer
|
||||
if (shape.mode == 5)
|
||||
{
|
||||
builder.begin(VertexFormat.Mode.DEBUG_LINE_STRIP, DefaultVertexFormat.POSITION_COLOR);
|
||||
Vec3 vec = shape.vertex_list.get(1);
|
||||
Vec3 vec = shape.vertexList.get(1);
|
||||
if (shape.relative.get(1))
|
||||
{
|
||||
vec = shape.relativiseRender(client.level, vec, partialTick);
|
||||
}
|
||||
builder.vertex(vec.x() - cx, vec.y() - cy, vec.z() - cz).color(shape.r, shape.g, shape.b, shape.a).endVertex();
|
||||
int i;
|
||||
for (i = 0; i < shape.vertex_list.size(); i += 2)
|
||||
for (i = 0; i < shape.vertexList.size(); i += 2)
|
||||
{
|
||||
vec = shape.vertex_list.get(i);
|
||||
vec = shape.vertexList.get(i);
|
||||
if (shape.relative.get(i))
|
||||
{
|
||||
vec = shape.relativiseRender(client.level, vec, partialTick);
|
||||
}
|
||||
builder.vertex(vec.x() - cx, vec.y() - cy, vec.z() - cz).color(shape.r, shape.g, shape.b, shape.a).endVertex();
|
||||
}
|
||||
i = shape.vertex_list.size() - 1;
|
||||
i = shape.vertexList.size() - 1;
|
||||
for (i -= 1 - i % 2; i > 0; i -= 2)
|
||||
{
|
||||
vec = shape.vertex_list.get(i);
|
||||
vec = shape.vertexList.get(i);
|
||||
if (shape.relative.get(i))
|
||||
{
|
||||
vec = shape.relativiseRender(client.level, vec, partialTick);
|
||||
@@ -754,9 +754,9 @@ public class ShapesRenderer
|
||||
}
|
||||
if (shape.inneredges)
|
||||
{
|
||||
for (i = 2; i < shape.vertex_list.size() - 1; i++)
|
||||
for (i = 2; i < shape.vertexList.size() - 1; i++)
|
||||
{
|
||||
vec = shape.vertex_list.get(i);
|
||||
vec = shape.vertexList.get(i);
|
||||
if (shape.relative.get(i))
|
||||
{
|
||||
vec = shape.relativiseRender(client.level, vec, partialTick);
|
||||
@@ -770,21 +770,21 @@ public class ShapesRenderer
|
||||
if (shape.mode == 4)
|
||||
{
|
||||
builder.begin(VertexFormat.Mode.DEBUG_LINES, DefaultVertexFormat.POSITION_COLOR);
|
||||
for (int i = 0; i < shape.vertex_list.size(); i++)
|
||||
for (int i = 0; i < shape.vertexList.size(); i++)
|
||||
{
|
||||
Vec3 vecA = shape.vertex_list.get(i);
|
||||
Vec3 vecA = shape.vertexList.get(i);
|
||||
if (shape.relative.get(i))
|
||||
{
|
||||
vecA = shape.relativiseRender(client.level, vecA, partialTick);
|
||||
}
|
||||
i++;
|
||||
Vec3 vecB = shape.vertex_list.get(i);
|
||||
Vec3 vecB = shape.vertexList.get(i);
|
||||
if (shape.relative.get(i))
|
||||
{
|
||||
vecB = shape.relativiseRender(client.level, vecB, partialTick);
|
||||
}
|
||||
i++;
|
||||
Vec3 vecC = shape.vertex_list.get(i);
|
||||
Vec3 vecC = shape.vertexList.get(i);
|
||||
if (shape.relative.get(i))
|
||||
{
|
||||
vecC = shape.relativiseRender(client.level, vecC, partialTick);
|
||||
@@ -805,19 +805,19 @@ public class ShapesRenderer
|
||||
|
||||
public static class RenderedSphere extends RenderedShape<ShapeDispatcher.Sphere>
|
||||
{
|
||||
public RenderedSphere(final Minecraft client, final ShapeDispatcher.ExpiringShape shape)
|
||||
public RenderedSphere(Minecraft client, ShapeDispatcher.ExpiringShape shape)
|
||||
{
|
||||
super(client, (ShapeDispatcher.Sphere) shape);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderLines(final PoseStack matrices, final Tesselator tessellator, final BufferBuilder bufferBuilder, final double cx, final double cy, final double cz, final float partialTick)
|
||||
public void renderLines(PoseStack matrices, Tesselator tessellator, BufferBuilder bufferBuilder, double cx, double cy, double cz, float partialTick)
|
||||
{
|
||||
if (shape.a == 0.0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
final Vec3 vc = shape.relativiseRender(client.level, shape.center, partialTick);
|
||||
Vec3 vc = shape.relativiseRender(client.level, shape.center, partialTick);
|
||||
drawSphereWireframe(tessellator, bufferBuilder,
|
||||
(float) (vc.x - cx), (float) (vc.y - cy), (float) (vc.z - cz),
|
||||
(float) (shape.radius + renderEpsilon), shape.subdivisions,
|
||||
@@ -825,13 +825,13 @@ public class ShapesRenderer
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderFaces(final Tesselator tessellator, final BufferBuilder bufferBuilder, final double cx, final double cy, final double cz, final float partialTick)
|
||||
public void renderFaces(Tesselator tessellator, BufferBuilder bufferBuilder, double cx, double cy, double cz, float partialTick)
|
||||
{
|
||||
if (shape.fa == 0.0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
final Vec3 vc = shape.relativiseRender(client.level, shape.center, partialTick);
|
||||
Vec3 vc = shape.relativiseRender(client.level, shape.center, partialTick);
|
||||
drawSphereFaces(tessellator, bufferBuilder,
|
||||
(float) (vc.x - cx), (float) (vc.y - cy), (float) (vc.z - cz),
|
||||
(float) (shape.radius + renderEpsilon), shape.subdivisions,
|
||||
@@ -841,20 +841,20 @@ public class ShapesRenderer
|
||||
|
||||
public static class RenderedCylinder extends RenderedShape<ShapeDispatcher.Cylinder>
|
||||
{
|
||||
public RenderedCylinder(final Minecraft client, final ShapeDispatcher.ExpiringShape shape)
|
||||
public RenderedCylinder(Minecraft client, ShapeDispatcher.ExpiringShape shape)
|
||||
{
|
||||
super(client, (ShapeDispatcher.Cylinder) shape);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderLines(final PoseStack matrices, final Tesselator tessellator, final BufferBuilder bufferBuilder, final double cx, final double cy, final double cz, final float partialTick)
|
||||
public void renderLines(PoseStack matrices, Tesselator tessellator, BufferBuilder bufferBuilder, double cx, double cy, double cz, float partialTick)
|
||||
{
|
||||
if (shape.a == 0.0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
final Vec3 vc = shape.relativiseRender(client.level, shape.center, partialTick);
|
||||
final double dir = Mth.sign(shape.height);
|
||||
Vec3 vc = shape.relativiseRender(client.level, shape.center, partialTick);
|
||||
double dir = Mth.sign(shape.height);
|
||||
drawCylinderWireframe(tessellator, bufferBuilder,
|
||||
(float) (vc.x - cx - dir * renderEpsilon), (float) (vc.y - cy - dir * renderEpsilon), (float) (vc.z - cz - dir * renderEpsilon),
|
||||
(float) (shape.radius + renderEpsilon), (float) (shape.height + 2 * dir * renderEpsilon), shape.axis,
|
||||
@@ -864,14 +864,14 @@ public class ShapesRenderer
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderFaces(final Tesselator tessellator, final BufferBuilder bufferBuilder, final double cx, final double cy, final double cz, final float partialTick)
|
||||
public void renderFaces(Tesselator tessellator, BufferBuilder bufferBuilder, double cx, double cy, double cz, float partialTick)
|
||||
{
|
||||
if (shape.fa == 0.0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
final Vec3 vc = shape.relativiseRender(client.level, shape.center, partialTick);
|
||||
final double dir = Mth.sign(shape.height);
|
||||
Vec3 vc = shape.relativiseRender(client.level, shape.center, partialTick);
|
||||
double dir = Mth.sign(shape.height);
|
||||
drawCylinderFaces(tessellator, bufferBuilder,
|
||||
(float) (vc.x - cx - dir * renderEpsilon), (float) (vc.y - cy - dir * renderEpsilon), (float) (vc.z - cz - dir * renderEpsilon),
|
||||
(float) (shape.radius + renderEpsilon), (float) (shape.height + 2 * dir * renderEpsilon), shape.axis,
|
||||
@@ -882,7 +882,7 @@ public class ShapesRenderer
|
||||
|
||||
// some raw shit
|
||||
|
||||
public static void drawLine(final Tesselator tessellator, final BufferBuilder builder, final float x1, final float y1, final float z1, final float x2, final float y2, final float z2, final float red1, final float grn1, final float blu1, final float alpha)
|
||||
public static void drawLine(Tesselator tessellator, BufferBuilder builder, float x1, float y1, float z1, float x2, float y2, float z2, float red1, float grn1, float blu1, float alpha)
|
||||
{
|
||||
builder.begin(VertexFormat.Mode.DEBUG_LINES, DefaultVertexFormat.POSITION_COLOR);
|
||||
builder.vertex(x1, y1, z1).color(red1, grn1, blu1, alpha).endVertex();
|
||||
@@ -891,11 +891,11 @@ public class ShapesRenderer
|
||||
}
|
||||
|
||||
public static void drawBoxWireGLLines(
|
||||
final Tesselator tessellator, final BufferBuilder builder,
|
||||
final float x1, final float y1, final float z1,
|
||||
final float x2, final float y2, final float z2,
|
||||
final boolean xthick, final boolean ythick, final boolean zthick,
|
||||
final float red1, final float grn1, final float blu1, final float alpha, final float red2, final float grn2, final float blu2)
|
||||
Tesselator tessellator, BufferBuilder builder,
|
||||
float x1, float y1, float z1,
|
||||
float x2, float y2, float z2,
|
||||
boolean xthick, boolean ythick, boolean zthick,
|
||||
float red1, float grn1, float blu1, float alpha, float red2, float grn2, float blu2)
|
||||
{
|
||||
builder.begin(VertexFormat.Mode.DEBUG_LINES, DefaultVertexFormat.POSITION_COLOR);
|
||||
if (xthick)
|
||||
@@ -944,11 +944,11 @@ public class ShapesRenderer
|
||||
}
|
||||
|
||||
public static void drawBoxFaces(
|
||||
final Tesselator tessellator, final BufferBuilder builder,
|
||||
final float x1, final float y1, final float z1,
|
||||
final float x2, final float y2, final float z2,
|
||||
final boolean xthick, final boolean ythick, final boolean zthick,
|
||||
final float red1, final float grn1, final float blu1, final float alpha)
|
||||
Tesselator tessellator, BufferBuilder builder,
|
||||
float x1, float y1, float z1,
|
||||
float x2, float y2, float z2,
|
||||
boolean xthick, boolean ythick, boolean zthick,
|
||||
float red1, float grn1, float blu1, float alpha)
|
||||
{
|
||||
builder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR);
|
||||
|
||||
@@ -1004,14 +1004,14 @@ public class ShapesRenderer
|
||||
tessellator.end();
|
||||
}
|
||||
|
||||
public static void drawCylinderWireframe(final Tesselator tessellator, final BufferBuilder builder,
|
||||
final float cx, final float cy, final float cz,
|
||||
final float r, final float h, final Direction.Axis axis, final int subd, final boolean isFlat,
|
||||
final float red, final float grn, final float blu, final float alpha)
|
||||
public static void drawCylinderWireframe(Tesselator tessellator, BufferBuilder builder,
|
||||
float cx, float cy, float cz,
|
||||
float r, float h, Direction.Axis axis, int subd, boolean isFlat,
|
||||
float red, float grn, float blu, float alpha)
|
||||
{
|
||||
final float step = (float) Math.PI / (subd / 2);
|
||||
final int num_steps180 = (int) (Math.PI / step) + 1;
|
||||
final int num_steps360 = (int) (2 * Math.PI / step);
|
||||
float step = (float) Math.PI / (subd / 2);
|
||||
int num_steps180 = (int) (Math.PI / step) + 1;
|
||||
int num_steps360 = (int) (2 * Math.PI / step);
|
||||
int hsteps = 1;
|
||||
float hstep = 1.0f;
|
||||
if (!isFlat)
|
||||
@@ -1024,14 +1024,14 @@ public class ShapesRenderer
|
||||
{
|
||||
for (int dh = 0; dh < hsteps; dh++)
|
||||
{
|
||||
final float hh = dh * hstep;
|
||||
float hh = dh * hstep;
|
||||
builder.begin(VertexFormat.Mode.DEBUG_LINE_STRIP, DefaultVertexFormat.POSITION_COLOR); // line loop to line strip
|
||||
for (int i = 0; i <= num_steps360 + 1; i++)
|
||||
{
|
||||
final float theta = step * i;
|
||||
final float x = r * Mth.cos(theta);
|
||||
final float y = hh;
|
||||
final float z = r * Mth.sin(theta);
|
||||
float theta = step * i;
|
||||
float x = r * Mth.cos(theta);
|
||||
float y = hh;
|
||||
float z = r * Mth.sin(theta);
|
||||
builder.vertex(x + cx, y + cy, z + cz).color(red, grn, blu, alpha).endVertex();
|
||||
}
|
||||
tessellator.end();
|
||||
@@ -1042,10 +1042,10 @@ public class ShapesRenderer
|
||||
for (int i = 0; i <= num_steps180; i++)
|
||||
{
|
||||
builder.begin(VertexFormat.Mode.DEBUG_LINE_STRIP, DefaultVertexFormat.POSITION_COLOR); // line loop to line strip
|
||||
final float theta = step * i;
|
||||
final float x = r * Mth.cos(theta);
|
||||
float theta = step * i;
|
||||
float x = r * Mth.cos(theta);
|
||||
|
||||
final float z = r * Mth.sin(theta);
|
||||
float z = r * Mth.sin(theta);
|
||||
|
||||
builder.vertex(cx - x, cy + 0, cz + z).color(red, grn, blu, alpha).endVertex();
|
||||
builder.vertex(cx + x, cy + 0, cz - z).color(red, grn, blu, alpha).endVertex();
|
||||
@@ -1060,9 +1060,9 @@ public class ShapesRenderer
|
||||
builder.begin(VertexFormat.Mode.DEBUG_LINES, DefaultVertexFormat.POSITION_COLOR);
|
||||
for (int i = 0; i <= num_steps180; i++)
|
||||
{
|
||||
final float theta = step * i;
|
||||
final float x = r * Mth.cos(theta);
|
||||
final float z = r * Mth.sin(theta);
|
||||
float theta = step * i;
|
||||
float x = r * Mth.cos(theta);
|
||||
float z = r * Mth.sin(theta);
|
||||
builder.vertex(cx - x, cy, cz + z).color(red, grn, blu, alpha).endVertex();
|
||||
builder.vertex(cx + x, cy, cz - z).color(red, grn, blu, alpha).endVertex();
|
||||
}
|
||||
@@ -1074,14 +1074,14 @@ public class ShapesRenderer
|
||||
{
|
||||
for (int dh = 0; dh < hsteps; dh++)
|
||||
{
|
||||
final float hh = dh * hstep;
|
||||
float hh = dh * hstep;
|
||||
builder.begin(VertexFormat.Mode.DEBUG_LINE_STRIP, DefaultVertexFormat.POSITION_COLOR); // line loop to line strip
|
||||
for (int i = 0; i <= num_steps360; i++)
|
||||
{
|
||||
final float theta = step * i;
|
||||
final float z = r * Mth.cos(theta);
|
||||
final float x = hh;
|
||||
final float y = r * Mth.sin(theta);
|
||||
float theta = step * i;
|
||||
float z = r * Mth.cos(theta);
|
||||
float x = hh;
|
||||
float y = r * Mth.sin(theta);
|
||||
builder.vertex(x + cx, y + cy, z + cz).color(red, grn, blu, alpha).endVertex();
|
||||
}
|
||||
tessellator.end();
|
||||
@@ -1092,10 +1092,10 @@ public class ShapesRenderer
|
||||
for (int i = 0; i <= num_steps180; i++)
|
||||
{
|
||||
builder.begin(VertexFormat.Mode.DEBUG_LINE_STRIP, DefaultVertexFormat.POSITION_COLOR); // line loop to line strip
|
||||
final float theta = step * i;
|
||||
final float y = r * Mth.cos(theta);
|
||||
float theta = step * i;
|
||||
float y = r * Mth.cos(theta);
|
||||
|
||||
final float z = r * Mth.sin(theta);
|
||||
float z = r * Mth.sin(theta);
|
||||
|
||||
builder.vertex(cx + 0, cy - y, cz + z).color(red, grn, blu, alpha).endVertex();
|
||||
builder.vertex(cx + 0, cy + y, cz - z).color(red, grn, blu, alpha).endVertex();
|
||||
@@ -1109,9 +1109,9 @@ public class ShapesRenderer
|
||||
builder.begin(VertexFormat.Mode.DEBUG_LINES, DefaultVertexFormat.POSITION_COLOR);
|
||||
for (int i = 0; i <= num_steps180; i++)
|
||||
{
|
||||
final float theta = step * i;
|
||||
final float y = r * Mth.cos(theta);
|
||||
final float z = r * Mth.sin(theta);
|
||||
float theta = step * i;
|
||||
float y = r * Mth.cos(theta);
|
||||
float z = r * Mth.sin(theta);
|
||||
builder.vertex(cx, cy - y, cz + z).color(red, grn, blu, alpha).endVertex();
|
||||
builder.vertex(cx, cy + y, cz - z).color(red, grn, blu, alpha).endVertex();
|
||||
}
|
||||
@@ -1122,14 +1122,14 @@ public class ShapesRenderer
|
||||
{
|
||||
for (int dh = 0; dh < hsteps; dh++)
|
||||
{
|
||||
final float hh = dh * hstep;
|
||||
float hh = dh * hstep;
|
||||
builder.begin(VertexFormat.Mode.DEBUG_LINE_STRIP, DefaultVertexFormat.POSITION_COLOR); // line loop to line strip
|
||||
for (int i = 0; i <= num_steps360; i++)
|
||||
{
|
||||
final float theta = step * i;
|
||||
final float y = r * Mth.cos(theta);
|
||||
final float z = hh;
|
||||
final float x = r * Mth.sin(theta);
|
||||
float theta = step * i;
|
||||
float y = r * Mth.cos(theta);
|
||||
float z = hh;
|
||||
float x = r * Mth.sin(theta);
|
||||
builder.vertex(x + cx, y + cy, z + cz).color(red, grn, blu, alpha).endVertex();
|
||||
}
|
||||
tessellator.end();
|
||||
@@ -1139,10 +1139,10 @@ public class ShapesRenderer
|
||||
for (int i = 0; i <= num_steps180; i++)
|
||||
{
|
||||
builder.begin(VertexFormat.Mode.DEBUG_LINE_STRIP, DefaultVertexFormat.POSITION_COLOR); // line loop to line strip
|
||||
final float theta = step * i;
|
||||
final float x = r * Mth.cos(theta);
|
||||
float theta = step * i;
|
||||
float x = r * Mth.cos(theta);
|
||||
|
||||
final float y = r * Mth.sin(theta);
|
||||
float y = r * Mth.sin(theta);
|
||||
|
||||
builder.vertex(cx + x, cy - y, cz + 0).color(red, grn, blu, alpha).endVertex();
|
||||
builder.vertex(cx - x, cy + y, cz + 0).color(red, grn, blu, alpha).endVertex();
|
||||
@@ -1156,9 +1156,9 @@ public class ShapesRenderer
|
||||
builder.begin(VertexFormat.Mode.DEBUG_LINES, DefaultVertexFormat.POSITION_COLOR);
|
||||
for (int i = 0; i <= num_steps180; i++)
|
||||
{
|
||||
final float theta = step * i;
|
||||
final float x = r * Mth.cos(theta);
|
||||
final float y = r * Mth.sin(theta);
|
||||
float theta = step * i;
|
||||
float x = r * Mth.cos(theta);
|
||||
float y = r * Mth.sin(theta);
|
||||
builder.vertex(cx + x, cy - y, cz).color(red, grn, blu, alpha).endVertex();
|
||||
builder.vertex(cx - x, cy + y, cz).color(red, grn, blu, alpha).endVertex();
|
||||
}
|
||||
@@ -1168,14 +1168,14 @@ public class ShapesRenderer
|
||||
}
|
||||
}
|
||||
|
||||
public static void drawCylinderFaces(final Tesselator tessellator, final BufferBuilder builder,
|
||||
final float cx, final float cy, final float cz,
|
||||
final float r, final float h, final Direction.Axis axis, final int subd, final boolean isFlat,
|
||||
final float red, final float grn, final float blu, final float alpha)
|
||||
public static void drawCylinderFaces(Tesselator tessellator, BufferBuilder builder,
|
||||
float cx, float cy, float cz,
|
||||
float r, float h, Direction.Axis axis, int subd, boolean isFlat,
|
||||
float red, float grn, float blu, float alpha)
|
||||
{
|
||||
final float step = (float) Math.PI / (subd / 2);
|
||||
float step = (float) Math.PI / (subd / 2);
|
||||
//final int num_steps180 = (int) (Math.PI / step) + 1;
|
||||
final int num_steps360 = (int) (2 * Math.PI / step) + 1;
|
||||
int num_steps360 = (int) (2 * Math.PI / step) + 1;
|
||||
|
||||
if (axis == Direction.Axis.Y)
|
||||
{
|
||||
@@ -1184,9 +1184,9 @@ public class ShapesRenderer
|
||||
builder.vertex(cx, cy, cz).color(red, grn, blu, alpha).endVertex();
|
||||
for (int i = 0; i <= num_steps360; i++)
|
||||
{
|
||||
final float theta = step * i;
|
||||
final float x = r * Mth.cos(theta);
|
||||
final float z = r * Mth.sin(theta);
|
||||
float theta = step * i;
|
||||
float x = r * Mth.cos(theta);
|
||||
float z = r * Mth.sin(theta);
|
||||
builder.vertex(x + cx, cy, z + cz).color(red, grn, blu, alpha).endVertex();
|
||||
}
|
||||
tessellator.end();
|
||||
@@ -1196,9 +1196,9 @@ public class ShapesRenderer
|
||||
builder.vertex(cx, cy + h, cz).color(red, grn, blu, alpha).endVertex();
|
||||
for (int i = 0; i <= num_steps360; i++)
|
||||
{
|
||||
final float theta = step * i;
|
||||
final float x = r * Mth.cos(theta);
|
||||
final float z = r * Mth.sin(theta);
|
||||
float theta = step * i;
|
||||
float x = r * Mth.cos(theta);
|
||||
float z = r * Mth.sin(theta);
|
||||
builder.vertex(x + cx, cy + h, z + cz).color(red, grn, blu, alpha).endVertex();
|
||||
}
|
||||
tessellator.end();
|
||||
@@ -1208,9 +1208,9 @@ public class ShapesRenderer
|
||||
float zp = r * 0;
|
||||
for (int i = 1; i <= num_steps360; i++)
|
||||
{
|
||||
final float theta = step * i;
|
||||
final float x = r * Mth.cos(theta);
|
||||
final float z = r * Mth.sin(theta);
|
||||
float theta = step * i;
|
||||
float x = r * Mth.cos(theta);
|
||||
float z = r * Mth.sin(theta);
|
||||
builder.vertex(cx + xp, cy + 0, cz + zp).color(red, grn, blu, alpha).endVertex();
|
||||
builder.vertex(cx + xp, cy + h, cz + zp).color(red, grn, blu, alpha).endVertex();
|
||||
builder.vertex(cx + x, cy + h, cz + z).color(red, grn, blu, alpha).endVertex();
|
||||
@@ -1228,9 +1228,9 @@ public class ShapesRenderer
|
||||
builder.vertex(cx, cy, cz).color(red, grn, blu, alpha).endVertex();
|
||||
for (int i = 0; i <= num_steps360; i++)
|
||||
{
|
||||
final float theta = step * i;
|
||||
final float y = r * Mth.cos(theta);
|
||||
final float z = r * Mth.sin(theta);
|
||||
float theta = step * i;
|
||||
float y = r * Mth.cos(theta);
|
||||
float z = r * Mth.sin(theta);
|
||||
builder.vertex(cx, cy + y, z + cz).color(red, grn, blu, alpha).endVertex();
|
||||
}
|
||||
tessellator.end();
|
||||
@@ -1240,9 +1240,9 @@ public class ShapesRenderer
|
||||
builder.vertex(cx + h, cy, cz).color(red, grn, blu, alpha).endVertex();
|
||||
for (int i = 0; i <= num_steps360; i++)
|
||||
{
|
||||
final float theta = step * i;
|
||||
final float y = r * Mth.cos(theta);
|
||||
final float z = r * Mth.sin(theta);
|
||||
float theta = step * i;
|
||||
float y = r * Mth.cos(theta);
|
||||
float z = r * Mth.sin(theta);
|
||||
builder.vertex(cx + h, cy + y, cz + z).color(red, grn, blu, alpha).endVertex();
|
||||
}
|
||||
tessellator.end();
|
||||
@@ -1252,9 +1252,9 @@ public class ShapesRenderer
|
||||
float zp = r * 0;
|
||||
for (int i = 1; i <= num_steps360; i++)
|
||||
{
|
||||
final float theta = step * i;
|
||||
final float y = r * Mth.cos(theta);
|
||||
final float z = r * Mth.sin(theta);
|
||||
float theta = step * i;
|
||||
float y = r * Mth.cos(theta);
|
||||
float z = r * Mth.sin(theta);
|
||||
builder.vertex(cx + 0, cy + yp, cz + zp).color(red, grn, blu, alpha).endVertex();
|
||||
builder.vertex(cx + h, cy + yp, cz + zp).color(red, grn, blu, alpha).endVertex();
|
||||
builder.vertex(cx + h, cy + y, cz + z).color(red, grn, blu, alpha).endVertex();
|
||||
@@ -1271,9 +1271,9 @@ public class ShapesRenderer
|
||||
builder.vertex(cx, cy, cz).color(red, grn, blu, alpha).endVertex();
|
||||
for (int i = 0; i <= num_steps360; i++)
|
||||
{
|
||||
final float theta = step * i;
|
||||
final float x = r * Mth.cos(theta);
|
||||
final float y = r * Mth.sin(theta);
|
||||
float theta = step * i;
|
||||
float x = r * Mth.cos(theta);
|
||||
float y = r * Mth.sin(theta);
|
||||
builder.vertex(x + cx, cy + y, cz).color(red, grn, blu, alpha).endVertex();
|
||||
}
|
||||
tessellator.end();
|
||||
@@ -1283,9 +1283,9 @@ public class ShapesRenderer
|
||||
builder.vertex(cx, cy, cz + h).color(red, grn, blu, alpha).endVertex();
|
||||
for (int i = 0; i <= num_steps360; i++)
|
||||
{
|
||||
final float theta = step * i;
|
||||
final float x = r * Mth.cos(theta);
|
||||
final float y = r * Mth.sin(theta);
|
||||
float theta = step * i;
|
||||
float x = r * Mth.cos(theta);
|
||||
float y = r * Mth.sin(theta);
|
||||
builder.vertex(x + cx, cy + y, cz + h).color(red, grn, blu, alpha).endVertex();
|
||||
}
|
||||
tessellator.end();
|
||||
@@ -1295,9 +1295,9 @@ public class ShapesRenderer
|
||||
float yp = 0;
|
||||
for (int i = 1; i <= num_steps360; i++)
|
||||
{
|
||||
final float theta = step * i;
|
||||
final float x = r * Mth.cos(theta);
|
||||
final float y = r * Mth.sin(theta);
|
||||
float theta = step * i;
|
||||
float x = r * Mth.cos(theta);
|
||||
float y = r * Mth.sin(theta);
|
||||
builder.vertex(cx + xp, cy + yp, cz + 0).color(red, grn, blu, alpha).endVertex();
|
||||
builder.vertex(cx + xp, cy + yp, cz + h).color(red, grn, blu, alpha).endVertex();
|
||||
builder.vertex(cx + x, cy + y, cz + h).color(red, grn, blu, alpha).endVertex();
|
||||
@@ -1310,24 +1310,24 @@ public class ShapesRenderer
|
||||
}
|
||||
}
|
||||
|
||||
public static void drawSphereWireframe(final Tesselator tessellator, final BufferBuilder builder,
|
||||
final float cx, final float cy, final float cz,
|
||||
final float r, final int subd,
|
||||
final float red, final float grn, final float blu, final float alpha)
|
||||
public static void drawSphereWireframe(Tesselator tessellator, BufferBuilder builder,
|
||||
float cx, float cy, float cz,
|
||||
float r, int subd,
|
||||
float red, float grn, float blu, float alpha)
|
||||
{
|
||||
final float step = (float) Math.PI / (subd / 2);
|
||||
final int num_steps180 = (int) (Math.PI / step) + 1;
|
||||
final int num_steps360 = (int) (2 * Math.PI / step) + 1;
|
||||
float step = (float) Math.PI / (subd / 2);
|
||||
int num_steps180 = (int) (Math.PI / step) + 1;
|
||||
int num_steps360 = (int) (2 * Math.PI / step) + 1;
|
||||
for (int i = 0; i <= num_steps360; i++)
|
||||
{
|
||||
builder.begin(VertexFormat.Mode.DEBUG_LINE_STRIP, DefaultVertexFormat.POSITION_COLOR);
|
||||
final float theta = step * i;
|
||||
float theta = step * i;
|
||||
for (int j = 0; j <= num_steps180; j++)
|
||||
{
|
||||
final float phi = step * j;
|
||||
final float x = r * Mth.sin(phi) * Mth.cos(theta);
|
||||
final float z = r * Mth.sin(phi) * Mth.sin(theta);
|
||||
final float y = r * Mth.cos(phi);
|
||||
float phi = step * j;
|
||||
float x = r * Mth.sin(phi) * Mth.cos(theta);
|
||||
float z = r * Mth.sin(phi) * Mth.sin(theta);
|
||||
float y = r * Mth.cos(phi);
|
||||
builder.vertex(x + cx, y + cy, z + cz).color(red, grn, blu, alpha).endVertex();
|
||||
}
|
||||
tessellator.end();
|
||||
@@ -1335,14 +1335,14 @@ public class ShapesRenderer
|
||||
for (int j = 0; j <= num_steps180; j++)
|
||||
{
|
||||
builder.begin(VertexFormat.Mode.DEBUG_LINE_STRIP, DefaultVertexFormat.POSITION_COLOR); // line loop to line strip
|
||||
final float phi = step * j;
|
||||
float phi = step * j;
|
||||
|
||||
for (int i = 0; i <= num_steps360; i++)
|
||||
{
|
||||
final float theta = step * i;
|
||||
final float x = r * Mth.sin(phi) * Mth.cos(theta);
|
||||
final float z = r * Mth.sin(phi) * Mth.sin(theta);
|
||||
final float y = r * Mth.cos(phi);
|
||||
float theta = step * i;
|
||||
float x = r * Mth.sin(phi) * Mth.cos(theta);
|
||||
float z = r * Mth.sin(phi) * Mth.sin(theta);
|
||||
float y = r * Mth.cos(phi);
|
||||
builder.vertex(x + cx, y + cy, z + cz).color(red, grn, blu, alpha).endVertex();
|
||||
}
|
||||
tessellator.end();
|
||||
@@ -1350,19 +1350,19 @@ public class ShapesRenderer
|
||||
|
||||
}
|
||||
|
||||
public static void drawSphereFaces(final Tesselator tessellator, final BufferBuilder builder,
|
||||
final float cx, final float cy, final float cz,
|
||||
final float r, final int subd,
|
||||
final float red, final float grn, final float blu, final float alpha)
|
||||
public static void drawSphereFaces(Tesselator tessellator, BufferBuilder builder,
|
||||
float cx, float cy, float cz,
|
||||
float r, int subd,
|
||||
float red, float grn, float blu, float alpha)
|
||||
{
|
||||
|
||||
final float step = (float) Math.PI / (subd / 2);
|
||||
final int num_steps180 = (int) (Math.PI / step) + 1;
|
||||
final int num_steps360 = (int) (2 * Math.PI / step);
|
||||
float step = (float) Math.PI / (subd / 2);
|
||||
int num_steps180 = (int) (Math.PI / step) + 1;
|
||||
int num_steps360 = (int) (2 * Math.PI / step);
|
||||
for (int i = 0; i <= num_steps360; i++)
|
||||
{
|
||||
final float theta = i * step;
|
||||
final float thetaprime = theta + step;
|
||||
float theta = i * step;
|
||||
float thetaprime = theta + step;
|
||||
builder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR); // quad strip to quads
|
||||
float xb = 0;
|
||||
float zb = 0;
|
||||
@@ -1371,12 +1371,12 @@ public class ShapesRenderer
|
||||
float yp = r;
|
||||
for (int j = 0; j <= num_steps180; j++)
|
||||
{
|
||||
final float phi = j * step;
|
||||
final float x = r * Mth.sin(phi) * Mth.cos(theta);
|
||||
final float z = r * Mth.sin(phi) * Mth.sin(theta);
|
||||
final float y = r * Mth.cos(phi);
|
||||
final float xp = r * Mth.sin(phi) * Mth.cos(thetaprime);
|
||||
final float zp = r * Mth.sin(phi) * Mth.sin(thetaprime);
|
||||
float phi = j * step;
|
||||
float x = r * Mth.sin(phi) * Mth.cos(theta);
|
||||
float z = r * Mth.sin(phi) * Mth.sin(theta);
|
||||
float y = r * Mth.cos(phi);
|
||||
float xp = r * Mth.sin(phi) * Mth.cos(thetaprime);
|
||||
float zp = r * Mth.sin(phi) * Mth.sin(thetaprime);
|
||||
builder.vertex(xb + cx, yp + cy, zb + cz).color(red, grn, blu, alpha).endVertex();
|
||||
builder.vertex(xbp + cx, yp + cy, zbp + cz).color(red, grn, blu, alpha).endVertex();
|
||||
builder.vertex(xp + cx, y + cy, zp + cz).color(red, grn, blu, alpha).endVertex();
|
||||
|
||||
@@ -15,7 +15,7 @@ public class SimplexNoiseSampler extends PerlinNoiseSampler
|
||||
public static SimplexNoiseSampler instance = new SimplexNoiseSampler(new Random(0));
|
||||
public static Map<Long, SimplexNoiseSampler> samplers = new Long2ObjectOpenHashMap<>();
|
||||
|
||||
public static SimplexNoiseSampler getSimplex(final long aLong)
|
||||
public static SimplexNoiseSampler getSimplex(long aLong)
|
||||
{
|
||||
if (samplers.size() > 256)
|
||||
{
|
||||
@@ -24,15 +24,15 @@ public class SimplexNoiseSampler extends PerlinNoiseSampler
|
||||
return samplers.computeIfAbsent(aLong, seed -> new SimplexNoiseSampler(new Random(seed)));
|
||||
}
|
||||
|
||||
public SimplexNoiseSampler(final Random random)
|
||||
public SimplexNoiseSampler(Random random)
|
||||
{
|
||||
super(random);
|
||||
}
|
||||
|
||||
private double grad(final int hash, final double x, final double y, final double z, final double d)
|
||||
private double grad(int hash, double x, double y, double z, double d)
|
||||
{
|
||||
double e = d - x * x - y * y - z * z;
|
||||
final double g;
|
||||
double g;
|
||||
if (e < 0.0D)
|
||||
{
|
||||
g = 0.0D;
|
||||
@@ -51,16 +51,16 @@ public class SimplexNoiseSampler extends PerlinNoiseSampler
|
||||
{
|
||||
x = x / 2;
|
||||
y = y / 2;
|
||||
final double d = (x + y) * SKEW_FACTOR_2D;
|
||||
final int i = PerlinNoiseSampler.floor(x + d);
|
||||
final int j = PerlinNoiseSampler.floor(y + d);
|
||||
final double e = (i + j) * UNSKEW_FACTOR_2D;
|
||||
final double f = i - e;
|
||||
final double g = j - e;
|
||||
final double h = x - f;
|
||||
final double k = y - g;
|
||||
final byte n;
|
||||
final byte o;
|
||||
double d = (x + y) * SKEW_FACTOR_2D;
|
||||
int i = PerlinNoiseSampler.floor(x + d);
|
||||
int j = PerlinNoiseSampler.floor(y + d);
|
||||
double e = (i + j) * UNSKEW_FACTOR_2D;
|
||||
double f = i - e;
|
||||
double g = j - e;
|
||||
double h = x - f;
|
||||
double k = y - g;
|
||||
byte n;
|
||||
byte o;
|
||||
if (h > k)
|
||||
{
|
||||
n = 1;
|
||||
@@ -72,18 +72,18 @@ public class SimplexNoiseSampler extends PerlinNoiseSampler
|
||||
o = 1;
|
||||
}
|
||||
|
||||
final double p = h - n + UNSKEW_FACTOR_2D;
|
||||
final double q = k - o + UNSKEW_FACTOR_2D;
|
||||
final double r = h - 1.0D + 2.0D * UNSKEW_FACTOR_2D;
|
||||
final double s = k - 1.0D + 2.0D * UNSKEW_FACTOR_2D;
|
||||
final int t = i & 255;
|
||||
final int u = j & 255;
|
||||
final int v = this.getGradient(t + this.getGradient(u)) % 12;
|
||||
final int w = this.getGradient(t + n + this.getGradient(u + o)) % 12;
|
||||
final int z = this.getGradient(t + 1 + this.getGradient(u + 1)) % 12;
|
||||
final double aa = this.grad(v, h, k, 0.0D, 0.5D);
|
||||
final double ab = this.grad(w, p, q, 0.0D, 0.5D);
|
||||
final double ac = this.grad(z, r, s, 0.0D, 0.5D);
|
||||
double p = h - n + UNSKEW_FACTOR_2D;
|
||||
double q = k - o + UNSKEW_FACTOR_2D;
|
||||
double r = h - 1.0D + 2.0D * UNSKEW_FACTOR_2D;
|
||||
double s = k - 1.0D + 2.0D * UNSKEW_FACTOR_2D;
|
||||
int t = i & 255;
|
||||
int u = j & 255;
|
||||
int v = this.getGradient(t + this.getGradient(u)) % 12;
|
||||
int w = this.getGradient(t + n + this.getGradient(u + o)) % 12;
|
||||
int z = this.getGradient(t + 1 + this.getGradient(u + 1)) % 12;
|
||||
double aa = this.grad(v, h, k, 0.0D, 0.5D);
|
||||
double ab = this.grad(w, p, q, 0.0D, 0.5D);
|
||||
double ac = this.grad(z, r, s, 0.0D, 0.5D);
|
||||
//return 70.0D * (aa + ab + ac);
|
||||
return 35.0D * (aa + ab + ac) + 0.5;
|
||||
}
|
||||
@@ -95,24 +95,24 @@ public class SimplexNoiseSampler extends PerlinNoiseSampler
|
||||
e = e / 2;
|
||||
f = f / 2;
|
||||
//final double g = 0.3333333333333333D;
|
||||
final double h = (d + e + f) * 0.3333333333333333D;
|
||||
final int i = floor(d + h);
|
||||
final int j = floor(e + h);
|
||||
final int k = floor(f + h);
|
||||
double h = (d + e + f) * 0.3333333333333333D;
|
||||
int i = floor(d + h);
|
||||
int j = floor(e + h);
|
||||
int k = floor(f + h);
|
||||
//final double l = 0.16666666666666666D;
|
||||
final double m = (i + j + k) * 0.16666666666666666D;
|
||||
final double n = i - m;
|
||||
final double o = j - m;
|
||||
final double p = k - m;
|
||||
final double q = d - n;
|
||||
final double r = e - o;
|
||||
final double s = f - p;
|
||||
final byte z;
|
||||
final byte aa;
|
||||
final byte ab;
|
||||
final byte ac;
|
||||
final byte ad;
|
||||
final byte bc;
|
||||
double m = (i + j + k) * 0.16666666666666666D;
|
||||
double n = i - m;
|
||||
double o = j - m;
|
||||
double p = k - m;
|
||||
double q = d - n;
|
||||
double r = e - o;
|
||||
double s = f - p;
|
||||
byte z;
|
||||
byte aa;
|
||||
byte ab;
|
||||
byte ac;
|
||||
byte ad;
|
||||
byte bc;
|
||||
if (q >= r)
|
||||
{
|
||||
if (r >= s)
|
||||
@@ -171,26 +171,26 @@ public class SimplexNoiseSampler extends PerlinNoiseSampler
|
||||
bc = 0;
|
||||
}
|
||||
|
||||
final double bd = q - z + 0.16666666666666666D;
|
||||
final double be = r - aa + 0.16666666666666666D;
|
||||
final double bf = s - ab + 0.16666666666666666D;
|
||||
final double bg = q - ac + 0.3333333333333333D;
|
||||
final double bh = r - ad + 0.3333333333333333D;
|
||||
final double bi = s - bc + 0.3333333333333333D;
|
||||
final double bj = q - 1.0D + 0.5D;
|
||||
final double bk = r - 1.0D + 0.5D;
|
||||
final double bl = s - 1.0D + 0.5D;
|
||||
final int bm = i & 255;
|
||||
final int bn = j & 255;
|
||||
final int bo = k & 255;
|
||||
final int bp = this.getGradient(bm + this.getGradient(bn + this.getGradient(bo))) % 12;
|
||||
final int bq = this.getGradient(bm + z + this.getGradient(bn + aa + this.getGradient(bo + ab))) % 12;
|
||||
final int br = this.getGradient(bm + ac + this.getGradient(bn + ad + this.getGradient(bo + bc))) % 12;
|
||||
final int bs = this.getGradient(bm + 1 + this.getGradient(bn + 1 + this.getGradient(bo + 1))) % 12;
|
||||
final double bt = this.grad(bp, q, r, s, 0.6D);
|
||||
final double bu = this.grad(bq, bd, be, bf, 0.6D);
|
||||
final double bv = this.grad(br, bg, bh, bi, 0.6D);
|
||||
final double bw = this.grad(bs, bj, bk, bl, 0.6D);
|
||||
double bd = q - z + 0.16666666666666666D;
|
||||
double be = r - aa + 0.16666666666666666D;
|
||||
double bf = s - ab + 0.16666666666666666D;
|
||||
double bg = q - ac + 0.3333333333333333D;
|
||||
double bh = r - ad + 0.3333333333333333D;
|
||||
double bi = s - bc + 0.3333333333333333D;
|
||||
double bj = q - 1.0D + 0.5D;
|
||||
double bk = r - 1.0D + 0.5D;
|
||||
double bl = s - 1.0D + 0.5D;
|
||||
int bm = i & 255;
|
||||
int bn = j & 255;
|
||||
int bo = k & 255;
|
||||
int bp = this.getGradient(bm + this.getGradient(bn + this.getGradient(bo))) % 12;
|
||||
int bq = this.getGradient(bm + z + this.getGradient(bn + aa + this.getGradient(bo + ab))) % 12;
|
||||
int br = this.getGradient(bm + ac + this.getGradient(bn + ad + this.getGradient(bo + bc))) % 12;
|
||||
int bs = this.getGradient(bm + 1 + this.getGradient(bn + 1 + this.getGradient(bo + 1))) % 12;
|
||||
double bt = this.grad(bp, q, r, s, 0.6D);
|
||||
double bu = this.grad(bq, bd, be, bf, 0.6D);
|
||||
double bv = this.grad(br, bg, bh, bi, 0.6D);
|
||||
double bw = this.grad(bs, bj, bk, bl, 0.6D);
|
||||
return 16.0D * (bt + bu + bv + bw) + 0.5;
|
||||
}
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ public class SnoopyCommandSource extends CommandSourceStack
|
||||
private final List<Component> chatOutput;
|
||||
private final CommandSigningContext signingContext;
|
||||
|
||||
public SnoopyCommandSource(final CommandSourceStack original, final Component[] error, final List<Component> chatOutput)
|
||||
public SnoopyCommandSource(CommandSourceStack original, Component[] error, List<Component> chatOutput)
|
||||
{
|
||||
super(CommandSource.NULL, original.getPosition(), original.getRotation(), original.getLevel(), Vanilla.MinecraftServer_getRunPermissionLevel(original.getServer()),
|
||||
original.getTextName(), original.getDisplayName(), original.getServer(), original.getEntity(), false,
|
||||
@@ -63,7 +63,7 @@ public class SnoopyCommandSource extends CommandSourceStack
|
||||
this.signingContext = original.getSigningContext();
|
||||
}
|
||||
|
||||
public SnoopyCommandSource(final ServerPlayer player, final Component[] error, final List<Component> output)
|
||||
public SnoopyCommandSource(ServerPlayer player, Component[] error, List<Component> output)
|
||||
{
|
||||
super(player, player.position(), player.getRotationVector(),
|
||||
player.level instanceof final ServerLevel serverLevel ? serverLevel : null,
|
||||
@@ -86,8 +86,8 @@ public class SnoopyCommandSource extends CommandSourceStack
|
||||
this.signingContext = CommandSigningContext.ANONYMOUS;
|
||||
}
|
||||
|
||||
private SnoopyCommandSource(final CommandSource output, final Vec3 pos, final Vec2 rot, final ServerLevel world, final int level, final String simpleName, final Component name, final MinecraftServer server, @Nullable final Entity entity, final ResultConsumer<CommandSourceStack> consumer, final EntityAnchorArgument.Anchor entityAnchor, final CommandSigningContext context,
|
||||
final Component[] error, final List<Component> chatOutput
|
||||
private SnoopyCommandSource(CommandSource output, Vec3 pos, Vec2 rot, ServerLevel world, int level, String simpleName, Component name, MinecraftServer server, @Nullable Entity entity, ResultConsumer<CommandSourceStack> consumer, EntityAnchorArgument.Anchor entityAnchor, CommandSigningContext context,
|
||||
Component[] error, List<Component> chatOutput
|
||||
)
|
||||
{
|
||||
super(output, pos, rot, world, level,
|
||||
@@ -110,33 +110,33 @@ public class SnoopyCommandSource extends CommandSourceStack
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandSourceStack withEntity(final Entity entity)
|
||||
public CommandSourceStack withEntity(Entity entity)
|
||||
{
|
||||
return new SnoopyCommandSource(output, position, rotation, world, level, entity.getName().getString(), entity.getDisplayName(), server, entity, resultConsumer, entityAnchor, signingContext, error, chatOutput);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandSourceStack withPosition(final Vec3 position)
|
||||
public CommandSourceStack withPosition(Vec3 position)
|
||||
{
|
||||
return new SnoopyCommandSource(output, position, rotation, world, level, simpleName, name, server, entity, resultConsumer, entityAnchor, signingContext, error, chatOutput);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandSourceStack withRotation(final Vec2 rotation)
|
||||
public CommandSourceStack withRotation(Vec2 rotation)
|
||||
{
|
||||
return new SnoopyCommandSource(output, position, rotation, world, level, simpleName, name, server, entity, resultConsumer, entityAnchor, signingContext, error, chatOutput);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandSourceStack withCallback(final ResultConsumer<CommandSourceStack> consumer)
|
||||
public CommandSourceStack withCallback(ResultConsumer<CommandSourceStack> consumer)
|
||||
{
|
||||
return new SnoopyCommandSource(output, position, rotation, world, level, simpleName, name, server, entity, consumer, entityAnchor, signingContext, error, chatOutput);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandSourceStack withCallback(final ResultConsumer<CommandSourceStack> consumer, final BinaryOperator<ResultConsumer<CommandSourceStack>> binaryOperator)
|
||||
public CommandSourceStack withCallback(ResultConsumer<CommandSourceStack> consumer, BinaryOperator<ResultConsumer<CommandSourceStack>> binaryOperator)
|
||||
{
|
||||
final ResultConsumer<CommandSourceStack> resultConsumer = binaryOperator.apply(this.resultConsumer, consumer);
|
||||
ResultConsumer<CommandSourceStack> resultConsumer = binaryOperator.apply(this.resultConsumer, consumer);
|
||||
return this.withCallback(resultConsumer);
|
||||
}
|
||||
|
||||
@@ -145,58 +145,58 @@ public class SnoopyCommandSource extends CommandSourceStack
|
||||
//public ServerCommandSource withSilent() { return this; }
|
||||
|
||||
@Override
|
||||
public CommandSourceStack withPermission(final int level)
|
||||
public CommandSourceStack withPermission(int level)
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandSourceStack withMaximumPermission(final int level)
|
||||
public CommandSourceStack withMaximumPermission(int level)
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandSourceStack withAnchor(final EntityAnchorArgument.Anchor anchor)
|
||||
public CommandSourceStack withAnchor(EntityAnchorArgument.Anchor anchor)
|
||||
{
|
||||
return new SnoopyCommandSource(output, position, rotation, world, level, simpleName, name, server, entity, resultConsumer, anchor, signingContext, error, chatOutput);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandSourceStack withSigningContext(final CommandSigningContext commandSigningContext)
|
||||
public CommandSourceStack withSigningContext(CommandSigningContext commandSigningContext)
|
||||
{
|
||||
return new SnoopyCommandSource(output, position, rotation, world, level, simpleName, name, server, entity, resultConsumer, entityAnchor, commandSigningContext, error, chatOutput);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandSourceStack withLevel(final ServerLevel world)
|
||||
public CommandSourceStack withLevel(ServerLevel world)
|
||||
{
|
||||
final double d = DimensionType.getTeleportationScale(this.world.dimensionType(), world.dimensionType());
|
||||
final Vec3 position = new Vec3(this.position.x * d, this.position.y, this.position.z * d);
|
||||
double d = DimensionType.getTeleportationScale(this.world.dimensionType(), world.dimensionType());
|
||||
Vec3 position = new Vec3(this.position.x * d, this.position.y, this.position.z * d);
|
||||
return new SnoopyCommandSource(output, position, rotation, world, level, simpleName, name, server, entity, resultConsumer, entityAnchor, signingContext, error, chatOutput);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandSourceStack facing(final Vec3 position)
|
||||
public CommandSourceStack facing(Vec3 position)
|
||||
{
|
||||
final Vec3 vec3d = this.entityAnchor.apply(this);
|
||||
final double d = position.x - vec3d.x;
|
||||
final double e = position.y - vec3d.y;
|
||||
final double f = position.z - vec3d.z;
|
||||
final double g = Math.sqrt(d * d + f * f);
|
||||
final float h = Mth.wrapDegrees((float) (-(Mth.atan2(e, g) * 57.2957763671875D)));
|
||||
final float i = Mth.wrapDegrees((float) (Mth.atan2(f, d) * 57.2957763671875D) - 90.0F);
|
||||
Vec3 vec3d = this.entityAnchor.apply(this);
|
||||
double d = position.x - vec3d.x;
|
||||
double e = position.y - vec3d.y;
|
||||
double f = position.z - vec3d.z;
|
||||
double g = Math.sqrt(d * d + f * f);
|
||||
float h = Mth.wrapDegrees((float) (-(Mth.atan2(e, g) * 57.2957763671875D)));
|
||||
float i = Mth.wrapDegrees((float) (Mth.atan2(f, d) * 57.2957763671875D) - 90.0F);
|
||||
return this.withRotation(new Vec2(h, i));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendFailure(final Component message)
|
||||
public void sendFailure(Component message)
|
||||
{
|
||||
error[0] = message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendSuccess(final Component message, final boolean broadcastToOps)
|
||||
public void sendSuccess(Component message, boolean broadcastToOps)
|
||||
{
|
||||
chatOutput.add(message);
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ public class SystemInfo
|
||||
{{
|
||||
put("app_name", c ->
|
||||
{
|
||||
final String name = c.host.getName();
|
||||
String name = c.host.getName();
|
||||
return name == null ? Value.NULL : new StringValue(name);
|
||||
});
|
||||
put("app_list", c -> ListValue.wrap(((CarpetScriptHost) c.host).scriptServer().modules.keySet().stream().filter(Objects::nonNull).map(StringValue::new)));
|
||||
@@ -49,18 +49,18 @@ public class SystemInfo
|
||||
put("server_motd", c -> StringValue.of(c.server().getMotd()));
|
||||
put("world_path", c -> StringValue.of(c.server().getWorldPath(LevelResource.ROOT).toString()));
|
||||
put("world_folder", c -> {
|
||||
final Path serverPath = c.server().getWorldPath(LevelResource.ROOT);
|
||||
final int nodeCount = serverPath.getNameCount();
|
||||
Path serverPath = c.server().getWorldPath(LevelResource.ROOT);
|
||||
int nodeCount = serverPath.getNameCount();
|
||||
if (nodeCount < 2)
|
||||
{
|
||||
return Value.NULL;
|
||||
}
|
||||
final String tlf = serverPath.getName(nodeCount - 2).toString();
|
||||
String tlf = serverPath.getName(nodeCount - 2).toString();
|
||||
return StringValue.of(tlf);
|
||||
});
|
||||
put("world_dimensions", c -> ListValue.wrap(c.server().levelKeys().stream().map(k -> ValueConversions.of(k.location()))));
|
||||
put("world_spawn_point", c -> {
|
||||
final LevelData prop = c.server().overworld().getLevelData();
|
||||
LevelData prop = c.server().overworld().getLevelData();
|
||||
return ListValue.of(NumericValue.of(prop.getXSpawn()), NumericValue.of(prop.getYSpawn()), NumericValue.of(prop.getZSpawn()));
|
||||
});
|
||||
|
||||
@@ -69,7 +69,7 @@ public class SystemInfo
|
||||
put("world_top", c -> new NumericValue(c.level().getMaxBuildHeight()));
|
||||
|
||||
put("world_center", c -> {
|
||||
final WorldBorder worldBorder = c.level().getWorldBorder();
|
||||
WorldBorder worldBorder = c.level().getWorldBorder();
|
||||
return ListValue.fromTriple(worldBorder.getCenterX(), 0, worldBorder.getCenterZ());
|
||||
});
|
||||
|
||||
@@ -90,11 +90,11 @@ public class SystemInfo
|
||||
put("game_target", c -> StringValue.of(Vanilla.MinecraftServer_getReleaseTarget(c.server())));
|
||||
put("game_protocol", c -> NumericValue.of(SharedConstants.getProtocolVersion()));
|
||||
put("game_major_target", c -> {
|
||||
final String[] vers = Vanilla.MinecraftServer_getReleaseTarget(c.server()).split("\\.");
|
||||
String[] vers = Vanilla.MinecraftServer_getReleaseTarget(c.server()).split("\\.");
|
||||
return NumericValue.of((vers.length > 1) ? Integer.parseInt(vers[1]) : 0);
|
||||
});
|
||||
put("game_minor_target", c -> {
|
||||
final String[] vers = Vanilla.MinecraftServer_getReleaseTarget(c.server()).split("\\.");
|
||||
String[] vers = Vanilla.MinecraftServer_getReleaseTarget(c.server()).split("\\.");
|
||||
return NumericValue.of((vers.length > 2) ? Integer.parseInt(vers[2]) : 0);
|
||||
});
|
||||
put("game_stable", c -> BooleanValue.of(SharedConstants.getCurrentVersion().isStable()));
|
||||
@@ -104,24 +104,24 @@ public class SystemInfo
|
||||
put("server_ip", c -> StringValue.of(c.server().getLocalIp()));
|
||||
put("server_whitelisted", c -> BooleanValue.of(c.server().isEnforceWhitelist()));
|
||||
put("server_whitelist", c -> {
|
||||
final MapValue whitelist = new MapValue(Collections.emptyList());
|
||||
for (final String s : c.server().getPlayerList().getWhiteListNames())
|
||||
MapValue whitelist = new MapValue(Collections.emptyList());
|
||||
for (String s : c.server().getPlayerList().getWhiteListNames())
|
||||
{
|
||||
whitelist.append(StringValue.of(s));
|
||||
}
|
||||
return whitelist;
|
||||
});
|
||||
put("server_banned_players", c -> {
|
||||
final MapValue whitelist = new MapValue(Collections.emptyList());
|
||||
for (final String s : c.server().getPlayerList().getBans().getUserList())
|
||||
MapValue whitelist = new MapValue(Collections.emptyList());
|
||||
for (String s : c.server().getPlayerList().getBans().getUserList())
|
||||
{
|
||||
whitelist.append(StringValue.of(s));
|
||||
}
|
||||
return whitelist;
|
||||
});
|
||||
put("server_banned_ips", c -> {
|
||||
final MapValue whitelist = new MapValue(Collections.emptyList());
|
||||
for (final String s : c.server().getPlayerList().getIpBans().getUserList())
|
||||
MapValue whitelist = new MapValue(Collections.emptyList());
|
||||
for (String s : c.server().getPlayerList().getIpBans().getUserList())
|
||||
{
|
||||
whitelist.append(StringValue.of(s));
|
||||
}
|
||||
@@ -132,9 +132,9 @@ public class SystemInfo
|
||||
put("server_last_tick_times", c -> {
|
||||
//assuming we are in the tick world section
|
||||
// might be off one tick when run in the off tasks or asynchronously.
|
||||
final int currentReportedTick = c.server().getTickCount() - 1;
|
||||
final List<Value> ticks = new ArrayList<>(100);
|
||||
final long[] tickArray = c.server().tickTimes;
|
||||
int currentReportedTick = c.server().getTickCount() - 1;
|
||||
List<Value> ticks = new ArrayList<>(100);
|
||||
long[] tickArray = c.server().tickTimes;
|
||||
for (int i = currentReportedTick + 100; i > currentReportedTick; i--)
|
||||
{
|
||||
ticks.add(new NumericValue((tickArray[i % 100]) / 1000000.0));
|
||||
@@ -148,9 +148,9 @@ public class SystemInfo
|
||||
put("java_cpu_count", c -> new NumericValue(Runtime.getRuntime().availableProcessors()));
|
||||
put("java_version", c -> StringValue.of(System.getProperty("java.version")));
|
||||
put("java_bits", c -> {
|
||||
for (final String property : new String[]{"sun.arch.data.model", "com.ibm.vm.bitmode", "os.arch"})
|
||||
for (String property : new String[]{"sun.arch.data.model", "com.ibm.vm.bitmode", "os.arch"})
|
||||
{
|
||||
final String value = System.getProperty(property);
|
||||
String value = System.getProperty(property);
|
||||
if (value != null && value.contains("64"))
|
||||
{
|
||||
return new NumericValue(64);
|
||||
@@ -159,23 +159,23 @@ public class SystemInfo
|
||||
return new NumericValue(32);
|
||||
});
|
||||
put("java_system_cpu_load", c -> {
|
||||
final OperatingSystemMXBean osBean = ManagementFactory.getPlatformMXBean(
|
||||
OperatingSystemMXBean osBean = ManagementFactory.getPlatformMXBean(
|
||||
OperatingSystemMXBean.class);
|
||||
return new NumericValue(osBean.getCpuLoad());
|
||||
});
|
||||
put("java_process_cpu_load", c -> {
|
||||
final OperatingSystemMXBean osBean = ManagementFactory.getPlatformMXBean(
|
||||
OperatingSystemMXBean osBean = ManagementFactory.getPlatformMXBean(
|
||||
OperatingSystemMXBean.class);
|
||||
return new NumericValue(osBean.getProcessCpuLoad());
|
||||
});
|
||||
put("world_carpet_rules", c -> Carpet.getAllCarpetRules());
|
||||
put("world_gamerules", c -> {
|
||||
final Map<Value, Value> rules = new HashMap<>();
|
||||
final GameRules gameRules = c.level().getGameRules();
|
||||
Map<Value, Value> rules = new HashMap<>();
|
||||
GameRules gameRules = c.level().getGameRules();
|
||||
GameRules.visitGameRuleTypes(new GameRules.GameRuleTypeVisitor()
|
||||
{
|
||||
@Override
|
||||
public <T extends GameRules.Value<T>> void visit(final GameRules.Key<T> key, final GameRules.Type<T> type)
|
||||
public <T extends GameRules.Value<T>> void visit(GameRules.Key<T> key, GameRules.Type<T> type)
|
||||
{
|
||||
rules.put(StringValue.of(key.getId()), StringValue.of(gameRules.getRule(key).toString()));
|
||||
}
|
||||
@@ -188,13 +188,13 @@ public class SystemInfo
|
||||
put("source_position", c -> ValueConversions.of(c.source().getPosition()));
|
||||
put("source_dimension", c -> ValueConversions.of(c.level()));
|
||||
put("source_rotation", c -> {
|
||||
final Vec2 rotation = c.source().getRotation();
|
||||
Vec2 rotation = c.source().getRotation();
|
||||
return ListValue.of(new NumericValue(rotation.x), new NumericValue(rotation.y));
|
||||
});
|
||||
put("scarpet_version", c -> StringValue.of(Carpet.getCarpetVersion()));
|
||||
}};
|
||||
|
||||
public static Value get(final String what, final CarpetContext cc)
|
||||
public static Value get(String what, CarpetContext cc)
|
||||
{
|
||||
return options.getOrDefault(what, c -> null).apply(cc);
|
||||
}
|
||||
|
||||
@@ -14,45 +14,45 @@ import net.minecraft.world.phys.Vec3;
|
||||
|
||||
public class Tracer
|
||||
{
|
||||
public static HitResult rayTrace(final Entity source, final float partialTicks, final double reach, final boolean fluids)
|
||||
public static HitResult rayTrace(Entity source, float partialTicks, double reach, boolean fluids)
|
||||
{
|
||||
final BlockHitResult blockHit = rayTraceBlocks(source, partialTicks, reach, fluids);
|
||||
BlockHitResult blockHit = rayTraceBlocks(source, partialTicks, reach, fluids);
|
||||
double maxSqDist = reach * reach;
|
||||
if (blockHit != null)
|
||||
{
|
||||
maxSqDist = blockHit.getLocation().distanceToSqr(source.getEyePosition(partialTicks));
|
||||
}
|
||||
final EntityHitResult entityHit = rayTraceEntities(source, partialTicks, reach, maxSqDist);
|
||||
EntityHitResult entityHit = rayTraceEntities(source, partialTicks, reach, maxSqDist);
|
||||
return entityHit == null ? blockHit : entityHit;
|
||||
}
|
||||
|
||||
public static BlockHitResult rayTraceBlocks(final Entity source, final float partialTicks, final double reach, final boolean fluids)
|
||||
public static BlockHitResult rayTraceBlocks(Entity source, float partialTicks, double reach, boolean fluids)
|
||||
{
|
||||
final Vec3 pos = source.getEyePosition(partialTicks);
|
||||
final Vec3 rotation = source.getViewVector(partialTicks);
|
||||
final Vec3 reachEnd = pos.add(rotation.x * reach, rotation.y * reach, rotation.z * reach);
|
||||
Vec3 pos = source.getEyePosition(partialTicks);
|
||||
Vec3 rotation = source.getViewVector(partialTicks);
|
||||
Vec3 reachEnd = pos.add(rotation.x * reach, rotation.y * reach, rotation.z * reach);
|
||||
return source.level.clip(new ClipContext(pos, reachEnd, ClipContext.Block.OUTLINE, fluids ?
|
||||
ClipContext.Fluid.ANY : ClipContext.Fluid.NONE, source));
|
||||
}
|
||||
|
||||
public static EntityHitResult rayTraceEntities(final Entity source, final float partialTicks, final double reach, final double maxSqDist)
|
||||
public static EntityHitResult rayTraceEntities(Entity source, float partialTicks, double reach, double maxSqDist)
|
||||
{
|
||||
final Vec3 pos = source.getEyePosition(partialTicks);
|
||||
final Vec3 reachVec = source.getViewVector(partialTicks).scale(reach);
|
||||
final AABB box = source.getBoundingBox().expandTowards(reachVec).inflate(1);
|
||||
Vec3 pos = source.getEyePosition(partialTicks);
|
||||
Vec3 reachVec = source.getViewVector(partialTicks).scale(reach);
|
||||
AABB box = source.getBoundingBox().expandTowards(reachVec).inflate(1);
|
||||
return rayTraceEntities(source, pos, pos.add(reachVec), box, e -> !e.isSpectator() && e.isPickable(), maxSqDist);
|
||||
}
|
||||
|
||||
public static EntityHitResult rayTraceEntities(final Entity source, final Vec3 start, final Vec3 end, final AABB box, final Predicate<Entity> predicate, final double maxSqDistance)
|
||||
public static EntityHitResult rayTraceEntities(Entity source, Vec3 start, Vec3 end, AABB box, Predicate<Entity> predicate, double maxSqDistance)
|
||||
{
|
||||
final Level world = source.level;
|
||||
Level world = source.level;
|
||||
double targetDistance = maxSqDistance;
|
||||
Entity target = null;
|
||||
Vec3 targetHitPos = null;
|
||||
for (final Entity current : world.getEntities(source, box, predicate))
|
||||
for (Entity current : world.getEntities(source, box, predicate))
|
||||
{
|
||||
final AABB currentBox = current.getBoundingBox().inflate(current.getPickRadius());
|
||||
final Optional<Vec3> currentHit = currentBox.clip(start, end);
|
||||
AABB currentBox = current.getBoundingBox().inflate(current.getPickRadius());
|
||||
Optional<Vec3> currentHit = currentBox.clip(start, end);
|
||||
if (currentBox.contains(start))
|
||||
{
|
||||
if (targetDistance >= 0)
|
||||
@@ -64,8 +64,8 @@ public class Tracer
|
||||
}
|
||||
else if (currentHit.isPresent())
|
||||
{
|
||||
final Vec3 currentHitPos = currentHit.get();
|
||||
final double currentDistance = start.distanceToSqr(currentHitPos);
|
||||
Vec3 currentHitPos = currentHit.get();
|
||||
double currentDistance = start.distanceToSqr(currentHitPos);
|
||||
if (currentDistance < targetDistance || targetDistance == 0)
|
||||
{
|
||||
if (current.getRootVehicle() == source.getRootVehicle())
|
||||
|
||||
@@ -34,6 +34,7 @@ import net.minecraft.world.level.levelgen.WorldGenSettings;
|
||||
import net.minecraft.world.level.storage.DerivedLevelData;
|
||||
import net.minecraft.world.level.storage.ServerLevelData;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.util.List;
|
||||
@@ -44,24 +45,24 @@ import java.util.Set;
|
||||
public class WorldTools
|
||||
{
|
||||
|
||||
public static boolean canHasChunk(final ServerLevel world, final ChunkPos chpos, final Map<String, RegionFile> regionCache, final boolean deepcheck)
|
||||
public static boolean canHasChunk(ServerLevel world, ChunkPos chpos, @Nullable Map<String, RegionFile> regionCache, boolean deepcheck)
|
||||
{
|
||||
if (world.getChunk(chpos.x, chpos.z, ChunkStatus.STRUCTURE_STARTS, false) != null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
final String currentRegionName = "r." + chpos.getRegionX() + "." + chpos.getRegionZ() + ".mca";
|
||||
String currentRegionName = "r." + chpos.getRegionX() + "." + chpos.getRegionZ() + ".mca";
|
||||
if (regionCache != null && regionCache.containsKey(currentRegionName))
|
||||
{
|
||||
final RegionFile region = regionCache.get(currentRegionName);
|
||||
RegionFile region = regionCache.get(currentRegionName);
|
||||
if (region == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return region.hasChunk(chpos);
|
||||
}
|
||||
final Path regionsFolder = Vanilla.MinecraftServer_storageSource(world.getServer()).getDimensionPath(world.dimension()).resolve("region");
|
||||
final Path regionPath = regionsFolder.resolve(currentRegionName);
|
||||
Path regionsFolder = Vanilla.MinecraftServer_storageSource(world.getServer()).getDimensionPath(world.dimension()).resolve("region");
|
||||
Path regionPath = regionsFolder.resolve(currentRegionName);
|
||||
if (!regionPath.toFile().exists())
|
||||
{
|
||||
if (regionCache != null)
|
||||
@@ -76,14 +77,14 @@ public class WorldTools
|
||||
}
|
||||
try
|
||||
{
|
||||
final RegionFile region = new RegionFile(regionPath, regionsFolder, true);
|
||||
RegionFile region = new RegionFile(regionPath, regionsFolder, true);
|
||||
if (regionCache != null)
|
||||
{
|
||||
regionCache.put(currentRegionName, region);
|
||||
}
|
||||
return region.hasChunk(chpos);
|
||||
}
|
||||
catch (final IOException ignored)
|
||||
catch (IOException ignored)
|
||||
{
|
||||
}
|
||||
return true;
|
||||
@@ -155,16 +156,16 @@ public class WorldTools
|
||||
return true;
|
||||
}*/
|
||||
|
||||
public static void forceChunkUpdate(final BlockPos pos, final ServerLevel world)
|
||||
public static void forceChunkUpdate(BlockPos pos, ServerLevel world)
|
||||
{
|
||||
final ChunkPos chunkPos = new ChunkPos(pos);
|
||||
final LevelChunk worldChunk = world.getChunkSource().getChunk(chunkPos.x, chunkPos.z, false);
|
||||
ChunkPos chunkPos = new ChunkPos(pos);
|
||||
LevelChunk worldChunk = world.getChunkSource().getChunk(chunkPos.x, chunkPos.z, false);
|
||||
if (worldChunk != null)
|
||||
{
|
||||
final List<ServerPlayer> players = world.getChunkSource().chunkMap.getPlayers(chunkPos, false);
|
||||
List<ServerPlayer> players = world.getChunkSource().chunkMap.getPlayers(chunkPos, false);
|
||||
if (!players.isEmpty())
|
||||
{
|
||||
final ClientboundLevelChunkWithLightPacket packet = new ClientboundLevelChunkWithLightPacket(worldChunk, world.getLightEngine(), null, null, false); // false seems to update neighbours as well.
|
||||
ClientboundLevelChunkWithLightPacket packet = new ClientboundLevelChunkWithLightPacket(worldChunk, world.getLightEngine(), null, null, false); // false seems to update neighbours as well.
|
||||
players.forEach(p -> p.connection.send(packet));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import com.mojang.math.Axis;
|
||||
import net.minecraft.client.Camera;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Locale;
|
||||
|
||||
public enum ShapeDirection
|
||||
@@ -18,7 +19,8 @@ public enum ShapeDirection
|
||||
CAMERA,
|
||||
PLAYER;
|
||||
|
||||
public static ShapeDirection fromString(final String direction)
|
||||
@Nullable
|
||||
public static ShapeDirection fromString(String direction)
|
||||
{
|
||||
return switch (direction.toLowerCase(Locale.ROOT))
|
||||
{
|
||||
@@ -34,7 +36,7 @@ public enum ShapeDirection
|
||||
};
|
||||
}
|
||||
|
||||
public static void rotatePoseStackByShapeDirection(final PoseStack poseStack, final ShapeDirection shapeDirection, final Camera camera, final Vec3 objectPos)
|
||||
public static void rotatePoseStackByShapeDirection(PoseStack poseStack, ShapeDirection shapeDirection, Camera camera, Vec3 objectPos)
|
||||
{
|
||||
switch (shapeDirection)
|
||||
{
|
||||
@@ -46,13 +48,13 @@ public enum ShapeDirection
|
||||
case DOWN -> poseStack.mulPose(Axis.XP.rotationDegrees(-90));
|
||||
case CAMERA -> poseStack.mulPose(camera.rotation());
|
||||
case PLAYER -> {
|
||||
final Vec3 vector = objectPos.subtract(camera.getPosition());
|
||||
final double x = vector.x;
|
||||
final double y = vector.y;
|
||||
final double z = vector.z;
|
||||
final double d = Math.sqrt(x * x + z * z);
|
||||
final float rotX = (float) (Math.atan2(x, z));
|
||||
final float rotY = (float) (Math.atan2(y, d));
|
||||
Vec3 vector = objectPos.subtract(camera.getPosition());
|
||||
double x = vector.x;
|
||||
double y = vector.y;
|
||||
double z = vector.z;
|
||||
double d = Math.sqrt(x * x + z * z);
|
||||
float rotX = (float) (Math.atan2(x, z));
|
||||
float rotY = (float) (Math.atan2(y, d));
|
||||
|
||||
// that should work somehow but it doesn't for some reason
|
||||
//matrices.mulPose(new Quaternion( -rotY, rotX, 0, false));
|
||||
|
||||
@@ -9,7 +9,7 @@ public abstract class AbstractListValue extends Value implements Iterable<Value>
|
||||
{
|
||||
public List<Value> unpack()
|
||||
{
|
||||
final List<Value> retVal = Lists.newArrayList(iterator());
|
||||
List<Value> retVal = Lists.newArrayList(iterator());
|
||||
fatality();
|
||||
return retVal;
|
||||
}
|
||||
@@ -18,7 +18,7 @@ public abstract class AbstractListValue extends Value implements Iterable<Value>
|
||||
{
|
||||
}
|
||||
|
||||
public void append(final Value v)
|
||||
public void append(Value v)
|
||||
{
|
||||
throw new InternalExpressionException("Cannot append a value to an abstract list");
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.context.BlockPlaceContext;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.block.state.properties.Property;
|
||||
@@ -38,24 +39,30 @@ import net.minecraft.world.level.chunk.LevelChunk;
|
||||
import net.minecraft.world.phys.BlockHitResult;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import static carpet.script.value.NBTSerializableValue.nameFromRegistryId;
|
||||
import static carpet.script.value.NBTSerializableValue.nameFromResource;
|
||||
|
||||
public class BlockValue extends Value
|
||||
{
|
||||
private BlockState blockState;
|
||||
private final BlockPos pos;
|
||||
private final Level world;
|
||||
private final ServerLevel world;
|
||||
private CompoundTag data;
|
||||
|
||||
public static BlockValue fromCoords(final CarpetContext c, final int x, final int y, final int z)
|
||||
// we only care for null values a few times, most of the time we would assume its all present
|
||||
public static final BlockValue NONE = new BlockValue(Blocks.AIR.defaultBlockState(), null, BlockPos.ZERO, null);
|
||||
|
||||
public static BlockValue fromCoords(CarpetContext c, int x, int y, int z)
|
||||
{
|
||||
final BlockPos pos = locateBlockPos(c, x, y, z);
|
||||
BlockPos pos = locateBlockPos(c, x, y, z);
|
||||
return new BlockValue(null, c.level(), pos);
|
||||
}
|
||||
|
||||
private static final Map<String, BlockValue> bvCache = new HashMap<>();
|
||||
|
||||
public static BlockValue fromString(final String str, final Level level)
|
||||
public static BlockValue fromString(String str, ServerLevel level)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -64,7 +71,7 @@ public class BlockValue extends Value
|
||||
{
|
||||
return bv;
|
||||
}
|
||||
final BlockStateParser.BlockResult foo = BlockStateParser.parseForBlock(level.registryAccess().lookupOrThrow(Registries.BLOCK), new StringReader(str), true);
|
||||
BlockStateParser.BlockResult foo = BlockStateParser.parseForBlock(level.registryAccess().lookupOrThrow(Registries.BLOCK), new StringReader(str), true);
|
||||
if (foo.blockState() != null)
|
||||
{
|
||||
CompoundTag bd = foo.nbt();
|
||||
@@ -81,15 +88,15 @@ public class BlockValue extends Value
|
||||
return bv;
|
||||
}
|
||||
}
|
||||
catch (final CommandSyntaxException ignored)
|
||||
catch (CommandSyntaxException ignored)
|
||||
{
|
||||
}
|
||||
throw new ThrowStatement(str, Throwables.UNKNOWN_BLOCK);
|
||||
}
|
||||
|
||||
public static BlockPos locateBlockPos(final CarpetContext c, final int xpos, final int ypos, final int zpos)
|
||||
public static BlockPos locateBlockPos(CarpetContext c, int xpos, int ypos, int zpos)
|
||||
{
|
||||
final BlockPos pos = c.origin();
|
||||
BlockPos pos = c.origin();
|
||||
return new BlockPos(pos.getX() + xpos, pos.getY() + ypos, pos.getZ() + zpos);
|
||||
}
|
||||
|
||||
@@ -107,7 +114,7 @@ public class BlockValue extends Value
|
||||
throw new InternalExpressionException("Attempted to fetch block state without world or stored block state");
|
||||
}
|
||||
|
||||
public static BlockEntity getBlockEntity(final Level level, final BlockPos pos)
|
||||
public static BlockEntity getBlockEntity(Level level, BlockPos pos)
|
||||
{
|
||||
if (level instanceof final ServerLevel serverLevel)
|
||||
{
|
||||
@@ -127,7 +134,7 @@ public class BlockValue extends Value
|
||||
}
|
||||
if (pos != null)
|
||||
{
|
||||
final BlockEntity be = getBlockEntity(world, pos);
|
||||
BlockEntity be = getBlockEntity(world, pos);
|
||||
if (be == null)
|
||||
{
|
||||
data = new CompoundTag();
|
||||
@@ -140,7 +147,7 @@ public class BlockValue extends Value
|
||||
}
|
||||
|
||||
|
||||
public BlockValue(final BlockState state, final Level world, final BlockPos position)
|
||||
public BlockValue(BlockState state, ServerLevel world, BlockPos position)
|
||||
{
|
||||
this.world = world;
|
||||
blockState = state;
|
||||
@@ -148,7 +155,39 @@ public class BlockValue extends Value
|
||||
data = null;
|
||||
}
|
||||
|
||||
public BlockValue(final BlockState state, final Level world, final BlockPos position, final CompoundTag nbt)
|
||||
public BlockValue(BlockState state)
|
||||
{
|
||||
this.world = null;
|
||||
blockState = state;
|
||||
pos = null;
|
||||
data = null;
|
||||
}
|
||||
|
||||
public BlockValue(ServerLevel world, BlockPos position)
|
||||
{
|
||||
this.world = world;
|
||||
blockState = null;
|
||||
pos = position;
|
||||
data = null;
|
||||
}
|
||||
|
||||
public BlockValue(BlockState state, CompoundTag nbt)
|
||||
{
|
||||
this.world = null;
|
||||
blockState = state;
|
||||
pos = null;
|
||||
data = nbt;
|
||||
}
|
||||
|
||||
public BlockValue(BlockState state, ServerLevel world, CompoundTag nbt)
|
||||
{
|
||||
this.world = world;
|
||||
blockState = state;
|
||||
pos = null;
|
||||
data = nbt;
|
||||
}
|
||||
|
||||
private BlockValue(@Nullable BlockState state, @Nullable ServerLevel world, @Nullable BlockPos position, @Nullable CompoundTag nbt)
|
||||
{
|
||||
this.world = world;
|
||||
blockState = state;
|
||||
@@ -160,8 +199,8 @@ public class BlockValue extends Value
|
||||
@Override
|
||||
public String getString()
|
||||
{
|
||||
final Registry<Block> blockRegistry = world.registryAccess().registryOrThrow(Registries.BLOCK);
|
||||
return nameFromRegistryId(blockRegistry.getKey(getBlockState().getBlock()));
|
||||
Registry<Block> blockRegistry = world.registryAccess().registryOrThrow(Registries.BLOCK);
|
||||
return nameFromResource(blockRegistry.getKey(getBlockState().getBlock()));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -201,29 +240,29 @@ public class BlockValue extends Value
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tag toTag(final boolean force)
|
||||
public Tag toTag(boolean force)
|
||||
{
|
||||
if (!force)
|
||||
{
|
||||
throw new NBTSerializableValue.IncompatibleTypeException(this);
|
||||
}
|
||||
// follows falling block convertion
|
||||
final CompoundTag tag = new CompoundTag();
|
||||
final CompoundTag state = new CompoundTag();
|
||||
final BlockState s = getBlockState();
|
||||
CompoundTag tag = new CompoundTag();
|
||||
CompoundTag state = new CompoundTag();
|
||||
BlockState s = getBlockState();
|
||||
state.put("Name", StringTag.valueOf(world.registryAccess().registryOrThrow(Registries.BLOCK).getKey(s.getBlock()).toString()));
|
||||
final Collection<Property<?>> properties = s.getProperties();
|
||||
Collection<Property<?>> properties = s.getProperties();
|
||||
if (!properties.isEmpty())
|
||||
{
|
||||
final CompoundTag props = new CompoundTag();
|
||||
for (final Property<?> p : properties)
|
||||
CompoundTag props = new CompoundTag();
|
||||
for (Property<?> p : properties)
|
||||
{
|
||||
props.put(p.getName(), StringTag.valueOf(s.getValue(p).toString().toLowerCase(Locale.ROOT)));
|
||||
}
|
||||
state.put("Properties", props);
|
||||
}
|
||||
tag.put("BlockState", state);
|
||||
final CompoundTag dataTag = getData();
|
||||
CompoundTag dataTag = getData();
|
||||
if (dataTag != null)
|
||||
{
|
||||
tag.put("TileEntityData", dataTag);
|
||||
@@ -265,7 +304,7 @@ public class BlockValue extends Value
|
||||
private static final Map<String, SpecificDirection> DIRECTION_MAP = Arrays.stream(values()).collect(Collectors.toMap(SpecificDirection::getName, d -> d));
|
||||
|
||||
|
||||
SpecificDirection(final String name, final double hitx, final double hity, final double hitz, final Direction blockFacing)
|
||||
SpecificDirection(String name, double hitx, double hity, double hitz, Direction blockFacing)
|
||||
{
|
||||
this.name = name;
|
||||
this.hitOffset = new Vec3(hitx, hity, hitz);
|
||||
@@ -283,18 +322,18 @@ public class BlockValue extends Value
|
||||
private final Direction facing;
|
||||
private final boolean sneakPlace;
|
||||
|
||||
public static PlacementContext from(final Level world, final BlockPos pos, final String direction, final boolean sneakPlace, final ItemStack itemStack)
|
||||
public static PlacementContext from(Level world, BlockPos pos, String direction, boolean sneakPlace, ItemStack itemStack)
|
||||
{
|
||||
final SpecificDirection dir = SpecificDirection.DIRECTION_MAP.get(direction);
|
||||
SpecificDirection dir = SpecificDirection.DIRECTION_MAP.get(direction);
|
||||
if (dir == null)
|
||||
{
|
||||
throw new InternalExpressionException("unknown block placement direction: " + direction);
|
||||
}
|
||||
final BlockHitResult hitres = new BlockHitResult(Vec3.atLowerCornerOf(pos).add(dir.hitOffset), dir.facing, pos, false);
|
||||
BlockHitResult hitres = new BlockHitResult(Vec3.atLowerCornerOf(pos).add(dir.hitOffset), dir.facing, pos, false);
|
||||
return new PlacementContext(world, dir.facing, sneakPlace, itemStack, hitres);
|
||||
}
|
||||
|
||||
private PlacementContext(final Level world_1, final Direction direction_1, final boolean sneakPlace, final ItemStack itemStack_1, final BlockHitResult hitres)
|
||||
private PlacementContext(Level world_1, Direction direction_1, boolean sneakPlace, ItemStack itemStack_1, BlockHitResult hitres)
|
||||
{
|
||||
super(world_1, null, InteractionHand.MAIN_HAND, itemStack_1, hitres);
|
||||
this.facing = direction_1;
|
||||
@@ -304,9 +343,9 @@ public class BlockValue extends Value
|
||||
@Override
|
||||
public BlockPos getClickedPos()
|
||||
{
|
||||
final boolean prevcanReplaceExisting = replaceClicked;
|
||||
boolean prevcanReplaceExisting = replaceClicked;
|
||||
replaceClicked = true;
|
||||
final BlockPos ret = super.getClickedPos();
|
||||
BlockPos ret = super.getClickedPos();
|
||||
replaceClicked = prevcanReplaceExisting;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -12,13 +12,13 @@ public class BooleanValue extends NumericValue
|
||||
|
||||
boolean boolValue;
|
||||
|
||||
private BooleanValue(final boolean boolval)
|
||||
private BooleanValue(boolean boolval)
|
||||
{
|
||||
super(boolval ? 1L : 0L);
|
||||
boolValue = boolval;
|
||||
}
|
||||
|
||||
public static BooleanValue of(final boolean value)
|
||||
public static BooleanValue of(boolean value)
|
||||
{
|
||||
return value ? TRUE : FALSE;
|
||||
}
|
||||
@@ -54,7 +54,7 @@ public class BooleanValue extends NumericValue
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tag toTag(final boolean force)
|
||||
public Tag toTag(boolean force)
|
||||
{
|
||||
return ByteTag.valueOf(boolValue);
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ public interface ContainerValueInterface
|
||||
{
|
||||
boolean put(Value where, Value value);
|
||||
|
||||
default boolean put(final Value where, final Value value, final Value conditions)
|
||||
default boolean put(Value where, Value value, Value conditions)
|
||||
{
|
||||
return put(where, value);
|
||||
}
|
||||
|
||||
@@ -74,6 +74,7 @@ import net.minecraft.world.phys.EntityHitResult;
|
||||
import net.minecraft.world.phys.HitResult;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.EnumSet;
|
||||
@@ -97,19 +98,19 @@ public class EntityValue extends Value
|
||||
{
|
||||
private Entity entity;
|
||||
|
||||
public EntityValue(final Entity e)
|
||||
public EntityValue(Entity e)
|
||||
{
|
||||
entity = e;
|
||||
}
|
||||
|
||||
public static Value of(final Entity e)
|
||||
public static Value of(@Nullable Entity e)
|
||||
{
|
||||
return e == null ? Value.NULL : new EntityValue(e);
|
||||
}
|
||||
|
||||
private static final Map<String, EntitySelector> selectorCache = new HashMap<>();
|
||||
|
||||
public static Collection<? extends Entity> getEntitiesFromSelector(final CommandSourceStack source, final String selector)
|
||||
public static Collection<? extends Entity> getEntitiesFromSelector(CommandSourceStack source, String selector)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -122,7 +123,7 @@ public class EntityValue extends Value
|
||||
selectorCache.put(selector, entitySelector);
|
||||
return entitySelector.findEntities(source.withMaximumPermission(4));
|
||||
}
|
||||
catch (final CommandSyntaxException e)
|
||||
catch (CommandSyntaxException e)
|
||||
{
|
||||
throw new InternalExpressionException("Cannot select entities from " + selector);
|
||||
}
|
||||
@@ -132,7 +133,7 @@ public class EntityValue extends Value
|
||||
{
|
||||
if (entity instanceof final ServerPlayer serverPlayer && Vanilla.ServerPlayer_isInvalidEntityObject(serverPlayer))
|
||||
{
|
||||
final ServerPlayer newPlayer = entity.getServer().getPlayerList().getPlayer(entity.getUUID());
|
||||
ServerPlayer newPlayer = entity.getServer().getPlayerList().getPlayer(entity.getUUID());
|
||||
if (newPlayer != null)
|
||||
{
|
||||
entity = newPlayer;
|
||||
@@ -141,7 +142,7 @@ public class EntityValue extends Value
|
||||
return entity;
|
||||
}
|
||||
|
||||
public static ServerPlayer getPlayerByValue(final MinecraftServer server, final Value value)
|
||||
public static ServerPlayer getPlayerByValue(MinecraftServer server, Value value)
|
||||
{
|
||||
if (value instanceof final EntityValue ev && ev.getEntity() instanceof final ServerPlayer sp)
|
||||
{
|
||||
@@ -151,11 +152,11 @@ public class EntityValue extends Value
|
||||
{
|
||||
return null;
|
||||
}
|
||||
final String playerName = value.getString();
|
||||
String playerName = value.getString();
|
||||
return server.getPlayerList().getPlayerByName(playerName);
|
||||
}
|
||||
|
||||
public static String getPlayerNameByValue(final Value value)
|
||||
public static String getPlayerNameByValue(Value value)
|
||||
{
|
||||
if (value instanceof final EntityValue ev && ev.getEntity() instanceof final ServerPlayer sp)
|
||||
{
|
||||
@@ -181,7 +182,7 @@ public class EntityValue extends Value
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object v)
|
||||
public boolean equals(Object v)
|
||||
{
|
||||
if (v instanceof final EntityValue ev)
|
||||
{
|
||||
@@ -191,12 +192,12 @@ public class EntityValue extends Value
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value in(final Value v)
|
||||
public Value in(Value v)
|
||||
{
|
||||
if (v instanceof final ListValue lv)
|
||||
{
|
||||
final List<Value> values = lv.getItems();
|
||||
final String what = values.get(0).getString();
|
||||
List<Value> values = lv.getItems();
|
||||
String what = values.get(0).getString();
|
||||
Value arg = null;
|
||||
if (values.size() == 2)
|
||||
{
|
||||
@@ -208,7 +209,7 @@ public class EntityValue extends Value
|
||||
}
|
||||
return this.get(what, arg);
|
||||
}
|
||||
final String what = v.getString();
|
||||
String what = v.getString();
|
||||
return this.get(what, null);
|
||||
}
|
||||
|
||||
@@ -226,9 +227,9 @@ public class EntityValue extends Value
|
||||
|
||||
public static final EntityTypeTest<Entity, ?> ANY = EntityTypeTest.forClass(Entity.class);
|
||||
|
||||
public static EntityClassDescriptor getEntityDescriptor(String who, final MinecraftServer server)
|
||||
public static EntityClassDescriptor getEntityDescriptor(String who, MinecraftServer server)
|
||||
{
|
||||
final EntityClassDescriptor eDesc = EntityClassDescriptor.byName.get(who);
|
||||
EntityClassDescriptor eDesc = EntityClassDescriptor.byName.get(who);
|
||||
if (eDesc == null)
|
||||
{
|
||||
boolean positive = true;
|
||||
@@ -237,16 +238,16 @@ public class EntityValue extends Value
|
||||
positive = false;
|
||||
who = who.substring(1);
|
||||
}
|
||||
final String booWho = who;
|
||||
final HolderSet.Named<EntityType<?>> eTagValue = server.registryAccess().registryOrThrow(Registries.ENTITY_TYPE)
|
||||
String booWho = who;
|
||||
HolderSet.Named<EntityType<?>> eTagValue = server.registryAccess().registryOrThrow(Registries.ENTITY_TYPE)
|
||||
.getTag(TagKey.create(Registries.ENTITY_TYPE, InputValidator.identifierOf(who)))
|
||||
.orElseThrow(() -> new InternalExpressionException(booWho + " is not a valid entity descriptor"));
|
||||
final Set<EntityType<?>> eTag = eTagValue.stream().map(Holder::value).collect(Collectors.toUnmodifiableSet());
|
||||
Set<EntityType<?>> eTag = eTagValue.stream().map(Holder::value).collect(Collectors.toUnmodifiableSet());
|
||||
if (positive)
|
||||
{
|
||||
if (eTag.size() == 1)
|
||||
{
|
||||
final EntityType<?> type = eTag.iterator().next();
|
||||
EntityType<?> type = eTag.iterator().next();
|
||||
return new EntityClassDescriptor(type, Entity::isAlive, eTag.stream());
|
||||
}
|
||||
else
|
||||
@@ -270,36 +271,36 @@ public class EntityValue extends Value
|
||||
public final Predicate<? super Entity> filteringPredicate;
|
||||
public final List<EntityType<? extends Entity>> types;
|
||||
|
||||
EntityClassDescriptor(final EntityTypeTest<Entity, ?> type, final Predicate<? super Entity> predicate, final List<EntityType<?>> types)
|
||||
EntityClassDescriptor(EntityTypeTest<Entity, ?> type, Predicate<? super Entity> predicate, List<EntityType<?>> types)
|
||||
{
|
||||
this.directType = type;
|
||||
this.filteringPredicate = predicate;
|
||||
this.types = types;
|
||||
}
|
||||
|
||||
EntityClassDescriptor(final EntityTypeTest<Entity, ?> type, final Predicate<? super Entity> predicate, final Stream<EntityType<?>> types)
|
||||
EntityClassDescriptor(EntityTypeTest<Entity, ?> type, Predicate<? super Entity> predicate, Stream<EntityType<?>> types)
|
||||
{
|
||||
this(type, predicate, types.toList());
|
||||
}
|
||||
|
||||
public Value listValue(final RegistryAccess regs)
|
||||
public Value listValue(RegistryAccess regs)
|
||||
{
|
||||
final Registry<EntityType> entityRegs = regs.registryOrThrow(Registries.ENTITY_TYPE);
|
||||
return ListValue.wrap(types.stream().map(et -> StringValue.of(nameFromRegistryId(entityRegs.getKey(et)))));
|
||||
Registry<EntityType<?>> entityRegs = regs.registryOrThrow(Registries.ENTITY_TYPE);
|
||||
return ListValue.wrap(types.stream().map(et -> nameFromRegistryId(entityRegs.getKey(et))));
|
||||
}
|
||||
|
||||
public static final Map<String, EntityClassDescriptor> byName = new HashMap<>()
|
||||
{{
|
||||
final List<EntityType<?>> allTypes = BuiltInRegistries.ENTITY_TYPE.stream().toList();
|
||||
List<EntityType<?>> allTypes = BuiltInRegistries.ENTITY_TYPE.stream().toList();
|
||||
// nonliving types
|
||||
final Set<EntityType<?>> projectiles = Set.of(
|
||||
Set<EntityType<?>> projectiles = Set.of(
|
||||
EntityType.ARROW, EntityType.DRAGON_FIREBALL, EntityType.FIREWORK_ROCKET,
|
||||
EntityType.FIREBALL, EntityType.LLAMA_SPIT, EntityType.SMALL_FIREBALL,
|
||||
EntityType.SNOWBALL, EntityType.SPECTRAL_ARROW, EntityType.EGG,
|
||||
EntityType.ENDER_PEARL, EntityType.EXPERIENCE_BOTTLE, EntityType.POTION,
|
||||
EntityType.TRIDENT, EntityType.WITHER_SKULL, EntityType.FISHING_BOBBER, EntityType.SHULKER_BULLET
|
||||
);
|
||||
final Set<EntityType<?>> deads = Set.of(
|
||||
Set<EntityType<?>> deads = Set.of(
|
||||
EntityType.AREA_EFFECT_CLOUD, EntityType.MARKER, EntityType.BOAT, EntityType.END_CRYSTAL,
|
||||
EntityType.EVOKER_FANGS, EntityType.EXPERIENCE_ORB, EntityType.EYE_OF_ENDER,
|
||||
EntityType.FALLING_BLOCK, EntityType.ITEM, EntityType.ITEM_FRAME, EntityType.GLOW_ITEM_FRAME,
|
||||
@@ -307,37 +308,37 @@ public class EntityValue extends Value
|
||||
EntityType.TNT, EntityType.ARMOR_STAND, EntityType.CHEST_BOAT
|
||||
|
||||
);
|
||||
final Set<EntityType<?>> minecarts = Set.of(
|
||||
Set<EntityType<?>> minecarts = Set.of(
|
||||
EntityType.MINECART, EntityType.CHEST_MINECART, EntityType.COMMAND_BLOCK_MINECART,
|
||||
EntityType.FURNACE_MINECART, EntityType.HOPPER_MINECART,
|
||||
EntityType.SPAWNER_MINECART, EntityType.TNT_MINECART
|
||||
);
|
||||
// living mob groups - non-defeault
|
||||
final Set<EntityType<?>> undeads = Set.of(
|
||||
Set<EntityType<?>> undeads = Set.of(
|
||||
EntityType.STRAY, EntityType.SKELETON, EntityType.WITHER_SKELETON,
|
||||
EntityType.ZOMBIE, EntityType.DROWNED, EntityType.ZOMBIE_VILLAGER,
|
||||
EntityType.ZOMBIE_HORSE, EntityType.SKELETON_HORSE, EntityType.PHANTOM,
|
||||
EntityType.WITHER, EntityType.ZOGLIN, EntityType.HUSK, EntityType.ZOMBIFIED_PIGLIN
|
||||
|
||||
);
|
||||
final Set<EntityType<?>> arthropods = Set.of(
|
||||
Set<EntityType<?>> arthropods = Set.of(
|
||||
EntityType.BEE, EntityType.ENDERMITE, EntityType.SILVERFISH, EntityType.SPIDER,
|
||||
EntityType.CAVE_SPIDER
|
||||
);
|
||||
final Set<EntityType<?>> aquatique = Set.of(
|
||||
Set<EntityType<?>> aquatique = Set.of(
|
||||
EntityType.GUARDIAN, EntityType.TURTLE, EntityType.COD, EntityType.DOLPHIN, EntityType.PUFFERFISH,
|
||||
EntityType.SALMON, EntityType.SQUID, EntityType.TROPICAL_FISH
|
||||
);
|
||||
final Set<EntityType<?>> illagers = Set.of(
|
||||
Set<EntityType<?>> illagers = Set.of(
|
||||
EntityType.PILLAGER, EntityType.ILLUSIONER, EntityType.VINDICATOR, EntityType.EVOKER,
|
||||
EntityType.RAVAGER, EntityType.WITCH
|
||||
);
|
||||
|
||||
final Set<EntityType<?>> living = allTypes.stream().filter(et ->
|
||||
Set<EntityType<?>> living = allTypes.stream().filter(et ->
|
||||
!deads.contains(et) && !projectiles.contains(et) && !minecarts.contains(et)
|
||||
).collect(Collectors.toSet());
|
||||
|
||||
final Set<EntityType<?>> regular = allTypes.stream().filter(et ->
|
||||
Set<EntityType<?>> regular = allTypes.stream().filter(et ->
|
||||
living.contains(et) && !undeads.contains(et) && !arthropods.contains(et) && !aquatique.contains(et) && !illagers.contains(et)
|
||||
).collect(Collectors.toSet());
|
||||
|
||||
@@ -373,23 +374,23 @@ public class EntityValue extends Value
|
||||
put("regular", new EntityClassDescriptor(EntityTypeTest.forClass(LivingEntity.class), e -> (((LivingEntity) e).getMobType() == MobType.UNDEFINED && e.isAlive()), allTypes.stream().filter(regular::contains)));
|
||||
put("!regular", new EntityClassDescriptor(EntityTypeTest.forClass(LivingEntity.class), e -> (((LivingEntity) e).getMobType() != MobType.UNDEFINED && e.isAlive()), allTypes.stream().filter(et -> !regular.contains(et) && living.contains(et))));
|
||||
|
||||
for (final ResourceLocation typeId : BuiltInRegistries.ENTITY_TYPE.keySet())
|
||||
for (ResourceLocation typeId : BuiltInRegistries.ENTITY_TYPE.keySet())
|
||||
{
|
||||
final EntityType<?> type = BuiltInRegistries.ENTITY_TYPE.get(typeId);
|
||||
final String mobType = ValueConversions.simplify(typeId);
|
||||
EntityType<?> type = BuiltInRegistries.ENTITY_TYPE.get(typeId);
|
||||
String mobType = ValueConversions.simplify(typeId);
|
||||
put(mobType, new EntityClassDescriptor(type, net.minecraft.world.entity.EntitySelector.ENTITY_STILL_ALIVE, Stream.of(type)));
|
||||
put("!" + mobType, new EntityClassDescriptor(ANY, (e) -> e.getType() != type && e.isAlive(), allTypes.stream().filter(et -> et != type)));
|
||||
}
|
||||
for (final MobCategory catId : MobCategory.values())
|
||||
for (MobCategory catId : MobCategory.values())
|
||||
{
|
||||
final String catStr = catId.getName();
|
||||
String catStr = catId.getName();
|
||||
put(catStr, new EntityClassDescriptor(ANY, e -> ((e.getType().getCategory() == catId) && e.isAlive()), allTypes.stream().filter(et -> et.getCategory() == catId)));
|
||||
put("!" + catStr, new EntityClassDescriptor(ANY, e -> ((e.getType().getCategory() != catId) && e.isAlive()), allTypes.stream().filter(et -> et.getCategory() != catId)));
|
||||
}
|
||||
}};
|
||||
}
|
||||
|
||||
public Value get(final String what, final Value arg)
|
||||
public Value get(String what, @Nullable Value arg)
|
||||
{
|
||||
if (!(featureAccessors.containsKey(what)))
|
||||
{
|
||||
@@ -399,7 +400,7 @@ public class EntityValue extends Value
|
||||
{
|
||||
return featureAccessors.get(what).apply(getEntity(), arg);
|
||||
}
|
||||
catch (final NullPointerException npe)
|
||||
catch (NullPointerException npe)
|
||||
{
|
||||
throw new InternalExpressionException("Cannot fetch '" + what + "' with these arguments");
|
||||
}
|
||||
@@ -427,7 +428,7 @@ public class EntityValue extends Value
|
||||
put("z", (e, a) -> new NumericValue(e.getZ()));
|
||||
put("motion", (e, a) ->
|
||||
{
|
||||
final Vec3 velocity = e.getDeltaMovement();
|
||||
Vec3 velocity = e.getDeltaMovement();
|
||||
return ListValue.of(new NumericValue(velocity.x), new NumericValue(velocity.y), new NumericValue(velocity.z));
|
||||
});
|
||||
put("motion_x", (e, a) -> new NumericValue(e.getDeltaMovement().x));
|
||||
@@ -438,7 +439,7 @@ public class EntityValue extends Value
|
||||
put("display_name", (e, a) -> new FormattedTextValue(e.getDisplayName()));
|
||||
put("command_name", (e, a) -> new StringValue(e.getScoreboardName()));
|
||||
put("custom_name", (e, a) -> e.hasCustomName() ? new StringValue(e.getCustomName().getString()) : Value.NULL);
|
||||
put("type", (e, a) -> new StringValue(nameFromRegistryId(e.getLevel().registryAccess().registryOrThrow(Registries.ENTITY_TYPE).getKey(e.getType()))));
|
||||
put("type", (e, a) -> nameFromRegistryId(e.getLevel().registryAccess().registryOrThrow(Registries.ENTITY_TYPE).getKey(e.getType())));
|
||||
put("is_riding", (e, a) -> BooleanValue.of(e.isPassenger()));
|
||||
put("is_ridden", (e, a) -> BooleanValue.of(e.isVehicle()));
|
||||
put("passengers", (e, a) -> ListValue.wrap(e.getPassengers().stream().map(EntityValue::new)));
|
||||
@@ -449,7 +450,7 @@ public class EntityValue extends Value
|
||||
|
||||
put("scoreboard_tags", (e, a) -> ListValue.wrap(e.getTags().stream().map(StringValue::new)));
|
||||
put("entity_tags", (e, a) -> {
|
||||
final EntityType<?> type = e.getType();
|
||||
EntityType<?> type = e.getType();
|
||||
return ListValue.wrap(e.getServer().registryAccess().registryOrThrow(Registries.ENTITY_TYPE).getTags().filter(entry -> entry.getSecond().stream().anyMatch(h -> h.value() == type)).map(entry -> ValueConversions.of(entry.getFirst())));
|
||||
});
|
||||
// deprecated
|
||||
@@ -457,7 +458,7 @@ public class EntityValue extends Value
|
||||
|
||||
put("has_scoreboard_tag", (e, a) -> BooleanValue.of(e.getTags().contains(a.getString())));
|
||||
put("has_entity_tag", (e, a) -> {
|
||||
final Optional<HolderSet.Named<EntityType<?>>> tag = e.getServer().registryAccess().registryOrThrow(Registries.ENTITY_TYPE).getTag(TagKey.create(Registries.ENTITY_TYPE, InputValidator.identifierOf(a.getString())));
|
||||
Optional<HolderSet.Named<EntityType<?>>> tag = e.getServer().registryAccess().registryOrThrow(Registries.ENTITY_TYPE).getTag(TagKey.create(Registries.ENTITY_TYPE, InputValidator.identifierOf(a.getString())));
|
||||
if (tag.isEmpty())
|
||||
{
|
||||
return Value.NULL;
|
||||
@@ -465,7 +466,7 @@ public class EntityValue extends Value
|
||||
//Tag<EntityType<?>> tag = e.getServer().getTags().getOrEmpty(Registry.ENTITY_TYPE_REGISTRY).getTag(InputValidator.identifierOf(a.getString()));
|
||||
//if (tag == null) return Value.NULL;
|
||||
//return BooleanValue.of(e.getType().is(tag));
|
||||
final EntityType<?> type = e.getType();
|
||||
EntityType<?> type = e.getType();
|
||||
return BooleanValue.of(tag.get().stream().anyMatch(h -> h.value() == type));
|
||||
});
|
||||
|
||||
@@ -475,7 +476,7 @@ public class EntityValue extends Value
|
||||
|
||||
put("pitch", (e, a) -> new NumericValue(e.getXRot()));
|
||||
put("look", (e, a) -> {
|
||||
final Vec3 look = e.getLookAngle();
|
||||
Vec3 look = e.getLookAngle();
|
||||
return ListValue.of(new NumericValue(look.x), new NumericValue(look.y), new NumericValue(look.z));
|
||||
});
|
||||
put("is_burning", (e, a) -> BooleanValue.of(e.isOnFire()));
|
||||
@@ -488,7 +489,7 @@ public class EntityValue extends Value
|
||||
put("immune_to_frost", (e, a) -> BooleanValue.of(!e.canFreeze()));
|
||||
|
||||
put("invulnerable", (e, a) -> BooleanValue.of(e.isInvulnerable()));
|
||||
put("dimension", (e, a) -> new StringValue(nameFromRegistryId(e.level.dimension().location()))); // getDimId
|
||||
put("dimension", (e, a) -> nameFromRegistryId(e.level.dimension().location())); // getDimId
|
||||
put("height", (e, a) -> new NumericValue(e.getDimensions(Pose.STANDING).height));
|
||||
put("width", (e, a) -> new NumericValue(e.getDimensions(Pose.STANDING).width));
|
||||
put("eye_height", (e, a) -> new NumericValue(e.getEyeHeight()));
|
||||
@@ -507,7 +508,7 @@ public class EntityValue extends Value
|
||||
put("target", (e, a) -> {
|
||||
if (e instanceof final Mob mob)
|
||||
{
|
||||
final LivingEntity target = mob.getTarget(); // there is also getAttacking in living....
|
||||
LivingEntity target = mob.getTarget(); // there is also getAttacking in living....
|
||||
if (target != null)
|
||||
{
|
||||
return new EntityValue(target);
|
||||
@@ -515,7 +516,7 @@ public class EntityValue extends Value
|
||||
}
|
||||
return Value.NULL;
|
||||
});
|
||||
put("home", (e, a) -> e instanceof final Mob mob ? (mob.getRestrictRadius() > 0) ? new BlockValue(null, e.getCommandSenderWorld(), mob.getRestrictCenter()) : Value.FALSE : Value.NULL);
|
||||
put("home", (e, a) -> e instanceof final Mob mob ? (mob.getRestrictRadius() > 0) ? new BlockValue(null, (ServerLevel) e.getLevel(), mob.getRestrictCenter()) : Value.FALSE : Value.NULL);
|
||||
put("spawn_point", (e, a) -> {
|
||||
if (e instanceof final ServerPlayer spe)
|
||||
{
|
||||
@@ -553,7 +554,7 @@ public class EntityValue extends Value
|
||||
put("path", (e, a) -> {
|
||||
if (e instanceof final Mob mob)
|
||||
{
|
||||
final Path path = mob.getNavigation().getPath();
|
||||
Path path = mob.getNavigation().getPath();
|
||||
if (path == null)
|
||||
{
|
||||
return Value.NULL;
|
||||
@@ -564,22 +565,22 @@ public class EntityValue extends Value
|
||||
});
|
||||
|
||||
put("brain", (e, a) -> {
|
||||
final String module = a.getString();
|
||||
final MemoryModuleType<?> moduleType = e.getLevel().registryAccess().registryOrThrow(Registries.MEMORY_MODULE_TYPE).get(InputValidator.identifierOf(module));
|
||||
String module = a.getString();
|
||||
MemoryModuleType<?> moduleType = e.getLevel().registryAccess().registryOrThrow(Registries.MEMORY_MODULE_TYPE).get(InputValidator.identifierOf(module));
|
||||
if (moduleType == MemoryModuleType.DUMMY)
|
||||
{
|
||||
return Value.NULL;
|
||||
}
|
||||
if (e instanceof final LivingEntity livingEntity)
|
||||
{
|
||||
final Brain<?> brain = livingEntity.getBrain();
|
||||
final Map<MemoryModuleType<?>, Optional<? extends ExpirableValue<?>>> memories = brain.getMemories();
|
||||
final Optional<? extends ExpirableValue<?>> optmemory = memories.get(moduleType);
|
||||
Brain<?> brain = livingEntity.getBrain();
|
||||
Map<MemoryModuleType<?>, Optional<? extends ExpirableValue<?>>> memories = brain.getMemories();
|
||||
Optional<? extends ExpirableValue<?>> optmemory = memories.get(moduleType);
|
||||
if (optmemory == null || !optmemory.isPresent())
|
||||
{
|
||||
return Value.NULL;
|
||||
}
|
||||
final ExpirableValue<?> memory = optmemory.get();
|
||||
ExpirableValue<?> memory = optmemory.get();
|
||||
return ValueConversions.fromTimedMemory(e, memory.getTimeToLive(), memory.getValue());
|
||||
}
|
||||
return Value.NULL;
|
||||
@@ -604,22 +605,22 @@ public class EntityValue extends Value
|
||||
put("player_type", (e, a) -> {
|
||||
if (e instanceof final Player p)
|
||||
{
|
||||
final String moddedType = Carpet.isModdedPlayer(p);
|
||||
String moddedType = Carpet.isModdedPlayer(p);
|
||||
if (moddedType != null)
|
||||
{
|
||||
return StringValue.of(moddedType);
|
||||
}
|
||||
final MinecraftServer server = p.getCommandSenderWorld().getServer();
|
||||
MinecraftServer server = p.getCommandSenderWorld().getServer();
|
||||
if (server.isDedicatedServer())
|
||||
{
|
||||
return new StringValue("multiplayer");
|
||||
}
|
||||
final boolean runningLan = server.isPublished();
|
||||
boolean runningLan = server.isPublished();
|
||||
if (!runningLan)
|
||||
{
|
||||
return new StringValue("singleplayer");
|
||||
}
|
||||
final boolean isowner = server.isSingleplayerOwner(p.getGameProfile());
|
||||
boolean isowner = server.isSingleplayerOwner(p.getGameProfile());
|
||||
if (isowner)
|
||||
{
|
||||
return new StringValue("lan_host");
|
||||
@@ -644,8 +645,8 @@ public class EntityValue extends Value
|
||||
}
|
||||
if (a == null)
|
||||
{
|
||||
final List<Value> effects = new ArrayList<>();
|
||||
for (final MobEffectInstance p : le.getActiveEffects())
|
||||
List<Value> effects = new ArrayList<>();
|
||||
for (MobEffectInstance p : le.getActiveEffects())
|
||||
{
|
||||
effects.add(ListValue.of(
|
||||
new StringValue(p.getDescriptionId().replaceFirst("^effect\\.minecraft\\.", "")),
|
||||
@@ -655,8 +656,8 @@ public class EntityValue extends Value
|
||||
}
|
||||
return ListValue.wrap(effects);
|
||||
}
|
||||
final String effectName = a.getString();
|
||||
final MobEffect potion = BuiltInRegistries.MOB_EFFECT.get(InputValidator.identifierOf(effectName));
|
||||
String effectName = a.getString();
|
||||
MobEffect potion = BuiltInRegistries.MOB_EFFECT.get(InputValidator.identifierOf(effectName));
|
||||
if (potion == null)
|
||||
{
|
||||
throw new InternalExpressionException("No such an effect: " + effectName);
|
||||
@@ -665,7 +666,7 @@ public class EntityValue extends Value
|
||||
{
|
||||
return Value.NULL;
|
||||
}
|
||||
final MobEffectInstance pe = le.getEffect(potion);
|
||||
MobEffectInstance pe = le.getEffect(potion);
|
||||
return ListValue.of(new NumericValue(pe.getAmplifier()), new NumericValue(pe.getDuration()));
|
||||
});
|
||||
|
||||
@@ -698,12 +699,12 @@ public class EntityValue extends Value
|
||||
put("active_block", (e, a) -> {
|
||||
if (e instanceof final ServerPlayer sp)
|
||||
{
|
||||
final BlockPos pos = Vanilla.ServerPlayerGameMode_getCurrentBlockPosition(sp.gameMode);
|
||||
BlockPos pos = Vanilla.ServerPlayerGameMode_getCurrentBlockPosition(sp.gameMode);
|
||||
if (pos == null)
|
||||
{
|
||||
return Value.NULL;
|
||||
}
|
||||
return new BlockValue(null, e.level, pos);
|
||||
return new BlockValue(null, sp.getLevel(), pos);
|
||||
}
|
||||
return Value.NULL;
|
||||
});
|
||||
@@ -711,7 +712,7 @@ public class EntityValue extends Value
|
||||
put("breaking_progress", (e, a) -> {
|
||||
if (e instanceof final ServerPlayer sp)
|
||||
{
|
||||
final int progress = Vanilla.ServerPlayerGameMode_getCurrentBlockBreakingProgress (sp.gameMode);
|
||||
int progress = Vanilla.ServerPlayerGameMode_getCurrentBlockBreakingProgress (sp.gameMode);
|
||||
return progress < 0 ? Value.NULL : new NumericValue(progress);
|
||||
}
|
||||
return Value.NULL;
|
||||
@@ -748,7 +749,7 @@ public class EntityValue extends Value
|
||||
}
|
||||
else
|
||||
{
|
||||
final List<Value> args = lv.getItems();
|
||||
List<Value> args = lv.getItems();
|
||||
if (args.size() == 0)
|
||||
{
|
||||
throw new InternalExpressionException("'trace' needs more arguments");
|
||||
@@ -760,7 +761,7 @@ public class EntityValue extends Value
|
||||
blocks = false;
|
||||
for (int i = 1; i < args.size(); i++)
|
||||
{
|
||||
final String what = args.get(i).getString();
|
||||
String what = args.get(i).getString();
|
||||
if (what.equalsIgnoreCase("entities"))
|
||||
{
|
||||
entities = true;
|
||||
@@ -791,7 +792,7 @@ public class EntityValue extends Value
|
||||
reach = 5.0f;
|
||||
}
|
||||
|
||||
final HitResult hitres;
|
||||
HitResult hitres;
|
||||
if (entities && !blocks)
|
||||
{
|
||||
hitres = Tracer.rayTraceEntities(e, 1, reach, reach * reach);
|
||||
@@ -818,7 +819,7 @@ public class EntityValue extends Value
|
||||
case MISS:
|
||||
return Value.NULL;
|
||||
case BLOCK:
|
||||
return new BlockValue(null, e.getCommandSenderWorld(), ((BlockHitResult) hitres).getBlockPos());
|
||||
return new BlockValue((ServerLevel) e.getCommandSenderWorld(), ((BlockHitResult) hitres).getBlockPos());
|
||||
case ENTITY:
|
||||
return new EntityValue(((EntityHitResult) hitres).getEntity());
|
||||
}
|
||||
@@ -830,14 +831,14 @@ public class EntityValue extends Value
|
||||
{
|
||||
return Value.NULL;
|
||||
}
|
||||
final Registry<Attribute> attributes = e.getLevel().registryAccess().registryOrThrow(Registries.ATTRIBUTE);
|
||||
Registry<Attribute> attributes = e.getLevel().registryAccess().registryOrThrow(Registries.ATTRIBUTE);
|
||||
if (a == null)
|
||||
{
|
||||
final AttributeMap container = el.getAttributes();
|
||||
AttributeMap container = el.getAttributes();
|
||||
return MapValue.wrap(attributes.stream().filter(container::hasAttribute).collect(Collectors.toMap(aa -> ValueConversions.of(attributes.getKey(aa)), aa -> NumericValue.of(container.getValue(aa)))));
|
||||
}
|
||||
final ResourceLocation id = InputValidator.identifierOf(a.getString());
|
||||
final Attribute attrib = attributes.getOptional(id).orElseThrow(
|
||||
ResourceLocation id = InputValidator.identifierOf(a.getString());
|
||||
Attribute attrib = attributes.getOptional(id).orElseThrow(
|
||||
() -> new InternalExpressionException("Unknown attribute: " + a.getString())
|
||||
);
|
||||
if (!el.getAttributes().hasAttribute(attrib))
|
||||
@@ -848,7 +849,7 @@ public class EntityValue extends Value
|
||||
});
|
||||
|
||||
put("nbt", (e, a) -> {
|
||||
final CompoundTag nbttagcompound = e.saveWithoutId((new CompoundTag()));
|
||||
CompoundTag nbttagcompound = e.saveWithoutId((new CompoundTag()));
|
||||
if (a == null)
|
||||
{
|
||||
return new NBTSerializableValue(nbttagcompound);
|
||||
@@ -861,7 +862,7 @@ public class EntityValue extends Value
|
||||
});
|
||||
}};
|
||||
|
||||
public void set(final String what, final Value toWhat)
|
||||
public void set(String what, @Nullable Value toWhat)
|
||||
{
|
||||
if (!(featureModifiers.containsKey(what)))
|
||||
{
|
||||
@@ -871,17 +872,17 @@ public class EntityValue extends Value
|
||||
{
|
||||
featureModifiers.get(what).accept(getEntity(), toWhat);
|
||||
}
|
||||
catch (final NullPointerException npe)
|
||||
catch (NullPointerException npe)
|
||||
{
|
||||
throw new InternalExpressionException("'modify' for '" + what + "' expects a value");
|
||||
}
|
||||
catch (final IndexOutOfBoundsException ind)
|
||||
catch (IndexOutOfBoundsException ind)
|
||||
{
|
||||
throw new InternalExpressionException("Wrong number of arguments for `modify` option: " + what);
|
||||
}
|
||||
}
|
||||
|
||||
private static void updatePosition(final Entity e, final double x, final double y, final double z, final float yaw, final float pitch)
|
||||
private static void updatePosition(Entity e, double x, double y, double z, float yaw, float pitch)
|
||||
{
|
||||
if (
|
||||
!Double.isFinite(x) || Double.isNaN(x) ||
|
||||
@@ -896,7 +897,7 @@ public class EntityValue extends Value
|
||||
if (e instanceof final ServerPlayer sp)
|
||||
{
|
||||
// this forces position but doesn't angles for some reason. Need both in the API in the future.
|
||||
final EnumSet<RelativeMovement> set = EnumSet.noneOf(RelativeMovement.class);
|
||||
EnumSet<RelativeMovement> set = EnumSet.noneOf(RelativeMovement.class);
|
||||
set.add(RelativeMovement.X_ROT);
|
||||
set.add(RelativeMovement.Y_ROT);
|
||||
sp.connection.teleport(x, y, z, yaw, pitch, set);
|
||||
@@ -921,7 +922,7 @@ public class EntityValue extends Value
|
||||
}
|
||||
}
|
||||
|
||||
private static void updateVelocity(final Entity e, final double scale)
|
||||
private static void updateVelocity(Entity e, double scale)
|
||||
{
|
||||
e.hurtMarked = true;
|
||||
if (Math.abs(scale) > 10000)
|
||||
@@ -935,7 +936,7 @@ public class EntityValue extends Value
|
||||
put("remove", (entity, value) -> entity.discard()); // using discard here - will see other options if valid
|
||||
put("age", (e, v) -> e.tickCount = Math.abs((int) NumericValue.asNumber(v).getLong()));
|
||||
put("health", (e, v) -> {
|
||||
final float health = (float) NumericValue.asNumber(v).getDouble();
|
||||
float health = (float) NumericValue.asNumber(v).getDouble();
|
||||
if (health <= 0f && e instanceof final ServerPlayer player)
|
||||
{
|
||||
if (player.containerMenu != null)
|
||||
@@ -954,7 +955,7 @@ public class EntityValue extends Value
|
||||
});
|
||||
|
||||
put("may_fly", (e, v) -> {
|
||||
final boolean mayFly = v.getBoolean();
|
||||
boolean mayFly = v.getBoolean();
|
||||
if (e instanceof final ServerPlayer player)
|
||||
{
|
||||
player.getAbilities().mayfly = mayFly;
|
||||
@@ -967,7 +968,7 @@ public class EntityValue extends Value
|
||||
});
|
||||
|
||||
put("flying", (e, v) -> {
|
||||
final boolean flying = v.getBoolean();
|
||||
boolean flying = v.getBoolean();
|
||||
if (e instanceof final ServerPlayer player)
|
||||
{
|
||||
player.getAbilities().flying = flying;
|
||||
@@ -976,7 +977,7 @@ public class EntityValue extends Value
|
||||
});
|
||||
|
||||
put("may_build", (e, v) -> {
|
||||
final boolean mayBuild = v.getBoolean();
|
||||
boolean mayBuild = v.getBoolean();
|
||||
if (e instanceof final ServerPlayer player)
|
||||
{
|
||||
player.getAbilities().mayBuild = mayBuild;
|
||||
@@ -985,7 +986,7 @@ public class EntityValue extends Value
|
||||
});
|
||||
|
||||
put("insta_build", (e, v) -> {
|
||||
final boolean instaBuild = v.getBoolean();
|
||||
boolean instaBuild = v.getBoolean();
|
||||
if (e instanceof final ServerPlayer player)
|
||||
{
|
||||
player.getAbilities().instabuild = instaBuild;
|
||||
@@ -994,7 +995,7 @@ public class EntityValue extends Value
|
||||
});
|
||||
|
||||
put("fly_speed", (e, v) -> {
|
||||
final float flySpeed = NumericValue.asNumber(v).getFloat();
|
||||
float flySpeed = NumericValue.asNumber(v).getFloat();
|
||||
if (e instanceof final ServerPlayer player)
|
||||
{
|
||||
player.getAbilities().setFlyingSpeed(flySpeed);
|
||||
@@ -1003,7 +1004,7 @@ public class EntityValue extends Value
|
||||
});
|
||||
|
||||
put("walk_speed", (e, v) -> {
|
||||
final float walkSpeed = NumericValue.asNumber(v).getFloat();
|
||||
float walkSpeed = NumericValue.asNumber(v).getFloat();
|
||||
if (e instanceof final ServerPlayer player)
|
||||
{
|
||||
player.getAbilities().setWalkingSpeed(walkSpeed);
|
||||
@@ -1015,7 +1016,7 @@ public class EntityValue extends Value
|
||||
{
|
||||
if (e instanceof final ServerPlayer player)
|
||||
{
|
||||
final int slot = NumericValue.asNumber(v).getInt();
|
||||
int slot = NumericValue.asNumber(v).getInt();
|
||||
player.connection.send(new ClientboundSetCarriedItemPacket(slot));
|
||||
}
|
||||
});
|
||||
@@ -1042,7 +1043,7 @@ public class EntityValue extends Value
|
||||
{
|
||||
throw new InternalExpressionException("Expected a list of 5 parameters as a second argument");
|
||||
}
|
||||
final List<Value> coords = lv.getItems();
|
||||
List<Value> coords = lv.getItems();
|
||||
updatePosition(e,
|
||||
NumericValue.asNumber(coords.get(0)).getDouble(),
|
||||
NumericValue.asNumber(coords.get(1)).getDouble(),
|
||||
@@ -1057,7 +1058,7 @@ public class EntityValue extends Value
|
||||
{
|
||||
throw new InternalExpressionException("Expected a list of 3 parameters as a second argument");
|
||||
}
|
||||
final List<Value> coords = lv.getItems();
|
||||
List<Value> coords = lv.getItems();
|
||||
updatePosition(e,
|
||||
NumericValue.asNumber(coords.get(0)).getDouble(),
|
||||
NumericValue.asNumber(coords.get(1)).getDouble(),
|
||||
@@ -1092,11 +1093,11 @@ public class EntityValue extends Value
|
||||
{
|
||||
throw new InternalExpressionException("Expected a list of 3 parameters as a second argument");
|
||||
}
|
||||
final List<Value> vec = lv.getItems();
|
||||
List<Value> vec = lv.getItems();
|
||||
float x = NumericValue.asNumber(vec.get(0)).getFloat();
|
||||
float y = NumericValue.asNumber(vec.get(1)).getFloat();
|
||||
float z = NumericValue.asNumber(vec.get(2)).getFloat();
|
||||
final float l = Mth.sqrt(x * x + y * y + z * z);
|
||||
float l = Mth.sqrt(x * x + y * y + z * z);
|
||||
if (l == 0)
|
||||
{
|
||||
return;
|
||||
@@ -1104,8 +1105,8 @@ public class EntityValue extends Value
|
||||
x /= l;
|
||||
y /= l;
|
||||
z /= l;
|
||||
final float pitch = (float) -Math.asin(y) / 0.017453292F;
|
||||
final float yaw = (float) (x == 0 && z == 0 ? e.getYRot() : Mth.atan2(-x, z) / 0.017453292F);
|
||||
float pitch = (float) -Math.asin(y) / 0.017453292F;
|
||||
float yaw = (float) (x == 0 && z == 0 ? e.getYRot() : Mth.atan2(-x, z) / 0.017453292F);
|
||||
updatePosition(e, e.getX(), e.getY(), e.getZ(), yaw, pitch);
|
||||
});
|
||||
|
||||
@@ -1118,7 +1119,7 @@ public class EntityValue extends Value
|
||||
{
|
||||
throw new InternalExpressionException("Expected a list of 3 parameters as a second argument");
|
||||
}
|
||||
final List<Value> coords = lv.getItems();
|
||||
List<Value> coords = lv.getItems();
|
||||
updatePosition(e,
|
||||
e.getX() + NumericValue.asNumber(coords.get(0)).getDouble(),
|
||||
e.getY() + NumericValue.asNumber(coords.get(1)).getDouble(),
|
||||
@@ -1134,31 +1135,31 @@ public class EntityValue extends Value
|
||||
{
|
||||
throw new InternalExpressionException("Expected a list of 3 parameters as a second argument");
|
||||
}
|
||||
final List<Value> coords = lv.getItems();
|
||||
final double dx = NumericValue.asNumber(coords.get(0)).getDouble();
|
||||
final double dy = NumericValue.asNumber(coords.get(1)).getDouble();
|
||||
final double dz = NumericValue.asNumber(coords.get(2)).getDouble();
|
||||
List<Value> coords = lv.getItems();
|
||||
double dx = NumericValue.asNumber(coords.get(0)).getDouble();
|
||||
double dy = NumericValue.asNumber(coords.get(1)).getDouble();
|
||||
double dz = NumericValue.asNumber(coords.get(2)).getDouble();
|
||||
e.setDeltaMovement(dx, dy, dz);
|
||||
updateVelocity(e, Mth.absMax(Mth.absMax(dx, dy), dz));
|
||||
});
|
||||
put("motion_x", (e, v) ->
|
||||
{
|
||||
final Vec3 velocity = e.getDeltaMovement();
|
||||
final double dv = NumericValue.asNumber(v).getDouble();
|
||||
Vec3 velocity = e.getDeltaMovement();
|
||||
double dv = NumericValue.asNumber(v).getDouble();
|
||||
e.setDeltaMovement(dv, velocity.y, velocity.z);
|
||||
updateVelocity(e, dv);
|
||||
});
|
||||
put("motion_y", (e, v) ->
|
||||
{
|
||||
final Vec3 velocity = e.getDeltaMovement();
|
||||
final double dv = NumericValue.asNumber(v).getDouble();
|
||||
Vec3 velocity = e.getDeltaMovement();
|
||||
double dv = NumericValue.asNumber(v).getDouble();
|
||||
e.setDeltaMovement(velocity.x, dv, velocity.z);
|
||||
updateVelocity(e, dv);
|
||||
});
|
||||
put("motion_z", (e, v) ->
|
||||
{
|
||||
final Vec3 velocity = e.getDeltaMovement();
|
||||
final double dv = NumericValue.asNumber(v).getDouble();
|
||||
Vec3 velocity = e.getDeltaMovement();
|
||||
double dv = NumericValue.asNumber(v).getDouble();
|
||||
e.setDeltaMovement(velocity.x, velocity.y, dv);
|
||||
updateVelocity(e, dv);
|
||||
});
|
||||
@@ -1169,7 +1170,7 @@ public class EntityValue extends Value
|
||||
{
|
||||
throw new InternalExpressionException("Expected a list of 3 parameters as a second argument");
|
||||
}
|
||||
final List<Value> coords = lv.getItems();
|
||||
List<Value> coords = lv.getItems();
|
||||
e.push(
|
||||
NumericValue.asNumber(coords.get(0)).getDouble(),
|
||||
NumericValue.asNumber(coords.get(1)).getDouble(),
|
||||
@@ -1232,7 +1233,7 @@ public class EntityValue extends Value
|
||||
}
|
||||
else if (v instanceof final ListValue lv)
|
||||
{
|
||||
for (final Value element : lv.getItems())
|
||||
for (Value element : lv.getItems())
|
||||
{
|
||||
if (element instanceof final EntityValue ev)
|
||||
{
|
||||
@@ -1248,7 +1249,7 @@ public class EntityValue extends Value
|
||||
}
|
||||
if (v instanceof final ListValue lv)
|
||||
{
|
||||
for (final Value element : lv.getItems())
|
||||
for (Value element : lv.getItems())
|
||||
{
|
||||
e.addTag(element.getString());
|
||||
}
|
||||
@@ -1265,7 +1266,7 @@ public class EntityValue extends Value
|
||||
}
|
||||
if (v instanceof final ListValue lv)
|
||||
{
|
||||
for (final Value element : lv.getItems())
|
||||
for (Value element : lv.getItems())
|
||||
{
|
||||
e.removeTag(element.getString());
|
||||
}
|
||||
@@ -1309,13 +1310,13 @@ public class EntityValue extends Value
|
||||
if (v.isNull())
|
||||
{
|
||||
ec.restrictTo(BlockPos.ZERO, -1);
|
||||
final Map<String, Goal> tasks = Vanilla.Mob_getTemporaryTasks(ec);
|
||||
Map<String, Goal> tasks = Vanilla.Mob_getTemporaryTasks(ec);
|
||||
Vanilla.Mob_getAI(ec, false).removeGoal(tasks.get("home"));
|
||||
tasks.remove("home");
|
||||
return;
|
||||
}
|
||||
|
||||
final BlockPos pos;
|
||||
BlockPos pos;
|
||||
int distance = 16;
|
||||
|
||||
if (v instanceof final BlockValue bv)
|
||||
@@ -1328,8 +1329,8 @@ public class EntityValue extends Value
|
||||
}
|
||||
else if (v instanceof final ListValue lv)
|
||||
{
|
||||
final List<Value> list = lv.getItems();
|
||||
final Vector3Argument locator = Vector3Argument.findIn(list, 0, false, false);
|
||||
List<Value> list = lv.getItems();
|
||||
Vector3Argument locator = Vector3Argument.findIn(list, 0, false, false);
|
||||
pos = new BlockPos(locator.vec.x, locator.vec.y, locator.vec.z);
|
||||
if (list.size() > locator.offset)
|
||||
{
|
||||
@@ -1342,10 +1343,10 @@ public class EntityValue extends Value
|
||||
}
|
||||
|
||||
ec.restrictTo(pos, distance);
|
||||
final Map<String, Goal> tasks = Vanilla.Mob_getTemporaryTasks(ec);
|
||||
Map<String, Goal> tasks = Vanilla.Mob_getTemporaryTasks(ec);
|
||||
if (!tasks.containsKey("home"))
|
||||
{
|
||||
final Goal task = new MoveTowardsRestrictionGoal(ec, 1.0D);
|
||||
Goal task = new MoveTowardsRestrictionGoal(ec, 1.0D);
|
||||
tasks.put("home", task);
|
||||
Vanilla.Mob_getAI(ec, false).addGoal(10, task);
|
||||
}
|
||||
@@ -1362,15 +1363,15 @@ public class EntityValue extends Value
|
||||
}
|
||||
else if (a instanceof final ListValue lv)
|
||||
{
|
||||
final List<Value> params = lv.getItems();
|
||||
final Vector3Argument blockLocator = Vector3Argument.findIn(params, 0, false, false);
|
||||
final BlockPos pos = new BlockPos(blockLocator.vec);
|
||||
List<Value> params = lv.getItems();
|
||||
Vector3Argument blockLocator = Vector3Argument.findIn(params, 0, false, false);
|
||||
BlockPos pos = new BlockPos(blockLocator.vec);
|
||||
ResourceKey<Level> world = spe.getCommandSenderWorld().dimension();
|
||||
float angle = spe.getYHeadRot();
|
||||
boolean forced = false;
|
||||
if (params.size() > blockLocator.offset)
|
||||
{
|
||||
final Value worldValue = params.get(blockLocator.offset + 0);
|
||||
Value worldValue = params.get(blockLocator.offset + 0);
|
||||
world = ValueConversions.dimFromValue(worldValue, spe.getServer()).dimension();
|
||||
if (params.size() > blockLocator.offset + 1)
|
||||
{
|
||||
@@ -1467,11 +1468,11 @@ public class EntityValue extends Value
|
||||
}
|
||||
else if (v instanceof final ListValue lv)
|
||||
{
|
||||
final List<Value> list = lv.getItems();
|
||||
List<Value> list = lv.getItems();
|
||||
if (list.size() >= 1 && list.size() <= 6)
|
||||
{
|
||||
final String effectName = list.get(0).getString();
|
||||
final MobEffect effect = BuiltInRegistries.MOB_EFFECT.get(InputValidator.identifierOf(effectName));
|
||||
String effectName = list.get(0).getString();
|
||||
MobEffect effect = BuiltInRegistries.MOB_EFFECT.get(InputValidator.identifierOf(effectName));
|
||||
if (effect == null)
|
||||
{
|
||||
throw new InternalExpressionException("Wrong effect name: " + effectName);
|
||||
@@ -1481,7 +1482,7 @@ public class EntityValue extends Value
|
||||
le.removeEffect(effect);
|
||||
return;
|
||||
}
|
||||
final int duration = (int) NumericValue.asNumber(list.get(1)).getLong();
|
||||
int duration = (int) NumericValue.asNumber(list.get(1)).getLong();
|
||||
if (duration <= 0)
|
||||
{
|
||||
le.removeEffect(effect);
|
||||
@@ -1513,8 +1514,8 @@ public class EntityValue extends Value
|
||||
}
|
||||
else
|
||||
{
|
||||
final String effectName = v.getString();
|
||||
final MobEffect effect = BuiltInRegistries.MOB_EFFECT.get(InputValidator.identifierOf(effectName));
|
||||
String effectName = v.getString();
|
||||
MobEffect effect = BuiltInRegistries.MOB_EFFECT.get(InputValidator.identifierOf(effectName));
|
||||
if (effect == null)
|
||||
{
|
||||
throw new InternalExpressionException("Wrong effect name: " + effectName);
|
||||
@@ -1530,7 +1531,7 @@ public class EntityValue extends Value
|
||||
{
|
||||
return;
|
||||
}
|
||||
final GameType toSet = v instanceof NumericValue ?
|
||||
GameType toSet = v instanceof NumericValue ?
|
||||
GameType.byId(((NumericValue) v).getInt()) :
|
||||
GameType.byName(v.getString().toLowerCase(Locale.ROOT), null);
|
||||
if (toSet != null)
|
||||
@@ -1564,7 +1565,7 @@ public class EntityValue extends Value
|
||||
InteractionHand hand = InteractionHand.MAIN_HAND;
|
||||
if (v != null)
|
||||
{
|
||||
final String handString = v.getString().toLowerCase(Locale.ROOT);
|
||||
String handString = v.getString().toLowerCase(Locale.ROOT);
|
||||
if (handString.equals("offhand") || handString.equals("off_hand"))
|
||||
{
|
||||
hand = InteractionHand.OFF_HAND;
|
||||
@@ -1579,7 +1580,7 @@ public class EntityValue extends Value
|
||||
put("gravity", (e, v) -> e.setNoGravity(!v.getBoolean()));
|
||||
|
||||
put("invulnerable", (e, v) -> {
|
||||
final boolean invulnerable = v.getBoolean();
|
||||
boolean invulnerable = v.getBoolean();
|
||||
if (e instanceof final ServerPlayer player)
|
||||
{
|
||||
player.getAbilities().invulnerable = invulnerable;
|
||||
@@ -1663,7 +1664,7 @@ public class EntityValue extends Value
|
||||
put("breaking_progress", (e, a) -> {
|
||||
if (e instanceof final ServerPlayer sp)
|
||||
{
|
||||
final int progress = (a == null || a.isNull()) ? -1 : NumericValue.asNumber(a).getInt();
|
||||
int progress = (a == null || a.isNull()) ? -1 : NumericValue.asNumber(a).getInt();
|
||||
Vanilla.ServerPlayerGameMode_setBlockBreakingProgress(sp.gameMode, progress);
|
||||
}
|
||||
});
|
||||
@@ -1671,8 +1672,8 @@ public class EntityValue extends Value
|
||||
put("nbt", (e, v) -> {
|
||||
if (!(e instanceof Player))
|
||||
{
|
||||
final UUID uUID = e.getUUID();
|
||||
final Value tagValue = NBTSerializableValue.fromValue(v);
|
||||
UUID uUID = e.getUUID();
|
||||
Value tagValue = NBTSerializableValue.fromValue(v);
|
||||
if (tagValue instanceof final NBTSerializableValue nbtsv)
|
||||
{
|
||||
e.load(nbtsv.getCompoundTag());
|
||||
@@ -1683,11 +1684,11 @@ public class EntityValue extends Value
|
||||
put("nbt_merge", (e, v) -> {
|
||||
if (!(e instanceof Player))
|
||||
{
|
||||
final UUID uUID = e.getUUID();
|
||||
final Value tagValue = NBTSerializableValue.fromValue(v);
|
||||
UUID uUID = e.getUUID();
|
||||
Value tagValue = NBTSerializableValue.fromValue(v);
|
||||
if (tagValue instanceof final NBTSerializableValue nbtsv)
|
||||
{
|
||||
final CompoundTag nbttagcompound = e.saveWithoutId((new CompoundTag()));
|
||||
CompoundTag nbttagcompound = e.saveWithoutId((new CompoundTag()));
|
||||
nbttagcompound.merge(nbtsv.getCompoundTag());
|
||||
e.load(nbttagcompound);
|
||||
e.setUUID(uUID);
|
||||
@@ -1710,7 +1711,7 @@ public class EntityValue extends Value
|
||||
|
||||
});
|
||||
put("item", (e, v) -> {
|
||||
final ItemStack item = ValueConversions.getItemStackFromValue(v, true, e.level.registryAccess());
|
||||
ItemStack item = ValueConversions.getItemStackFromValue(v, true, e.level.registryAccess());
|
||||
if (e instanceof final ItemEntity itementity)
|
||||
{
|
||||
itementity.setItem(item);
|
||||
@@ -1725,9 +1726,9 @@ public class EntityValue extends Value
|
||||
// "effect_"name []
|
||||
}};
|
||||
|
||||
public void setEvent(final CarpetContext cc, final String eventName, final FunctionValue fun, final List<Value> args)
|
||||
public void setEvent(CarpetContext cc, String eventName, FunctionValue fun, List<Value> args)
|
||||
{
|
||||
final EntityEventsGroup.Event event = EntityEventsGroup.Event.byName.get(eventName);
|
||||
EntityEventsGroup.Event event = EntityEventsGroup.Event.byName.get(eventName);
|
||||
if (event == null)
|
||||
{
|
||||
throw new InternalExpressionException("Unknown entity event: " + eventName);
|
||||
@@ -1736,15 +1737,15 @@ public class EntityValue extends Value
|
||||
}
|
||||
|
||||
@Override
|
||||
public net.minecraft.nbt.Tag toTag(final boolean force)
|
||||
public net.minecraft.nbt.Tag toTag(boolean force)
|
||||
{
|
||||
if (!force)
|
||||
{
|
||||
throw new NBTSerializableValue.IncompatibleTypeException(this);
|
||||
}
|
||||
final CompoundTag tag = new CompoundTag();
|
||||
CompoundTag tag = new CompoundTag();
|
||||
tag.put("Data", getEntity().saveWithoutId(new CompoundTag()));
|
||||
final Registry<EntityType<?>> reg = getEntity().level.registryAccess().registryOrThrow(Registries.ENTITY_TYPE);
|
||||
Registry<EntityType<?>> reg = getEntity().level.registryAccess().registryOrThrow(Registries.ENTITY_TYPE);
|
||||
tag.put("Name", StringTag.valueOf(reg.getKey(getEntity().getType()).toString()));
|
||||
return tag;
|
||||
}
|
||||
|
||||
@@ -10,15 +10,15 @@ public class FormattedTextValue extends StringValue
|
||||
{
|
||||
Component text;
|
||||
|
||||
public FormattedTextValue(final Component text)
|
||||
public FormattedTextValue(Component text)
|
||||
{
|
||||
super(null);
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
public static Value combine(final Value left, final Value right)
|
||||
public static Value combine(Value left, Value right)
|
||||
{
|
||||
final MutableComponent text;
|
||||
MutableComponent text;
|
||||
if (left instanceof final FormattedTextValue ftv)
|
||||
{
|
||||
text = ftv.getText().copy();
|
||||
@@ -45,7 +45,7 @@ public class FormattedTextValue extends StringValue
|
||||
return new FormattedTextValue(text);
|
||||
}
|
||||
|
||||
public static Value of(final Component text)
|
||||
public static Value of(Component text)
|
||||
{
|
||||
return text == null ? Value.NULL : new FormattedTextValue(text);
|
||||
}
|
||||
@@ -80,7 +80,7 @@ public class FormattedTextValue extends StringValue
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tag toTag(final boolean force)
|
||||
public Tag toTag(boolean force)
|
||||
{
|
||||
if (!force)
|
||||
{
|
||||
@@ -96,7 +96,7 @@ public class FormattedTextValue extends StringValue
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value add(final Value o)
|
||||
public Value add(Value o)
|
||||
{
|
||||
return combine(this, o);
|
||||
}
|
||||
@@ -106,12 +106,12 @@ public class FormattedTextValue extends StringValue
|
||||
return Component.Serializer.toJson(text);
|
||||
}
|
||||
|
||||
public static FormattedTextValue deserialize(final String serialized)
|
||||
public static FormattedTextValue deserialize(String serialized)
|
||||
{
|
||||
return new FormattedTextValue(Component.Serializer.fromJson(serialized));
|
||||
}
|
||||
|
||||
public static Component getTextByValue(final Value value)
|
||||
public static Component getTextByValue(Value value)
|
||||
{
|
||||
return (value instanceof final FormattedTextValue ftv) ? ftv.getText() : Component.literal(value.getString());
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ public abstract class FrameworkValue extends Value
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tag toTag(final boolean force)
|
||||
public Tag toTag(boolean force)
|
||||
{
|
||||
throw new UnsupportedOperationException("Scarpet language component cannot be serialized to the tag");
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ public class FunctionAnnotationValue extends Value
|
||||
|
||||
public Type type;
|
||||
|
||||
public FunctionAnnotationValue(final Value variable, final Type type)
|
||||
public FunctionAnnotationValue(Value variable, Type type)
|
||||
{
|
||||
if (variable.boundVariable == null)
|
||||
{
|
||||
@@ -41,7 +41,7 @@ public class FunctionAnnotationValue extends Value
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tag toTag(final boolean force)
|
||||
public Tag toTag(boolean force)
|
||||
{
|
||||
throw new UnsupportedOperationException("Global value cannot be serialized to the tag");
|
||||
}
|
||||
|
||||
@@ -4,12 +4,12 @@ import java.util.List;
|
||||
|
||||
public class FunctionSignatureValue extends FrameworkValue
|
||||
{
|
||||
private String identifier;
|
||||
private List<String> arguments;
|
||||
private List<String> globals;
|
||||
private String varArgs;
|
||||
private final String identifier;
|
||||
private final List<String> arguments;
|
||||
private final List<String> globals;
|
||||
private final String varArgs;
|
||||
|
||||
public FunctionSignatureValue(final String name, final List<String> args, final String varArgs, final List<String> globals)
|
||||
public FunctionSignatureValue(String name, List<String> args, String varArgs, List<String> globals)
|
||||
{
|
||||
this.identifier = name;
|
||||
this.arguments = args;
|
||||
|
||||
@@ -4,7 +4,7 @@ import java.util.List;
|
||||
|
||||
public class FunctionUnpackedArgumentsValue extends ListValue
|
||||
{
|
||||
public FunctionUnpackedArgumentsValue(final List<Value> list)
|
||||
public FunctionUnpackedArgumentsValue(List<Value> list)
|
||||
{
|
||||
super(list);
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ public class FunctionValue extends Value implements Fluff.ILazyFunction
|
||||
private static long variantCounter = 1;
|
||||
private long variant;
|
||||
|
||||
private FunctionValue(final Expression expression, final Tokenizer.Token token, final String name, final LazyValue body, final List<String> args, final String varArgs)
|
||||
private FunctionValue(Expression expression, Tokenizer.Token token, String name, LazyValue body, List<String> args, String varArgs)
|
||||
{
|
||||
this.expression = expression;
|
||||
this.token = token;
|
||||
@@ -46,7 +46,7 @@ public class FunctionValue extends Value implements Fluff.ILazyFunction
|
||||
variant = 0L;
|
||||
}
|
||||
|
||||
public FunctionValue(final Expression expression, final Tokenizer.Token token, final String name, final LazyValue body, final List<String> args, final String varArgs, final Map<String, LazyValue> outerState)
|
||||
public FunctionValue(Expression expression, Tokenizer.Token token, String name, LazyValue body, List<String> args, String varArgs, Map<String, LazyValue> outerState)
|
||||
{
|
||||
this.expression = expression;
|
||||
this.token = token;
|
||||
@@ -72,7 +72,7 @@ public class FunctionValue extends Value implements Fluff.ILazyFunction
|
||||
@Override
|
||||
public String getPrettyString()
|
||||
{
|
||||
final List<String> stringArgs = new ArrayList<>(args);
|
||||
List<String> stringArgs = new ArrayList<>(args);
|
||||
if (outerState != null)
|
||||
{
|
||||
stringArgs.addAll(outerState.entrySet().stream().map(e ->
|
||||
@@ -95,7 +95,7 @@ public class FunctionValue extends Value implements Fluff.ILazyFunction
|
||||
@Override
|
||||
protected Value clone()
|
||||
{
|
||||
final FunctionValue ret = new FunctionValue(expression, token, name, body, args, varArgs);
|
||||
FunctionValue ret = new FunctionValue(expression, token, name, body, args, varArgs);
|
||||
ret.outerState = this.outerState;
|
||||
ret.variant = this.variant;
|
||||
return ret;
|
||||
@@ -108,17 +108,17 @@ public class FunctionValue extends Value implements Fluff.ILazyFunction
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object o)
|
||||
public boolean equals(Object o)
|
||||
{
|
||||
return o instanceof final FunctionValue fv && name.equals(fv.name) && variant == fv.variant;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(final Value o)
|
||||
public int compareTo(Value o)
|
||||
{
|
||||
if (o instanceof final FunctionValue fv)
|
||||
{
|
||||
final int nameSame = this.name.compareTo(fv.name);
|
||||
int nameSame = this.name.compareTo(fv.name);
|
||||
return nameSame != 0 ? nameSame : (int) (variant - fv.variant);
|
||||
}
|
||||
return getString().compareTo(o.getString());
|
||||
@@ -137,7 +137,7 @@ public class FunctionValue extends Value implements Fluff.ILazyFunction
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value slice(final long from, final Long to)
|
||||
public Value slice(long from, Long to)
|
||||
{
|
||||
throw new InternalExpressionException("Cannot slice a function");
|
||||
}
|
||||
@@ -154,31 +154,31 @@ public class FunctionValue extends Value implements Fluff.ILazyFunction
|
||||
return varArgs != null;
|
||||
}
|
||||
|
||||
public LazyValue callInContext(final Context c, final Context.Type type, final List<Value> params)
|
||||
public LazyValue callInContext(Context c, Context.Type type, List<Value> params)
|
||||
{
|
||||
try
|
||||
{
|
||||
return execute(c, type, expression, token, params);
|
||||
}
|
||||
catch (final ExpressionException exc)
|
||||
catch (ExpressionException exc)
|
||||
{
|
||||
exc.stack.add(this);
|
||||
throw exc;
|
||||
}
|
||||
catch (final InternalExpressionException exc)
|
||||
catch (InternalExpressionException exc)
|
||||
{
|
||||
exc.stack.add(this);
|
||||
throw new ExpressionException(c, expression, token, exc.getMessage(), exc.stack);
|
||||
}
|
||||
catch (final ArithmeticException exc)
|
||||
catch (ArithmeticException exc)
|
||||
{
|
||||
throw new ExpressionException(c, expression, token, "Your math is wrong, " + exc.getMessage(), Collections.singletonList(this));
|
||||
}
|
||||
}
|
||||
|
||||
public void checkArgs(final int candidates)
|
||||
public void checkArgs(int candidates)
|
||||
{
|
||||
final int actual = getArguments().size();
|
||||
int actual = getArguments().size();
|
||||
|
||||
if (candidates < actual)
|
||||
{
|
||||
@@ -190,13 +190,13 @@ public class FunctionValue extends Value implements Fluff.ILazyFunction
|
||||
}
|
||||
}
|
||||
|
||||
public static List<Value> unpackArgs(final List<LazyValue> lazyParams, final Context c)
|
||||
public static List<Value> unpackArgs(List<LazyValue> lazyParams, Context c)
|
||||
{
|
||||
// TODO we shoudn't need that if all fuctions are not lazy really
|
||||
final List<Value> params = new ArrayList<>();
|
||||
for (final LazyValue lv : lazyParams)
|
||||
List<Value> params = new ArrayList<>();
|
||||
for (LazyValue lv : lazyParams)
|
||||
{
|
||||
final Value param = lv.evalValue(c, Context.NONE);
|
||||
Value param = lv.evalValue(c, Context.NONE);
|
||||
if (param instanceof FunctionUnpackedArgumentsValue)
|
||||
{
|
||||
CarpetScriptServer.LOG.error("How did we get here?");
|
||||
@@ -211,13 +211,13 @@ public class FunctionValue extends Value implements Fluff.ILazyFunction
|
||||
}
|
||||
|
||||
@Override
|
||||
public LazyValue lazyEval(final Context c, final Context.Type type, final Expression e, final Tokenizer.Token t, final List<LazyValue> lazyParams)
|
||||
public LazyValue lazyEval(Context c, Context.Type type, Expression e, Tokenizer.Token t, List<LazyValue> lazyParams)
|
||||
{
|
||||
final List<Value> resolvedParams = unpackArgs(lazyParams, c);
|
||||
List<Value> resolvedParams = unpackArgs(lazyParams, c);
|
||||
return execute(c, type, e, t, resolvedParams);
|
||||
}
|
||||
|
||||
public LazyValue execute(final Context c, final Context.Type type, final Expression e, final Tokenizer.Token t, final List<Value> params)
|
||||
public LazyValue execute(Context c, Context.Type type, Expression e, Tokenizer.Token t, List<Value> params)
|
||||
{
|
||||
assertArgsOk(params, fixedArgs -> {
|
||||
if (fixedArgs) // wrong number of args for fixed args
|
||||
@@ -229,14 +229,14 @@ public class FunctionValue extends Value implements Fluff.ILazyFunction
|
||||
}
|
||||
// too few args for varargs
|
||||
|
||||
final List<String> argList = new ArrayList<>(args);
|
||||
List<String> argList = new ArrayList<>(args);
|
||||
argList.add("... " + varArgs);
|
||||
throw new ExpressionException(c, e, t,
|
||||
"Incorrect number of arguments for function " + name +
|
||||
". Should be at least " + args.size() + ", not " + params.size() + " like " + argList
|
||||
);
|
||||
});
|
||||
final Context newFrame = c.recreate();
|
||||
Context newFrame = c.recreate();
|
||||
|
||||
if (outerState != null)
|
||||
{
|
||||
@@ -244,18 +244,18 @@ public class FunctionValue extends Value implements Fluff.ILazyFunction
|
||||
}
|
||||
for (int i = 0; i < args.size(); i++)
|
||||
{
|
||||
final String arg = args.get(i);
|
||||
final Value val = params.get(i).reboundedTo(arg); // todo check if we need to copy that
|
||||
String arg = args.get(i);
|
||||
Value val = params.get(i).reboundedTo(arg); // todo check if we need to copy that
|
||||
newFrame.setVariable(arg, (cc, tt) -> val);
|
||||
}
|
||||
if (varArgs != null)
|
||||
{
|
||||
final List<Value> extraParams = new ArrayList<>();
|
||||
List<Value> extraParams = new ArrayList<>();
|
||||
for (int i = args.size(), mx = params.size(); i < mx; i++)
|
||||
{
|
||||
extraParams.add(params.get(i).reboundedTo(null)); // copy by value I guess
|
||||
}
|
||||
final Value rest = ListValue.wrap(extraParams).bindTo(varArgs); // didn't we just copied that?
|
||||
Value rest = ListValue.wrap(extraParams).bindTo(varArgs); // didn't we just copied that?
|
||||
newFrame.setVariable(varArgs, (cc, tt) -> rest);
|
||||
|
||||
}
|
||||
@@ -264,15 +264,15 @@ public class FunctionValue extends Value implements Fluff.ILazyFunction
|
||||
{
|
||||
retVal = body.evalValue(newFrame, type); // todo not sure if we need to propagete type / consider boolean context in defined functions - answer seems ye
|
||||
}
|
||||
catch (final BreakStatement | ContinueStatement exc)
|
||||
catch (BreakStatement | ContinueStatement exc)
|
||||
{
|
||||
throw new ExpressionException(c, e, t, "'continue' and 'break' can only be called inside loop function bodies");
|
||||
}
|
||||
catch (final ReturnStatement returnStatement)
|
||||
catch (ReturnStatement returnStatement)
|
||||
{
|
||||
retVal = returnStatement.retval;
|
||||
}
|
||||
final Value otherRetVal = retVal;
|
||||
Value otherRetVal = retVal;
|
||||
return (cc, tt) -> otherRetVal;
|
||||
}
|
||||
|
||||
@@ -297,7 +297,7 @@ public class FunctionValue extends Value implements Fluff.ILazyFunction
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tag toTag(final boolean force)
|
||||
public Tag toTag(boolean force)
|
||||
{
|
||||
if (!force)
|
||||
{
|
||||
@@ -306,9 +306,9 @@ public class FunctionValue extends Value implements Fluff.ILazyFunction
|
||||
return StringTag.valueOf(getString());
|
||||
}
|
||||
|
||||
public void assertArgsOk(final List<?> list, final Consumer<Boolean> feedback)
|
||||
public void assertArgsOk(List<?> list, Consumer<Boolean> feedback)
|
||||
{
|
||||
final int size = list.size();
|
||||
int size = list.size();
|
||||
if (varArgs == null && args.size() != size) // wrong number of args for fixed args
|
||||
{
|
||||
feedback.accept(true);
|
||||
|
||||
@@ -6,7 +6,7 @@ public class LContainerValue extends FrameworkValue
|
||||
private final Value address;
|
||||
public static final LContainerValue NULL_CONTAINER = new LContainerValue(null, null);
|
||||
|
||||
public LContainerValue(final ContainerValueInterface c, final Value v)
|
||||
public LContainerValue(ContainerValueInterface c, Value v)
|
||||
{
|
||||
container = c;
|
||||
address = v;
|
||||
|
||||
@@ -12,7 +12,7 @@ import net.minecraft.nbt.Tag;
|
||||
|
||||
public abstract class LazyListValue extends AbstractListValue implements Iterator<Value>
|
||||
{
|
||||
public static LazyListValue rangeDouble(final double from, final double to, final double step)
|
||||
public static LazyListValue rangeDouble(double from, double to, double step)
|
||||
{
|
||||
return new LazyListValue()
|
||||
{
|
||||
@@ -35,7 +35,7 @@ public abstract class LazyListValue extends AbstractListValue implements Iterato
|
||||
@Override
|
||||
public Value next()
|
||||
{
|
||||
final Value val = new NumericValue(current);
|
||||
Value val = new NumericValue(current);
|
||||
current += stepp;
|
||||
return val;
|
||||
}
|
||||
@@ -60,7 +60,7 @@ public abstract class LazyListValue extends AbstractListValue implements Iterato
|
||||
};
|
||||
}
|
||||
|
||||
public static LazyListValue rangeLong(final long from, final long to, final long step)
|
||||
public static LazyListValue rangeLong(long from, long to, long step)
|
||||
{
|
||||
return new LazyListValue()
|
||||
{
|
||||
@@ -83,7 +83,7 @@ public abstract class LazyListValue extends AbstractListValue implements Iterato
|
||||
@Override
|
||||
public Value next()
|
||||
{
|
||||
final Value val = new NumericValue(current);
|
||||
Value val = new NumericValue(current);
|
||||
current += stepp;
|
||||
return val;
|
||||
}
|
||||
@@ -136,7 +136,7 @@ public abstract class LazyListValue extends AbstractListValue implements Iterato
|
||||
|
||||
public List<Value> unroll()
|
||||
{
|
||||
final List<Value> result = new ArrayList<>();
|
||||
List<Value> result = new ArrayList<>();
|
||||
this.forEachRemaining(result::add);
|
||||
fatality();
|
||||
return result;
|
||||
@@ -157,7 +157,7 @@ public abstract class LazyListValue extends AbstractListValue implements Iterato
|
||||
{
|
||||
return ListValue.of();
|
||||
}
|
||||
final List<Value> result = new ArrayList<>();
|
||||
List<Value> result = new ArrayList<>();
|
||||
int i;
|
||||
for (i = 0; i < from; i++)
|
||||
{
|
||||
@@ -187,13 +187,13 @@ public abstract class LazyListValue extends AbstractListValue implements Iterato
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value add(final Value other)
|
||||
public Value add(Value other)
|
||||
{
|
||||
throw new InternalExpressionException("Cannot add to iterators");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object o)
|
||||
public boolean equals(Object o)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -207,12 +207,12 @@ public abstract class LazyListValue extends AbstractListValue implements Iterato
|
||||
@Override
|
||||
public Object clone()
|
||||
{
|
||||
final Object copy;
|
||||
Object copy;
|
||||
try
|
||||
{
|
||||
copy = super.clone();
|
||||
}
|
||||
catch (final CloneNotSupportedException e)
|
||||
catch (CloneNotSupportedException e)
|
||||
{
|
||||
throw new InternalExpressionException("Cannot copy iterators");
|
||||
}
|
||||
@@ -233,7 +233,7 @@ public abstract class LazyListValue extends AbstractListValue implements Iterato
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tag toTag(final boolean force)
|
||||
public Tag toTag(boolean force)
|
||||
{
|
||||
if (!force)
|
||||
{
|
||||
|
||||
@@ -60,54 +60,54 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
|
||||
@Override
|
||||
public Value deepcopy()
|
||||
{
|
||||
final List<Value> copyItems = new ArrayList<>(items.size());
|
||||
for (final Value entry : items)
|
||||
List<Value> copyItems = new ArrayList<>(items.size());
|
||||
for (Value entry : items)
|
||||
{
|
||||
copyItems.add(entry.deepcopy());
|
||||
}
|
||||
return new ListValue(copyItems);
|
||||
}
|
||||
|
||||
public ListValue(final Collection<? extends Value> list)
|
||||
public ListValue(Collection<? extends Value> list)
|
||||
{
|
||||
items = new ArrayList<>(list);
|
||||
}
|
||||
|
||||
protected ListValue(final List<Value> list)
|
||||
protected ListValue(List<Value> list)
|
||||
{
|
||||
items = list;
|
||||
}
|
||||
|
||||
public static Value fromTriple(final double a, final double b, final double c)
|
||||
public static Value fromTriple(double a, double b, double c)
|
||||
{
|
||||
return ListValue.of(new NumericValue(a), new NumericValue(b), new NumericValue(c));
|
||||
}
|
||||
|
||||
public static Value fromTriple(final int a, final int b, final int c)
|
||||
public static Value fromTriple(int a, int b, int c)
|
||||
{
|
||||
return fromTriple((double) a, b, c);
|
||||
}
|
||||
|
||||
|
||||
public static ListValue wrap(final Stream<Value> stream)
|
||||
public static ListValue wrap(Stream<Value> stream)
|
||||
{
|
||||
return wrap(stream.collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
public static ListValue wrap(final List<Value> list)
|
||||
public static ListValue wrap(List<Value> list)
|
||||
{
|
||||
return new ListValue(list);
|
||||
}
|
||||
|
||||
public static ListValue of(final Value... list)
|
||||
public static ListValue of(Value... list)
|
||||
{
|
||||
return new ListValue(new ArrayList<>(Arrays.asList(list)));
|
||||
}
|
||||
|
||||
public static ListValue ofNums(final Number... list)
|
||||
public static ListValue ofNums(Number... list)
|
||||
{
|
||||
final List<Value> valList = new ArrayList<>();
|
||||
for (final Number i : list)
|
||||
List<Value> valList = new ArrayList<>();
|
||||
for (Number i : list)
|
||||
{
|
||||
valList.add(new NumericValue(i.doubleValue()));
|
||||
}
|
||||
@@ -116,7 +116,7 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
|
||||
|
||||
public static LazyValue lazyEmpty()
|
||||
{
|
||||
final Value ret = new ListValue();
|
||||
Value ret = new ListValue();
|
||||
return (c, t) -> ret;
|
||||
}
|
||||
|
||||
@@ -126,12 +126,12 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value add(final Value other)
|
||||
public Value add(Value other)
|
||||
{
|
||||
final ListValue output = new ListValue();
|
||||
ListValue output = new ListValue();
|
||||
if (other instanceof final ListValue list)
|
||||
{
|
||||
final List<Value> otherItems = list.items;
|
||||
List<Value> otherItems = list.items;
|
||||
if (otherItems.size() == items.size())
|
||||
{
|
||||
for (int i = 0, size = items.size(); i < size; i++)
|
||||
@@ -146,7 +146,7 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
|
||||
}
|
||||
else
|
||||
{
|
||||
for (final Value v : items)
|
||||
for (Value v : items)
|
||||
{
|
||||
output.items.add(v.add(other));
|
||||
}
|
||||
@@ -155,18 +155,18 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
|
||||
}
|
||||
|
||||
@Override
|
||||
public void append(final Value v)
|
||||
public void append(Value v)
|
||||
{
|
||||
items.add(v);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value subtract(final Value other)
|
||||
public Value subtract(Value other)
|
||||
{
|
||||
final ListValue output = new ListValue();
|
||||
ListValue output = new ListValue();
|
||||
if (other instanceof final ListValue list)
|
||||
{
|
||||
final List<Value> otherItems = list.items;
|
||||
List<Value> otherItems = list.items;
|
||||
if (otherItems.size() == items.size())
|
||||
{
|
||||
for (int i = 0, size = items.size(); i < size; i++)
|
||||
@@ -181,7 +181,7 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
|
||||
}
|
||||
else
|
||||
{
|
||||
for (final Value v : items)
|
||||
for (Value v : items)
|
||||
{
|
||||
output.items.add(v.subtract(other));
|
||||
}
|
||||
@@ -189,19 +189,19 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
|
||||
return output;
|
||||
}
|
||||
|
||||
public void subtractFrom(final Value v) // if I ever do -= then it wouod remove items
|
||||
public void subtractFrom(Value v) // if I ever do -= then it wouod remove items
|
||||
{
|
||||
throw new UnsupportedOperationException(); // TODO
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Value multiply(final Value other)
|
||||
public Value multiply(Value other)
|
||||
{
|
||||
final ListValue output = new ListValue();
|
||||
ListValue output = new ListValue();
|
||||
if (other instanceof final ListValue list)
|
||||
{
|
||||
final List<Value> otherItems = list.items;
|
||||
List<Value> otherItems = list.items;
|
||||
if (otherItems.size() == items.size())
|
||||
{
|
||||
for (int i = 0, size = items.size(); i < size; i++)
|
||||
@@ -216,7 +216,7 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
|
||||
}
|
||||
else
|
||||
{
|
||||
for (final Value v : items)
|
||||
for (Value v : items)
|
||||
{
|
||||
output.items.add(v.multiply(other));
|
||||
}
|
||||
@@ -225,12 +225,12 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value divide(final Value other)
|
||||
public Value divide(Value other)
|
||||
{
|
||||
final ListValue output = new ListValue();
|
||||
ListValue output = new ListValue();
|
||||
if (other instanceof final ListValue list)
|
||||
{
|
||||
final List<Value> otherItems = list.items;
|
||||
List<Value> otherItems = list.items;
|
||||
if (otherItems.size() == items.size())
|
||||
{
|
||||
for (int i = 0, size = items.size(); i < size; i++)
|
||||
@@ -245,7 +245,7 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
|
||||
}
|
||||
else
|
||||
{
|
||||
for (final Value v : items)
|
||||
for (Value v : items)
|
||||
{
|
||||
output.items.add(v.divide(other));
|
||||
}
|
||||
@@ -254,12 +254,12 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(final Value o)
|
||||
public int compareTo(Value o)
|
||||
{
|
||||
if (o instanceof final ListValue ol)
|
||||
{
|
||||
final int size = this.getItems().size();
|
||||
final int otherSize = ol.getItems().size();
|
||||
int size = this.getItems().size();
|
||||
int otherSize = ol.getItems().size();
|
||||
if (size != otherSize)
|
||||
{
|
||||
return size - otherSize;
|
||||
@@ -270,7 +270,7 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
|
||||
}
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
final int res = this.items.get(i).compareTo(ol.items.get(i));
|
||||
int res = this.items.get(i).compareTo(ol.items.get(i));
|
||||
if (res != 0)
|
||||
{
|
||||
return res;
|
||||
@@ -282,7 +282,7 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object o)
|
||||
public boolean equals(Object o)
|
||||
{
|
||||
return o instanceof final ListValue list && getItems().equals(list.getItems());
|
||||
}
|
||||
@@ -304,7 +304,7 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
|
||||
return new ArrayList<>(items);
|
||||
}
|
||||
|
||||
public void extend(final List<Value> subList)
|
||||
public void extend(List<Value> subList)
|
||||
{
|
||||
items.addAll(subList);
|
||||
}
|
||||
@@ -316,13 +316,13 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
|
||||
* @param len
|
||||
* @return
|
||||
*/
|
||||
public static int normalizeIndex(long idx, final int len)
|
||||
public static int normalizeIndex(long idx, int len)
|
||||
{
|
||||
if (idx >= 0 && idx < len)
|
||||
{
|
||||
return (int) idx;
|
||||
}
|
||||
final long range = abs(idx) / len;
|
||||
long range = abs(idx) / len;
|
||||
idx += (range + 2) * len;
|
||||
idx = idx % len;
|
||||
return (int) idx;
|
||||
@@ -330,7 +330,7 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
|
||||
|
||||
public static class ListConstructorValue extends ListValue
|
||||
{
|
||||
public ListConstructorValue(final Collection<? extends Value> list)
|
||||
public ListConstructorValue(Collection<? extends Value> list)
|
||||
{
|
||||
super(list);
|
||||
}
|
||||
@@ -343,11 +343,11 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value in(final Value value1)
|
||||
public Value in(Value value1)
|
||||
{
|
||||
for (int i = 0; i < items.size(); i++)
|
||||
{
|
||||
final Value v = items.get(i);
|
||||
Value v = items.get(i);
|
||||
if (v.equals(value1))
|
||||
{
|
||||
return new NumericValue(i);
|
||||
@@ -357,16 +357,16 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value slice(final long fromDesc, final Long toDesc)
|
||||
public Value slice(long fromDesc, Long toDesc)
|
||||
{
|
||||
final List<Value> items = getItems();
|
||||
final int size = items.size();
|
||||
final int from = normalizeIndex(fromDesc, size);
|
||||
List<Value> items = getItems();
|
||||
int size = items.size();
|
||||
int from = normalizeIndex(fromDesc, size);
|
||||
if (toDesc == null)
|
||||
{
|
||||
return new ListValue(new ArrayList<>(getItems().subList(from, size)));
|
||||
}
|
||||
final int to = normalizeIndex(toDesc, size + 1);
|
||||
int to = normalizeIndex(toDesc, size + 1);
|
||||
if (from > to)
|
||||
{
|
||||
return ListValue.of();
|
||||
@@ -375,9 +375,9 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value split(final Value delimiter)
|
||||
public Value split(Value delimiter)
|
||||
{
|
||||
final ListValue result = new ListValue();
|
||||
ListValue result = new ListValue();
|
||||
if (delimiter == null)
|
||||
{
|
||||
this.forEach(item -> result.items.add(of(item)));
|
||||
@@ -385,7 +385,7 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
|
||||
}
|
||||
int startIndex = 0;
|
||||
int index = 0;
|
||||
for (final Value val : this.items)
|
||||
for (Value val : this.items)
|
||||
{
|
||||
index++;
|
||||
if (val.equals(delimiter))
|
||||
@@ -405,9 +405,9 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean put(final Value where, final Value value, final Value conditionValue)
|
||||
public boolean put(Value where, Value value, Value conditionValue)
|
||||
{
|
||||
final String condition = conditionValue.getString();
|
||||
String condition = conditionValue.getString();
|
||||
if (condition.equalsIgnoreCase("insert"))
|
||||
{
|
||||
return put(where, value, false, false);
|
||||
@@ -424,12 +424,12 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean put(final Value ind, final Value value)
|
||||
public boolean put(Value ind, Value value)
|
||||
{
|
||||
return put(ind, value, true, false);
|
||||
}
|
||||
|
||||
private boolean put(final Value ind, final Value value, final boolean replace, final boolean extend)
|
||||
private boolean put(Value ind, Value value, boolean replace, boolean extend)
|
||||
{
|
||||
if (ind.isNull())
|
||||
{
|
||||
@@ -444,7 +444,7 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
|
||||
}
|
||||
else
|
||||
{
|
||||
final int numitems = items.size();
|
||||
int numitems = items.size();
|
||||
if (!(ind instanceof NumericValue))
|
||||
{
|
||||
return false;
|
||||
@@ -470,8 +470,8 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
|
||||
|
||||
if (extend && value instanceof AbstractListValue)
|
||||
{
|
||||
final Iterable<Value> iterable = ((AbstractListValue) value)::iterator;
|
||||
final List<Value> appendix = StreamSupport.stream(iterable.spliterator(), false).collect(Collectors.toList());
|
||||
Iterable<Value> iterable = ((AbstractListValue) value)::iterator;
|
||||
List<Value> appendix = StreamSupport.stream(iterable.spliterator(), false).collect(Collectors.toList());
|
||||
items.addAll(index, appendix);
|
||||
return true;
|
||||
}
|
||||
@@ -481,27 +481,27 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value get(final Value value)
|
||||
public Value get(Value value)
|
||||
{
|
||||
final int size = items.size();
|
||||
int size = items.size();
|
||||
return size == 0 ? Value.NULL : items.get(normalizeIndex(NumericValue.asNumber(value, "'address' to a list index").getLong(), size));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean has(final Value where)
|
||||
public boolean has(Value where)
|
||||
{
|
||||
final long index = NumericValue.asNumber(where, "'address' to a list index").getLong();
|
||||
long index = NumericValue.asNumber(where, "'address' to a list index").getLong();
|
||||
return index >= 0 && index < items.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean delete(final Value where)
|
||||
public boolean delete(Value where)
|
||||
{
|
||||
if (!(where instanceof NumericValue) || items.isEmpty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
final long index = ((NumericValue) where).getLong();
|
||||
long index = ((NumericValue) where).getLong();
|
||||
items.remove(normalizeIndex(index, items.size()));
|
||||
return true;
|
||||
}
|
||||
@@ -527,7 +527,7 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
|
||||
MAP,
|
||||
STRING;
|
||||
|
||||
private static TagTypeCompat getType(final Tag tag)
|
||||
private static TagTypeCompat getType(Tag tag)
|
||||
{
|
||||
if (tag instanceof IntTag)
|
||||
{
|
||||
@@ -555,23 +555,23 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
|
||||
|
||||
|
||||
@Override
|
||||
public Tag toTag(final boolean force)
|
||||
public Tag toTag(boolean force)
|
||||
{
|
||||
final int argSize = items.size();
|
||||
int argSize = items.size();
|
||||
if (argSize == 0)
|
||||
{
|
||||
return new ListTag();
|
||||
}
|
||||
final ListTag tag = new ListTag();
|
||||
ListTag tag = new ListTag();
|
||||
if (argSize == 1)
|
||||
{
|
||||
tag.add(items.get(0).toTag(force));
|
||||
return tag;
|
||||
}
|
||||
// figuring out the types
|
||||
final List<Tag> tags = new ArrayList<>();
|
||||
List<Tag> tags = new ArrayList<>();
|
||||
items.forEach(v -> tags.add(v.toTag(force)));
|
||||
final Set<TagTypeCompat> cases = EnumSet.noneOf(TagTypeCompat.class);
|
||||
Set<TagTypeCompat> cases = EnumSet.noneOf(TagTypeCompat.class);
|
||||
tags.forEach(t -> cases.add(TagTypeCompat.getType(t)));
|
||||
if (cases.size() == 1) // well, one type of items
|
||||
{
|
||||
@@ -599,8 +599,8 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
|
||||
@Override
|
||||
public JsonElement toJson()
|
||||
{
|
||||
final JsonArray array = new JsonArray();
|
||||
for (final Value el : items)
|
||||
JsonArray array = new JsonArray();
|
||||
for (Value el : items)
|
||||
{
|
||||
array.add(el.toJson());
|
||||
}
|
||||
|
||||
@@ -25,13 +25,13 @@ public class MapValue extends AbstractListValue implements ContainerValueInterfa
|
||||
map = new HashMap<>();
|
||||
}
|
||||
|
||||
public MapValue(final List<Value> kvPairs)
|
||||
public MapValue(List<Value> kvPairs)
|
||||
{
|
||||
this();
|
||||
kvPairs.forEach(this::put);
|
||||
}
|
||||
|
||||
public MapValue(final Set<Value> keySet)
|
||||
public MapValue(Set<Value> keySet)
|
||||
{
|
||||
this();
|
||||
keySet.forEach(v -> map.put(v, Value.NULL));
|
||||
@@ -62,8 +62,8 @@ public class MapValue extends AbstractListValue implements ContainerValueInterfa
|
||||
{
|
||||
return "{" + map.entrySet().stream().map(p -> p.getKey().getPrettyString() + ": " + p.getValue().getPrettyString()).collect(Collectors.joining(", ")) + "}";
|
||||
}
|
||||
final List<Value> keys = new ArrayList<>(map.keySet());
|
||||
final int max = keys.size();
|
||||
List<Value> keys = new ArrayList<>(map.keySet());
|
||||
int max = keys.size();
|
||||
return "{" + keys.get(0).getPrettyString() + ": " + map.get(keys.get(0)).getPrettyString() + ", " +
|
||||
keys.get(1).getPrettyString() + ": " + map.get(keys.get(1)).getPrettyString() + ", ..., " +
|
||||
keys.get(max - 2).getPrettyString() + ": " + map.get(keys.get(max - 2)).getPrettyString() + ", " +
|
||||
@@ -85,32 +85,32 @@ public class MapValue extends AbstractListValue implements ContainerValueInterfa
|
||||
@Override
|
||||
public Value deepcopy()
|
||||
{
|
||||
final Map<Value, Value> copyMap = new HashMap<>();
|
||||
Map<Value, Value> copyMap = new HashMap<>();
|
||||
map.forEach((key, value) -> copyMap.put(key.deepcopy(), value.deepcopy()));
|
||||
return new MapValue(copyMap);
|
||||
}
|
||||
|
||||
private MapValue(final Map<Value, Value> other)
|
||||
private MapValue(Map<Value, Value> other)
|
||||
{
|
||||
map = other;
|
||||
}
|
||||
|
||||
public static MapValue wrap(final Map<Value, Value> other)
|
||||
public static MapValue wrap(Map<Value, Value> other)
|
||||
{
|
||||
return new MapValue(other);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value add(final Value o)
|
||||
public Value add(Value o)
|
||||
{
|
||||
final Map<Value, Value> newItems = new HashMap<>(map);
|
||||
Map<Value, Value> newItems = new HashMap<>(map);
|
||||
if (o instanceof final MapValue mapValue)
|
||||
{
|
||||
newItems.putAll(mapValue.map);
|
||||
}
|
||||
else if (o instanceof final AbstractListValue alv)
|
||||
{
|
||||
for (final Value value : alv)
|
||||
for (Value value : alv)
|
||||
{
|
||||
newItems.put(value, Value.NULL);
|
||||
}
|
||||
@@ -123,24 +123,24 @@ public class MapValue extends AbstractListValue implements ContainerValueInterfa
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value subtract(final Value v)
|
||||
public Value subtract(Value v)
|
||||
{
|
||||
throw new InternalExpressionException("Cannot subtract from a map value");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value multiply(final Value v)
|
||||
public Value multiply(Value v)
|
||||
{
|
||||
throw new InternalExpressionException("Cannot multiply with a map value");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value divide(final Value v)
|
||||
public Value divide(Value v)
|
||||
{
|
||||
throw new InternalExpressionException("Cannot divide a map value");
|
||||
}
|
||||
|
||||
public void put(final Value v)
|
||||
public void put(Value v)
|
||||
{
|
||||
if (!(v instanceof final ListValue pair))
|
||||
{
|
||||
@@ -155,19 +155,19 @@ public class MapValue extends AbstractListValue implements ContainerValueInterfa
|
||||
}
|
||||
|
||||
@Override
|
||||
public void append(final Value v)
|
||||
public void append(Value v)
|
||||
{
|
||||
map.put(v, Value.NULL);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(final Value o)
|
||||
public int compareTo(Value o)
|
||||
{
|
||||
throw new InternalExpressionException("Cannot compare with a map value");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object o)
|
||||
public boolean equals(Object o)
|
||||
{
|
||||
return o instanceof final MapValue mapValue && map.equals(mapValue.map);
|
||||
}
|
||||
@@ -177,7 +177,7 @@ public class MapValue extends AbstractListValue implements ContainerValueInterfa
|
||||
return map;
|
||||
}
|
||||
|
||||
public void extend(final List<Value> subList)
|
||||
public void extend(List<Value> subList)
|
||||
{
|
||||
subList.forEach(this::put);
|
||||
}
|
||||
@@ -189,19 +189,19 @@ public class MapValue extends AbstractListValue implements ContainerValueInterfa
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value in(final Value value)
|
||||
public Value in(Value value)
|
||||
{
|
||||
return map.containsKey(value) ? value : Value.NULL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value slice(final long from, final Long to)
|
||||
public Value slice(long from, Long to)
|
||||
{
|
||||
throw new InternalExpressionException("Cannot slice a map value");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value split(final Value delimiter)
|
||||
public Value split(Value delimiter)
|
||||
{
|
||||
throw new InternalExpressionException("Cannot split a map value");
|
||||
}
|
||||
@@ -213,25 +213,25 @@ public class MapValue extends AbstractListValue implements ContainerValueInterfa
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value get(final Value v2)
|
||||
public Value get(Value v2)
|
||||
{
|
||||
return map.getOrDefault(v2, Value.NULL);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean has(final Value where)
|
||||
public boolean has(Value where)
|
||||
{
|
||||
return map.containsKey(where);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean delete(final Value where)
|
||||
public boolean delete(Value where)
|
||||
{
|
||||
return map.remove(where) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean put(final Value key, final Value value)
|
||||
public boolean put(Value key, Value value)
|
||||
{
|
||||
return map.put(key, value) != null;
|
||||
}
|
||||
@@ -249,9 +249,9 @@ public class MapValue extends AbstractListValue implements ContainerValueInterfa
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tag toTag(final boolean force)
|
||||
public Tag toTag(boolean force)
|
||||
{
|
||||
final CompoundTag tag = new CompoundTag();
|
||||
CompoundTag tag = new CompoundTag();
|
||||
map.forEach((k, v) ->
|
||||
{
|
||||
if (!force && !(k instanceof StringValue))
|
||||
@@ -266,8 +266,8 @@ public class MapValue extends AbstractListValue implements ContainerValueInterfa
|
||||
@Override
|
||||
public JsonElement toJson()
|
||||
{
|
||||
final JsonObject jsonMap = new JsonObject();
|
||||
final List<Value> keys = new ArrayList<>(map.keySet());
|
||||
JsonObject jsonMap = new JsonObject();
|
||||
List<Value> keys = new ArrayList<>(map.keySet());
|
||||
Collections.sort(keys);
|
||||
keys.forEach(k -> jsonMap.add(k.getString(), map.get(k).toJson()));
|
||||
return jsonMap;
|
||||
|
||||
@@ -55,6 +55,8 @@ import net.minecraft.world.level.block.entity.ChestBlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.phys.AABB;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class NBTSerializableValue extends Value implements ContainerValueInterface
|
||||
{
|
||||
private String nbtString = null;
|
||||
@@ -66,7 +68,7 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa
|
||||
{
|
||||
}
|
||||
|
||||
public NBTSerializableValue(final String nbtString)
|
||||
public NBTSerializableValue(String nbtString)
|
||||
{
|
||||
nbtSupplier = () ->
|
||||
{
|
||||
@@ -74,7 +76,7 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa
|
||||
{
|
||||
return (new TagParser(new StringReader(nbtString))).readValue();
|
||||
}
|
||||
catch (final CommandSyntaxException e)
|
||||
catch (CommandSyntaxException e)
|
||||
{
|
||||
throw new InternalExpressionException("Incorrect NBT data: " + nbtString);
|
||||
}
|
||||
@@ -82,13 +84,13 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa
|
||||
owned = true;
|
||||
}
|
||||
|
||||
public NBTSerializableValue(final Tag tag)
|
||||
public NBTSerializableValue(Tag tag)
|
||||
{
|
||||
nbtTag = tag;
|
||||
owned = true;
|
||||
}
|
||||
|
||||
public static Value of(final Tag tag)
|
||||
public static Value of(Tag tag)
|
||||
{
|
||||
if (tag == null)
|
||||
{
|
||||
@@ -97,49 +99,57 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa
|
||||
return new NBTSerializableValue(tag);
|
||||
}
|
||||
|
||||
public NBTSerializableValue(final Supplier<Tag> tagSupplier)
|
||||
public NBTSerializableValue(Supplier<Tag> tagSupplier)
|
||||
{
|
||||
nbtSupplier = tagSupplier;
|
||||
}
|
||||
|
||||
public static Value fromStack(final ItemStack stack)
|
||||
public static Value fromStack(ItemStack stack)
|
||||
{
|
||||
if (stack.hasTag())
|
||||
{
|
||||
final NBTSerializableValue value = new NBTSerializableValue();
|
||||
NBTSerializableValue value = new NBTSerializableValue();
|
||||
value.nbtSupplier = stack::getTag;
|
||||
return value;
|
||||
}
|
||||
return Value.NULL;
|
||||
}
|
||||
|
||||
public static String nameFromRegistryId(final ResourceLocation id)
|
||||
public static Value nameFromRegistryId(@Nullable ResourceLocation id)
|
||||
{
|
||||
if (id == null) // should be Value.NULL
|
||||
{
|
||||
return "";
|
||||
}
|
||||
return id.getNamespace().equals("minecraft") ? id.getPath() : id.toString();
|
||||
return StringValue.of(nameFromResource(id));
|
||||
}
|
||||
|
||||
public static NBTSerializableValue parseString(final String nbtString, final boolean fail)
|
||||
@Nullable
|
||||
public static String nameFromResource(@Nullable ResourceLocation id)
|
||||
{
|
||||
return id == null ? null : id.getNamespace().equals("minecraft") ? id.getPath() : id.toString();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static NBTSerializableValue parseString(String nbtString)
|
||||
{
|
||||
final Tag tag;
|
||||
try
|
||||
{
|
||||
tag = (new TagParser(new StringReader(nbtString))).readValue();
|
||||
Tag tag = (new TagParser(new StringReader(nbtString))).readValue();
|
||||
NBTSerializableValue value = new NBTSerializableValue(tag);
|
||||
value.nbtString = null;
|
||||
return value;
|
||||
}
|
||||
catch (final CommandSyntaxException e)
|
||||
catch (CommandSyntaxException e)
|
||||
{
|
||||
if (fail)
|
||||
{
|
||||
throw new InternalExpressionException("Incorrect NBT tag: " + nbtString);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
final NBTSerializableValue value = new NBTSerializableValue(tag);
|
||||
value.nbtString = null;
|
||||
return value;
|
||||
}
|
||||
|
||||
public static NBTSerializableValue parseStringOrFail(String nbtString)
|
||||
{
|
||||
NBTSerializableValue result = parseString(nbtString);
|
||||
if (result == null)
|
||||
{
|
||||
throw new InternalExpressionException("Incorrect NBT tag: " + nbtString);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -147,7 +157,7 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa
|
||||
public Value clone()
|
||||
{
|
||||
// sets only nbttag, even if emtpy;
|
||||
final NBTSerializableValue copy = new NBTSerializableValue(nbtTag);
|
||||
NBTSerializableValue copy = new NBTSerializableValue(nbtTag);
|
||||
copy.nbtSupplier = this.nbtSupplier;
|
||||
copy.nbtString = this.nbtString;
|
||||
copy.owned = this.owned;
|
||||
@@ -157,7 +167,7 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa
|
||||
@Override
|
||||
public Value deepcopy()
|
||||
{
|
||||
final NBTSerializableValue copy = (NBTSerializableValue) clone();
|
||||
NBTSerializableValue copy = (NBTSerializableValue) clone();
|
||||
copy.owned = false;
|
||||
ensureOwnership();
|
||||
return copy;
|
||||
@@ -170,18 +180,18 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa
|
||||
}
|
||||
|
||||
// stolen from HopperBlockEntity, adjusted for threaded operation
|
||||
public static Container getInventoryAt(final ServerLevel world, final BlockPos blockPos)
|
||||
public static Container getInventoryAt(ServerLevel world, BlockPos blockPos)
|
||||
{
|
||||
Container inventory = null;
|
||||
final BlockState blockState = world.getBlockState(blockPos);
|
||||
final Block block = blockState.getBlock();
|
||||
BlockState blockState = world.getBlockState(blockPos);
|
||||
Block block = blockState.getBlock();
|
||||
if (block instanceof final WorldlyContainerHolder containerHolder)
|
||||
{
|
||||
inventory = containerHolder.getContainer(blockState, world, blockPos);
|
||||
}
|
||||
else if (blockState.hasBlockEntity())
|
||||
{
|
||||
final BlockEntity blockEntity = BlockValue.getBlockEntity(world, blockPos);
|
||||
BlockEntity blockEntity = BlockValue.getBlockEntity(world, blockPos);
|
||||
if (blockEntity instanceof final Container inventoryHolder)
|
||||
{
|
||||
inventory = inventoryHolder;
|
||||
@@ -194,7 +204,7 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa
|
||||
|
||||
if (inventory == null)
|
||||
{
|
||||
final List<Entity> list = world.getEntities(
|
||||
List<Entity> list = world.getEntities(
|
||||
(Entity) null, //TODO check this matches the correct method
|
||||
new AABB(
|
||||
blockPos.getX() - 0.5D, blockPos.getY() - 0.5D, blockPos.getZ() - 0.5D,
|
||||
@@ -210,7 +220,7 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa
|
||||
return inventory;
|
||||
}
|
||||
|
||||
public static InventoryLocator locateInventory(final CarpetContext c, final List<Value> params, int offset)
|
||||
public static InventoryLocator locateInventory(CarpetContext c, List<Value> params, int offset)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -225,8 +235,8 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa
|
||||
String strVal = v1.getString().toLowerCase(Locale.ROOT);
|
||||
if (strVal.equals("enderchest"))
|
||||
{
|
||||
final Value v2 = params.get(1 + offset);
|
||||
final ServerPlayer player = EntityValue.getPlayerByValue(c.server(), v2);
|
||||
Value v2 = params.get(1 + offset);
|
||||
ServerPlayer player = EntityValue.getPlayerByValue(c.server(), v2);
|
||||
if (player == null)
|
||||
{
|
||||
throw new InternalExpressionException("enderchest inventory requires player argument");
|
||||
@@ -235,24 +245,24 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa
|
||||
}
|
||||
if (strVal.equals("equipment"))
|
||||
{
|
||||
final Value v2 = params.get(1 + offset);
|
||||
Value v2 = params.get(1 + offset);
|
||||
if (!(v2 instanceof final EntityValue ev))
|
||||
{
|
||||
throw new InternalExpressionException("Equipment inventory requires a living entity argument");
|
||||
}
|
||||
final Entity e = ev.getEntity();
|
||||
Entity e = ev.getEntity();
|
||||
if (!(e instanceof final LivingEntity le))
|
||||
{
|
||||
throw new InternalExpressionException("Equipment inventory requires a living entity argument");
|
||||
}
|
||||
return new InventoryLocator(e, e.blockPosition(), new EquipmentInventory(le), offset + 2);
|
||||
}
|
||||
final boolean isEnder = strVal.startsWith("enderchest_");
|
||||
boolean isEnder = strVal.startsWith("enderchest_");
|
||||
if (isEnder)
|
||||
{
|
||||
strVal = strVal.substring(11); // len("enderchest_")
|
||||
}
|
||||
final ServerPlayer player = c.server().getPlayerList().getPlayerByName(strVal);
|
||||
ServerPlayer player = c.server().getPlayerList().getPlayerByName(strVal);
|
||||
if (player == null)
|
||||
{
|
||||
throw new InternalExpressionException("String description of an inventory should either denote a player or player's enderchest");
|
||||
@@ -268,7 +278,7 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa
|
||||
if (v1 instanceof final EntityValue ev)
|
||||
{
|
||||
Container inv = null;
|
||||
final Entity e = ev.getEntity();
|
||||
Entity e = ev.getEntity();
|
||||
if (e instanceof final Player pe)
|
||||
{
|
||||
inv = pe.getInventory();
|
||||
@@ -294,36 +304,36 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa
|
||||
}
|
||||
if (v1 instanceof final BlockValue bv)
|
||||
{
|
||||
final BlockPos pos = bv.getPos();
|
||||
BlockPos pos = bv.getPos();
|
||||
if (pos == null)
|
||||
{
|
||||
throw new InternalExpressionException("Block to access inventory needs to be positioned in the world");
|
||||
}
|
||||
final Container inv = getInventoryAt(c.level(), pos);
|
||||
Container inv = getInventoryAt(c.level(), pos);
|
||||
return inv == null ? null : new InventoryLocator(pos, pos, inv, offset + 1);
|
||||
}
|
||||
if (v1 instanceof final ListValue lv)
|
||||
{
|
||||
final List<Value> args = lv.getItems();
|
||||
final BlockPos pos = new BlockPos(
|
||||
List<Value> args = lv.getItems();
|
||||
BlockPos pos = new BlockPos(
|
||||
NumericValue.asNumber(args.get(0)).getDouble(),
|
||||
NumericValue.asNumber(args.get(1)).getDouble(),
|
||||
NumericValue.asNumber(args.get(2)).getDouble());
|
||||
final Container inv = getInventoryAt(c.level(), pos);
|
||||
Container inv = getInventoryAt(c.level(), pos);
|
||||
return inv == null ? null : new InventoryLocator(pos, pos, inv, offset + 1);
|
||||
}
|
||||
if (v1 instanceof final ScreenValue screenValue)
|
||||
{
|
||||
return !screenValue.isOpen() ? null : new InventoryLocator(screenValue.getPlayer(), screenValue.getPlayer().blockPosition(), screenValue.getInventory(), offset + 1);
|
||||
}
|
||||
final BlockPos pos = new BlockPos(
|
||||
BlockPos pos = new BlockPos(
|
||||
NumericValue.asNumber(v1).getDouble(),
|
||||
NumericValue.asNumber(params.get(1 + offset)).getDouble(),
|
||||
NumericValue.asNumber(params.get(2 + offset)).getDouble());
|
||||
final Container inv = getInventoryAt(c.level(), pos);
|
||||
Container inv = getInventoryAt(c.level(), pos);
|
||||
return inv == null ? null : new InventoryLocator(pos, pos, inv, offset + 3);
|
||||
}
|
||||
catch (final IndexOutOfBoundsException e)
|
||||
catch (IndexOutOfBoundsException e)
|
||||
{
|
||||
throw new InternalExpressionException("Inventory should be defined either by three coordinates, a block value, an entity, or a screen");
|
||||
}
|
||||
@@ -331,12 +341,12 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa
|
||||
|
||||
private static final Map<String, ItemInput> itemCache = new HashMap<>();
|
||||
|
||||
public static ItemInput parseItem(final String itemString, final RegistryAccess regs)
|
||||
public static ItemInput parseItem(String itemString, RegistryAccess regs)
|
||||
{
|
||||
return parseItem(itemString, null, regs);
|
||||
}
|
||||
|
||||
public static ItemInput parseItem(final String itemString, final CompoundTag customTag, final RegistryAccess regs)
|
||||
public static ItemInput parseItem(String itemString, @Nullable CompoundTag customTag, RegistryAccess regs)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -345,7 +355,7 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa
|
||||
{
|
||||
return customTag == null ? res : new ItemInput(Holder.direct(res.getItem()), customTag);
|
||||
}
|
||||
final ItemParser.ItemResult parser = ItemParser.parseForItem(regs.lookupOrThrow(Registries.ITEM), new StringReader(itemString));
|
||||
ItemParser.ItemResult parser = ItemParser.parseForItem(regs.lookupOrThrow(Registries.ITEM), new StringReader(itemString));
|
||||
res = new ItemInput(parser.item(), parser.nbt());
|
||||
|
||||
itemCache.put(itemString, res);
|
||||
@@ -355,15 +365,15 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa
|
||||
}
|
||||
return customTag == null ? res : new ItemInput(Holder.direct(res.getItem()), customTag);
|
||||
}
|
||||
catch (final CommandSyntaxException e)
|
||||
catch (CommandSyntaxException e)
|
||||
{
|
||||
throw new ThrowStatement(itemString, Throwables.UNKNOWN_ITEM);
|
||||
}
|
||||
}
|
||||
|
||||
public static int validateSlot(int slot, final Container inv)
|
||||
public static int validateSlot(int slot, Container inv)
|
||||
{
|
||||
final int invSize = inv.getContainerSize();
|
||||
int invSize = inv.getContainerSize();
|
||||
if (slot < 0)
|
||||
{
|
||||
slot = invSize + slot;
|
||||
@@ -371,7 +381,7 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa
|
||||
return slot < 0 || slot >= invSize ? inv.getContainerSize() : slot; // outside of inventory
|
||||
}
|
||||
|
||||
private static Value decodeSimpleTag(final Tag t)
|
||||
private static Value decodeSimpleTag(Tag t)
|
||||
{
|
||||
if (t instanceof final NumericTag number)
|
||||
{
|
||||
@@ -389,17 +399,17 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa
|
||||
throw new InternalExpressionException("How did we get here: Unknown nbt element class: " + t.getType().getName());
|
||||
}
|
||||
|
||||
private static Value decodeTag(final Tag t)
|
||||
private static Value decodeTag(Tag t)
|
||||
{
|
||||
return t instanceof CompoundTag || t instanceof CollectionTag ? new NBTSerializableValue(() -> t) : decodeSimpleTag(t);
|
||||
}
|
||||
|
||||
private static Value decodeTagDeep(final Tag t)
|
||||
private static Value decodeTagDeep(Tag t)
|
||||
{
|
||||
if (t instanceof final CompoundTag ctag)
|
||||
{
|
||||
final Map<Value, Value> pairs = new HashMap<>();
|
||||
for (final String key : ctag.getAllKeys())
|
||||
Map<Value, Value> pairs = new HashMap<>();
|
||||
for (String key : ctag.getAllKeys())
|
||||
{
|
||||
pairs.put(new StringValue(key), decodeTagDeep(ctag.get(key)));
|
||||
}
|
||||
@@ -407,8 +417,8 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa
|
||||
}
|
||||
if (t instanceof final CollectionTag<?> ltag)
|
||||
{
|
||||
final List<Value> elems = new ArrayList<>();
|
||||
for (final Tag elem : ltag)
|
||||
List<Value> elems = new ArrayList<>();
|
||||
for (Tag elem : ltag)
|
||||
{
|
||||
elems.add(decodeTagDeep(elem));
|
||||
}
|
||||
@@ -422,7 +432,7 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa
|
||||
return decodeTagDeep(this.getTag());
|
||||
}
|
||||
|
||||
public static Value fromValue(final Value v)
|
||||
public static Value fromValue(Value v)
|
||||
{
|
||||
if (v instanceof NBTSerializableValue)
|
||||
{
|
||||
@@ -432,7 +442,7 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa
|
||||
{
|
||||
return Value.NULL;
|
||||
}
|
||||
return NBTSerializableValue.parseString(v.getString(), true);
|
||||
return NBTSerializableValue.parseStringOrFail(v.getString());
|
||||
}
|
||||
|
||||
public Tag getTag()
|
||||
@@ -445,7 +455,7 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object o)
|
||||
public boolean equals(Object o)
|
||||
{
|
||||
return o instanceof final NBTSerializableValue nbtsv ? getTag().equals(nbtsv.getTag()) : super.equals(o);
|
||||
}
|
||||
@@ -463,7 +473,7 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa
|
||||
@Override
|
||||
public boolean getBoolean()
|
||||
{
|
||||
final Tag tag = getTag();
|
||||
Tag tag = getTag();
|
||||
if (tag instanceof final CompoundTag ctag)
|
||||
{
|
||||
return !(ctag).isEmpty();
|
||||
@@ -490,35 +500,35 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa
|
||||
ensureOwnership();
|
||||
return (CompoundTag) getTag();
|
||||
}
|
||||
catch (final ClassCastException e)
|
||||
catch (ClassCastException e)
|
||||
{
|
||||
throw new InternalExpressionException(getString() + " is not a valid compound tag");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean put(final Value where, final Value value)
|
||||
public boolean put(Value where, Value value)
|
||||
{
|
||||
return put(where, value, new StringValue("replace"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean put(final Value where, final Value value, final Value conditions)
|
||||
public boolean put(Value where, Value value, Value conditions)
|
||||
{
|
||||
/// WIP
|
||||
ensureOwnership();
|
||||
final NbtPathArgument.NbtPath path = cachePath(where.getString());
|
||||
final Tag tagToInsert = value instanceof final NBTSerializableValue nbtsv
|
||||
NbtPathArgument.NbtPath path = cachePath(where.getString());
|
||||
Tag tagToInsert = value instanceof final NBTSerializableValue nbtsv
|
||||
? nbtsv.getTag()
|
||||
: new NBTSerializableValue(value.getString()).getTag();
|
||||
final boolean modifiedTag;
|
||||
boolean modifiedTag;
|
||||
if (conditions instanceof final NumericValue number)
|
||||
{
|
||||
modifiedTag = modifyInsert((int) number.getLong(), path, tagToInsert);
|
||||
}
|
||||
else
|
||||
{
|
||||
final String ops = conditions.getString();
|
||||
String ops = conditions.getString();
|
||||
if (ops.equalsIgnoreCase("merge"))
|
||||
{
|
||||
modifiedTag = modifyMerge(path, tagToInsert);
|
||||
@@ -540,25 +550,25 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa
|
||||
}
|
||||
|
||||
|
||||
private boolean modifyInsert(final int index, final NbtPathArgument.NbtPath nbtPath, final Tag newElement)
|
||||
private boolean modifyInsert(int index, NbtPathArgument.NbtPath nbtPath, Tag newElement)
|
||||
{
|
||||
return modifyInsert(index, nbtPath, newElement, this.getTag());
|
||||
}
|
||||
|
||||
private boolean modifyInsert(final int index, final NbtPathArgument.NbtPath nbtPath, final Tag newElement, final Tag currentTag)
|
||||
private boolean modifyInsert(int index, NbtPathArgument.NbtPath nbtPath, Tag newElement, Tag currentTag)
|
||||
{
|
||||
final Collection<Tag> targets;
|
||||
Collection<Tag> targets;
|
||||
try
|
||||
{
|
||||
targets = nbtPath.getOrCreate(currentTag, ListTag::new);
|
||||
}
|
||||
catch (final CommandSyntaxException e)
|
||||
catch (CommandSyntaxException e)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean modified = false;
|
||||
for (final Tag target : targets)
|
||||
for (Tag target : targets)
|
||||
{
|
||||
if (!(target instanceof final CollectionTag<?> targetList))
|
||||
{
|
||||
@@ -572,7 +582,7 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa
|
||||
}
|
||||
modified = true;
|
||||
}
|
||||
catch (final IndexOutOfBoundsException ignored)
|
||||
catch (IndexOutOfBoundsException ignored)
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -580,16 +590,16 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa
|
||||
}
|
||||
|
||||
|
||||
private boolean modifyMerge(final NbtPathArgument.NbtPath nbtPath, final Tag replacement) //nbtPathArgumentType$NbtPath_1, list_1)
|
||||
private boolean modifyMerge(NbtPathArgument.NbtPath nbtPath, Tag replacement) //nbtPathArgumentType$NbtPath_1, list_1)
|
||||
{
|
||||
if (!(replacement instanceof final CompoundTag replacementCompound))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
final Tag ownTag = getTag();
|
||||
Tag ownTag = getTag();
|
||||
try
|
||||
{
|
||||
for (final Tag target : nbtPath.getOrCreate(ownTag, CompoundTag::new))
|
||||
for (Tag target : nbtPath.getOrCreate(ownTag, CompoundTag::new))
|
||||
{
|
||||
if (!(target instanceof final CompoundTag targetCompound))
|
||||
{
|
||||
@@ -598,31 +608,31 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa
|
||||
targetCompound.merge(replacementCompound);
|
||||
}
|
||||
}
|
||||
catch (final CommandSyntaxException ignored)
|
||||
catch (CommandSyntaxException ignored)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean modifyReplace(final NbtPathArgument.NbtPath nbtPath, final Tag replacement) //nbtPathArgumentType$NbtPath_1, list_1)
|
||||
private boolean modifyReplace(NbtPathArgument.NbtPath nbtPath, Tag replacement) //nbtPathArgumentType$NbtPath_1, list_1)
|
||||
{
|
||||
final Tag tag = getTag();
|
||||
final String pathText = nbtPath.toString();
|
||||
Tag tag = getTag();
|
||||
String pathText = nbtPath.toString();
|
||||
if (pathText.endsWith("]")) // workaround for array replacement or item in the array replacement
|
||||
{
|
||||
if (nbtPath.remove(tag) == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
final Pattern pattern = Pattern.compile("\\[[^\\[]*]$");
|
||||
final Matcher matcher = pattern.matcher(pathText);
|
||||
Pattern pattern = Pattern.compile("\\[[^\\[]*]$");
|
||||
Matcher matcher = pattern.matcher(pathText);
|
||||
if (!matcher.find()) // malformed path
|
||||
{
|
||||
return false;
|
||||
}
|
||||
final String arrAccess = matcher.group();
|
||||
final int pos;
|
||||
String arrAccess = matcher.group();
|
||||
int pos;
|
||||
if (arrAccess.length() == 2) // we just removed entire array
|
||||
{
|
||||
pos = 0;
|
||||
@@ -633,19 +643,19 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa
|
||||
{
|
||||
pos = Integer.parseInt(arrAccess.substring(1, arrAccess.length() - 1));
|
||||
}
|
||||
catch (final NumberFormatException e)
|
||||
catch (NumberFormatException e)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
final NbtPathArgument.NbtPath newPath = cachePath(pathText.substring(0, pathText.length() - arrAccess.length()));
|
||||
NbtPathArgument.NbtPath newPath = cachePath(pathText.substring(0, pathText.length() - arrAccess.length()));
|
||||
return modifyInsert(pos, newPath, replacement, tag);
|
||||
}
|
||||
try
|
||||
{
|
||||
nbtPath.set(tag, replacement);
|
||||
}
|
||||
catch (final CommandSyntaxException e)
|
||||
catch (CommandSyntaxException e)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -653,13 +663,13 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value get(final Value value)
|
||||
public Value get(Value value)
|
||||
{
|
||||
final String valString = value.getString();
|
||||
final NbtPathArgument.NbtPath path = cachePath(valString);
|
||||
String valString = value.getString();
|
||||
NbtPathArgument.NbtPath path = cachePath(valString);
|
||||
try
|
||||
{
|
||||
final List<Tag> tags = path.get(getTag());
|
||||
List<Tag> tags = path.get(getTag());
|
||||
if (tags.isEmpty())
|
||||
{
|
||||
return Value.NULL;
|
||||
@@ -670,14 +680,14 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa
|
||||
}
|
||||
return ListValue.wrap(tags.stream().map(NBTSerializableValue::decodeTag));
|
||||
}
|
||||
catch (final CommandSyntaxException ignored)
|
||||
catch (CommandSyntaxException ignored)
|
||||
{
|
||||
}
|
||||
return Value.NULL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean has(final Value where)
|
||||
public boolean has(Value where)
|
||||
{
|
||||
return cachePath(where.getString()).countMatching(getTag()) > 0;
|
||||
}
|
||||
@@ -699,11 +709,11 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean delete(final Value where)
|
||||
public boolean delete(Value where)
|
||||
{
|
||||
final NbtPathArgument.NbtPath path = cachePath(where.getString());
|
||||
NbtPathArgument.NbtPath path = cachePath(where.getString());
|
||||
ensureOwnership();
|
||||
final int removed = path.remove(getTag());
|
||||
int removed = path.remove(getTag());
|
||||
if (removed > 0)
|
||||
{
|
||||
dirty();
|
||||
@@ -715,7 +725,7 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa
|
||||
public record InventoryLocator(Object owner, BlockPos position, Container inventory, int offset,
|
||||
boolean isEnder)
|
||||
{
|
||||
InventoryLocator(final Object owner, final BlockPos pos, final Container i, final int o)
|
||||
InventoryLocator(Object owner, BlockPos pos, Container i, int o)
|
||||
{
|
||||
this(owner, pos, i, o, false);
|
||||
}
|
||||
@@ -723,7 +733,7 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa
|
||||
|
||||
private static final Map<String, NbtPathArgument.NbtPath> pathCache = new HashMap<>();
|
||||
|
||||
private static NbtPathArgument.NbtPath cachePath(final String arg)
|
||||
private static NbtPathArgument.NbtPath cachePath(String arg)
|
||||
{
|
||||
NbtPathArgument.NbtPath res = pathCache.get(arg);
|
||||
if (res != null)
|
||||
@@ -734,7 +744,7 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa
|
||||
{
|
||||
res = NbtPathArgument.nbtPath().parse(new StringReader(arg));
|
||||
}
|
||||
catch (final CommandSyntaxException exc)
|
||||
catch (CommandSyntaxException exc)
|
||||
{
|
||||
throw new InternalExpressionException("Incorrect nbt path: " + arg);
|
||||
}
|
||||
@@ -754,7 +764,7 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa
|
||||
|
||||
|
||||
@Override
|
||||
public Tag toTag(final boolean force)
|
||||
public Tag toTag(boolean force)
|
||||
{
|
||||
if (!force)
|
||||
{
|
||||
@@ -768,7 +778,7 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa
|
||||
{
|
||||
public final Value val;
|
||||
|
||||
public IncompatibleTypeException(final Value val)
|
||||
public IncompatibleTypeException(Value val)
|
||||
{
|
||||
this.val = val;
|
||||
}
|
||||
|
||||
@@ -41,13 +41,13 @@ public class NullValue extends NumericValue // TODO check nonsingleton code
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object o)
|
||||
public boolean equals(Object o)
|
||||
{
|
||||
return o instanceof Value value && value.isNull();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value slice(final long fromDesc, final Long toDesc)
|
||||
public Value slice(long fromDesc, Long toDesc)
|
||||
{
|
||||
return Value.NULL;
|
||||
}
|
||||
@@ -65,13 +65,13 @@ public class NullValue extends NumericValue // TODO check nonsingleton code
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(final Value o)
|
||||
public int compareTo(Value o)
|
||||
{
|
||||
return o.isNull() ? 0 : -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value in(final Value value)
|
||||
public Value in(Value value)
|
||||
{
|
||||
return Value.NULL;
|
||||
}
|
||||
@@ -89,7 +89,7 @@ public class NullValue extends NumericValue // TODO check nonsingleton code
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tag toTag(final boolean force)
|
||||
public Tag toTag(boolean force)
|
||||
{
|
||||
if (!force)
|
||||
{
|
||||
@@ -99,7 +99,7 @@ public class NullValue extends NumericValue // TODO check nonsingleton code
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value split(final Value delimiter)
|
||||
public Value split(Value delimiter)
|
||||
{
|
||||
return ListValue.wrap(new ArrayList<>());
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ public class NumericValue extends Value
|
||||
private static final double epsilon = abs(32 * ((7 * 0.1) * 10 - 7));
|
||||
private static final MathContext displayRounding = new MathContext(12, RoundingMode.HALF_EVEN);
|
||||
|
||||
public static NumericValue asNumber(final Value v1, final String id)
|
||||
public static NumericValue asNumber(Value v1, String id)
|
||||
{
|
||||
if (v1 instanceof final NumericValue nv)
|
||||
{
|
||||
@@ -34,7 +34,7 @@ public class NumericValue extends Value
|
||||
throw new InternalExpressionException("Argument " + id + " has to be of a numeric type");
|
||||
}
|
||||
|
||||
public static NumericValue asNumber(final Value v1)
|
||||
public static NumericValue asNumber(Value v1)
|
||||
{
|
||||
if (v1 instanceof final NumericValue nv)
|
||||
{
|
||||
@@ -43,7 +43,7 @@ public class NumericValue extends Value
|
||||
throw new InternalExpressionException("Operand has to be of a numeric type");
|
||||
}
|
||||
|
||||
public static <T extends Number> Value of(final T value)
|
||||
public static <T extends Number> Value of(T value)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
@@ -85,7 +85,7 @@ public class NumericValue extends Value
|
||||
// dobules have 16 point precision, 12 is plenty to display
|
||||
return BigDecimal.valueOf(value).round(displayRounding).stripTrailingZeros().toPlainString();
|
||||
}
|
||||
catch (final NumberFormatException exc)
|
||||
catch (NumberFormatException exc)
|
||||
{
|
||||
throw new InternalExpressionException("Incorrect number format for " + value);
|
||||
}
|
||||
@@ -115,9 +115,9 @@ public class NumericValue extends Value
|
||||
return (float) value;
|
||||
}
|
||||
|
||||
private static long floor(final double v)
|
||||
private static long floor(double v)
|
||||
{
|
||||
final long invValue = (long) v;
|
||||
long invValue = (long) v;
|
||||
return v < invValue ? invValue - 1 : invValue;
|
||||
}
|
||||
|
||||
@@ -127,7 +127,7 @@ public class NumericValue extends Value
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value add(final Value v)
|
||||
public Value add(Value v)
|
||||
{ // TODO test if definintn add(NumericVlaue) woud solve the casting
|
||||
if (v instanceof final NumericValue nv)
|
||||
{
|
||||
@@ -137,7 +137,7 @@ public class NumericValue extends Value
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value subtract(final Value v)
|
||||
public Value subtract(Value v)
|
||||
{ // TODO test if definintn add(NumericVlaue) woud solve the casting
|
||||
if (v instanceof final NumericValue nv)
|
||||
{
|
||||
@@ -147,7 +147,7 @@ public class NumericValue extends Value
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value multiply(final Value v)
|
||||
public Value multiply(Value v)
|
||||
{
|
||||
if (v instanceof final NumericValue nv)
|
||||
{
|
||||
@@ -157,7 +157,7 @@ public class NumericValue extends Value
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value divide(final Value v)
|
||||
public Value divide(Value v)
|
||||
{
|
||||
return v instanceof final NumericValue nv ? new NumericValue(getDouble() / nv.getDouble()) : super.divide(v);
|
||||
}
|
||||
@@ -169,7 +169,7 @@ public class NumericValue extends Value
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(final Value o)
|
||||
public int compareTo(Value o)
|
||||
{
|
||||
if (o.isNull())
|
||||
{
|
||||
@@ -183,7 +183,7 @@ public class NumericValue extends Value
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object o)
|
||||
public boolean equals(Object o)
|
||||
{
|
||||
if (o instanceof final Value otherValue)
|
||||
{
|
||||
@@ -200,34 +200,34 @@ public class NumericValue extends Value
|
||||
return false;
|
||||
}
|
||||
|
||||
public NumericValue(final double value)
|
||||
public NumericValue(double value)
|
||||
{
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
private NumericValue(final double value, final Long longValue)
|
||||
private NumericValue(double value, Long longValue)
|
||||
{
|
||||
this.value = value;
|
||||
this.longValue = longValue;
|
||||
}
|
||||
|
||||
public NumericValue(final String value)
|
||||
public NumericValue(String value)
|
||||
{
|
||||
final BigDecimal decimal = new BigDecimal(value);
|
||||
BigDecimal decimal = new BigDecimal(value);
|
||||
if (decimal.stripTrailingZeros().scale() <= 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
longValue = decimal.longValueExact();
|
||||
}
|
||||
catch (final ArithmeticException ignored)
|
||||
catch (ArithmeticException ignored)
|
||||
{
|
||||
}
|
||||
}
|
||||
this.value = decimal.doubleValue();
|
||||
}
|
||||
|
||||
public NumericValue(final long value)
|
||||
public NumericValue(long value)
|
||||
{
|
||||
this.longValue = value;
|
||||
this.value = (double) value;
|
||||
@@ -271,7 +271,7 @@ public class NumericValue extends Value
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tag toTag(final boolean force)
|
||||
public Tag toTag(boolean force)
|
||||
{
|
||||
if (longValue != null)
|
||||
{
|
||||
@@ -281,7 +281,7 @@ public class NumericValue extends Value
|
||||
}
|
||||
return LongTag.valueOf(longValue);
|
||||
}
|
||||
final long lv = getLong();
|
||||
long lv = getLong();
|
||||
if (value == (double) lv)
|
||||
{
|
||||
if (abs(value) < Integer.MAX_VALUE - 2)
|
||||
@@ -303,7 +303,7 @@ public class NumericValue extends Value
|
||||
{
|
||||
return new JsonPrimitive(longValue);
|
||||
}
|
||||
final long lv = getLong();
|
||||
long lv = getLong();
|
||||
return new JsonPrimitive(value == lv ? getLong() : value);
|
||||
}
|
||||
|
||||
@@ -317,14 +317,14 @@ public class NumericValue extends Value
|
||||
return longValue != null || getDouble() == getLong();
|
||||
}
|
||||
|
||||
public Value mod(final NumericValue n2)
|
||||
public Value mod(NumericValue n2)
|
||||
{
|
||||
if (this.longValue != null && n2.longValue != null)
|
||||
{
|
||||
return new NumericValue(Math.floorMod(longValue, n2.longValue));
|
||||
}
|
||||
final double x = value;
|
||||
final double y = n2.value;
|
||||
double x = value;
|
||||
double y = n2.value;
|
||||
if (y == 0)
|
||||
{
|
||||
throw new ArithmeticException("Division by zero");
|
||||
|
||||
Loaded 100 of 106 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user