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;
|
public CommandSourceStack s;
|
||||||
private final BlockPos origin;
|
private final BlockPos origin;
|
||||||
|
|
||||||
public CarpetContext(final CarpetScriptHost host, final CommandSourceStack source)
|
public CarpetContext(CarpetScriptHost host, CommandSourceStack source)
|
||||||
{
|
{
|
||||||
this(host, source, BlockPos.ZERO);
|
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);
|
super(host);
|
||||||
s = source;
|
s = source;
|
||||||
@@ -60,7 +60,7 @@ public class CarpetContext extends Context
|
|||||||
return s.getLevel().registryAccess();
|
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);
|
return registryAccess().registryOrThrow(resourceKey);
|
||||||
}
|
}
|
||||||
@@ -75,7 +75,7 @@ public class CarpetContext extends Context
|
|||||||
return origin;
|
return origin;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void swapSource(final CommandSourceStack source)
|
public void swapSource(CommandSourceStack source)
|
||||||
{
|
{
|
||||||
s = source;
|
s = source;
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large.
Load diff
@@ -42,7 +42,7 @@ public class CarpetExpression
|
|||||||
return origin;
|
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.origin = origin;
|
||||||
this.source = source;
|
this.source = source;
|
||||||
@@ -61,7 +61,7 @@ public class CarpetExpression
|
|||||||
Carpet.handleExtensionsAPI(this);
|
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();
|
CarpetScriptServer scriptServer = (CarpetScriptServer) host.scriptServer();
|
||||||
if (scriptServer.stopAll)
|
if (scriptServer.stopAll)
|
||||||
@@ -70,39 +70,39 @@ public class CarpetExpression
|
|||||||
}
|
}
|
||||||
try
|
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("x", (c, t) -> new NumericValue(x - origin.getX()).bindTo("x")).
|
||||||
with("y", (c, t) -> new NumericValue(y - origin.getY()).bindTo("y")).
|
with("y", (c, t) -> new NumericValue(y - origin.getY()).bindTo("y")).
|
||||||
with("z", (c, t) -> new NumericValue(z - origin.getZ()).bindTo("z")).
|
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("_"));
|
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)
|
if (e == null)
|
||||||
{
|
{
|
||||||
final Value nullPlayer = Value.NULL.reboundedTo("p");
|
Value nullPlayer = Value.NULL.reboundedTo("p");
|
||||||
context.with("p", (cc, tt) -> nullPlayer);
|
context.with("p", (cc, tt) -> nullPlayer);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
final Value playerValue = new EntityValue(e).bindTo("p");
|
Value playerValue = new EntityValue(e).bindTo("p");
|
||||||
context.with("p", (cc, tt) -> playerValue);
|
context.with("p", (cc, tt) -> playerValue);
|
||||||
}
|
}
|
||||||
return scriptServer.events.handleEvents.getWhileDisabled(() -> this.expr.eval(context).getBoolean());
|
return scriptServer.events.handleEvents.getWhileDisabled(() -> this.expr.eval(context).getBoolean());
|
||||||
}
|
}
|
||||||
catch (final ExpressionException e)
|
catch (ExpressionException e)
|
||||||
{
|
{
|
||||||
throw new CarpetExpressionException(e.getMessage(), e.stack);
|
throw new CarpetExpressionException(e.getMessage(), e.stack);
|
||||||
}
|
}
|
||||||
catch (final ArithmeticException ae)
|
catch (ArithmeticException ae)
|
||||||
{
|
{
|
||||||
throw new CarpetExpressionException("Math doesn't compute... " + ae.getMessage(), null);
|
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);
|
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();
|
CarpetScriptServer scriptServer = (CarpetScriptServer) host.scriptServer();
|
||||||
if (scriptServer.stopAll)
|
if (scriptServer.stopAll)
|
||||||
@@ -111,32 +111,32 @@ public class CarpetExpression
|
|||||||
}
|
}
|
||||||
try
|
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("x", (c, t) -> new NumericValue(pos.getX() - origin.getX()).bindTo("x")).
|
||||||
with("y", (c, t) -> new NumericValue(pos.getY() - origin.getY()).bindTo("y")).
|
with("y", (c, t) -> new NumericValue(pos.getY() - origin.getY()).bindTo("y")).
|
||||||
with("z", (c, t) -> new NumericValue(pos.getZ() - origin.getZ()).bindTo("z"));
|
with("z", (c, t) -> new NumericValue(pos.getZ() - origin.getZ()).bindTo("z"));
|
||||||
final Entity e = source.getEntity();
|
Entity e = source.getEntity();
|
||||||
if (e == null)
|
if (e == null)
|
||||||
{
|
{
|
||||||
final Value nullPlayer = Value.NULL.reboundedTo("p");
|
Value nullPlayer = Value.NULL.reboundedTo("p");
|
||||||
context.with("p", (cc, tt) -> nullPlayer);
|
context.with("p", (cc, tt) -> nullPlayer);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
final Value playerValue = new EntityValue(e).bindTo("p");
|
Value playerValue = new EntityValue(e).bindTo("p");
|
||||||
context.with("p", (cc, tt) -> playerValue);
|
context.with("p", (cc, tt) -> playerValue);
|
||||||
}
|
}
|
||||||
return scriptServer.events.handleEvents.getWhileDisabled(() -> this.expr.eval(context));
|
return scriptServer.events.handleEvents.getWhileDisabled(() -> this.expr.eval(context));
|
||||||
}
|
}
|
||||||
catch (final ExpressionException e)
|
catch (ExpressionException e)
|
||||||
{
|
{
|
||||||
throw new CarpetExpressionException(e.getMessage(), e.stack);
|
throw new CarpetExpressionException(e.getMessage(), e.stack);
|
||||||
}
|
}
|
||||||
catch (final ArithmeticException ae)
|
catch (ArithmeticException ae)
|
||||||
{
|
{
|
||||||
throw new CarpetExpressionException("Math doesn't compute... " + ae.getMessage(), null);
|
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);
|
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.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.file.FileVisitOption;
|
import java.nio.file.FileVisitOption;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
@@ -73,7 +74,7 @@ public class CarpetScriptServer extends ScriptServer
|
|||||||
* @param app The {@link Module} of the app
|
* @param app The {@link Module} of the app
|
||||||
* @see Module#fromJarPath(String, String, boolean)
|
* @see Module#fromJarPath(String, String, boolean)
|
||||||
*/
|
*/
|
||||||
public static void registerBuiltInApp(final Module app)
|
public static void registerBuiltInApp(Module app)
|
||||||
{
|
{
|
||||||
bundledModuleData.add(app);
|
bundledModuleData.add(app);
|
||||||
}
|
}
|
||||||
@@ -85,7 +86,7 @@ public class CarpetScriptServer extends ScriptServer
|
|||||||
* @param app The {@link Module} of the app.
|
* @param app The {@link Module} of the app.
|
||||||
* @see Module#fromJarPath(String, String, boolean)
|
* @see Module#fromJarPath(String, String, boolean)
|
||||||
*/
|
*/
|
||||||
public static void registerSettingsApp(final Module app)
|
public static void registerSettingsApp(Module app)
|
||||||
{
|
{
|
||||||
ruleModuleData.add(app);
|
ruleModuleData.add(app);
|
||||||
}
|
}
|
||||||
@@ -104,7 +105,7 @@ public class CarpetScriptServer extends ScriptServer
|
|||||||
registerBuiltInApp(Module.carpetNative("distance_beta", false));
|
registerBuiltInApp(Module.carpetNative("distance_beta", false));
|
||||||
}
|
}
|
||||||
|
|
||||||
public CarpetScriptServer(final MinecraftServer server)
|
public CarpetScriptServer(MinecraftServer server)
|
||||||
{
|
{
|
||||||
this.server = server;
|
this.server = server;
|
||||||
init();
|
init();
|
||||||
@@ -125,7 +126,7 @@ public class CarpetScriptServer extends ScriptServer
|
|||||||
{
|
{
|
||||||
if (Vanilla.MinecraftServer_doScriptsAutoload(server))
|
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);
|
addScriptHost(server.createCommandSourceStack(), moduleName, null, true, true, false, null);
|
||||||
}
|
}
|
||||||
@@ -133,18 +134,18 @@ public class CarpetScriptServer extends ScriptServer
|
|||||||
CarpetEventServer.Event.START.onTick(server);
|
CarpetEventServer.Event.START.onTick(server);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Module getModule(final String name, final boolean allowLibraries)
|
public Module getModule(String name, boolean allowLibraries)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
final Path folder = server.getWorldPath(LevelResource.ROOT).resolve("scripts");
|
Path folder = server.getWorldPath(LevelResource.ROOT).resolve("scripts");
|
||||||
if (!Files.exists(folder))
|
if (!Files.exists(folder))
|
||||||
{
|
{
|
||||||
Files.createDirectories(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 ->
|
.filter(script ->
|
||||||
script.getFileName().toString().equalsIgnoreCase(name + ".sc") ||
|
script.getFileName().toString().equalsIgnoreCase(name + ".sc") ||
|
||||||
(allowLibraries && script.getFileName().toString().equalsIgnoreCase(name + ".scl"))
|
(allowLibraries && script.getFileName().toString().equalsIgnoreCase(name + ".scl"))
|
||||||
@@ -157,14 +158,14 @@ public class CarpetScriptServer extends ScriptServer
|
|||||||
|
|
||||||
if (FabricLoader.getInstance().getEnvironmentType() == EnvType.CLIENT)
|
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))
|
if (!Files.exists(globalFolder))
|
||||||
{
|
{
|
||||||
Files.createDirectories(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") ||
|
.filter(script -> script.getFileName().toString().equalsIgnoreCase(name + ".sc") ||
|
||||||
(allowLibraries && script.getFileName().toString().equalsIgnoreCase(name + ".scl")))
|
(allowLibraries && script.getFileName().toString().equalsIgnoreCase(name + ".scl")))
|
||||||
.findFirst();
|
.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);
|
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()))
|
if (moduleData.name().equalsIgnoreCase(name) && (allowLibraries || !moduleData.library()))
|
||||||
{
|
{
|
||||||
@@ -189,9 +190,9 @@ public class CarpetScriptServer extends ScriptServer
|
|||||||
return null;
|
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))
|
if (moduleData.name().equalsIgnoreCase(name))
|
||||||
{
|
{
|
||||||
@@ -201,12 +202,12 @@ public class CarpetScriptServer extends ScriptServer
|
|||||||
return null;
|
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)
|
if (includeBuiltIns)
|
||||||
{
|
{
|
||||||
for (final Module mi : bundledModuleData)
|
for (Module mi : bundledModuleData)
|
||||||
{
|
{
|
||||||
if (!mi.library() && !mi.name().endsWith("_beta"))
|
if (!mi.library() && !mi.name().endsWith("_beta"))
|
||||||
{
|
{
|
||||||
@@ -216,12 +217,12 @@ public class CarpetScriptServer extends ScriptServer
|
|||||||
}
|
}
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
final Path worldScripts = server.getWorldPath(LevelResource.ROOT).resolve("scripts");
|
Path worldScripts = server.getWorldPath(LevelResource.ROOT).resolve("scripts");
|
||||||
if (!Files.exists(worldScripts))
|
if (!Files.exists(worldScripts))
|
||||||
{
|
{
|
||||||
Files.createDirectories(worldScripts);
|
Files.createDirectories(worldScripts);
|
||||||
}
|
}
|
||||||
try (final Stream<Path> folderLister = Files.list(worldScripts))
|
try (Stream<Path> folderLister = Files.list(worldScripts))
|
||||||
{
|
{
|
||||||
folderLister
|
folderLister
|
||||||
.filter(f -> f.toString().endsWith(".sc"))
|
.filter(f -> f.toString().endsWith(".sc"))
|
||||||
@@ -230,12 +231,12 @@ public class CarpetScriptServer extends ScriptServer
|
|||||||
|
|
||||||
if (includeBuiltIns && (FabricLoader.getInstance().getEnvironmentType() == EnvType.CLIENT))
|
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))
|
if (!Files.exists(globalScripts))
|
||||||
{
|
{
|
||||||
Files.createDirectories(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
|
folderWalker
|
||||||
.filter(f -> f.toString().endsWith(".sc"))
|
.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);
|
LOG.error("Exception while searching for apps: ", e);
|
||||||
}
|
}
|
||||||
return moduleNames;
|
return moduleNames;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CarpetScriptHost getAppHostByName(final String name)
|
public CarpetScriptHost getAppHostByName(String name)
|
||||||
{
|
{
|
||||||
return name == null ? globalHost : modules.get(name);
|
return name == null ? globalHost : modules.get(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean addScriptHost(final CommandSourceStack source, String name, Predicate<CommandSourceStack> commandValidator,
|
public boolean addScriptHost(CommandSourceStack source, String name, @Nullable Predicate<CommandSourceStack> commandValidator,
|
||||||
final boolean perPlayer, final boolean autoload, final boolean isRuleApp, final AppStoreManager.StoreNode installer)
|
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)
|
if (commandValidator == null)
|
||||||
{
|
{
|
||||||
commandValidator = p -> true;
|
commandValidator = p -> true;
|
||||||
}
|
}
|
||||||
final long start = System.nanoTime();
|
long start = System.nanoTime();
|
||||||
name = name.toLowerCase(Locale.ROOT);
|
name = name.toLowerCase(Locale.ROOT);
|
||||||
boolean reload = false;
|
boolean reload = false;
|
||||||
if (modules.containsKey(name))
|
if (modules.containsKey(name))
|
||||||
@@ -275,18 +276,18 @@ public class CarpetScriptServer extends ScriptServer
|
|||||||
removeScriptHost(source, name, false, isRuleApp);
|
removeScriptHost(source, name, false, isRuleApp);
|
||||||
reload = true;
|
reload = true;
|
||||||
}
|
}
|
||||||
final Module module = isRuleApp ? getRuleModule(name) : getModule(name, false);
|
Module module = isRuleApp ? getRuleModule(name) : getModule(name, false);
|
||||||
if (module == null)
|
if (module == null)
|
||||||
{
|
{
|
||||||
Carpet.Messenger_message(source, "r Failed to add " + name + " app: App not found");
|
Carpet.Messenger_message(source, "r Failed to add " + name + " app: App not found");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
final CarpetScriptHost newHost;
|
CarpetScriptHost newHost;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
newHost = CarpetScriptHost.create(this, module, perPlayer, source, commandValidator, isRuleApp, installer);
|
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()));
|
Carpet.Messenger_message(source, "r Failed to add " + name + " app" + (e.getMessage() == null ? "" : ": " + e.getMessage()));
|
||||||
return false;
|
return false;
|
||||||
@@ -303,10 +304,10 @@ public class CarpetScriptServer extends ScriptServer
|
|||||||
removeScriptHost(source, name, false, false);
|
removeScriptHost(source, name, false, false);
|
||||||
return 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;
|
String finalName = name;
|
||||||
final Boolean isCommandAdded = newHost.addAppCommands(s -> {
|
Boolean isCommandAdded = newHost.addAppCommands(s -> {
|
||||||
if (!isRuleApp)
|
if (!isRuleApp)
|
||||||
{
|
{
|
||||||
Carpet.Messenger_message(source, "r Failed to add app '" + finalName + "': ", s);
|
Carpet.Messenger_message(source, "r Failed to add app '" + finalName + "': ", s);
|
||||||
@@ -336,7 +337,7 @@ public class CarpetScriptServer extends ScriptServer
|
|||||||
if (newHost.isPerUser())
|
if (newHost.isPerUser())
|
||||||
{
|
{
|
||||||
// that will provide player hosts right at the startup
|
// 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);
|
newHost.retrieveForExecution(player.createCommandSourceStack(), player);
|
||||||
}
|
}
|
||||||
@@ -344,25 +345,25 @@ public class CarpetScriptServer extends ScriptServer
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// global app - calling start now.
|
// global app - calling start now.
|
||||||
final FunctionValue onStart = newHost.getFunction("__on_start");
|
FunctionValue onStart = newHost.getFunction("__on_start");
|
||||||
if (onStart != null)
|
if (onStart != null)
|
||||||
{
|
{
|
||||||
newHost.callNow(onStart, Collections.emptyList());
|
newHost.callNow(onStart, Collections.emptyList());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
token.run();
|
token.run();
|
||||||
final long end = System.nanoTime();
|
long end = System.nanoTime();
|
||||||
LOG.info("App " + name + " loaded in " + (end - start) / 1000000 + " ms");
|
LOG.info("App " + name + " loaded in " + (end - start) / 1000000 + " ms");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isInvalidCommandRoot(final String appName)
|
public boolean isInvalidCommandRoot(String appName)
|
||||||
{
|
{
|
||||||
return holyMoly.contains(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);
|
name = name.toLowerCase(Locale.ROOT);
|
||||||
if (!modules.containsKey(name) || (!isRuleApp && !unloadableModules.contains(name)))
|
if (!modules.containsKey(name) || (!isRuleApp && !unloadableModules.contains(name)))
|
||||||
@@ -374,7 +375,7 @@ public class CarpetScriptServer extends ScriptServer
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// stop all events associated with name
|
// stop all events associated with name
|
||||||
final CarpetScriptHost host = modules.remove(name);
|
CarpetScriptHost host = modules.remove(name);
|
||||||
events.removeAllHostEvents(host);
|
events.removeAllHostEvents(host);
|
||||||
host.onClose();
|
host.onClose();
|
||||||
if (host.hasCommand)
|
if (host.hasCommand)
|
||||||
@@ -393,12 +394,12 @@ public class CarpetScriptServer extends ScriptServer
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean uninstallApp(final CommandSourceStack source, String name)
|
public boolean uninstallApp(CommandSourceStack source, String name)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
name = name.toLowerCase(Locale.ROOT);
|
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))
|
if (!Files.exists(folder))
|
||||||
{
|
{
|
||||||
Files.createDirectories(folder);
|
Files.createDirectories(folder);
|
||||||
@@ -413,7 +414,7 @@ public class CarpetScriptServer extends ScriptServer
|
|||||||
Carpet.Messenger_message(source, "gi Removed " + name + " app");
|
Carpet.Messenger_message(source, "gi Removed " + name + " app");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
catch (final IOException exc)
|
catch (IOException exc)
|
||||||
{
|
{
|
||||||
Carpet.Messenger_message(source, "rb Failed to uninstall the app");
|
Carpet.Messenger_message(source, "rb Failed to uninstall the app");
|
||||||
}
|
}
|
||||||
@@ -430,7 +431,7 @@ public class CarpetScriptServer extends ScriptServer
|
|||||||
});
|
});
|
||||||
token.run();
|
token.run();
|
||||||
token = Carpet.startProfilerSection("Scarpet app data");
|
token = Carpet.startProfilerSection("Scarpet app data");
|
||||||
for (final CarpetScriptHost host : modules.values())
|
for (CarpetScriptHost host : modules.values())
|
||||||
{
|
{
|
||||||
host.tick();
|
host.tick();
|
||||||
}
|
}
|
||||||
@@ -440,7 +441,7 @@ public class CarpetScriptServer extends ScriptServer
|
|||||||
public void onClose()
|
public void onClose()
|
||||||
{
|
{
|
||||||
CarpetEventServer.Event.SHUTDOWN.onTick(server);
|
CarpetEventServer.Event.SHUTDOWN.onTick(server);
|
||||||
for (final CarpetScriptHost host : modules.values())
|
for (CarpetScriptHost host : modules.values())
|
||||||
{
|
{
|
||||||
host.onClose();
|
host.onClose();
|
||||||
events.removeAllHostEvents(host);
|
events.removeAllHostEvents(host);
|
||||||
@@ -448,7 +449,7 @@ public class CarpetScriptServer extends ScriptServer
|
|||||||
stopAll = true;
|
stopAll = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onPlayerJoin(final ServerPlayer player)
|
public void onPlayerJoin(ServerPlayer player)
|
||||||
{
|
{
|
||||||
modules.values().forEach(h ->
|
modules.values().forEach(h ->
|
||||||
{
|
{
|
||||||
@@ -458,7 +459,7 @@ public class CarpetScriptServer extends ScriptServer
|
|||||||
{
|
{
|
||||||
h.retrieveOwnForExecution(player.createCommandSourceStack());
|
h.retrieveOwnForExecution(player.createCommandSourceStack());
|
||||||
}
|
}
|
||||||
catch (final CommandSyntaxException ignored)
|
catch (CommandSyntaxException ignored)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -466,7 +467,7 @@ public class CarpetScriptServer extends ScriptServer
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Path resolveResource(final String suffix)
|
public Path resolveResource(String suffix)
|
||||||
{
|
{
|
||||||
return server.getWorldPath(LevelResource.ROOT).resolve("scripts/" + 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,
|
private record TransferData(boolean perUser, Predicate<CommandSourceStack> commandValidator,
|
||||||
boolean isRuleApp)
|
boolean isRuleApp)
|
||||||
{
|
{
|
||||||
private TransferData(final CarpetScriptHost host)
|
private TransferData(CarpetScriptHost host)
|
||||||
{
|
{
|
||||||
this(host.perUser, host.commandValidator, host.isRuleApp);
|
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)));
|
modules.forEach((s, h) -> apps.put(s, new TransferData(h)));
|
||||||
apps.keySet().forEach(s -> removeScriptHost(server.createCommandSourceStack(), s, false, false));
|
apps.keySet().forEach(s -> removeScriptHost(server.createCommandSourceStack(), s, false, false));
|
||||||
CarpetEventServer.Event.clearAllBuiltinEvents();
|
CarpetEventServer.Event.clearAllBuiltinEvents();
|
||||||
|
|||||||
@@ -30,32 +30,32 @@ public class Context
|
|||||||
|
|
||||||
public final ScriptHost host;
|
public final ScriptHost host;
|
||||||
|
|
||||||
public Context(final ScriptHost host)
|
public Context(ScriptHost host)
|
||||||
{
|
{
|
||||||
this.host = host;
|
this.host = host;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LazyValue getVariable(final String name)
|
public LazyValue getVariable(String name)
|
||||||
{
|
{
|
||||||
return variables.get(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);
|
variables.put(name, lv);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void delVariable(final String variable)
|
public void delVariable(String variable)
|
||||||
{
|
{
|
||||||
variables.remove(variable);
|
variables.remove(variable);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeVariablesMatching(final String varname)
|
public void removeVariablesMatching(String varname)
|
||||||
{
|
{
|
||||||
variables.entrySet().removeIf(e -> e.getKey().startsWith(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);
|
variables.put(variable, lv);
|
||||||
return this;
|
return this;
|
||||||
@@ -68,7 +68,7 @@ public class Context
|
|||||||
|
|
||||||
public Context recreate()
|
public Context recreate()
|
||||||
{
|
{
|
||||||
final Context ctx = duplicate();
|
Context ctx = duplicate();
|
||||||
ctx.initialize();
|
ctx.initialize();
|
||||||
return ctx;
|
return ctx;
|
||||||
}
|
}
|
||||||
@@ -104,7 +104,7 @@ public class Context
|
|||||||
{
|
{
|
||||||
public ScriptHost.ErrorSnooper optmizerEerrorSnooper;
|
public ScriptHost.ErrorSnooper optmizerEerrorSnooper;
|
||||||
|
|
||||||
public ContextForErrorReporting(final Context parent)
|
public ContextForErrorReporting(Context parent)
|
||||||
{
|
{
|
||||||
super(null);
|
super(null);
|
||||||
optmizerEerrorSnooper = parent.host.errorSnooper;
|
optmizerEerrorSnooper = parent.host.errorSnooper;
|
||||||
@@ -125,32 +125,32 @@ public class Context
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LazyValue getVariable(final String name)
|
public LazyValue getVariable(String name)
|
||||||
{
|
{
|
||||||
badProgrammer();
|
badProgrammer();
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setVariable(final String name, final LazyValue lv)
|
public void setVariable(String name, LazyValue lv)
|
||||||
{
|
{
|
||||||
badProgrammer();
|
badProgrammer();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void delVariable(final String variable)
|
public void delVariable(String variable)
|
||||||
{
|
{
|
||||||
badProgrammer();
|
badProgrammer();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removeVariablesMatching(final String varname)
|
public void removeVariablesMatching(String varname)
|
||||||
{
|
{
|
||||||
badProgrammer();
|
badProgrammer();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Context with(final String variable, final LazyValue lv)
|
public Context with(String variable, LazyValue lv)
|
||||||
{
|
{
|
||||||
badProgrammer();
|
badProgrammer();
|
||||||
return this;
|
return this;
|
||||||
|
|||||||
@@ -29,33 +29,33 @@ public class EntityEventsGroup
|
|||||||
private final Map<Event, Map<EventKey, CarpetEventServer.Callback>> actions;
|
private final Map<Event, Map<EventKey, CarpetEventServer.Callback>> actions;
|
||||||
private final Entity entity;
|
private final Entity entity;
|
||||||
|
|
||||||
public EntityEventsGroup(final Entity e)
|
public EntityEventsGroup(Entity e)
|
||||||
{
|
{
|
||||||
actions = new HashMap<>();
|
actions = new HashMap<>();
|
||||||
entity = e;
|
entity = e;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onEvent(final Event type, final Object... args)
|
public void onEvent(Event type, Object... args)
|
||||||
{
|
{
|
||||||
if (actions.isEmpty())
|
if (actions.isEmpty())
|
||||||
{
|
{
|
||||||
return; // most of the cases, trying to be nice
|
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)
|
if (actionSet == null)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final CarpetScriptServer scriptServer = Vanilla.MinecraftServer_getScriptServer(entity.getServer());
|
CarpetScriptServer scriptServer = Vanilla.MinecraftServer_getScriptServer(entity.getServer());
|
||||||
if (scriptServer.stopAll)
|
if (scriptServer.stopAll)
|
||||||
{
|
{
|
||||||
return; // executed after world is closin down
|
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();
|
Map.Entry<EventKey, CarpetEventServer.Callback> action = iterator.next();
|
||||||
final EventKey key = action.getKey();
|
EventKey key = action.getKey();
|
||||||
final ScriptHost host = scriptServer.getAppHostByName(key.host());
|
ScriptHost host = scriptServer.getAppHostByName(key.host());
|
||||||
if (host == null)
|
if (host == null)
|
||||||
{
|
{
|
||||||
iterator.remove();
|
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)
|
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)
|
if (call == null)
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("wrong number of arguments for callback, required " + type.argcount);
|
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)
|
public static final Event ON_DEATH = new Event("on_death", 1)
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
public List<Value> makeArgs(final Entity entity, final Object... providedArgs)
|
public List<Value> makeArgs(Entity entity, Object... providedArgs)
|
||||||
{
|
{
|
||||||
return Arrays.asList(
|
return Arrays.asList(
|
||||||
new EntityValue(entity),
|
new EntityValue(entity),
|
||||||
@@ -119,10 +119,10 @@ public class EntityEventsGroup
|
|||||||
public static final Event ON_DAMAGE = new Event("on_damaged", 3)
|
public static final Event ON_DAMAGE = new Event("on_damaged", 3)
|
||||||
{
|
{
|
||||||
@Override
|
@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];
|
float amount = (Float) providedArgs[0];
|
||||||
final DamageSource source = (DamageSource) providedArgs[1];
|
DamageSource source = (DamageSource) providedArgs[1];
|
||||||
return Arrays.asList(
|
return Arrays.asList(
|
||||||
new EntityValue(entity),
|
new EntityValue(entity),
|
||||||
new NumericValue(amount),
|
new NumericValue(amount),
|
||||||
@@ -134,7 +134,7 @@ public class EntityEventsGroup
|
|||||||
public static final Event ON_MOVE = new Event("on_move", 3)
|
public static final Event ON_MOVE = new Event("on_move", 3)
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
public List<Value> makeArgs(final Entity entity, final Object... providedArgs)
|
public List<Value> makeArgs(Entity entity, Object... providedArgs)
|
||||||
{
|
{
|
||||||
return Arrays.asList(
|
return Arrays.asList(
|
||||||
new EntityValue(entity),
|
new EntityValue(entity),
|
||||||
@@ -148,14 +148,14 @@ public class EntityEventsGroup
|
|||||||
public final int argcount;
|
public final int argcount;
|
||||||
public final String id;
|
public final String id;
|
||||||
|
|
||||||
public Event(final String identifier, final int args)
|
public Event(String identifier, int args)
|
||||||
{
|
{
|
||||||
id = identifier;
|
id = identifier;
|
||||||
argcount = args + 1; // entity is not extra
|
argcount = args + 1; // entity is not extra
|
||||||
byName.put(identifier, this);
|
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)
|
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);
|
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;
|
assert args.length == argcount - 1;
|
||||||
return tickCall.execute(entity.createCommandSourceStack(), makeArgs(entity, args));
|
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));
|
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
|
* @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;
|
return transitive() ? outerType : Context.NONE;
|
||||||
}
|
}
|
||||||
@@ -106,7 +106,7 @@ public abstract class Fluff
|
|||||||
protected String name;
|
protected String name;
|
||||||
int numParams;
|
int numParams;
|
||||||
|
|
||||||
public AbstractLazyFunction(final int numParams, final String name)
|
public AbstractLazyFunction(int numParams, String name)
|
||||||
{
|
{
|
||||||
super();
|
super();
|
||||||
this.numParams = numParams;
|
this.numParams = numParams;
|
||||||
@@ -131,12 +131,12 @@ public abstract class Fluff
|
|||||||
return numParams < 0;
|
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<>();
|
List<Value> args = new ArrayList<>();
|
||||||
for (final LazyValue lv : lzargs)
|
for (LazyValue lv : lzargs)
|
||||||
{
|
{
|
||||||
final Value arg = lv.evalValue(c, contextType);
|
Value arg = lv.evalValue(c, contextType);
|
||||||
if (arg instanceof FunctionUnpackedArgumentsValue)
|
if (arg instanceof FunctionUnpackedArgumentsValue)
|
||||||
{
|
{
|
||||||
args.addAll(((ListValue) arg).getItems());
|
args.addAll(((ListValue) arg).getItems());
|
||||||
@@ -149,9 +149,9 @@ public abstract class Fluff
|
|||||||
return args;
|
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())
|
if (!numParamsVaries() && getNumParams() != args.size())
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("Function " + getName() + " expected " + getNumParams() + " parameters, got " + args.size());
|
throw new InternalExpressionException("Function " + getName() + " expected " + getNumParams() + " parameters, got " + args.size());
|
||||||
@@ -159,9 +159,9 @@ public abstract class Fluff
|
|||||||
return args;
|
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));
|
args.forEach(v -> lzargs.add((c, t) -> v));
|
||||||
return lzargs;
|
return lzargs;
|
||||||
}
|
}
|
||||||
@@ -169,7 +169,7 @@ public abstract class Fluff
|
|||||||
|
|
||||||
public abstract static class AbstractFunction extends AbstractLazyFunction implements IFunction
|
public abstract static class AbstractFunction extends AbstractLazyFunction implements IFunction
|
||||||
{
|
{
|
||||||
AbstractFunction(final int numParams, final String name)
|
AbstractFunction(int numParams, String name)
|
||||||
{
|
{
|
||||||
super(numParams, name);
|
super(numParams, name);
|
||||||
}
|
}
|
||||||
@@ -187,7 +187,7 @@ public abstract class Fluff
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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()
|
return new LazyValue()
|
||||||
@@ -195,20 +195,20 @@ public abstract class Fluff
|
|||||||
private List<Value> params;
|
private List<Value> params;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Value evalValue(final Context c, final Context.Type type)
|
public Value evalValue(Context c, Context.Type type)
|
||||||
{
|
{
|
||||||
ILazyFunction.checkInterrupts();
|
ILazyFunction.checkInterrupts();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return AbstractFunction.this.eval(getParams(c));
|
return AbstractFunction.this.eval(getParams(c));
|
||||||
}
|
}
|
||||||
catch (final RuntimeException exc)
|
catch (RuntimeException exc)
|
||||||
{
|
{
|
||||||
throw Expression.handleCodeException(cc, exc, e, t);
|
throw Expression.handleCodeException(cc, exc, e, t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Value> getParams(final Context c)
|
private List<Value> getParams(Context c)
|
||||||
{
|
{
|
||||||
if (params == null)
|
if (params == null)
|
||||||
{
|
{
|
||||||
@@ -231,7 +231,7 @@ public abstract class Fluff
|
|||||||
|
|
||||||
boolean leftAssoc;
|
boolean leftAssoc;
|
||||||
|
|
||||||
AbstractLazyOperator(final int precedence, final boolean leftAssoc)
|
AbstractLazyOperator(int precedence, boolean leftAssoc)
|
||||||
{
|
{
|
||||||
super();
|
super();
|
||||||
this.precedence = precedence;
|
this.precedence = precedence;
|
||||||
@@ -255,7 +255,7 @@ public abstract class Fluff
|
|||||||
public abstract static class AbstractOperator extends AbstractLazyOperator implements IOperator
|
public abstract static class AbstractOperator extends AbstractLazyOperator implements IOperator
|
||||||
{
|
{
|
||||||
|
|
||||||
AbstractOperator(final int precedence, final boolean leftAssoc)
|
AbstractOperator(int precedence, boolean leftAssoc)
|
||||||
{
|
{
|
||||||
super(precedence, leftAssoc);
|
super(precedence, leftAssoc);
|
||||||
}
|
}
|
||||||
@@ -273,14 +273,14 @@ public abstract class Fluff
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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) -> {
|
return (c, typeIgnored) -> {
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return AbstractOperator.this.eval(v1.evalValue(c, Context.Type.NONE), v2.evalValue(c, Context.Type.NONE));
|
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);
|
throw Expression.handleCodeException(cc, exc, e, t);
|
||||||
}
|
}
|
||||||
@@ -290,7 +290,7 @@ public abstract class Fluff
|
|||||||
|
|
||||||
public abstract static class AbstractUnaryOperator extends AbstractOperator
|
public abstract static class AbstractUnaryOperator extends AbstractOperator
|
||||||
{
|
{
|
||||||
AbstractUnaryOperator(final int precedence, final boolean leftAssoc)
|
AbstractUnaryOperator(int precedence, boolean leftAssoc)
|
||||||
{
|
{
|
||||||
super(precedence, leftAssoc);
|
super(precedence, leftAssoc);
|
||||||
}
|
}
|
||||||
@@ -308,7 +308,7 @@ public abstract class Fluff
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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)
|
if (v2 != null)
|
||||||
{
|
{
|
||||||
@@ -319,7 +319,7 @@ public abstract class Fluff
|
|||||||
{
|
{
|
||||||
return AbstractUnaryOperator.this.evalUnary(v1.evalValue(c, Context.Type.NONE));
|
return AbstractUnaryOperator.this.evalUnary(v1.evalValue(c, Context.Type.NONE));
|
||||||
}
|
}
|
||||||
catch (final RuntimeException exc)
|
catch (RuntimeException exc)
|
||||||
{
|
{
|
||||||
throw Expression.handleCodeException(cc, exc, e, t);
|
throw Expression.handleCodeException(cc, exc, e, t);
|
||||||
}
|
}
|
||||||
@@ -327,7 +327,7 @@ public abstract class Fluff
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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");
|
throw new IllegalStateException("Shouldn't end up here");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,14 +13,14 @@ public interface LazyValue
|
|||||||
LazyValue NULL = (c, t) -> Value.NULL;
|
LazyValue NULL = (c, t) -> Value.NULL;
|
||||||
LazyValue ZERO = (c, t) -> Value.ZERO;
|
LazyValue ZERO = (c, t) -> Value.ZERO;
|
||||||
|
|
||||||
static LazyValue ofConstant(final Value val)
|
static LazyValue ofConstant(Value val)
|
||||||
{
|
{
|
||||||
return new Constant(val);
|
return new Constant(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
Value evalValue(Context c, Context.Type type);
|
Value evalValue(Context c, Context.Type type);
|
||||||
|
|
||||||
default Value evalValue(final Context c)
|
default Value evalValue(Context c)
|
||||||
{
|
{
|
||||||
return evalValue(c, Context.Type.NONE);
|
return evalValue(c, Context.Type.NONE);
|
||||||
}
|
}
|
||||||
@@ -32,7 +32,7 @@ public interface LazyValue
|
|||||||
Value evalType(Context.Type type);
|
Value evalType(Context.Type type);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
default Value evalValue(final Context c, final Context.Type type)
|
default Value evalValue(Context c, Context.Type type)
|
||||||
{
|
{
|
||||||
return evalType(type);
|
return evalType(type);
|
||||||
}
|
}
|
||||||
@@ -43,7 +43,7 @@ public interface LazyValue
|
|||||||
{
|
{
|
||||||
Value result;
|
Value result;
|
||||||
|
|
||||||
public Constant(final Value value)
|
public Constant(Value value)
|
||||||
{
|
{
|
||||||
result = value;
|
result = value;
|
||||||
}
|
}
|
||||||
@@ -54,14 +54,14 @@ public interface LazyValue
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Value evalType(final Context.Type type)
|
public Value evalType(Context.Type type)
|
||||||
{
|
{
|
||||||
|
|
||||||
return result.fromConstant();
|
return result.fromConstant();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Value evalValue(final Context c, final Context.Type type)
|
public Value evalValue(Context c, Context.Type type)
|
||||||
{
|
{
|
||||||
return result.fromConstant();
|
return result.fromConstant();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,16 +20,16 @@ public record Module(String name, String code, boolean library)
|
|||||||
Objects.requireNonNull(code);
|
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
|
try
|
||||||
{
|
{
|
||||||
final String name = path.getFileName().toString().replaceFirst("\\.scl?", "").toLowerCase(Locale.ROOT);
|
String name = path.getFileName().toString().replaceFirst("\\.scl?", "").toLowerCase(Locale.ROOT);
|
||||||
final String code = new String(Files.readAllBytes(path), StandardCharsets.UTF_8);
|
String code = new String(Files.readAllBytes(path), StandardCharsets.UTF_8);
|
||||||
return new Module(name, code, library);
|
return new Module(name, code, library);
|
||||||
}
|
}
|
||||||
catch (final IOException e)
|
catch (IOException e)
|
||||||
{
|
{
|
||||||
throw new IllegalArgumentException("Failed to load scarpet module", 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
|
* @param isLibrary A {@link boolean} indicating whether or not the script is a library
|
||||||
* @return The created {@link BundledModule}
|
* @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);
|
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}
|
* @return The created {@link BundledModule}
|
||||||
* @see #fromJarPathWithCustomName(String, String, boolean)
|
* @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);
|
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}
|
* @return The created {@link Module}
|
||||||
* @see #fromJarPath(String, String, boolean)
|
* @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
|
try
|
||||||
{
|
{
|
||||||
final String name = customName.toLowerCase(Locale.ROOT);
|
String name = customName.toLowerCase(Locale.ROOT);
|
||||||
final String code = IOUtils.toString(
|
String code = IOUtils.toString(
|
||||||
Module.class.getClassLoader().getResourceAsStream(fullPath),
|
Module.class.getClassLoader().getResourceAsStream(fullPath),
|
||||||
StandardCharsets.UTF_8
|
StandardCharsets.UTF_8
|
||||||
);
|
);
|
||||||
return new Module(name, code, isLibrary);
|
return new Module(name, code, isLibrary);
|
||||||
}
|
}
|
||||||
catch (final IOException e)
|
catch (IOException e)
|
||||||
{
|
{
|
||||||
throw new IllegalArgumentException("Failed to load bundled module", 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)))
|
if (dataFile == null || !Files.exists(dataFile) || !(Files.isRegularFile(dataFile)))
|
||||||
{
|
{
|
||||||
return null;
|
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)
|
if (dataFile == null)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@@ -113,7 +113,7 @@ public record Module(String name, String code, boolean library)
|
|||||||
{
|
{
|
||||||
Files.createDirectories(dataFile.getParent());
|
Files.createDirectories(dataFile.getParent());
|
||||||
}
|
}
|
||||||
catch (final IOException e)
|
catch (IOException e)
|
||||||
{
|
{
|
||||||
throw new IllegalStateException(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");
|
return module == null ? null : scriptServer.resolveResource(module.name() + ".data.nbt");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,22 +53,22 @@ public class ScriptCommand
|
|||||||
|
|
||||||
static
|
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());
|
scarpetFunctions = new TreeSet<>(Expression.none.getFunctionNames());
|
||||||
APIFunctions = allFunctions.stream().filter(s -> !scarpetFunctions.contains(s)).collect(Collectors.toCollection(TreeSet::new));
|
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("\\'", "");
|
previous = previous.replace("\\'", "");
|
||||||
final int quoteCount = StringUtils.countMatches(previous, '\'');
|
int quoteCount = StringUtils.countMatches(previous, '\'');
|
||||||
if (quoteCount % 2 == 1)
|
if (quoteCount % 2 == 1)
|
||||||
{
|
{
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
final int maxLen = prefix.length() < 3 ? (prefix.length() * 2 + 1) : 1234;
|
int maxLen = prefix.length() < 3 ? (prefix.length() * 2 + 1) : 1234;
|
||||||
final String eventPrefix = prefix.startsWith("__on_") ? prefix.substring(5) : null;
|
String eventPrefix = prefix.startsWith("__on_") ? prefix.substring(5) : null;
|
||||||
final List<String> scarpetMatches = scarpetFunctions.stream().
|
List<String> scarpetMatches = scarpetFunctions.stream().
|
||||||
filter(s -> s.startsWith(prefix) && s.length() <= maxLen).map(s -> s + "(").collect(Collectors.toList());
|
filter(s -> s.startsWith(prefix) && s.length() <= maxLen).map(s -> s + "(").collect(Collectors.toList());
|
||||||
scarpetMatches.addAll(APIFunctions.stream().
|
scarpetMatches.addAll(APIFunctions.stream().
|
||||||
filter(s -> s.startsWith(prefix) && s.length() <= maxLen).map(s -> s + "(").toList());
|
filter(s -> s.startsWith(prefix) && s.length() <= maxLen).map(s -> s + "(").toList());
|
||||||
@@ -84,17 +84,17 @@ public class ScriptCommand
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static CompletableFuture<Suggestions> suggestCode(
|
private static CompletableFuture<Suggestions> suggestCode(
|
||||||
final CommandContext<CommandSourceStack> context,
|
CommandContext<CommandSourceStack> context,
|
||||||
final SuggestionsBuilder suggestionsBuilder
|
SuggestionsBuilder suggestionsBuilder
|
||||||
) throws CommandSyntaxException
|
) throws CommandSyntaxException
|
||||||
{
|
{
|
||||||
final CarpetScriptHost currentHost = getHost(context);
|
CarpetScriptHost currentHost = getHost(context);
|
||||||
final String previous = suggestionsBuilder.getRemaining();
|
String previous = suggestionsBuilder.getRemaining();
|
||||||
final int strlen = previous.length();
|
int strlen = previous.length();
|
||||||
final StringBuilder lastToken = new StringBuilder();
|
StringBuilder lastToken = new StringBuilder();
|
||||||
for (int idx = strlen - 1; idx >= 0; idx--)
|
for (int idx = strlen - 1; idx >= 0; idx--)
|
||||||
{
|
{
|
||||||
final char ch = previous.charAt(idx);
|
char ch = previous.charAt(idx);
|
||||||
if (Character.isLetterOrDigit(ch) || ch == '_')
|
if (Character.isLetterOrDigit(ch) || ch == '_')
|
||||||
{
|
{
|
||||||
lastToken.append(ch);
|
lastToken.append(ch);
|
||||||
@@ -108,8 +108,8 @@ public class ScriptCommand
|
|||||||
{
|
{
|
||||||
return suggestionsBuilder.buildFuture();
|
return suggestionsBuilder.buildFuture();
|
||||||
}
|
}
|
||||||
final String prefix = lastToken.reverse().toString();
|
String prefix = lastToken.reverse().toString();
|
||||||
final String previousString = previous.substring(0, previous.length() - prefix.length());
|
String previousString = previous.substring(0, previous.length() - prefix.length());
|
||||||
suggestFunctions(currentHost, previousString, prefix).forEach(text -> suggestionsBuilder.suggest(previousString + text));
|
suggestFunctions(currentHost, previousString, prefix).forEach(text -> suggestionsBuilder.suggest(previousString + text));
|
||||||
return suggestionsBuilder.buildFuture();
|
return suggestionsBuilder.buildFuture();
|
||||||
}
|
}
|
||||||
@@ -119,18 +119,18 @@ public class ScriptCommand
|
|||||||
* variable.
|
* variable.
|
||||||
*/
|
*/
|
||||||
private static CompletableFuture<Suggestions> suggestDownloadableApps(
|
private static CompletableFuture<Suggestions> suggestDownloadableApps(
|
||||||
final CommandContext<CommandSourceStack> context,
|
CommandContext<CommandSourceStack> context,
|
||||||
final SuggestionsBuilder suggestionsBuilder
|
SuggestionsBuilder suggestionsBuilder
|
||||||
) throws CommandSyntaxException
|
) throws CommandSyntaxException
|
||||||
{
|
{
|
||||||
|
|
||||||
return CompletableFuture.supplyAsync(() -> {
|
return CompletableFuture.supplyAsync(() -> {
|
||||||
final String previous = suggestionsBuilder.getRemaining();
|
String previous = suggestionsBuilder.getRemaining();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
AppStoreManager.suggestionsFromPath(previous).forEach(suggestionsBuilder::suggest);
|
AppStoreManager.suggestionsFromPath(previous).forEach(suggestionsBuilder::suggest);
|
||||||
}
|
}
|
||||||
catch (final IOException e)
|
catch (IOException e)
|
||||||
{
|
{
|
||||||
CarpetScriptServer.LOG.warn("Exception when fetching app store structure", 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());
|
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)).
|
executes(context -> listGlobals(context, false)).
|
||||||
then(literal("all").executes(context -> listGlobals(context, true)));
|
then(literal("all").executes(context -> listGlobals(context, true)));
|
||||||
final LiteralArgumentBuilder<CommandSourceStack> o = literal("stop").
|
LiteralArgumentBuilder<CommandSourceStack> o = literal("stop").
|
||||||
executes((cc) -> {
|
executes((cc) -> {
|
||||||
ss(cc).stopAll = true;
|
ss(cc).stopAll = true;
|
||||||
return 1;
|
return 1;
|
||||||
});
|
});
|
||||||
final LiteralArgumentBuilder<CommandSourceStack> u = literal("resume").
|
LiteralArgumentBuilder<CommandSourceStack> u = literal("resume").
|
||||||
executes((cc) -> {
|
executes((cc) -> {
|
||||||
ss(cc).stopAll = false;
|
ss(cc).stopAll = false;
|
||||||
return 1;
|
return 1;
|
||||||
});
|
});
|
||||||
final LiteralArgumentBuilder<CommandSourceStack> l = literal("run").
|
LiteralArgumentBuilder<CommandSourceStack> l = literal("run").
|
||||||
requires(Vanilla::ServerPlayer_canScriptACE).
|
requires(Vanilla::ServerPlayer_canScriptACE).
|
||||||
then(argument("expr", StringArgumentType.greedyString()).suggests(ScriptCommand::suggestCode).
|
then(argument("expr", StringArgumentType.greedyString()).suggests(ScriptCommand::suggestCode).
|
||||||
executes((cc) -> compute(
|
executes((cc) -> compute(
|
||||||
cc,
|
cc,
|
||||||
StringArgumentType.getString(cc, "expr"))));
|
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)).
|
then(argument("call", StringArgumentType.word()).suggests((cc, bb) -> suggest(suggestFunctionCalls(cc), bb)).
|
||||||
executes((cc) -> invoke(
|
executes((cc) -> invoke(
|
||||||
cc,
|
cc,
|
||||||
@@ -181,7 +181,7 @@ public class ScriptCommand
|
|||||||
null,
|
null,
|
||||||
StringArgumentType.getString(cc, "arguments")
|
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("call", StringArgumentType.word()).suggests((cc, bb) -> suggest(suggestFunctionCalls(cc), bb)).
|
||||||
then(argument("origin", BlockPosArgument.blockPos()).
|
then(argument("origin", BlockPosArgument.blockPos()).
|
||||||
executes((cc) -> invoke(
|
executes((cc) -> invoke(
|
||||||
@@ -199,7 +199,7 @@ public class ScriptCommand
|
|||||||
null,
|
null,
|
||||||
StringArgumentType.getString(cc, "arguments")
|
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("call", StringArgumentType.word()).suggests((cc, bb) -> suggest(suggestFunctionCalls(cc), bb)).
|
||||||
then(argument("from", BlockPosArgument.blockPos()).
|
then(argument("from", BlockPosArgument.blockPos()).
|
||||||
then(argument("to", BlockPosArgument.blockPos()).
|
then(argument("to", BlockPosArgument.blockPos()).
|
||||||
@@ -218,7 +218,7 @@ public class ScriptCommand
|
|||||||
BlockPosArgument.getSpawnablePos(cc, "to"),
|
BlockPosArgument.getSpawnablePos(cc, "to"),
|
||||||
StringArgumentType.getString(cc, "arguments")
|
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("origin", BlockPosArgument.blockPos()).
|
||||||
then(argument("from", BlockPosArgument.blockPos()).
|
then(argument("from", BlockPosArgument.blockPos()).
|
||||||
then(argument("to", BlockPosArgument.blockPos()).
|
then(argument("to", BlockPosArgument.blockPos()).
|
||||||
@@ -231,7 +231,7 @@ public class ScriptCommand
|
|||||||
BlockPosArgument.getSpawnablePos(cc, "to"),
|
BlockPosArgument.getSpawnablePos(cc, "to"),
|
||||||
StringArgumentType.getString(cc, "expr")
|
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("origin", BlockPosArgument.blockPos()).
|
||||||
then(argument("from", BlockPosArgument.blockPos()).
|
then(argument("from", BlockPosArgument.blockPos()).
|
||||||
then(argument("to", BlockPosArgument.blockPos()).
|
then(argument("to", BlockPosArgument.blockPos()).
|
||||||
@@ -258,7 +258,7 @@ public class ScriptCommand
|
|||||||
BlockPredicateArgument.getBlockPredicate(cc, "filter"),
|
BlockPredicateArgument.getBlockPredicate(cc, "filter"),
|
||||||
"solid"
|
"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("origin", BlockPosArgument.blockPos()).
|
||||||
then(argument("from", BlockPosArgument.blockPos()).
|
then(argument("from", BlockPosArgument.blockPos()).
|
||||||
then(argument("to", BlockPosArgument.blockPos()).
|
then(argument("to", BlockPosArgument.blockPos()).
|
||||||
@@ -285,33 +285,33 @@ public class ScriptCommand
|
|||||||
BlockPredicateArgument.getBlockPredicate(cc, "filter"),
|
BlockPredicateArgument.getBlockPredicate(cc, "filter"),
|
||||||
"outline"
|
"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()).
|
then(argument("app", StringArgumentType.word()).
|
||||||
suggests((cc, bb) -> suggest(ss(cc).listAvailableModules(true), bb)).
|
suggests((cc, bb) -> suggest(ss(cc).listAvailableModules(true), bb)).
|
||||||
executes((cc) ->
|
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;
|
return success ? 1 : 0;
|
||||||
}).
|
}).
|
||||||
then(literal("global").
|
then(literal("global").
|
||||||
executes((cc) ->
|
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;
|
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()).
|
then(argument("app", StringArgumentType.word()).
|
||||||
suggests((cc, bb) -> suggest(ss(cc).unloadableModules, bb)).
|
suggests((cc, bb) -> suggest(ss(cc).unloadableModules, bb)).
|
||||||
executes((cc) ->
|
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;
|
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).
|
executes(ScriptCommand::listEvents).
|
||||||
then(literal("add_to").
|
then(literal("add_to").
|
||||||
then(argument("event", StringArgumentType.word()).
|
then(argument("event", StringArgumentType.word()).
|
||||||
@@ -346,16 +346,16 @@ public class ScriptCommand
|
|||||||
StringArgumentType.getString(cc, "call")
|
StringArgumentType.getString(cc, "call")
|
||||||
) ? 1 : 0))));
|
) ? 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()).
|
then(argument("path", StringArgumentType.greedyString()).
|
||||||
suggests(ScriptCommand::suggestDownloadableApps).
|
suggests(ScriptCommand::suggestDownloadableApps).
|
||||||
executes(cc -> AppStoreManager.downloadScript(cc.getSource(), StringArgumentType.getString(cc, "path"))));
|
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()).
|
then(argument("app", StringArgumentType.word()).
|
||||||
suggests((cc, bb) -> suggest(ss(cc).unloadableModules, bb)).
|
suggests((cc, bb) -> suggest(ss(cc).unloadableModules, bb)).
|
||||||
executes((cc) ->
|
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;
|
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))));
|
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;
|
CarpetScriptHost host;
|
||||||
final CarpetScriptServer scriptServer = ss(context);
|
CarpetScriptServer scriptServer = ss(context);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
final String name = StringArgumentType.getString(context, "app").toLowerCase(Locale.ROOT);
|
String name = StringArgumentType.getString(context, "app").toLowerCase(Locale.ROOT);
|
||||||
final CarpetScriptHost parentHost = scriptServer.modules.getOrDefault(name, scriptServer.globalHost);
|
CarpetScriptHost parentHost = scriptServer.modules.getOrDefault(name, scriptServer.globalHost);
|
||||||
host = parentHost.retrieveOwnForExecution(context.getSource());
|
host = parentHost.retrieveOwnForExecution(context.getSource());
|
||||||
}
|
}
|
||||||
catch (final IllegalArgumentException ignored)
|
catch (IllegalArgumentException ignored)
|
||||||
{
|
{
|
||||||
host = scriptServer.globalHost;
|
host = scriptServer.globalHost;
|
||||||
}
|
}
|
||||||
@@ -388,21 +388,21 @@ public class ScriptCommand
|
|||||||
return host;
|
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());
|
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);
|
CarpetScriptServer scriptServer = ss(context);
|
||||||
CommandSourceStack source = context.getSource();
|
CommandSourceStack source = context.getSource();
|
||||||
Carpet.Messenger_message(source, "w Lists ALL event handlers:");
|
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;
|
boolean shownEvent = false;
|
||||||
for (final CarpetEventServer.Callback c : event.handler.inspectCurrentCalls())
|
for (CarpetEventServer.Callback c : event.handler.inspectCurrentCalls())
|
||||||
{
|
{
|
||||||
if (!shownEvent)
|
if (!shownEvent)
|
||||||
{
|
{
|
||||||
@@ -415,26 +415,26 @@ public class ScriptCommand
|
|||||||
return 1;
|
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);
|
CarpetScriptHost host = getHost(context);
|
||||||
final CommandSourceStack source = context.getSource();
|
CommandSourceStack source = context.getSource();
|
||||||
final CarpetScriptServer scriptServer = ss(context);
|
CarpetScriptServer scriptServer = ss(context);
|
||||||
|
|
||||||
Carpet.Messenger_message(source, "lb Stored functions" + ((host == scriptServer.globalHost) ? ":" : " in " + host.getName() + ":"));
|
Carpet.Messenger_message(source, "lb Stored functions" + ((host == scriptServer.globalHost) ? ":" : " in " + host.getName() + ":"));
|
||||||
host.globalFunctionNames(host.main, (str) -> all || !str.startsWith("__")).sorted().forEach((s) -> {
|
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)
|
if (fun == null)
|
||||||
{
|
{
|
||||||
Carpet.Messenger_message(source, "gb " + s, "g - unused import");
|
Carpet.Messenger_message(source, "gb " + s, "g - unused import");
|
||||||
Carpet.Messenger_message(source, "gi ----------------");
|
Carpet.Messenger_message(source, "gi ----------------");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final Expression expr = fun.getExpression();
|
Expression expr = fun.getExpression();
|
||||||
final Tokenizer.Token tok = fun.getToken();
|
Tokenizer.Token tok = fun.getToken();
|
||||||
final List<String> snippet = expr.getExpressionSnippet(tok);
|
List<String> snippet = expr.getExpressionSnippet(tok);
|
||||||
Carpet.Messenger_message(source, "wb " + fun.fullName(), "t defined at: line " + (tok.lineno + 1) + " pos " + (tok.linepos + 1));
|
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);
|
Carpet.Messenger_message(source, "w " + snippetLine);
|
||||||
}
|
}
|
||||||
@@ -444,7 +444,7 @@ public class ScriptCommand
|
|||||||
Carpet.Messenger_message(source, "w ");
|
Carpet.Messenger_message(source, "w ");
|
||||||
Carpet.Messenger_message(source, "lb Global variables" + ((host == scriptServer.globalHost) ? ":" : " in " + host.getName() + ":"));
|
Carpet.Messenger_message(source, "lb Global variables" + ((host == scriptServer.globalHost) ? ":" : " in " + host.getName() + ":"));
|
||||||
host.globalVariableNames(host.main, (s) -> s.startsWith("global_")).sorted().forEach((s) -> {
|
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)
|
if (variable == null)
|
||||||
{
|
{
|
||||||
Carpet.Messenger_message(source, "gb " + s, "g - unused import");
|
Carpet.Messenger_message(source, "gb " + s, "g - unused import");
|
||||||
@@ -457,14 +457,14 @@ public class ScriptCommand
|
|||||||
return 1;
|
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
|
try
|
||||||
{
|
{
|
||||||
final Runnable token = Carpet.startProfilerSection("Scarpet run");
|
Runnable token = Carpet.startProfilerSection("Scarpet run");
|
||||||
host.setChatErrorSnooper(source);
|
host.setChatErrorSnooper(source);
|
||||||
final long start = System.nanoTime();
|
long start = System.nanoTime();
|
||||||
final Value result = call.get();
|
Value result = call.get();
|
||||||
long time = ((System.nanoTime() - start) / 1000);
|
long time = ((System.nanoTime() - start) / 1000);
|
||||||
String metric = "\u00B5s";
|
String metric = "\u00B5s";
|
||||||
if (time > 5000)
|
if (time > 5000)
|
||||||
@@ -478,19 +478,19 @@ public class ScriptCommand
|
|||||||
metric = "s";
|
metric = "s";
|
||||||
}
|
}
|
||||||
Carpet.Messenger_message(source, "wi = ", "wb " + result.getString(), "gi (" + time + metric + ")");
|
Carpet.Messenger_message(source, "wi = ", "wb " + result.getString(), "gi (" + time + metric + ")");
|
||||||
final int intres = (int) result.readInteger();
|
int intres = (int) result.readInteger();
|
||||||
token.run();
|
token.run();
|
||||||
return intres;
|
return intres;
|
||||||
}
|
}
|
||||||
catch (final CarpetExpressionException e)
|
catch (CarpetExpressionException e)
|
||||||
{
|
{
|
||||||
host.handleErrorWithStack("Error while evaluating expression", e);
|
host.handleErrorWithStack("Error while evaluating expression", e);
|
||||||
}
|
}
|
||||||
catch (final ArithmeticException ae)
|
catch (ArithmeticException ae)
|
||||||
{
|
{
|
||||||
host.handleErrorWithStack("Math doesn't compute", ae);
|
host.handleErrorWithStack("Math doesn't compute", ae);
|
||||||
}
|
}
|
||||||
catch (final StackOverflowError soe)
|
catch (StackOverflowError soe)
|
||||||
{
|
{
|
||||||
host.handleErrorWithStack("Your thoughts are too deep", 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
|
//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();
|
CommandSourceStack source = context.getSource();
|
||||||
final CarpetScriptHost host = getHost(context);
|
CarpetScriptHost host = getHost(context);
|
||||||
if (call.startsWith("__"))
|
if (call.startsWith("__"))
|
||||||
{
|
{
|
||||||
Carpet.Messenger_message(source, "r Hidden functions are only callable in scripts");
|
Carpet.Messenger_message(source, "r Hidden functions are only callable in scripts");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
final List<Integer> positions = new ArrayList<>();
|
List<Integer> positions = new ArrayList<>();
|
||||||
if (pos1 != null)
|
if (pos1 != null)
|
||||||
{
|
{
|
||||||
positions.add(pos1.getX());
|
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();
|
CommandSourceStack source = context.getSource();
|
||||||
final CarpetScriptHost host = getHost(context);
|
CarpetScriptHost host = getHost(context);
|
||||||
return handleCall(source, host, () -> {
|
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()));
|
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();
|
CommandSourceStack source = context.getSource();
|
||||||
final CarpetScriptHost host = getHost(context);
|
CarpetScriptHost host = getHost(context);
|
||||||
final BoundingBox area = BoundingBox.fromCorners(a, b);
|
BoundingBox area = BoundingBox.fromCorners(a, b);
|
||||||
final CarpetExpression cexpr = new CarpetExpression(host.main, expr, source, origin);
|
CarpetExpression cexpr = new CarpetExpression(host.main, expr, source, origin);
|
||||||
final int int_1 = area.getXSpan() * area.getYSpan() * area.getZSpan(); // X Y Z
|
int int_1 = area.getXSpan() * area.getYSpan() * area.getZSpan(); // X Y Z
|
||||||
if (int_1 > Vanilla.MinecraftServer_getFillLimit(source.getServer()) )
|
if (int_1 > Vanilla.MinecraftServer_getFillLimit(source.getServer()) )
|
||||||
{
|
{
|
||||||
Carpet.Messenger_message(source, "r too many blocks to evaluate: " + int_1);
|
Carpet.Messenger_message(source, "r too many blocks to evaluate: " + int_1);
|
||||||
@@ -565,14 +565,14 @@ public class ScriptCommand
|
|||||||
successCount++;
|
successCount++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (final ArithmeticException ignored)
|
catch (ArithmeticException ignored)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (final CarpetExpressionException exc)
|
catch (CarpetExpressionException exc)
|
||||||
{
|
{
|
||||||
host.handleErrorWithStack("Error while processing command", exc);
|
host.handleErrorWithStack("Error while processing command", exc);
|
||||||
return 0;
|
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,
|
private static int scriptFill(CommandContext<CommandSourceStack> context, BlockPos origin, BlockPos a, BlockPos b, String expr,
|
||||||
final BlockInput block, final Predicate<BlockInWorld> replacement, final String mode) throws CommandSyntaxException
|
BlockInput block, Predicate<BlockInWorld> replacement, String mode) throws CommandSyntaxException
|
||||||
{
|
{
|
||||||
final CommandSourceStack source = context.getSource();
|
CommandSourceStack source = context.getSource();
|
||||||
final CarpetScriptHost host = getHost(context);
|
CarpetScriptHost host = getHost(context);
|
||||||
final BoundingBox area = BoundingBox.fromCorners(a, b);
|
BoundingBox area = BoundingBox.fromCorners(a, b);
|
||||||
final CarpetExpression cexpr = new CarpetExpression(host.main, expr, source, origin);
|
CarpetExpression cexpr = new CarpetExpression(host.main, expr, source, origin);
|
||||||
final int int_1 = area.getXSpan() * area.getYSpan() * area.getZSpan();
|
int int_1 = area.getXSpan() * area.getYSpan() * area.getZSpan();
|
||||||
if (int_1 > Vanilla.MinecraftServer_getFillLimit(source.getServer()))
|
if (int_1 > Vanilla.MinecraftServer_getFillLimit(source.getServer()))
|
||||||
{
|
{
|
||||||
Carpet.Messenger_message(source, "r too many blocks to evaluate: " + int_1);
|
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
|
boolean[][][] volume = new boolean[area.getXSpan()][area.getYSpan()][area.getZSpan()]; //X then Y then Z got messedup
|
||||||
|
|
||||||
final BlockPos.MutableBlockPos mbpos = origin.mutable();
|
BlockPos.MutableBlockPos mbpos = origin.mutable();
|
||||||
final ServerLevel world = source.getLevel();
|
ServerLevel world = source.getLevel();
|
||||||
|
|
||||||
for (int x = area.minX(); x <= area.maxX(); x++)
|
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;
|
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);
|
host.handleErrorWithStack("Exception while filling the area", e);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
catch (final ArithmeticException e)
|
catch (ArithmeticException e)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
final int maxx = area.getXSpan() - 1;
|
int maxx = area.getXSpan() - 1;
|
||||||
final int maxy = area.getYSpan() - 1;
|
int maxy = area.getYSpan() - 1;
|
||||||
final int maxz = area.getZSpan() - 1;
|
int maxz = area.getZSpan() - 1;
|
||||||
if ("outline".equalsIgnoreCase(mode))
|
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 x = 0; x <= maxx; x++)
|
||||||
{
|
{
|
||||||
for (int y = 0; y <= maxy; y++)
|
for (int y = 0; y <= maxy; y++)
|
||||||
@@ -675,7 +675,7 @@ public class ScriptCommand
|
|||||||
if (replacement == null || replacement.test(
|
if (replacement == null || replacement.test(
|
||||||
new BlockInWorld(world, mbpos, true)))
|
new BlockInWorld(world, mbpos, true)))
|
||||||
{
|
{
|
||||||
final BlockEntity tileentity = world.getBlockEntity(mbpos);
|
BlockEntity tileentity = world.getBlockEntity(mbpos);
|
||||||
Clearable.tryClear(tileentity);
|
Clearable.tryClear(tileentity);
|
||||||
|
|
||||||
if (block.place(world, mbpos, 2))
|
if (block.place(world, mbpos, 2))
|
||||||
@@ -700,7 +700,7 @@ public class ScriptCommand
|
|||||||
if (volume[x][y][z])
|
if (volume[x][y][z])
|
||||||
{
|
{
|
||||||
mbpos.set(x + area.minX(), y + area.minY(), z + area.minZ());
|
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);
|
world.blockUpdated(mbpos, blokc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ public abstract class ScriptHost
|
|||||||
|
|
||||||
private final Set<String> deprecations = new HashSet<>();
|
private final Set<String> deprecations = new HashSet<>();
|
||||||
|
|
||||||
public Random getRandom(final long aLong)
|
public Random getRandom(long aLong)
|
||||||
{
|
{
|
||||||
if (randomizers.size() > 65536)
|
if (randomizers.size() > 65536)
|
||||||
{
|
{
|
||||||
@@ -48,12 +48,12 @@ public abstract class ScriptHost
|
|||||||
return randomizers.computeIfAbsent(aLong, Random::new);
|
return randomizers.computeIfAbsent(aLong, Random::new);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean resetRandom(final long aLong)
|
public boolean resetRandom(long aLong)
|
||||||
{
|
{
|
||||||
return randomizers.remove(aLong) != null;
|
return randomizers.remove(aLong) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Path resolveScriptFile(final String suffix)
|
public Path resolveScriptFile(String suffix)
|
||||||
{
|
{
|
||||||
return scriptServer.resolveResource(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> globalsImports = new Object2ObjectOpenHashMap<>(); // imported global variables string to module
|
||||||
public final Map<String, ModuleData> futureImports = new Object2ObjectOpenHashMap<>(); // imports not known before used
|
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();
|
super();
|
||||||
// imports are just pointers, but they still point to the wrong modules (point to the parent)
|
// 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);
|
globalFunctions.putAll(other.globalFunctions);
|
||||||
other.globalVariables.forEach((key, value) ->
|
other.globalVariables.forEach((key, value) ->
|
||||||
{
|
{
|
||||||
final Value var = value.evalValue(null);
|
Value var = value.evalValue(null);
|
||||||
final Value copy = var.deepcopy();
|
Value copy = var.deepcopy();
|
||||||
copy.boundVariable = var.boundVariable;
|
copy.boundVariable = var.boundVariable;
|
||||||
globalVariables.put(key, (c, t) -> copy);
|
globalVariables.put(key, (c, t) -> copy);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setImportsBasedOn(final ScriptHost host, final ModuleData other)
|
public void setImportsBasedOn(ScriptHost host, ModuleData other)
|
||||||
{
|
{
|
||||||
// fixing imports
|
// fixing imports
|
||||||
other.functionImports.forEach((name, targetData) -> {
|
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;
|
this.parent = parent;
|
||||||
}
|
}
|
||||||
@@ -126,7 +126,7 @@ public abstract class ScriptHost
|
|||||||
|
|
||||||
public ErrorSnooper errorSnooper = null;
|
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.parent = parent;
|
||||||
this.main = code;
|
this.main = code;
|
||||||
@@ -134,30 +134,30 @@ public abstract class ScriptHost
|
|||||||
this.user = null;
|
this.user = null;
|
||||||
this.strict = false;
|
this.strict = false;
|
||||||
this.scriptServer = scriptServer;
|
this.scriptServer = scriptServer;
|
||||||
final ModuleData moduleData = new ModuleData(code);
|
ModuleData moduleData = new ModuleData(code);
|
||||||
initializeModuleGlobals(moduleData);
|
initializeModuleGlobals(moduleData);
|
||||||
this.moduleData.put(code, moduleData);
|
this.moduleData.put(code, moduleData);
|
||||||
this.modules.put(code == null ? null : code.name(), code);
|
this.modules.put(code == null ? null : code.name(), code);
|
||||||
mainThread = Thread.currentThread();
|
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)))
|
if (modules.containsKey(moduleName.toLowerCase(Locale.ROOT)))
|
||||||
{
|
{
|
||||||
return; // aready imported
|
return; // aready imported
|
||||||
}
|
}
|
||||||
final Module module = getModuleOrLibraryByName(moduleName);
|
Module module = getModuleOrLibraryByName(moduleName);
|
||||||
if (modules.containsKey(module.name()))
|
if (modules.containsKey(module.name()))
|
||||||
{
|
{
|
||||||
return; // aready imported, once again, in case some discrepancies in names?
|
return; // aready imported, once again, in case some discrepancies in names?
|
||||||
}
|
}
|
||||||
modules.put(module.name(), module);
|
modules.put(module.name(), module);
|
||||||
final ModuleData data = new ModuleData(module);
|
ModuleData data = new ModuleData(module);
|
||||||
initializeModuleGlobals(data);
|
initializeModuleGlobals(data);
|
||||||
moduleData.put(module, data);
|
moduleData.put(module, data);
|
||||||
runModuleCode(c, module);
|
runModuleCode(c, module);
|
||||||
@@ -166,20 +166,20 @@ public abstract class ScriptHost
|
|||||||
//throw new InternalExpressionException("Failed to import a module "+moduleName);
|
//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))
|
if (!moduleData.containsKey(targetModule))
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("Cannot import to module that doesn't exist");
|
throw new InternalExpressionException("Cannot import to module that doesn't exist");
|
||||||
}
|
}
|
||||||
final Module source = modules.get(sourceModuleName);
|
Module source = modules.get(sourceModuleName);
|
||||||
final ModuleData sourceData = moduleData.get(source);
|
ModuleData sourceData = moduleData.get(source);
|
||||||
final ModuleData targetData = moduleData.get(targetModule);
|
ModuleData targetData = moduleData.get(targetModule);
|
||||||
if (sourceData == null || targetData == null)
|
if (sourceData == null || targetData == null)
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("Cannot import from module that is not imported");
|
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))
|
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);
|
Module source = modules.get(moduleName);
|
||||||
final ModuleData sourceData = moduleData.get(source);
|
ModuleData sourceData = moduleData.get(source);
|
||||||
if (sourceData == null)
|
if (sourceData == null)
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("Cannot import from module that is not imported");
|
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
|
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);
|
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 (ret == null)
|
||||||
{
|
{
|
||||||
if (module == main)
|
if (module == main)
|
||||||
@@ -236,9 +236,9 @@ public abstract class ScriptHost
|
|||||||
return ret;
|
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
|
FunctionValue ret = local.globalFunctions.get(name); // most uses would be from local scope anyways
|
||||||
if (ret != null)
|
if (ret != null)
|
||||||
{
|
{
|
||||||
@@ -269,7 +269,7 @@ public abstract class ScriptHost
|
|||||||
return target.globalFunctions.get(name);
|
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)
|
if (ttl > 64)
|
||||||
{
|
{
|
||||||
@@ -290,14 +290,14 @@ public abstract class ScriptHost
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LazyValue getGlobalVariable(final String name)
|
public LazyValue getGlobalVariable(String name)
|
||||||
{
|
{
|
||||||
return getGlobalVariable(main, 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
|
LazyValue ret = local.globalVariables.get(name); // most uses would be from local scope anyways
|
||||||
if (ret != null)
|
if (ret != null)
|
||||||
{
|
{
|
||||||
@@ -328,7 +328,7 @@ public abstract class ScriptHost
|
|||||||
return target.globalVariables.get(name);
|
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)
|
if (ttl > 64)
|
||||||
{
|
{
|
||||||
@@ -349,37 +349,37 @@ public abstract class ScriptHost
|
|||||||
return null;
|
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.globalFunctions.entrySet().removeIf(e -> e.getKey().startsWith(prefix));
|
||||||
data.functionImports.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.globalFunctions.remove(funName);
|
||||||
data.functionImports.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.globalVariables.entrySet().removeIf(e -> e.getKey().startsWith(prefix));
|
||||||
data.globalsImports.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.globalFunctions.remove(varName);
|
||||||
data.functionImports.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)
|
if (data == null)
|
||||||
{
|
{
|
||||||
throw new IntegrityException("Module structure changed for the app. Did you reload the app with tasks running?");
|
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;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void assertAppIntegrity(final Module module)
|
protected void assertAppIntegrity(Module module)
|
||||||
{
|
{
|
||||||
getModuleData(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);
|
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);
|
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(
|
return Stream.concat(Stream.concat(
|
||||||
getModuleData(module).globalVariables.keySet().stream(),
|
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);
|
), 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(
|
return Stream.concat(Stream.concat(
|
||||||
getModuleData(module).globalFunctions.keySet().stream(),
|
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);
|
), 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)
|
if (!perUser)
|
||||||
{
|
{
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
final ScriptHost oldUserHost = userHosts.get(user);
|
ScriptHost oldUserHost = userHosts.get(user);
|
||||||
if (oldUserHost != null)
|
if (oldUserHost != null)
|
||||||
{
|
{
|
||||||
return oldUserHost;
|
return oldUserHost;
|
||||||
}
|
}
|
||||||
final ScriptHost userHost = this.duplicate();
|
ScriptHost userHost = this.duplicate();
|
||||||
userHost.user = user;
|
userHost.user = user;
|
||||||
this.setupUserHost(userHost);
|
this.setupUserHost(userHost);
|
||||||
userHosts.put(user, userHost);
|
userHosts.put(user, userHost);
|
||||||
return userHost;
|
return userHost;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void setupUserHost(final ScriptHost host)
|
protected void setupUserHost(ScriptHost host)
|
||||||
{
|
{
|
||||||
// adding imports
|
// adding imports
|
||||||
host.modules.putAll(this.modules);
|
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)));
|
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);
|
System.out.println(msg + ": " + exc);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract ScriptHost duplicate();
|
protected abstract ScriptHost duplicate();
|
||||||
|
|
||||||
public Object getLock(final Value name)
|
public Object getLock(Value name)
|
||||||
{
|
{
|
||||||
return locks.computeIfAbsent(name, n -> new Object());
|
return locks.computeIfAbsent(name, n -> new Object());
|
||||||
}
|
}
|
||||||
|
|
||||||
public ThreadPoolExecutor getExecutor(final Value pool)
|
public ThreadPoolExecutor getExecutor(Value pool)
|
||||||
{
|
{
|
||||||
if (inTermination)
|
if (inTermination)
|
||||||
{
|
{
|
||||||
@@ -471,7 +471,7 @@ public abstract class ScriptHost
|
|||||||
return executorServices.values().stream().map(ThreadPoolExecutor::getActiveCount).reduce(0, Integer::sum);
|
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;
|
return executorServices.containsKey(pool) ? executorServices.get(pool).getActiveCount() : 0;
|
||||||
}
|
}
|
||||||
@@ -480,14 +480,14 @@ public abstract class ScriptHost
|
|||||||
{
|
{
|
||||||
inTermination = true;
|
inTermination = true;
|
||||||
executorServices.values().forEach(ThreadPoolExecutor::shutdown);
|
executorServices.values().forEach(ThreadPoolExecutor::shutdown);
|
||||||
for (final ScriptHost uh : userHosts.values())
|
for (ScriptHost uh : userHosts.values())
|
||||||
{
|
{
|
||||||
uh.onClose();
|
uh.onClose();
|
||||||
}
|
}
|
||||||
if (taskCount() > 0)
|
if (taskCount() > 0)
|
||||||
{
|
{
|
||||||
executorServices.values().forEach(e -> {
|
executorServices.values().forEach(e -> {
|
||||||
final ExecutorService stopper = Executors.newSingleThreadExecutor();
|
ExecutorService stopper = Executors.newSingleThreadExecutor();
|
||||||
stopper.submit(() -> {
|
stopper.submit(() -> {
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -502,7 +502,7 @@ public abstract class ScriptHost
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (final InterruptedException ie)
|
catch (InterruptedException ie)
|
||||||
{
|
{
|
||||||
// (Re-)Cancel if current thread also interrupted
|
// (Re-)Cancel if current thread also interrupted
|
||||||
e.shutdownNow();
|
e.shutdownNow();
|
||||||
@@ -516,7 +516,7 @@ public abstract class ScriptHost
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPerPlayer(final boolean isPerUser)
|
public void setPerPlayer(boolean isPerUser)
|
||||||
{
|
{
|
||||||
perUser = isPerUser;
|
perUser = isPerUser;
|
||||||
}
|
}
|
||||||
@@ -539,7 +539,7 @@ public abstract class ScriptHost
|
|||||||
|
|
||||||
public static final Logger DEPRECATION_LOG = LoggerFactory.getLogger("Scarpet Deprecation Warnings");
|
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))
|
if (deprecations.contains(feature))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -11,5 +11,5 @@ public abstract class ScriptServer
|
|||||||
{
|
{
|
||||||
public final Map<Value, Value> systemGlobals = new ConcurrentHashMap<>();
|
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 Expression expression;
|
||||||
private final Context context;
|
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.input = input;
|
||||||
this.expression = expr;
|
this.expression = expr;
|
||||||
@@ -55,13 +55,13 @@ public class Tokenizer implements Iterator<Tokenizer.Token>
|
|||||||
|
|
||||||
public List<Token> postProcess()
|
public List<Token> postProcess()
|
||||||
{
|
{
|
||||||
final Iterable<Token> iterable = () -> this;
|
Iterable<Token> iterable = () -> this;
|
||||||
final List<Token> originalTokens = StreamSupport.stream(iterable.spliterator(), false).collect(Collectors.toList());
|
List<Token> originalTokens = StreamSupport.stream(iterable.spliterator(), false).collect(Collectors.toList());
|
||||||
final List<Token> cleanedTokens = new ArrayList<>();
|
List<Token> cleanedTokens = new ArrayList<>();
|
||||||
Token last = null;
|
Token last = null;
|
||||||
while (!originalTokens.isEmpty())
|
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("//"))
|
if (current.type == Token.TokenType.MARKER && current.surface.startsWith("//"))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
@@ -120,22 +120,22 @@ public class Tokenizer implements Iterator<Tokenizer.Token>
|
|||||||
return (pos < (input.length() - 1)) ? input.charAt(pos + 1) : 0;
|
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')
|
return ch == 'x' || ch == 'X' || (ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'f')
|
||||||
|| (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(";"))
|
return (tok.type == Token.TokenType.OPERATOR && tok.surface.equals(";"))
|
||||||
|| (tok.type == Token.TokenType.UNARY_OPERATOR && tok.surface.equals(";u"));
|
|| (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);
|
Tokenizer tok = new Tokenizer(null, null, input, false, false);
|
||||||
final List<Token> res = new ArrayList<>();
|
List<Token> res = new ArrayList<>();
|
||||||
while (tok.hasNext())
|
while (tok.hasNext())
|
||||||
{
|
{
|
||||||
res.add(tok.next());
|
res.add(tok.next());
|
||||||
@@ -146,7 +146,7 @@ public class Tokenizer implements Iterator<Tokenizer.Token>
|
|||||||
@Override
|
@Override
|
||||||
public Token next()
|
public Token next()
|
||||||
{
|
{
|
||||||
final Token token = new Token();
|
Token token = new Token();
|
||||||
|
|
||||||
if (pos >= input.length())
|
if (pos >= input.length())
|
||||||
{
|
{
|
||||||
@@ -208,7 +208,7 @@ public class Tokenizer implements Iterator<Tokenizer.Token>
|
|||||||
{
|
{
|
||||||
if (ch == '\\')
|
if (ch == '\\')
|
||||||
{
|
{
|
||||||
final char nextChar = peekNextChar();
|
char nextChar = peekNextChar();
|
||||||
if (nextChar == 'n')
|
if (nextChar == 'n')
|
||||||
{
|
{
|
||||||
token.append('\n');
|
token.append('\n');
|
||||||
@@ -324,8 +324,8 @@ public class Tokenizer implements Iterator<Tokenizer.Token>
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
String greedyMatch = "";
|
String greedyMatch = "";
|
||||||
final int initialPos = pos;
|
int initialPos = pos;
|
||||||
final int initialLinePos = linepos;
|
int initialLinePos = linepos;
|
||||||
ch = input.charAt(pos);
|
ch = input.charAt(pos);
|
||||||
int validOperatorSeenUntil = -1;
|
int validOperatorSeenUntil = -1;
|
||||||
while (!Character.isLetter(ch) && !Character.isDigit(ch) && "_".indexOf(ch) < 0
|
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 functional;
|
||||||
final boolean constant;
|
final boolean constant;
|
||||||
|
|
||||||
TokenType(final boolean functional, final boolean constant)
|
TokenType(boolean functional, boolean constant)
|
||||||
{
|
{
|
||||||
this.functional = functional;
|
this.functional = functional;
|
||||||
this.constant = constant;
|
this.constant = constant;
|
||||||
@@ -457,9 +457,9 @@ public class Tokenizer implements Iterator<Tokenizer.Token>
|
|||||||
public int lineno;
|
public int lineno;
|
||||||
public static final Token NONE = new Token();
|
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.surface = newSurface;
|
||||||
created.type = newType;
|
created.type = newType;
|
||||||
created.pos = pos;
|
created.pos = pos;
|
||||||
@@ -468,23 +468,23 @@ public class Tokenizer implements Iterator<Tokenizer.Token>
|
|||||||
return created;
|
return created;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void morph(final TokenType type, final String s)
|
public void morph(TokenType type, String s)
|
||||||
{
|
{
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.surface = s;
|
this.surface = s;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void append(final char c)
|
public void append(char c)
|
||||||
{
|
{
|
||||||
surface += c;
|
surface += c;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void append(final String s)
|
public void append(String s)
|
||||||
{
|
{
|
||||||
surface += s;
|
surface += s;
|
||||||
}
|
}
|
||||||
|
|
||||||
public char charAt(final int pos)
|
public char charAt(int pos)
|
||||||
{
|
{
|
||||||
return surface.charAt(pos);
|
return surface.charAt(pos);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -104,10 +104,10 @@ public final class AnnotationParser
|
|||||||
* @see ScarpetFunction
|
* @see ScarpetFunction
|
||||||
* @param clazz The class to parse
|
* @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
|
// 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()))
|
if (Modifier.isAbstract(clazz.getModifiers()))
|
||||||
{
|
{
|
||||||
throw new IllegalArgumentException("Function class must be concrete to support non-static methods! Class: " + clazz.getSimpleName());
|
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();
|
return clazz.getConstructor().newInstance();
|
||||||
}
|
}
|
||||||
catch (final ReflectiveOperationException e)
|
catch (ReflectiveOperationException e)
|
||||||
{
|
{
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
"Couldn't create instance of given " + clazz + ". This is needed for non-static methods. Make sure default constructor is available", e);
|
"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();
|
Method[] methodz = clazz.getDeclaredMethods();
|
||||||
for (final Method method : methodz)
|
for (Method method : methodz)
|
||||||
{
|
{
|
||||||
if (!method.isAnnotationPresent(ScarpetFunction.class))
|
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");
|
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);
|
functionList.add(function);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -146,9 +146,9 @@ public final class AnnotationParser
|
|||||||
*
|
*
|
||||||
* @param expr The expression to add every function to
|
* @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);
|
expr.addLazyFunction(function.name, function.scarpetParamCount, function);
|
||||||
}
|
}
|
||||||
@@ -171,52 +171,52 @@ public final class AnnotationParser
|
|||||||
private final int scarpetParamCount;
|
private final int scarpetParamCount;
|
||||||
private final Context.Type contextType;
|
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.name = method.getName();
|
||||||
this.isMethodVarArgs = method.isVarArgs();
|
this.isMethodVarArgs = method.isVarArgs();
|
||||||
this.methodParamCount = method.getParameterCount();
|
this.methodParamCount = method.getParameterCount();
|
||||||
|
|
||||||
final Parameter[] methodParameters = method.getParameters();
|
Parameter[] methodParameters = method.getParameters();
|
||||||
this.valueConverters = new ValueConverter[isMethodVarArgs ? methodParamCount - 1 : methodParamCount];
|
this.valueConverters = new ValueConverter[isMethodVarArgs ? methodParamCount - 1 : methodParamCount];
|
||||||
for (int i = 0; i < this.methodParamCount; i++)
|
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
|
if (!isMethodVarArgs || i != this.methodParamCount - 1) // Varargs converter is separate
|
||||||
{
|
{
|
||||||
this.valueConverters[i] = ValueConverter.fromAnnotatedType(param.getAnnotatedType());
|
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.varArgsType = ClassUtils.primitiveToWrapper(originalVarArgsType); // Primitive array cannot be cast to Obj[]
|
||||||
this.primitiveVarArgs = originalVarArgsType != null && originalVarArgsType.isPrimitive();
|
this.primitiveVarArgs = originalVarArgsType != null && originalVarArgsType.isPrimitive();
|
||||||
this.varArgsConverter = isMethodVarArgs ? ValueConverter.fromAnnotatedType(methodParameters[methodParamCount - 1].getAnnotatedType()) : null;
|
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());
|
OutputConverter<Object> converter = OutputConverter.get((Class<Object>) method.getReturnType());
|
||||||
this.outputConverter = converter;
|
this.outputConverter = converter;
|
||||||
|
|
||||||
this.isEffectivelyVarArgs = isMethodVarArgs || Arrays.stream(valueConverters).anyMatch(ValueConverter::consumesVariableArgs);
|
this.isEffectivelyVarArgs = isMethodVarArgs || Arrays.stream(valueConverters).anyMatch(ValueConverter::consumesVariableArgs);
|
||||||
this.minParams = Arrays.stream(valueConverters).mapToInt(ValueConverter::valueConsumption).sum(); // Note: In !varargs, this is params
|
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)
|
if (this.isEffectivelyVarArgs)
|
||||||
{
|
{
|
||||||
maxParams = method.getAnnotation(ScarpetFunction.class).maxParams();
|
setMaxParams = method.getAnnotation(ScarpetFunction.class).maxParams();
|
||||||
if (maxParams == UNDEFINED_PARAMS)
|
if (setMaxParams == UNDEFINED_PARAMS)
|
||||||
{
|
{
|
||||||
throw new IllegalArgumentException("No maximum number of params specified for " + name + ", use ScarpetFunction.UNLIMITED_PARAMS for unlimited. "
|
throw new IllegalArgumentException("No maximum number of params specified for " + name + ", use ScarpetFunction.UNLIMITED_PARAMS for unlimited. "
|
||||||
+ "Provided in " + originClass);
|
+ "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."
|
throw new IllegalArgumentException("Provided maximum number of params for " + name + " is smaller than method's param count."
|
||||||
+ "Provided in " + originClass);
|
+ "Provided in " + originClass);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.maxParams = maxParams;
|
this.maxParams = setMaxParams;
|
||||||
|
|
||||||
// Why MethodHandles?
|
// Why MethodHandles?
|
||||||
// MethodHandles are blazing fast (in some situations they can even compile to a single invokeVirtual), but slightly complex to work with.
|
// 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
|
@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 (isEffectivelyVarArgs)
|
||||||
{
|
{
|
||||||
if (lv.size() < minParams)
|
if (lv.size() < minParams)
|
||||||
@@ -258,12 +258,12 @@ public final class AnnotationParser
|
|||||||
+ getUsage());
|
+ getUsage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
final Object[] params = getMethodParams(lv, context, t);
|
Object[] params = getMethodParams(lv, context, t);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return outputConverter.convert(handle.invokeExact(params));
|
return outputConverter.convert(handle.invokeExact(params));
|
||||||
}
|
}
|
||||||
catch (final Throwable e)
|
catch (Throwable e)
|
||||||
{
|
{
|
||||||
if (e instanceof RuntimeException re)
|
if (e instanceof RuntimeException re)
|
||||||
{
|
{
|
||||||
@@ -274,12 +274,12 @@ public final class AnnotationParser
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Hot code: Must be optimized
|
// 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];
|
Object[] params = new Object[methodParamCount];
|
||||||
final ListIterator<Value> lvIterator = lv.listIterator();
|
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++)
|
for (int i = 0; i < regularArgs; i++)
|
||||||
{
|
{
|
||||||
params[i] = valueConverters[i].checkAndConvert(lvIterator, context, theLazyT);
|
params[i] = valueConverters[i].checkAndConvert(lvIterator, context, theLazyT);
|
||||||
@@ -290,14 +290,14 @@ public final class AnnotationParser
|
|||||||
}
|
}
|
||||||
if (isMethodVarArgs)
|
if (isMethodVarArgs)
|
||||||
{
|
{
|
||||||
final int remaining = lv.size() - lvIterator.nextIndex();
|
int remaining = lv.size() - lvIterator.nextIndex();
|
||||||
final Object[] varArgs;
|
Object[] varArgs;
|
||||||
if (varArgsConverter.consumesVariableArgs())
|
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())
|
while (lvIterator.hasNext())
|
||||||
{
|
{
|
||||||
final Object obj = varArgsConverter.checkAndConvert(lvIterator, context, theLazyT);
|
Object obj = varArgsConverter.checkAndConvert(lvIterator, context, theLazyT);
|
||||||
if (obj == null)
|
if (obj == null)
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("Incorrect argument passsed to '" + name + "' function.\n" + getUsage());
|
throw new InternalExpressionException("Incorrect argument passsed to '" + name + "' function.\n" + getUsage());
|
||||||
@@ -326,7 +326,7 @@ public final class AnnotationParser
|
|||||||
public String getUsage()
|
public String getUsage()
|
||||||
{
|
{
|
||||||
// Possibility: More descriptive messages using param.getName()? Would need changing gradle setup to keep those
|
// 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(name);
|
||||||
builder.append('(');
|
builder.append('(');
|
||||||
builder.append(Arrays.stream(valueConverters).map(ValueConverter::getTypeName).filter(Objects::nonNull).collect(Collectors.joining(", ")));
|
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.ListValue;
|
||||||
import carpet.script.value.Value;
|
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>
|
* <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";
|
return (allowSingletonCreation ? itemConverter.getTypeName() + " or " : "") + "list of " + itemConverter.getTypeName() + "s";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
@Override
|
@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;
|
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());
|
List<T> list = new ArrayList<>(values.getItems().size());
|
||||||
for (final Value value : values)
|
for (Value value : values)
|
||||||
{
|
{
|
||||||
final T converted = itemConverter.convert(value, context);
|
T converted = itemConverter.convert(value, context);
|
||||||
if (converted == null)
|
if (converted == null)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
@@ -53,9 +57,10 @@ final class ListConverter<T> implements ValueConverter<List<T>>
|
|||||||
return list;
|
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)
|
if (converted == null)
|
||||||
{
|
{
|
||||||
return 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);
|
itemConverter = ValueConverter.fromAnnotatedType(itemType);
|
||||||
this.allowSingletonCreation = allowSingletonCreation;
|
this.allowSingletonCreation = allowSingletonCreation;
|
||||||
@@ -84,11 +89,11 @@ final class ListConverter<T> implements ValueConverter<List<T>>
|
|||||||
* @param annotatedType The type to get generics information from
|
* @param annotatedType The type to get generics information from
|
||||||
* @return A new {@link ListConverter} for the data specified in the {@link AnnotatedType}
|
* @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;
|
AnnotatedParameterizedType paramType = (AnnotatedParameterizedType) annotatedType;
|
||||||
final AnnotatedType itemType = paramType.getAnnotatedActualTypeArguments()[0];
|
AnnotatedType itemType = paramType.getAnnotatedActualTypeArguments()[0];
|
||||||
final boolean allowSingletonCreation = annotatedType.isAnnotationPresent(Param.AllowSingleton.class);
|
boolean allowSingletonCreation = annotatedType.isAnnotationPresent(Param.AllowSingleton.class);
|
||||||
return new ListConverter<>(itemType, allowSingletonCreation);
|
return new ListConverter<>(itemType, allowSingletonCreation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,8 @@ import carpet.script.value.BlockValue;
|
|||||||
import carpet.script.value.FunctionValue;
|
import carpet.script.value.FunctionValue;
|
||||||
import carpet.script.value.Value;
|
import carpet.script.value.Value;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
import static java.lang.annotation.ElementType.PARAMETER;
|
import static java.lang.annotation.ElementType.PARAMETER;
|
||||||
import static java.lang.annotation.ElementType.TYPE_USE;
|
import static java.lang.annotation.ElementType.TYPE_USE;
|
||||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||||
@@ -122,7 +124,7 @@ public interface Locator
|
|||||||
super();
|
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))
|
if (annoType.isAnnotationPresent(Block.class))
|
||||||
{
|
{
|
||||||
@@ -146,7 +148,7 @@ public interface Locator
|
|||||||
private final boolean anyString;
|
private final boolean anyString;
|
||||||
private final boolean optional;
|
private final boolean optional;
|
||||||
|
|
||||||
public BlockLocator(final Block annotation, final Class<R> type)
|
public BlockLocator(Block annotation, Class<R> type)
|
||||||
{
|
{
|
||||||
super();
|
super();
|
||||||
this.acceptString = annotation.acceptString();
|
this.acceptString = annotation.acceptString();
|
||||||
@@ -163,8 +165,9 @@ public interface Locator
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
@SuppressWarnings("unchecked")
|
@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)
|
if (type == BlockArgument.class)
|
||||||
{
|
{
|
||||||
@@ -192,9 +195,9 @@ public interface Locator
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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);
|
return returnFunction.apply(locator);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -205,7 +208,7 @@ public interface Locator
|
|||||||
private final boolean optionalEntity;
|
private final boolean optionalEntity;
|
||||||
private final boolean returnVec3d;
|
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.optionalDirection = annotation.optionalDirection();
|
||||||
this.optionalEntity = annotation.optionalEntity();
|
this.optionalEntity = annotation.optionalEntity();
|
||||||
@@ -227,10 +230,10 @@ public interface Locator
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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);
|
Vector3Argument locator = Vector3Argument.findIn(valueIterator, 0, optionalDirection, optionalEntity);
|
||||||
@SuppressWarnings("unchecked") final R ret = (R) (returnVec3d ? locator.vec : locator);
|
@SuppressWarnings("unchecked") R ret = (R) (returnVec3d ? locator.vec : locator);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -241,7 +244,7 @@ public interface Locator
|
|||||||
private final boolean allowNone;
|
private final boolean allowNone;
|
||||||
private final boolean checkArgs;
|
private final boolean checkArgs;
|
||||||
|
|
||||||
FunctionLocator(final Function annotation, final Class<R> type)
|
FunctionLocator(Function annotation, Class<R> type)
|
||||||
{
|
{
|
||||||
super();
|
super();
|
||||||
this.returnFunctionValue = type == FunctionValue.class;
|
this.returnFunctionValue = type == FunctionValue.class;
|
||||||
@@ -258,11 +261,11 @@ public interface Locator
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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;
|
Module module = context.host.main;
|
||||||
final FunctionArgument locator = FunctionArgument.findIn(context, module, Lists.newArrayList(valueIterator), 0, allowNone, checkArgs);
|
FunctionArgument locator = FunctionArgument.findIn(context, module, Lists.newArrayList(valueIterator), 0, allowNone, checkArgs);
|
||||||
@SuppressWarnings("unchecked") final R ret = (R) (returnFunctionValue ? locator.function : locator);
|
@SuppressWarnings("unchecked") R ret = (R) (returnFunctionValue ? locator.function : locator);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -276,7 +279,7 @@ public interface Locator
|
|||||||
private abstract static class AbstractLocator<R> implements ValueConverter<R>, Locator
|
private abstract static class AbstractLocator<R> implements ValueConverter<R>, Locator
|
||||||
{
|
{
|
||||||
@Override
|
@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!");
|
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.MapValue;
|
||||||
import carpet.script.value.Value;
|
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>
|
* <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
|
@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)
|
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);
|
K key = keyConverter.convert(entry.getKey(), context);
|
||||||
final V val = valueConverter.convert(entry.getValue(), context);
|
V val = valueConverter.convert(entry.getValue(), context);
|
||||||
if (key == null || val == null)
|
if (key == null || val == null)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
@@ -57,7 +59,7 @@ class MapConverter<K, V> implements ValueConverter<Map<K, V>>
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private MapConverter(final AnnotatedType keyType, final AnnotatedType valueType)
|
private MapConverter(AnnotatedType keyType, AnnotatedType valueType)
|
||||||
{
|
{
|
||||||
super();
|
super();
|
||||||
keyConverter = ValueConverter.fromAnnotatedType(keyType);
|
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
|
* @param annotatedType The type to get generics information from
|
||||||
* @return A new {@link MapConverter} for the data specified in the {@link AnnotatedType}
|
* @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)
|
return annotatedType.isAnnotationPresent(Param.KeyValuePairs.class)
|
||||||
? new PairConverter<>(annotatedGenerics[0], annotatedGenerics[1], annotatedType.getAnnotation(Param.KeyValuePairs.class))
|
? new PairConverter<>(annotatedGenerics[0], annotatedGenerics[1], annotatedType.getAnnotation(Param.KeyValuePairs.class))
|
||||||
: new MapConverter<>(annotatedGenerics[0], annotatedGenerics[1]);
|
: new MapConverter<>(annotatedGenerics[0], annotatedGenerics[1]);
|
||||||
@@ -92,7 +94,7 @@ class MapConverter<K, V> implements ValueConverter<Map<K, V>>
|
|||||||
{
|
{
|
||||||
private final boolean acceptMultiParam;
|
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);
|
super(keyType, valueType);
|
||||||
acceptMultiParam = config.allowMultiparam();
|
acceptMultiParam = config.allowMultiparam();
|
||||||
@@ -104,26 +106,28 @@ class MapConverter<K, V> implements ValueConverter<Map<K, V>>
|
|||||||
return acceptMultiParam;
|
return acceptMultiParam;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
@Override
|
@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)
|
return value instanceof MapValue ? super.convert(value, context)
|
||||||
: value instanceof ListValue ? convertList(((ListValue)value).getItems(), context)
|
: value instanceof ListValue ? convertList(((ListValue)value).getItems(), context)
|
||||||
: null; // Multiparam mode can only be used in evalAndConvert
|
: 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)
|
if (valueList.size() % 2 == 1)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
final Map<K, V> map = new HashMap<>();
|
Map<K, V> map = new HashMap<>();
|
||||||
final Iterator<Value> val = valueList.iterator();
|
Iterator<Value> val = valueList.iterator();
|
||||||
while (val.hasNext())
|
while (val.hasNext())
|
||||||
{
|
{
|
||||||
final K key = keyConverter.convert(val.next(), context);
|
K key = keyConverter.convert(val.next(), context);
|
||||||
final V value = valueConverter.convert(val.next(), context);
|
V value = valueConverter.convert(val.next(), context);
|
||||||
if (key == null || value == null)
|
if (key == null || value == null)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
@@ -133,20 +137,21 @@ class MapConverter<K, V> implements ValueConverter<Map<K, V>>
|
|||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
@Override
|
@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())
|
if (!valueIterator.hasNext())
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
final Value val = valueIterator.next();
|
Value val = valueIterator.next();
|
||||||
if (!acceptMultiParam || val instanceof MapValue || (val instanceof ListValue && !(keyConverter instanceof ListConverter)))
|
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
|
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
|
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);
|
V value = valueConverter.checkAndConvert(valueIterator, context, theLazyT);
|
||||||
if (key == null || value == null)
|
if (key == null || value == null)
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ import java.util.Optional;
|
|||||||
import carpet.script.Context;
|
import carpet.script.Context;
|
||||||
import carpet.script.value.Value;
|
import carpet.script.value.Value;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>{@link ValueConverter} that accepts a parameter to not be present on function call.</p>
|
* <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
|
* @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.
|
* {@link #checkAndConvert(Iterator, Context, Context.Type)} and is only used as a fallback in types that don't support it.
|
||||||
*/
|
*/
|
||||||
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public Optional<R> convert(final Value value, final Context context)
|
public Optional<R> convert(Value value, @Nullable Context context)
|
||||||
{
|
{
|
||||||
if (value.isNull())
|
if (value.isNull())
|
||||||
{
|
{
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
final R converted = typeConverter.convert(value, context);
|
R converted = typeConverter.convert(value, context);
|
||||||
if (converted == null)
|
if (converted == null)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
@@ -64,15 +67,16 @@ final class OptionalConverter<R> implements ValueConverter<Optional<R>>
|
|||||||
return Optional.of(converted);
|
return Optional.of(converted);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
@Override
|
@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())
|
if (!valueIterator.hasNext() || valueIterator.next().isNull())
|
||||||
{
|
{
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
((ListIterator<Value>) valueIterator).previous();
|
((ListIterator<Value>) valueIterator).previous();
|
||||||
final R converted = typeConverter.checkAndConvert(valueIterator, context, theLazyT);
|
R converted = typeConverter.checkAndConvert(valueIterator, context, theLazyT);
|
||||||
if (converted == null)
|
if (converted == null)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
@@ -106,10 +110,10 @@ final class OptionalConverter<R> implements ValueConverter<Optional<R>>
|
|||||||
* @param annotatedType The type to get generics information from
|
* @param annotatedType The type to get generics information from
|
||||||
* @return A new {@link OptionalConverter} for the data specified in the {@link AnnotatedType}
|
* @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;
|
AnnotatedParameterizedType paramType = (AnnotatedParameterizedType) annotatedType;
|
||||||
final AnnotatedType wrappedType = paramType.getAnnotatedActualTypeArguments()[0];
|
AnnotatedType wrappedType = paramType.getAnnotatedActualTypeArguments()[0];
|
||||||
return new OptionalConverter<>(wrappedType);
|
return new OptionalConverter<>(wrappedType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -23,6 +23,8 @@ import carpet.script.value.StringValue;
|
|||||||
import carpet.script.value.Value;
|
import carpet.script.value.Value;
|
||||||
import carpet.script.value.ValueConversions;
|
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
|
* <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>
|
* values.</p>
|
||||||
@@ -57,7 +59,7 @@ public final class OutputConverter<T>
|
|||||||
|
|
||||||
private final Function<T, LazyValue> converter;
|
private final Function<T, LazyValue> converter;
|
||||||
|
|
||||||
private OutputConverter(final Function<T, LazyValue> converter)
|
private OutputConverter(Function<T, LazyValue> converter)
|
||||||
{
|
{
|
||||||
this.converter = converter;
|
this.converter = converter;
|
||||||
}
|
}
|
||||||
@@ -90,7 +92,7 @@ public final class OutputConverter<T>
|
|||||||
* @param input The value to convert
|
* @param input The value to convert
|
||||||
* @return The converted value
|
* @return The converted value
|
||||||
*/
|
*/
|
||||||
public LazyValue convert(final T input)
|
public LazyValue convert(@Nullable T input)
|
||||||
{
|
{
|
||||||
return input == null ? LazyValue.NULL : converter.apply(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 inputType The class of T
|
||||||
* @param converter The function that converts the an instance of T to a {@link LazyValue}
|
* @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))
|
if (byResult.containsKey(inputType))
|
||||||
{
|
{
|
||||||
throw new IllegalArgumentException(inputType + " already has a registered OutputConverter");
|
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 inputType The class of T
|
||||||
* @param converter The function that converts an instance of T to a {@link Value}
|
* @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))
|
if (byResult.containsKey(inputType))
|
||||||
{
|
{
|
||||||
throw new IllegalArgumentException(inputType + " already has a registered OutputConverter");
|
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.MinecraftServer;
|
||||||
import net.minecraft.server.level.ServerPlayer;
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
import static java.lang.annotation.ElementType.PARAMETER;
|
import static java.lang.annotation.ElementType.PARAMETER;
|
||||||
import static java.lang.annotation.ElementType.TYPE_USE;
|
import static java.lang.annotation.ElementType.TYPE_USE;
|
||||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
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}
|
* <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>
|
* 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
|
@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");
|
throw new UnsupportedOperationException("Called convert() with Value in Context Provider converter, where only checkAndConvert is supported");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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;
|
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}
|
* <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>
|
* 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
|
@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");
|
throw new UnsupportedOperationException("Called convert() with a Value in TheLazyT Provider, where only checkAndConvert is supported");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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;
|
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
|
* @throws IllegalArgumentException If the type doesn't accept the {@link Strict} annotation or if it has been used incorrectly (shallow in
|
||||||
* unsupported places)
|
* unsupported places)
|
||||||
*/
|
*/
|
||||||
static ValueConverter<?> getStrictConverter(final AnnotatedType type)
|
static ValueConverter<?> getStrictConverter(AnnotatedType type)
|
||||||
{
|
{
|
||||||
final boolean shallow = type.getAnnotation(Strict.class).shallow();
|
boolean shallow = type.getAnnotation(Strict.class).shallow();
|
||||||
final Class<?> clazz = (Class<?>) type.getType();
|
Class<?> clazz = (Class<?>) type.getType();
|
||||||
final StrictConverterInfo key = new StrictConverterInfo(clazz, shallow);
|
StrictConverterInfo key = new StrictConverterInfo(clazz, shallow);
|
||||||
final ValueConverter<?> converter = strictParamsByClassAndShallowness.get(key);
|
ValueConverter<?> converter = strictParamsByClassAndShallowness.get(key);
|
||||||
if (converter != null)
|
if (converter != null)
|
||||||
{
|
{
|
||||||
return converter;
|
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 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.
|
* @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))
|
if (strictParamsByClassAndShallowness.containsKey(key))
|
||||||
{
|
{
|
||||||
throw new IllegalArgumentException(type + " already has a registered " + (shallow ? "" : "non-") + "shallow StrictConverter");
|
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.
|
* avoid possible collisions with other extensions.
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked") // this makes no sense... But I guess its preferable to enforce typesafety in callers
|
@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);
|
customFactories.add((BiFunction<AnnotatedType, Class<?>, ValueConverter<?>>) (Object) factory);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked") // Stored correctly
|
@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;
|
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)
|
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.Value;
|
||||||
import carpet.script.value.ValueConversions;
|
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
|
* <p>A simple {@link ValueConverter} implementation that converts from a specified subclass of {@link Value} into {@code <R>} by using a given
|
||||||
* function.</p>
|
* function.</p>
|
||||||
@@ -61,7 +63,7 @@ public final class SimpleTypeConverter<T extends Value, R> implements ValueConve
|
|||||||
*
|
*
|
||||||
* @see #SimpleTypeConverter(Class, BiFunction, String)
|
* @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);
|
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 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
|
* @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();
|
super();
|
||||||
this.converter = converter;
|
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
|
* @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.
|
@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);
|
return (SimpleTypeConverter<Value, R>) byResult.get(outputType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("unchecked") // more than checked. not using class.cast because then "method is too big" for inlining, because javac is useless
|
@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;
|
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)
|
* @see #registerType(Class, Class, BiFunction, String)
|
||||||
*/
|
*/
|
||||||
public static <T extends Value, R> void registerType(final Class<T> requiredInputType, final Class<R> outputType,
|
public static <T extends Value, R> void registerType(Class<T> requiredInputType, Class<R> outputType,
|
||||||
final Function<T, R> converter, final String typeName)
|
Function<T, R> converter, String typeName)
|
||||||
{
|
{
|
||||||
registerType(requiredInputType, outputType, (val, ctx) -> converter.apply(val), 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.
|
* 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()}
|
* @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,
|
public static <T extends Value, R> void registerType(Class<T> requiredInputType, Class<R> outputType,
|
||||||
final BiFunction<T, Context, R> converter, final String typeName)
|
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);
|
byResult.put(outputType, type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -18,6 +18,8 @@ import carpet.script.value.StringValue;
|
|||||||
import carpet.script.value.ThreadValue;
|
import carpet.script.value.ThreadValue;
|
||||||
import carpet.script.value.Value;
|
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
|
* <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>
|
* 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 Class<R> outputType;
|
||||||
private final String typeName;
|
private final String typeName;
|
||||||
|
|
||||||
private ValueCaster(final Class<R> outputType, final String typeName)
|
private ValueCaster(Class<R> outputType, String typeName)
|
||||||
{
|
{
|
||||||
super();
|
super();
|
||||||
this.outputType = outputType;
|
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
|
@SuppressWarnings("unchecked") // Casters are stored with their exact class, for sure since the map is private (&& class has same generic as
|
||||||
// caster)
|
// 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);
|
return (ValueCaster<R>) byResult.get(outputType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("unchecked") // more than checked, see SimpleTypeConverter#converter for reasoning
|
@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))
|
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
|
* required<!--, with the form //Outdated concept <code>(function name) requires a (typeName) to be passed as (argName, if
|
||||||
* available)</code>-->
|
* 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);
|
byResult.putIfAbsent(valueClass, caster);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -9,12 +9,13 @@ import java.util.Objects;
|
|||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
import org.apache.commons.lang3.ClassUtils;
|
import org.apache.commons.lang3.ClassUtils;
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import carpet.script.Context;
|
import carpet.script.Context;
|
||||||
import carpet.script.annotation.Param.Params;
|
import carpet.script.annotation.Param.Params;
|
||||||
import carpet.script.value.Value;
|
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
|
* <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>
|
* 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
|
* @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.
|
* helpful usage instructions.
|
||||||
*/
|
*/
|
||||||
|
@Nullable
|
||||||
String getTypeName();
|
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
|
* <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>
|
* {@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>
|
* Old version of {@link #convert(Value)} without taking a {@link Context}.<p>
|
||||||
@@ -75,8 +77,9 @@ public interface ValueConverter<R>
|
|||||||
* @return A converted value
|
* @return A converted value
|
||||||
* @deprecated Calling this method instead of {@link #convert(Value, Context)} may not return values for some converters
|
* @deprecated Calling this method instead of {@link #convert(Value, Context)} may not return values for some converters
|
||||||
*/
|
*/
|
||||||
|
@Nullable
|
||||||
@Deprecated(forRemoval = true)
|
@Deprecated(forRemoval = true)
|
||||||
default R convert(final Value value)
|
default R convert(Value value)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -130,7 +133,7 @@ public interface ValueConverter<R>
|
|||||||
* @return A usable {@link ValueConverter} to convert from a {@link Value} to {@code <R>}
|
* @return A usable {@link ValueConverter} to convert from a {@link Value} to {@code <R>}
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@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> type = annoType.getType() instanceof ParameterizedType ? // We are defining R here.
|
||||||
(Class<R>) ((ParameterizedType) annoType.getType()).getRawType() :
|
(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
|
* @implNote This method's default implementation runs the {@link #convert(Value, Context)} function in the next {@link Value} ignoring {@link Context} and
|
||||||
* {@code theLazyT}.
|
* {@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);
|
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 class BlockIterators
|
||||||
{
|
{
|
||||||
public static void apply(final Expression expression)
|
public static void apply(Expression expression)
|
||||||
{
|
{
|
||||||
// lazy cause of lazy expression
|
// lazy cause of lazy expression
|
||||||
expression.addLazyFunction("scan", (c, t, llv) ->
|
expression.addLazyFunction("scan", (c, t, llv) ->
|
||||||
@@ -40,12 +40,12 @@ public class BlockIterators
|
|||||||
{
|
{
|
||||||
throw new InternalExpressionException("'scan' needs many more arguments");
|
throw new InternalExpressionException("'scan' 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 CarpetContext cc = (CarpetContext) c;
|
CarpetContext cc = (CarpetContext) c;
|
||||||
final BlockArgument centerLocator = BlockArgument.findIn(cc, lv, 0);
|
BlockArgument centerLocator = BlockArgument.findIn(cc, lv, 0);
|
||||||
Vector3Argument rangeLocator = Vector3Argument.findIn(lv, centerLocator.offset);
|
Vector3Argument rangeLocator = Vector3Argument.findIn(lv, centerLocator.offset);
|
||||||
final BlockPos center = centerLocator.block.getPos();
|
BlockPos center = centerLocator.block.getPos();
|
||||||
final Vec3i range;
|
Vec3i range;
|
||||||
|
|
||||||
if (rangeLocator.fromBlock)
|
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);
|
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();
|
int cx = center.getX();
|
||||||
final int cy = center.getY();
|
int cy = center.getY();
|
||||||
final int cz = center.getZ();
|
int cz = center.getZ();
|
||||||
final int xrange = range.getX();
|
int xrange = range.getX();
|
||||||
final int yrange = range.getY();
|
int yrange = range.getY();
|
||||||
final int zrange = range.getZ();
|
int zrange = range.getZ();
|
||||||
final int xprange = upperRange.getX();
|
int xprange = upperRange.getX();
|
||||||
final int yprange = upperRange.getY();
|
int yprange = upperRange.getY();
|
||||||
final int zprange = upperRange.getZ();
|
int zprange = upperRange.getZ();
|
||||||
|
|
||||||
//saving outer scope
|
//saving outer scope
|
||||||
final LazyValue _x = c.getVariable("_x");
|
LazyValue xVal = c.getVariable("_x");
|
||||||
final LazyValue _y = c.getVariable("_y");
|
LazyValue yVal = c.getVariable("_y");
|
||||||
final LazyValue _z = c.getVariable("_z");
|
LazyValue zVal = c.getVariable("_z");
|
||||||
final LazyValue __ = c.getVariable("_");
|
LazyValue defaultVal = c.getVariable("_");
|
||||||
int sCount = 0;
|
int sCount = 0;
|
||||||
outer:
|
outer:
|
||||||
for (int y = cy - yrange; y <= cy + yprange; y++)
|
for (int y = cy - yrange; y <= cy + yprange; y++)
|
||||||
{
|
{
|
||||||
final int yFinal = y;
|
int yFinal = y;
|
||||||
c.setVariable("_y", (c_, t_) -> new NumericValue(yFinal).bindTo("_y"));
|
c.setVariable("_y", (ct, tt) -> new NumericValue(yFinal).bindTo("_y"));
|
||||||
for (int x = cx - xrange; x <= cx + xprange; x++)
|
for (int x = cx - xrange; x <= cx + xprange; x++)
|
||||||
{
|
{
|
||||||
final int xFinal = x;
|
int xFinal = x;
|
||||||
c.setVariable("_x", (c_, t_) -> new NumericValue(xFinal).bindTo("_x"));
|
c.setVariable("_x", (ct, tt) -> new NumericValue(xFinal).bindTo("_x"));
|
||||||
for (int z = cz - zrange; z <= cz + zprange; z++)
|
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"));
|
c.setVariable("_z", (ct, tt) -> new NumericValue(zFinal).bindTo("_z"));
|
||||||
final Value blockValue = BlockValue.fromCoords(((CarpetContext) c), xFinal, yFinal, zFinal).bindTo("_");
|
Value blockValue = BlockValue.fromCoords(((CarpetContext) c), xFinal, yFinal, zFinal).bindTo("_");
|
||||||
c.setVariable("_", (cc_, t_c) -> blockValue);
|
c.setVariable("_", (ct, tt) -> blockValue);
|
||||||
Value result;
|
Value result;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
result = expr.evalValue(c, t);
|
result = expr.evalValue(c, t);
|
||||||
}
|
}
|
||||||
catch (final ContinueStatement notIgnored)
|
catch (ContinueStatement notIgnored)
|
||||||
{
|
{
|
||||||
result = notIgnored.retval;
|
result = notIgnored.retval;
|
||||||
}
|
}
|
||||||
catch (final BreakStatement notIgnored)
|
catch (BreakStatement notIgnored)
|
||||||
{
|
{
|
||||||
break outer;
|
break outer;
|
||||||
}
|
}
|
||||||
@@ -135,74 +135,74 @@ public class BlockIterators
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
//restoring outer scope
|
//restoring outer scope
|
||||||
c.setVariable("_x", _x);
|
c.setVariable("_x", xVal);
|
||||||
c.setVariable("_y", _y);
|
c.setVariable("_y", yVal);
|
||||||
c.setVariable("_z", _z);
|
c.setVariable("_z", zVal);
|
||||||
c.setVariable("_", __);
|
c.setVariable("_", defaultVal);
|
||||||
final int finalSCount = sCount;
|
int finalSCount = sCount;
|
||||||
return (c_, t_) -> new NumericValue(finalSCount);
|
return (ct, tt) -> new NumericValue(finalSCount);
|
||||||
});
|
});
|
||||||
|
|
||||||
// must be lazy
|
// must be lazy
|
||||||
expression.addLazyFunction("volume", (c, t, llv) ->
|
expression.addLazyFunction("volume", (c, t, llv) ->
|
||||||
{
|
{
|
||||||
final CarpetContext cc = (CarpetContext) c;
|
CarpetContext cc = (CarpetContext) c;
|
||||||
if (llv.size() < 3)
|
if (llv.size() < 3)
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("'volume' needs many more arguments");
|
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);
|
BlockArgument pos1Locator = BlockArgument.findIn(cc, lv, 0);
|
||||||
final BlockArgument pos2Locator = BlockArgument.findIn(cc, lv, pos1Locator.offset);
|
BlockArgument pos2Locator = BlockArgument.findIn(cc, lv, pos1Locator.offset);
|
||||||
final BlockPos pos1 = pos1Locator.block.getPos();
|
BlockPos pos1 = pos1Locator.block.getPos();
|
||||||
final BlockPos pos2 = pos2Locator.block.getPos();
|
BlockPos pos2 = pos2Locator.block.getPos();
|
||||||
|
|
||||||
final int x1 = pos1.getX();
|
int x1 = pos1.getX();
|
||||||
final int y1 = pos1.getY();
|
int y1 = pos1.getY();
|
||||||
final int z1 = pos1.getZ();
|
int z1 = pos1.getZ();
|
||||||
final int x2 = pos2.getX();
|
int x2 = pos2.getX();
|
||||||
final int y2 = pos2.getY();
|
int y2 = pos2.getY();
|
||||||
final int z2 = pos2.getZ();
|
int z2 = pos2.getZ();
|
||||||
final int minx = min(x1, x2);
|
int minx = min(x1, x2);
|
||||||
final int miny = min(y1, y2);
|
int miny = min(y1, y2);
|
||||||
final int minz = min(z1, z2);
|
int minz = min(z1, z2);
|
||||||
final int maxx = max(x1, x2);
|
int maxx = max(x1, x2);
|
||||||
final int maxy = max(y1, y2);
|
int maxy = max(y1, y2);
|
||||||
final int maxz = max(z1, z2);
|
int maxz = max(z1, z2);
|
||||||
final LazyValue expr = llv.get(pos2Locator.offset);
|
LazyValue expr = llv.get(pos2Locator.offset);
|
||||||
|
|
||||||
//saving outer scope
|
//saving outer scope
|
||||||
final LazyValue _x = c.getVariable("_x");
|
LazyValue xVal = c.getVariable("_x");
|
||||||
final LazyValue _y = c.getVariable("_y");
|
LazyValue yVal = c.getVariable("_y");
|
||||||
final LazyValue _z = c.getVariable("_z");
|
LazyValue zVal = c.getVariable("_z");
|
||||||
final LazyValue __ = c.getVariable("_");
|
LazyValue defaultVal = c.getVariable("_");
|
||||||
int sCount = 0;
|
int sCount = 0;
|
||||||
outer:
|
outer:
|
||||||
for (int y = miny; y <= maxy; y++)
|
for (int y = miny; y <= maxy; y++)
|
||||||
{
|
{
|
||||||
final int yFinal = y;
|
int yFinal = y;
|
||||||
c.setVariable("_y", (c_, t_) -> new NumericValue(yFinal).bindTo("_y"));
|
c.setVariable("_y", (ct, tt) -> new NumericValue(yFinal).bindTo("_y"));
|
||||||
for (int x = minx; x <= maxx; x++)
|
for (int x = minx; x <= maxx; x++)
|
||||||
{
|
{
|
||||||
final int xFinal = x;
|
int xFinal = x;
|
||||||
c.setVariable("_x", (c_, t_) -> new NumericValue(xFinal).bindTo("_x"));
|
c.setVariable("_x", (ct, tt) -> new NumericValue(xFinal).bindTo("_x"));
|
||||||
for (int z = minz; z <= maxz; z++)
|
for (int z = minz; z <= maxz; z++)
|
||||||
{
|
{
|
||||||
final int zFinal = z;
|
int zFinal = z;
|
||||||
c.setVariable("_z", (c_, t_) -> new NumericValue(zFinal).bindTo("_z"));
|
c.setVariable("_z", (ct, tt) -> new NumericValue(zFinal).bindTo("_z"));
|
||||||
final Value blockValue = BlockValue.fromCoords(((CarpetContext) c), xFinal, yFinal, zFinal).bindTo("_");
|
Value blockValue = BlockValue.fromCoords(((CarpetContext) c), xFinal, yFinal, zFinal).bindTo("_");
|
||||||
c.setVariable("_", (cc_, t_c) -> blockValue);
|
c.setVariable("_", (ct, tt) -> blockValue);
|
||||||
Value result;
|
Value result;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
result = expr.evalValue(c, t);
|
result = expr.evalValue(c, t);
|
||||||
}
|
}
|
||||||
catch (final ContinueStatement notIgnored)
|
catch (ContinueStatement notIgnored)
|
||||||
{
|
{
|
||||||
result = notIgnored.retval;
|
result = notIgnored.retval;
|
||||||
}
|
}
|
||||||
catch (final BreakStatement notIgnored)
|
catch (BreakStatement notIgnored)
|
||||||
{
|
{
|
||||||
break outer;
|
break outer;
|
||||||
}
|
}
|
||||||
@@ -214,49 +214,49 @@ public class BlockIterators
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
//restoring outer scope
|
//restoring outer scope
|
||||||
c.setVariable("_x", _x);
|
c.setVariable("_x", xVal);
|
||||||
c.setVariable("_y", _y);
|
c.setVariable("_y", yVal);
|
||||||
c.setVariable("_z", _z);
|
c.setVariable("_z", zVal);
|
||||||
c.setVariable("_", __);
|
c.setVariable("_", defaultVal);
|
||||||
final int finalSCount = sCount;
|
int finalSCount = sCount;
|
||||||
return (c_, t_) -> new NumericValue(finalSCount);
|
return (ct, tt) -> new NumericValue(finalSCount);
|
||||||
});
|
});
|
||||||
|
|
||||||
expression.addContextFunction("neighbours", -1, (c, t, lv) ->
|
expression.addContextFunction("neighbours", -1, (c, t, lv) ->
|
||||||
{
|
{
|
||||||
final BlockPos center = BlockArgument.findIn((CarpetContext) c, lv, 0).block.getPos();
|
BlockPos center = BlockArgument.findIn((CarpetContext) c, lv, 0).block.getPos();
|
||||||
final ServerLevel world = ((CarpetContext) c).level();
|
ServerLevel world = ((CarpetContext) c).level();
|
||||||
|
|
||||||
final List<Value> neighbours = new ArrayList<>();
|
List<Value> neighbours = new ArrayList<>();
|
||||||
neighbours.add(new BlockValue(null, world, center.above()));
|
neighbours.add(new BlockValue(world, center.above()));
|
||||||
neighbours.add(new BlockValue(null, world, center.below()));
|
neighbours.add(new BlockValue(world, center.below()));
|
||||||
neighbours.add(new BlockValue(null, world, center.north()));
|
neighbours.add(new BlockValue(world, center.north()));
|
||||||
neighbours.add(new BlockValue(null, world, center.south()));
|
neighbours.add(new BlockValue(world, center.south()));
|
||||||
neighbours.add(new BlockValue(null, world, center.east()));
|
neighbours.add(new BlockValue(world, center.east()));
|
||||||
neighbours.add(new BlockValue(null, world, center.west()));
|
neighbours.add(new BlockValue(world, center.west()));
|
||||||
return ListValue.wrap(neighbours);
|
return ListValue.wrap(neighbours);
|
||||||
});
|
});
|
||||||
|
|
||||||
expression.addContextFunction("rect", -1, (c, t, lv) ->
|
expression.addContextFunction("rect", -1, (c, t, lv) ->
|
||||||
{
|
{
|
||||||
final CarpetContext cc = (CarpetContext) c;
|
CarpetContext cc = (CarpetContext) c;
|
||||||
final int cx;
|
int cx;
|
||||||
final int cy;
|
int cy;
|
||||||
final int cz;
|
int cz;
|
||||||
final int sminx;
|
int sminx;
|
||||||
final int sminy;
|
int sminy;
|
||||||
final int sminz;
|
int sminz;
|
||||||
final int smaxx;
|
int smaxx;
|
||||||
final int smaxy;
|
int smaxy;
|
||||||
final int smaxz;
|
int smaxz;
|
||||||
final BlockArgument cposLocator = BlockArgument.findIn(cc, lv, 0);
|
BlockArgument cposLocator = BlockArgument.findIn(cc, lv, 0);
|
||||||
final BlockPos cpos = cposLocator.block.getPos();
|
BlockPos cpos = cposLocator.block.getPos();
|
||||||
cx = cpos.getX();
|
cx = cpos.getX();
|
||||||
cy = cpos.getY();
|
cy = cpos.getY();
|
||||||
cz = cpos.getZ();
|
cz = cpos.getZ();
|
||||||
if (lv.size() > cposLocator.offset)
|
if (lv.size() > cposLocator.offset)
|
||||||
{
|
{
|
||||||
final Vector3Argument diffLocator = Vector3Argument.findIn(lv, cposLocator.offset);
|
Vector3Argument diffLocator = Vector3Argument.findIn(lv, cposLocator.offset);
|
||||||
if (diffLocator.fromBlock)
|
if (diffLocator.fromBlock)
|
||||||
{
|
{
|
||||||
sminx = Mth.floor(abs(diffLocator.vec.x - cx));
|
sminx = Mth.floor(abs(diffLocator.vec.x - cx));
|
||||||
@@ -271,7 +271,7 @@ public class BlockIterators
|
|||||||
}
|
}
|
||||||
if (lv.size() > diffLocator.offset)
|
if (lv.size() > diffLocator.offset)
|
||||||
{
|
{
|
||||||
final Vector3Argument posDiff = Vector3Argument.findIn(lv, diffLocator.offset);
|
Vector3Argument posDiff = Vector3Argument.findIn(lv, diffLocator.offset);
|
||||||
if (posDiff.fromBlock)
|
if (posDiff.fromBlock)
|
||||||
{
|
{
|
||||||
smaxx = Mth.floor(abs(posDiff.vec.x - cx));
|
smaxx = Mth.floor(abs(posDiff.vec.x - cx));
|
||||||
@@ -328,7 +328,7 @@ public class BlockIterators
|
|||||||
@Override
|
@Override
|
||||||
public Value next()
|
public Value next()
|
||||||
{
|
{
|
||||||
final Value r = BlockValue.fromCoords(cc, x, y, z);
|
Value r = BlockValue.fromCoords(cc, x, y, z);
|
||||||
//possibly reroll context
|
//possibly reroll context
|
||||||
x++;
|
x++;
|
||||||
if (x > maxx)
|
if (x > maxx)
|
||||||
@@ -371,16 +371,16 @@ public class BlockIterators
|
|||||||
|
|
||||||
expression.addContextFunction("diamond", -1, (c, t, lv) ->
|
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);
|
BlockArgument cposLocator = BlockArgument.findIn((CarpetContext) c, lv, 0);
|
||||||
final BlockPos cpos = cposLocator.block.getPos();
|
BlockPos cpos = cposLocator.block.getPos();
|
||||||
|
|
||||||
final int cx;
|
int cx;
|
||||||
final int cy;
|
int cy;
|
||||||
final int cz;
|
int cz;
|
||||||
final int width;
|
int width;
|
||||||
final int height;
|
int height;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
cx = cpos.getX();
|
cx = cpos.getX();
|
||||||
@@ -414,7 +414,7 @@ public class BlockIterators
|
|||||||
throw new InternalExpressionException("Incorrect number of arguments for 'diamond'");
|
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'");
|
throw new InternalExpressionException("Attempted to pass a non-number to 'diamond'");
|
||||||
}
|
}
|
||||||
@@ -445,7 +445,7 @@ public class BlockIterators
|
|||||||
}
|
}
|
||||||
// x = 3-|i-6|
|
// x = 3-|i-6|
|
||||||
// z = |( (i-3)%12-6|-3
|
// 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++;
|
curpos++;
|
||||||
if (curpos >= curradius * 4)
|
if (curpos >= curradius * 4)
|
||||||
{
|
{
|
||||||
@@ -503,7 +503,7 @@ public class BlockIterators
|
|||||||
// x = 3-|i-6|
|
// x = 3-|i-6|
|
||||||
// z = |( (i-3)%12-6|-3
|
// 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++;
|
curpos++;
|
||||||
if (curpos >= curradius * 4)
|
if (curpos >= curradius * 4)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -42,10 +42,10 @@ import net.minecraft.world.phys.Vec3;
|
|||||||
|
|
||||||
public class Entities
|
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<>();
|
List<Value> ret = new ArrayList<>();
|
||||||
for (final ServerPlayer player : ((CarpetContext) c).level().players())
|
for (ServerPlayer player : ((CarpetContext) c).level().players())
|
||||||
{
|
{
|
||||||
if (condition.test(player))
|
if (condition.test(player))
|
||||||
{
|
{
|
||||||
@@ -55,45 +55,45 @@ public class Entities
|
|||||||
return ListValue.wrap(ret);
|
return ListValue.wrap(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void apply(final Expression expression)
|
public static void apply(Expression expression)
|
||||||
{
|
{
|
||||||
expression.addContextFunction("player", -1, (c, t, lv) ->
|
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)
|
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);
|
return EntityValue.of(player);
|
||||||
}
|
}
|
||||||
final Entity callingEntity = cc.source().getEntity();
|
Entity callingEntity = cc.source().getEntity();
|
||||||
if (callingEntity instanceof Player)
|
if (callingEntity instanceof Player)
|
||||||
{
|
{
|
||||||
return EntityValue.of(callingEntity);
|
return EntityValue.of(callingEntity);
|
||||||
}
|
}
|
||||||
final Vec3 pos = ((CarpetContext) c).source().getPosition();
|
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);
|
Player closestPlayer = ((CarpetContext) c).level().getNearestPlayer(pos.x, pos.y, pos.z, -1.0, EntitySelector.ENTITY_STILL_ALIVE);
|
||||||
return EntityValue.of(closestPlayer);
|
return EntityValue.of(closestPlayer);
|
||||||
}
|
}
|
||||||
final String playerName = lv.get(0).getString();
|
String playerName = lv.get(0).getString();
|
||||||
return switch (playerName)
|
return switch (playerName)
|
||||||
{
|
{
|
||||||
case "all" -> {
|
case "all" -> {
|
||||||
final List<Value> ret = new ArrayList<>();
|
List<Value> ret = new ArrayList<>();
|
||||||
for (final ServerPlayer player : ((CarpetContext) c).server().getPlayerList().getPlayers())
|
for (ServerPlayer player : ((CarpetContext) c).server().getPlayerList().getPlayers())
|
||||||
{
|
{
|
||||||
ret.add(new EntityValue(player));
|
ret.add(new EntityValue(player));
|
||||||
}
|
}
|
||||||
yield ListValue.wrap(ret);
|
yield ListValue.wrap(ret);
|
||||||
}
|
}
|
||||||
case "*" -> getPlayersFromWorldMatching(c, p -> true);
|
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 "creative" -> getPlayersFromWorldMatching(c, ServerPlayer::isCreative);
|
||||||
case "spectating" -> getPlayersFromWorldMatching(c, ServerPlayer::isSpectator);
|
case "spectating" -> getPlayersFromWorldMatching(c, ServerPlayer::isSpectator);
|
||||||
case "!spectating" -> getPlayersFromWorldMatching(c, p -> !p.isSpectator());
|
case "!spectating" -> getPlayersFromWorldMatching(c, p -> !p.isSpectator());
|
||||||
default -> {
|
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;
|
yield player != null ? new EntityValue(player) : Value.NULL;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -101,28 +101,28 @@ public class Entities
|
|||||||
|
|
||||||
expression.addContextFunction("spawn", -1, (c, t, lv) ->
|
expression.addContextFunction("spawn", -1, (c, t, lv) ->
|
||||||
{
|
{
|
||||||
final CarpetContext cc = (CarpetContext) c;
|
CarpetContext cc = (CarpetContext) c;
|
||||||
if (lv.size() < 2)
|
if (lv.size() < 2)
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("'spawn' function takes mob name, and position to spawn");
|
throw new InternalExpressionException("'spawn' function takes mob name, and position to spawn");
|
||||||
}
|
}
|
||||||
final String entityString = lv.get(0).getString();
|
String entityString = lv.get(0).getString();
|
||||||
final ResourceLocation entityId;
|
ResourceLocation entityId;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
entityId = ResourceLocation.read(new StringReader(entityString));
|
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())
|
if (type == null || !type.canSummon())
|
||||||
{
|
{
|
||||||
return Value.NULL;
|
return Value.NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (final CommandSyntaxException ignored)
|
catch (CommandSyntaxException ignored)
|
||||||
{
|
{
|
||||||
return Value.NULL;
|
return Value.NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
final Vector3Argument position = Vector3Argument.findIn(lv, 1);
|
Vector3Argument position = Vector3Argument.findIn(lv, 1);
|
||||||
if (position.fromBlock)
|
if (position.fromBlock)
|
||||||
{
|
{
|
||||||
position.vec = position.vec.subtract(0, 0.5, 0);
|
position.vec = position.vec.subtract(0, 0.5, 0);
|
||||||
@@ -131,20 +131,20 @@ public class Entities
|
|||||||
boolean hasTag = false;
|
boolean hasTag = false;
|
||||||
if (lv.size() > position.offset)
|
if (lv.size() > position.offset)
|
||||||
{
|
{
|
||||||
final Value nbt = lv.get(position.offset);
|
Value nbt = lv.get(position.offset);
|
||||||
final NBTSerializableValue v = (nbt instanceof final NBTSerializableValue nbtsv)
|
NBTSerializableValue v = (nbt instanceof final NBTSerializableValue nbtsv)
|
||||||
? nbtsv
|
? nbtsv
|
||||||
: NBTSerializableValue.parseString(nbt.getString(), true);
|
: NBTSerializableValue.parseStringOrFail(nbt.getString());
|
||||||
hasTag = true;
|
hasTag = true;
|
||||||
tag = v.getCompoundTag();
|
tag = v.getCompoundTag();
|
||||||
}
|
}
|
||||||
tag.putString("id", entityId.toString());
|
tag.putString("id", entityId.toString());
|
||||||
final Vec3 vec3d = position.vec;
|
Vec3 vec3d = position.vec;
|
||||||
|
|
||||||
final ServerLevel serverWorld = cc.level();
|
ServerLevel serverWorld = cc.level();
|
||||||
final Entity entity = EntityType.loadEntityRecursive(tag, serverWorld, e -> {
|
Entity entity = EntityType.loadEntityRecursive(tag, serverWorld, e -> {
|
||||||
e.moveTo(vec3d.x, vec3d.y, vec3d.z, e.getYRot(), e.getXRot());
|
e.moveTo(vec3d.x, vec3d.y, vec3d.z, e.getYRot(), e.getXRot());
|
||||||
return !serverWorld.addWithUUID(e) ? null : e;
|
return e;
|
||||||
});
|
});
|
||||||
if (entity == null)
|
if (entity == null)
|
||||||
{
|
{
|
||||||
@@ -154,12 +154,17 @@ public class Entities
|
|||||||
{
|
{
|
||||||
mob.finalizeSpawn(serverWorld, serverWorld.getCurrentDifficultyAt(entity.blockPosition()), MobSpawnType.COMMAND, null, null);
|
mob.finalizeSpawn(serverWorld, serverWorld.getCurrentDifficultyAt(entity.blockPosition()), MobSpawnType.COMMAND, null, null);
|
||||||
}
|
}
|
||||||
|
if (!serverWorld.tryAddFreshEntityWithPassengers(entity))
|
||||||
|
{
|
||||||
|
entity.discard();
|
||||||
|
return Value.NULL;
|
||||||
|
}
|
||||||
return new EntityValue(entity);
|
return new EntityValue(entity);
|
||||||
});
|
});
|
||||||
|
|
||||||
expression.addContextFunction("entity_id", 1, (c, t, lv) ->
|
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)
|
if (who instanceof final NumericValue numericValue)
|
||||||
{
|
{
|
||||||
return EntityValue.of(((CarpetContext) c).level().getEntity((int) numericValue.getLong()));
|
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) ->
|
expression.addContextFunction("entity_list", 1, (c, t, lv) ->
|
||||||
{
|
{
|
||||||
final String who = lv.get(0).getString();
|
String who = lv.get(0).getString();
|
||||||
final CommandSourceStack source = ((CarpetContext) c).source();
|
CommandSourceStack source = ((CarpetContext) c).source();
|
||||||
final EntityValue.EntityClassDescriptor eDesc = EntityValue.getEntityDescriptor(who, source.getServer());
|
EntityValue.EntityClassDescriptor eDesc = EntityValue.getEntityDescriptor(who, source.getServer());
|
||||||
final List<? extends Entity> entityList = source.getLevel().getEntities(eDesc.directType, eDesc.filteringPredicate);
|
List<? extends Entity> entityList = source.getLevel().getEntities(eDesc.directType, eDesc.filteringPredicate);
|
||||||
return ListValue.wrap(entityList.stream().map(EntityValue::new));
|
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");
|
throw new InternalExpressionException("'entity_area' requires entity type, center and range arguments");
|
||||||
}
|
}
|
||||||
final String who = lv.get(0).getString();
|
String who = lv.get(0).getString();
|
||||||
final CarpetContext cc = (CarpetContext) c;
|
CarpetContext cc = (CarpetContext) c;
|
||||||
final Vector3Argument centerLocator = Vector3Argument.findIn(lv, 1, false, true);
|
Vector3Argument centerLocator = Vector3Argument.findIn(lv, 1, false, true);
|
||||||
|
|
||||||
final AABB centerBox;
|
AABB centerBox;
|
||||||
if (centerLocator.entity != null)
|
if (centerLocator.entity != null)
|
||||||
{
|
{
|
||||||
centerBox = centerLocator.entity.getBoundingBox();
|
centerBox = centerLocator.entity.getBoundingBox();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
final Vec3 center = centerLocator.vec;
|
Vec3 center = centerLocator.vec;
|
||||||
if (centerLocator.fromBlock)
|
if (centerLocator.fromBlock)
|
||||||
{
|
{
|
||||||
center.add(0.5, 0.5, 0.5);
|
center.add(0.5, 0.5, 0.5);
|
||||||
}
|
}
|
||||||
centerBox = new AABB(center, center);
|
centerBox = new AABB(center, center);
|
||||||
}
|
}
|
||||||
final Vector3Argument rangeLocator = Vector3Argument.findIn(lv, centerLocator.offset);
|
Vector3Argument rangeLocator = Vector3Argument.findIn(lv, centerLocator.offset);
|
||||||
if (rangeLocator.fromBlock)
|
if (rangeLocator.fromBlock)
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("Range of 'entity_area' cannot come from a block argument");
|
throw new InternalExpressionException("Range of 'entity_area' cannot come from a block argument");
|
||||||
}
|
}
|
||||||
final Vec3 range = rangeLocator.vec;
|
Vec3 range = rangeLocator.vec;
|
||||||
final AABB area = centerBox.inflate(range.x, range.y, range.z);
|
AABB area = centerBox.inflate(range.x, range.y, range.z);
|
||||||
final EntityValue.EntityClassDescriptor eDesc = EntityValue.getEntityDescriptor(who, cc.server());
|
EntityValue.EntityClassDescriptor eDesc = EntityValue.getEntityDescriptor(who, cc.server());
|
||||||
final List<? extends Entity> entityList = cc.level().getEntities(eDesc.directType, area, eDesc.filteringPredicate);
|
List<? extends Entity> entityList = cc.level().getEntities(eDesc.directType, area, eDesc.filteringPredicate);
|
||||||
return ListValue.wrap(entityList.stream().map(EntityValue::new));
|
return ListValue.wrap(entityList.stream().map(EntityValue::new));
|
||||||
});
|
});
|
||||||
|
|
||||||
expression.addContextFunction("entity_selector", -1, (c, t, lv) ->
|
expression.addContextFunction("entity_selector", -1, (c, t, lv) ->
|
||||||
{
|
{
|
||||||
final String selector = lv.get(0).getString();
|
String selector = lv.get(0).getString();
|
||||||
final List<Value> retlist = new ArrayList<>();
|
List<Value> retlist = new ArrayList<>();
|
||||||
for (final Entity e : EntityValue.getEntitiesFromSelector(((CarpetContext) c).source(), selector))
|
for (Entity e : EntityValue.getEntitiesFromSelector(((CarpetContext) c).source(), selector))
|
||||||
{
|
{
|
||||||
retlist.add(new EntityValue(e));
|
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");
|
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))
|
if (!(v instanceof final EntityValue ev))
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("First argument to query should be an entity");
|
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"))
|
if (what.equals("tags"))
|
||||||
{
|
{
|
||||||
c.host.issueDeprecation("'tags' for entity querying");
|
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");
|
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))
|
if (!(v instanceof final EntityValue ev))
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("First argument to modify should be an entity");
|
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())
|
switch (lv.size())
|
||||||
{
|
{
|
||||||
case 2 -> ev.set(what, null);
|
case 2 -> ev.set(what, null);
|
||||||
@@ -275,7 +280,7 @@ public class Entities
|
|||||||
{
|
{
|
||||||
throw new InternalExpressionException("'entity_types' requires one or no arguments");
|
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());
|
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");
|
throw new InternalExpressionException("'entity_load_handler' required the entity type, and a function to call");
|
||||||
}
|
}
|
||||||
final Value entityValue = lv.get(0);
|
Value entityValue = lv.get(0);
|
||||||
final List<String> descriptors = (entityValue instanceof final ListValue list)
|
List<String> descriptors = (entityValue instanceof final ListValue list)
|
||||||
? list.getItems().stream().map(Value::getString).toList()
|
? list.getItems().stream().map(Value::getString).toList()
|
||||||
: Collections.singletonList(entityValue.getString());
|
: 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));
|
descriptors.forEach(s -> types.addAll(EntityValue.getEntityDescriptor(s, ((CarpetContext) c).server()).types));
|
||||||
final FunctionArgument funArg = FunctionArgument.findIn(c, expression.module, lv, 1, true, false);
|
FunctionArgument funArg = FunctionArgument.findIn(c, expression.module, lv, 1, true, false);
|
||||||
final CarpetEventServer events = ((CarpetScriptHost) c.host).scriptServer().events;
|
CarpetEventServer events = ((CarpetScriptHost) c.host).scriptServer().events;
|
||||||
if (funArg.function == null)
|
if (funArg.function == null)
|
||||||
{
|
{
|
||||||
types.forEach(et -> events.removeBuiltInEvent(CarpetEventServer.Event.getEntityLoadEventName(et), (CarpetScriptHost) c.host));
|
types.forEach(et -> events.removeBuiltInEvent(CarpetEventServer.Event.getEntityLoadEventName(et), (CarpetScriptHost) c.host));
|
||||||
@@ -301,7 +306,7 @@ public class Entities
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
///compat
|
///compat
|
||||||
final int numberOfArguments = funArg.function.getArguments().size() - funArg.args.size();
|
int numberOfArguments = funArg.function.getArguments().size() - funArg.args.size();
|
||||||
if (numberOfArguments == 1)
|
if (numberOfArguments == 1)
|
||||||
{
|
{
|
||||||
c.host.issueDeprecation("entity_load_handler() with single argument callback");
|
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");
|
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))
|
if (!(v instanceof final EntityValue ev))
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("First argument to entity_event should be an entity");
|
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);
|
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.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
@@ -54,7 +55,7 @@ import net.minecraft.world.phys.Vec3;
|
|||||||
|
|
||||||
public class Inventories
|
public class Inventories
|
||||||
{
|
{
|
||||||
public static void apply(final Expression expression)
|
public static void apply(Expression expression)
|
||||||
{
|
{
|
||||||
expression.addContextFunction("stack_limit", 1, (c, t, lv) ->
|
expression.addContextFunction("stack_limit", 1, (c, t, lv) ->
|
||||||
new NumericValue(NBTSerializableValue.parseItem(lv.get(0).getString(), ((CarpetContext) c).registryAccess()).getItem().getMaxStackSize()));
|
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) ->
|
expression.addContextFunction("item_list", -1, (c, t, lv) ->
|
||||||
{
|
{
|
||||||
final CarpetContext cc = (CarpetContext) c;
|
CarpetContext cc = (CarpetContext) c;
|
||||||
final Registry<Item> items = cc.registry(Registries.ITEM);
|
Registry<Item> items = cc.registry(Registries.ITEM);
|
||||||
if (lv.size() == 0)
|
if (lv.isEmpty())
|
||||||
{
|
{
|
||||||
return ListValue.wrap(items.keySet().stream().map(ValueConversions::of));
|
return ListValue.wrap(items.keySet().stream().map(ValueConversions::of));
|
||||||
}
|
}
|
||||||
final String tag = lv.get(0).getString();
|
String tag = lv.get(0).getString();
|
||||||
final Optional<HolderSet.Named<Item>> itemTag = items.getTag(TagKey.create(Registries.ITEM, InputValidator.identifierOf(tag)));
|
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()))));
|
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) ->
|
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);
|
Registry<Item> blocks = cc.registry(Registries.ITEM);
|
||||||
if (lv.size() == 0)
|
if (lv.isEmpty())
|
||||||
{
|
{
|
||||||
return ListValue.wrap(blocks.getTagNames().map(ValueConversions::of));
|
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)
|
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())));
|
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();
|
String tag = lv.get(1).getString();
|
||||||
final Optional<HolderSet.Named<Item>> tagSet = blocks.getTag(TagKey.create(Registries.ITEM, InputValidator.identifierOf(tag)));
|
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));
|
return tagSet.isEmpty() ? Value.NULL : BooleanValue.of(tagSet.get().stream().anyMatch(h -> h.value() == item));
|
||||||
});
|
});
|
||||||
|
|
||||||
expression.addContextFunction("recipe_data", -1, (c, t, lv) ->
|
expression.addContextFunction("recipe_data", -1, (c, t, lv) ->
|
||||||
{
|
{
|
||||||
final CarpetContext cc = (CarpetContext) c;
|
CarpetContext cc = (CarpetContext) c;
|
||||||
if (lv.size() < 1)
|
if (lv.size() < 1)
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("'recipe_data' requires at least one argument");
|
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;
|
RecipeType<?> type = RecipeType.CRAFTING;
|
||||||
if (lv.size() > 1)
|
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));
|
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())
|
if (recipes.isEmpty())
|
||||||
{
|
{
|
||||||
return Value.NULL;
|
return Value.NULL;
|
||||||
}
|
}
|
||||||
final List<Value> recipesOutput = new ArrayList<>();
|
List<Value> recipesOutput = new ArrayList<>();
|
||||||
final RegistryAccess regs = cc.registryAccess();
|
RegistryAccess regs = cc.registryAccess();
|
||||||
for (final Recipe<?> recipe : recipes)
|
for (Recipe<?> recipe : recipes)
|
||||||
{
|
{
|
||||||
final ItemStack result = recipe.getResultItem(regs);
|
ItemStack result = recipe.getResultItem(regs);
|
||||||
final List<Value> ingredientValue = new ArrayList<>();
|
List<Value> ingredientValue = new ArrayList<>();
|
||||||
recipe.getIngredients().forEach( ingredient -> {
|
recipe.getIngredients().forEach( ingredient -> {
|
||||||
// I am flattening ingredient lists per slot.
|
// I am flattening ingredient lists per slot.
|
||||||
// consider recipe_data('wooden_sword','crafting') and ('iron_nugget', 'blasting') and notice difference
|
// consider recipe_data('wooden_sword','crafting') and ('iron_nugget', 'blasting') and notice difference
|
||||||
// in depths of lists.
|
// in depths of lists.
|
||||||
final List<Collection<ItemStack>> stacks = Vanilla.Ingredient_getRecipeStacks(ingredient);
|
List<Collection<ItemStack>> stacks = Vanilla.Ingredient_getRecipeStacks(ingredient);
|
||||||
if (stacks.isEmpty())
|
if (stacks.isEmpty())
|
||||||
{
|
{
|
||||||
ingredientValue.add(Value.NULL);
|
ingredientValue.add(Value.NULL);
|
||||||
}
|
}
|
||||||
else
|
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));
|
stacks.forEach(col -> col.stream().map(is -> ValueConversions.of(is, regs)).forEach(alternatives::add));
|
||||||
ingredientValue.add(ListValue.wrap(alternatives));
|
ingredientValue.add(ListValue.wrap(alternatives));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
final Value recipeSpec;
|
Value recipeSpec;
|
||||||
if (recipe instanceof final ShapedRecipe shapedRecipe)
|
if (recipe instanceof final ShapedRecipe shapedRecipe)
|
||||||
{
|
{
|
||||||
recipeSpec = ListValue.of(
|
recipeSpec = ListValue.of(
|
||||||
@@ -178,42 +183,41 @@ public class Inventories
|
|||||||
|
|
||||||
expression.addContextFunction("crafting_remaining_item", 1, (c, t, v) ->
|
expression.addContextFunction("crafting_remaining_item", 1, (c, t, v) ->
|
||||||
{
|
{
|
||||||
final String itemStr = v.get(0).getString();
|
String itemStr = v.get(0).getString();
|
||||||
final ResourceLocation id = InputValidator.identifierOf(itemStr);
|
ResourceLocation id = InputValidator.identifierOf(itemStr);
|
||||||
final Registry<Item> registry = ((CarpetContext) c).registry(Registries.ITEM);
|
Registry<Item> registry = ((CarpetContext) c).registry(Registries.ITEM);
|
||||||
final Item item = registry.getOptional(id).orElseThrow(() -> new ThrowStatement(itemStr, Throwables.UNKNOWN_ITEM));
|
Item item = registry.getOptional(id).orElseThrow(() -> new ThrowStatement(itemStr, Throwables.UNKNOWN_ITEM));
|
||||||
return !item.hasCraftingRemainingItem()
|
Item reminder = item.getCraftingRemainingItem();
|
||||||
? Value.NULL
|
return reminder == null ? Value.NULL : NBTSerializableValue.nameFromRegistryId(registry.getKey(reminder));
|
||||||
: new StringValue(NBTSerializableValue.nameFromRegistryId(registry.getKey(item.getCraftingRemainingItem())));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
expression.addContextFunction("inventory_size", -1, (c, t, lv) ->
|
expression.addContextFunction("inventory_size", -1, (c, t, lv) ->
|
||||||
{
|
{
|
||||||
final CarpetContext cc = (CarpetContext) c;
|
CarpetContext cc = (CarpetContext) c;
|
||||||
final NBTSerializableValue.InventoryLocator inventoryLocator = NBTSerializableValue.locateInventory(cc, lv, 0);
|
NBTSerializableValue.InventoryLocator inventoryLocator = NBTSerializableValue.locateInventory(cc, lv, 0);
|
||||||
return inventoryLocator == null ? Value.NULL : new NumericValue(inventoryLocator.inventory().getContainerSize());
|
return inventoryLocator == null ? Value.NULL : new NumericValue(inventoryLocator.inventory().getContainerSize());
|
||||||
});
|
});
|
||||||
|
|
||||||
expression.addContextFunction("inventory_has_items", -1, (c, t, lv) ->
|
expression.addContextFunction("inventory_has_items", -1, (c, t, lv) ->
|
||||||
{
|
{
|
||||||
final CarpetContext cc = (CarpetContext) c;
|
CarpetContext cc = (CarpetContext) c;
|
||||||
final NBTSerializableValue.InventoryLocator inventoryLocator = NBTSerializableValue.locateInventory(cc, lv, 0);
|
NBTSerializableValue.InventoryLocator inventoryLocator = NBTSerializableValue.locateInventory(cc, lv, 0);
|
||||||
return inventoryLocator == null ? Value.NULL : BooleanValue.of(!inventoryLocator.inventory().isEmpty());
|
return inventoryLocator == null ? Value.NULL : BooleanValue.of(!inventoryLocator.inventory().isEmpty());
|
||||||
});
|
});
|
||||||
|
|
||||||
//inventory_get(<b, e>, <n>) -> item_triple
|
//inventory_get(<b, e>, <n>) -> item_triple
|
||||||
expression.addContextFunction("inventory_get", -1, (c, t, lv) ->
|
expression.addContextFunction("inventory_get", -1, (c, t, lv) ->
|
||||||
{
|
{
|
||||||
final CarpetContext cc = (CarpetContext) c;
|
CarpetContext cc = (CarpetContext) c;
|
||||||
final NBTSerializableValue.InventoryLocator inventoryLocator = NBTSerializableValue.locateInventory(cc, lv, 0);
|
NBTSerializableValue.InventoryLocator inventoryLocator = NBTSerializableValue.locateInventory(cc, lv, 0);
|
||||||
if (inventoryLocator == null)
|
if (inventoryLocator == null)
|
||||||
{
|
{
|
||||||
return Value.NULL;
|
return Value.NULL;
|
||||||
}
|
}
|
||||||
final RegistryAccess regs = cc.registryAccess();
|
RegistryAccess regs = cc.registryAccess();
|
||||||
if (lv.size() == inventoryLocator.offset())
|
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++)
|
for (int i = 0, maxi = inventoryLocator.inventory().getContainerSize(); i < maxi; i++)
|
||||||
{
|
{
|
||||||
fullInventory.add(ValueConversions.of(inventoryLocator.inventory().getItem(i), regs));
|
fullInventory.add(ValueConversions.of(inventoryLocator.inventory().getItem(i), regs));
|
||||||
@@ -230,8 +234,8 @@ public class Inventories
|
|||||||
//inventory_set(<b,e>, <n>, <count>, <item>, <nbt>)
|
//inventory_set(<b,e>, <n>, <count>, <item>, <nbt>)
|
||||||
expression.addContextFunction("inventory_set", -1, (c, t, lv) ->
|
expression.addContextFunction("inventory_set", -1, (c, t, lv) ->
|
||||||
{
|
{
|
||||||
final CarpetContext cc = (CarpetContext) c;
|
CarpetContext cc = (CarpetContext) c;
|
||||||
final NBTSerializableValue.InventoryLocator inventoryLocator = NBTSerializableValue.locateInventory(cc, lv, 0);
|
NBTSerializableValue.InventoryLocator inventoryLocator = NBTSerializableValue.locateInventory(cc, lv, 0);
|
||||||
if (inventoryLocator == null)
|
if (inventoryLocator == null)
|
||||||
{
|
{
|
||||||
return Value.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");
|
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());
|
slot = NBTSerializableValue.validateSlot(slot, inventoryLocator.inventory());
|
||||||
if (slot == inventoryLocator.inventory().getContainerSize())
|
if (slot == inventoryLocator.inventory().getContainerSize())
|
||||||
{
|
{
|
||||||
return Value.NULL;
|
return Value.NULL;
|
||||||
}
|
}
|
||||||
final int count = (int) NumericValue.asNumber(lv.get(inventoryLocator.offset() + 1)).getLong();
|
int count = (int) NumericValue.asNumber(lv.get(inventoryLocator.offset() + 1)).getLong();
|
||||||
final RegistryAccess regs = cc.registryAccess();
|
RegistryAccess regs = cc.registryAccess();
|
||||||
if (count == 0)
|
if (count == 0)
|
||||||
{
|
{
|
||||||
// clear slot
|
// clear slot
|
||||||
final ItemStack removedStack = inventoryLocator.inventory().removeItemNoUpdate(slot);
|
ItemStack removedStack = inventoryLocator.inventory().removeItemNoUpdate(slot);
|
||||||
syncPlayerInventory(inventoryLocator, slot);
|
syncPlayerInventory(inventoryLocator, slot);
|
||||||
return ValueConversions.of(removedStack, regs);
|
return ValueConversions.of(removedStack, regs);
|
||||||
}
|
}
|
||||||
if (lv.size() < inventoryLocator.offset() + 3)
|
if (lv.size() < inventoryLocator.offset() + 3)
|
||||||
{
|
{
|
||||||
final ItemStack previousStack = inventoryLocator.inventory().getItem(slot);
|
ItemStack previousStack = inventoryLocator.inventory().getItem(slot);
|
||||||
final ItemStack newStack = previousStack.copy();
|
ItemStack newStack = previousStack.copy();
|
||||||
newStack.setCount(count);
|
newStack.setCount(count);
|
||||||
inventoryLocator.inventory().setItem(slot, newStack);
|
inventoryLocator.inventory().setItem(slot, newStack);
|
||||||
syncPlayerInventory(inventoryLocator, slot);
|
syncPlayerInventory(inventoryLocator, slot);
|
||||||
@@ -267,28 +271,24 @@ public class Inventories
|
|||||||
CompoundTag nbt = null; // skipping one argument
|
CompoundTag nbt = null; // skipping one argument
|
||||||
if (lv.size() > inventoryLocator.offset() + 3)
|
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)
|
if (nbtValue instanceof final NBTSerializableValue nbtsv)
|
||||||
{
|
{
|
||||||
nbt = nbtsv.getCompoundTag();
|
nbt = nbtsv.getCompoundTag();
|
||||||
}
|
}
|
||||||
else if (nbtValue.isNull())
|
else if (!nbtValue.isNull())
|
||||||
{
|
|
||||||
nbt = null;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
nbt = new NBTSerializableValue(nbtValue.getString()).getCompoundTag();
|
nbt = new NBTSerializableValue(nbtValue.getString()).getCompoundTag();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
final ItemInput newitem = NBTSerializableValue.parseItem(lv.get(inventoryLocator.offset() + 2).getString(), nbt, cc.registryAccess());
|
ItemInput newitem = NBTSerializableValue.parseItem(lv.get(inventoryLocator.offset() + 2).getString(), nbt, cc.registryAccess());
|
||||||
final ItemStack previousStack = inventoryLocator.inventory().getItem(slot);
|
ItemStack previousStack = inventoryLocator.inventory().getItem(slot);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
inventoryLocator.inventory().setItem(slot, newitem.createItemStack(count, false));
|
inventoryLocator.inventory().setItem(slot, newitem.createItemStack(count, false));
|
||||||
syncPlayerInventory(inventoryLocator, slot);
|
syncPlayerInventory(inventoryLocator, slot);
|
||||||
}
|
}
|
||||||
catch (final CommandSyntaxException e)
|
catch (CommandSyntaxException e)
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException(e.getMessage());
|
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
|
//inventory_find(<b, e>, <item> or null (first empty slot), <start_from=0> ) -> <N> or null
|
||||||
expression.addContextFunction("inventory_find", -1, (c, t, lv) ->
|
expression.addContextFunction("inventory_find", -1, (c, t, lv) ->
|
||||||
{
|
{
|
||||||
final CarpetContext cc = (CarpetContext) c;
|
CarpetContext cc = (CarpetContext) c;
|
||||||
final NBTSerializableValue.InventoryLocator inventoryLocator = NBTSerializableValue.locateInventory(cc, lv, 0);
|
NBTSerializableValue.InventoryLocator inventoryLocator = NBTSerializableValue.locateInventory(cc, lv, 0);
|
||||||
if (inventoryLocator == null)
|
if (inventoryLocator == null)
|
||||||
{
|
{
|
||||||
return Value.NULL;
|
return Value.NULL;
|
||||||
@@ -307,7 +307,7 @@ public class Inventories
|
|||||||
ItemInput itemArg = null;
|
ItemInput itemArg = null;
|
||||||
if (lv.size() > inventoryLocator.offset())
|
if (lv.size() > inventoryLocator.offset())
|
||||||
{
|
{
|
||||||
final Value secondArg = lv.get(inventoryLocator.offset() + 0);
|
Value secondArg = lv.get(inventoryLocator.offset());
|
||||||
if (!secondArg.isNull())
|
if (!secondArg.isNull())
|
||||||
{
|
{
|
||||||
itemArg = NBTSerializableValue.parseItem(secondArg.getString(), cc.registryAccess());
|
itemArg = NBTSerializableValue.parseItem(secondArg.getString(), cc.registryAccess());
|
||||||
@@ -321,7 +321,7 @@ public class Inventories
|
|||||||
startIndex = NBTSerializableValue.validateSlot(startIndex, inventoryLocator.inventory());
|
startIndex = NBTSerializableValue.validateSlot(startIndex, inventoryLocator.inventory());
|
||||||
for (int i = startIndex, maxi = inventoryLocator.inventory().getContainerSize(); i < maxi; i++)
|
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())))
|
if ((itemArg == null && stack.isEmpty()) || (itemArg != null && itemArg.getItem().equals(stack.getItem())))
|
||||||
{
|
{
|
||||||
return new NumericValue(i);
|
return new NumericValue(i);
|
||||||
@@ -333,8 +333,8 @@ public class Inventories
|
|||||||
//inventory_remove(<b, e>, <item>, <amount=1>) -> bool
|
//inventory_remove(<b, e>, <item>, <amount=1>) -> bool
|
||||||
expression.addContextFunction("inventory_remove", -1, (c, t, lv) ->
|
expression.addContextFunction("inventory_remove", -1, (c, t, lv) ->
|
||||||
{
|
{
|
||||||
final CarpetContext cc = (CarpetContext) c;
|
CarpetContext cc = (CarpetContext) c;
|
||||||
final NBTSerializableValue.InventoryLocator inventoryLocator = NBTSerializableValue.locateInventory(cc, lv, 0);
|
NBTSerializableValue.InventoryLocator inventoryLocator = NBTSerializableValue.locateInventory(cc, lv, 0);
|
||||||
if (inventoryLocator == null)
|
if (inventoryLocator == null)
|
||||||
{
|
{
|
||||||
return Value.NULL;
|
return Value.NULL;
|
||||||
@@ -343,7 +343,7 @@ public class Inventories
|
|||||||
{
|
{
|
||||||
throw new InternalExpressionException("'inventory_remove' requires at least an item to be removed");
|
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;
|
int amount = 1;
|
||||||
if (lv.size() > inventoryLocator.offset() + 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++)
|
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()))
|
if (stack.isEmpty() || !stack.getItem().equals(searchItem.getItem()))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
final int left = stack.getCount() - amount;
|
int left = stack.getCount() - amount;
|
||||||
if (left > 0)
|
if (left > 0)
|
||||||
{
|
{
|
||||||
stack.setCount(left);
|
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
|
//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) ->
|
expression.addContextFunction("drop_item", -1, (c, t, lv) ->
|
||||||
{
|
{
|
||||||
final CarpetContext cc = (CarpetContext) c;
|
CarpetContext cc = (CarpetContext) c;
|
||||||
final NBTSerializableValue.InventoryLocator inventoryLocator = NBTSerializableValue.locateInventory(cc, lv, 0);
|
NBTSerializableValue.InventoryLocator inventoryLocator = NBTSerializableValue.locateInventory(cc, lv, 0);
|
||||||
if (inventoryLocator == null)
|
if (inventoryLocator == null)
|
||||||
{
|
{
|
||||||
return Value.NULL;
|
return Value.NULL;
|
||||||
@@ -409,7 +409,7 @@ public class Inventories
|
|||||||
{
|
{
|
||||||
throw new InternalExpressionException("Cannot throw negative number of items");
|
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())
|
if (stack == null || stack.isEmpty())
|
||||||
{
|
{
|
||||||
return Value.ZERO;
|
return Value.ZERO;
|
||||||
@@ -418,30 +418,34 @@ public class Inventories
|
|||||||
{
|
{
|
||||||
amount = stack.getCount();
|
amount = stack.getCount();
|
||||||
}
|
}
|
||||||
final ItemStack droppedStack = inventoryLocator.inventory().removeItem(slot, amount);
|
ItemStack droppedStack = inventoryLocator.inventory().removeItem(slot, amount);
|
||||||
if (droppedStack.isEmpty())
|
if (droppedStack.isEmpty())
|
||||||
{
|
{
|
||||||
return Value.ZERO;
|
return Value.ZERO;
|
||||||
}
|
}
|
||||||
final Object owner = inventoryLocator.owner();
|
Object owner = inventoryLocator.owner();
|
||||||
final ItemEntity item;
|
ItemEntity item;
|
||||||
if (owner instanceof final Player player)
|
if (owner instanceof final Player player)
|
||||||
{
|
{
|
||||||
item = player.drop(droppedStack, false, true);
|
item = player.drop(droppedStack, false, true);
|
||||||
|
if (item == null)
|
||||||
|
{
|
||||||
|
return Value.ZERO;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (owner instanceof LivingEntity livingEntity)
|
else if (owner instanceof LivingEntity livingEntity)
|
||||||
{
|
{
|
||||||
// stolen from LookTargetUtil.give((VillagerEntity)owner, droppedStack, (LivingEntity) owner);
|
// stolen from LookTargetUtil.give((VillagerEntity)owner, droppedStack, (LivingEntity) owner);
|
||||||
double double_1 = livingEntity.getY() - 0.30000001192092896D + livingEntity.getEyeHeight();
|
double dropY = livingEntity.getY() - 0.30000001192092896D + livingEntity.getEyeHeight();
|
||||||
item = new ItemEntity(livingEntity.level, livingEntity.getX(), double_1, livingEntity.getZ(), droppedStack);
|
item = new ItemEntity(livingEntity.level, livingEntity.getX(), dropY, livingEntity.getZ(), droppedStack);
|
||||||
final Vec3 vec3d = livingEntity.getViewVector(1.0F).normalize().scale(0.3);// new Vec3d(0, 0.3, 0);
|
Vec3 vec3d = livingEntity.getViewVector(1.0F).normalize().scale(0.3);// new Vec3d(0, 0.3, 0);
|
||||||
item.setDeltaMovement(vec3d);
|
item.setDeltaMovement(vec3d);
|
||||||
item.setDefaultPickUpDelay();
|
item.setDefaultPickUpDelay();
|
||||||
cc.level().addFreshEntity(item);
|
cc.level().addFreshEntity(item);
|
||||||
}
|
}
|
||||||
else
|
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 = new ItemEntity(cc.level(), point.x, point.y, point.z, droppedStack);
|
||||||
item.setDefaultPickUpDelay();
|
item.setDefaultPickUpDelay();
|
||||||
cc.level().addFreshEntity(item);
|
cc.level().addFreshEntity(item);
|
||||||
@@ -455,14 +459,14 @@ public class Inventories
|
|||||||
{
|
{
|
||||||
throw new InternalExpressionException("'create_screen' requires at least three arguments");
|
throw new InternalExpressionException("'create_screen' requires at least three arguments");
|
||||||
}
|
}
|
||||||
final Value playerValue = lv.get(0);
|
Value playerValue = lv.get(0);
|
||||||
final ServerPlayer player = EntityValue.getPlayerByValue(((CarpetContext) c).server(), playerValue);
|
ServerPlayer player = EntityValue.getPlayerByValue(((CarpetContext) c).server(), playerValue);
|
||||||
if (player == null)
|
if (player == null)
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("'create_screen' requires a valid online player as the first argument.");
|
throw new InternalExpressionException("'create_screen' requires a valid online player as the first argument.");
|
||||||
}
|
}
|
||||||
final String type = lv.get(1).getString();
|
String type = lv.get(1).getString();
|
||||||
final Component name = FormattedTextValue.getTextByValue(lv.get(2));
|
Component name = FormattedTextValue.getTextByValue(lv.get(2));
|
||||||
FunctionValue function = null;
|
FunctionValue function = null;
|
||||||
if (lv.size() > 3)
|
if (lv.size() > 3)
|
||||||
{
|
{
|
||||||
@@ -474,7 +478,7 @@ public class Inventories
|
|||||||
|
|
||||||
expression.addContextFunction("close_screen", 1, (c, t, lv) ->
|
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))
|
if (!(value instanceof final ScreenValue screenValue))
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("'close_screen' requires a screen value as the first argument.");
|
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");
|
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
|
return lv.size() >= 3
|
||||||
? screenValue.modifyProperty(propertyName, lv.subList(2, lv.size()))
|
? screenValue.modifyProperty(propertyName, lv.subList(2, lv.size()))
|
||||||
: screenValue.queryProperty(propertyName);
|
: 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))
|
if (inventory.owner() instanceof final ServerPlayer player && !inventory.isEnder() && !(inventory.inventory() instanceof ScreenValue.ScreenHandlerInventory))
|
||||||
{
|
{
|
||||||
player.connection.send(new ClientboundContainerSetSlotPacket(
|
player.connection.send(new ClientboundContainerSetSlotPacket(
|
||||||
-2, 0, // resolve mystery argument
|
-2, 0, // resolve mystery argument
|
||||||
int_1,
|
slot,
|
||||||
inventory.inventory().getItem(int_1)
|
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()));
|
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) ->
|
expression.addContextFunction("system_info", -1, (c, t, lv) ->
|
||||||
{
|
{
|
||||||
if (lv.size() == 0)
|
if (lv.isEmpty())
|
||||||
{
|
{
|
||||||
return SystemInfo.getAll();
|
return SystemInfo.getAll();
|
||||||
}
|
}
|
||||||
if (lv.size() == 1)
|
if (lv.size() == 1)
|
||||||
{
|
{
|
||||||
final String what = lv.get(0).getString();
|
String what = lv.get(0).getString();
|
||||||
final Value res = SystemInfo.get(what, (CarpetContext) c);
|
Value res = SystemInfo.get(what, (CarpetContext) c);
|
||||||
if (res == null)
|
if (res == null)
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("Unknown option for 'system_info': " + what);
|
throw new InternalExpressionException("Unknown option for 'system_info': " + what);
|
||||||
@@ -50,21 +50,21 @@ public class Monitoring
|
|||||||
// game processed snooper functions
|
// game processed snooper functions
|
||||||
expression.addContextFunction("get_mob_counts", -1, (c, t, lv) ->
|
expression.addContextFunction("get_mob_counts", -1, (c, t, lv) ->
|
||||||
{
|
{
|
||||||
final CarpetContext cc = (CarpetContext) c;
|
CarpetContext cc = (CarpetContext) c;
|
||||||
final ServerLevel world = cc.level();
|
ServerLevel world = cc.level();
|
||||||
final NaturalSpawner.SpawnState info = world.getChunkSource().getLastSpawnState();
|
NaturalSpawner.SpawnState info = world.getChunkSource().getLastSpawnState();
|
||||||
if (info == null)
|
if (info == null)
|
||||||
{
|
{
|
||||||
return Value.NULL;
|
return Value.NULL;
|
||||||
}
|
}
|
||||||
final Object2IntMap<MobCategory> mobcounts = info.getMobCategoryCounts();
|
Object2IntMap<MobCategory> mobcounts = info.getMobCategoryCounts();
|
||||||
final int chunks = info.getSpawnableChunkCount();
|
int chunks = info.getSpawnableChunkCount();
|
||||||
if (lv.size() == 0)
|
if (lv.isEmpty())
|
||||||
{
|
{
|
||||||
final Map<Value, Value> retDict = new HashMap<>();
|
Map<Value, Value> retDict = new HashMap<>();
|
||||||
for (final MobCategory category : mobcounts.keySet())
|
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(
|
retDict.put(
|
||||||
new StringValue(category.getSerializedName().toLowerCase(Locale.ROOT)),
|
new StringValue(category.getSerializedName().toLowerCase(Locale.ROOT)),
|
||||||
ListValue.of(
|
ListValue.of(
|
||||||
@@ -74,15 +74,15 @@ public class Monitoring
|
|||||||
}
|
}
|
||||||
return MapValue.wrap(retDict);
|
return MapValue.wrap(retDict);
|
||||||
}
|
}
|
||||||
final String catString = lv.get(0).getString();
|
String catString = lv.get(0).getString();
|
||||||
final MobCategory cat = MOB_CATEGORY_MAP.get(catString.toLowerCase(Locale.ROOT));
|
MobCategory cat = MOB_CATEGORY_MAP.get(catString.toLowerCase(Locale.ROOT));
|
||||||
if (cat == null)
|
if (cat == null)
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("Unreconized mob category: " + catString);
|
throw new InternalExpressionException("Unreconized mob category: " + catString);
|
||||||
}
|
}
|
||||||
return ListValue.of(
|
return ListValue.of(
|
||||||
new NumericValue(mobcounts.getInt(cat)),
|
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
|
public class Scoreboards
|
||||||
{
|
{
|
||||||
private static String getScoreboardKeyFromValue(final Value keyValue)
|
private static String getScoreboardKeyFromValue(Value keyValue)
|
||||||
{
|
{
|
||||||
if (keyValue instanceof final EntityValue ev)
|
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 e instanceof Player ? e.getName().getString() : e.getStringUUID();
|
||||||
}
|
}
|
||||||
return keyValue.getString();
|
return keyValue.getString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void apply(final Expression expression)
|
public static void apply(Expression expression)
|
||||||
{
|
{
|
||||||
// scoreboard(player,'objective')
|
// scoreboard(player,'objective')
|
||||||
// scoreboard(player, objective, newValue)
|
// scoreboard(player, objective, newValue)
|
||||||
expression.addContextFunction("scoreboard", -1, (c, t, lv) ->
|
expression.addContextFunction("scoreboard", -1, (c, t, lv) ->
|
||||||
{
|
{
|
||||||
final CarpetContext cc = (CarpetContext) c;
|
CarpetContext cc = (CarpetContext) c;
|
||||||
final Scoreboard scoreboard = cc.server().getScoreboard();
|
Scoreboard scoreboard = cc.server().getScoreboard();
|
||||||
if (lv.size() == 0)
|
if (lv.isEmpty())
|
||||||
{
|
{
|
||||||
return ListValue.wrap(scoreboard.getObjectiveNames().stream().map(StringValue::new));
|
return ListValue.wrap(scoreboard.getObjectiveNames().stream().map(StringValue::new));
|
||||||
}
|
}
|
||||||
final String objectiveName = lv.get(0).getString();
|
String objectiveName = lv.get(0).getString();
|
||||||
final Objective objective = scoreboard.getOrCreateObjective(objectiveName);
|
Objective objective = scoreboard.getOrCreateObjective(objectiveName);
|
||||||
if (objective == null)
|
if (objective == null)
|
||||||
{
|
{
|
||||||
return Value.NULL;
|
return Value.NULL;
|
||||||
@@ -70,7 +70,7 @@ public class Scoreboards
|
|||||||
{
|
{
|
||||||
return ListValue.wrap(scoreboard.getPlayerScores(objective).stream().map(s -> new StringValue(s.getOwner())));
|
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)
|
if (lv.size() == 2)
|
||||||
{
|
{
|
||||||
return !scoreboard.hasPlayerScore(key, objective)
|
return !scoreboard.hasPlayerScore(key, objective)
|
||||||
@@ -78,16 +78,16 @@ public class Scoreboards
|
|||||||
: NumericValue.of(scoreboard.getOrCreatePlayerScore(key, objective).getScore());
|
: NumericValue.of(scoreboard.getOrCreatePlayerScore(key, objective).getScore());
|
||||||
}
|
}
|
||||||
|
|
||||||
final Value value = lv.get(2);
|
Value value = lv.get(2);
|
||||||
if (value.isNull())
|
if (value.isNull())
|
||||||
{
|
{
|
||||||
final Score score = scoreboard.getOrCreatePlayerScore(key, objective);
|
Score score = scoreboard.getOrCreatePlayerScore(key, objective);
|
||||||
scoreboard.resetPlayerScore(key, objective);
|
scoreboard.resetPlayerScore(key, objective);
|
||||||
return NumericValue.of(score.getScore());
|
return NumericValue.of(score.getScore());
|
||||||
}
|
}
|
||||||
if (value instanceof NumericValue)
|
if (value instanceof NumericValue)
|
||||||
{
|
{
|
||||||
final Score score = scoreboard.getOrCreatePlayerScore(key, objective);
|
Score score = scoreboard.getOrCreatePlayerScore(key, objective);
|
||||||
score.setScore(NumericValue.asNumber(value).getInt());
|
score.setScore(NumericValue.asNumber(value).getInt());
|
||||||
return NumericValue.of(score.getScore());
|
return NumericValue.of(score.getScore());
|
||||||
}
|
}
|
||||||
@@ -96,14 +96,14 @@ public class Scoreboards
|
|||||||
|
|
||||||
expression.addContextFunction("scoreboard_remove", -1, (c, t, lv) ->
|
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");
|
throw new InternalExpressionException("'scoreboard_remove' requires at least one parameter");
|
||||||
}
|
}
|
||||||
final CarpetContext cc = (CarpetContext) c;
|
CarpetContext cc = (CarpetContext) c;
|
||||||
final Scoreboard scoreboard = cc.server().getScoreboard();
|
Scoreboard scoreboard = cc.server().getScoreboard();
|
||||||
final String objectiveName = lv.get(0).getString();
|
String objectiveName = lv.get(0).getString();
|
||||||
final Objective objective = scoreboard.getOrCreateObjective(objectiveName);
|
Objective objective = scoreboard.getOrCreateObjective(objectiveName);
|
||||||
if (objective == null)
|
if (objective == null)
|
||||||
{
|
{
|
||||||
return Value.FALSE;
|
return Value.FALSE;
|
||||||
@@ -113,13 +113,13 @@ public class Scoreboards
|
|||||||
scoreboard.removeObjective(objective);
|
scoreboard.removeObjective(objective);
|
||||||
return Value.TRUE;
|
return Value.TRUE;
|
||||||
}
|
}
|
||||||
final String key = getScoreboardKeyFromValue(lv.get(1));
|
String key = getScoreboardKeyFromValue(lv.get(1));
|
||||||
if (!scoreboard.hasPlayerScore(key, objective))
|
if (!scoreboard.hasPlayerScore(key, objective))
|
||||||
{
|
{
|
||||||
return Value.NULL;
|
return Value.NULL;
|
||||||
}
|
}
|
||||||
final Score scoreboardPlayerScore = scoreboard.getOrCreatePlayerScore(key, objective);
|
Score scoreboardPlayerScore = scoreboard.getOrCreatePlayerScore(key, objective);
|
||||||
final Value previous = new NumericValue(scoreboardPlayerScore.getScore());
|
Value previous = new NumericValue(scoreboardPlayerScore.getScore());
|
||||||
scoreboard.resetPlayerScore(key, objective);
|
scoreboard.resetPlayerScore(key, objective);
|
||||||
return previous;
|
return previous;
|
||||||
});
|
});
|
||||||
@@ -129,21 +129,21 @@ public class Scoreboards
|
|||||||
|
|
||||||
expression.addContextFunction("scoreboard_add", -1, (c, t, lv) ->
|
expression.addContextFunction("scoreboard_add", -1, (c, t, lv) ->
|
||||||
{
|
{
|
||||||
final CarpetContext cc = (CarpetContext) c;
|
CarpetContext cc = (CarpetContext) c;
|
||||||
final Scoreboard scoreboard = cc.server().getScoreboard();
|
Scoreboard scoreboard = cc.server().getScoreboard();
|
||||||
if (lv.size() == 0 || lv.size() > 2)
|
if (lv.isEmpty() || lv.size() > 2)
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("'scoreboard_add' should have one or two parameters");
|
throw new InternalExpressionException("'scoreboard_add' should have one or two parameters");
|
||||||
}
|
}
|
||||||
final String objectiveName = lv.get(0).getString();
|
String objectiveName = lv.get(0).getString();
|
||||||
final ObjectiveCriteria criterion;
|
ObjectiveCriteria criterion;
|
||||||
if (lv.size() == 1)
|
if (lv.size() == 1)
|
||||||
{
|
{
|
||||||
criterion = ObjectiveCriteria.DUMMY;
|
criterion = ObjectiveCriteria.DUMMY;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
final String critetionName = lv.get(1).getString();
|
String critetionName = lv.get(1).getString();
|
||||||
criterion = ObjectiveCriteria.byName(critetionName).orElse(null);
|
criterion = ObjectiveCriteria.byName(critetionName).orElse(null);
|
||||||
if (criterion == 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)
|
if (objective != null)
|
||||||
{
|
{
|
||||||
c.host.issueDeprecation("reading or modifying an objective's criterion with scoreboard_add");
|
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.Scoreboard_getObjectivesByCriterion(scoreboard).get(objective.getCriteria()).remove(objective);
|
||||||
Vanilla.Objective_setCriterion(objective, criterion);
|
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);
|
scoreboard.onObjectiveAdded(objective);
|
||||||
return Value.FALSE;
|
return Value.FALSE;
|
||||||
}
|
}
|
||||||
@@ -179,27 +179,27 @@ public class Scoreboards
|
|||||||
{
|
{
|
||||||
throw new InternalExpressionException("'scoreboard_property' requires at least two parameters");
|
throw new InternalExpressionException("'scoreboard_property' requires at least two parameters");
|
||||||
}
|
}
|
||||||
final CarpetContext cc = (CarpetContext) c;
|
CarpetContext cc = (CarpetContext) c;
|
||||||
final Scoreboard scoreboard = cc.server().getScoreboard();
|
Scoreboard scoreboard = cc.server().getScoreboard();
|
||||||
final Objective objective = scoreboard.getOrCreateObjective(lv.get(0).getString());
|
Objective objective = scoreboard.getOrCreateObjective(lv.get(0).getString());
|
||||||
if (objective == null)
|
if (objective == null)
|
||||||
{
|
{
|
||||||
return Value.NULL;
|
return Value.NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
final boolean modify = lv.size() > 2;
|
boolean modify = lv.size() > 2;
|
||||||
Value setValue = null;
|
Value setValue = null;
|
||||||
if (modify)
|
if (modify)
|
||||||
{
|
{
|
||||||
setValue = lv.get(2);
|
setValue = lv.get(2);
|
||||||
}
|
}
|
||||||
final String property = lv.get(1).getString();
|
String property = lv.get(1).getString();
|
||||||
switch (property)
|
switch (property)
|
||||||
{
|
{
|
||||||
case "criterion" -> {
|
case "criterion" -> {
|
||||||
if (modify)
|
if (modify)
|
||||||
{
|
{
|
||||||
final ObjectiveCriteria criterion = ObjectiveCriteria.byName(setValue.getString()).orElse(null);
|
ObjectiveCriteria criterion = ObjectiveCriteria.byName(setValue.getString()).orElse(null);
|
||||||
if (criterion == null)
|
if (criterion == null)
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("Unknown scoreboard criterion: " + setValue.getString());
|
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.Scoreboard_getObjectivesByCriterion(scoreboard).get(objective.getCriteria()).remove(objective);
|
||||||
Vanilla.Objective_setCriterion(objective, criterion);
|
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);
|
scoreboard.onObjectiveAdded(objective);
|
||||||
return Value.TRUE;
|
return Value.TRUE;
|
||||||
}
|
}
|
||||||
@@ -219,7 +219,7 @@ public class Scoreboards
|
|||||||
case "display_name" -> {
|
case "display_name" -> {
|
||||||
if (modify)
|
if (modify)
|
||||||
{
|
{
|
||||||
final Component text = FormattedTextValue.getTextByValue(setValue);
|
Component text = FormattedTextValue.getTextByValue(setValue);
|
||||||
objective.setDisplayName(text);
|
objective.setDisplayName(text);
|
||||||
return Value.TRUE;
|
return Value.TRUE;
|
||||||
}
|
}
|
||||||
@@ -228,7 +228,7 @@ public class Scoreboards
|
|||||||
case "display_slot" -> {
|
case "display_slot" -> {
|
||||||
if (modify)
|
if (modify)
|
||||||
{
|
{
|
||||||
final int slotId = Scoreboard.getDisplaySlotByName(setValue.getString());
|
int slotId = Scoreboard.getDisplaySlotByName(setValue.getString());
|
||||||
if (slotId == -1)
|
if (slotId == -1)
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("Unknown scoreboard display slot: " + setValue.getString());
|
throw new InternalExpressionException("Unknown scoreboard display slot: " + setValue.getString());
|
||||||
@@ -240,12 +240,12 @@ public class Scoreboards
|
|||||||
scoreboard.setDisplayObjective(slotId, objective);
|
scoreboard.setDisplayObjective(slotId, objective);
|
||||||
return Value.TRUE;
|
return Value.TRUE;
|
||||||
}
|
}
|
||||||
final List<Value> slots = new ArrayList<>();
|
List<Value> slots = new ArrayList<>();
|
||||||
for (int i = 0; i < 19; i++)
|
for (int i = 0; i < 19; i++)
|
||||||
{
|
{
|
||||||
if (scoreboard.getDisplayObjective(i) == objective)
|
if (scoreboard.getDisplayObjective(i) == objective)
|
||||||
{
|
{
|
||||||
final String slotName = Scoreboard.getDisplaySlotName(i);
|
String slotName = Scoreboard.getDisplaySlotName(i);
|
||||||
slots.add(StringValue.of(slotName));
|
slots.add(StringValue.of(slotName));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -254,7 +254,7 @@ public class Scoreboards
|
|||||||
case "render_type" -> {
|
case "render_type" -> {
|
||||||
if (modify)
|
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))
|
if (objective.getRenderType().equals(renderType))
|
||||||
{
|
{
|
||||||
return Value.FALSE;
|
return Value.FALSE;
|
||||||
@@ -270,22 +270,22 @@ public class Scoreboards
|
|||||||
|
|
||||||
expression.addContextFunction("scoreboard_display", 2, (c, t, lv) ->
|
expression.addContextFunction("scoreboard_display", 2, (c, t, lv) ->
|
||||||
{
|
{
|
||||||
final CarpetContext cc = (CarpetContext) c;
|
CarpetContext cc = (CarpetContext) c;
|
||||||
final Scoreboard scoreboard = cc.server().getScoreboard();
|
Scoreboard scoreboard = cc.server().getScoreboard();
|
||||||
final String location = lv.get(0).getString();
|
String location = lv.get(0).getString();
|
||||||
final int slot = Scoreboard.getDisplaySlotByName(location);
|
int slot = Scoreboard.getDisplaySlotByName(location);
|
||||||
if (slot < 0)
|
if (slot < 0)
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("Invalid objective slot: " + location);
|
throw new InternalExpressionException("Invalid objective slot: " + location);
|
||||||
}
|
}
|
||||||
final Value target = lv.get(1);
|
Value target = lv.get(1);
|
||||||
if (target.isNull())
|
if (target.isNull())
|
||||||
{
|
{
|
||||||
scoreboard.setDisplayObjective(slot, null);
|
scoreboard.setDisplayObjective(slot, null);
|
||||||
return new NumericValue(slot);
|
return new NumericValue(slot);
|
||||||
}
|
}
|
||||||
final String objectiveString = target.getString();
|
String objectiveString = target.getString();
|
||||||
final Objective objective = scoreboard.getOrCreateObjective(objectiveString);
|
Objective objective = scoreboard.getOrCreateObjective(objectiveString);
|
||||||
if (objective == null)
|
if (objective == null)
|
||||||
{
|
{
|
||||||
return Value.NULL;
|
return Value.NULL;
|
||||||
@@ -300,9 +300,9 @@ public class Scoreboards
|
|||||||
{
|
{
|
||||||
throw new InternalExpressionException("'team_list' requires zero or one parameters");
|
throw new InternalExpressionException("'team_list' requires zero or one parameters");
|
||||||
}
|
}
|
||||||
final CarpetContext cc = (CarpetContext) c;
|
CarpetContext cc = (CarpetContext) c;
|
||||||
final ServerScoreboard scoreboard = cc.server().getScoreboard();
|
ServerScoreboard scoreboard = cc.server().getScoreboard();
|
||||||
if (lv.size() == 0)
|
if (lv.isEmpty())
|
||||||
{
|
{
|
||||||
return ListValue.wrap(scoreboard.getTeamNames().stream().map(StringValue::of));
|
return ListValue.wrap(scoreboard.getTeamNames().stream().map(StringValue::of));
|
||||||
}
|
}
|
||||||
@@ -310,21 +310,21 @@ public class Scoreboards
|
|||||||
{
|
{
|
||||||
return Value.NULL;
|
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));
|
return team == null ? Value.NULL : ListValue.wrap(team.getPlayers().stream().map(StringValue::of));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
expression.addContextFunction("team_add", -1, (c, t, lv) ->
|
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");
|
throw new InternalExpressionException("'team_add' requires one or two parameters");
|
||||||
}
|
}
|
||||||
|
|
||||||
final CarpetContext cc = (CarpetContext) c;
|
CarpetContext cc = (CarpetContext) c;
|
||||||
final ServerScoreboard scoreboard = cc.server().getScoreboard();
|
ServerScoreboard scoreboard = cc.server().getScoreboard();
|
||||||
final String teamName = lv.get(0).getString();
|
String teamName = lv.get(0).getString();
|
||||||
|
|
||||||
if (lv.size() == 1)
|
if (lv.size() == 1)
|
||||||
{
|
{
|
||||||
@@ -339,13 +339,13 @@ public class Scoreboards
|
|||||||
{
|
{
|
||||||
return Value.NULL;
|
return Value.NULL;
|
||||||
}
|
}
|
||||||
final Value playerVal = lv.get(1);
|
Value playerVal = lv.get(1);
|
||||||
final String player = EntityValue.getPlayerNameByValue(playerVal);
|
String player = EntityValue.getPlayerNameByValue(playerVal);
|
||||||
if (player == null)
|
if (player == null)
|
||||||
{
|
{
|
||||||
return Value.NULL;
|
return Value.NULL;
|
||||||
}
|
}
|
||||||
final PlayerTeam team = scoreboard.getPlayerTeam(teamName);
|
PlayerTeam team = scoreboard.getPlayerTeam(teamName);
|
||||||
if (team == null)
|
if (team == null)
|
||||||
{
|
{
|
||||||
return Value.NULL;
|
return Value.NULL;
|
||||||
@@ -354,44 +354,44 @@ public class Scoreboards
|
|||||||
{
|
{
|
||||||
return Value.FALSE;
|
return Value.FALSE;
|
||||||
}
|
}
|
||||||
scoreboard.addPlayerToTeam(player, scoreboard.getPlayerTeam(teamName));
|
scoreboard.addPlayerToTeam(player, team);
|
||||||
return Value.TRUE;
|
return Value.TRUE;
|
||||||
});
|
});
|
||||||
|
|
||||||
expression.addContextFunction("team_remove", 1, (c, t, lv) ->
|
expression.addContextFunction("team_remove", 1, (c, t, lv) ->
|
||||||
{
|
{
|
||||||
final CarpetContext cc = (CarpetContext) c;
|
CarpetContext cc = (CarpetContext) c;
|
||||||
final ServerScoreboard scoreboard = cc.server().getScoreboard();
|
ServerScoreboard scoreboard = cc.server().getScoreboard();
|
||||||
final Value teamVal = lv.get(0);
|
Value teamVal = lv.get(0);
|
||||||
final String team = teamVal.getString();
|
PlayerTeam team = scoreboard.getPlayerTeam(teamVal.getString());
|
||||||
if (scoreboard.getPlayerTeam(team) == null)
|
if (team == null)
|
||||||
{
|
{
|
||||||
return Value.NULL;
|
return Value.NULL;
|
||||||
}
|
}
|
||||||
scoreboard.removePlayerTeam(scoreboard.getPlayerTeam(team));
|
scoreboard.removePlayerTeam(team);
|
||||||
return Value.TRUE;
|
return Value.TRUE;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
expression.addContextFunction("team_leave", 1, (c, t, lv) ->
|
expression.addContextFunction("team_leave", 1, (c, t, lv) ->
|
||||||
{
|
{
|
||||||
final CarpetContext cc = (CarpetContext) c;
|
CarpetContext cc = (CarpetContext) c;
|
||||||
final ServerScoreboard scoreboard = cc.server().getScoreboard();
|
ServerScoreboard scoreboard = cc.server().getScoreboard();
|
||||||
final Value playerVal = lv.get(0);
|
Value playerVal = lv.get(0);
|
||||||
final String player = EntityValue.getPlayerNameByValue(playerVal);
|
String player = EntityValue.getPlayerNameByValue(playerVal);
|
||||||
return player == null ? Value.NULL : BooleanValue.of(scoreboard.removePlayerFromTeam(player));
|
return player == null ? Value.NULL : BooleanValue.of(scoreboard.removePlayerFromTeam(player));
|
||||||
});
|
});
|
||||||
|
|
||||||
expression.addContextFunction("team_property", -1, (c, t, lv) ->
|
expression.addContextFunction("team_property", -1, (c, t, lv) ->
|
||||||
{
|
{
|
||||||
final CarpetContext cc = (CarpetContext) c;
|
CarpetContext cc = (CarpetContext) c;
|
||||||
final ServerScoreboard scoreboard = cc.server().getScoreboard();
|
ServerScoreboard scoreboard = cc.server().getScoreboard();
|
||||||
if (lv.size() < 2 || lv.size() > 3)
|
if (lv.size() < 2 || lv.size() > 3)
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("'team_property' requires two or three arguments");
|
throw new InternalExpressionException("'team_property' requires two or three arguments");
|
||||||
}
|
}
|
||||||
final Value teamVal = lv.get(0);
|
Value teamVal = lv.get(0);
|
||||||
final Value propertyVal = lv.get(1);
|
Value propertyVal = lv.get(1);
|
||||||
|
|
||||||
Value settingVal = null;
|
Value settingVal = null;
|
||||||
boolean modifying = false;
|
boolean modifying = false;
|
||||||
@@ -401,7 +401,7 @@ public class Scoreboards
|
|||||||
settingVal = lv.get(2);
|
settingVal = lv.get(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
final PlayerTeam team = scoreboard.getPlayerTeam(teamVal.getString());
|
PlayerTeam team = scoreboard.getPlayerTeam(teamVal.getString());
|
||||||
if (team == null)
|
if (team == null)
|
||||||
{
|
{
|
||||||
return Value.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());
|
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)
|
if (collisionRule == null)
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("Unknown value for property " + propertyVal.getString() + ": " + settingVal.getString());
|
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());
|
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())
|
if (color == null || !color.isColor())
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("Unknown value for property " + propertyVal.getString() + ": " + settingVal.getString());
|
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());
|
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)
|
if (deathMessageVisibility == null)
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("Unknown value for property " + propertyVal.getString() + ": " + settingVal.getString());
|
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());
|
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)
|
if (nametagVisibility == null)
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("Unknown value for property " + propertyVal.getString() + ": " + settingVal.getString());
|
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) ->
|
expression.addContextFunction("bossbar", -1, (c, t, lv) ->
|
||||||
{
|
{
|
||||||
final CustomBossEvents bossBarManager = ((CarpetContext) c).server().getCustomBossEvents();
|
CustomBossEvents bossBarManager = ((CarpetContext) c).server().getCustomBossEvents();
|
||||||
if (lv.size() > 3)
|
if (lv.size() > 3)
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("'bossbar' accepts max three arguments");
|
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));
|
return ListValue.wrap(bossBarManager.getEvents().stream().map(CustomBossEvent::getTextId).map(ResourceLocation::toString).map(StringValue::of));
|
||||||
}
|
}
|
||||||
|
|
||||||
final String id = lv.get(0).getString();
|
String id = lv.get(0).getString();
|
||||||
final ResourceLocation identifier = InputValidator.identifierOf(id);
|
ResourceLocation identifier = InputValidator.identifierOf(id);
|
||||||
|
|
||||||
if (lv.size() == 1)
|
if (lv.size() == 1)
|
||||||
{
|
{
|
||||||
@@ -563,25 +563,25 @@ public class Scoreboards
|
|||||||
return StringValue.of(bossBarManager.create(identifier, Component.literal(id)).getTextId().toString());
|
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)
|
if (bossBar == null)
|
||||||
{
|
{
|
||||||
return Value.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)
|
switch (property)
|
||||||
{
|
{
|
||||||
case "color" -> {
|
case "color" -> {
|
||||||
if (propertyValue == null)
|
if (propertyValue == null)
|
||||||
{
|
{
|
||||||
final BossEvent.BossBarColor color = (bossBar).getColor();
|
BossEvent.BossBarColor color = (bossBar).getColor();
|
||||||
return color == null ? Value.NULL : StringValue.of(color.getName());
|
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)
|
if (color == null)
|
||||||
{
|
{
|
||||||
return Value.NULL;
|
return Value.NULL;
|
||||||
@@ -616,8 +616,8 @@ public class Scoreboards
|
|||||||
}
|
}
|
||||||
if (propertyValue instanceof final ListValue list)
|
if (propertyValue instanceof final ListValue list)
|
||||||
{
|
{
|
||||||
list.getItems().forEach((v) -> {
|
list.getItems().forEach(v -> {
|
||||||
final ServerPlayer player = EntityValue.getPlayerByValue(((CarpetContext) c).server(), propertyValue);
|
ServerPlayer player = EntityValue.getPlayerByValue(((CarpetContext) c).server(), propertyValue);
|
||||||
if (player != null)
|
if (player != null)
|
||||||
{
|
{
|
||||||
bossBar.addPlayer(player);
|
bossBar.addPlayer(player);
|
||||||
@@ -625,7 +625,7 @@ public class Scoreboards
|
|||||||
});
|
});
|
||||||
return Value.TRUE;
|
return Value.TRUE;
|
||||||
}
|
}
|
||||||
final ServerPlayer player = EntityValue.getPlayerByValue(((CarpetContext) c).server(), propertyValue);
|
ServerPlayer player = EntityValue.getPlayerByValue(((CarpetContext) c).server(), propertyValue);
|
||||||
if (player != null)
|
if (player != null)
|
||||||
{
|
{
|
||||||
bossBar.addPlayer(player);
|
bossBar.addPlayer(player);
|
||||||
@@ -650,7 +650,7 @@ public class Scoreboards
|
|||||||
});
|
});
|
||||||
return Value.TRUE;
|
return Value.TRUE;
|
||||||
}
|
}
|
||||||
final ServerPlayer p = EntityValue.getPlayerByValue(((CarpetContext) c).server(), propertyValue);
|
ServerPlayer p = EntityValue.getPlayerByValue(((CarpetContext) c).server(), propertyValue);
|
||||||
bossBar.removeAllPlayers();
|
bossBar.removeAllPlayers();
|
||||||
if (p != null)
|
if (p != null)
|
||||||
{
|
{
|
||||||
@@ -664,7 +664,7 @@ public class Scoreboards
|
|||||||
{
|
{
|
||||||
return StringValue.of(bossBar.getOverlay().getName());
|
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)
|
if (style == null)
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("'" + propertyValue.getString() + "' is not a valid value for property " + property);
|
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)
|
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) -> {
|
expression.addContextFunction("task_join", 1, (c, t, lv) -> {
|
||||||
if (((CarpetContext) c).server().isSameThread())
|
if (((CarpetContext) c).server().isSameThread())
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("'task_join' cannot be called from main thread to avoid deadlocks");
|
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))
|
if (!(v instanceof final ThreadValue tv))
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("'task_join' could only be used with a task value");
|
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
|
// has to be lazy due to deferred execution of the expression
|
||||||
expression.addLazyFunctionWithDelegation("task_dock", 1, false, true, (c, t, expr, tok, lv) -> {
|
expression.addLazyFunctionWithDelegation("task_dock", 1, false, true, (c, t, expr, tok, lv) -> {
|
||||||
final CarpetContext cc = (CarpetContext) c;
|
CarpetContext cc = (CarpetContext) c;
|
||||||
final MinecraftServer server = cc.server();
|
MinecraftServer server = cc.server();
|
||||||
if (server.isSameThread())
|
if (server.isSameThread())
|
||||||
{
|
{
|
||||||
return lv.get(0); // pass through for on thread tasks
|
return lv.get(0); // pass through for on thread tasks
|
||||||
}
|
}
|
||||||
final Value[] result = new Value[]{Value.NULL};
|
Value[] result = new Value[]{Value.NULL};
|
||||||
final RuntimeException[] internal = new RuntimeException[]{null};
|
RuntimeException[] internal = new RuntimeException[]{null};
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
((CarpetContext) c).server().executeBlocking(() ->
|
((CarpetContext) c).server().executeBlocking(() ->
|
||||||
@@ -46,22 +46,22 @@ public class Threading
|
|||||||
{
|
{
|
||||||
result[0] = lv.get(0).evalValue(c, t);
|
result[0] = lv.get(0).evalValue(c, t);
|
||||||
}
|
}
|
||||||
catch (final ExpressionException exc)
|
catch (ExpressionException exc)
|
||||||
{
|
{
|
||||||
internal[0] = exc;
|
internal[0] = exc;
|
||||||
}
|
}
|
||||||
catch (final InternalExpressionException exc)
|
catch (InternalExpressionException exc)
|
||||||
{
|
{
|
||||||
internal[0] = new ExpressionException(c, expr, tok, exc.getMessage(), exc.stack);
|
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());
|
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");
|
throw new InternalExpressionException("Error while executing docked task section, internal stack trace is gone");
|
||||||
}
|
}
|
||||||
@@ -69,8 +69,8 @@ public class Threading
|
|||||||
{
|
{
|
||||||
throw internal[0];
|
throw internal[0];
|
||||||
}
|
}
|
||||||
final Value ret = result[0]; // preventing from lazy evaluating of the result in case a future completes later
|
Value ret = result[0]; // preventing from lazy evaluating of the result in case a future completes later
|
||||||
return (_c, _t) -> ret;
|
return (ct, tt) -> ret;
|
||||||
// pass through placeholder
|
// pass through placeholder
|
||||||
// implmenetation should dock the task on the main thread.
|
// 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 abstract class Argument
|
||||||
{
|
{
|
||||||
public int offset;
|
public final int offset;
|
||||||
|
|
||||||
protected Argument(int offset)
|
protected Argument(int offset)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -14,53 +14,55 @@ import java.util.NoSuchElementException;
|
|||||||
|
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
public class BlockArgument extends Argument
|
public class BlockArgument extends Argument
|
||||||
{
|
{
|
||||||
public final BlockValue block;
|
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);
|
super(o);
|
||||||
block = b;
|
block = b;
|
||||||
replacement = null;
|
replacement = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private BlockArgument(final BlockValue b, final int o, final String replacement)
|
private BlockArgument(BlockValue b, int o, @Nullable String replacement)
|
||||||
{
|
{
|
||||||
super(o);
|
super(o);
|
||||||
block = b;
|
block = b;
|
||||||
this.replacement = replacement;
|
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);
|
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);
|
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);
|
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
|
try
|
||||||
{
|
{
|
||||||
final Value v1 = params.next();
|
Value v1 = params.next();
|
||||||
//add conditional from string name
|
//add conditional from string name
|
||||||
if (optional && v1.isNull())
|
if (optional && v1.isNull())
|
||||||
{
|
{
|
||||||
return new BlockArgument(null, 1 + offset);
|
return new MissingBlockArgument(1 + offset, null);
|
||||||
}
|
}
|
||||||
if (anyString && v1 instanceof StringValue)
|
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)
|
if (acceptString && v1 instanceof StringValue)
|
||||||
{
|
{
|
||||||
@@ -70,28 +72,26 @@ public class BlockArgument extends Argument
|
|||||||
{
|
{
|
||||||
return new BlockArgument(((BlockValue) v1), 1 + offset);
|
return new BlockArgument(((BlockValue) v1), 1 + offset);
|
||||||
}
|
}
|
||||||
final BlockPos pos = c.origin();
|
BlockPos pos = c.origin();
|
||||||
if (v1 instanceof ListValue)
|
if (v1 instanceof ListValue)
|
||||||
{
|
{
|
||||||
final List<Value> args = ((ListValue) v1).getItems();
|
List<Value> args = ((ListValue) v1).getItems();
|
||||||
final int xpos = (int) NumericValue.asNumber(args.get(0)).getLong();
|
int xpos = (int) NumericValue.asNumber(args.get(0)).getLong();
|
||||||
final int ypos = (int) NumericValue.asNumber(args.get(1)).getLong();
|
int ypos = (int) NumericValue.asNumber(args.get(1)).getLong();
|
||||||
final int zpos = (int) NumericValue.asNumber(args.get(2)).getLong();
|
int zpos = (int) NumericValue.asNumber(args.get(2)).getLong();
|
||||||
|
|
||||||
return new BlockArgument(
|
return new BlockArgument(
|
||||||
new BlockValue(
|
new BlockValue(
|
||||||
null,
|
|
||||||
c.level(),
|
c.level(),
|
||||||
new BlockPos(pos.getX() + xpos, pos.getY() + ypos, pos.getZ() + zpos)
|
new BlockPos(pos.getX() + xpos, pos.getY() + ypos, pos.getZ() + zpos)
|
||||||
),
|
),
|
||||||
1 + offset);
|
1 + offset);
|
||||||
}
|
}
|
||||||
final int xpos = (int) NumericValue.asNumber(v1).getLong();
|
int xpos = (int) NumericValue.asNumber(v1).getLong();
|
||||||
final int ypos = (int) NumericValue.asNumber(params.next()).getLong();
|
int ypos = (int) NumericValue.asNumber(params.next()).getLong();
|
||||||
final int zpos = (int) NumericValue.asNumber(params.next()).getLong();
|
int zpos = (int) NumericValue.asNumber(params.next()).getLong();
|
||||||
return new BlockArgument(
|
return new BlockArgument(
|
||||||
new BlockValue(
|
new BlockValue(
|
||||||
null,
|
|
||||||
c.level(),
|
c.level(),
|
||||||
new BlockPos(pos.getX() + xpos, pos.getY() + ypos, pos.getZ() + zpos)
|
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";
|
String message = "Block-type argument should be defined either by three coordinates (a triple or by three arguments), or a block value";
|
||||||
if (acceptString)
|
if (acceptString)
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import net.minecraft.nbt.TagTypes;
|
|||||||
import org.apache.commons.io.FilenameUtils;
|
import org.apache.commons.io.FilenameUtils;
|
||||||
import org.apache.commons.lang3.tuple.Pair;
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
import java.io.BufferedInputStream;
|
import java.io.BufferedInputStream;
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.BufferedWriter;
|
import java.io.BufferedWriter;
|
||||||
@@ -50,15 +51,15 @@ import java.util.stream.Stream;
|
|||||||
|
|
||||||
public class FileArgument
|
public class FileArgument
|
||||||
{
|
{
|
||||||
public String resource;
|
public final String resource;
|
||||||
public Type type;
|
public final Type type;
|
||||||
public String zipContainer;
|
public final String zipContainer;
|
||||||
public boolean isFolder;
|
public final boolean isFolder;
|
||||||
public boolean isShared;
|
public final boolean isShared;
|
||||||
public Reason reason;
|
public final Reason reason;
|
||||||
private FileSystem zfs;
|
private FileSystem zfs;
|
||||||
private Path zipPath;
|
private Path zipPath;
|
||||||
private ScriptHost host;
|
private final ScriptHost host;
|
||||||
|
|
||||||
public static final Object writeIOSync = new Object();
|
public static final Object writeIOSync = new Object();
|
||||||
|
|
||||||
@@ -70,7 +71,7 @@ public class FileArgument
|
|||||||
{
|
{
|
||||||
zfs.close();
|
zfs.close();
|
||||||
}
|
}
|
||||||
catch (final IOException e)
|
catch (IOException e)
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("Unable to close zip container: " + zipContainer);
|
throw new InternalExpressionException("Unable to close zip container: " + zipContainer);
|
||||||
}
|
}
|
||||||
@@ -90,9 +91,9 @@ public class FileArgument
|
|||||||
private final String id;
|
private final String id;
|
||||||
private final String extension;
|
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.id = id;
|
||||||
this.extension = extension;
|
this.extension = extension;
|
||||||
@@ -104,7 +105,7 @@ public class FileArgument
|
|||||||
READ, CREATE, DELETE
|
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.resource = resource;
|
||||||
this.type = type;
|
this.type = type;
|
||||||
@@ -120,24 +121,24 @@ public class FileArgument
|
|||||||
@Override
|
@Override
|
||||||
public String toString()
|
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)
|
if (lv.size() < 2)
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("File functions require path and type as first two arguments");
|
throw new InternalExpressionException("File functions require path and type as first two arguments");
|
||||||
}
|
}
|
||||||
final String origtype = lv.get(1).getString().toLowerCase(Locale.ROOT);
|
String origtype = lv.get(1).getString().toLowerCase(Locale.ROOT);
|
||||||
final boolean shared = origtype.startsWith("shared_");
|
boolean shared = origtype.startsWith("shared_");
|
||||||
final String typeString = shared ? origtype.substring(7) : origtype; //len(shared_)
|
String typeString = shared ? origtype.substring(7) : origtype; //len(shared_)
|
||||||
final Type type = Type.of.get(typeString);
|
Type type = Type.of.get(typeString);
|
||||||
final Pair<String, String> resource = recognizeResource(lv.get(0).getString(), isFolder, type);
|
|
||||||
if (type == null)
|
if (type == null)
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("Unsupported file type: " + origtype);
|
throw new InternalExpressionException("Unsupported file type: " + origtype);
|
||||||
}
|
}
|
||||||
|
Pair<String, String> resource = recognizeResource(lv.get(0).getString(), isFolder, type);
|
||||||
if (type == Type.FOLDER && !isFolder)
|
if (type == Type.FOLDER && !isFolder)
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("Folder types are no supported for this IO function");
|
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);
|
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("[/\\\\]+");
|
String[] pathElements = origfile.split("[/\\\\]+");
|
||||||
final List<String> path = new ArrayList<>();
|
List<String> path = new ArrayList<>();
|
||||||
String zipPath = null;
|
String zipPath = null;
|
||||||
for (int i = 0; i < pathElements.length; i++)
|
for (int i = 0; i < pathElements.length; i++)
|
||||||
{
|
{
|
||||||
String token = pathElements[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)
|
if (zipPath != null && isZip)
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException(token + " indicates zip access in an already zipped location " + zipPath);
|
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);
|
return Pair.of(String.join("/", path), zipPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Path resolve(final String suffix)
|
private Path resolve(String suffix)
|
||||||
{
|
{
|
||||||
return host.resolveScriptFile(suffix);
|
return host.resolveScriptFile(suffix);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Path toPath(final Module module)
|
@Nullable
|
||||||
|
private Path toPath(@Nullable Module module)
|
||||||
{
|
{
|
||||||
if (!isShared && module == null)
|
if (!isShared && module == null)
|
||||||
{
|
{
|
||||||
@@ -215,7 +217,7 @@ public class FileArgument
|
|||||||
{
|
{
|
||||||
if (zfs == null)
|
if (zfs == null)
|
||||||
{
|
{
|
||||||
final Map<String, String> env = new HashMap<>();
|
Map<String, String> env = new HashMap<>();
|
||||||
if (reason == Reason.CREATE)
|
if (reason == Reason.CREATE)
|
||||||
{
|
{
|
||||||
env.put("create", "true");
|
env.put("create", "true");
|
||||||
@@ -233,7 +235,7 @@ public class FileArgument
|
|||||||
}
|
}
|
||||||
zfs = FileSystems.newFileSystem(URI.create("jar:" + zipPath.toUri()), env);
|
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);
|
CarpetScriptServer.LOG.warn("Exception when opening zip file", e);
|
||||||
throw new ThrowStatement("Unable to open zip file: " + zipContainer, Throwables.IO_EXCEPTION);
|
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
|
return !isShared && module == null
|
||||||
? null
|
? null
|
||||||
@@ -255,7 +258,7 @@ public class FileArgument
|
|||||||
return (isShared ? "shared/" : "") + (zipContainer != null ? zipContainer + "/" : "") + resource + type.extension;
|
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)
|
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
|
try
|
||||||
{
|
{
|
||||||
synchronized (writeIOSync)
|
synchronized (writeIOSync)
|
||||||
{
|
{
|
||||||
final Path dataFile = toPath(module);//, resourceName, supportedTypes.get(type), isShared);
|
Path dataFile = toPath(module);//, resourceName, supportedTypes.get(type), isShared);
|
||||||
if (dataFile == null)
|
if (dataFile == null)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@@ -291,14 +294,15 @@ public class FileArgument
|
|||||||
return true;
|
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))
|
if (dir == null || !Files.exists(dir))
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
final String ext = type.extension;
|
String ext = type.extension;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return Files.list(dir).filter(path -> (type == Type.FOLDER)
|
return Files.list(dir).filter(path -> (type == Type.FOLDER)
|
||||||
@@ -306,16 +310,17 @@ public class FileArgument
|
|||||||
: (Files.isRegularFile(path) && path.toString().endsWith(ext))
|
: (Files.isRegularFile(path) && path.toString().endsWith(ext))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
catch (final IOException ignored)
|
catch (IOException ignored)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Stream<String> listFolder(final Module module)
|
@Nullable
|
||||||
|
public Stream<String> listFolder(Module module)
|
||||||
{
|
{
|
||||||
Stream<String> strings;
|
Stream<String> strings;
|
||||||
try (final Stream<Path> result = listFiles(module))
|
try (Stream<Path> result = listFiles(module))
|
||||||
{
|
{
|
||||||
synchronized (writeIOSync)
|
synchronized (writeIOSync)
|
||||||
{
|
{
|
||||||
@@ -323,12 +328,12 @@ public class FileArgument
|
|||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
final Path rootPath = moduleRootPath(module);
|
Path rootPath = moduleRootPath(module);
|
||||||
if (rootPath == null)
|
if (rootPath == null)
|
||||||
{
|
{
|
||||||
return 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
|
// need to evaluate the stream before exiting try-with-resources else there'll be no data to stream
|
||||||
strings = (zipContainer == null)
|
strings = (zipContainer == null)
|
||||||
? result.map(p -> rootPath.relativize(p).toString().replaceAll("[\\\\/]+", "/")).toList().stream()
|
? result.map(p -> rootPath.relativize(p).toString().replaceAll("[\\\\/]+", "/")).toList().stream()
|
||||||
@@ -345,7 +350,7 @@ public class FileArgument
|
|||||||
: strings.map(FilenameUtils::removeExtension);
|
: strings.map(FilenameUtils::removeExtension);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createPaths(final Path file)
|
private void createPaths(Path file)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -357,29 +362,29 @@ public class FileArgument
|
|||||||
throw new IOException();
|
throw new IOException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (final IOException e)
|
catch (IOException e)
|
||||||
{
|
{
|
||||||
CarpetScriptServer.LOG.warn("IOException when creating paths", e);
|
CarpetScriptServer.LOG.warn("IOException when creating paths", e);
|
||||||
throw new ThrowStatement("Unable to create paths for " + file, Throwables.IO_EXCEPTION);
|
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
|
try
|
||||||
{
|
{
|
||||||
synchronized (writeIOSync)
|
synchronized (writeIOSync)
|
||||||
{
|
{
|
||||||
final Path dataFile = toPath(module);
|
Path dataFile = toPath(module);
|
||||||
if (dataFile == null)
|
if (dataFile == null)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
createPaths(dataFile);
|
createPaths(dataFile);
|
||||||
final OutputStream out = Files.newOutputStream(dataFile, StandardOpenOption.APPEND, StandardOpenOption.CREATE);
|
OutputStream out = Files.newOutputStream(dataFile, StandardOpenOption.APPEND, StandardOpenOption.CREATE);
|
||||||
try (final BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out, StandardCharsets.UTF_8)))
|
try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out, StandardCharsets.UTF_8)))
|
||||||
{
|
{
|
||||||
for (final String line : message)
|
for (String line : message)
|
||||||
{
|
{
|
||||||
writer.append(line);
|
writer.append(line);
|
||||||
if (type == Type.TEXT)
|
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);
|
CarpetScriptServer.LOG.warn("IOException when appending to text file", e);
|
||||||
throw new ThrowStatement("Error when writing to the file: " + e, Throwables.IO_EXCEPTION);
|
throw new ThrowStatement("Error when writing to the file: " + e, Throwables.IO_EXCEPTION);
|
||||||
@@ -402,13 +407,14 @@ public class FileArgument
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Tag getNbtData(final Module module) // aka getData
|
@Nullable
|
||||||
|
public Tag getNbtData(Module module) // aka getData
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
synchronized (writeIOSync)
|
synchronized (writeIOSync)
|
||||||
{
|
{
|
||||||
final Path dataFile = toPath(module);
|
Path dataFile = toPath(module);
|
||||||
if (dataFile == null || !Files.exists(dataFile))
|
if (dataFile == null || !Files.exists(dataFile))
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
@@ -424,29 +430,30 @@ public class FileArgument
|
|||||||
|
|
||||||
//copied private method from net.minecraft.nbt.NbtIo.read()
|
//copied private method from net.minecraft.nbt.NbtIo.read()
|
||||||
// to read non-compound tags - these won't be compressed
|
// 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
|
try
|
||||||
{
|
{
|
||||||
return NbtIo.readCompressed(Files.newInputStream(path));
|
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
|
// Copy of NbtIo.read(File) because that's now client-side only
|
||||||
if (!Files.exists(path))
|
if (!Files.exists(path))
|
||||||
{
|
{
|
||||||
return null;
|
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);
|
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
|
// 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)
|
if (b == 0)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
@@ -457,7 +464,7 @@ public class FileArgument
|
|||||||
return TagTypes.getType(b).load(dataInputStream, 0, NbtAccounter.UNLIMITED);
|
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 when trying to read nbt file, something may have gone wrong with the fs", e);
|
||||||
CarpetScriptServer.LOG.warn("", ioException);
|
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
|
try
|
||||||
{
|
{
|
||||||
synchronized (writeIOSync)
|
synchronized (writeIOSync)
|
||||||
{
|
{
|
||||||
final Path dataFile = toPath(module);
|
Path dataFile = toPath(module);
|
||||||
if (dataFile == null)
|
if (dataFile == null)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@@ -494,9 +501,9 @@ public class FileArgument
|
|||||||
}
|
}
|
||||||
|
|
||||||
//copied private method from net.minecraft.nbt.NbtIo.write() and client method safe_write
|
//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
|
try
|
||||||
{
|
{
|
||||||
if (!zipped)
|
if (!zipped)
|
||||||
@@ -511,7 +518,7 @@ public class FileArgument
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
try (final DataOutputStream dataOutputStream = new DataOutputStream(Files.newOutputStream(path)))
|
try (DataOutputStream dataOutputStream = new DataOutputStream(Files.newOutputStream(path)))
|
||||||
{
|
{
|
||||||
dataOutputStream.writeByte(tag.getId());
|
dataOutputStream.writeByte(tag.getId());
|
||||||
if (tag.getId() != 0)
|
if (tag.getId() != 0)
|
||||||
@@ -528,20 +535,20 @@ public class FileArgument
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
catch (final IOException e)
|
catch (IOException e)
|
||||||
{
|
{
|
||||||
CarpetScriptServer.LOG.warn("IO Exception when writing nbt file", e);
|
CarpetScriptServer.LOG.warn("IO Exception when writing nbt file", e);
|
||||||
throw new ThrowStatement("Unable to write tag to " + original, Throwables.IO_EXCEPTION);
|
throw new ThrowStatement("Unable to write tag to " + original, Throwables.IO_EXCEPTION);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean dropExistingFile(final Module module)
|
public boolean dropExistingFile(Module module)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
synchronized (writeIOSync)
|
synchronized (writeIOSync)
|
||||||
{
|
{
|
||||||
final Path dataFile = toPath(module);
|
Path dataFile = toPath(module);
|
||||||
if (dataFile == null)
|
if (dataFile == null)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@@ -549,7 +556,7 @@ public class FileArgument
|
|||||||
return Files.deleteIfExists(dataFile);
|
return Files.deleteIfExists(dataFile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (final IOException e)
|
catch (IOException e)
|
||||||
{
|
{
|
||||||
CarpetScriptServer.LOG.warn("IOException when removing file", e);
|
CarpetScriptServer.LOG.warn("IOException when removing file", e);
|
||||||
throw new ThrowStatement("Error while removing file: " + getDisplayPath(), Throwables.IO_EXCEPTION);
|
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
|
try
|
||||||
{
|
{
|
||||||
synchronized (writeIOSync)
|
synchronized (writeIOSync)
|
||||||
{
|
{
|
||||||
final Path dataFile = toPath(module);
|
Path dataFile = toPath(module);
|
||||||
if (dataFile == null)
|
if (dataFile == null)
|
||||||
{
|
{
|
||||||
return 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 (; ; )
|
for (; ; )
|
||||||
{
|
{
|
||||||
final String line = reader.readLine();
|
String line = reader.readLine();
|
||||||
if (line == null)
|
if (line == null)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
@@ -600,20 +608,21 @@ public class FileArgument
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
catch (final IOException e)
|
catch (IOException e)
|
||||||
{
|
{
|
||||||
CarpetScriptServer.LOG.warn("IOException when reading text file", e);
|
CarpetScriptServer.LOG.warn("IOException when reading text file", e);
|
||||||
throw new ThrowStatement("Failed to read text file " + filePath, Throwables.IO_EXCEPTION);
|
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
|
try
|
||||||
{
|
{
|
||||||
synchronized (writeIOSync)
|
synchronized (writeIOSync)
|
||||||
{
|
{
|
||||||
final Path dataFile = toPath(module);
|
Path dataFile = toPath(module);
|
||||||
if (dataFile == null || !Files.exists(dataFile))
|
if (dataFile == null || !Files.exists(dataFile))
|
||||||
{
|
{
|
||||||
return null;
|
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);
|
return JsonParser.parseReader(reader);
|
||||||
}
|
}
|
||||||
catch (final JsonParseException e)
|
catch (JsonParseException e)
|
||||||
{
|
{
|
||||||
Throwable exc = e;
|
Throwable exc = e;
|
||||||
if (e.getCause() != null)
|
if (e.getCause() != null)
|
||||||
@@ -645,7 +654,7 @@ public class FileArgument
|
|||||||
StringValue.of("path"), StringValue.of(filePath.toString())
|
StringValue.of("path"), StringValue.of(filePath.toString())
|
||||||
)), Throwables.JSON_ERROR);
|
)), Throwables.JSON_ERROR);
|
||||||
}
|
}
|
||||||
catch (final IOException e)
|
catch (IOException e)
|
||||||
{
|
{
|
||||||
CarpetScriptServer.LOG.warn("IOException when reading JSON file", e);
|
CarpetScriptServer.LOG.warn("IOException when reading JSON file", e);
|
||||||
throw new ThrowStatement("Failed to read json file content " + filePath, Throwables.IO_EXCEPTION);
|
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 carpet.script.value.Value;
|
||||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class FunctionArgument extends Argument
|
public class FunctionArgument extends Argument
|
||||||
{
|
{
|
||||||
public FunctionValue function;
|
public final FunctionValue function;
|
||||||
public List<Value> args;
|
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);
|
super(offset);
|
||||||
this.function = function;
|
this.function = function;
|
||||||
@@ -38,12 +39,12 @@ public class FunctionArgument extends Argument
|
|||||||
* @return argument data
|
* @return argument data
|
||||||
*/
|
*/
|
||||||
public static FunctionArgument findIn(
|
public static FunctionArgument findIn(
|
||||||
final Context c,
|
Context c,
|
||||||
final Module module,
|
Module module,
|
||||||
final List<Value> params,
|
List<Value> params,
|
||||||
final int offset,
|
int offset,
|
||||||
final boolean allowNone,
|
boolean allowNone,
|
||||||
final boolean checkArgs)
|
boolean checkArgs)
|
||||||
{
|
{
|
||||||
Value functionValue = params.get(offset);
|
Value functionValue = params.get(offset);
|
||||||
if (functionValue.isNull())
|
if (functionValue.isNull())
|
||||||
@@ -56,14 +57,14 @@ public class FunctionArgument extends Argument
|
|||||||
}
|
}
|
||||||
if (!(functionValue instanceof FunctionValue))
|
if (!(functionValue instanceof FunctionValue))
|
||||||
{
|
{
|
||||||
final String name = functionValue.getString();
|
String name = functionValue.getString();
|
||||||
functionValue = c.host.getAssertFunction(module, name);
|
functionValue = c.host.getAssertFunction(module, name);
|
||||||
}
|
}
|
||||||
final FunctionValue fun = (FunctionValue) functionValue;
|
FunctionValue fun = (FunctionValue) functionValue;
|
||||||
final int argsize = fun.getArguments().size();
|
int argsize = fun.getArguments().size();
|
||||||
if (checkArgs)
|
if (checkArgs)
|
||||||
{
|
{
|
||||||
final int extraargs = params.size() - argsize - offset - 1;
|
int extraargs = params.size() - argsize - offset - 1;
|
||||||
if (extraargs < 0)
|
if (extraargs < 0)
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("Function " + fun.getPrettyString() + " requires at least " + fun.getArguments().size() + " arguments");
|
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");
|
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++)
|
for (int i = offset + 1, mx = params.size(); i < mx; i++)
|
||||||
{
|
{
|
||||||
lvargs.add(params.get(i));
|
lvargs.add(params.get(i));
|
||||||
@@ -81,27 +82,27 @@ public class FunctionArgument extends Argument
|
|||||||
return new FunctionArgument(fun, offset + 1 + argsize, lvargs);
|
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();
|
List<Value> args = Collections.emptyList();
|
||||||
if (!(funSpec instanceof ListValue))
|
if (!(funSpec instanceof ListValue))
|
||||||
{
|
{
|
||||||
funSpec = ListValue.of(funSpec);
|
funSpec = ListValue.of(funSpec);
|
||||||
}
|
}
|
||||||
final List<Value> params = ((ListValue) funSpec).getItems();
|
List<Value> params = ((ListValue) funSpec).getItems();
|
||||||
if (params.isEmpty())
|
if (params.isEmpty())
|
||||||
{
|
{
|
||||||
throw CommandArgument.error("Function has empty spec");
|
throw CommandArgument.error("Function has empty spec");
|
||||||
}
|
}
|
||||||
final Value first = params.get(0);
|
Value first = params.get(0);
|
||||||
if (first instanceof FunctionValue)
|
if (first instanceof FunctionValue)
|
||||||
{
|
{
|
||||||
function = (FunctionValue) first;
|
function = (FunctionValue) first;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
final String name = first.getString();
|
String name = first.getString();
|
||||||
function = host.getFunction(name);
|
function = host.getFunction(name);
|
||||||
if (function == null)
|
if (function == null)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -14,15 +14,18 @@ import java.util.NoSuchElementException;
|
|||||||
import net.minecraft.world.entity.Entity;
|
import net.minecraft.world.entity.Entity;
|
||||||
import net.minecraft.world.phys.Vec3;
|
import net.minecraft.world.phys.Vec3;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
public class Vector3Argument extends Argument
|
public class Vector3Argument extends Argument
|
||||||
{
|
{
|
||||||
public Vec3 vec;
|
public Vec3 vec;
|
||||||
public final double yaw;
|
public final double yaw;
|
||||||
public final double pitch;
|
public final double pitch;
|
||||||
public boolean fromBlock = false;
|
public boolean fromBlock = false;
|
||||||
|
@Nullable
|
||||||
public Entity entity = null;
|
public Entity entity = null;
|
||||||
|
|
||||||
private Vector3Argument(final Vec3 v, final int o)
|
private Vector3Argument(Vec3 v, int o)
|
||||||
{
|
{
|
||||||
super(o);
|
super(o);
|
||||||
this.vec = v;
|
this.vec = v;
|
||||||
@@ -30,7 +33,7 @@ public class Vector3Argument extends Argument
|
|||||||
this.pitch = 0.0D;
|
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);
|
super(o);
|
||||||
this.vec = v;
|
this.vec = v;
|
||||||
@@ -44,40 +47,40 @@ public class Vector3Argument extends Argument
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Vector3Argument withEntity(final Entity e)
|
private Vector3Argument withEntity(Entity e)
|
||||||
{
|
{
|
||||||
entity = e;
|
entity = e;
|
||||||
return this;
|
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);
|
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);
|
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
|
try
|
||||||
{
|
{
|
||||||
final Value v1 = params.next();
|
Value v1 = params.next();
|
||||||
if (v1 instanceof BlockValue)
|
if (v1 instanceof BlockValue)
|
||||||
{
|
{
|
||||||
return (new Vector3Argument(Vec3.atCenterOf(((BlockValue) v1).getPos()), 1 + offset)).fromBlock();
|
return (new Vector3Argument(Vec3.atCenterOf(((BlockValue) v1).getPos()), 1 + offset)).fromBlock();
|
||||||
}
|
}
|
||||||
if (optionalEntity && v1 instanceof EntityValue)
|
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);
|
return new Vector3Argument(e.position(), 1 + offset).withEntity(e);
|
||||||
}
|
}
|
||||||
if (v1 instanceof ListValue)
|
if (v1 instanceof ListValue)
|
||||||
{
|
{
|
||||||
final List<Value> args = ((ListValue) v1).getItems();
|
List<Value> args = ((ListValue) v1).getItems();
|
||||||
final Vec3 pos = new Vec3(
|
Vec3 pos = new Vec3(
|
||||||
NumericValue.asNumber(args.get(0)).getDouble(),
|
NumericValue.asNumber(args.get(0)).getDouble(),
|
||||||
NumericValue.asNumber(args.get(1)).getDouble(),
|
NumericValue.asNumber(args.get(1)).getDouble(),
|
||||||
NumericValue.asNumber(args.get(2)).getDouble());
|
NumericValue.asNumber(args.get(2)).getDouble());
|
||||||
@@ -90,7 +93,7 @@ public class Vector3Argument extends Argument
|
|||||||
}
|
}
|
||||||
return new Vector3Argument(pos, offset + 1, yaw, pitch);
|
return new Vector3Argument(pos, offset + 1, yaw, pitch);
|
||||||
}
|
}
|
||||||
final Vec3 pos = new Vec3(
|
Vec3 pos = new Vec3(
|
||||||
NumericValue.asNumber(v1).getDouble(),
|
NumericValue.asNumber(v1).getDouble(),
|
||||||
NumericValue.asNumber(params.next()).getDouble(),
|
NumericValue.asNumber(params.next()).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);
|
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");
|
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.phys.Vec2;
|
||||||
import net.minecraft.world.scores.Scoreboard;
|
import net.minecraft.world.scores.Scoreboard;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
import static net.minecraft.commands.Commands.argument;
|
import static net.minecraft.commands.Commands.argument;
|
||||||
|
|
||||||
public abstract class CommandArgument
|
public abstract class CommandArgument
|
||||||
{
|
{
|
||||||
public static CommandSyntaxException error(final String text)
|
public static CommandSyntaxException error(String text)
|
||||||
{
|
{
|
||||||
return new SimpleCommandExceptionType(Component.literal(text)).create();
|
return new SimpleCommandExceptionType(Component.literal(text)).create();
|
||||||
}
|
}
|
||||||
@@ -133,7 +135,7 @@ public abstract class CommandArgument
|
|||||||
new VanillaUnconfigurableArgument("block", BlockStateArgument::block,
|
new VanillaUnconfigurableArgument("block", BlockStateArgument::block,
|
||||||
(c, p) -> {
|
(c, p) -> {
|
||||||
BlockInput result = BlockStateArgument.getBlock(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)
|
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
|
(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) -> {
|
(c, p) -> {
|
||||||
ResourceOrTagArgument.Result<Biome> result = ResourceOrTagArgument.getResourceOrTag(c, "biome", Registries.BIOME);
|
ResourceOrTagArgument.Result<Biome> result = ResourceOrTagArgument.getResourceOrTag(c, "biome", Registries.BIOME);
|
||||||
Either<Holder.Reference<Biome>, HolderSet.Named<Biome>> res = result.unwrap();
|
Either<Holder.Reference<Biome>, HolderSet.Named<Biome>> res = result.unwrap();
|
||||||
@@ -270,7 +272,7 @@ public abstract class CommandArgument
|
|||||||
new VanillaUnconfigurableArgument("uuid", UuidArgument::uuid,
|
new VanillaUnconfigurableArgument("uuid", UuidArgument::uuid,
|
||||||
(c, p) -> StringValue.of(UuidArgument.getUuid(c, p).toString()), false
|
(c, p) -> StringValue.of(UuidArgument.getUuid(c, p).toString()), false
|
||||||
),
|
),
|
||||||
new VanillaUnconfigurableArgument("surfacelocation", () -> Vec2Argument.vec2(), // vec2
|
new VanillaUnconfigurableArgument("surfacelocation", Vec2Argument::vec2,
|
||||||
(c, p) -> {
|
(c, p) -> {
|
||||||
Vec2 res = Vec2Argument.getVec2(c, p);
|
Vec2 res = Vec2Argument.getVec2(c, p);
|
||||||
return ListValue.of(NumericValue.of(res.x), NumericValue.of(res.y));
|
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 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;
|
CommandArgument arg;
|
||||||
for (int i = 0; i < components.length; i++)
|
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);
|
arg = host.appArgTypes.get(candidate);
|
||||||
if (arg != null)
|
if (arg != null)
|
||||||
{
|
{
|
||||||
@@ -305,9 +307,9 @@ public abstract class CommandArgument
|
|||||||
return DEFAULT;
|
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)
|
if (arg.suggestionProvider != null)
|
||||||
{
|
{
|
||||||
return argument(param, arg.getArgumentType(host)).suggests(arg.suggestionProvider.apply(param));
|
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));
|
return argument(param, arg.getArgumentType(host));
|
||||||
}
|
}
|
||||||
final String hostName = host.getName();
|
String hostName = host.getName();
|
||||||
final CarpetScriptServer scriptServer = host.scriptServer();
|
CarpetScriptServer scriptServer = host.scriptServer();
|
||||||
return argument(param, arg.getArgumentType(host)).suggests((ctx, b) -> {
|
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);
|
return arg.suggest(ctx, b, cHost);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
protected String suffix;
|
protected String suffix;
|
||||||
|
@Nullable
|
||||||
protected Collection<String> examples;
|
protected Collection<String> examples;
|
||||||
protected boolean needsMatching;
|
protected boolean needsMatching;
|
||||||
protected boolean caseSensitive = true;
|
protected boolean caseSensitive = true;
|
||||||
@@ -333,9 +336,9 @@ public abstract class CommandArgument
|
|||||||
|
|
||||||
|
|
||||||
protected CommandArgument(
|
protected CommandArgument(
|
||||||
final String suffix,
|
String suffix,
|
||||||
final Collection<String> examples,
|
@Nullable Collection<String> examples,
|
||||||
final boolean suggestFromExamples)
|
boolean suggestFromExamples)
|
||||||
{
|
{
|
||||||
this.suffix = suffix;
|
this.suffix = suffix;
|
||||||
this.examples = examples;
|
this.examples = examples;
|
||||||
@@ -345,7 +348,7 @@ public abstract class CommandArgument
|
|||||||
protected abstract ArgumentType<?> getArgumentType(CarpetScriptHost host) throws CommandSyntaxException;
|
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);
|
return getTypeForArgument(param, host).getValueFromContext(context, param);
|
||||||
}
|
}
|
||||||
@@ -357,24 +360,24 @@ public abstract class CommandArgument
|
|||||||
return suffix;
|
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"))
|
if (!config.containsKey("type"))
|
||||||
{
|
{
|
||||||
throw CommandArgument.error("Custom type " + suffix + " should at least specify the 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))
|
if (!builtIns.containsKey(baseType))
|
||||||
{
|
{
|
||||||
throw CommandArgument.error("Unknown base type " + baseType + " for custom type " + suffix);
|
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.suffix = suffix;
|
||||||
variant.configure(config, host);
|
variant.configure(config, host);
|
||||||
return variant;
|
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();
|
caseSensitive = config.getOrDefault("case_sensitive", Value.TRUE).getBoolean();
|
||||||
if (config.containsKey("suggester"))
|
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);
|
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))
|
if (!(suggestionValue instanceof ListValue))
|
||||||
{
|
{
|
||||||
throw error("Argument suggestions needs to be a list" + " for custom type " + suffix);
|
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(
|
public CompletableFuture<Suggestions> suggest(
|
||||||
final CommandContext<CommandSourceStack> context,
|
CommandContext<CommandSourceStack> context,
|
||||||
final SuggestionsBuilder suggestionsBuilder,
|
SuggestionsBuilder suggestionsBuilder,
|
||||||
final CarpetScriptHost host
|
CarpetScriptHost host
|
||||||
) throws CommandSyntaxException
|
) throws CommandSyntaxException
|
||||||
{
|
{
|
||||||
String prefix = suggestionsBuilder.getRemaining();
|
String prefix = suggestionsBuilder.getRemaining();
|
||||||
@@ -417,41 +420,41 @@ public abstract class CommandArgument
|
|||||||
return suggestionsBuilder.buildFuture();
|
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());
|
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)
|
if (customSuggester != null)
|
||||||
{
|
{
|
||||||
final Runnable currentSection = Carpet.startProfilerSection("Scarpet command");
|
Runnable currentSection = Carpet.startProfilerSection("Scarpet command");
|
||||||
final Map<Value, Value> params = new HashMap<>();
|
Map<Value, Value> params = new HashMap<>();
|
||||||
for (final ParsedCommandNode<CommandSourceStack> pnode : context.getNodes())
|
for (ParsedCommandNode<CommandSourceStack> pnode : context.getNodes())
|
||||||
{
|
{
|
||||||
final CommandNode<CommandSourceStack> node = pnode.getNode();
|
CommandNode<CommandSourceStack> node = pnode.getNode();
|
||||||
if (node instanceof ArgumentCommandNode)
|
if (node instanceof ArgumentCommandNode)
|
||||||
{
|
{
|
||||||
params.put(StringValue.of(node.getName()), CommandArgument.getValue(context, node.getName(), host));
|
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.add(MapValue.wrap(params));
|
||||||
args.addAll(customSuggester.args);
|
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))
|
if (!(response instanceof ListValue))
|
||||||
{
|
{
|
||||||
throw error("Custom suggester should return a list of options" + " for custom type " + suffix);
|
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();
|
currentSection.run();
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
return needsMatching ? examples : Collections.singletonList("... " + getTypeSuffix());
|
return needsMatching ? examples : Collections.singletonList("... " + getTypeSuffix());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean optionMatchesPrefix(final String prefix, String option)
|
protected boolean optionMatchesPrefix(String prefix, String option)
|
||||||
{
|
{
|
||||||
if (!caseSensitive)
|
if (!caseSensitive)
|
||||||
{
|
{
|
||||||
@@ -480,13 +483,13 @@ public abstract class CommandArgument
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ArgumentType<?> getArgumentType(final CarpetScriptHost host)
|
public ArgumentType<?> getArgumentType(CarpetScriptHost host)
|
||||||
{
|
{
|
||||||
return StringArgumentType.string();
|
return StringArgumentType.string();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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);
|
String choseValue = StringArgumentType.getString(context, param);
|
||||||
if (!caseSensitive)
|
if (!caseSensitive)
|
||||||
@@ -501,12 +504,12 @@ public abstract class CommandArgument
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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);
|
super.configure(config, host);
|
||||||
if (config.containsKey("options"))
|
if (config.containsKey("options"))
|
||||||
{
|
{
|
||||||
final Value optionsValue = config.get("options");
|
Value optionsValue = config.get("options");
|
||||||
if (!(optionsValue instanceof ListValue))
|
if (!(optionsValue instanceof ListValue))
|
||||||
{
|
{
|
||||||
throw error("Custom string type requires options passed as a list" + " for custom type " + suffix);
|
throw error("Custom string type requires options passed as a list" + " for custom type " + suffix);
|
||||||
@@ -518,13 +521,13 @@ public abstract class CommandArgument
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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;
|
return validOptions.isEmpty() ? super.getOptions(context, host) : validOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Supplier<CommandArgument> factory(final MinecraftServer server)
|
protected Supplier<CommandArgument> factory(MinecraftServer server)
|
||||||
{
|
{
|
||||||
return StringArgument::new;
|
return StringArgument::new;
|
||||||
}
|
}
|
||||||
@@ -540,13 +543,13 @@ public abstract class CommandArgument
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ArgumentType<?> getArgumentType(final CarpetScriptHost host)
|
public ArgumentType<?> getArgumentType(CarpetScriptHost host)
|
||||||
{
|
{
|
||||||
return StringArgumentType.word();
|
return StringArgumentType.word();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Supplier<CommandArgument> factory(final MinecraftServer server)
|
protected Supplier<CommandArgument> factory(MinecraftServer server)
|
||||||
{
|
{
|
||||||
return WordArgument::new;
|
return WordArgument::new;
|
||||||
}
|
}
|
||||||
@@ -562,13 +565,13 @@ public abstract class CommandArgument
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ArgumentType<?> getArgumentType(final CarpetScriptHost host)
|
public ArgumentType<?> getArgumentType(CarpetScriptHost host)
|
||||||
{
|
{
|
||||||
return StringArgumentType.greedyString();
|
return StringArgumentType.greedyString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Supplier<CommandArgument> factory(final MinecraftServer server)
|
protected Supplier<CommandArgument> factory(MinecraftServer server)
|
||||||
{
|
{
|
||||||
return GreedyStringArgument::new;
|
return GreedyStringArgument::new;
|
||||||
}
|
}
|
||||||
@@ -584,29 +587,29 @@ public abstract class CommandArgument
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ArgumentType<?> getArgumentType(final CarpetScriptHost host)
|
public ArgumentType<?> getArgumentType(CarpetScriptHost host)
|
||||||
{
|
{
|
||||||
return net.minecraft.commands.arguments.coordinates.BlockPosArgument.blockPos();
|
return net.minecraft.commands.arguments.coordinates.BlockPosArgument.blockPos();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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.getLoadedBlockPos(context, param)
|
||||||
: net.minecraft.commands.arguments.coordinates.BlockPosArgument.getSpawnablePos(context, param);
|
: net.minecraft.commands.arguments.coordinates.BlockPosArgument.getSpawnablePos(context, param);
|
||||||
return ValueConversions.of(pos);
|
return ValueConversions.of(pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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);
|
super.configure(config, host);
|
||||||
mustBeLoaded = config.getOrDefault("loaded", Value.FALSE).getBoolean();
|
mustBeLoaded = config.getOrDefault("loaded", Value.FALSE).getBoolean();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Supplier<CommandArgument> factory(final MinecraftServer server)
|
protected Supplier<CommandArgument> factory(MinecraftServer server)
|
||||||
{
|
{
|
||||||
return BlockPosArgument::new;
|
return BlockPosArgument::new;
|
||||||
}
|
}
|
||||||
@@ -623,26 +626,26 @@ public abstract class CommandArgument
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected ArgumentType<?> getArgumentType(final CarpetScriptHost host)
|
protected ArgumentType<?> getArgumentType(CarpetScriptHost host)
|
||||||
{
|
{
|
||||||
return Vec3Argument.vec3(blockCentered);
|
return Vec3Argument.vec3(blockCentered);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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));
|
return ValueConversions.of(Vec3Argument.getVec3(context, param));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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);
|
super.configure(config, host);
|
||||||
blockCentered = config.getOrDefault("block_centered", Value.TRUE).getBoolean();
|
blockCentered = config.getOrDefault("block_centered", Value.TRUE).getBoolean();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Supplier<CommandArgument> factory(final MinecraftServer server)
|
protected Supplier<CommandArgument> factory(MinecraftServer server)
|
||||||
{
|
{
|
||||||
return LocationArgument::new;
|
return LocationArgument::new;
|
||||||
}
|
}
|
||||||
@@ -661,7 +664,7 @@ public abstract class CommandArgument
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected ArgumentType<?> getArgumentType(final CarpetScriptHost host)
|
protected ArgumentType<?> getArgumentType(CarpetScriptHost host)
|
||||||
{
|
{
|
||||||
if (onlyFans)
|
if (onlyFans)
|
||||||
{
|
{
|
||||||
@@ -671,14 +674,14 @@ public abstract class CommandArgument
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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)
|
if (!single)
|
||||||
{
|
{
|
||||||
return ListValue.wrap(founds.stream().map(EntityValue::new));
|
return ListValue.wrap(founds.stream().map(EntityValue::new));
|
||||||
}
|
}
|
||||||
if (founds.size() == 0)
|
if (founds.isEmpty())
|
||||||
{
|
{
|
||||||
return Value.NULL;
|
return Value.NULL;
|
||||||
}
|
}
|
||||||
@@ -690,7 +693,7 @@ public abstract class CommandArgument
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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);
|
super.configure(config, host);
|
||||||
onlyFans = config.getOrDefault("players", Value.FALSE).getBoolean();
|
onlyFans = config.getOrDefault("players", Value.FALSE).getBoolean();
|
||||||
@@ -698,7 +701,7 @@ public abstract class CommandArgument
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Supplier<CommandArgument> factory(final MinecraftServer server)
|
protected Supplier<CommandArgument> factory(MinecraftServer server)
|
||||||
{
|
{
|
||||||
return EntityArgument::new;
|
return EntityArgument::new;
|
||||||
}
|
}
|
||||||
@@ -715,20 +718,20 @@ public abstract class CommandArgument
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected ArgumentType<?> getArgumentType(final CarpetScriptHost host)
|
protected ArgumentType<?> getArgumentType(CarpetScriptHost host)
|
||||||
{
|
{
|
||||||
return GameProfileArgument.gameProfile();
|
return GameProfileArgument.gameProfile();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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)
|
if (!single)
|
||||||
{
|
{
|
||||||
return ListValue.wrap(profiles.stream().map(p -> StringValue.of(p.getName())));
|
return ListValue.wrap(profiles.stream().map(p -> StringValue.of(p.getName())));
|
||||||
}
|
}
|
||||||
final int size = profiles.size();
|
int size = profiles.size();
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
{
|
{
|
||||||
return Value.NULL;
|
return Value.NULL;
|
||||||
@@ -741,14 +744,14 @@ public abstract class CommandArgument
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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);
|
super.configure(config, host);
|
||||||
single = config.getOrDefault("single", Value.FALSE).getBoolean();
|
single = config.getOrDefault("single", Value.FALSE).getBoolean();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Supplier<CommandArgument> factory(final MinecraftServer server)
|
protected Supplier<CommandArgument> factory(MinecraftServer server)
|
||||||
{
|
{
|
||||||
return PlayerProfileArgument::new;
|
return PlayerProfileArgument::new;
|
||||||
}
|
}
|
||||||
@@ -766,20 +769,20 @@ public abstract class CommandArgument
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected ArgumentType<?> getArgumentType(final CarpetScriptHost host)
|
protected ArgumentType<?> getArgumentType(CarpetScriptHost host)
|
||||||
{
|
{
|
||||||
return single ? ScoreHolderArgument.scoreHolder() : ScoreHolderArgument.scoreHolders();
|
return single ? ScoreHolderArgument.scoreHolder() : ScoreHolderArgument.scoreHolders();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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)
|
if (!single)
|
||||||
{
|
{
|
||||||
return ListValue.wrap(holders.stream().map(StringValue::of));
|
return ListValue.wrap(holders.stream().map(StringValue::of));
|
||||||
}
|
}
|
||||||
final int size = holders.size();
|
int size = holders.size();
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
{
|
{
|
||||||
return Value.NULL;
|
return Value.NULL;
|
||||||
@@ -792,14 +795,14 @@ public abstract class CommandArgument
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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);
|
super.configure(config, host);
|
||||||
single = config.getOrDefault("single", Value.FALSE).getBoolean();
|
single = config.getOrDefault("single", Value.FALSE).getBoolean();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Supplier<CommandArgument> factory(final MinecraftServer server)
|
protected Supplier<CommandArgument> factory(MinecraftServer server)
|
||||||
{
|
{
|
||||||
return PlayerProfileArgument::new;
|
return PlayerProfileArgument::new;
|
||||||
}
|
}
|
||||||
@@ -816,13 +819,13 @@ public abstract class CommandArgument
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected ArgumentType<?> getArgumentType(final CarpetScriptHost host)
|
protected ArgumentType<?> getArgumentType(CarpetScriptHost host)
|
||||||
{
|
{
|
||||||
return mapRequired ? CompoundTagArgument.compoundTag() : NbtTagArgument.nbtTag();
|
return mapRequired ? CompoundTagArgument.compoundTag() : NbtTagArgument.nbtTag();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Value getValueFromContext(final CommandContext<CommandSourceStack> context, final String param) throws CommandSyntaxException
|
protected Value getValueFromContext(CommandContext<CommandSourceStack> context, String param)
|
||||||
{
|
{
|
||||||
return mapRequired
|
return mapRequired
|
||||||
? new NBTSerializableValue(CompoundTagArgument.getCompoundTag(context, param))
|
? new NBTSerializableValue(CompoundTagArgument.getCompoundTag(context, param))
|
||||||
@@ -830,14 +833,14 @@ public abstract class CommandArgument
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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);
|
super.configure(config, host);
|
||||||
mapRequired = !config.getOrDefault("allow_element", Value.FALSE).getBoolean();
|
mapRequired = !config.getOrDefault("allow_element", Value.FALSE).getBoolean();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Supplier<CommandArgument> factory(final MinecraftServer server)
|
protected Supplier<CommandArgument> factory(MinecraftServer server)
|
||||||
{
|
{
|
||||||
return TagArgument::new;
|
return TagArgument::new;
|
||||||
}
|
}
|
||||||
@@ -853,15 +856,15 @@ public abstract class CommandArgument
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected ArgumentType<?> getArgumentType(final CarpetScriptHost host)
|
protected ArgumentType<?> getArgumentType(CarpetScriptHost host)
|
||||||
{
|
{
|
||||||
return ResourceLocationArgument.id();
|
return ResourceLocationArgument.id();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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))
|
if (!validOptions.isEmpty() && !validOptions.contains(choseValue))
|
||||||
{
|
{
|
||||||
throw new SimpleCommandExceptionType(Component.literal("Incorrect value for " + param + ": " + choseValue + " for custom type " + suffix)).create();
|
throw new SimpleCommandExceptionType(Component.literal("Incorrect value for " + param + ": " + choseValue + " for custom type " + suffix)).create();
|
||||||
@@ -870,18 +873,18 @@ public abstract class CommandArgument
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Supplier<CommandArgument> factory(final MinecraftServer server)
|
protected Supplier<CommandArgument> factory(MinecraftServer server)
|
||||||
{
|
{
|
||||||
return CustomIdentifierArgument::new;
|
return CustomIdentifierArgument::new;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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);
|
super.configure(config, host);
|
||||||
if (config.containsKey("options"))
|
if (config.containsKey("options"))
|
||||||
{
|
{
|
||||||
final Value optionsValue = config.get("options");
|
Value optionsValue = config.get("options");
|
||||||
if (!(optionsValue instanceof ListValue))
|
if (!(optionsValue instanceof ListValue))
|
||||||
{
|
{
|
||||||
throw error("Custom sting type requires options passed as a list" + " for custom type " + suffix);
|
throw error("Custom sting type requires options passed as a list" + " for custom type " + suffix);
|
||||||
@@ -902,7 +905,7 @@ public abstract class CommandArgument
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ArgumentType<?> getArgumentType(final CarpetScriptHost host)
|
public ArgumentType<?> getArgumentType(CarpetScriptHost host)
|
||||||
{
|
{
|
||||||
if (min != null)
|
if (min != null)
|
||||||
{
|
{
|
||||||
@@ -916,13 +919,13 @@ public abstract class CommandArgument
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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));
|
return new NumericValue(DoubleArgumentType.getDouble(context, param));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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);
|
super.configure(config, host);
|
||||||
if (config.containsKey("min"))
|
if (config.containsKey("min"))
|
||||||
@@ -940,7 +943,7 @@ public abstract class CommandArgument
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Supplier<CommandArgument> factory(final MinecraftServer server)
|
protected Supplier<CommandArgument> factory(MinecraftServer server)
|
||||||
{
|
{
|
||||||
return FloatArgument::new;
|
return FloatArgument::new;
|
||||||
}
|
}
|
||||||
@@ -957,7 +960,7 @@ public abstract class CommandArgument
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ArgumentType<?> getArgumentType(final CarpetScriptHost host)
|
public ArgumentType<?> getArgumentType(CarpetScriptHost host)
|
||||||
{
|
{
|
||||||
if (min != null)
|
if (min != null)
|
||||||
{
|
{
|
||||||
@@ -971,13 +974,13 @@ public abstract class CommandArgument
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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));
|
return new NumericValue(LongArgumentType.getLong(context, param));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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);
|
super.configure(config, host);
|
||||||
if (config.containsKey("min"))
|
if (config.containsKey("min"))
|
||||||
@@ -995,7 +998,7 @@ public abstract class CommandArgument
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Supplier<CommandArgument> factory(final MinecraftServer server)
|
protected Supplier<CommandArgument> factory(MinecraftServer server)
|
||||||
{
|
{
|
||||||
return IntArgument::new;
|
return IntArgument::new;
|
||||||
}
|
}
|
||||||
@@ -1011,7 +1014,7 @@ public abstract class CommandArgument
|
|||||||
private static final Map<String, ContainerIds> RESTRICTED_CONTAINERS = new HashMap<>()
|
private static final Map<String, ContainerIds> RESTRICTED_CONTAINERS = new HashMap<>()
|
||||||
{{
|
{{
|
||||||
int i;
|
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<>()));
|
put(source, new ContainerIds(new IntOpenHashSet(), new HashSet<>()));
|
||||||
}
|
}
|
||||||
@@ -1031,13 +1034,13 @@ public abstract class CommandArgument
|
|||||||
{
|
{
|
||||||
get("player").commandIds().add("inventory." + i);
|
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("player").commandIds().add(place);
|
||||||
get("equipment").commandIds().add(place);
|
get("equipment").commandIds().add(place);
|
||||||
get("weapon").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("player").commandIds().add(place);
|
||||||
get("equipment").commandIds().add(place);
|
get("equipment").commandIds().add(place);
|
||||||
@@ -1106,15 +1109,15 @@ public abstract class CommandArgument
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected ArgumentType<?> getArgumentType(final CarpetScriptHost host) throws CommandSyntaxException
|
protected ArgumentType<?> getArgumentType(CarpetScriptHost host)
|
||||||
{
|
{
|
||||||
return net.minecraft.commands.arguments.SlotArgument.slot();
|
return net.minecraft.commands.arguments.SlotArgument.slot();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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))
|
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();
|
throw new SimpleCommandExceptionType(Component.literal("Incorrect slot restricted to " + restrict + " for custom type " + suffix)).create();
|
||||||
@@ -1123,7 +1126,7 @@ public abstract class CommandArgument
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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);
|
super.configure(config, host);
|
||||||
if (config.containsKey("restrict"))
|
if (config.containsKey("restrict"))
|
||||||
@@ -1138,13 +1141,13 @@ public abstract class CommandArgument
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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();
|
return restrict == null ? super.getOptions(context, host) : RESTRICTED_CONTAINERS.get(restrict).commandIds();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Supplier<CommandArgument> factory(final MinecraftServer server)
|
protected Supplier<CommandArgument> factory(MinecraftServer server)
|
||||||
{
|
{
|
||||||
return SlotArgument::new;
|
return SlotArgument::new;
|
||||||
}
|
}
|
||||||
@@ -1176,10 +1179,10 @@ public abstract class CommandArgument
|
|||||||
private final boolean providesExamples;
|
private final boolean providesExamples;
|
||||||
|
|
||||||
public VanillaUnconfigurableArgument(
|
public VanillaUnconfigurableArgument(
|
||||||
final String suffix,
|
String suffix,
|
||||||
final ArgumentProvider argumentTypeSupplier,
|
ArgumentProvider argumentTypeSupplier,
|
||||||
final ValueExtractor valueExtractor,
|
ValueExtractor valueExtractor,
|
||||||
final boolean suggestFromExamples
|
boolean suggestFromExamples
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
super(suffix, null, suggestFromExamples);
|
super(suffix, null, suggestFromExamples);
|
||||||
@@ -1187,7 +1190,7 @@ public abstract class CommandArgument
|
|||||||
{
|
{
|
||||||
this.examples = argumentTypeSupplier.get().getExamples();
|
this.examples = argumentTypeSupplier.get().getExamples();
|
||||||
}
|
}
|
||||||
catch (final CommandSyntaxException e)
|
catch (CommandSyntaxException e)
|
||||||
{
|
{
|
||||||
this.examples = Collections.emptyList();
|
this.examples = Collections.emptyList();
|
||||||
}
|
}
|
||||||
@@ -1198,10 +1201,10 @@ public abstract class CommandArgument
|
|||||||
}
|
}
|
||||||
|
|
||||||
public VanillaUnconfigurableArgument(
|
public VanillaUnconfigurableArgument(
|
||||||
final String suffix,
|
String suffix,
|
||||||
final ArgumentProvider argumentTypeSupplier,
|
ArgumentProvider argumentTypeSupplier,
|
||||||
final ValueExtractor valueExtractor,
|
ValueExtractor valueExtractor,
|
||||||
final SuggestionProvider<CommandSourceStack> suggester
|
SuggestionProvider<CommandSourceStack> suggester
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
super(suffix, Collections.emptyList(), false);
|
super(suffix, Collections.emptyList(), false);
|
||||||
@@ -1213,19 +1216,19 @@ public abstract class CommandArgument
|
|||||||
}
|
}
|
||||||
|
|
||||||
public VanillaUnconfigurableArgument(
|
public VanillaUnconfigurableArgument(
|
||||||
final String suffix,
|
String suffix,
|
||||||
final ArgumentProviderEx argumentTypeSupplier,
|
ArgumentProviderEx argumentTypeSupplier,
|
||||||
final ValueExtractor valueExtractor,
|
ValueExtractor valueExtractor,
|
||||||
final boolean suggestFromExamples,
|
boolean suggestFromExamples,
|
||||||
final MinecraftServer server)
|
MinecraftServer server)
|
||||||
{
|
{
|
||||||
super(suffix, null, suggestFromExamples);
|
super(suffix, null, suggestFromExamples);
|
||||||
try
|
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();
|
this.examples = argumentTypeSupplier.get(context).getExamples();
|
||||||
}
|
}
|
||||||
catch (final CommandSyntaxException e)
|
catch (CommandSyntaxException e)
|
||||||
{
|
{
|
||||||
this.examples = Collections.emptyList();
|
this.examples = Collections.emptyList();
|
||||||
}
|
}
|
||||||
@@ -1236,10 +1239,10 @@ public abstract class CommandArgument
|
|||||||
}
|
}
|
||||||
|
|
||||||
public VanillaUnconfigurableArgument(
|
public VanillaUnconfigurableArgument(
|
||||||
final String suffix,
|
String suffix,
|
||||||
final ArgumentProviderEx argumentTypeSupplier,
|
ArgumentProviderEx argumentTypeSupplier,
|
||||||
final ValueExtractor valueExtractor,
|
ValueExtractor valueExtractor,
|
||||||
final SuggestionProvider<CommandSourceStack> suggester
|
SuggestionProvider<CommandSourceStack> suggester
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
super(suffix, Collections.emptyList(), false);
|
super(suffix, Collections.emptyList(), false);
|
||||||
@@ -1251,10 +1254,10 @@ public abstract class CommandArgument
|
|||||||
}
|
}
|
||||||
|
|
||||||
public VanillaUnconfigurableArgument(
|
public VanillaUnconfigurableArgument(
|
||||||
final String suffix,
|
String suffix,
|
||||||
final ArgumentProviderEx argumentTypeSupplier,
|
ArgumentProviderEx argumentTypeSupplier,
|
||||||
final ValueExtractor valueExtractor,
|
ValueExtractor valueExtractor,
|
||||||
final Function<String, SuggestionProvider<CommandSourceStack>> suggesterGen
|
Function<String, SuggestionProvider<CommandSourceStack>> suggesterGen
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
super(suffix, Collections.emptyList(), false);
|
super(suffix, Collections.emptyList(), false);
|
||||||
@@ -1266,20 +1269,20 @@ public abstract class CommandArgument
|
|||||||
}
|
}
|
||||||
|
|
||||||
public <T> VanillaUnconfigurableArgument(
|
public <T> VanillaUnconfigurableArgument(
|
||||||
final String suffix,
|
String suffix,
|
||||||
final ResourceKey<Registry<T>> registry
|
ResourceKey<Registry<T>> registry
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
this(
|
this(
|
||||||
suffix,
|
suffix,
|
||||||
(c) -> ResourceArgument.resource(c, registry),
|
c -> ResourceArgument.resource(c, registry),
|
||||||
(c, p) -> ValueConversions.of(ResourceArgument.getResource(c, p, registry).key()),
|
(c, p) -> ValueConversions.of(ResourceArgument.getResource(c, p, registry).key()),
|
||||||
(c, b) -> SharedSuggestionProvider.suggestResource(c.getSource().getServer().registryAccess().registryOrThrow(registry).keySet(), b)
|
(c, b) -> SharedSuggestionProvider.suggestResource(c.getSource().getServer().registryAccess().registryOrThrow(registry).keySet(), b)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected ArgumentType<?> getArgumentType(final CarpetScriptHost host) throws CommandSyntaxException
|
protected ArgumentType<?> getArgumentType(CarpetScriptHost host) throws CommandSyntaxException
|
||||||
{
|
{
|
||||||
return argumentTypeSupplier != null
|
return argumentTypeSupplier != null
|
||||||
? argumentTypeSupplier.get()
|
? argumentTypeSupplier.get()
|
||||||
@@ -1287,13 +1290,13 @@ public abstract class CommandArgument
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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);
|
return valueExtractor.apply(context, param);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Supplier<CommandArgument> factory(final MinecraftServer server)
|
protected Supplier<CommandArgument> factory(MinecraftServer server)
|
||||||
{
|
{
|
||||||
return argumentTypeSupplier != null
|
return argumentTypeSupplier != null
|
||||||
? (() -> new VanillaUnconfigurableArgument(getTypeSuffix(), argumentTypeSupplier, valueExtractor, providesExamples))
|
? (() -> new VanillaUnconfigurableArgument(getTypeSuffix(), argumentTypeSupplier, valueExtractor, providesExamples))
|
||||||
|
|||||||
@@ -14,22 +14,26 @@ import java.util.Objects;
|
|||||||
|
|
||||||
import net.minecraft.commands.CommandSourceStack;
|
import net.minecraft.commands.CommandSourceStack;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
import static net.minecraft.commands.Commands.literal;
|
import static net.minecraft.commands.Commands.literal;
|
||||||
|
|
||||||
public class CommandToken implements Comparable<CommandToken>
|
public class CommandToken implements Comparable<CommandToken>
|
||||||
{
|
{
|
||||||
public String surface;
|
public final String surface;
|
||||||
public boolean isArgument;
|
public final boolean isArgument;
|
||||||
public CommandArgument type;
|
@Nullable
|
||||||
|
public final CommandArgument type;
|
||||||
|
|
||||||
private CommandToken(final String surface, final CommandArgument type)
|
private CommandToken(String surface, @Nullable CommandArgument type)
|
||||||
{
|
{
|
||||||
this.surface = surface;
|
this.surface = surface;
|
||||||
this.type = type;
|
this.type = type;
|
||||||
isArgument = type != null;
|
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
|
// todo add more type checking and return null
|
||||||
if (!source.startsWith("<"))
|
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;
|
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();
|
spec = spec.trim();
|
||||||
if (spec.isEmpty())
|
if (spec.isEmpty())
|
||||||
{
|
{
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
final List<CommandToken> elements = new ArrayList<>();
|
List<CommandToken> elements = new ArrayList<>();
|
||||||
final HashSet<String> seenArgs = new HashSet<>();
|
HashSet<String> seenArgs = new HashSet<>();
|
||||||
for (final String el : spec.split("\\s+"))
|
for (String el : spec.split("\\s+"))
|
||||||
{
|
{
|
||||||
final CommandToken tok = CommandToken.getToken(el, host);
|
CommandToken tok = CommandToken.getToken(el, host);
|
||||||
if (tok == null)
|
if (tok == null)
|
||||||
{
|
{
|
||||||
throw CommandArgument.error("Unrecognized command token: " + el);
|
throw CommandArgument.error("Unrecognized command token: " + el);
|
||||||
@@ -69,23 +73,23 @@ public class CommandToken implements Comparable<CommandToken>
|
|||||||
return elements;
|
return elements;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String specFromSignature(final FunctionValue function)
|
public static String specFromSignature(FunctionValue function)
|
||||||
{
|
{
|
||||||
final List<String> tokens = Lists.newArrayList(function.getString());
|
List<String> tokens = Lists.newArrayList(function.getString());
|
||||||
for (final String arg : function.getArguments())
|
for (String arg : function.getArguments())
|
||||||
{
|
{
|
||||||
tokens.add("<" + arg + ">");
|
tokens.add("<" + arg + ">");
|
||||||
}
|
}
|
||||||
return String.join(" ", tokens);
|
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);
|
return isArgument ? CommandArgument.argumentNode(surface, host) : literal(surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(final Object o)
|
public boolean equals(Object o)
|
||||||
{
|
{
|
||||||
if (this == o)
|
if (this == o)
|
||||||
{
|
{
|
||||||
@@ -95,7 +99,7 @@ public class CommandToken implements Comparable<CommandToken>
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
final CommandToken that = (CommandToken) o;
|
CommandToken that = (CommandToken) o;
|
||||||
return surface.equals(that.surface) &&
|
return surface.equals(that.surface) &&
|
||||||
Objects.equals(type, that.type);
|
Objects.equals(type, that.type);
|
||||||
}
|
}
|
||||||
@@ -107,7 +111,7 @@ public class CommandToken implements Comparable<CommandToken>
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int compareTo(final CommandToken o)
|
public int compareTo(CommandToken o)
|
||||||
{
|
{
|
||||||
if (isArgument && !o.isArgument)
|
if (isArgument && !o.isArgument)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2,9 +2,11 @@ package carpet.script.exception;
|
|||||||
|
|
||||||
import carpet.script.value.Value;
|
import carpet.script.value.Value;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
public class BreakStatement extends ExitStatement
|
public class BreakStatement extends ExitStatement
|
||||||
{
|
{
|
||||||
public BreakStatement(final Value value)
|
public BreakStatement(@Nullable Value value)
|
||||||
{
|
{
|
||||||
super(value);
|
super(value);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,17 +11,17 @@ public class CarpetExpressionException extends StacklessRuntimeException impleme
|
|||||||
{
|
{
|
||||||
public final List<FunctionValue> stack;
|
public final List<FunctionValue> stack;
|
||||||
|
|
||||||
public CarpetExpressionException(final String message, final List<FunctionValue> stack)
|
public CarpetExpressionException(String message, List<FunctionValue> stack)
|
||||||
{
|
{
|
||||||
super(message);
|
super(message);
|
||||||
this.stack = stack;
|
this.stack = stack;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void printStack(final CommandSourceStack source)
|
public void printStack(CommandSourceStack source)
|
||||||
{
|
{
|
||||||
if (stack != null && !stack.isEmpty())
|
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));
|
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 carpet.script.value.Value;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
public class ContinueStatement extends ExitStatement
|
public class ContinueStatement extends ExitStatement
|
||||||
{
|
{
|
||||||
public ContinueStatement(final Value value)
|
public ContinueStatement(@Nullable Value value)
|
||||||
{
|
{
|
||||||
super(value);
|
super(value);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,12 +2,15 @@ package carpet.script.exception;
|
|||||||
|
|
||||||
import carpet.script.value.Value;
|
import carpet.script.value.Value;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
/* Exception thrown to terminate execution mid expression (aka return statement) */
|
/* Exception thrown to terminate execution mid expression (aka return statement) */
|
||||||
public class ExitStatement extends StacklessRuntimeException
|
public class ExitStatement extends StacklessRuntimeException
|
||||||
{
|
{
|
||||||
|
@Nullable
|
||||||
public final Value retval;
|
public final Value retval;
|
||||||
|
|
||||||
public ExitStatement(final Value value)
|
public ExitStatement(@Nullable Value value)
|
||||||
{
|
{
|
||||||
retval = value;
|
retval = value;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import carpet.script.Tokenizer;
|
|||||||
import carpet.script.external.Carpet;
|
import carpet.script.external.Carpet;
|
||||||
import carpet.script.value.FunctionValue;
|
import carpet.script.value.FunctionValue;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -25,17 +26,17 @@ public class ExpressionException extends StacklessRuntimeException implements Re
|
|||||||
Carpet.Messenger_compose("foo bar");
|
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);
|
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());
|
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");
|
super("Error");
|
||||||
this.stack.addAll(stack);
|
this.stack.addAll(stack);
|
||||||
@@ -44,7 +45,7 @@ public class ExpressionException extends StacklessRuntimeException implements Re
|
|||||||
context = c;
|
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");
|
super("Error");
|
||||||
this.stack.addAll(stack);
|
this.stack.addAll(stack);
|
||||||
@@ -53,13 +54,13 @@ public class ExpressionException extends StacklessRuntimeException implements Re
|
|||||||
context = c;
|
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());
|
errmessage += expr.getModuleName() == null ? "" : (" in " + expr.getModuleName());
|
||||||
if (token != null)
|
if (token != null)
|
||||||
{
|
{
|
||||||
final List<String> snippet = expr.getExpressionSnippet(token);
|
List<String> snippet = expr.getExpressionSnippet(token);
|
||||||
errMsg.addAll(snippet);
|
errMsg.addAll(snippet);
|
||||||
|
|
||||||
if (snippet.size() != 1)
|
if (snippet.size() != 1)
|
||||||
@@ -75,11 +76,11 @@ public class ExpressionException extends StacklessRuntimeException implements Re
|
|||||||
return errMsg;
|
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)
|
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)
|
if (alternative != null)
|
||||||
{
|
{
|
||||||
return String.join("\n", alternative);
|
return String.join("\n", alternative);
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ package carpet.script.exception;
|
|||||||
|
|
||||||
public class IntegrityException extends RuntimeException
|
public class IntegrityException extends RuntimeException
|
||||||
{
|
{
|
||||||
public IntegrityException(final String message)
|
public IntegrityException(String message)
|
||||||
{
|
{
|
||||||
super(message);
|
super(message);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ public class InternalExpressionException extends StacklessRuntimeException
|
|||||||
{
|
{
|
||||||
public List<FunctionValue> stack = new ArrayList<>();
|
public List<FunctionValue> stack = new ArrayList<>();
|
||||||
|
|
||||||
public InternalExpressionException(final String message)
|
public InternalExpressionException(String message)
|
||||||
{
|
{
|
||||||
super(message);
|
super(message);
|
||||||
}
|
}
|
||||||
@@ -30,7 +30,7 @@ public class InternalExpressionException extends StacklessRuntimeException
|
|||||||
* @return The new {@link ExpressionException} (or {@link ProcessedThrowStatement}),
|
* @return The new {@link ExpressionException} (or {@link ProcessedThrowStatement}),
|
||||||
* depending on the implementation.
|
* 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);
|
return new ExpressionException(c, e, token, getMessage(), stack);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ public class LoadException extends RuntimeException implements ResolvedException
|
|||||||
{
|
{
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
public LoadException(final String message)
|
public LoadException(String message)
|
||||||
{
|
{
|
||||||
super(message);
|
super(message);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ public class ProcessedThrowStatement extends ExpressionException
|
|||||||
public final Throwables thrownExceptionType;
|
public final Throwables thrownExceptionType;
|
||||||
public final Value data;
|
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);
|
super(c, e, token, () -> "Unhandled " + thrownExceptionType.getId() + " exception: " + data.getString(), stack);
|
||||||
this.thrownExceptionType = thrownExceptionType;
|
this.thrownExceptionType = thrownExceptionType;
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import carpet.script.value.Value;
|
|||||||
|
|
||||||
public class ReturnStatement extends ExitStatement
|
public class ReturnStatement extends ExitStatement
|
||||||
{
|
{
|
||||||
public ReturnStatement(final Value value)
|
public ReturnStatement(Value value)
|
||||||
{
|
{
|
||||||
super(value);
|
super(value);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ public abstract class StacklessRuntimeException extends RuntimeException
|
|||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
public StacklessRuntimeException(final String message)
|
public StacklessRuntimeException(String message)
|
||||||
{
|
{
|
||||||
super(message);
|
super(message);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,14 +18,14 @@ public class ThrowStatement extends InternalExpressionException
|
|||||||
* @param data The value to pass
|
* @param data The value to pass
|
||||||
* @param type Exception type
|
* @param type Exception type
|
||||||
*/
|
*/
|
||||||
public ThrowStatement(final Value data, final Throwables type)
|
public ThrowStatement(Value data, Throwables type)
|
||||||
{
|
{
|
||||||
super(type.getId());
|
super(type.getId());
|
||||||
this.data = data;
|
this.data = data;
|
||||||
this.type = type;
|
this.type = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ThrowStatement(final Value data, final Throwables parent, final String subtype)
|
public ThrowStatement(Value data, Throwables parent, String subtype)
|
||||||
{
|
{
|
||||||
super(subtype);
|
super(subtype);
|
||||||
this.data = data;
|
this.data = data;
|
||||||
@@ -42,7 +42,7 @@ public class ThrowStatement extends InternalExpressionException
|
|||||||
* for this exception. When throwing from Java,
|
* for this exception. When throwing from Java,
|
||||||
* those exceptions should be pre-registered.
|
* those exceptions should be pre-registered.
|
||||||
*/
|
*/
|
||||||
public ThrowStatement(final String message, final Throwables type)
|
public ThrowStatement(String message, Throwables type)
|
||||||
{
|
{
|
||||||
super(type.getId());
|
super(type.getId());
|
||||||
this.data = StringValue.of(message);
|
this.data = StringValue.of(message);
|
||||||
@@ -50,7 +50,7 @@ public class ThrowStatement extends InternalExpressionException
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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);
|
return new ProcessedThrowStatement(c, e, token, stack, type, data);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package carpet.script.exception;
|
package carpet.script.exception;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@@ -10,6 +11,7 @@ import java.util.Map;
|
|||||||
public class Throwables
|
public class Throwables
|
||||||
{
|
{
|
||||||
private final String id;
|
private final String id;
|
||||||
|
@Nullable
|
||||||
private final Throwables parent;
|
private final Throwables parent;
|
||||||
|
|
||||||
private static final Map<String, Throwables> byId = new HashMap<>();
|
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
|
* @param parent The parent of the exception being created, or <code>null</code> if top-level
|
||||||
* @return The created exception
|
* @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);
|
byId.put(id, exc);
|
||||||
return exc;
|
return exc;
|
||||||
}
|
}
|
||||||
@@ -55,15 +57,15 @@ public class Throwables
|
|||||||
*
|
*
|
||||||
* @param id The exception's value as a {@link String}
|
* @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.id = id;
|
||||||
this.parent = parent;
|
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)
|
if (properType == null)
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("Unknown exception type: " + type);
|
throw new InternalExpressionException("Unknown exception type: " + type);
|
||||||
@@ -78,7 +80,7 @@ public class Throwables
|
|||||||
* @param filter The type to check against
|
* @param filter The type to check against
|
||||||
* @return Whether or not the given value matches this exception's hierarchy
|
* @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)));
|
return (id.equals(filter) || (parent != null && parent.isRelevantFor(filter)));
|
||||||
}
|
}
|
||||||
|
|||||||
+14
-14
@@ -46,17 +46,17 @@ public class Carpet
|
|||||||
return HUDController.scarpet_footers;
|
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);
|
HUDController.update_hud(server, players);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Component Messenger_compose(final Object... messages)
|
public static Component Messenger_compose(Object... messages)
|
||||||
{
|
{
|
||||||
return Messenger.c(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);
|
Messenger.m(source, messages);
|
||||||
}
|
}
|
||||||
@@ -81,34 +81,34 @@ public class Carpet
|
|||||||
return BlockInfo.materialName;
|
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);
|
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);
|
((MinecraftServerInterface) server).addScriptServer(scriptServer);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isValidCarpetPlayer(final ServerPlayer player)
|
public static boolean isValidCarpetPlayer(ServerPlayer player)
|
||||||
{
|
{
|
||||||
return ServerNetworkHandler.isValidCarpetPlayer(player);
|
return ServerNetworkHandler.isValidCarpetPlayer(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getPlayerStatus(final ServerPlayer player)
|
public static String getPlayerStatus(ServerPlayer player)
|
||||||
{
|
{
|
||||||
return ServerNetworkHandler.getPlayerStatus(player);
|
return ServerNetworkHandler.getPlayerStatus(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static MapValue getAllCarpetRules()
|
public static MapValue getAllCarpetRules()
|
||||||
{
|
{
|
||||||
final Collection<CarpetRule<?>> rules = CarpetServer.settingsManager.getCarpetRules();
|
Collection<CarpetRule<?>> rules = CarpetServer.settingsManager.getCarpetRules();
|
||||||
final MapValue carpetRules = new MapValue(Collections.emptyList());
|
MapValue carpetRules = new MapValue(Collections.emptyList());
|
||||||
rules.forEach(rule -> carpetRules.put(new StringValue(rule.name()), new StringValue(RuleHelper.toRuleString(rule.value()))));
|
rules.forEach(rule -> carpetRules.put(new StringValue(rule.name()), new StringValue(RuleHelper.toRuleString(rule.value()))));
|
||||||
CarpetServer.extensions.forEach(e -> {
|
CarpetServer.extensions.forEach(e -> {
|
||||||
final SettingsManager manager = e.extensionSettingsManager();
|
SettingsManager manager = e.extensionSettingsManager();
|
||||||
if (manager == null)
|
if (manager == null)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@@ -124,7 +124,7 @@ public class Carpet
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public static String isModdedPlayer(final Player p)
|
public static String isModdedPlayer(Player p)
|
||||||
{
|
{
|
||||||
if (p instanceof final EntityPlayerMPFake fake)
|
if (p instanceof final EntityPlayerMPFake fake)
|
||||||
{
|
{
|
||||||
@@ -138,7 +138,7 @@ public class Carpet
|
|||||||
return !TickSpeed.process_entities;
|
return !TickSpeed.process_entities;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void handleExtensionsAPI(final CarpetExpression expression)
|
public static void handleExtensionsAPI(CarpetExpression expression)
|
||||||
{
|
{
|
||||||
CarpetServer.extensions.forEach(e -> e.scarpetApi(expression));
|
CarpetServer.extensions.forEach(e -> e.scarpetApi(expression));
|
||||||
}
|
}
|
||||||
@@ -151,7 +151,7 @@ public class Carpet
|
|||||||
public static class ScarpetAppStoreValidator extends Validator<String>
|
public static class ScarpetAppStoreValidator extends Validator<String>
|
||||||
{
|
{
|
||||||
@Override
|
@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()))
|
if (newValue.equals(currentRule.value()))
|
||||||
{
|
{
|
||||||
|
|||||||
+53
-53
@@ -93,27 +93,27 @@ import java.util.function.Predicate;
|
|||||||
|
|
||||||
public class Vanilla
|
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);
|
((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);
|
((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);
|
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();
|
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);
|
return ((RecipeManagerInterface) recipeManager).getAllMatching(type, output, registryAccess);
|
||||||
}
|
}
|
||||||
@@ -123,72 +123,72 @@ public class Vanilla
|
|||||||
return SpawnReporter.MAGIC_NUMBER;
|
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();
|
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);
|
((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();
|
return ((Scoreboard_scarpetMixin) scoreboard).getObjectivesByCriterion();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ServerLevelData ServerLevel_getWorldProperties(final ServerLevel world)
|
public static ServerLevelData ServerLevel_getWorldProperties(ServerLevel world)
|
||||||
{
|
{
|
||||||
return ((ServerWorldInterface) world).getWorldPropertiesCM();
|
return ((ServerWorldInterface) world).getWorldPropertiesCM();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static DistanceManager ServerChunkCache_getCMTicketManager(final ServerChunkCache chunkCache)
|
public static DistanceManager ServerChunkCache_getCMTicketManager(ServerChunkCache chunkCache)
|
||||||
{
|
{
|
||||||
return ((ServerChunkManagerInterface) chunkCache).getCMTicketManager();
|
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();
|
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();
|
return ((RandomStateVisitorAccessor) (Object) randomState).getVisitor();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static CompoundTag BlockInput_getTag(final BlockInput blockInput)
|
public static CompoundTag BlockInput_getTag(BlockInput blockInput)
|
||||||
{
|
{
|
||||||
return ((BlockStateArgumentInterface) blockInput).getCMTag();
|
return ((BlockStateArgumentInterface) blockInput).getCMTag();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static CarpetScriptServer MinecraftServer_getScriptServer(final MinecraftServer server)
|
public static CarpetScriptServer MinecraftServer_getScriptServer(MinecraftServer server)
|
||||||
{
|
{
|
||||||
return ((MinecraftServerInterface) server).getScriptServer();
|
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();
|
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
|
{ // not sure does vanilla care at all - needs checking
|
||||||
return CarpetSettings.skipGenerationChecks;
|
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
|
{ // dont forget to add the packet to vanilla packed handler and call ShapesRenderer.addShape to handle on client
|
||||||
ServerNetworkHandler.sendCustomCommand(player, "scShapes", data);
|
ServerNetworkHandler.sendCustomCommand(player, "scShapes", data);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int MinecraftServer_getRunPermissionLevel(final MinecraftServer server)
|
public static int MinecraftServer_getRunPermissionLevel(MinecraftServer server)
|
||||||
{
|
{
|
||||||
return CarpetSettings.runPermissionLevel;
|
return CarpetSettings.runPermissionLevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String MinecraftServer_getReleaseTarget(final MinecraftServer server)
|
public static String MinecraftServer_getReleaseTarget(MinecraftServer server)
|
||||||
{
|
{
|
||||||
return CarpetSettings.releaseTarget;
|
return CarpetSettings.releaseTarget;
|
||||||
}
|
}
|
||||||
@@ -198,165 +198,165 @@ public class Vanilla
|
|||||||
return FabricLoader.getInstance().isDevelopmentEnvironment();
|
return FabricLoader.getInstance().isDevelopmentEnvironment();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static MapValue getServerMods(final MinecraftServer server)
|
public static MapValue getServerMods(MinecraftServer server)
|
||||||
{
|
{
|
||||||
final Map<Value, Value> ret = new HashMap<>();
|
Map<Value, Value> ret = new HashMap<>();
|
||||||
for (final ModContainer mod : FabricLoader.getInstance().getAllMods())
|
for (ModContainer mod : FabricLoader.getInstance().getAllMods())
|
||||||
{
|
{
|
||||||
ret.put(new StringValue(mod.getMetadata().getId()), new StringValue(mod.getMetadata().getVersion().getFriendlyString()));
|
ret.put(new StringValue(mod.getMetadata().getId()), new StringValue(mod.getMetadata().getVersion().getFriendlyString()));
|
||||||
}
|
}
|
||||||
return MapValue.wrap(ret);
|
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();
|
return ((MinecraftServerInterface) server).getCMSession();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static BlockPos ServerPlayerGameMode_getCurrentBlockPosition(final ServerPlayerGameMode gameMode)
|
public static BlockPos ServerPlayerGameMode_getCurrentBlockPosition(ServerPlayerGameMode gameMode)
|
||||||
{
|
{
|
||||||
return ((ServerPlayerInteractionManagerInterface) gameMode).getCurrentBreakingBlock();
|
return ((ServerPlayerInteractionManagerInterface) gameMode).getCurrentBreakingBlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int ServerPlayerGameMode_getCurrentBlockBreakingProgress(final ServerPlayerGameMode gameMode)
|
public static int ServerPlayerGameMode_getCurrentBlockBreakingProgress(ServerPlayerGameMode gameMode)
|
||||||
{
|
{
|
||||||
return ((ServerPlayerInteractionManagerInterface) gameMode).getCurrentBlockBreakingProgress();
|
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);
|
((ServerPlayerInteractionManagerInterface) gameMode).setBlockBreakingProgress(progress);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean ServerPlayer_isInvalidEntityObject(final ServerPlayer player)
|
public static boolean ServerPlayer_isInvalidEntityObject(ServerPlayer player)
|
||||||
{
|
{
|
||||||
return ((ServerPlayerInterface) player).isInvalidEntityObject();
|
return ((ServerPlayerInterface) player).isInvalidEntityObject();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String ServerPlayer_getLanguage(final ServerPlayer player)
|
public static String ServerPlayer_getLanguage(ServerPlayer player)
|
||||||
{
|
{
|
||||||
return ((ServerPlayerInterface) player).getLanguage();
|
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);
|
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();
|
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);
|
((MobEntityInterface) mob).setPersistence(what);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static EntityEventsGroup Entity_getEventContainer(final Entity entity)
|
public static EntityEventsGroup Entity_getEventContainer(Entity entity)
|
||||||
{
|
{
|
||||||
return ((EntityInterface) entity).getEventContainer();
|
return ((EntityInterface) entity).getEventContainer();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean Entity_isPermanentVehicle(final Entity entity)
|
public static boolean Entity_isPermanentVehicle(Entity entity)
|
||||||
{
|
{
|
||||||
return ((EntityInterface) entity).isPermanentVehicle();
|
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);
|
((EntityInterface) entity).setPermanentVehicle(permanent);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int Entity_getPortalTimer(final Entity entity)
|
public static int Entity_getPortalTimer(Entity entity)
|
||||||
{
|
{
|
||||||
return ((EntityInterface) entity).getPortalTimer();
|
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);
|
((EntityInterface) entity).setPortalTimer(amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int Entity_getPublicNetherPortalCooldown(final Entity entity)
|
public static int Entity_getPublicNetherPortalCooldown(Entity entity)
|
||||||
{
|
{
|
||||||
return ((EntityInterface) entity).getPublicNetherPortalCooldown();
|
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);
|
((EntityInterface) entity).setPublicNetherPortalCooldown(what);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int ItemEntity_getPickupDelay(final ItemEntity entity)
|
public static int ItemEntity_getPickupDelay(ItemEntity entity)
|
||||||
{
|
{
|
||||||
return ((ItemEntityInterface) entity).getPickupDelayCM();
|
return ((ItemEntityInterface) entity).getPickupDelayCM();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean LivingEntity_isJumping(final LivingEntity entity)
|
public static boolean LivingEntity_isJumping(LivingEntity entity)
|
||||||
{
|
{
|
||||||
return ((LivingEntityInterface) entity).isJumpingCM();
|
return ((LivingEntityInterface) entity).isJumpingCM();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void LivingEntity_setJumping(final LivingEntity entity)
|
public static void LivingEntity_setJumping(LivingEntity entity)
|
||||||
{
|
{
|
||||||
((LivingEntityInterface) entity).doJumpCM();
|
((LivingEntityInterface) entity).doJumpCM();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Container AbstractHorse_getInventory(final AbstractHorse horse)
|
public static Container AbstractHorse_getInventory(AbstractHorse horse)
|
||||||
{
|
{
|
||||||
return ((InventoryBearerInterface) horse).getCMInventory();
|
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);
|
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);
|
((CommandDispatcherInterface) dispatcher).carpet$unregister(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean MinecraftServer_doScriptsAutoload(final MinecraftServer server)
|
public static boolean MinecraftServer_doScriptsAutoload(MinecraftServer server)
|
||||||
{
|
{
|
||||||
return CarpetSettings.scriptsAutoload;
|
return CarpetSettings.scriptsAutoload;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void MinecraftServer_notifyPlayersCommandsChanged(final MinecraftServer server)
|
public static void MinecraftServer_notifyPlayersCommandsChanged(MinecraftServer server)
|
||||||
{
|
{
|
||||||
CommandHelper.notifyPlayersCommandsChanged(server);
|
CommandHelper.notifyPlayersCommandsChanged(server);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean ScriptServer_scriptOptimizations(final MinecraftServer scriptServer)
|
public static boolean ScriptServer_scriptOptimizations(MinecraftServer scriptServer)
|
||||||
{
|
{
|
||||||
return CarpetSettings.scriptsOptimization;
|
return CarpetSettings.scriptsOptimization;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean ScriptServer_scriptDebugging(final MinecraftServer server)
|
public static boolean ScriptServer_scriptDebugging(MinecraftServer server)
|
||||||
{
|
{
|
||||||
return CarpetSettings.scriptsDebugging;
|
return CarpetSettings.scriptsDebugging;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean ServerPlayer_canScriptACE(final CommandSourceStack player)
|
public static boolean ServerPlayer_canScriptACE(CommandSourceStack player)
|
||||||
{
|
{
|
||||||
return CommandHelper.canUseCommand(player, CarpetSettings.commandScriptACE);
|
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);
|
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);
|
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 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());
|
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 class VanillaClient
|
||||||
{
|
{
|
||||||
public static ShulkerModel<?> ShulkerBoxRenderer_model(final BlockEntityRenderer<ShulkerBoxBlockEntity> shulkerBoxRenderer) {
|
public static ShulkerModel<?> ShulkerBoxRenderer_model(BlockEntityRenderer<ShulkerBoxBlockEntity> shulkerBoxRenderer) {
|
||||||
return ((ShulkerBoxAccessMixin)shulkerBoxRenderer).getModel();
|
return ((ShulkerBoxAccessMixin)shulkerBoxRenderer).getModel();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -13,12 +13,12 @@ public class Arithmetic
|
|||||||
public static final Value PI = new NumericValue(Math.PI);
|
public static final Value PI = new NumericValue(Math.PI);
|
||||||
public static final Value euler = new NumericValue(Math.E);
|
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.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)
|
if (number < 21)
|
||||||
{
|
{
|
||||||
long factorial = 1;
|
long factorial = 1;
|
||||||
@@ -82,26 +82,26 @@ public class Arithmetic
|
|||||||
expression.addMathematicalUnaryIntFunction("ceil", n -> (long) Math.ceil(n));
|
expression.addMathematicalUnaryIntFunction("ceil", n -> (long) Math.ceil(n));
|
||||||
|
|
||||||
expression.addContextFunction("mandelbrot", 3, (c, t, lv) -> {
|
expression.addContextFunction("mandelbrot", 3, (c, t, lv) -> {
|
||||||
final double a0 = NumericValue.asNumber(lv.get(0)).getDouble();
|
double a0 = NumericValue.asNumber(lv.get(0)).getDouble();
|
||||||
final double b0 = NumericValue.asNumber(lv.get(1)).getDouble();
|
double b0 = NumericValue.asNumber(lv.get(1)).getDouble();
|
||||||
final long maxiter = NumericValue.asNumber(lv.get(2)).getLong();
|
long maxiter = NumericValue.asNumber(lv.get(2)).getLong();
|
||||||
double a = 0.0D;
|
double a = 0.0D;
|
||||||
double b = 0.0D;
|
double b = 0.0D;
|
||||||
long iter = 0;
|
long iter = 0;
|
||||||
while (a * a + b * b < 4 && iter < maxiter)
|
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;
|
b = 2 * a * b + b0;
|
||||||
a = temp;
|
a = temp;
|
||||||
iter++;
|
iter++;
|
||||||
}
|
}
|
||||||
final long iFinal = iter;
|
long iFinal = iter;
|
||||||
return new NumericValue(iFinal);
|
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");
|
throw new InternalExpressionException("'max' requires at least one parameter");
|
||||||
}
|
}
|
||||||
@@ -110,7 +110,7 @@ public class Arithmetic
|
|||||||
{
|
{
|
||||||
lv = ((ListValue) lv.get(0)).getItems();
|
lv = ((ListValue) lv.get(0)).getItems();
|
||||||
}
|
}
|
||||||
for (final Value parameter : lv)
|
for (Value parameter : lv)
|
||||||
{
|
{
|
||||||
if (max == null || parameter.compareTo(max) > 0)
|
if (max == null || parameter.compareTo(max) > 0)
|
||||||
{
|
{
|
||||||
@@ -120,9 +120,9 @@ public class Arithmetic
|
|||||||
return max;
|
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");
|
throw new InternalExpressionException("'min' requires at least one parameter");
|
||||||
}
|
}
|
||||||
@@ -131,7 +131,7 @@ public class Arithmetic
|
|||||||
{
|
{
|
||||||
lv = ((ListValue) lv.get(0)).getItems();
|
lv = ((ListValue) lv.get(0)).getItems();
|
||||||
}
|
}
|
||||||
for (final Value parameter : lv)
|
for (Value parameter : lv)
|
||||||
{
|
{
|
||||||
if (min == null || parameter.compareTo(min) < 0)
|
if (min == null || parameter.compareTo(min) < 0)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -19,23 +19,23 @@ import java.util.stream.Collectors;
|
|||||||
|
|
||||||
public class ControlFlow
|
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
|
// needs to be lazy cause of custom contextualization
|
||||||
expression.addLazyBinaryOperator(";", Operators.precedence.get("nextop;"), true, true, t -> Context.Type.VOID, (c, t, lv1, lv2) ->
|
expression.addLazyBinaryOperator(";", Operators.precedence.get("nextop;"), true, true, t -> Context.Type.VOID, (c, t, lv1, lv2) ->
|
||||||
{
|
{
|
||||||
lv1.evalValue(c, Context.VOID);
|
lv1.evalValue(c, Context.VOID);
|
||||||
final Value v2 = lv2.evalValue(c, t);
|
Value v2 = lv2.evalValue(c, t);
|
||||||
return (cc, tt) -> v2;
|
return (cc, tt) -> v2;
|
||||||
});
|
});
|
||||||
|
|
||||||
expression.addPureLazyFunction("then", -1, t -> Context.Type.VOID, (c, t, lv) -> {
|
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++)
|
for (int i = 0; i < imax; i++)
|
||||||
{
|
{
|
||||||
lv.get(i).evalValue(c, Context.VOID);
|
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;
|
return (cc, tt) -> v;
|
||||||
});
|
});
|
||||||
expression.addFunctionalEquivalence(";", "then");
|
expression.addFunctionalEquivalence(";", "then");
|
||||||
@@ -52,20 +52,20 @@ public class ControlFlow
|
|||||||
{
|
{
|
||||||
if (lv.get(i).evalValue(c, Context.BOOLEAN).getBoolean())
|
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;
|
return (cc, tt) -> ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (lv.size() % 2 == 1)
|
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) -> ret;
|
||||||
}
|
}
|
||||||
return (cc, tt) -> Value.NULL;
|
return (cc, tt) -> Value.NULL;
|
||||||
});
|
});
|
||||||
|
|
||||||
expression.addImpureFunction("exit", (lv) -> {
|
expression.addImpureFunction("exit", lv -> {
|
||||||
throw new ExitStatement(lv.size() == 0 ? Value.NULL : lv.get(0));
|
throw new ExitStatement(lv.isEmpty() ? Value.NULL : lv.get(0));
|
||||||
});
|
});
|
||||||
|
|
||||||
expression.addImpureFunction("throw", lv ->
|
expression.addImpureFunction("throw", lv ->
|
||||||
@@ -83,16 +83,16 @@ public class ControlFlow
|
|||||||
// needs to be lazy since execution of parameters but first one are conditional
|
// needs to be lazy since execution of parameters but first one are conditional
|
||||||
expression.addLazyFunction("try", (c, t, lv) ->
|
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");
|
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
|
try
|
||||||
{
|
{
|
||||||
final Value retval = lv.get(0).evalValue(c, t);
|
Value retval = lv.get(0).evalValue(c, t);
|
||||||
return (c_, t_) -> retval;
|
return (ct, tt) -> retval;
|
||||||
}
|
}
|
||||||
catch (final ProcessedThrowStatement ret)
|
catch (ProcessedThrowStatement ret)
|
||||||
{
|
{
|
||||||
if (lv.size() == 1)
|
if (lv.size() == 1)
|
||||||
{
|
{
|
||||||
@@ -100,7 +100,7 @@ public class ControlFlow
|
|||||||
{
|
{
|
||||||
throw ret;
|
throw ret;
|
||||||
}
|
}
|
||||||
return (c_, t_) -> Value.NULL;
|
return (ct, tt) -> Value.NULL;
|
||||||
}
|
}
|
||||||
if (lv.size() > 3 && lv.size() % 2 == 0)
|
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
|
Value val = null; // This is always assigned at some point, just the compiler doesn't know
|
||||||
|
|
||||||
final LazyValue __ = c.getVariable("_");
|
LazyValue defaultVal = c.getVariable("_");
|
||||||
c.setVariable("_", (__c, __t) -> ret.data.reboundedTo("_"));
|
c.setVariable("_", (ct, tt) -> ret.data.reboundedTo("_"));
|
||||||
final LazyValue _trace = c.getVariable("_trace");
|
LazyValue trace = c.getVariable("_trace");
|
||||||
c.setVariable("_trace", (__c, __t) -> MapValue.wrap(Map.of(
|
c.setVariable("_trace", (ct, tt) -> MapValue.wrap(Map.of(
|
||||||
StringValue.of("stack"), ListValue.wrap(ret.stack.stream().map(f -> ListValue.of(
|
StringValue.of("stack"), ListValue.wrap(ret.stack.stream().map(f -> ListValue.of(
|
||||||
StringValue.of(f.getModule().name()),
|
StringValue.of(f.getModule().name()),
|
||||||
StringValue.of(f.getString()),
|
StringValue.of(f.getString()),
|
||||||
@@ -151,10 +151,10 @@ public class ControlFlow
|
|||||||
pointer += 2;
|
pointer += 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
c.setVariable("_", __);
|
c.setVariable("_", defaultVal);
|
||||||
if (_trace != null)
|
if (trace != null)
|
||||||
{
|
{
|
||||||
c.setVariable("_trace", _trace);
|
c.setVariable("_trace", trace);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -164,8 +164,8 @@ public class ControlFlow
|
|||||||
{
|
{
|
||||||
throw ret;
|
throw ret;
|
||||||
}
|
}
|
||||||
final Value retval = val;
|
Value retval = val;
|
||||||
return (c_, t_) -> retval;
|
return (ct, tt) -> retval;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,21 +27,21 @@ import java.util.stream.Collectors;
|
|||||||
|
|
||||||
public class DataStructures
|
public class DataStructures
|
||||||
{
|
{
|
||||||
public static void apply(final Expression expression)
|
public static void apply(Expression expression)
|
||||||
{
|
{
|
||||||
expression.addFunction("l", lv ->
|
expression.addFunction("l", lv ->
|
||||||
lv.size() == 1 && lv.get(0) instanceof final LazyListValue llv
|
lv.size() == 1 && lv.get(0) instanceof final LazyListValue llv
|
||||||
? ListValue.wrap(llv.unroll())
|
? ListValue.wrap(llv.unroll())
|
||||||
: new ListValue.ListConstructorValue(lv));
|
: new ListValue.ListConstructorValue(lv));
|
||||||
|
|
||||||
expression.addFunction("join", (lv) ->
|
expression.addFunction("join", lv ->
|
||||||
{
|
{
|
||||||
if (lv.size() < 2)
|
if (lv.size() < 2)
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("'join' takes at least 2 arguments");
|
throw new InternalExpressionException("'join' takes at least 2 arguments");
|
||||||
}
|
}
|
||||||
final String delimiter = lv.get(0).getString();
|
String delimiter = lv.get(0).getString();
|
||||||
final List<Value> toJoin;
|
List<Value> toJoin;
|
||||||
if (lv.size() == 2 && lv.get(1) instanceof final LazyListValue llv)
|
if (lv.size() == 2 && lv.get(1) instanceof final LazyListValue llv)
|
||||||
{
|
{
|
||||||
toJoin = llv.unroll();
|
toJoin = llv.unroll();
|
||||||
@@ -57,10 +57,10 @@ public class DataStructures
|
|||||||
return new StringValue(toJoin.stream().map(Value::getString).collect(Collectors.joining(delimiter)));
|
return new StringValue(toJoin.stream().map(Value::getString).collect(Collectors.joining(delimiter)));
|
||||||
});
|
});
|
||||||
|
|
||||||
expression.addFunction("split", (lv) ->
|
expression.addFunction("split", lv ->
|
||||||
{
|
{
|
||||||
final Value delimiter;
|
Value delimiter;
|
||||||
final Value hwat;
|
Value hwat;
|
||||||
if (lv.size() == 1)
|
if (lv.size() == 1)
|
||||||
{
|
{
|
||||||
hwat = lv.get(0);
|
hwat = lv.get(0);
|
||||||
@@ -78,14 +78,14 @@ public class DataStructures
|
|||||||
return hwat.split(delimiter);
|
return hwat.split(delimiter);
|
||||||
});
|
});
|
||||||
|
|
||||||
expression.addFunction("slice", (lv) ->
|
expression.addFunction("slice", lv ->
|
||||||
{
|
{
|
||||||
if (lv.size() != 2 && lv.size() != 3)
|
if (lv.size() != 2 && lv.size() != 3)
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("'slice' takes 2 or 3 arguments");
|
throw new InternalExpressionException("'slice' takes 2 or 3 arguments");
|
||||||
}
|
}
|
||||||
final Value hwat = lv.get(0);
|
Value hwat = lv.get(0);
|
||||||
final long from = NumericValue.asNumber(lv.get(1)).getLong();
|
long from = NumericValue.asNumber(lv.get(1)).getLong();
|
||||||
Long to = null;
|
Long to = null;
|
||||||
if (lv.size() == 3)
|
if (lv.size() == 3)
|
||||||
{
|
{
|
||||||
@@ -94,7 +94,7 @@ public class DataStructures
|
|||||||
return hwat.slice(from, to);
|
return hwat.slice(from, to);
|
||||||
});
|
});
|
||||||
|
|
||||||
expression.addFunction("sort", (lv) ->
|
expression.addFunction("sort", lv ->
|
||||||
{
|
{
|
||||||
List<Value> toSort = lv;
|
List<Value> toSort = lv;
|
||||||
if (lv.size() == 1 && lv.get(0) instanceof final ListValue llv)
|
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
|
// needs lazy cause sort function is reused
|
||||||
expression.addLazyFunction("sort_key", (c, t, lv) -> //get working with iterators
|
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");
|
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))
|
if (!(v instanceof final ListValue list))
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("First argument for 'sort_key' should be a 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)
|
if (lv.size() == 1)
|
||||||
{
|
{
|
||||||
Collections.shuffle(toSort);
|
Collections.shuffle(toSort);
|
||||||
final Value ret = ListValue.wrap(toSort);
|
Value ret = ListValue.wrap(toSort);
|
||||||
return (_c, _t) -> ret;
|
return (ct, tt) -> ret;
|
||||||
}
|
}
|
||||||
final LazyValue sortKey = lv.get(1);
|
LazyValue sortKey = lv.get(1);
|
||||||
//scoping
|
//scoping
|
||||||
final LazyValue __ = c.getVariable("_");
|
LazyValue defaultVal = c.getVariable("_");
|
||||||
toSort.sort((v1, v2) -> {
|
toSort.sort((v1, v2) -> {
|
||||||
c.setVariable("_", (cc, tt) -> v1);
|
c.setVariable("_", (cc, tt) -> v1);
|
||||||
final Value ev1 = sortKey.evalValue(c);
|
Value ev1 = sortKey.evalValue(c);
|
||||||
c.setVariable("_", (cc, tt) -> v2);
|
c.setVariable("_", (cc, tt) -> v2);
|
||||||
final Value ev2 = sortKey.evalValue(c);
|
Value ev2 = sortKey.evalValue(c);
|
||||||
return ev1.compareTo(ev2);
|
return ev1.compareTo(ev2);
|
||||||
});
|
});
|
||||||
//revering scope
|
//revering scope
|
||||||
c.setVariable("_", __);
|
c.setVariable("_", defaultVal);
|
||||||
final Value ret = ListValue.wrap(toSort);
|
Value ret = ListValue.wrap(toSort);
|
||||||
return (cc, tt) -> ret;
|
return (cc, tt) -> ret;
|
||||||
});
|
});
|
||||||
|
|
||||||
expression.addFunction("range", (lv) ->
|
expression.addFunction("range", lv ->
|
||||||
{
|
{
|
||||||
NumericValue from = Value.ZERO;
|
NumericValue from = Value.ZERO;
|
||||||
NumericValue to;
|
NumericValue to;
|
||||||
NumericValue step = Value.ONE;
|
NumericValue step = Value.ONE;
|
||||||
final int argsize = lv.size();
|
int argsize = lv.size();
|
||||||
if (argsize == 0 || argsize > 3)
|
if (argsize == 0 || argsize > 3)
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("'range' accepts from 1 to 3 arguments, not " + argsize);
|
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)
|
if (container instanceof final LContainerValue lcv)
|
||||||
{
|
{
|
||||||
final ContainerValueInterface outerContainer = lcv.container();
|
ContainerValueInterface outerContainer = lcv.container();
|
||||||
if (outerContainer == null)
|
if (outerContainer == null)
|
||||||
{
|
{
|
||||||
return LContainerValue.NULL_CONTAINER;
|
return LContainerValue.NULL_CONTAINER;
|
||||||
@@ -211,23 +211,23 @@ public class DataStructures
|
|||||||
// lazy cause conditional typing - questionable
|
// lazy cause conditional typing - questionable
|
||||||
expression.addLazyFunction("get", (c, t, lv) ->
|
expression.addLazyFunction("get", (c, t, lv) ->
|
||||||
{
|
{
|
||||||
if (lv.size() == 0)
|
if (lv.isEmpty())
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("'get' requires parameters");
|
throw new InternalExpressionException("'get' requires parameters");
|
||||||
}
|
}
|
||||||
if (lv.size() == 1)
|
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))
|
if (!(v instanceof final LContainerValue lcv))
|
||||||
{
|
{
|
||||||
return LazyValue.NULL;
|
return LazyValue.NULL;
|
||||||
}
|
}
|
||||||
final ContainerValueInterface container = lcv.container();
|
ContainerValueInterface container = lcv.container();
|
||||||
if (container == null)
|
if (container == null)
|
||||||
{
|
{
|
||||||
return LazyValue.NULL;
|
return LazyValue.NULL;
|
||||||
}
|
}
|
||||||
final Value ret = container.get(lcv.address());
|
Value ret = container.get(lcv.address());
|
||||||
return (cc, tt) -> ret;
|
return (cc, tt) -> ret;
|
||||||
}
|
}
|
||||||
Value container = lv.get(0).evalValue(c);
|
Value container = lv.get(0).evalValue(c);
|
||||||
@@ -243,30 +243,30 @@ public class DataStructures
|
|||||||
{
|
{
|
||||||
return (cc, tt) -> Value.NULL;
|
return (cc, tt) -> Value.NULL;
|
||||||
}
|
}
|
||||||
final Value finalContainer = container;
|
Value finalContainer = container;
|
||||||
return (cc, tt) -> finalContainer;
|
return (cc, tt) -> finalContainer;
|
||||||
});
|
});
|
||||||
|
|
||||||
// same as `get`
|
// same as `get`
|
||||||
expression.addLazyFunction("has", (c, t, lv) ->
|
expression.addLazyFunction("has", (c, t, lv) ->
|
||||||
{
|
{
|
||||||
if (lv.size() == 0)
|
if (lv.isEmpty())
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("'has' requires parameters");
|
throw new InternalExpressionException("'has' requires parameters");
|
||||||
}
|
}
|
||||||
if (lv.size() == 1)
|
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))
|
if (!(v instanceof final LContainerValue lcv))
|
||||||
{
|
{
|
||||||
return LazyValue.NULL;
|
return LazyValue.NULL;
|
||||||
}
|
}
|
||||||
final ContainerValueInterface container = lcv.container();
|
ContainerValueInterface container = lcv.container();
|
||||||
if (container == null)
|
if (container == null)
|
||||||
{
|
{
|
||||||
return LazyValue.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;
|
return (cc, tt) -> ret;
|
||||||
}
|
}
|
||||||
Value container = lv.get(0).evalValue(c);
|
Value container = lv.get(0).evalValue(c);
|
||||||
@@ -282,7 +282,7 @@ public class DataStructures
|
|||||||
{
|
{
|
||||||
return LazyValue.NULL;
|
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;
|
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");
|
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)
|
if (container instanceof final LContainerValue lcv)
|
||||||
{
|
{
|
||||||
final ContainerValueInterface internalContainer = lcv.container();
|
ContainerValueInterface internalContainer = lcv.container();
|
||||||
if (internalContainer == null)
|
if (internalContainer == null)
|
||||||
{
|
{
|
||||||
return LazyValue.NULL;
|
return LazyValue.NULL;
|
||||||
}
|
}
|
||||||
final Value address = lcv.address();
|
Value address = lcv.address();
|
||||||
final Value what = lv.get(1).evalValue(c);
|
Value what = lv.get(1).evalValue(c);
|
||||||
final Value retVal = BooleanValue.of((lv.size() > 2)
|
Value retVal = BooleanValue.of((lv.size() > 2)
|
||||||
? internalContainer.put(address, what, lv.get(2).evalValue(c))
|
? internalContainer.put(address, what, lv.get(2).evalValue(c))
|
||||||
: internalContainer.put(address, what));
|
: internalContainer.put(address, what));
|
||||||
return (cc, tt) -> retVal;
|
return (cc, tt) -> retVal;
|
||||||
@@ -317,9 +317,9 @@ public class DataStructures
|
|||||||
{
|
{
|
||||||
return LazyValue.NULL;
|
return LazyValue.NULL;
|
||||||
}
|
}
|
||||||
final Value where = lv.get(1).evalValue(c);
|
Value where = lv.get(1).evalValue(c);
|
||||||
final Value what = lv.get(2).evalValue(c);
|
Value what = lv.get(2).evalValue(c);
|
||||||
final Value retVal = BooleanValue.of((lv.size() > 3)
|
Value retVal = BooleanValue.of((lv.size() > 3)
|
||||||
? cvi.put(where, what, lv.get(3).evalValue(c))
|
? cvi.put(where, what, lv.get(3).evalValue(c))
|
||||||
: cvi.put(where, what));
|
: cvi.put(where, what));
|
||||||
return (cc, tt) -> retVal;
|
return (cc, tt) -> retVal;
|
||||||
@@ -328,23 +328,23 @@ public class DataStructures
|
|||||||
// same as `get`
|
// same as `get`
|
||||||
expression.addLazyFunction("delete", (c, t, lv) ->
|
expression.addLazyFunction("delete", (c, t, lv) ->
|
||||||
{
|
{
|
||||||
if (lv.size() == 0)
|
if (lv.isEmpty())
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("'delete' requires parameters");
|
throw new InternalExpressionException("'delete' requires parameters");
|
||||||
}
|
}
|
||||||
if (lv.size() == 1)
|
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))
|
if (!(v instanceof final LContainerValue lcv))
|
||||||
{
|
{
|
||||||
return LazyValue.NULL;
|
return LazyValue.NULL;
|
||||||
}
|
}
|
||||||
final ContainerValueInterface container = lcv.container();
|
ContainerValueInterface container = lcv.container();
|
||||||
if (container == null)
|
if (container == null)
|
||||||
{
|
{
|
||||||
return LazyValue.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;
|
return (cc, tt) -> ret;
|
||||||
}
|
}
|
||||||
Value container = lv.get(0).evalValue(c);
|
Value container = lv.get(0).evalValue(c);
|
||||||
@@ -360,7 +360,7 @@ public class DataStructures
|
|||||||
{
|
{
|
||||||
return LazyValue.NULL;
|
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;
|
return (cc, tt) -> ret;
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -370,7 +370,7 @@ public class DataStructures
|
|||||||
{
|
{
|
||||||
return StringValue.of(new String(Base64.getDecoder().decode(v.getString()), StandardCharsets.UTF_8));
|
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);
|
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);
|
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);
|
throw new ThrowStatement("Invalid json string: " + v.getString(), Throwables.JSON_ERROR);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ import java.util.Locale;
|
|||||||
|
|
||||||
public class Functions
|
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
|
// artificial construct to handle user defined functions and function definitions
|
||||||
expression.addContextFunction("import", -1, (c, t, lv) ->
|
expression.addContextFunction("import", -1, (c, t, lv) ->
|
||||||
@@ -45,28 +45,28 @@ public class Functions
|
|||||||
expression.addCustomFunction("call", new Fluff.AbstractLazyFunction(-1, "call")
|
expression.addCustomFunction("call", new Fluff.AbstractLazyFunction(-1, "call")
|
||||||
{
|
{
|
||||||
@Override
|
@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");
|
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
|
//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
|
if (t != Context.SIGNATURE) // just call the function
|
||||||
{
|
{
|
||||||
final List<Value> args = Fluff.AbstractFunction.unpackLazy(lv, c, Context.NONE);
|
List<Value> args = Fluff.AbstractFunction.unpackLazy(lv, c, Context.NONE);
|
||||||
final FunctionArgument functionArgument = FunctionArgument.findIn(c, expression.module, args, 0, false, true);
|
FunctionArgument functionArgument = FunctionArgument.findIn(c, expression.module, args, 0, false, true);
|
||||||
final FunctionValue fun = functionArgument.function;
|
FunctionValue fun = functionArgument.function;
|
||||||
return fun.callInContext(c, t, functionArgument.args);
|
return fun.callInContext(c, t, functionArgument.args);
|
||||||
}
|
}
|
||||||
// gimme signature
|
// gimme signature
|
||||||
final String name = lv.get(0).evalValue(c, Context.NONE).getString();
|
String name = lv.get(0).evalValue(c, Context.NONE).getString();
|
||||||
final List<String> args = new ArrayList<>();
|
List<String> args = new ArrayList<>();
|
||||||
final List<String> globals = new ArrayList<>();
|
List<String> globals = new ArrayList<>();
|
||||||
String varArgs = null;
|
String varArgs = null;
|
||||||
for (int i = 1; i < lv.size(); i++)
|
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())
|
if (!v.isBound())
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("Only variables can be used in function signature, not " + v.getString());
|
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);
|
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;
|
return (cc, tt) -> retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,7 +108,7 @@ public class Functions
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Context.Type staticType(final Context.Type outerType)
|
public Context.Type staticType(Context.Type outerType)
|
||||||
{
|
{
|
||||||
return outerType == Context.SIGNATURE ? Context.LOCALIZATION : Context.NONE;
|
return outerType == Context.SIGNATURE ? Context.LOCALIZATION : Context.NONE;
|
||||||
}
|
}
|
||||||
@@ -130,19 +130,19 @@ public class Functions
|
|||||||
{
|
{
|
||||||
if (type == Context.MAPDEF)
|
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;
|
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))
|
if (!(v1 instanceof final FunctionSignatureValue sign))
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("'->' operator requires a function signature on the LHS");
|
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;
|
return (cc, tt) -> result;
|
||||||
});
|
});
|
||||||
|
|
||||||
expression.addImpureFunction("return", (lv) -> {
|
expression.addImpureFunction("return", lv -> {
|
||||||
throw new ReturnStatement(lv.size() == 0 ? Value.NULL : lv.get(0));
|
throw new ReturnStatement(lv.size() == 0 ? Value.NULL : lv.get(0));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,14 +17,14 @@ import java.util.List;
|
|||||||
|
|
||||||
public class Loops
|
public class Loops
|
||||||
{
|
{
|
||||||
public static void apply(final Expression expression)
|
public static void apply(Expression expression)
|
||||||
{
|
{
|
||||||
// condition and expression will get a bound '_i'
|
// condition and expression will get a bound '_i'
|
||||||
// returns last successful expression or false
|
// returns last successful expression or false
|
||||||
// while(cond, limit, expr) => ??
|
// while(cond, limit, expr) => ??
|
||||||
expression.addImpureFunction("break", lv ->
|
expression.addImpureFunction("break", lv ->
|
||||||
{
|
{
|
||||||
if (lv.size() == 0)
|
if (lv.isEmpty())
|
||||||
{
|
{
|
||||||
throw new BreakStatement(null);
|
throw new BreakStatement(null);
|
||||||
}
|
}
|
||||||
@@ -37,7 +37,7 @@ public class Loops
|
|||||||
|
|
||||||
expression.addImpureFunction("continue", lv ->
|
expression.addImpureFunction("continue", lv ->
|
||||||
{
|
{
|
||||||
if (lv.size() == 0)
|
if (lv.isEmpty())
|
||||||
{
|
{
|
||||||
throw new ContinueStatement(null);
|
throw new ContinueStatement(null);
|
||||||
}
|
}
|
||||||
@@ -51,13 +51,13 @@ public class Loops
|
|||||||
// lazy
|
// lazy
|
||||||
expression.addLazyFunction("while", 3, (c, t, lv) ->
|
expression.addLazyFunction("while", 3, (c, t, lv) ->
|
||||||
{
|
{
|
||||||
final long limit = NumericValue.asNumber(lv.get(1).evalValue(c)).getLong();
|
long limit = NumericValue.asNumber(lv.get(1).evalValue(c)).getLong();
|
||||||
final LazyValue condition = lv.get(0);
|
LazyValue condition = lv.get(0);
|
||||||
final LazyValue expr = lv.get(2);
|
LazyValue expr = lv.get(2);
|
||||||
long i = 0;
|
long i = 0;
|
||||||
Value lastOne = Value.NULL;
|
Value lastOne = Value.NULL;
|
||||||
//scoping
|
//scoping
|
||||||
final LazyValue _val = c.getVariable("_");
|
LazyValue defaultVal = c.getVariable("_");
|
||||||
c.setVariable("_", (cc, tt) -> new NumericValue(0).bindTo("_"));
|
c.setVariable("_", (cc, tt) -> new NumericValue(0).bindTo("_"));
|
||||||
while (i < limit && condition.evalValue(c, Context.BOOLEAN).getBoolean())
|
while (i < limit && condition.evalValue(c, Context.BOOLEAN).getBoolean())
|
||||||
{
|
{
|
||||||
@@ -65,7 +65,7 @@ public class Loops
|
|||||||
{
|
{
|
||||||
lastOne = expr.evalValue(c, t);
|
lastOne = expr.evalValue(c, t);
|
||||||
}
|
}
|
||||||
catch (final BreakStatement | ContinueStatement stmt)
|
catch (BreakStatement | ContinueStatement stmt)
|
||||||
{
|
{
|
||||||
if (stmt.retval != null)
|
if (stmt.retval != null)
|
||||||
{
|
{
|
||||||
@@ -77,33 +77,33 @@ public class Loops
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
final long seriously = i;
|
long seriously = i;
|
||||||
c.setVariable("_", (cc, tt) -> new NumericValue(seriously).bindTo("_"));
|
c.setVariable("_", (cc, tt) -> new NumericValue(seriously).bindTo("_"));
|
||||||
}
|
}
|
||||||
//revering scope
|
//revering scope
|
||||||
c.setVariable("_", _val);
|
c.setVariable("_", defaultVal);
|
||||||
final Value lastValueNoKidding = lastOne;
|
Value lastValueNoKidding = lastOne;
|
||||||
return (cc, tt) -> lastValueNoKidding;
|
return (cc, tt) -> lastValueNoKidding;
|
||||||
});
|
});
|
||||||
|
|
||||||
// loop(Num, expr) => last_value
|
// loop(Num, expr) => lastdefaultValue
|
||||||
// expr receives bounded variable '_' indicating iteration
|
// expr receives bounded variable '_' indicating iteration
|
||||||
expression.addLazyFunction("loop", 2, (c, t, lv) ->
|
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;
|
Value lastOne = Value.NULL;
|
||||||
final LazyValue expr = lv.get(1);
|
LazyValue expr = lv.get(1);
|
||||||
//scoping
|
//scoping
|
||||||
final LazyValue _val = c.getVariable("_");
|
LazyValue defaultVal = c.getVariable("_");
|
||||||
for (long i = 0; i < limit; i++)
|
for (long i = 0; i < limit; i++)
|
||||||
{
|
{
|
||||||
final long whyYouAsk = i;
|
long whyYouAsk = i;
|
||||||
c.setVariable("_", (cc, tt) -> new NumericValue(whyYouAsk).bindTo("_"));
|
c.setVariable("_", (cc, tt) -> new NumericValue(whyYouAsk).bindTo("_"));
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
lastOne = expr.evalValue(c, t);
|
lastOne = expr.evalValue(c, t);
|
||||||
}
|
}
|
||||||
catch (final BreakStatement | ContinueStatement stmt)
|
catch (BreakStatement | ContinueStatement stmt)
|
||||||
{
|
{
|
||||||
if (stmt.retval != null)
|
if (stmt.retval != null)
|
||||||
{
|
{
|
||||||
@@ -116,8 +116,8 @@ public class Loops
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
//revering scope
|
//revering scope
|
||||||
c.setVariable("_", _val);
|
c.setVariable("_", defaultVal);
|
||||||
final Value trulyLastOne = lastOne;
|
Value trulyLastOne = lastOne;
|
||||||
return (cc, tt) -> trulyLastOne;
|
return (cc, tt) -> trulyLastOne;
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -125,7 +125,7 @@ public class Loops
|
|||||||
// receives bounded variable '_' with the expression
|
// receives bounded variable '_' with the expression
|
||||||
expression.addLazyFunction("map", 2, (c, t, lv) ->
|
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())
|
if (rval.isNull())
|
||||||
{
|
{
|
||||||
return ListValue.lazyEmpty();
|
return ListValue.lazyEmpty();
|
||||||
@@ -134,25 +134,25 @@ public class Loops
|
|||||||
{
|
{
|
||||||
throw new InternalExpressionException("First argument of 'map' function should be a list or iterator");
|
throw new InternalExpressionException("First argument of 'map' function should be a list or iterator");
|
||||||
}
|
}
|
||||||
final Iterator<Value> iterator = alv.iterator();
|
Iterator<Value> iterator = alv.iterator();
|
||||||
final LazyValue expr = lv.get(1);
|
LazyValue expr = lv.get(1);
|
||||||
//scoping
|
//scoping
|
||||||
final LazyValue _val = c.getVariable("_");
|
LazyValue defaultVal = c.getVariable("_");
|
||||||
final LazyValue _iter = c.getVariable("_i");
|
LazyValue iterVal = c.getVariable("_i");
|
||||||
final List<Value> result = new ArrayList<>();
|
List<Value> result = new ArrayList<>();
|
||||||
for (int i = 0; iterator.hasNext(); i++)
|
for (int i = 0; iterator.hasNext(); i++)
|
||||||
{
|
{
|
||||||
final Value next = iterator.next();
|
Value next = iterator.next();
|
||||||
final String var = next.boundVariable;
|
String variable = next.boundVariable;
|
||||||
next.bindTo("_");
|
next.bindTo("_");
|
||||||
final int doYouReally = i;
|
int doYouReally = i;
|
||||||
c.setVariable("_", (cc, tt) -> next);
|
c.setVariable("_", (cc, tt) -> next);
|
||||||
c.setVariable("_i", (cc, tt) -> new NumericValue(doYouReally).bindTo("_i"));
|
c.setVariable("_i", (cc, tt) -> new NumericValue(doYouReally).bindTo("_i"));
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
result.add(expr.evalValue(c, t));
|
result.add(expr.evalValue(c, t));
|
||||||
}
|
}
|
||||||
catch (final BreakStatement | ContinueStatement stmt)
|
catch (BreakStatement | ContinueStatement stmt)
|
||||||
{
|
{
|
||||||
if (stmt.retval != null)
|
if (stmt.retval != null)
|
||||||
{
|
{
|
||||||
@@ -160,17 +160,17 @@ public class Loops
|
|||||||
}
|
}
|
||||||
if (stmt instanceof BreakStatement)
|
if (stmt instanceof BreakStatement)
|
||||||
{
|
{
|
||||||
next.boundVariable = var;
|
next.boundVariable = variable;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
next.boundVariable = var;
|
next.boundVariable = variable;
|
||||||
}
|
}
|
||||||
((AbstractListValue) rval).fatality();
|
((AbstractListValue) rval).fatality();
|
||||||
final Value ret = ListValue.wrap(result);
|
Value ret = ListValue.wrap(result);
|
||||||
//revering scope
|
//revering scope
|
||||||
c.setVariable("_", _val);
|
c.setVariable("_", defaultVal);
|
||||||
c.setVariable("_i", _iter);
|
c.setVariable("_i", iterVal);
|
||||||
return (cc, tt) -> ret;
|
return (cc, tt) -> ret;
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -179,7 +179,7 @@ public class Loops
|
|||||||
// produces list of values for which the expression is true
|
// produces list of values for which the expression is true
|
||||||
expression.addLazyFunction("filter", 2, (c, t, lv) ->
|
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())
|
if (rval.isNull())
|
||||||
{
|
{
|
||||||
return ListValue.lazyEmpty();
|
return ListValue.lazyEmpty();
|
||||||
@@ -188,18 +188,18 @@ public class Loops
|
|||||||
{
|
{
|
||||||
throw new InternalExpressionException("First argument of 'filter' function should be a list or iterator");
|
throw new InternalExpressionException("First argument of 'filter' function should be a list or iterator");
|
||||||
}
|
}
|
||||||
final Iterator<Value> iterator = alv.iterator();
|
Iterator<Value> iterator = alv.iterator();
|
||||||
final LazyValue expr = lv.get(1);
|
LazyValue expr = lv.get(1);
|
||||||
//scoping
|
//scoping
|
||||||
final LazyValue _val = c.getVariable("_");
|
LazyValue defaultVal = c.getVariable("_");
|
||||||
final LazyValue _iter = c.getVariable("_i");
|
LazyValue iterVal = c.getVariable("_i");
|
||||||
final List<Value> result = new ArrayList<>();
|
List<Value> result = new ArrayList<>();
|
||||||
for (int i = 0; iterator.hasNext(); i++)
|
for (int i = 0; iterator.hasNext(); i++)
|
||||||
{
|
{
|
||||||
final Value next = iterator.next();
|
Value next = iterator.next();
|
||||||
final String var = next.boundVariable;
|
String veriable = next.boundVariable;
|
||||||
next.bindTo("_");
|
next.bindTo("_");
|
||||||
final int seriously = i;
|
int seriously = i;
|
||||||
c.setVariable("_", (cc, tt) -> next);
|
c.setVariable("_", (cc, tt) -> next);
|
||||||
c.setVariable("_i", (cc, tt) -> new NumericValue(seriously).bindTo("_i"));
|
c.setVariable("_i", (cc, tt) -> new NumericValue(seriously).bindTo("_i"));
|
||||||
try
|
try
|
||||||
@@ -209,7 +209,7 @@ public class Loops
|
|||||||
result.add(next);
|
result.add(next);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (final BreakStatement | ContinueStatement stmt)
|
catch (BreakStatement | ContinueStatement stmt)
|
||||||
{
|
{
|
||||||
if (stmt.retval != null && stmt.retval.getBoolean())
|
if (stmt.retval != null && stmt.retval.getBoolean())
|
||||||
{
|
{
|
||||||
@@ -217,17 +217,17 @@ public class Loops
|
|||||||
}
|
}
|
||||||
if (stmt instanceof BreakStatement)
|
if (stmt instanceof BreakStatement)
|
||||||
{
|
{
|
||||||
next.boundVariable = var;
|
next.boundVariable = veriable;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
next.boundVariable = var;
|
next.boundVariable = veriable;
|
||||||
}
|
}
|
||||||
((AbstractListValue) rval).fatality();
|
((AbstractListValue) rval).fatality();
|
||||||
final Value ret = ListValue.wrap(result);
|
Value ret = ListValue.wrap(result);
|
||||||
//revering scope
|
//revering scope
|
||||||
c.setVariable("_", _val);
|
c.setVariable("_", defaultVal);
|
||||||
c.setVariable("_i", _iter);
|
c.setVariable("_i", iterVal);
|
||||||
return (cc, tt) -> ret;
|
return (cc, tt) -> ret;
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -236,7 +236,7 @@ public class Loops
|
|||||||
// returns first element on the list for which the expr is true
|
// returns first element on the list for which the expr is true
|
||||||
expression.addLazyFunction("first", 2, (c, t, lv) ->
|
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())
|
if (rval.isNull())
|
||||||
{
|
{
|
||||||
return LazyValue.NULL;
|
return LazyValue.NULL;
|
||||||
@@ -245,18 +245,18 @@ public class Loops
|
|||||||
{
|
{
|
||||||
throw new InternalExpressionException("First argument of 'first' function should be a list or iterator");
|
throw new InternalExpressionException("First argument of 'first' function should be a list or iterator");
|
||||||
}
|
}
|
||||||
final Iterator<Value> iterator = alv.iterator();
|
Iterator<Value> iterator = alv.iterator();
|
||||||
final LazyValue expr = lv.get(1);
|
LazyValue expr = lv.get(1);
|
||||||
//scoping
|
//scoping
|
||||||
final LazyValue _val = c.getVariable("_");
|
LazyValue defaultVal = c.getVariable("_");
|
||||||
final LazyValue _iter = c.getVariable("_i");
|
LazyValue iterVal = c.getVariable("_i");
|
||||||
Value result = Value.NULL;
|
Value result = Value.NULL;
|
||||||
for (int i = 0; iterator.hasNext(); i++)
|
for (int i = 0; iterator.hasNext(); i++)
|
||||||
{
|
{
|
||||||
final Value next = iterator.next();
|
Value next = iterator.next();
|
||||||
final String var = next.boundVariable;
|
String variable = next.boundVariable;
|
||||||
next.bindTo("_");
|
next.bindTo("_");
|
||||||
final int seriously = i;
|
int seriously = i;
|
||||||
c.setVariable("_", (cc, tt) -> next);
|
c.setVariable("_", (cc, tt) -> next);
|
||||||
c.setVariable("_i", (cc, tt) -> new NumericValue(seriously).bindTo("_i"));
|
c.setVariable("_i", (cc, tt) -> new NumericValue(seriously).bindTo("_i"));
|
||||||
try
|
try
|
||||||
@@ -264,27 +264,27 @@ public class Loops
|
|||||||
if (expr.evalValue(c, Context.BOOLEAN).getBoolean())
|
if (expr.evalValue(c, Context.BOOLEAN).getBoolean())
|
||||||
{
|
{
|
||||||
result = next;
|
result = next;
|
||||||
next.boundVariable = var;
|
next.boundVariable = variable;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (final BreakStatement stmt)
|
catch (BreakStatement stmt)
|
||||||
{
|
{
|
||||||
result = stmt.retval == null ? next : stmt.retval;
|
result = stmt.retval == null ? next : stmt.retval;
|
||||||
next.boundVariable = var;
|
next.boundVariable = variable;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
catch (final ContinueStatement ignored)
|
catch (ContinueStatement ignored)
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("'continue' inside 'first' function has no sense");
|
throw new InternalExpressionException("'continue' inside 'first' function has no sense");
|
||||||
}
|
}
|
||||||
next.boundVariable = var;
|
next.boundVariable = variable;
|
||||||
}
|
}
|
||||||
//revering scope
|
//revering scope
|
||||||
((AbstractListValue) rval).fatality();
|
((AbstractListValue) rval).fatality();
|
||||||
final Value whyWontYouTrustMeJava = result;
|
Value whyWontYouTrustMeJava = result;
|
||||||
c.setVariable("_", _val);
|
c.setVariable("_", defaultVal);
|
||||||
c.setVariable("_i", _iter);
|
c.setVariable("_i", iterVal);
|
||||||
return (cc, tt) -> whyWontYouTrustMeJava;
|
return (cc, tt) -> whyWontYouTrustMeJava;
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -293,7 +293,7 @@ public class Loops
|
|||||||
// returns true if expr is true for all items
|
// returns true if expr is true for all items
|
||||||
expression.addLazyFunction("all", 2, (c, t, lv) ->
|
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())
|
if (rval.isNull())
|
||||||
{
|
{
|
||||||
return LazyValue.TRUE;
|
return LazyValue.TRUE;
|
||||||
@@ -302,42 +302,42 @@ public class Loops
|
|||||||
{
|
{
|
||||||
throw new InternalExpressionException("First argument of 'all' function should be a list or iterator");
|
throw new InternalExpressionException("First argument of 'all' function should be a list or iterator");
|
||||||
}
|
}
|
||||||
final Iterator<Value> iterator = alv.iterator();
|
Iterator<Value> iterator = alv.iterator();
|
||||||
final LazyValue expr = lv.get(1);
|
LazyValue expr = lv.get(1);
|
||||||
//scoping
|
//scoping
|
||||||
final LazyValue _val = c.getVariable("_");
|
LazyValue defaultVal = c.getVariable("_");
|
||||||
final LazyValue _iter = c.getVariable("_i");
|
LazyValue iterVal = c.getVariable("_i");
|
||||||
LazyValue result = LazyValue.TRUE;
|
LazyValue result = LazyValue.TRUE;
|
||||||
for (int i = 0; iterator.hasNext(); i++)
|
for (int i = 0; iterator.hasNext(); i++)
|
||||||
{
|
{
|
||||||
final Value next = iterator.next();
|
Value next = iterator.next();
|
||||||
final String var = next.boundVariable;
|
String variable = next.boundVariable;
|
||||||
next.bindTo("_");
|
next.bindTo("_");
|
||||||
final int seriously = i;
|
int seriously = i;
|
||||||
c.setVariable("_", (cc, tt) -> next);
|
c.setVariable("_", (cc, tt) -> next);
|
||||||
c.setVariable("_i", (cc, tt) -> new NumericValue(seriously).bindTo("_i"));
|
c.setVariable("_i", (cc, tt) -> new NumericValue(seriously).bindTo("_i"));
|
||||||
if (!expr.evalValue(c, Context.BOOLEAN).getBoolean())
|
if (!expr.evalValue(c, Context.BOOLEAN).getBoolean())
|
||||||
{
|
{
|
||||||
result = LazyValue.FALSE;
|
result = LazyValue.FALSE;
|
||||||
next.boundVariable = var;
|
next.boundVariable = variable;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
next.boundVariable = var;
|
next.boundVariable = variable;
|
||||||
}
|
}
|
||||||
//revering scope
|
//revering scope
|
||||||
((AbstractListValue) rval).fatality();
|
((AbstractListValue) rval).fatality();
|
||||||
c.setVariable("_", _val);
|
c.setVariable("_", defaultVal);
|
||||||
c.setVariable("_i", _iter);
|
c.setVariable("_i", iterVal);
|
||||||
return result;
|
return result;
|
||||||
});
|
});
|
||||||
|
|
||||||
// runs traditional for(init, condition, increment, body) tri-argument for loop with body in between
|
// runs traditional for(init, condition, increment, body) tri-argument for loop with body in between
|
||||||
expression.addLazyFunction("c_for", 4, (c, t, lv) ->
|
expression.addLazyFunction("c_for", 4, (c, t, lv) ->
|
||||||
{
|
{
|
||||||
final LazyValue initial = lv.get(0);
|
LazyValue initial = lv.get(0);
|
||||||
final LazyValue condition = lv.get(1);
|
LazyValue condition = lv.get(1);
|
||||||
final LazyValue increment = lv.get(2);
|
LazyValue increment = lv.get(2);
|
||||||
final LazyValue body = lv.get(3);
|
LazyValue body = lv.get(3);
|
||||||
int iterations = 0;
|
int iterations = 0;
|
||||||
for (initial.evalValue(c, Context.VOID); condition.evalValue(c, Context.BOOLEAN).getBoolean(); increment.evalValue(c, Context.VOID))
|
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);
|
body.evalValue(c, Context.VOID);
|
||||||
}
|
}
|
||||||
catch (final BreakStatement stmt)
|
catch (BreakStatement stmt)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
catch (final ContinueStatement ignored)
|
catch (ContinueStatement ignored)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
iterations++;
|
iterations++;
|
||||||
}
|
}
|
||||||
final int finalIterations = iterations;
|
int finalIterations = iterations;
|
||||||
return (cc, tt) -> new NumericValue(finalIterations);
|
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
|
// 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) ->
|
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())
|
if (rval.isNull())
|
||||||
{
|
{
|
||||||
return LazyValue.ZERO;
|
return LazyValue.ZERO;
|
||||||
@@ -372,18 +372,18 @@ public class Loops
|
|||||||
{
|
{
|
||||||
throw new InternalExpressionException("First argument of 'for' function should be a list or iterator");
|
throw new InternalExpressionException("First argument of 'for' function should be a list or iterator");
|
||||||
}
|
}
|
||||||
final Iterator<Value> iterator = alv.iterator();
|
Iterator<Value> iterator = alv.iterator();
|
||||||
final LazyValue expr = lv.get(1);
|
LazyValue expr = lv.get(1);
|
||||||
//scoping
|
//scoping
|
||||||
final LazyValue _val = c.getVariable("_");
|
LazyValue defaultVal = c.getVariable("_");
|
||||||
final LazyValue _ite = c.getVariable("_i");
|
LazyValue iterVal = c.getVariable("_i");
|
||||||
int successCount = 0;
|
int successCount = 0;
|
||||||
for (int i = 0; iterator.hasNext(); i++)
|
for (int i = 0; iterator.hasNext(); i++)
|
||||||
{
|
{
|
||||||
final Value next = iterator.next();
|
Value next = iterator.next();
|
||||||
final String var = next.boundVariable;
|
String variable = next.boundVariable;
|
||||||
next.bindTo("_");
|
next.bindTo("_");
|
||||||
final int seriously = i;
|
int seriously = i;
|
||||||
c.setVariable("_", (cc, tt) -> next);
|
c.setVariable("_", (cc, tt) -> next);
|
||||||
c.setVariable("_i", (cc, tt) -> new NumericValue(seriously).bindTo("_i"));
|
c.setVariable("_i", (cc, tt) -> new NumericValue(seriously).bindTo("_i"));
|
||||||
Value result = Value.FALSE;
|
Value result = Value.FALSE;
|
||||||
@@ -391,7 +391,7 @@ public class Loops
|
|||||||
{
|
{
|
||||||
result = expr.evalValue(c, t);
|
result = expr.evalValue(c, t);
|
||||||
}
|
}
|
||||||
catch (final BreakStatement | ContinueStatement stmt)
|
catch (BreakStatement | ContinueStatement stmt)
|
||||||
{
|
{
|
||||||
if (stmt.retval != null)
|
if (stmt.retval != null)
|
||||||
{
|
{
|
||||||
@@ -399,7 +399,7 @@ public class Loops
|
|||||||
}
|
}
|
||||||
if (stmt instanceof BreakStatement)
|
if (stmt instanceof BreakStatement)
|
||||||
{
|
{
|
||||||
next.boundVariable = var;
|
next.boundVariable = variable;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -407,13 +407,13 @@ public class Loops
|
|||||||
{
|
{
|
||||||
successCount++;
|
successCount++;
|
||||||
}
|
}
|
||||||
next.boundVariable = var;
|
next.boundVariable = variable;
|
||||||
}
|
}
|
||||||
//revering scope
|
//revering scope
|
||||||
((AbstractListValue) rval).fatality();
|
((AbstractListValue) rval).fatality();
|
||||||
c.setVariable("_", _val);
|
c.setVariable("_", defaultVal);
|
||||||
c.setVariable("_i", _ite);
|
c.setVariable("_i", iterVal);
|
||||||
final long promiseWontChange = successCount;
|
long promiseWontChange = successCount;
|
||||||
return (cc, tt) -> new NumericValue(promiseWontChange);
|
return (cc, tt) -> new NumericValue(promiseWontChange);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -425,7 +425,7 @@ public class Loops
|
|||||||
expression.addLazyFunction("reduce", 3, (c, t, lv) ->
|
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())
|
if (rval.isNull())
|
||||||
{
|
{
|
||||||
return ListValue.lazyEmpty();
|
return ListValue.lazyEmpty();
|
||||||
@@ -434,28 +434,28 @@ public class Loops
|
|||||||
{
|
{
|
||||||
throw new InternalExpressionException("First argument of 'reduce' should be a list or iterator");
|
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);
|
Value acc = lv.get(2).evalValue(c, Context.NONE);
|
||||||
final Iterator<Value> iterator = alv.iterator();
|
Iterator<Value> iterator = alv.iterator();
|
||||||
|
|
||||||
if (!iterator.hasNext())
|
if (!iterator.hasNext())
|
||||||
{
|
{
|
||||||
final Value seriouslyWontChange = acc;
|
Value seriouslyWontChange = acc;
|
||||||
return (cc, tt) -> seriouslyWontChange;
|
return (cc, tt) -> seriouslyWontChange;
|
||||||
}
|
}
|
||||||
|
|
||||||
//scoping
|
//scoping
|
||||||
final LazyValue _val = c.getVariable("_");
|
LazyValue defaultVal = c.getVariable("_");
|
||||||
final LazyValue _acc = c.getVariable("_a");
|
LazyValue accumulatorVal = c.getVariable("_a");
|
||||||
final LazyValue _ite = c.getVariable("_i");
|
LazyValue iterVal = c.getVariable("_i");
|
||||||
|
|
||||||
for (int i = 0; iterator.hasNext(); i++)
|
for (int i = 0; iterator.hasNext(); i++)
|
||||||
{
|
{
|
||||||
final Value next = iterator.next();
|
Value next = iterator.next();
|
||||||
final String var = next.boundVariable;
|
String variable = next.boundVariable;
|
||||||
next.bindTo("_");
|
next.bindTo("_");
|
||||||
final Value promiseWontChangeYou = acc;
|
Value promiseWontChangeYou = acc;
|
||||||
final int seriously = i;
|
int seriously = i;
|
||||||
c.setVariable("_a", (cc, tt) -> promiseWontChangeYou.bindTo("_a"));
|
c.setVariable("_a", (cc, tt) -> promiseWontChangeYou.bindTo("_a"));
|
||||||
c.setVariable("_", (cc, tt) -> next);
|
c.setVariable("_", (cc, tt) -> next);
|
||||||
c.setVariable("_i", (cc, tt) -> new NumericValue(seriously).bindTo("_i"));
|
c.setVariable("_i", (cc, tt) -> new NumericValue(seriously).bindTo("_i"));
|
||||||
@@ -463,7 +463,7 @@ public class Loops
|
|||||||
{
|
{
|
||||||
acc = expr.evalValue(c, t);
|
acc = expr.evalValue(c, t);
|
||||||
}
|
}
|
||||||
catch (final BreakStatement | ContinueStatement stmt)
|
catch (BreakStatement | ContinueStatement stmt)
|
||||||
{
|
{
|
||||||
if (stmt.retval != null)
|
if (stmt.retval != null)
|
||||||
{
|
{
|
||||||
@@ -471,19 +471,19 @@ public class Loops
|
|||||||
}
|
}
|
||||||
if (stmt instanceof BreakStatement)
|
if (stmt instanceof BreakStatement)
|
||||||
{
|
{
|
||||||
next.boundVariable = var;
|
next.boundVariable = variable;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
next.boundVariable = var;
|
next.boundVariable = variable;
|
||||||
}
|
}
|
||||||
//reverting scope
|
//reverting scope
|
||||||
((AbstractListValue) rval).fatality();
|
((AbstractListValue) rval).fatality();
|
||||||
c.setVariable("_a", _acc);
|
c.setVariable("_a", accumulatorVal);
|
||||||
c.setVariable("_", _val);
|
c.setVariable("_", defaultVal);
|
||||||
c.setVariable("_i", _ite);
|
c.setVariable("_i", iterVal);
|
||||||
|
|
||||||
final Value hopeItsEnoughPromise = acc;
|
Value hopeItsEnoughPromise = acc;
|
||||||
return (cc, tt) -> hopeItsEnoughPromise;
|
return (cc, tt) -> hopeItsEnoughPromise;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,17 +39,17 @@ public class Operators
|
|||||||
put("nextop;", 1);
|
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.addBinaryOperator("+", precedence.get("addition+-"), true, Value::add);
|
||||||
expression.addFunction("sum", lv -> {
|
expression.addFunction("sum", lv -> {
|
||||||
final int size = lv.size();
|
int size = lv.size();
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
{
|
{
|
||||||
return Value.NULL;
|
return Value.NULL;
|
||||||
}
|
}
|
||||||
Value accumulator = lv.get(0);
|
Value accumulator = lv.get(0);
|
||||||
for (final Value v : lv.subList(1, size))
|
for (Value v : lv.subList(1, size))
|
||||||
{
|
{
|
||||||
accumulator = accumulator.add(v);
|
accumulator = accumulator.add(v);
|
||||||
}
|
}
|
||||||
@@ -59,13 +59,13 @@ public class Operators
|
|||||||
|
|
||||||
expression.addBinaryOperator("-", precedence.get("addition+-"), true, Value::subtract);
|
expression.addBinaryOperator("-", precedence.get("addition+-"), true, Value::subtract);
|
||||||
expression.addFunction("difference", lv -> {
|
expression.addFunction("difference", lv -> {
|
||||||
final int size = lv.size();
|
int size = lv.size();
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
{
|
{
|
||||||
return Value.NULL;
|
return Value.NULL;
|
||||||
}
|
}
|
||||||
Value accumulator = lv.get(0);
|
Value accumulator = lv.get(0);
|
||||||
for (final Value v : lv.subList(1, size))
|
for (Value v : lv.subList(1, size))
|
||||||
{
|
{
|
||||||
accumulator = accumulator.subtract(v);
|
accumulator = accumulator.subtract(v);
|
||||||
}
|
}
|
||||||
@@ -75,13 +75,13 @@ public class Operators
|
|||||||
|
|
||||||
expression.addBinaryOperator("*", precedence.get("multiplication*/%"), true, Value::multiply);
|
expression.addBinaryOperator("*", precedence.get("multiplication*/%"), true, Value::multiply);
|
||||||
expression.addFunction("product", lv -> {
|
expression.addFunction("product", lv -> {
|
||||||
final int size = lv.size();
|
int size = lv.size();
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
{
|
{
|
||||||
return Value.NULL;
|
return Value.NULL;
|
||||||
}
|
}
|
||||||
Value accumulator = lv.get(0);
|
Value accumulator = lv.get(0);
|
||||||
for (final Value v : lv.subList(1, size))
|
for (Value v : lv.subList(1, size))
|
||||||
{
|
{
|
||||||
accumulator = accumulator.multiply(v);
|
accumulator = accumulator.multiply(v);
|
||||||
}
|
}
|
||||||
@@ -91,13 +91,13 @@ public class Operators
|
|||||||
|
|
||||||
expression.addBinaryOperator("/", precedence.get("multiplication*/%"), true, Value::divide);
|
expression.addBinaryOperator("/", precedence.get("multiplication*/%"), true, Value::divide);
|
||||||
expression.addFunction("quotient", lv -> {
|
expression.addFunction("quotient", lv -> {
|
||||||
final int size = lv.size();
|
int size = lv.size();
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
{
|
{
|
||||||
return Value.NULL;
|
return Value.NULL;
|
||||||
}
|
}
|
||||||
Value accumulator = lv.get(0);
|
Value accumulator = lv.get(0);
|
||||||
for (final Value v : lv.subList(1, size))
|
for (Value v : lv.subList(1, size))
|
||||||
{
|
{
|
||||||
accumulator = accumulator.divide(v);
|
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())));
|
new NumericValue(java.lang.Math.pow(NumericValue.asNumber(v1).getDouble(), NumericValue.asNumber(v2).getDouble())));
|
||||||
|
|
||||||
expression.addFunction("bitwise_and", lv -> {
|
expression.addFunction("bitwise_and", lv -> {
|
||||||
final int size = lv.size();
|
int size = lv.size();
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
{
|
{
|
||||||
return Value.NULL;
|
return Value.NULL;
|
||||||
}
|
}
|
||||||
long accumulator = NumericValue.asNumber(lv.get(0)).getLong();
|
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();
|
accumulator = accumulator & NumericValue.asNumber(v).getLong();
|
||||||
}
|
}
|
||||||
@@ -125,13 +125,13 @@ public class Operators
|
|||||||
});
|
});
|
||||||
|
|
||||||
expression.addFunction("bitwise_xor", lv -> {
|
expression.addFunction("bitwise_xor", lv -> {
|
||||||
final int size = lv.size();
|
int size = lv.size();
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
{
|
{
|
||||||
return Value.NULL;
|
return Value.NULL;
|
||||||
}
|
}
|
||||||
long accumulator = NumericValue.asNumber(lv.get(0)).getLong();
|
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();
|
accumulator = accumulator ^ NumericValue.asNumber(v).getLong();
|
||||||
}
|
}
|
||||||
@@ -139,13 +139,13 @@ public class Operators
|
|||||||
});
|
});
|
||||||
|
|
||||||
expression.addFunction("bitwise_or", lv -> {
|
expression.addFunction("bitwise_or", lv -> {
|
||||||
final int size = lv.size();
|
int size = lv.size();
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
{
|
{
|
||||||
return Value.NULL;
|
return Value.NULL;
|
||||||
}
|
}
|
||||||
long accumulator = NumericValue.asNumber(lv.get(0)).getLong();
|
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();
|
accumulator = accumulator | NumericValue.asNumber(v).getLong();
|
||||||
}
|
}
|
||||||
@@ -155,22 +155,22 @@ public class Operators
|
|||||||
// lazy cause RHS is only conditional
|
// lazy cause RHS is only conditional
|
||||||
expression.addLazyBinaryOperator("&&", precedence.get("and&&"), false, true, t -> Context.Type.BOOLEAN, (c, t, lv1, lv2) ->
|
expression.addLazyBinaryOperator("&&", precedence.get("and&&"), false, true, t -> Context.Type.BOOLEAN, (c, t, lv1, lv2) ->
|
||||||
{ // todo check how is optimizations going
|
{ // 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);
|
return v1.getBoolean() ? lv2 : ((cc, tt) -> v1);
|
||||||
});
|
});
|
||||||
|
|
||||||
expression.addPureLazyFunction("and", -1, t -> Context.Type.BOOLEAN, (c, t, lv) -> {
|
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)
|
if (last == -1)
|
||||||
{
|
{
|
||||||
return LazyValue.TRUE;
|
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)
|
if (val instanceof final FunctionUnpackedArgumentsValue fuav)
|
||||||
{
|
{
|
||||||
for (final Value it : fuav)
|
for (Value it : fuav)
|
||||||
{
|
{
|
||||||
if (!it.getBoolean())
|
if (!it.getBoolean())
|
||||||
{
|
{
|
||||||
@@ -193,22 +193,22 @@ public class Operators
|
|||||||
// lazy cause RHS is only conditional
|
// lazy cause RHS is only conditional
|
||||||
expression.addLazyBinaryOperator("||", precedence.get("or||"), false, true, t -> Context.Type.BOOLEAN, (c, t, lv1, lv2) ->
|
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;
|
return v1.getBoolean() ? ((cc, tt) -> v1) : lv2;
|
||||||
});
|
});
|
||||||
|
|
||||||
expression.addPureLazyFunction("or", -1, t -> Context.Type.BOOLEAN, (c, t, lv) -> {
|
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)
|
if (last == -1)
|
||||||
{
|
{
|
||||||
return LazyValue.FALSE;
|
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)
|
if (val instanceof final FunctionUnpackedArgumentsValue fuav)
|
||||||
{
|
{
|
||||||
for (final Value it : fuav)
|
for (Value it : fuav)
|
||||||
{
|
{
|
||||||
if (it.getBoolean())
|
if (it.getBoolean())
|
||||||
{
|
{
|
||||||
@@ -233,13 +233,13 @@ public class Operators
|
|||||||
expression.addBinaryOperator(">", precedence.get("compare>=><=<"), false, (v1, v2) ->
|
expression.addBinaryOperator(">", precedence.get("compare>=><=<"), false, (v1, v2) ->
|
||||||
BooleanValue.of(v1.compareTo(v2) > 0));
|
BooleanValue.of(v1.compareTo(v2) > 0));
|
||||||
expression.addFunction("decreasing", lv -> {
|
expression.addFunction("decreasing", lv -> {
|
||||||
final int size = lv.size();
|
int size = lv.size();
|
||||||
if (size < 2)
|
if (size < 2)
|
||||||
{
|
{
|
||||||
return Value.TRUE;
|
return Value.TRUE;
|
||||||
}
|
}
|
||||||
Value prev = lv.get(0);
|
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)
|
if (prev.compareTo(next) <= 0)
|
||||||
{
|
{
|
||||||
@@ -254,13 +254,13 @@ public class Operators
|
|||||||
expression.addBinaryOperator(">=", precedence.get("compare>=><=<"), false, (v1, v2) ->
|
expression.addBinaryOperator(">=", precedence.get("compare>=><=<"), false, (v1, v2) ->
|
||||||
BooleanValue.of(v1.compareTo(v2) >= 0));
|
BooleanValue.of(v1.compareTo(v2) >= 0));
|
||||||
expression.addFunction("nonincreasing", lv -> {
|
expression.addFunction("nonincreasing", lv -> {
|
||||||
final int size = lv.size();
|
int size = lv.size();
|
||||||
if (size < 2)
|
if (size < 2)
|
||||||
{
|
{
|
||||||
return Value.TRUE;
|
return Value.TRUE;
|
||||||
}
|
}
|
||||||
Value prev = lv.get(0);
|
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)
|
if (prev.compareTo(next) < 0)
|
||||||
{
|
{
|
||||||
@@ -275,13 +275,13 @@ public class Operators
|
|||||||
expression.addBinaryOperator("<", precedence.get("compare>=><=<"), false, (v1, v2) ->
|
expression.addBinaryOperator("<", precedence.get("compare>=><=<"), false, (v1, v2) ->
|
||||||
BooleanValue.of(v1.compareTo(v2) < 0));
|
BooleanValue.of(v1.compareTo(v2) < 0));
|
||||||
expression.addFunction("increasing", lv -> {
|
expression.addFunction("increasing", lv -> {
|
||||||
final int size = lv.size();
|
int size = lv.size();
|
||||||
if (size < 2)
|
if (size < 2)
|
||||||
{
|
{
|
||||||
return Value.TRUE;
|
return Value.TRUE;
|
||||||
}
|
}
|
||||||
Value prev = lv.get(0);
|
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)
|
if (prev.compareTo(next) >= 0)
|
||||||
{
|
{
|
||||||
@@ -296,13 +296,13 @@ public class Operators
|
|||||||
expression.addBinaryOperator("<=", precedence.get("compare>=><=<"), false, (v1, v2) ->
|
expression.addBinaryOperator("<=", precedence.get("compare>=><=<"), false, (v1, v2) ->
|
||||||
BooleanValue.of(v1.compareTo(v2) <= 0));
|
BooleanValue.of(v1.compareTo(v2) <= 0));
|
||||||
expression.addFunction("nondecreasing", lv -> {
|
expression.addFunction("nondecreasing", lv -> {
|
||||||
final int size = lv.size();
|
int size = lv.size();
|
||||||
if (size < 2)
|
if (size < 2)
|
||||||
{
|
{
|
||||||
return Value.TRUE;
|
return Value.TRUE;
|
||||||
}
|
}
|
||||||
Value prev = lv.get(0);
|
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)
|
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_left", (num, amount) -> num << amount);
|
||||||
expression.addMathematicalBinaryIntFunction("bitwise_shift_right", (num, amount) -> num >> amount);
|
expression.addMathematicalBinaryIntFunction("bitwise_shift_right", (num, amount) -> num >> amount);
|
||||||
expression.addMathematicalBinaryIntFunction("bitwise_roll_left", (num, num2) -> {
|
expression.addMathematicalBinaryIntFunction("bitwise_roll_left", (num, num2) -> {
|
||||||
final long amount = num2 % 64;
|
long amount = num2 % 64;
|
||||||
final long amountToRoll = 64 - amount;
|
long amountToRoll = 64 - amount;
|
||||||
final long rolledBits = ((-1L) >> amountToRoll) << amountToRoll;
|
long rolledBits = ((-1L) >> amountToRoll) << amountToRoll;
|
||||||
final long rolledAmount = (num & rolledBits) >> amountToRoll;
|
long rolledAmount = (num & rolledBits) >> amountToRoll;
|
||||||
return num << amount | rolledAmount;
|
return num << amount | rolledAmount;
|
||||||
});
|
});
|
||||||
expression.addMathematicalBinaryIntFunction("bitwise_roll_right", (num, num2) -> {
|
expression.addMathematicalBinaryIntFunction("bitwise_roll_right", (num, num2) -> {
|
||||||
final long amount = num2 % 64;
|
long amount = num2 % 64;
|
||||||
final long amountToRoll = 64 - amount;
|
long amountToRoll = 64 - amount;
|
||||||
final long rolledBits = ((-1L) << amountToRoll) >> amountToRoll;
|
long rolledBits = ((-1L) << amountToRoll) >> amountToRoll;
|
||||||
final long rolledAmount = (num & rolledBits) << amountToRoll;
|
long rolledAmount = (num & rolledBits) << amountToRoll;
|
||||||
return num >> amount | rolledAmount;
|
return num >> amount | rolledAmount;
|
||||||
});
|
});
|
||||||
expression.addMathematicalUnaryIntFunction("bitwise_not", d -> {
|
expression.addMathematicalUnaryIntFunction("bitwise_not", d -> {
|
||||||
final long num = (long) d;
|
long num = (long) d;
|
||||||
return ~num;
|
return ~num;
|
||||||
});
|
});
|
||||||
expression.addMathematicalUnaryIntFunction("bitwise_popcount", d -> (long) Long.bitCount((long)d));
|
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) ->
|
expression.addBinaryOperator("==", precedence.get("equal==!="), false, (v1, v2) ->
|
||||||
v1.equals(v2) ? Value.TRUE : Value.FALSE);
|
v1.equals(v2) ? Value.TRUE : Value.FALSE);
|
||||||
expression.addFunction("equal", lv -> {
|
expression.addFunction("equal", lv -> {
|
||||||
final int size = lv.size();
|
int size = lv.size();
|
||||||
if (size < 2)
|
if (size < 2)
|
||||||
{
|
{
|
||||||
return Value.TRUE;
|
return Value.TRUE;
|
||||||
}
|
}
|
||||||
Value prev = lv.get(0);
|
Value prev = lv.get(0);
|
||||||
for (final Value next : lv.subList(1, size))
|
for (Value next : lv.subList(1, size))
|
||||||
{
|
{
|
||||||
if (!prev.equals(next))
|
if (!prev.equals(next))
|
||||||
{
|
{
|
||||||
@@ -360,7 +360,7 @@ public class Operators
|
|||||||
expression.addBinaryOperator("!=", precedence.get("equal==!="), false, (v1, v2) ->
|
expression.addBinaryOperator("!=", precedence.get("equal==!="), false, (v1, v2) ->
|
||||||
v1.equals(v2) ? Value.FALSE : Value.TRUE);
|
v1.equals(v2) ? Value.FALSE : Value.TRUE);
|
||||||
expression.addFunction("unique", lv -> {
|
expression.addFunction("unique", lv -> {
|
||||||
final int size = lv.size();
|
int size = lv.size();
|
||||||
if (size < 2)
|
if (size < 2)
|
||||||
{
|
{
|
||||||
return Value.TRUE;
|
return Value.TRUE;
|
||||||
@@ -368,7 +368,7 @@ public class Operators
|
|||||||
// need to order them so same obejects will be next to each other.
|
// need to order them so same obejects will be next to each other.
|
||||||
lv.sort(Comparator.comparingInt(Value::hashCode));
|
lv.sort(Comparator.comparingInt(Value::hashCode));
|
||||||
Value prev = lv.get(0);
|
Value prev = lv.get(0);
|
||||||
for (final Value next : lv.subList(1, size))
|
for (Value next : lv.subList(1, size))
|
||||||
{
|
{
|
||||||
if (prev.equals(next))
|
if (prev.equals(next))
|
||||||
{
|
{
|
||||||
@@ -383,12 +383,12 @@ public class Operators
|
|||||||
// lazy cause of assignment which is non-trivial
|
// lazy cause of assignment which is non-trivial
|
||||||
expression.addLazyBinaryOperator("=", precedence.get("assign=<>"), false, false, t -> Context.Type.LVALUE, (c, t, lv1, lv2) ->
|
expression.addLazyBinaryOperator("=", precedence.get("assign=<>"), false, false, t -> Context.Type.LVALUE, (c, t, lv1, lv2) ->
|
||||||
{
|
{
|
||||||
final Value v1 = lv1.evalValue(c, Context.LVALUE);
|
Value v1 = lv1.evalValue(c, Context.LVALUE);
|
||||||
final Value v2 = lv2.evalValue(c);
|
Value v2 = lv2.evalValue(c);
|
||||||
if (v1 instanceof final ListValue.ListConstructorValue lcv && v2 instanceof final ListValue list)
|
if (v1 instanceof final ListValue.ListConstructorValue lcv && v2 instanceof final ListValue list)
|
||||||
{
|
{
|
||||||
final List<Value> ll = lcv.getItems();
|
List<Value> ll = lcv.getItems();
|
||||||
final List<Value> rl = list.getItems();
|
List<Value> rl = list.getItems();
|
||||||
if (ll.size() < rl.size())
|
if (ll.size() < rl.size())
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("Too many values to unpack");
|
throw new InternalExpressionException("Too many values to unpack");
|
||||||
@@ -397,28 +397,28 @@ public class Operators
|
|||||||
{
|
{
|
||||||
throw new InternalExpressionException("Too few values to unpack");
|
throw new InternalExpressionException("Too few values to unpack");
|
||||||
}
|
}
|
||||||
for (final Value v : ll)
|
for (Value v : ll)
|
||||||
{
|
{
|
||||||
v.assertAssignable();
|
v.assertAssignable();
|
||||||
}
|
}
|
||||||
final Iterator<Value> li = ll.iterator();
|
Iterator<Value> li = ll.iterator();
|
||||||
final Iterator<Value> ri = rl.iterator();
|
Iterator<Value> ri = rl.iterator();
|
||||||
while (li.hasNext())
|
while (li.hasNext())
|
||||||
{
|
{
|
||||||
final String lname = li.next().getVariable();
|
String lname = li.next().getVariable();
|
||||||
final Value vval = ri.next().reboundedTo(lname);
|
Value vval = ri.next().reboundedTo(lname);
|
||||||
expression.setAnyVariable(c, lname, (cc, tt) -> vval);
|
expression.setAnyVariable(c, lname, (cc, tt) -> vval);
|
||||||
}
|
}
|
||||||
return (cc, tt) -> Value.TRUE;
|
return (cc, tt) -> Value.TRUE;
|
||||||
}
|
}
|
||||||
if (v1 instanceof final LContainerValue lcv)
|
if (v1 instanceof final LContainerValue lcv)
|
||||||
{
|
{
|
||||||
final ContainerValueInterface container = lcv.container();
|
ContainerValueInterface container = lcv.container();
|
||||||
if (container == null)
|
if (container == null)
|
||||||
{
|
{
|
||||||
return (cc, tt) -> Value.NULL;
|
return (cc, tt) -> Value.NULL;
|
||||||
}
|
}
|
||||||
final Value address = lcv.address();
|
Value address = lcv.address();
|
||||||
if (!(container.put(address, v2)))
|
if (!(container.put(address, v2)))
|
||||||
{
|
{
|
||||||
return (cc, tt) -> Value.NULL;
|
return (cc, tt) -> Value.NULL;
|
||||||
@@ -426,9 +426,9 @@ public class Operators
|
|||||||
return (cc, tt) -> v2;
|
return (cc, tt) -> v2;
|
||||||
}
|
}
|
||||||
v1.assertAssignable();
|
v1.assertAssignable();
|
||||||
final String varname = v1.getVariable();
|
String varname = v1.getVariable();
|
||||||
final Value copy = v2.reboundedTo(varname);
|
Value copy = v2.reboundedTo(varname);
|
||||||
final LazyValue boundedLHS = (cc, tt) -> copy;
|
LazyValue boundedLHS = (cc, tt) -> copy;
|
||||||
expression.setAnyVariable(c, varname, boundedLHS);
|
expression.setAnyVariable(c, varname, boundedLHS);
|
||||||
return boundedLHS;
|
return boundedLHS;
|
||||||
});
|
});
|
||||||
@@ -436,12 +436,12 @@ public class Operators
|
|||||||
// lazy due to assignment
|
// lazy due to assignment
|
||||||
expression.addLazyBinaryOperator("+=", precedence.get("assign=<>"), false, false, t -> Context.Type.LVALUE, (c, t, lv1, lv2) ->
|
expression.addLazyBinaryOperator("+=", precedence.get("assign=<>"), false, false, t -> Context.Type.LVALUE, (c, t, lv1, lv2) ->
|
||||||
{
|
{
|
||||||
final Value v1 = lv1.evalValue(c, Context.LVALUE);
|
Value v1 = lv1.evalValue(c, Context.LVALUE);
|
||||||
final Value v2 = lv2.evalValue(c);
|
Value v2 = lv2.evalValue(c);
|
||||||
if (v1 instanceof final ListValue.ListConstructorValue lcv && v2 instanceof final ListValue list)
|
if (v1 instanceof final ListValue.ListConstructorValue lcv && v2 instanceof final ListValue list)
|
||||||
{
|
{
|
||||||
final List<Value> ll = lcv.getItems();
|
List<Value> ll = lcv.getItems();
|
||||||
final List<Value> rl = list.getItems();
|
List<Value> rl = list.getItems();
|
||||||
if (ll.size() < rl.size())
|
if (ll.size() < rl.size())
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("Too many values to unpack");
|
throw new InternalExpressionException("Too many values to unpack");
|
||||||
@@ -450,30 +450,30 @@ public class Operators
|
|||||||
{
|
{
|
||||||
throw new InternalExpressionException("Too few values to unpack");
|
throw new InternalExpressionException("Too few values to unpack");
|
||||||
}
|
}
|
||||||
for (final Value v : ll)
|
for (Value v : ll)
|
||||||
{
|
{
|
||||||
v.assertAssignable();
|
v.assertAssignable();
|
||||||
}
|
}
|
||||||
final Iterator<Value> li = ll.iterator();
|
Iterator<Value> li = ll.iterator();
|
||||||
final Iterator<Value> ri = rl.iterator();
|
Iterator<Value> ri = rl.iterator();
|
||||||
while (li.hasNext())
|
while (li.hasNext())
|
||||||
{
|
{
|
||||||
final Value lval = li.next();
|
Value lval = li.next();
|
||||||
final String lname = lval.getVariable();
|
String lname = lval.getVariable();
|
||||||
final Value result = lval.add(ri.next()).bindTo(lname);
|
Value result = lval.add(ri.next()).bindTo(lname);
|
||||||
expression.setAnyVariable(c, lname, (cc, tt) -> result);
|
expression.setAnyVariable(c, lname, (cc, tt) -> result);
|
||||||
}
|
}
|
||||||
return (cc, tt) -> Value.TRUE;
|
return (cc, tt) -> Value.TRUE;
|
||||||
}
|
}
|
||||||
if (v1 instanceof final LContainerValue lcv)
|
if (v1 instanceof final LContainerValue lcv)
|
||||||
{
|
{
|
||||||
final ContainerValueInterface cvi = lcv.container();
|
ContainerValueInterface cvi = lcv.container();
|
||||||
if (cvi == null)
|
if (cvi == null)
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("Failed to resolve left hand side of the += operation");
|
throw new InternalExpressionException("Failed to resolve left hand side of the += operation");
|
||||||
}
|
}
|
||||||
final Value key = lcv.address();
|
Value key = lcv.address();
|
||||||
final Value value = cvi.get(key);
|
Value value = cvi.get(key);
|
||||||
if (value instanceof ListValue || value instanceof MapValue)
|
if (value instanceof ListValue || value instanceof MapValue)
|
||||||
{
|
{
|
||||||
((AbstractListValue) value).append(v2);
|
((AbstractListValue) value).append(v2);
|
||||||
@@ -481,14 +481,14 @@ public class Operators
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
final Value res = value.add(v2);
|
Value res = value.add(v2);
|
||||||
cvi.put(key, res);
|
cvi.put(key, res);
|
||||||
return (cc, tt) -> res;
|
return (cc, tt) -> res;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
v1.assertAssignable();
|
v1.assertAssignable();
|
||||||
final String varname = v1.getVariable();
|
String varname = v1.getVariable();
|
||||||
final LazyValue boundedLHS;
|
LazyValue boundedLHS;
|
||||||
if (v1 instanceof ListValue || v1 instanceof MapValue)
|
if (v1 instanceof ListValue || v1 instanceof MapValue)
|
||||||
{
|
{
|
||||||
((AbstractListValue) v1).append(v2);
|
((AbstractListValue) v1).append(v2);
|
||||||
@@ -496,7 +496,7 @@ public class Operators
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
final Value result = v1.add(v2).bindTo(varname);
|
Value result = v1.add(v2).bindTo(varname);
|
||||||
boundedLHS = (cc, tt) -> result;
|
boundedLHS = (cc, tt) -> result;
|
||||||
}
|
}
|
||||||
expression.setAnyVariable(c, varname, boundedLHS);
|
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)
|
if (v1 instanceof final ListValue.ListConstructorValue lcv1 && v2 instanceof final ListValue.ListConstructorValue lcv2)
|
||||||
{
|
{
|
||||||
final List<Value> ll = lcv1.getItems();
|
List<Value> ll = lcv1.getItems();
|
||||||
final List<Value> rl = lcv2.getItems();
|
List<Value> rl = lcv2.getItems();
|
||||||
if (ll.size() < rl.size())
|
if (ll.size() < rl.size())
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("Too many values to unpack");
|
throw new InternalExpressionException("Too many values to unpack");
|
||||||
@@ -517,22 +517,22 @@ public class Operators
|
|||||||
{
|
{
|
||||||
throw new InternalExpressionException("Too few values to unpack");
|
throw new InternalExpressionException("Too few values to unpack");
|
||||||
}
|
}
|
||||||
for (final Value v : ll)
|
for (Value v : ll)
|
||||||
{
|
{
|
||||||
v.assertAssignable();
|
v.assertAssignable();
|
||||||
}
|
}
|
||||||
for (final Value v : rl)
|
for (Value v : rl)
|
||||||
{
|
{
|
||||||
v.assertAssignable();
|
v.assertAssignable();
|
||||||
}
|
}
|
||||||
final Iterator<Value> li = ll.iterator();
|
Iterator<Value> li = ll.iterator();
|
||||||
final Iterator<Value> ri = rl.iterator();
|
Iterator<Value> ri = rl.iterator();
|
||||||
while (li.hasNext())
|
while (li.hasNext())
|
||||||
{
|
{
|
||||||
final Value lval = li.next();
|
Value lval = li.next();
|
||||||
final Value rval = ri.next();
|
Value rval = ri.next();
|
||||||
final String lname = lval.getVariable();
|
String lname = lval.getVariable();
|
||||||
final String rname = rval.getVariable();
|
String rname = rval.getVariable();
|
||||||
lval.reboundedTo(rname);
|
lval.reboundedTo(rname);
|
||||||
rval.reboundedTo(lname);
|
rval.reboundedTo(lname);
|
||||||
expression.setAnyVariable(c, lname, (cc, tt) -> rval);
|
expression.setAnyVariable(c, lname, (cc, tt) -> rval);
|
||||||
@@ -542,10 +542,10 @@ public class Operators
|
|||||||
}
|
}
|
||||||
v1.assertAssignable();
|
v1.assertAssignable();
|
||||||
v2.assertAssignable();
|
v2.assertAssignable();
|
||||||
final String lvalvar = v1.getVariable();
|
String lvalvar = v1.getVariable();
|
||||||
final String rvalvar = v2.getVariable();
|
String rvalvar = v2.getVariable();
|
||||||
final Value lval = v2.reboundedTo(lvalvar);
|
Value lval = v2.reboundedTo(lvalvar);
|
||||||
final Value rval = v1.reboundedTo(rvalvar);
|
Value rval = v1.reboundedTo(rvalvar);
|
||||||
expression.setAnyVariable(c, lvalvar, (cc, tt) -> lval);
|
expression.setAnyVariable(c, lvalvar, (cc, tt) -> lval);
|
||||||
expression.setAnyVariable(c, rvalvar, (cc, tt) -> rval);
|
expression.setAnyVariable(c, rvalvar, (cc, tt) -> rval);
|
||||||
return lval;
|
return lval;
|
||||||
@@ -571,7 +571,7 @@ public class Operators
|
|||||||
{
|
{
|
||||||
throw new InternalExpressionException("Unable to unpack a non-list");
|
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;
|
return (cc, tt) -> fuaval;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ import carpet.script.value.MapValue;
|
|||||||
import carpet.script.value.NumericValue;
|
import carpet.script.value.NumericValue;
|
||||||
import carpet.script.value.StringValue;
|
import carpet.script.value.StringValue;
|
||||||
import carpet.script.value.Value;
|
import carpet.script.value.Value;
|
||||||
import org.apache.commons.lang3.text.WordUtils;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
@@ -32,7 +31,7 @@ public class Sys
|
|||||||
// %[argument_index$][flags][width][.precision][t]conversion
|
// %[argument_index$][flags][width][.precision][t]conversion
|
||||||
private static final Pattern formatPattern = Pattern.compile("%(\\d+\\$)?([-#+ 0,(<]*)?(\\d+)?(\\.\\d+)?([tT])?([a-zA-Z%])");
|
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()));
|
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) ->
|
expression.addTypedContextFunction("bool", 1, Context.BOOLEAN, (c, t, lv) ->
|
||||||
{
|
{
|
||||||
final Value v = lv.get(0);
|
Value v = lv.get(0);
|
||||||
if (v instanceof StringValue)
|
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))
|
if ("false".equals(str) || "null".equals(str))
|
||||||
{
|
{
|
||||||
return Value.FALSE;
|
return Value.FALSE;
|
||||||
@@ -66,7 +65,7 @@ public class Sys
|
|||||||
{
|
{
|
||||||
return new NumericValue(v.getString());
|
return new NumericValue(v.getString());
|
||||||
}
|
}
|
||||||
catch (final NumberFormatException format)
|
catch (NumberFormatException format)
|
||||||
{
|
{
|
||||||
return Value.NULL;
|
return Value.NULL;
|
||||||
}
|
}
|
||||||
@@ -74,11 +73,11 @@ public class Sys
|
|||||||
|
|
||||||
expression.addFunction("str", lv ->
|
expression.addFunction("str", lv ->
|
||||||
{
|
{
|
||||||
if (lv.size() == 0)
|
if (lv.isEmpty())
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("'str' requires at least one argument");
|
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)
|
if (lv.size() == 1)
|
||||||
{
|
{
|
||||||
return new StringValue(format);
|
return new StringValue(format);
|
||||||
@@ -89,8 +88,8 @@ public class Sys
|
|||||||
lv = list.getItems();
|
lv = list.getItems();
|
||||||
argIndex = 0;
|
argIndex = 0;
|
||||||
}
|
}
|
||||||
final List<Object> args = new ArrayList<>();
|
List<Object> args = new ArrayList<>();
|
||||||
final Matcher m = formatPattern.matcher(format);
|
Matcher m = formatPattern.matcher(format);
|
||||||
|
|
||||||
for (int i = 0, len = format.length(); i < len; )
|
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
|
// of the format specifier is either fixed text or contains
|
||||||
// an invalid format string.
|
// an invalid format string.
|
||||||
// [[scarpet]] but we skip it and let the String.format fail
|
// [[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 (fmt == 's')
|
||||||
{
|
{
|
||||||
if (argIndex >= lv.size())
|
if (argIndex >= lv.size())
|
||||||
@@ -137,11 +136,7 @@ public class Sys
|
|||||||
args.add(lv.get(argIndex).getBoolean());
|
args.add(lv.get(argIndex).getBoolean());
|
||||||
argIndex++;
|
argIndex++;
|
||||||
}
|
}
|
||||||
else if (fmt == '%')
|
else if (fmt != '%')
|
||||||
{
|
|
||||||
//skip /%%
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("Format not supported: " + m.group(6));
|
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()));
|
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());
|
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("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)
|
if (lv.size() != 3 && lv.size() != 2)
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("'replace' expects string to read, pattern regex, and optional replacement string");
|
throw new InternalExpressionException("'replace' expects string to read, pattern regex, and optional replacement string");
|
||||||
}
|
}
|
||||||
final String data = lv.get(0).getString();
|
String data = lv.get(0).getString();
|
||||||
final String regex = lv.get(1).getString();
|
String regex = lv.get(1).getString();
|
||||||
String replacement = "";
|
String replacement = "";
|
||||||
if (lv.size() == 3)
|
if (lv.size() == 3)
|
||||||
{
|
{
|
||||||
@@ -189,20 +184,20 @@ public class Sys
|
|||||||
{
|
{
|
||||||
return new StringValue(data.replaceAll(regex, replacement));
|
return new StringValue(data.replaceAll(regex, replacement));
|
||||||
}
|
}
|
||||||
catch (final PatternSyntaxException pse)
|
catch (PatternSyntaxException pse)
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("Incorrect pattern for 'replace': " + pse.getMessage());
|
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)
|
if (lv.size() != 3 && lv.size() != 2)
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("'replace_first' expects string to read, pattern regex, and optional replacement string");
|
throw new InternalExpressionException("'replace_first' expects string to read, pattern regex, and optional replacement string");
|
||||||
}
|
}
|
||||||
final String data = lv.get(0).getString();
|
String data = lv.get(0).getString();
|
||||||
final String regex = lv.get(1).getString();
|
String regex = lv.get(1).getString();
|
||||||
String replacement = "";
|
String replacement = "";
|
||||||
if (lv.size() == 3)
|
if (lv.size() == 3)
|
||||||
{
|
{
|
||||||
@@ -215,7 +210,7 @@ public class Sys
|
|||||||
expression.addUnaryFunction("length", v -> new NumericValue(v.length()));
|
expression.addUnaryFunction("length", v -> new NumericValue(v.length()));
|
||||||
expression.addContextFunction("rand", -1, (c, t, lv) ->
|
expression.addContextFunction("rand", -1, (c, t, lv) ->
|
||||||
{
|
{
|
||||||
final int argsize = lv.size();
|
int argsize = lv.size();
|
||||||
Random randomizer = Sys.randomizer;
|
Random randomizer = Sys.randomizer;
|
||||||
if (argsize != 1 && argsize != 2)
|
if (argsize != 1 && argsize != 2)
|
||||||
{
|
{
|
||||||
@@ -225,24 +220,24 @@ public class Sys
|
|||||||
{
|
{
|
||||||
randomizer = c.host.getRandom(NumericValue.asNumber(lv.get(1)).getLong());
|
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)
|
if (argument instanceof final ListValue listValue)
|
||||||
{
|
{
|
||||||
final List<Value> list = listValue.getItems();
|
List<Value> list = listValue.getItems();
|
||||||
return list.get(randomizer.nextInt(list.size()));
|
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);
|
return t == Context.BOOLEAN ? BooleanValue.of(value >= 1.0D) : new NumericValue(value);
|
||||||
});
|
});
|
||||||
expression.addContextFunction("reset_seed", 1, (c, t, lv) -> {
|
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);
|
return BooleanValue.of(gotIt);
|
||||||
});
|
});
|
||||||
|
|
||||||
expression.addFunction("perlin", lv ->
|
expression.addFunction("perlin", lv ->
|
||||||
{
|
{
|
||||||
final PerlinNoiseSampler sampler;
|
PerlinNoiseSampler sampler;
|
||||||
final Value x;
|
Value x;
|
||||||
Value y;
|
Value y;
|
||||||
Value z;
|
Value z;
|
||||||
|
|
||||||
@@ -258,7 +253,7 @@ public class Sys
|
|||||||
sampler = PerlinNoiseSampler.instance;
|
sampler = PerlinNoiseSampler.instance;
|
||||||
y = Value.NULL;
|
y = Value.NULL;
|
||||||
z = Value.NULL;
|
z = Value.NULL;
|
||||||
if (lv.size() == 0)
|
if (lv.isEmpty())
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("'perlin' requires at least one dimension to sample from");
|
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())
|
if (z.isNull())
|
||||||
{
|
{
|
||||||
@@ -293,9 +288,9 @@ public class Sys
|
|||||||
|
|
||||||
expression.addFunction("simplex", lv ->
|
expression.addFunction("simplex", lv ->
|
||||||
{
|
{
|
||||||
final SimplexNoiseSampler sampler;
|
SimplexNoiseSampler sampler;
|
||||||
final Value x;
|
Value x;
|
||||||
final Value y;
|
Value y;
|
||||||
Value z;
|
Value z;
|
||||||
|
|
||||||
if (lv.size() >= 4)
|
if (lv.size() >= 4)
|
||||||
@@ -320,7 +315,7 @@ public class Sys
|
|||||||
z = NumericValue.asNumber(lv.get(2));
|
z = NumericValue.asNumber(lv.get(2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
final double result;
|
double result;
|
||||||
|
|
||||||
if (z.isNull())
|
if (z.isNull())
|
||||||
{
|
{
|
||||||
@@ -336,7 +331,7 @@ public class Sys
|
|||||||
return new NumericValue(result);
|
return new NumericValue(result);
|
||||||
});
|
});
|
||||||
|
|
||||||
expression.addUnaryFunction("print", (v) ->
|
expression.addUnaryFunction("print", v ->
|
||||||
{
|
{
|
||||||
System.out.println(v.getString());
|
System.out.println(v.getString());
|
||||||
return v; // pass through for variables
|
return v; // pass through for variables
|
||||||
@@ -351,14 +346,14 @@ public class Sys
|
|||||||
expression.addFunction("convert_date", lv ->
|
expression.addFunction("convert_date", lv ->
|
||||||
{
|
{
|
||||||
int argsize = lv.size();
|
int argsize = lv.size();
|
||||||
if (lv.size() == 0)
|
if (lv.isEmpty())
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("'convert_date' requires at least one parameter");
|
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))
|
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());
|
cal.setTimeInMillis(NumericValue.asNumber(value, "timestamp").getLong());
|
||||||
int weekday = cal.get(Calendar.DAY_OF_WEEK) - 1;
|
int weekday = cal.get(Calendar.DAY_OF_WEEK) - 1;
|
||||||
if (weekday == 0)
|
if (weekday == 0)
|
||||||
@@ -382,7 +377,7 @@ public class Sys
|
|||||||
lv = list.getItems();
|
lv = list.getItems();
|
||||||
argsize = lv.size();
|
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)
|
if (argsize == 3)
|
||||||
{
|
{
|
||||||
@@ -413,15 +408,15 @@ public class Sys
|
|||||||
// lazy cause evaluates expression multiple times
|
// lazy cause evaluates expression multiple times
|
||||||
expression.addLazyFunction("profile_expr", 1, (c, t, lv) ->
|
expression.addLazyFunction("profile_expr", 1, (c, t, lv) ->
|
||||||
{
|
{
|
||||||
final LazyValue lazy = lv.get(0);
|
LazyValue lazy = lv.get(0);
|
||||||
final long end = System.nanoTime() + 50000000L;
|
long end = System.nanoTime() + 50000000L;
|
||||||
long it = 0;
|
long it = 0;
|
||||||
while (System.nanoTime() < end)
|
while (System.nanoTime() < end)
|
||||||
{
|
{
|
||||||
lazy.evalValue(c);
|
lazy.evalValue(c);
|
||||||
it++;
|
it++;
|
||||||
}
|
}
|
||||||
final Value res = new NumericValue(it);
|
Value res = new NumericValue(it);
|
||||||
return (cc, tt) -> res;
|
return (cc, tt) -> res;
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -430,14 +425,14 @@ public class Sys
|
|||||||
|
|
||||||
expression.addContextFunction("undef", 1, (c, t, lv) ->
|
expression.addContextFunction("undef", 1, (c, t, lv) ->
|
||||||
{
|
{
|
||||||
final Value remove = lv.get(0);
|
Value remove = lv.get(0);
|
||||||
if (remove instanceof FunctionValue)
|
if (remove instanceof FunctionValue)
|
||||||
{
|
{
|
||||||
c.host.delFunction(expression.module, remove.getString());
|
c.host.delFunction(expression.module, remove.getString());
|
||||||
return Value.NULL;
|
return Value.NULL;
|
||||||
}
|
}
|
||||||
String varname = remove.getString();
|
String varname = remove.getString();
|
||||||
final boolean isPrefix = varname.endsWith("*");
|
boolean isPrefix = varname.endsWith("*");
|
||||||
if (isPrefix)
|
if (isPrefix)
|
||||||
{
|
{
|
||||||
varname = varname.replaceAll("\\*+$", "");
|
varname = varname.replaceAll("\\*+$", "");
|
||||||
@@ -472,11 +467,11 @@ public class Sys
|
|||||||
//deprecate
|
//deprecate
|
||||||
expression.addContextFunction("vars", 1, (c, t, lv) ->
|
expression.addContextFunction("vars", 1, (c, t, lv) ->
|
||||||
{
|
{
|
||||||
final String prefix = lv.get(0).getString();
|
String prefix = lv.get(0).getString();
|
||||||
final List<Value> values = new ArrayList<>();
|
List<Value> values = new ArrayList<>();
|
||||||
if (prefix.startsWith("global"))
|
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
|
else
|
||||||
{
|
{
|
||||||
@@ -488,23 +483,43 @@ public class Sys
|
|||||||
// lazy cause default expression may not be executed if not needed
|
// lazy cause default expression may not be executed if not needed
|
||||||
expression.addLazyFunction("system_variable_get", (c, t, lv) ->
|
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");
|
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)
|
if (lv.size() > 1)
|
||||||
{
|
{
|
||||||
c.host.scriptServer().systemGlobals.computeIfAbsent(key, k -> lv.get(1).evalValue(c));
|
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);
|
return res == null ? LazyValue.NULL : ((cc, tt) -> res);
|
||||||
});
|
});
|
||||||
|
|
||||||
expression.addContextFunction("system_variable_set", 2, (c, t, lv) ->
|
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;
|
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 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) ->
|
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");
|
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);
|
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());
|
ThreadValue thread = new ThreadValue(Value.NULL, functionArgument.function, expr, tok, c, functionArgument.checkedArgs());
|
||||||
Thread.yield();
|
Thread.yield();
|
||||||
return thread;
|
return thread;
|
||||||
});
|
});
|
||||||
@@ -31,18 +31,18 @@ public class Threading
|
|||||||
{
|
{
|
||||||
throw new InternalExpressionException("'task' requires at least function to call as a parameter");
|
throw new InternalExpressionException("'task' requires at least function to call as a parameter");
|
||||||
}
|
}
|
||||||
final Value queue = lv.get(0);
|
Value queue = lv.get(0);
|
||||||
final FunctionArgument functionArgument = FunctionArgument.findIn(c, expression.module, lv, 1, false, true);
|
FunctionArgument functionArgument = FunctionArgument.findIn(c, expression.module, lv, 1, false, true);
|
||||||
final ThreadValue thread = new ThreadValue(queue, functionArgument.function, expr, tok, c, functionArgument.checkedArgs());
|
ThreadValue thread = new ThreadValue(queue, functionArgument.function, expr, tok, c, functionArgument.checkedArgs());
|
||||||
Thread.yield();
|
Thread.yield();
|
||||||
return thread;
|
return thread;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
expression.addContextFunction("task_count", -1, (c, t, lv) ->
|
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))
|
if (!(v instanceof final ThreadValue tv))
|
||||||
{
|
{
|
||||||
@@ -51,7 +51,7 @@ public class Threading
|
|||||||
return tv.getValue();
|
return tv.getValue();
|
||||||
});
|
});
|
||||||
|
|
||||||
expression.addUnaryFunction("task_join", (v) ->
|
expression.addUnaryFunction("task_join", v ->
|
||||||
{
|
{
|
||||||
if (!(v instanceof final ThreadValue tv))
|
if (!(v instanceof final ThreadValue tv))
|
||||||
{
|
{
|
||||||
@@ -61,13 +61,12 @@ public class Threading
|
|||||||
});
|
});
|
||||||
|
|
||||||
expression.addLazyFunction("task_dock", 1, (c, t, lv) ->
|
expression.addLazyFunction("task_dock", 1, (c, t, lv) ->
|
||||||
{
|
|
||||||
// pass through placeholder
|
// pass through placeholder
|
||||||
// implmenetation should dock the task on the main thread.
|
// 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))
|
if (!(v instanceof final ThreadValue tv))
|
||||||
{
|
{
|
||||||
@@ -79,7 +78,7 @@ public class Threading
|
|||||||
// lazy cause expr is evaluated in the same type
|
// lazy cause expr is evaluated in the same type
|
||||||
expression.addLazyFunction("synchronize", (c, t, lv) ->
|
expression.addLazyFunction("synchronize", (c, t, lv) ->
|
||||||
{
|
{
|
||||||
if (lv.size() == 0)
|
if (lv.isEmpty())
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("'synchronize' require at least an expression to synchronize");
|
throw new InternalExpressionException("'synchronize' require at least an expression to synchronize");
|
||||||
}
|
}
|
||||||
@@ -92,15 +91,15 @@ public class Threading
|
|||||||
}
|
}
|
||||||
synchronized (c.host.getLock(lockValue))
|
synchronized (c.host.getLock(lockValue))
|
||||||
{
|
{
|
||||||
final Value ret = lv.get(ind).evalValue(c, t);
|
Value ret = lv.get(ind).evalValue(c, t);
|
||||||
return (_c, _t) -> ret;
|
return (ct, tt) -> ret;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// lazy since exception expression is very conditional
|
// lazy since exception expression is very conditional
|
||||||
expression.addLazyFunction("sleep", (c, t, lv) ->
|
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;
|
boolean interrupted = false;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -114,7 +113,7 @@ public class Threading
|
|||||||
}
|
}
|
||||||
Thread.yield();
|
Thread.yield();
|
||||||
}
|
}
|
||||||
catch (final InterruptedException ignored)
|
catch (InterruptedException ignored)
|
||||||
{
|
{
|
||||||
interrupted = true;
|
interrupted = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ public class AppStoreManager
|
|||||||
*/
|
*/
|
||||||
private static String scarpetRepoLink = "https://api.github.com/repos/gnembon/scarpet/contents/programs/";
|
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, "");
|
APP_STORE_ROOT = AppStoreManager.StoreNode.folder(null, "");
|
||||||
scarpetRepoLink = link;
|
scarpetRepoLink = link;
|
||||||
@@ -66,23 +66,24 @@ public class AppStoreManager
|
|||||||
public static class StoreNode
|
public static class StoreNode
|
||||||
{
|
{
|
||||||
public String name;
|
public String name;
|
||||||
|
@Nullable
|
||||||
public StoreNode parent;
|
public StoreNode parent;
|
||||||
public Map<String, StoreNode> children;
|
public Map<String, StoreNode> children;
|
||||||
public boolean sealed;
|
public boolean sealed;
|
||||||
public String value;
|
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.children = new HashMap<>();
|
||||||
node.value = null;
|
node.value = null;
|
||||||
node.sealed = false;
|
node.sealed = false;
|
||||||
return node;
|
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.children = null;
|
||||||
node.value = value;
|
node.value = value;
|
||||||
node.sealed = true;
|
node.sealed = true;
|
||||||
@@ -109,7 +110,7 @@ public class AppStoreManager
|
|||||||
return this == APP_STORE_ROOT ? new StringBuilder() : parent.createPrePath().append(pathElement());
|
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.parent = parent;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
@@ -127,43 +128,40 @@ public class AppStoreManager
|
|||||||
throw new IOException("Accessing scarpet app repo is disabled");
|
throw new IOException("Accessing scarpet app repo is disabled");
|
||||||
}
|
}
|
||||||
|
|
||||||
final String queryPath = scarpetRepoLink + getPath();
|
String queryPath = scarpetRepoLink + getPath();
|
||||||
final String response;
|
String response;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
response = IOUtils.toString(new URL(queryPath), StandardCharsets.UTF_8);
|
response = IOUtils.toString(new URL(queryPath), StandardCharsets.UTF_8);
|
||||||
}
|
}
|
||||||
catch (final IOException e)
|
catch (IOException e)
|
||||||
{
|
{
|
||||||
// Not sealing to allow retrying
|
// Not sealing to allow retrying
|
||||||
throw new IOException("Problems fetching " + queryPath, e);
|
throw new IOException("Problems fetching " + queryPath, e);
|
||||||
}
|
}
|
||||||
final JsonArray files = JsonParser.parseString(response).getAsJsonArray();
|
JsonArray files = JsonParser.parseString(response).getAsJsonArray();
|
||||||
for (final JsonElement je : files)
|
for (JsonElement je : files)
|
||||||
{
|
{
|
||||||
final JsonObject jo = je.getAsJsonObject();
|
JsonObject jo = je.getAsJsonObject();
|
||||||
final String name = jo.get("name").getAsString();
|
String elementName = jo.get("name").getAsString();
|
||||||
if (jo.get("type").getAsString().equals("dir"))
|
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?)"))
|
else// if (name.matches("(\\w+\\.scl?)"))
|
||||||
{
|
{
|
||||||
final String value = jo.get("download_url").getAsString();
|
String url = jo.get("download_url").getAsString();
|
||||||
children.put(name, scriptFile(this, name, value));
|
children.put(elementName, scriptFile(this, elementName, url));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sealed = true;
|
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.
|
* 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())
|
if (isLeaf())
|
||||||
{
|
{
|
||||||
@@ -180,14 +178,13 @@ public class AppStoreManager
|
|||||||
return name.endsWith(".sc") ? Collections.singletonList(getPath()) : Collections.emptyList();
|
return name.endsWith(".sc") ? Collections.singletonList(getPath()) : Collections.emptyList();
|
||||||
}
|
}
|
||||||
fillChildren();
|
fillChildren();
|
||||||
final String prefix = getPath();
|
String prefix = getPath();
|
||||||
return children.values().stream().
|
return children.values().stream().
|
||||||
filter(n -> (!n.isLeaf() || n.name.endsWith(".sc"))).
|
filter(n -> (!n.isLeaf() || n.name.endsWith(".sc"))).
|
||||||
map(s -> prefix + s.pathElement().replaceAll("/$", "")).
|
map(s -> prefix + s.pathElement().replaceAll("/$", "")).toList();
|
||||||
collect(Collectors.toList());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public StoreNode drillDown(final String pathElement) throws IOException
|
public StoreNode drillDown(String pathElement) throws IOException
|
||||||
{
|
{
|
||||||
if (isLeaf())
|
if (isLeaf())
|
||||||
{
|
{
|
||||||
@@ -201,9 +198,9 @@ public class AppStoreManager
|
|||||||
return children.get(pathElement);
|
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())
|
if (!leaf.isLeaf())
|
||||||
{
|
{
|
||||||
throw new IOException(file + " is not a file");
|
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
|
* @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
|
* @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;
|
StoreNode appKiosk = APP_STORE_ROOT;
|
||||||
for (final String pathElement : path)
|
for (String pathElement : path)
|
||||||
{
|
{
|
||||||
if (appKiosk.cannotContinueFor(pathElement))
|
if (appKiosk.cannotContinueFor(pathElement))
|
||||||
{
|
{
|
||||||
@@ -232,13 +229,10 @@ public class AppStoreManager
|
|||||||
}
|
}
|
||||||
appKiosk = appKiosk.children.get(pathElement);
|
appKiosk = appKiosk.children.get(pathElement);
|
||||||
}
|
}
|
||||||
final List<String> filteredSuggestions = appKiosk.createPathSuggestions().stream().filter(s -> s.startsWith(currentPath)).collect(Collectors.toList());
|
List<String> filteredSuggestions = appKiosk.createPathSuggestions().stream().filter(s -> s.startsWith(currentPath)).toList();
|
||||||
if (filteredSuggestions.size() == 1)
|
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;
|
return filteredSuggestions;
|
||||||
}
|
}
|
||||||
@@ -251,20 +245,20 @@ public class AppStoreManager
|
|||||||
* @return {@code 1} if we succesfully saved the script, {@code 0} otherwise
|
* @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);
|
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
|
try
|
||||||
{
|
{
|
||||||
code = IOUtils.toString(new URL(nodeInfo.url()), StandardCharsets.UTF_8);
|
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()));
|
throw new CommandRuntimeException(Carpet.Messenger_compose("rb Failed to obtain app file content: " + e.getMessage()));
|
||||||
}
|
}
|
||||||
@@ -272,7 +266,7 @@ public class AppStoreManager
|
|||||||
{
|
{
|
||||||
return 0;
|
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;
|
return success ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -282,35 +276,35 @@ public class AppStoreManager
|
|||||||
* @param appPath The user inputted path to the scarpet script
|
* @param appPath The user inputted path to the scarpet script
|
||||||
* @return Pair of app file name and content
|
* @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);
|
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;
|
StoreNode appKiosk = start;
|
||||||
try
|
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);
|
appKiosk = appKiosk.drillDown(pathElement);
|
||||||
}
|
}
|
||||||
final String appName = path[path.length - 1];
|
String appName = path[path.length - 1];
|
||||||
appKiosk.getValue(appName);
|
appKiosk.getValue(appName);
|
||||||
return new AppInfo(appName, appKiosk.getValue(appName), appKiosk);
|
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()));
|
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
|
if (globalSavePath && !source.getServer().isDedicatedServer()) // never happens, this is always called with globalSavePath being false
|
||||||
{ //cos config folder only is in clients
|
{ //cos config folder only is in clients
|
||||||
scriptLocation = FabricLoader.getInstance().getConfigDir().resolve("carpet/scripts/appstore").toAbsolutePath().resolve(path);
|
scriptLocation = FabricLoader.getInstance().getConfigDir().resolve("carpet/scripts/appstore").toAbsolutePath().resolve(path);
|
||||||
@@ -331,8 +325,8 @@ public class AppStoreManager
|
|||||||
int i = 0;
|
int i = 0;
|
||||||
while (Files.exists(trashPath))
|
while (Files.exists(trashPath))
|
||||||
{
|
{
|
||||||
final String[] nameAndExtension = appFileName.split("\\.");
|
String[] nameAndExtension = appFileName.split("\\.");
|
||||||
final String newFileName = String.format(nameAndExtension[0] + "%02d." + nameAndExtension[1], i);
|
String newFileName = String.format(nameAndExtension[0] + "%02d." + nameAndExtension[1], i);
|
||||||
trashPath = trashPath.getParent().resolve(newFileName);
|
trashPath = trashPath.getParent().resolve(newFileName);
|
||||||
i++;
|
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));
|
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.write(code);
|
||||||
writer.close();
|
writer.close();
|
||||||
}
|
}
|
||||||
catch (final IOException e)
|
catch (IOException e)
|
||||||
{
|
{
|
||||||
Carpet.Messenger_message(source, "r Error while downloading app: " + e);
|
Carpet.Messenger_message(source, "r Error while downloading app: " + e);
|
||||||
CarpetScriptServer.LOG.warn("Error while downloading app", e);
|
CarpetScriptServer.LOG.warn("Error while downloading app", e);
|
||||||
@@ -353,15 +347,15 @@ public class AppStoreManager
|
|||||||
return true;
|
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);
|
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
|
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
|
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))
|
if (!(resource instanceof final MapValue map))
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("This is not a valid resource map: " + resource.getString());
|
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"))
|
if (!resourceMap.containsKey("source"))
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("Missing 'source' field in resource descriptor: " + resource.getString());
|
throw new InternalExpressionException("Missing 'source' field in resource descriptor: " + resource.getString());
|
||||||
}
|
}
|
||||||
final String source = resourceMap.get("source").getString();
|
String source = resourceMap.get("source").getString();
|
||||||
final String contentUrl = getFullContentUrl(source, storeSource);
|
String contentUrl = getFullContentUrl(source, storeSource);
|
||||||
final String target = resourceMap.computeIfAbsent("target", k -> new StringValue(contentUrl.substring(contentUrl.lastIndexOf('/') + 1))).getString();
|
String target = resourceMap.computeIfAbsent("target", k -> new StringValue(contentUrl.substring(contentUrl.lastIndexOf('/') + 1))).getString();
|
||||||
final boolean shared = resourceMap.getOrDefault("shared", Value.FALSE).getBoolean();
|
boolean shared = resourceMap.getOrDefault("shared", Value.FALSE).getBoolean();
|
||||||
|
|
||||||
if (!carpetScriptHost.applyActionForResource(target, shared, p -> {
|
if (!carpetScriptHost.applyActionForResource(target, shared, p -> {
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
writeUrlToFile(contentUrl, p);
|
writeUrlToFile(contentUrl, p);
|
||||||
}
|
}
|
||||||
catch (final IOException e)
|
catch (IOException e)
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("Unable to write resource " + target + ": " + 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)}
|
* @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
|
* @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;
|
StoreNode next = originalSource;
|
||||||
if (sourceString == contentUrl) // External URL (check getFullUrlContent)
|
if (sourceString == contentUrl) // External URL (check getFullUrlContent)
|
||||||
@@ -426,7 +421,7 @@ public class AppStoreManager
|
|||||||
next = APP_STORE_ROOT;
|
next = APP_STORE_ROOT;
|
||||||
sourceString = sourceString.substring(1);
|
sourceString = sourceString.substring(1);
|
||||||
}
|
}
|
||||||
final String[] dirs = sourceString.split("/");
|
String[] dirs = sourceString.split("/");
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
for (int i = 0; i < dirs.length - 1; i++)
|
for (int i = 0; i < dirs.length - 1; i++)
|
||||||
@@ -434,23 +429,23 @@ public class AppStoreManager
|
|||||||
next = next.drillDown(dirs[i]);
|
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 null; // Should never happen, but let's not give a potentially incorrect node just in case
|
||||||
}
|
}
|
||||||
return next;
|
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))
|
if (!(library instanceof final MapValue map))
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("This is not a valid library map: " + library.getString());
|
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()));
|
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");
|
String source = libraryMap.get("source");
|
||||||
final String contentUrl = getFullContentUrl(source, storeSource);
|
String contentUrl = getFullContentUrl(source, storeSource);
|
||||||
final String target = libraryMap.computeIfAbsent("target", k -> contentUrl.substring(contentUrl.lastIndexOf('/') + 1));
|
String target = libraryMap.computeIfAbsent("target", k -> contentUrl.substring(contentUrl.lastIndexOf('/') + 1));
|
||||||
if (!(contentUrl.endsWith(".sc") || contentUrl.endsWith(".scl")))
|
if (!(contentUrl.endsWith(".sc") || contentUrl.endsWith(".scl")))
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("App resource type must download a scarpet app or library.");
|
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);
|
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);
|
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("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("precipitation", (w, b) -> StringValue.of(b.getPrecipitationAt(new BlockPos(0, w.getSeaLevel(), 0)).name().toLowerCase(Locale.ROOT)));
|
||||||
put("features", (w, b) -> {
|
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(
|
return ListValue.wrap(
|
||||||
b.getGenerationSettings().features().stream().map(step ->
|
b.getGenerationSettings().features().stream().map(step ->
|
||||||
ListValue.wrap(step.stream().map(cfp ->
|
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'
|
* 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())
|
if (!e.isOnGround() && !e.isInWaterOrBubble() && !e.isInLava())
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final float m = e.level.getBlockState(e.blockPosition()).getBlock().getJumpFactor();
|
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();
|
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;
|
float jumpVelocityMultiplier = m == 1.0D ? g : m;
|
||||||
final float jumpStrength = (0.42F * jumpVelocityMultiplier);
|
float jumpStrength = (0.42F * jumpVelocityMultiplier);
|
||||||
final Vec3 vec3d = e.getDeltaMovement();
|
Vec3 vec3d = e.getDeltaMovement();
|
||||||
e.setDeltaMovement(vec3d.x, jumpStrength, vec3d.z);
|
e.setDeltaMovement(vec3d.x, jumpStrength, vec3d.z);
|
||||||
if (e.isSprinting())
|
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.setDeltaMovement(e.getDeltaMovement().add((-Mth.sin(g) * 0.2F), 0.0D, (Mth.cos(u) * 0.2F)));
|
||||||
}
|
}
|
||||||
e.hasImpulse = true;
|
e.hasImpulse = true;
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ public class EquipmentInventory implements Container
|
|||||||
|
|
||||||
LivingEntity mob;
|
LivingEntity mob;
|
||||||
|
|
||||||
public EquipmentInventory(final LivingEntity mob)
|
public EquipmentInventory(LivingEntity mob)
|
||||||
{
|
{
|
||||||
this.mob = mob;
|
this.mob = mob;
|
||||||
}
|
}
|
||||||
@@ -33,7 +33,7 @@ public class EquipmentInventory implements Container
|
|||||||
@Override
|
@Override
|
||||||
public boolean isEmpty()
|
public boolean isEmpty()
|
||||||
{
|
{
|
||||||
for (final EquipmentSlot slot : slotToSlot)
|
for (EquipmentSlot slot : slotToSlot)
|
||||||
{
|
{
|
||||||
if (!mob.getItemBySlot(slot).isEmpty())
|
if (!mob.getItemBySlot(slot).isEmpty())
|
||||||
{
|
{
|
||||||
@@ -44,14 +44,14 @@ public class EquipmentInventory implements Container
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ItemStack getItem(final int slot)
|
public ItemStack getItem(int slot)
|
||||||
{
|
{
|
||||||
final EquipmentSlot slotSlot;
|
EquipmentSlot slotSlot;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
slotSlot = slotToSlot.get(slot);
|
slotSlot = slotToSlot.get(slot);
|
||||||
}
|
}
|
||||||
catch (final IndexOutOfBoundsException ignored)
|
catch (IndexOutOfBoundsException ignored)
|
||||||
{
|
{
|
||||||
//going out of the index should be really exceptional
|
//going out of the index should be really exceptional
|
||||||
return ItemStack.EMPTY;
|
return ItemStack.EMPTY;
|
||||||
@@ -60,14 +60,14 @@ public class EquipmentInventory implements Container
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ItemStack removeItem(final int slot, final int amount)
|
public ItemStack removeItem(int slot, int amount)
|
||||||
{
|
{
|
||||||
final EquipmentSlot slotSlot;
|
EquipmentSlot slotSlot;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
slotSlot = slotToSlot.get(slot);
|
slotSlot = slotToSlot.get(slot);
|
||||||
}
|
}
|
||||||
catch (final IndexOutOfBoundsException ignored)
|
catch (IndexOutOfBoundsException ignored)
|
||||||
{
|
{
|
||||||
//going out of the index should be really exceptional
|
//going out of the index should be really exceptional
|
||||||
return ItemStack.EMPTY;
|
return ItemStack.EMPTY;
|
||||||
@@ -76,32 +76,32 @@ public class EquipmentInventory implements Container
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ItemStack removeItemNoUpdate(final int slot)
|
public ItemStack removeItemNoUpdate(int slot)
|
||||||
{
|
{
|
||||||
final EquipmentSlot slotSlot;
|
EquipmentSlot slotSlot;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
slotSlot = slotToSlot.get(slot);
|
slotSlot = slotToSlot.get(slot);
|
||||||
}
|
}
|
||||||
catch (final IndexOutOfBoundsException ignored)
|
catch (IndexOutOfBoundsException ignored)
|
||||||
{
|
{
|
||||||
//going out of the index should be really exceptional
|
//going out of the index should be really exceptional
|
||||||
return ItemStack.EMPTY;
|
return ItemStack.EMPTY;
|
||||||
}
|
}
|
||||||
final ItemStack previous = mob.getItemBySlot(slotSlot);
|
ItemStack previous = mob.getItemBySlot(slotSlot);
|
||||||
mob.setItemSlot(slotSlot, ItemStack.EMPTY);
|
mob.setItemSlot(slotSlot, ItemStack.EMPTY);
|
||||||
return previous;
|
return previous;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setItem(final int slot, final ItemStack stack)
|
public void setItem(int slot, ItemStack stack)
|
||||||
{
|
{
|
||||||
final EquipmentSlot slotSlot;
|
EquipmentSlot slotSlot;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
slotSlot = slotToSlot.get(slot);
|
slotSlot = slotToSlot.get(slot);
|
||||||
}
|
}
|
||||||
catch (final IndexOutOfBoundsException ignored)
|
catch (IndexOutOfBoundsException ignored)
|
||||||
{
|
{
|
||||||
//going out of the index should be really exceptional
|
//going out of the index should be really exceptional
|
||||||
return;
|
return;
|
||||||
@@ -116,7 +116,7 @@ public class EquipmentInventory implements Container
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean stillValid(final Player player)
|
public boolean stillValid(Player player)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -124,7 +124,7 @@ public class EquipmentInventory implements Container
|
|||||||
@Override
|
@Override
|
||||||
public void clearContent()
|
public void clearContent()
|
||||||
{
|
{
|
||||||
for (final EquipmentSlot slot : slotToSlot)
|
for (EquipmentSlot slot : slotToSlot)
|
||||||
{
|
{
|
||||||
mob.setItemSlot(slot, ItemStack.EMPTY);
|
mob.setItemSlot(slot, ItemStack.EMPTY);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,24 +68,24 @@ import javax.annotation.Nullable;
|
|||||||
public class FeatureGenerator
|
public class FeatureGenerator
|
||||||
{
|
{
|
||||||
@Nullable
|
@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)
|
if (custom != null)
|
||||||
{
|
{
|
||||||
return custom.apply(world).plop(world, pos);
|
return custom.apply(world).plop(world, pos);
|
||||||
}
|
}
|
||||||
final ResourceLocation id = new ResourceLocation(featureName);
|
ResourceLocation id = new ResourceLocation(featureName);
|
||||||
final Structure structure = world.registryAccess().registryOrThrow(Registries.STRUCTURE).get(id);
|
Structure structure = world.registryAccess().registryOrThrow(Registries.STRUCTURE).get(id);
|
||||||
if (structure != null)
|
if (structure != null)
|
||||||
{
|
{
|
||||||
return plopAnywhere(structure, world, pos, world.getChunkSource().getGenerator(), false);
|
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)
|
if (configuredFeature != null)
|
||||||
{
|
{
|
||||||
final ThreadLocal<Boolean> checks = Vanilla.skipGenerationChecks(world);
|
ThreadLocal<Boolean> checks = Vanilla.skipGenerationChecks(world);
|
||||||
checks.set(true);
|
checks.set(true);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -96,22 +96,22 @@ public class FeatureGenerator
|
|||||||
checks.set(false);
|
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())
|
if (structureType.isPresent())
|
||||||
{
|
{
|
||||||
final Structure configuredStandard = getDefaultFeature(structureType.get(), world, pos);
|
Structure configuredStandard = getDefaultFeature(structureType.get(), world, pos);
|
||||||
if (configuredStandard != null)
|
if (configuredStandard != null)
|
||||||
{
|
{
|
||||||
return plopAnywhere(configuredStandard, world, pos, world.getChunkSource().getGenerator(), false);
|
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)
|
if (feature != null)
|
||||||
{
|
{
|
||||||
final ConfiguredFeature<?, ?> configuredStandard = getDefaultFeature(feature, world, pos, true);
|
ConfiguredFeature<?, ?> configuredStandard = getDefaultFeature(feature, world, pos, true);
|
||||||
if (configuredStandard != null)
|
if (configuredStandard != null)
|
||||||
{
|
{
|
||||||
final ThreadLocal<Boolean> checks = Vanilla.skipGenerationChecks(world);
|
ThreadLocal<Boolean> checks = Vanilla.skipGenerationChecks(world);
|
||||||
checks.set(true);
|
checks.set(true);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -126,15 +126,16 @@ public class FeatureGenerator
|
|||||||
return null;
|
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);
|
ResourceLocation id = new ResourceLocation(name);
|
||||||
final Structure configuredStructureFeature = world.registryAccess().registryOrThrow(Registries.STRUCTURE).get(id);
|
Structure configuredStructureFeature = world.registryAccess().registryOrThrow(Registries.STRUCTURE).get(id);
|
||||||
if (configuredStructureFeature != null)
|
if (configuredStructureFeature != null)
|
||||||
{
|
{
|
||||||
return configuredStructureFeature;
|
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)
|
if (structureFeature == null)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
@@ -142,7 +143,7 @@ public class FeatureGenerator
|
|||||||
return getDefaultFeature(structureFeature, world, pos);
|
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);
|
return plopAnywhere(structureFeature, world, pos, world.getChunkSource().getGenerator(), true);
|
||||||
}
|
}
|
||||||
@@ -153,10 +154,10 @@ public class FeatureGenerator
|
|||||||
Boolean plop(ServerLevel world, BlockPos pos);
|
Boolean plop(ServerLevel world, BlockPos pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Thing simplePlop(final ConfiguredFeature<?, ?> feature)
|
private static Thing simplePlop(ConfiguredFeature<?, ?> feature)
|
||||||
{
|
{
|
||||||
return (w, p) -> {
|
return (w, p) -> {
|
||||||
final ThreadLocal<Boolean> checks = Vanilla.skipGenerationChecks(w);
|
ThreadLocal<Boolean> checks = Vanilla.skipGenerationChecks(w);
|
||||||
checks.set(true);
|
checks.set(true);
|
||||||
try
|
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));
|
return simplePlop(new ConfiguredFeature<>(feature, config));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Thing simpleTree(final TreeConfiguration config)
|
private static Thing simpleTree(TreeConfiguration config)
|
||||||
{
|
{
|
||||||
//config.ignoreFluidCheck();
|
//config.ignoreFluidCheck();
|
||||||
return simplePlop(new ConfiguredFeature<>(Feature.TREE, config));
|
return simplePlop(new ConfiguredFeature<>(Feature.TREE, config));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Thing spawnCustomStructure(final Structure structure)
|
private static Thing spawnCustomStructure(Structure structure)
|
||||||
{
|
{
|
||||||
return setupCustomStructure(structure, false);
|
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);
|
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
|
// would be nice to have a way to grab structures of this type for position
|
||||||
// TODO allow old types, like vaillage, or bastion
|
// TODO allow old types, like vaillage, or bastion
|
||||||
final Holder<Biome> existingBiome = world.getBiome(pos);
|
Holder<Biome> existingBiome = world.getBiome(pos);
|
||||||
Structure result = null;
|
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())
|
filter(cS -> cS.getValue().type() == structure).map(Map.Entry::getValue).toList())
|
||||||
{
|
{
|
||||||
result = confstr;
|
result = confstr;
|
||||||
@@ -208,12 +209,12 @@ public class FeatureGenerator
|
|||||||
return result;
|
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();
|
List<HolderSet<PlacedFeature>> configuredStepFeatures = world.getBiome(pos).value().getGenerationSettings().features();
|
||||||
for (final HolderSet<PlacedFeature> step : configuredStepFeatures)
|
for (HolderSet<PlacedFeature> step : configuredStepFeatures)
|
||||||
{
|
{
|
||||||
for (final Holder<PlacedFeature> provider : step)
|
for (Holder<PlacedFeature> provider : step)
|
||||||
{
|
{
|
||||||
if (provider.value().feature().value().feature() == feature)
|
if (provider.value().feature().value().feature() == feature)
|
||||||
{
|
{
|
||||||
@@ -230,21 +231,22 @@ public class FeatureGenerator
|
|||||||
findFirst().map(Map.Entry::getValue).orElse(null);
|
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();
|
ServerChunkCache chunkSource = world.getChunkSource();
|
||||||
final RandomState seed = chunkSource.randomState();
|
RandomState seed = chunkSource.randomState();
|
||||||
final ChunkGenerator generator = chunkSource.getGenerator();
|
ChunkGenerator generator = chunkSource.getGenerator();
|
||||||
final ChunkGeneratorStructureState structureState = chunkSource.getGeneratorState();
|
ChunkGeneratorStructureState structureState = chunkSource.getGeneratorState();
|
||||||
final List<StructurePlacement> structureConfig = structureState.getPlacementsForStructure(Holder.direct(structure));
|
List<StructurePlacement> structureConfig = structureState.getPlacementsForStructure(Holder.direct(structure));
|
||||||
final ChunkPos chunkPos = new ChunkPos(pos);
|
ChunkPos chunkPos = new ChunkPos(pos);
|
||||||
final boolean couldPlace = structureConfig.stream().anyMatch(p -> p.isStructureChunk(structureState, chunkPos.x, chunkPos.z));
|
boolean couldPlace = structureConfig.stream().anyMatch(p -> p.isStructureChunk(structureState, chunkPos.x, chunkPos.z));
|
||||||
if (!couldPlace)
|
if (!couldPlace)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
final HolderSet<Biome> structureBiomes = structure.biomes();
|
HolderSet<Biome> structureBiomes = structure.biomes();
|
||||||
|
|
||||||
if (!computeBox)
|
if (!computeBox)
|
||||||
{
|
{
|
||||||
@@ -259,7 +261,7 @@ public class FeatureGenerator
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
final StructureStart filledStructure = structure.generate(
|
StructureStart filledStructure = structure.generate(
|
||||||
world.registryAccess(), generator, generator.getBiomeSource(), seed, world.getStructureManager(),
|
world.registryAccess(), generator, generator.getBiomeSource(), seed, world.getStructureManager(),
|
||||||
world.getSeed(), chunkPos, 0, world, structureBiomes::contains);
|
world.getSeed(), chunkPos, 0, world, structureBiomes::contains);
|
||||||
if (filledStructure != null && filledStructure.isValid())
|
if (filledStructure != null && filledStructure.isValid())
|
||||||
@@ -270,7 +272,7 @@ public class FeatureGenerator
|
|||||||
return null;
|
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));
|
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)
|
PlacementUtils.inlinePlaced(Feature.CORAL_MUSHROOM, FeatureConfiguration.NONE)
|
||||||
))));
|
))));
|
||||||
put("bastion_remnant_units", l -> {
|
put("bastion_remnant_units", l -> {
|
||||||
final RegistryAccess regs = l.registryAccess();
|
RegistryAccess regs = l.registryAccess();
|
||||||
|
|
||||||
final HolderGetter<StructureProcessorList> processorLists = regs.lookupOrThrow(Registries.PROCESSOR_LIST);
|
HolderGetter<StructureProcessorList> processorLists = regs.lookupOrThrow(Registries.PROCESSOR_LIST);
|
||||||
final Holder<StructureProcessorList> bastionGenericDegradation = processorLists.getOrThrow(ProcessorLists.BASTION_GENERIC_DEGRADATION);
|
Holder<StructureProcessorList> bastionGenericDegradation = processorLists.getOrThrow(ProcessorLists.BASTION_GENERIC_DEGRADATION);
|
||||||
|
|
||||||
final HolderGetter<StructureTemplatePool> pools = regs.lookupOrThrow(Registries.TEMPLATE_POOL);
|
HolderGetter<StructureTemplatePool> pools = regs.lookupOrThrow(Registries.TEMPLATE_POOL);
|
||||||
final Holder<StructureTemplatePool> empty = pools.getOrThrow(Pools.EMPTY);
|
Holder<StructureTemplatePool> empty = pools.getOrThrow(Pools.EMPTY);
|
||||||
|
|
||||||
|
|
||||||
return spawnCustomStructure(
|
return spawnCustomStructure(
|
||||||
@@ -322,13 +324,13 @@ public class FeatureGenerator
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
put("bastion_remnant_hoglin_stable", l -> {
|
put("bastion_remnant_hoglin_stable", l -> {
|
||||||
final RegistryAccess regs = l.registryAccess();
|
RegistryAccess regs = l.registryAccess();
|
||||||
|
|
||||||
final HolderGetter<StructureProcessorList> processorLists = regs.lookupOrThrow(Registries.PROCESSOR_LIST);
|
HolderGetter<StructureProcessorList> processorLists = regs.lookupOrThrow(Registries.PROCESSOR_LIST);
|
||||||
final Holder<StructureProcessorList> bastionGenericDegradation = processorLists.getOrThrow(ProcessorLists.BASTION_GENERIC_DEGRADATION);
|
Holder<StructureProcessorList> bastionGenericDegradation = processorLists.getOrThrow(ProcessorLists.BASTION_GENERIC_DEGRADATION);
|
||||||
|
|
||||||
final HolderGetter<StructureTemplatePool> pools = regs.lookupOrThrow(Registries.TEMPLATE_POOL);
|
HolderGetter<StructureTemplatePool> pools = regs.lookupOrThrow(Registries.TEMPLATE_POOL);
|
||||||
final Holder<StructureTemplatePool> empty = pools.getOrThrow(Pools.EMPTY);
|
Holder<StructureTemplatePool> empty = pools.getOrThrow(Pools.EMPTY);
|
||||||
|
|
||||||
return spawnCustomStructure(
|
return spawnCustomStructure(
|
||||||
new JigsawStructure(new Structure.StructureSettings(
|
new JigsawStructure(new Structure.StructureSettings(
|
||||||
@@ -351,13 +353,13 @@ public class FeatureGenerator
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
put("bastion_remnant_treasure", l -> {
|
put("bastion_remnant_treasure", l -> {
|
||||||
final RegistryAccess regs = l.registryAccess();
|
RegistryAccess regs = l.registryAccess();
|
||||||
|
|
||||||
final HolderGetter<StructureProcessorList> processorLists = regs.lookupOrThrow(Registries.PROCESSOR_LIST);
|
HolderGetter<StructureProcessorList> processorLists = regs.lookupOrThrow(Registries.PROCESSOR_LIST);
|
||||||
final Holder<StructureProcessorList> bastionGenericDegradation = processorLists.getOrThrow(ProcessorLists.BASTION_GENERIC_DEGRADATION);
|
Holder<StructureProcessorList> bastionGenericDegradation = processorLists.getOrThrow(ProcessorLists.BASTION_GENERIC_DEGRADATION);
|
||||||
|
|
||||||
final HolderGetter<StructureTemplatePool> pools = regs.lookupOrThrow(Registries.TEMPLATE_POOL);
|
HolderGetter<StructureTemplatePool> pools = regs.lookupOrThrow(Registries.TEMPLATE_POOL);
|
||||||
final Holder<StructureTemplatePool> empty = pools.getOrThrow(Pools.EMPTY);
|
Holder<StructureTemplatePool> empty = pools.getOrThrow(Pools.EMPTY);
|
||||||
|
|
||||||
return spawnCustomStructure(
|
return spawnCustomStructure(
|
||||||
new JigsawStructure(new Structure.StructureSettings(
|
new JigsawStructure(new Structure.StructureSettings(
|
||||||
@@ -380,13 +382,13 @@ public class FeatureGenerator
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
put("bastion_remnant_bridge", l -> {
|
put("bastion_remnant_bridge", l -> {
|
||||||
final RegistryAccess regs = l.registryAccess();
|
RegistryAccess regs = l.registryAccess();
|
||||||
|
|
||||||
final HolderGetter<StructureProcessorList> processorLists = regs.lookupOrThrow(Registries.PROCESSOR_LIST);
|
HolderGetter<StructureProcessorList> processorLists = regs.lookupOrThrow(Registries.PROCESSOR_LIST);
|
||||||
final Holder<StructureProcessorList> bastionGenericDegradation = processorLists.getOrThrow(ProcessorLists.BASTION_GENERIC_DEGRADATION);
|
Holder<StructureProcessorList> bastionGenericDegradation = processorLists.getOrThrow(ProcessorLists.BASTION_GENERIC_DEGRADATION);
|
||||||
|
|
||||||
final HolderGetter<StructureTemplatePool> pools = regs.lookupOrThrow(Registries.TEMPLATE_POOL);
|
HolderGetter<StructureTemplatePool> pools = regs.lookupOrThrow(Registries.TEMPLATE_POOL);
|
||||||
final Holder<StructureTemplatePool> empty = pools.getOrThrow(Pools.EMPTY);
|
Holder<StructureTemplatePool> empty = pools.getOrThrow(Pools.EMPTY);
|
||||||
|
|
||||||
return spawnCustomStructure(
|
return spawnCustomStructure(
|
||||||
new JigsawStructure(new Structure.StructureSettings(
|
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);
|
checks.set(true);
|
||||||
try
|
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)
|
if (start == StructureStart.INVALID_START)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
final RandomSource rand = RandomSource.create(world.getRandom().nextInt());
|
RandomSource rand = RandomSource.create(world.getRandom().nextInt());
|
||||||
final int j = pos.getX() >> 4;
|
int j = pos.getX() >> 4;
|
||||||
final int k = pos.getZ() >> 4;
|
int k = pos.getZ() >> 4;
|
||||||
final long chId = ChunkPos.asLong(j, k);
|
long chId = ChunkPos.asLong(j, k);
|
||||||
world.getChunk(j, k).setStartForStructure(structure, start);
|
world.getChunk(j, k).setStartForStructure(structure, start);
|
||||||
world.getChunk(j, k).addReferenceForStructure(structure, chId);
|
world.getChunk(j, k).addReferenceForStructure(structure, chId);
|
||||||
|
|
||||||
final BoundingBox box = start.getBoundingBox();
|
BoundingBox box = start.getBoundingBox();
|
||||||
|
|
||||||
if (!wireOnly)
|
if (!wireOnly)
|
||||||
{
|
{
|
||||||
final Registry<Structure> registry3 = world.registryAccess().registryOrThrow(Registries.STRUCTURE);
|
Registry<Structure> registry3 = world.registryAccess().registryOrThrow(Registries.STRUCTURE);
|
||||||
world.setCurrentlyGenerating(() -> {
|
world.setCurrentlyGenerating(() -> {
|
||||||
Objects.requireNonNull(structure);
|
Objects.requireNonNull(structure);
|
||||||
return registry3.getResourceKey(structure).map(Object::toString).orElseGet(structure::toString);
|
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));
|
start.placeInChunk(world, world.structureManager(), generator, rand, box, new ChunkPos(j, k));
|
||||||
}
|
}
|
||||||
//structurestart.notifyPostProcessAt(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();
|
//int i = getRadius();
|
||||||
for (int k1 = j - i; k1 <= j + i; ++k1)
|
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);
|
CarpetScriptServer.LOG.error("Unknown Exception while plopping structure: " + booboo, booboo);
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
package carpet.script.utils;
|
package carpet.script.utils;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
public class GlocalFlag extends ThreadLocal<Boolean>
|
public class GlocalFlag extends ThreadLocal<Boolean>
|
||||||
{
|
{
|
||||||
private final boolean initial;
|
private final boolean initial;
|
||||||
|
|
||||||
public GlocalFlag(final boolean initial)
|
public GlocalFlag(boolean initial)
|
||||||
{
|
{
|
||||||
this.initial = 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
|
* @param <T> - returned value of that action, whatever that might be
|
||||||
* @return result of the action
|
* @return result of the action
|
||||||
*/
|
*/
|
||||||
public <T> T getWhileDisabled(final Supplier<T> action)
|
public <T> T getWhileDisabled(Supplier<T> action)
|
||||||
{
|
{
|
||||||
return whileValueReturn(!initial, 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;
|
T result;
|
||||||
final boolean previous;
|
boolean previous;
|
||||||
synchronized (this)
|
synchronized (this)
|
||||||
{
|
{
|
||||||
previous = get();
|
previous = get();
|
||||||
@@ -49,7 +50,8 @@ public class GlocalFlag extends ThreadLocal<Boolean>
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T> T runIfEnabled(final Supplier<T> action)
|
@Nullable
|
||||||
|
public <T> T runIfEnabled(Supplier<T> action)
|
||||||
{
|
{
|
||||||
synchronized (this)
|
synchronized (this)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -9,9 +9,9 @@ import net.minecraft.resources.ResourceLocation;
|
|||||||
|
|
||||||
public class InputValidator
|
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)))
|
if (simplified.isEmpty() || (strict && !simplified.equals(input)))
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("simple name can only contain numbers, letter and _");
|
throw new InternalExpressionException("simple name can only contain numbers, letter and _");
|
||||||
@@ -19,13 +19,13 @@ public class InputValidator
|
|||||||
return simplified;
|
return simplified;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ResourceLocation identifierOf(final String string)
|
public static ResourceLocation identifierOf(String string)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return new ResourceLocation(string);
|
return new ResourceLocation(string);
|
||||||
}
|
}
|
||||||
catch (final ResourceLocationException iie)
|
catch (ResourceLocationException iie)
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("Incorrect identifier format '" + string + "': " + iie.getMessage());
|
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.ParticleOptions;
|
||||||
import net.minecraft.core.particles.ParticleType;
|
import net.minecraft.core.particles.ParticleType;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
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 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
|
try
|
||||||
{
|
{
|
||||||
return ParticleArgument.readParticle(new StringReader(name), lookup);
|
return ParticleArgument.readParticle(new StringReader(name), lookup);
|
||||||
}
|
}
|
||||||
catch (final CommandSyntaxException e)
|
catch (CommandSyntaxException e)
|
||||||
{
|
{
|
||||||
throw new IllegalArgumentException("No such particle: " + name);
|
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)
|
if (name == null)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ public class PerlinNoiseSampler
|
|||||||
public static PerlinNoiseSampler instance = new PerlinNoiseSampler(new Random(0));
|
public static PerlinNoiseSampler instance = new PerlinNoiseSampler(new Random(0));
|
||||||
public static Map<Long, PerlinNoiseSampler> samplers = new Long2ObjectOpenHashMap<>();
|
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)
|
if (samplers.size() > 256)
|
||||||
{
|
{
|
||||||
@@ -33,7 +33,7 @@ public class PerlinNoiseSampler
|
|||||||
return samplers.computeIfAbsent(aLong, seed -> new PerlinNoiseSampler(new Random(seed)));
|
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.originX = random.nextDouble() * 256.0D;
|
||||||
this.originY = random.nextDouble() * 256.0D;
|
this.originY = random.nextDouble() * 256.0D;
|
||||||
@@ -47,27 +47,27 @@ public class PerlinNoiseSampler
|
|||||||
}
|
}
|
||||||
for (j = 0; j < 256; ++j)
|
for (j = 0; j < 256; ++j)
|
||||||
{
|
{
|
||||||
final int k = random.nextInt(256 - j);
|
int k = random.nextInt(256 - j);
|
||||||
final byte b = this.permutations[j];
|
byte b = this.permutations[j];
|
||||||
this.permutations[j] = this.permutations[j + k];
|
this.permutations[j] = this.permutations[j + k];
|
||||||
this.permutations[j + k] = b;
|
this.permutations[j + k] = b;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//3D
|
//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) {
|
{//, double d, double e) {
|
||||||
final double f = x + this.originX;
|
double f = x + this.originX;
|
||||||
final double g = y + this.originY;
|
double g = y + this.originY;
|
||||||
final double h = z + this.originZ;
|
double h = z + this.originZ;
|
||||||
final int i = floor(f);
|
int i = floor(f);
|
||||||
final int j = floor(g);
|
int j = floor(g);
|
||||||
final int k = floor(h);
|
int k = floor(h);
|
||||||
final double l = f - (double) i;
|
double l = f - (double) i;
|
||||||
final double m = g - (double) j;
|
double m = g - (double) j;
|
||||||
final double n = h - (double) k;
|
double n = h - (double) k;
|
||||||
final double o = perlinFade(l);
|
double o = perlinFade(l);
|
||||||
final double p = perlinFade(m);
|
double p = perlinFade(m);
|
||||||
final double q = perlinFade(n);
|
double q = perlinFade(n);
|
||||||
//double t;
|
//double t;
|
||||||
/*
|
/*
|
||||||
if (d != 0.0D) {
|
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;
|
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;
|
int i = this.getGradient(sectionX) + sectionY;
|
||||||
final int j = this.getGradient(i) + sectionZ;
|
int j = this.getGradient(i) + sectionZ;
|
||||||
final int k = this.getGradient(i + 1) + sectionZ;
|
int k = this.getGradient(i + 1) + sectionZ;
|
||||||
final int l = this.getGradient(sectionX + 1) + sectionY;
|
int l = this.getGradient(sectionX + 1) + sectionY;
|
||||||
final int m = this.getGradient(l) + sectionZ;
|
int m = this.getGradient(l) + sectionZ;
|
||||||
final int n = this.getGradient(l + 1) + sectionZ;
|
int n = this.getGradient(l + 1) + sectionZ;
|
||||||
final double d = grad3d(this.getGradient(j), localX, localY, localZ);
|
double d = grad3d(this.getGradient(j), localX, localY, localZ);
|
||||||
final double e = grad3d(this.getGradient(m), localX - 1.0D, localY, localZ);
|
double e = grad3d(this.getGradient(m), localX - 1.0D, localY, localZ);
|
||||||
final double f = grad3d(this.getGradient(k), localX, localY - 1.0D, localZ);
|
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);
|
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);
|
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);
|
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);
|
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);
|
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);
|
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);
|
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;
|
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));
|
return lerp(deltaZ, lerp2(deltaX, deltaY, d, e, f, g), lerp2(deltaX, deltaY, h, i, j, k));
|
||||||
}
|
}
|
||||||
|
|
||||||
//2D
|
//2D
|
||||||
public double sample2d(final double x, final double y)
|
public double sample2d(double x, double y)
|
||||||
{
|
{
|
||||||
final double f = x + this.originX;
|
double f = x + this.originX;
|
||||||
final double g = y + this.originY;
|
double g = y + this.originY;
|
||||||
final int i = floor(f);
|
int i = floor(f);
|
||||||
final int j = floor(g);
|
int j = floor(g);
|
||||||
final double l = f - (double) i;
|
double l = f - (double) i;
|
||||||
final double m = g - (double) j;
|
double m = g - (double) j;
|
||||||
final double o = perlinFade(l);
|
double o = perlinFade(l);
|
||||||
final double p = perlinFade(m);
|
double p = perlinFade(m);
|
||||||
return this.sample2d(i, j, l, m, o, p) / 2 + 0.5;
|
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;
|
int j = this.getGradient(sectionX) + sectionY;
|
||||||
final int m = this.getGradient(sectionX + 1) + sectionY;
|
int m = this.getGradient(sectionX + 1) + sectionY;
|
||||||
final double d = grad2d(this.getGradient(j), localX, localY);
|
double d = grad2d(this.getGradient(j), localX, localY);
|
||||||
final double e = grad2d(this.getGradient(m), localX - 1.0D, localY);
|
double e = grad2d(this.getGradient(m), localX - 1.0D, localY);
|
||||||
final double f = grad2d(this.getGradient(j + 1), localX, localY - 1.0D);
|
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);
|
double g = grad2d(this.getGradient(m + 1), localX - 1.0D, localY - 1.0D);
|
||||||
|
|
||||||
return lerp2(fadeLocalX, fadeLocalY, d, e, f, g);
|
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);
|
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;
|
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));
|
return lerp(deltaY, lerp(deltaX, d, e), lerp(deltaX, f, g));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 1D
|
// 1D
|
||||||
public double sample1d(final double x)
|
public double sample1d(double x)
|
||||||
{
|
{
|
||||||
final double f = x + this.originX;
|
double f = x + this.originX;
|
||||||
final int i = floor(f);
|
int i = floor(f);
|
||||||
final double l = f - i;
|
double l = f - i;
|
||||||
final double o = perlinFade(l);
|
double o = perlinFade(l);
|
||||||
return this.sample1d(i, l, o) + 0.5;
|
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);
|
double d = grad1d(this.getGradient(sectionX), localX);
|
||||||
final double e = grad1d(this.getGradient(sectionX + 1), localX - 1.0D);
|
double e = grad1d(this.getGradient(sectionX + 1), localX - 1.0D);
|
||||||
return lerp(fadeLocalX, d, e);
|
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;
|
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);
|
return first + delta * (second - first);
|
||||||
}
|
}
|
||||||
|
|
||||||
// shared
|
// shared
|
||||||
public int getGradient(final int hash)
|
public int getGradient(int hash)
|
||||||
{
|
{
|
||||||
return this.permutations[hash & 255] & 255;
|
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);
|
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;
|
return d < i ? i - 1 : i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -24,12 +24,12 @@ public class ScarpetJsonDeserializer implements JsonDeserializer<Value>
|
|||||||
{
|
{
|
||||||
|
|
||||||
@Override
|
@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);
|
return parseElement(json);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Value parseElement(final JsonElement element) throws JsonParseException
|
private Value parseElement(JsonElement element) throws JsonParseException
|
||||||
{
|
{
|
||||||
if (element.isJsonObject())
|
if (element.isJsonObject())
|
||||||
{
|
{
|
||||||
@@ -46,21 +46,21 @@ public class ScarpetJsonDeserializer implements JsonDeserializer<Value>
|
|||||||
return Value.NULL;
|
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())));
|
jsonMap.entrySet().forEach(entry -> map.put(new StringValue(entry.getKey()), parseElement(entry.getValue())));
|
||||||
return MapValue.wrap(map);
|
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)));
|
jsonList.forEach(elem -> list.add(parseElement(elem)));
|
||||||
return new ListValue(list);
|
return new ListValue(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Value parsePrimitive(final JsonPrimitive primitive) throws JsonParseException
|
private Value parsePrimitive(JsonPrimitive primitive) throws JsonParseException
|
||||||
{
|
{
|
||||||
if (primitive.isString())
|
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));
|
put("item", (c, s) -> new RenderedSprite(c, s, true));
|
||||||
}};
|
}};
|
||||||
|
|
||||||
public ShapesRenderer(final Minecraft minecraftClient)
|
public ShapesRenderer(Minecraft minecraftClient)
|
||||||
{
|
{
|
||||||
this.client = minecraftClient;
|
this.client = minecraftClient;
|
||||||
shapes = new HashMap<>();
|
shapes = new HashMap<>();
|
||||||
labels = 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();
|
//Camera camera = this.client.gameRenderer.getCamera();
|
||||||
final ClientLevel iWorld = this.client.level;
|
ClientLevel iWorld = this.client.level;
|
||||||
final ResourceKey<Level> dimensionType = iWorld.dimension();
|
ResourceKey<Level> dimensionType = iWorld.dimension();
|
||||||
if ((shapes.get(dimensionType) == null || shapes.get(dimensionType).isEmpty()) &&
|
if ((shapes.get(dimensionType) == null || shapes.get(dimensionType).isEmpty()) &&
|
||||||
(labels.get(dimensionType) == null || labels.get(dimensionType).isEmpty()))
|
(labels.get(dimensionType) == null || labels.get(dimensionType).isEmpty()))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final long currentTime = client.level.getGameTime();
|
long currentTime = client.level.getGameTime();
|
||||||
RenderSystem.enableDepthTest();
|
RenderSystem.enableDepthTest();
|
||||||
RenderSystem.setShader(GameRenderer::getPositionColorShader);
|
RenderSystem.setShader(GameRenderer::getPositionColorShader);
|
||||||
RenderSystem.depthFunc(515);
|
RenderSystem.depthFunc(515);
|
||||||
@@ -107,21 +107,21 @@ public class ShapesRenderer
|
|||||||
//RenderSystem.polygonOffset(-3f, -3f);
|
//RenderSystem.polygonOffset(-3f, -3f);
|
||||||
//RenderSystem.enablePolygonOffset();
|
//RenderSystem.enablePolygonOffset();
|
||||||
|
|
||||||
final Tesselator tessellator = Tesselator.getInstance();
|
Tesselator tessellator = Tesselator.getInstance();
|
||||||
final BufferBuilder bufferBuilder = tessellator.getBuilder();
|
BufferBuilder bufferBuilder = tessellator.getBuilder();
|
||||||
|
|
||||||
// render
|
// render
|
||||||
final double cameraX = camera.getPosition().x;
|
double cameraX = camera.getPosition().x;
|
||||||
final double cameraY = camera.getPosition().y;
|
double cameraY = camera.getPosition().y;
|
||||||
final double cameraZ = camera.getPosition().z;
|
double cameraZ = camera.getPosition().z;
|
||||||
final boolean entityBoxes = client.getEntityRenderDispatcher().shouldRenderHitBoxes();
|
boolean entityBoxes = client.getEntityRenderDispatcher().shouldRenderHitBoxes();
|
||||||
|
|
||||||
if (shapes.size() != 0)
|
if (!shapes.isEmpty())
|
||||||
{
|
{
|
||||||
shapes.get(dimensionType).long2ObjectEntrySet().removeIf(
|
shapes.get(dimensionType).long2ObjectEntrySet().removeIf(
|
||||||
entry -> entry.getValue().isExpired(currentTime)
|
entry -> entry.getValue().isExpired(currentTime)
|
||||||
);
|
);
|
||||||
final PoseStack matrixStack = RenderSystem.getModelViewStack();
|
PoseStack matrixStack = RenderSystem.getModelViewStack();
|
||||||
matrixStack.pushPose();
|
matrixStack.pushPose();
|
||||||
matrixStack.mulPoseMatrix(matrices.last().pose());
|
matrixStack.mulPoseMatrix(matrices.last().pose());
|
||||||
RenderSystem.applyModelViewMatrix();
|
RenderSystem.applyModelViewMatrix();
|
||||||
@@ -147,7 +147,7 @@ public class ShapesRenderer
|
|||||||
RenderSystem.applyModelViewMatrix();
|
RenderSystem.applyModelViewMatrix();
|
||||||
|
|
||||||
}
|
}
|
||||||
if (labels.size() != 0)
|
if (!labels.isEmpty())
|
||||||
{
|
{
|
||||||
labels.get(dimensionType).long2ObjectEntrySet().removeIf(
|
labels.get(dimensionType).long2ObjectEntrySet().removeIf(
|
||||||
entry -> entry.getValue().isExpired(currentTime)
|
entry -> entry.getValue().isExpired(currentTime)
|
||||||
@@ -166,9 +166,9 @@ public class ShapesRenderer
|
|||||||
token.run();
|
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++)
|
for (int i = 0, count = tag.size(); i < count; i++)
|
||||||
{
|
{
|
||||||
addShape(tag.getCompound(i));
|
addShape(tag.getCompound(i));
|
||||||
@@ -176,14 +176,14 @@ public class ShapesRenderer
|
|||||||
token.run();
|
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)
|
if (shape == null)
|
||||||
{
|
{
|
||||||
return;
|
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"));
|
shapeFactory = renderedShapes.get(tag.getString("shape"));
|
||||||
if (shapeFactory == null)
|
if (shapeFactory == null)
|
||||||
{
|
{
|
||||||
@@ -191,12 +191,12 @@ public class ShapesRenderer
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
final RenderedShape<?> rshape = shapeFactory.apply(client, shape);
|
RenderedShape<?> rshape = shapeFactory.apply(client, shape);
|
||||||
final ResourceKey<Level> dim = shape.shapeDimension;
|
ResourceKey<Level> dim = shape.shapeDimension;
|
||||||
final long key = rshape.key();
|
long key = rshape.key();
|
||||||
final Map<ResourceKey<Level>, Long2ObjectOpenHashMap<RenderedShape<? extends ShapeDispatcher.ExpiringShape>>> container =
|
Map<ResourceKey<Level>, Long2ObjectOpenHashMap<RenderedShape<? extends ShapeDispatcher.ExpiringShape>>> container =
|
||||||
rshape.stageDeux() ? labels : shapes;
|
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)
|
if (existing != null)
|
||||||
{ // promoting previous shape
|
{ // promoting previous shape
|
||||||
existing.promoteWith(rshape);
|
existing.promoteWith(rshape);
|
||||||
@@ -217,7 +217,7 @@ public class ShapesRenderer
|
|||||||
|
|
||||||
public void renewShapes()
|
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++));
|
shapes.values().forEach(el -> el.values().forEach(shape -> shape.expiryTick++));
|
||||||
labels.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 T shape;
|
||||||
protected Minecraft client;
|
protected Minecraft client;
|
||||||
long expiryTick;
|
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 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.shape = shape;
|
||||||
this.client = client;
|
this.client = client;
|
||||||
@@ -245,7 +245,7 @@ public class ShapesRenderer
|
|||||||
renderEpsilon = (3 + ((double) key()) / Long.MAX_VALUE) / 1000;
|
renderEpsilon = (3 + ((double) key()) / Long.MAX_VALUE) / 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isExpired(final long currentTick)
|
public boolean isExpired(long currentTick)
|
||||||
{
|
{
|
||||||
return expiryTick < currentTick;
|
return expiryTick < currentTick;
|
||||||
}
|
}
|
||||||
@@ -255,7 +255,7 @@ public class ShapesRenderer
|
|||||||
return shape.key(client.level.registryAccess());
|
return shape.key(client.level.registryAccess());
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean shouldRender(final ResourceKey<Level> dim)
|
public boolean shouldRender(ResourceKey<Level> dim)
|
||||||
{
|
{
|
||||||
if (shape.followEntity <= 0)
|
if (shape.followEntity <= 0)
|
||||||
{
|
{
|
||||||
@@ -277,7 +277,7 @@ public class ShapesRenderer
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void promoteWith(final RenderedShape<?> rshape)
|
public void promoteWith(RenderedShape<?> rshape)
|
||||||
{
|
{
|
||||||
expiryTick = rshape.expiryTick;
|
expiryTick = rshape.expiryTick;
|
||||||
}
|
}
|
||||||
@@ -293,7 +293,7 @@ public class ShapesRenderer
|
|||||||
private BlockState blockState;
|
private BlockState blockState;
|
||||||
private BlockEntity BlockEntity = null;
|
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);
|
super(client, (ShapeDispatcher.DisplayedSprite) shape);
|
||||||
this.isitem = isitem;
|
this.isitem = isitem;
|
||||||
@@ -304,16 +304,16 @@ public class ShapesRenderer
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void renderLines(final PoseStack matrices, final Tesselator tessellator, final BufferBuilder builder, final double cx, final double cy,
|
public void renderLines(PoseStack matrices, Tesselator tessellator, BufferBuilder builder, double cx, double cy,
|
||||||
final double cz, final float partialTick)
|
double cz, float partialTick)
|
||||||
{
|
{
|
||||||
if (shape.a == 0.0)
|
if (shape.a == 0.0)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final Vec3 v1 = shape.relativiseRender(client.level, shape.pos, partialTick);
|
Vec3 v1 = shape.relativiseRender(client.level, shape.pos, partialTick);
|
||||||
final Camera camera1 = client.gameRenderer.getMainCamera();
|
Camera camera1 = client.gameRenderer.getMainCamera();
|
||||||
|
|
||||||
matrices.pushPose();
|
matrices.pushPose();
|
||||||
if (!isitem)// blocks should use its center as the origin
|
if (!isitem)// blocks should use its center as the origin
|
||||||
@@ -364,20 +364,20 @@ public class ShapesRenderer
|
|||||||
|
|
||||||
blockState = shape.blockState;
|
blockState = shape.blockState;
|
||||||
|
|
||||||
final MultiBufferSource.BufferSource immediate = client.renderBuffers().bufferSource();
|
MultiBufferSource.BufferSource immediate = client.renderBuffers().bufferSource();
|
||||||
if (!isitem)
|
if (!isitem)
|
||||||
{
|
{
|
||||||
// draw the block itself
|
// draw the block itself
|
||||||
if (blockState.getRenderShape() == RenderShape.MODEL)
|
if (blockState.getRenderShape() == RenderShape.MODEL)
|
||||||
{
|
{
|
||||||
|
|
||||||
final var bakedModel = client.getBlockRenderer().getBlockModel(blockState);
|
var bakedModel = client.getBlockRenderer().getBlockModel(blockState);
|
||||||
final int color = client.getBlockColors().getColor(blockState, client.level, blockPos, 0);
|
int color = client.getBlockColors().getColor(blockState, client.level, blockPos, 0);
|
||||||
//dont know why there is a 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
|
//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;
|
float red = (color >> 16 & 0xFF) / 255.0F;
|
||||||
final float green = (color >> 8 & 0xFF) / 255.0F;
|
float green = (color >> 8 & 0xFF) / 255.0F;
|
||||||
final float blue = (color & 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);
|
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)
|
if (BlockEntity != null)
|
||||||
{
|
{
|
||||||
final BlockEntityRenderer<BlockEntity> blockEntityRenderer = client.getBlockEntityRenderDispatcher().getRenderer(BlockEntity);
|
BlockEntityRenderer<BlockEntity> blockEntityRenderer = client.getBlockEntityRenderDispatcher().getRenderer(BlockEntity);
|
||||||
if (blockEntityRenderer != null)
|
if (blockEntityRenderer != null)
|
||||||
{
|
{
|
||||||
blockEntityRenderer.render(BlockEntity, partialTick,
|
blockEntityRenderer.render(BlockEntity, partialTick,
|
||||||
@@ -440,19 +440,19 @@ public class ShapesRenderer
|
|||||||
}
|
}
|
||||||
|
|
||||||
// copy and modifiy a bit from net.minecraft.client.renderer.blockentity.ShulkerBoxRenderer.render
|
// 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;
|
Direction direction = Direction.UP;
|
||||||
if (shulkerBoxBlockEntity.hasLevel())
|
if (shulkerBoxBlockEntity.hasLevel())
|
||||||
{
|
{
|
||||||
final BlockState blockState = shulkerBoxBlockEntity.getBlockState();
|
BlockState blockState = shulkerBoxBlockEntity.getBlockState();
|
||||||
if (blockState.getBlock() instanceof ShulkerBoxBlock)
|
if (blockState.getBlock() instanceof ShulkerBoxBlock)
|
||||||
{
|
{
|
||||||
direction = blockState.getValue(ShulkerBoxBlock.FACING);
|
direction = blockState.getValue(ShulkerBoxBlock.FACING);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
final DyeColor dyeColor = shulkerBoxBlockEntity.getColor();
|
DyeColor dyeColor = shulkerBoxBlockEntity.getColor();
|
||||||
final Material material;
|
Material material;
|
||||||
if (dyeColor == null)
|
if (dyeColor == null)
|
||||||
{
|
{
|
||||||
material = Sheets.DEFAULT_SHULKER_TEXTURE_LOCATION;
|
material = Sheets.DEFAULT_SHULKER_TEXTURE_LOCATION;
|
||||||
@@ -468,11 +468,11 @@ public class ShapesRenderer
|
|||||||
poseStack.mulPose(direction.getRotation());
|
poseStack.mulPose(direction.getRotation());
|
||||||
poseStack.scale(1.0F, -1.0F, -1.0F);
|
poseStack.scale(1.0F, -1.0F, -1.0F);
|
||||||
poseStack.translate(0.0, -1.0, 0.0);
|
poseStack.translate(0.0, -1.0, 0.0);
|
||||||
final ShulkerModel<?> model = VanillaClient.ShulkerBoxRenderer_model(client.getBlockEntityRenderDispatcher().getRenderer(shulkerBoxBlockEntity));
|
ShulkerModel<?> model = VanillaClient.ShulkerBoxRenderer_model(client.getBlockEntityRenderDispatcher().getRenderer(shulkerBoxBlockEntity));
|
||||||
final ModelPart modelPart = model.getLid();
|
ModelPart modelPart = model.getLid();
|
||||||
modelPart.setPos(0.0F, 24.0F - shulkerBoxBlockEntity.getProgress(f) * 0.5F * 16.0F, 0.0F);
|
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);
|
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);
|
model.renderToBuffer(poseStack, vertexConsumer, i, j, 1.0F, 1.0F, 1.0F, 1.0F);
|
||||||
poseStack.popPose();
|
poseStack.popPose();
|
||||||
}
|
}
|
||||||
@@ -482,21 +482,21 @@ public class ShapesRenderer
|
|||||||
public static class RenderedText extends RenderedShape<ShapeDispatcher.DisplayedText>
|
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);
|
super(client, (ShapeDispatcher.DisplayedText) shape);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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)
|
if (shape.a == 0.0)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final Vec3 v1 = shape.relativiseRender(client.level, shape.pos, partialTick);
|
Vec3 v1 = shape.relativiseRender(client.level, shape.pos, partialTick);
|
||||||
final Camera camera1 = client.gameRenderer.getMainCamera();
|
Camera camera1 = client.gameRenderer.getMainCamera();
|
||||||
final Font textRenderer = client.font;
|
Font textRenderer = client.font;
|
||||||
if (shape.doublesided)
|
if (shape.doublesided)
|
||||||
{
|
{
|
||||||
RenderSystem.disableCull();
|
RenderSystem.disableCull();
|
||||||
@@ -538,7 +538,7 @@ public class ShapesRenderer
|
|||||||
{
|
{
|
||||||
text_x = (float) (-textRenderer.width(shape.value.getString()));
|
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);
|
textRenderer.drawInBatch(shape.value, text_x, 0.0F, shape.textcolor, false, matrices.last().pose(), immediate, false, shape.textbck, 15728880);
|
||||||
immediate.endBatch();
|
immediate.endBatch();
|
||||||
matrices.popPose();
|
matrices.popPose();
|
||||||
@@ -552,14 +552,14 @@ public class ShapesRenderer
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void promoteWith(final RenderedShape<?> rshape)
|
public void promoteWith(RenderedShape<?> rshape)
|
||||||
{
|
{
|
||||||
super.promoteWith(rshape);
|
super.promoteWith(rshape);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
this.shape.value = ((ShapeDispatcher.DisplayedText) rshape.shape).value;
|
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");
|
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>
|
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);
|
super(client, (ShapeDispatcher.Box) shape);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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)
|
if (shape.a == 0.0)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final Vec3 v1 = shape.relativiseRender(client.level, shape.from, partialTick);
|
Vec3 v1 = shape.relativiseRender(client.level, shape.from, partialTick);
|
||||||
final Vec3 v2 = shape.relativiseRender(client.level, shape.to, partialTick);
|
Vec3 v2 = shape.relativiseRender(client.level, shape.to, partialTick);
|
||||||
drawBoxWireGLLines(tessellator, bufferBuilder,
|
drawBoxWireGLLines(tessellator, bufferBuilder,
|
||||||
(float) (v1.x - cx - renderEpsilon), (float) (v1.y - cy - renderEpsilon), (float) (v1.z - cz - renderEpsilon),
|
(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),
|
(float) (v2.x - cx + renderEpsilon), (float) (v2.y - cy + renderEpsilon), (float) (v2.z - cz + renderEpsilon),
|
||||||
@@ -592,14 +592,14 @@ public class ShapesRenderer
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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)
|
if (shape.fa == 0.0)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final Vec3 v1 = shape.relativiseRender(client.level, shape.from, partialTick);
|
Vec3 v1 = shape.relativiseRender(client.level, shape.from, partialTick);
|
||||||
final Vec3 v2 = shape.relativiseRender(client.level, shape.to, partialTick);
|
Vec3 v2 = shape.relativiseRender(client.level, shape.to, partialTick);
|
||||||
// consider using built-ins
|
// 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);
|
//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,
|
drawBoxFaces(tessellator, bufferBuilder,
|
||||||
@@ -613,16 +613,16 @@ public class ShapesRenderer
|
|||||||
|
|
||||||
public static class RenderedLine extends RenderedShape<ShapeDispatcher.Line>
|
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);
|
super(client, (ShapeDispatcher.Line) shape);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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);
|
Vec3 v1 = shape.relativiseRender(client.level, shape.from, partialTick);
|
||||||
final Vec3 v2 = shape.relativiseRender(client.level, shape.to, partialTick);
|
Vec3 v2 = shape.relativiseRender(client.level, shape.to, partialTick);
|
||||||
drawLine(tessellator, bufferBuilder,
|
drawLine(tessellator, bufferBuilder,
|
||||||
(float) (v1.x - cx - renderEpsilon), (float) (v1.y - cy - renderEpsilon), (float) (v1.z - cz - renderEpsilon),
|
(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),
|
(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[]{
|
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};
|
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);
|
super(client, (ShapeDispatcher.Polyface) shape);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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)
|
if (shape.fa == 0)
|
||||||
{
|
{
|
||||||
@@ -659,9 +659,9 @@ public class ShapesRenderer
|
|||||||
}
|
}
|
||||||
|
|
||||||
bufferBuilder.begin(faceIndices[shape.mode], DefaultVertexFormat.POSITION_COLOR);
|
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))
|
if (shape.relative.get(i))
|
||||||
{
|
{
|
||||||
vec = shape.relativiseRender(client.level, vec, partialTick);
|
vec = shape.relativiseRender(client.level, vec, partialTick);
|
||||||
@@ -678,8 +678,8 @@ public class ShapesRenderer
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void renderLines(final PoseStack matrices, final Tesselator tessellator, final BufferBuilder builder, final double cx, final double cy,
|
public void renderLines(PoseStack matrices, Tesselator tessellator, BufferBuilder builder, double cx, double cy,
|
||||||
final double cz, final float partialTick)
|
double cz, float partialTick)
|
||||||
{
|
{
|
||||||
if (shape.a == 0)
|
if (shape.a == 0)
|
||||||
{
|
{
|
||||||
@@ -690,9 +690,9 @@ public class ShapesRenderer
|
|||||||
{
|
{
|
||||||
builder.begin(VertexFormat.Mode.DEBUG_LINE_STRIP, DefaultVertexFormat.POSITION_COLOR);
|
builder.begin(VertexFormat.Mode.DEBUG_LINE_STRIP, DefaultVertexFormat.POSITION_COLOR);
|
||||||
Vec3 vec0 = null;
|
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))
|
if (shape.relative.get(i))
|
||||||
{
|
{
|
||||||
vec = shape.relativiseRender(client.level, vec, partialTick);
|
vec = shape.relativiseRender(client.level, vec, partialTick);
|
||||||
@@ -708,9 +708,9 @@ public class ShapesRenderer
|
|||||||
if (shape.inneredges)
|
if (shape.inneredges)
|
||||||
{
|
{
|
||||||
builder.begin(VertexFormat.Mode.DEBUG_LINES, DefaultVertexFormat.POSITION_COLOR);
|
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))
|
if (shape.relative.get(i))
|
||||||
{
|
{
|
||||||
vec = shape.relativiseRender(client.level, vec, partialTick);
|
vec = shape.relativiseRender(client.level, vec, partialTick);
|
||||||
@@ -726,26 +726,26 @@ public class ShapesRenderer
|
|||||||
if (shape.mode == 5)
|
if (shape.mode == 5)
|
||||||
{
|
{
|
||||||
builder.begin(VertexFormat.Mode.DEBUG_LINE_STRIP, DefaultVertexFormat.POSITION_COLOR);
|
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))
|
if (shape.relative.get(1))
|
||||||
{
|
{
|
||||||
vec = shape.relativiseRender(client.level, vec, partialTick);
|
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();
|
builder.vertex(vec.x() - cx, vec.y() - cy, vec.z() - cz).color(shape.r, shape.g, shape.b, shape.a).endVertex();
|
||||||
int i;
|
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))
|
if (shape.relative.get(i))
|
||||||
{
|
{
|
||||||
vec = shape.relativiseRender(client.level, vec, partialTick);
|
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();
|
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)
|
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))
|
if (shape.relative.get(i))
|
||||||
{
|
{
|
||||||
vec = shape.relativiseRender(client.level, vec, partialTick);
|
vec = shape.relativiseRender(client.level, vec, partialTick);
|
||||||
@@ -754,9 +754,9 @@ public class ShapesRenderer
|
|||||||
}
|
}
|
||||||
if (shape.inneredges)
|
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))
|
if (shape.relative.get(i))
|
||||||
{
|
{
|
||||||
vec = shape.relativiseRender(client.level, vec, partialTick);
|
vec = shape.relativiseRender(client.level, vec, partialTick);
|
||||||
@@ -770,21 +770,21 @@ public class ShapesRenderer
|
|||||||
if (shape.mode == 4)
|
if (shape.mode == 4)
|
||||||
{
|
{
|
||||||
builder.begin(VertexFormat.Mode.DEBUG_LINES, DefaultVertexFormat.POSITION_COLOR);
|
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))
|
if (shape.relative.get(i))
|
||||||
{
|
{
|
||||||
vecA = shape.relativiseRender(client.level, vecA, partialTick);
|
vecA = shape.relativiseRender(client.level, vecA, partialTick);
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
Vec3 vecB = shape.vertex_list.get(i);
|
Vec3 vecB = shape.vertexList.get(i);
|
||||||
if (shape.relative.get(i))
|
if (shape.relative.get(i))
|
||||||
{
|
{
|
||||||
vecB = shape.relativiseRender(client.level, vecB, partialTick);
|
vecB = shape.relativiseRender(client.level, vecB, partialTick);
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
Vec3 vecC = shape.vertex_list.get(i);
|
Vec3 vecC = shape.vertexList.get(i);
|
||||||
if (shape.relative.get(i))
|
if (shape.relative.get(i))
|
||||||
{
|
{
|
||||||
vecC = shape.relativiseRender(client.level, vecC, partialTick);
|
vecC = shape.relativiseRender(client.level, vecC, partialTick);
|
||||||
@@ -805,19 +805,19 @@ public class ShapesRenderer
|
|||||||
|
|
||||||
public static class RenderedSphere extends RenderedShape<ShapeDispatcher.Sphere>
|
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);
|
super(client, (ShapeDispatcher.Sphere) shape);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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)
|
if (shape.a == 0.0)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final Vec3 vc = shape.relativiseRender(client.level, shape.center, partialTick);
|
Vec3 vc = shape.relativiseRender(client.level, shape.center, partialTick);
|
||||||
drawSphereWireframe(tessellator, bufferBuilder,
|
drawSphereWireframe(tessellator, bufferBuilder,
|
||||||
(float) (vc.x - cx), (float) (vc.y - cy), (float) (vc.z - cz),
|
(float) (vc.x - cx), (float) (vc.y - cy), (float) (vc.z - cz),
|
||||||
(float) (shape.radius + renderEpsilon), shape.subdivisions,
|
(float) (shape.radius + renderEpsilon), shape.subdivisions,
|
||||||
@@ -825,13 +825,13 @@ public class ShapesRenderer
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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)
|
if (shape.fa == 0.0)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final Vec3 vc = shape.relativiseRender(client.level, shape.center, partialTick);
|
Vec3 vc = shape.relativiseRender(client.level, shape.center, partialTick);
|
||||||
drawSphereFaces(tessellator, bufferBuilder,
|
drawSphereFaces(tessellator, bufferBuilder,
|
||||||
(float) (vc.x - cx), (float) (vc.y - cy), (float) (vc.z - cz),
|
(float) (vc.x - cx), (float) (vc.y - cy), (float) (vc.z - cz),
|
||||||
(float) (shape.radius + renderEpsilon), shape.subdivisions,
|
(float) (shape.radius + renderEpsilon), shape.subdivisions,
|
||||||
@@ -841,20 +841,20 @@ public class ShapesRenderer
|
|||||||
|
|
||||||
public static class RenderedCylinder extends RenderedShape<ShapeDispatcher.Cylinder>
|
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);
|
super(client, (ShapeDispatcher.Cylinder) shape);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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)
|
if (shape.a == 0.0)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final Vec3 vc = shape.relativiseRender(client.level, shape.center, partialTick);
|
Vec3 vc = shape.relativiseRender(client.level, shape.center, partialTick);
|
||||||
final double dir = Mth.sign(shape.height);
|
double dir = Mth.sign(shape.height);
|
||||||
drawCylinderWireframe(tessellator, bufferBuilder,
|
drawCylinderWireframe(tessellator, bufferBuilder,
|
||||||
(float) (vc.x - cx - dir * renderEpsilon), (float) (vc.y - cy - dir * renderEpsilon), (float) (vc.z - cz - dir * renderEpsilon),
|
(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,
|
(float) (shape.radius + renderEpsilon), (float) (shape.height + 2 * dir * renderEpsilon), shape.axis,
|
||||||
@@ -864,14 +864,14 @@ public class ShapesRenderer
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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)
|
if (shape.fa == 0.0)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final Vec3 vc = shape.relativiseRender(client.level, shape.center, partialTick);
|
Vec3 vc = shape.relativiseRender(client.level, shape.center, partialTick);
|
||||||
final double dir = Mth.sign(shape.height);
|
double dir = Mth.sign(shape.height);
|
||||||
drawCylinderFaces(tessellator, bufferBuilder,
|
drawCylinderFaces(tessellator, bufferBuilder,
|
||||||
(float) (vc.x - cx - dir * renderEpsilon), (float) (vc.y - cy - dir * renderEpsilon), (float) (vc.z - cz - dir * renderEpsilon),
|
(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,
|
(float) (shape.radius + renderEpsilon), (float) (shape.height + 2 * dir * renderEpsilon), shape.axis,
|
||||||
@@ -882,7 +882,7 @@ public class ShapesRenderer
|
|||||||
|
|
||||||
// some raw shit
|
// 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.begin(VertexFormat.Mode.DEBUG_LINES, DefaultVertexFormat.POSITION_COLOR);
|
||||||
builder.vertex(x1, y1, z1).color(red1, grn1, blu1, alpha).endVertex();
|
builder.vertex(x1, y1, z1).color(red1, grn1, blu1, alpha).endVertex();
|
||||||
@@ -891,11 +891,11 @@ public class ShapesRenderer
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void drawBoxWireGLLines(
|
public static void drawBoxWireGLLines(
|
||||||
final Tesselator tessellator, final BufferBuilder builder,
|
Tesselator tessellator, BufferBuilder builder,
|
||||||
final float x1, final float y1, final float z1,
|
float x1, float y1, float z1,
|
||||||
final float x2, final float y2, final float z2,
|
float x2, float y2, float z2,
|
||||||
final boolean xthick, final boolean ythick, final boolean zthick,
|
boolean xthick, boolean ythick, boolean zthick,
|
||||||
final float red1, final float grn1, final float blu1, final float alpha, final float red2, final float grn2, final float blu2)
|
float red1, float grn1, float blu1, float alpha, float red2, float grn2, float blu2)
|
||||||
{
|
{
|
||||||
builder.begin(VertexFormat.Mode.DEBUG_LINES, DefaultVertexFormat.POSITION_COLOR);
|
builder.begin(VertexFormat.Mode.DEBUG_LINES, DefaultVertexFormat.POSITION_COLOR);
|
||||||
if (xthick)
|
if (xthick)
|
||||||
@@ -944,11 +944,11 @@ public class ShapesRenderer
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void drawBoxFaces(
|
public static void drawBoxFaces(
|
||||||
final Tesselator tessellator, final BufferBuilder builder,
|
Tesselator tessellator, BufferBuilder builder,
|
||||||
final float x1, final float y1, final float z1,
|
float x1, float y1, float z1,
|
||||||
final float x2, final float y2, final float z2,
|
float x2, float y2, float z2,
|
||||||
final boolean xthick, final boolean ythick, final boolean zthick,
|
boolean xthick, boolean ythick, boolean zthick,
|
||||||
final float red1, final float grn1, final float blu1, final float alpha)
|
float red1, float grn1, float blu1, float alpha)
|
||||||
{
|
{
|
||||||
builder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR);
|
builder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR);
|
||||||
|
|
||||||
@@ -1004,14 +1004,14 @@ public class ShapesRenderer
|
|||||||
tessellator.end();
|
tessellator.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void drawCylinderWireframe(final Tesselator tessellator, final BufferBuilder builder,
|
public static void drawCylinderWireframe(Tesselator tessellator, BufferBuilder builder,
|
||||||
final float cx, final float cy, final float cz,
|
float cx, float cy, float cz,
|
||||||
final float r, final float h, final Direction.Axis axis, final int subd, final boolean isFlat,
|
float r, float h, Direction.Axis axis, int subd, boolean isFlat,
|
||||||
final float red, final float grn, final float blu, final float alpha)
|
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;
|
int num_steps180 = (int) (Math.PI / step) + 1;
|
||||||
final int num_steps360 = (int) (2 * Math.PI / step);
|
int num_steps360 = (int) (2 * Math.PI / step);
|
||||||
int hsteps = 1;
|
int hsteps = 1;
|
||||||
float hstep = 1.0f;
|
float hstep = 1.0f;
|
||||||
if (!isFlat)
|
if (!isFlat)
|
||||||
@@ -1024,14 +1024,14 @@ public class ShapesRenderer
|
|||||||
{
|
{
|
||||||
for (int dh = 0; dh < hsteps; dh++)
|
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
|
builder.begin(VertexFormat.Mode.DEBUG_LINE_STRIP, DefaultVertexFormat.POSITION_COLOR); // line loop to line strip
|
||||||
for (int i = 0; i <= num_steps360 + 1; i++)
|
for (int i = 0; i <= num_steps360 + 1; i++)
|
||||||
{
|
{
|
||||||
final float theta = step * i;
|
float theta = step * i;
|
||||||
final float x = r * Mth.cos(theta);
|
float x = r * Mth.cos(theta);
|
||||||
final float y = hh;
|
float y = hh;
|
||||||
final float z = r * Mth.sin(theta);
|
float z = r * Mth.sin(theta);
|
||||||
builder.vertex(x + cx, y + cy, z + cz).color(red, grn, blu, alpha).endVertex();
|
builder.vertex(x + cx, y + cy, z + cz).color(red, grn, blu, alpha).endVertex();
|
||||||
}
|
}
|
||||||
tessellator.end();
|
tessellator.end();
|
||||||
@@ -1042,10 +1042,10 @@ public class ShapesRenderer
|
|||||||
for (int i = 0; i <= num_steps180; i++)
|
for (int i = 0; i <= num_steps180; i++)
|
||||||
{
|
{
|
||||||
builder.begin(VertexFormat.Mode.DEBUG_LINE_STRIP, DefaultVertexFormat.POSITION_COLOR); // line loop to line strip
|
builder.begin(VertexFormat.Mode.DEBUG_LINE_STRIP, DefaultVertexFormat.POSITION_COLOR); // line loop to line strip
|
||||||
final float theta = step * i;
|
float theta = step * i;
|
||||||
final float x = r * Mth.cos(theta);
|
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();
|
||||||
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);
|
builder.begin(VertexFormat.Mode.DEBUG_LINES, DefaultVertexFormat.POSITION_COLOR);
|
||||||
for (int i = 0; i <= num_steps180; i++)
|
for (int i = 0; i <= num_steps180; i++)
|
||||||
{
|
{
|
||||||
final float theta = step * i;
|
float theta = step * i;
|
||||||
final float x = r * Mth.cos(theta);
|
float x = r * Mth.cos(theta);
|
||||||
final float z = r * Mth.sin(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();
|
||||||
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++)
|
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
|
builder.begin(VertexFormat.Mode.DEBUG_LINE_STRIP, DefaultVertexFormat.POSITION_COLOR); // line loop to line strip
|
||||||
for (int i = 0; i <= num_steps360; i++)
|
for (int i = 0; i <= num_steps360; i++)
|
||||||
{
|
{
|
||||||
final float theta = step * i;
|
float theta = step * i;
|
||||||
final float z = r * Mth.cos(theta);
|
float z = r * Mth.cos(theta);
|
||||||
final float x = hh;
|
float x = hh;
|
||||||
final float y = r * Mth.sin(theta);
|
float y = r * Mth.sin(theta);
|
||||||
builder.vertex(x + cx, y + cy, z + cz).color(red, grn, blu, alpha).endVertex();
|
builder.vertex(x + cx, y + cy, z + cz).color(red, grn, blu, alpha).endVertex();
|
||||||
}
|
}
|
||||||
tessellator.end();
|
tessellator.end();
|
||||||
@@ -1092,10 +1092,10 @@ public class ShapesRenderer
|
|||||||
for (int i = 0; i <= num_steps180; i++)
|
for (int i = 0; i <= num_steps180; i++)
|
||||||
{
|
{
|
||||||
builder.begin(VertexFormat.Mode.DEBUG_LINE_STRIP, DefaultVertexFormat.POSITION_COLOR); // line loop to line strip
|
builder.begin(VertexFormat.Mode.DEBUG_LINE_STRIP, DefaultVertexFormat.POSITION_COLOR); // line loop to line strip
|
||||||
final float theta = step * i;
|
float theta = step * i;
|
||||||
final float y = r * Mth.cos(theta);
|
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();
|
||||||
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);
|
builder.begin(VertexFormat.Mode.DEBUG_LINES, DefaultVertexFormat.POSITION_COLOR);
|
||||||
for (int i = 0; i <= num_steps180; i++)
|
for (int i = 0; i <= num_steps180; i++)
|
||||||
{
|
{
|
||||||
final float theta = step * i;
|
float theta = step * i;
|
||||||
final float y = r * Mth.cos(theta);
|
float y = r * Mth.cos(theta);
|
||||||
final float z = r * Mth.sin(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();
|
||||||
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++)
|
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
|
builder.begin(VertexFormat.Mode.DEBUG_LINE_STRIP, DefaultVertexFormat.POSITION_COLOR); // line loop to line strip
|
||||||
for (int i = 0; i <= num_steps360; i++)
|
for (int i = 0; i <= num_steps360; i++)
|
||||||
{
|
{
|
||||||
final float theta = step * i;
|
float theta = step * i;
|
||||||
final float y = r * Mth.cos(theta);
|
float y = r * Mth.cos(theta);
|
||||||
final float z = hh;
|
float z = hh;
|
||||||
final float x = r * Mth.sin(theta);
|
float x = r * Mth.sin(theta);
|
||||||
builder.vertex(x + cx, y + cy, z + cz).color(red, grn, blu, alpha).endVertex();
|
builder.vertex(x + cx, y + cy, z + cz).color(red, grn, blu, alpha).endVertex();
|
||||||
}
|
}
|
||||||
tessellator.end();
|
tessellator.end();
|
||||||
@@ -1139,10 +1139,10 @@ public class ShapesRenderer
|
|||||||
for (int i = 0; i <= num_steps180; i++)
|
for (int i = 0; i <= num_steps180; i++)
|
||||||
{
|
{
|
||||||
builder.begin(VertexFormat.Mode.DEBUG_LINE_STRIP, DefaultVertexFormat.POSITION_COLOR); // line loop to line strip
|
builder.begin(VertexFormat.Mode.DEBUG_LINE_STRIP, DefaultVertexFormat.POSITION_COLOR); // line loop to line strip
|
||||||
final float theta = step * i;
|
float theta = step * i;
|
||||||
final float x = r * Mth.cos(theta);
|
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();
|
||||||
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);
|
builder.begin(VertexFormat.Mode.DEBUG_LINES, DefaultVertexFormat.POSITION_COLOR);
|
||||||
for (int i = 0; i <= num_steps180; i++)
|
for (int i = 0; i <= num_steps180; i++)
|
||||||
{
|
{
|
||||||
final float theta = step * i;
|
float theta = step * i;
|
||||||
final float x = r * Mth.cos(theta);
|
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).color(red, grn, blu, alpha).endVertex();
|
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();
|
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,
|
public static void drawCylinderFaces(Tesselator tessellator, BufferBuilder builder,
|
||||||
final float cx, final float cy, final float cz,
|
float cx, float cy, float cz,
|
||||||
final float r, final float h, final Direction.Axis axis, final int subd, final boolean isFlat,
|
float r, float h, Direction.Axis axis, int subd, boolean isFlat,
|
||||||
final float red, final float grn, final float blu, final float alpha)
|
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_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)
|
if (axis == Direction.Axis.Y)
|
||||||
{
|
{
|
||||||
@@ -1184,9 +1184,9 @@ public class ShapesRenderer
|
|||||||
builder.vertex(cx, cy, cz).color(red, grn, blu, alpha).endVertex();
|
builder.vertex(cx, cy, cz).color(red, grn, blu, alpha).endVertex();
|
||||||
for (int i = 0; i <= num_steps360; i++)
|
for (int i = 0; i <= num_steps360; i++)
|
||||||
{
|
{
|
||||||
final float theta = step * i;
|
float theta = step * i;
|
||||||
final float x = r * Mth.cos(theta);
|
float x = r * Mth.cos(theta);
|
||||||
final float z = r * Mth.sin(theta);
|
float z = r * Mth.sin(theta);
|
||||||
builder.vertex(x + cx, cy, z + cz).color(red, grn, blu, alpha).endVertex();
|
builder.vertex(x + cx, cy, z + cz).color(red, grn, blu, alpha).endVertex();
|
||||||
}
|
}
|
||||||
tessellator.end();
|
tessellator.end();
|
||||||
@@ -1196,9 +1196,9 @@ public class ShapesRenderer
|
|||||||
builder.vertex(cx, cy + h, cz).color(red, grn, blu, alpha).endVertex();
|
builder.vertex(cx, cy + h, cz).color(red, grn, blu, alpha).endVertex();
|
||||||
for (int i = 0; i <= num_steps360; i++)
|
for (int i = 0; i <= num_steps360; i++)
|
||||||
{
|
{
|
||||||
final float theta = step * i;
|
float theta = step * i;
|
||||||
final float x = r * Mth.cos(theta);
|
float x = r * Mth.cos(theta);
|
||||||
final float z = r * Mth.sin(theta);
|
float z = r * Mth.sin(theta);
|
||||||
builder.vertex(x + cx, cy + h, z + cz).color(red, grn, blu, alpha).endVertex();
|
builder.vertex(x + cx, cy + h, z + cz).color(red, grn, blu, alpha).endVertex();
|
||||||
}
|
}
|
||||||
tessellator.end();
|
tessellator.end();
|
||||||
@@ -1208,9 +1208,9 @@ public class ShapesRenderer
|
|||||||
float zp = r * 0;
|
float zp = r * 0;
|
||||||
for (int i = 1; i <= num_steps360; i++)
|
for (int i = 1; i <= num_steps360; i++)
|
||||||
{
|
{
|
||||||
final float theta = step * i;
|
float theta = step * i;
|
||||||
final float x = r * Mth.cos(theta);
|
float x = r * Mth.cos(theta);
|
||||||
final float z = r * Mth.sin(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 + 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 + 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();
|
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();
|
builder.vertex(cx, cy, cz).color(red, grn, blu, alpha).endVertex();
|
||||||
for (int i = 0; i <= num_steps360; i++)
|
for (int i = 0; i <= num_steps360; i++)
|
||||||
{
|
{
|
||||||
final float theta = step * i;
|
float theta = step * i;
|
||||||
final float y = r * Mth.cos(theta);
|
float y = r * Mth.cos(theta);
|
||||||
final float z = r * Mth.sin(theta);
|
float z = r * Mth.sin(theta);
|
||||||
builder.vertex(cx, cy + y, z + cz).color(red, grn, blu, alpha).endVertex();
|
builder.vertex(cx, cy + y, z + cz).color(red, grn, blu, alpha).endVertex();
|
||||||
}
|
}
|
||||||
tessellator.end();
|
tessellator.end();
|
||||||
@@ -1240,9 +1240,9 @@ public class ShapesRenderer
|
|||||||
builder.vertex(cx + h, cy, cz).color(red, grn, blu, alpha).endVertex();
|
builder.vertex(cx + h, cy, cz).color(red, grn, blu, alpha).endVertex();
|
||||||
for (int i = 0; i <= num_steps360; i++)
|
for (int i = 0; i <= num_steps360; i++)
|
||||||
{
|
{
|
||||||
final float theta = step * i;
|
float theta = step * i;
|
||||||
final float y = r * Mth.cos(theta);
|
float y = r * Mth.cos(theta);
|
||||||
final float z = r * Mth.sin(theta);
|
float z = r * Mth.sin(theta);
|
||||||
builder.vertex(cx + h, cy + y, cz + z).color(red, grn, blu, alpha).endVertex();
|
builder.vertex(cx + h, cy + y, cz + z).color(red, grn, blu, alpha).endVertex();
|
||||||
}
|
}
|
||||||
tessellator.end();
|
tessellator.end();
|
||||||
@@ -1252,9 +1252,9 @@ public class ShapesRenderer
|
|||||||
float zp = r * 0;
|
float zp = r * 0;
|
||||||
for (int i = 1; i <= num_steps360; i++)
|
for (int i = 1; i <= num_steps360; i++)
|
||||||
{
|
{
|
||||||
final float theta = step * i;
|
float theta = step * i;
|
||||||
final float y = r * Mth.cos(theta);
|
float y = r * Mth.cos(theta);
|
||||||
final float z = r * Mth.sin(theta);
|
float z = r * Mth.sin(theta);
|
||||||
builder.vertex(cx + 0, cy + yp, cz + zp).color(red, grn, blu, alpha).endVertex();
|
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 + yp, cz + zp).color(red, grn, blu, alpha).endVertex();
|
||||||
builder.vertex(cx + h, cy + y, cz + z).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();
|
builder.vertex(cx, cy, cz).color(red, grn, blu, alpha).endVertex();
|
||||||
for (int i = 0; i <= num_steps360; i++)
|
for (int i = 0; i <= num_steps360; i++)
|
||||||
{
|
{
|
||||||
final float theta = step * i;
|
float theta = step * i;
|
||||||
final float x = r * Mth.cos(theta);
|
float x = r * Mth.cos(theta);
|
||||||
final float y = r * Mth.sin(theta);
|
float y = r * Mth.sin(theta);
|
||||||
builder.vertex(x + cx, cy + y, cz).color(red, grn, blu, alpha).endVertex();
|
builder.vertex(x + cx, cy + y, cz).color(red, grn, blu, alpha).endVertex();
|
||||||
}
|
}
|
||||||
tessellator.end();
|
tessellator.end();
|
||||||
@@ -1283,9 +1283,9 @@ public class ShapesRenderer
|
|||||||
builder.vertex(cx, cy, cz + h).color(red, grn, blu, alpha).endVertex();
|
builder.vertex(cx, cy, cz + h).color(red, grn, blu, alpha).endVertex();
|
||||||
for (int i = 0; i <= num_steps360; i++)
|
for (int i = 0; i <= num_steps360; i++)
|
||||||
{
|
{
|
||||||
final float theta = step * i;
|
float theta = step * i;
|
||||||
final float x = r * Mth.cos(theta);
|
float x = r * Mth.cos(theta);
|
||||||
final float y = r * Mth.sin(theta);
|
float y = r * Mth.sin(theta);
|
||||||
builder.vertex(x + cx, cy + y, cz + h).color(red, grn, blu, alpha).endVertex();
|
builder.vertex(x + cx, cy + y, cz + h).color(red, grn, blu, alpha).endVertex();
|
||||||
}
|
}
|
||||||
tessellator.end();
|
tessellator.end();
|
||||||
@@ -1295,9 +1295,9 @@ public class ShapesRenderer
|
|||||||
float yp = 0;
|
float yp = 0;
|
||||||
for (int i = 1; i <= num_steps360; i++)
|
for (int i = 1; i <= num_steps360; i++)
|
||||||
{
|
{
|
||||||
final float theta = step * i;
|
float theta = step * i;
|
||||||
final float x = r * Mth.cos(theta);
|
float x = r * Mth.cos(theta);
|
||||||
final float y = r * Mth.sin(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 + 0).color(red, grn, blu, alpha).endVertex();
|
||||||
builder.vertex(cx + xp, cy + yp, cz + h).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();
|
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,
|
public static void drawSphereWireframe(Tesselator tessellator, BufferBuilder builder,
|
||||||
final float cx, final float cy, final float cz,
|
float cx, float cy, float cz,
|
||||||
final float r, final int subd,
|
float r, int subd,
|
||||||
final float red, final float grn, final float blu, final float alpha)
|
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;
|
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;
|
||||||
for (int i = 0; i <= num_steps360; i++)
|
for (int i = 0; i <= num_steps360; i++)
|
||||||
{
|
{
|
||||||
builder.begin(VertexFormat.Mode.DEBUG_LINE_STRIP, DefaultVertexFormat.POSITION_COLOR);
|
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++)
|
for (int j = 0; j <= num_steps180; j++)
|
||||||
{
|
{
|
||||||
final float phi = step * j;
|
float phi = step * j;
|
||||||
final float x = r * Mth.sin(phi) * Mth.cos(theta);
|
float x = r * Mth.sin(phi) * Mth.cos(theta);
|
||||||
final float z = r * Mth.sin(phi) * Mth.sin(theta);
|
float z = r * Mth.sin(phi) * Mth.sin(theta);
|
||||||
final float y = r * Mth.cos(phi);
|
float y = r * Mth.cos(phi);
|
||||||
builder.vertex(x + cx, y + cy, z + cz).color(red, grn, blu, alpha).endVertex();
|
builder.vertex(x + cx, y + cy, z + cz).color(red, grn, blu, alpha).endVertex();
|
||||||
}
|
}
|
||||||
tessellator.end();
|
tessellator.end();
|
||||||
@@ -1335,14 +1335,14 @@ public class ShapesRenderer
|
|||||||
for (int j = 0; j <= num_steps180; j++)
|
for (int j = 0; j <= num_steps180; j++)
|
||||||
{
|
{
|
||||||
builder.begin(VertexFormat.Mode.DEBUG_LINE_STRIP, DefaultVertexFormat.POSITION_COLOR); // line loop to line strip
|
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++)
|
for (int i = 0; i <= num_steps360; i++)
|
||||||
{
|
{
|
||||||
final float theta = step * i;
|
float theta = step * i;
|
||||||
final float x = r * Mth.sin(phi) * Mth.cos(theta);
|
float x = r * Mth.sin(phi) * Mth.cos(theta);
|
||||||
final float z = r * Mth.sin(phi) * Mth.sin(theta);
|
float z = r * Mth.sin(phi) * Mth.sin(theta);
|
||||||
final float y = r * Mth.cos(phi);
|
float y = r * Mth.cos(phi);
|
||||||
builder.vertex(x + cx, y + cy, z + cz).color(red, grn, blu, alpha).endVertex();
|
builder.vertex(x + cx, y + cy, z + cz).color(red, grn, blu, alpha).endVertex();
|
||||||
}
|
}
|
||||||
tessellator.end();
|
tessellator.end();
|
||||||
@@ -1350,19 +1350,19 @@ public class ShapesRenderer
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void drawSphereFaces(final Tesselator tessellator, final BufferBuilder builder,
|
public static void drawSphereFaces(Tesselator tessellator, BufferBuilder builder,
|
||||||
final float cx, final float cy, final float cz,
|
float cx, float cy, float cz,
|
||||||
final float r, final int subd,
|
float r, int subd,
|
||||||
final float red, final float grn, final float blu, final float alpha)
|
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;
|
int num_steps180 = (int) (Math.PI / step) + 1;
|
||||||
final int num_steps360 = (int) (2 * Math.PI / step);
|
int num_steps360 = (int) (2 * Math.PI / step);
|
||||||
for (int i = 0; i <= num_steps360; i++)
|
for (int i = 0; i <= num_steps360; i++)
|
||||||
{
|
{
|
||||||
final float theta = i * step;
|
float theta = i * step;
|
||||||
final float thetaprime = theta + step;
|
float thetaprime = theta + step;
|
||||||
builder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR); // quad strip to quads
|
builder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR); // quad strip to quads
|
||||||
float xb = 0;
|
float xb = 0;
|
||||||
float zb = 0;
|
float zb = 0;
|
||||||
@@ -1371,12 +1371,12 @@ public class ShapesRenderer
|
|||||||
float yp = r;
|
float yp = r;
|
||||||
for (int j = 0; j <= num_steps180; j++)
|
for (int j = 0; j <= num_steps180; j++)
|
||||||
{
|
{
|
||||||
final float phi = j * step;
|
float phi = j * step;
|
||||||
final float x = r * Mth.sin(phi) * Mth.cos(theta);
|
float x = r * Mth.sin(phi) * Mth.cos(theta);
|
||||||
final float z = r * Mth.sin(phi) * Mth.sin(theta);
|
float z = r * Mth.sin(phi) * Mth.sin(theta);
|
||||||
final float y = r * Mth.cos(phi);
|
float y = r * Mth.cos(phi);
|
||||||
final float xp = r * Mth.sin(phi) * Mth.cos(thetaprime);
|
float xp = r * Mth.sin(phi) * Mth.cos(thetaprime);
|
||||||
final float zp = r * Mth.sin(phi) * Mth.sin(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(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(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();
|
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 SimplexNoiseSampler instance = new SimplexNoiseSampler(new Random(0));
|
||||||
public static Map<Long, SimplexNoiseSampler> samplers = new Long2ObjectOpenHashMap<>();
|
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)
|
if (samplers.size() > 256)
|
||||||
{
|
{
|
||||||
@@ -24,15 +24,15 @@ public class SimplexNoiseSampler extends PerlinNoiseSampler
|
|||||||
return samplers.computeIfAbsent(aLong, seed -> new SimplexNoiseSampler(new Random(seed)));
|
return samplers.computeIfAbsent(aLong, seed -> new SimplexNoiseSampler(new Random(seed)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public SimplexNoiseSampler(final Random random)
|
public SimplexNoiseSampler(Random random)
|
||||||
{
|
{
|
||||||
super(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;
|
double e = d - x * x - y * y - z * z;
|
||||||
final double g;
|
double g;
|
||||||
if (e < 0.0D)
|
if (e < 0.0D)
|
||||||
{
|
{
|
||||||
g = 0.0D;
|
g = 0.0D;
|
||||||
@@ -51,16 +51,16 @@ public class SimplexNoiseSampler extends PerlinNoiseSampler
|
|||||||
{
|
{
|
||||||
x = x / 2;
|
x = x / 2;
|
||||||
y = y / 2;
|
y = y / 2;
|
||||||
final double d = (x + y) * SKEW_FACTOR_2D;
|
double d = (x + y) * SKEW_FACTOR_2D;
|
||||||
final int i = PerlinNoiseSampler.floor(x + d);
|
int i = PerlinNoiseSampler.floor(x + d);
|
||||||
final int j = PerlinNoiseSampler.floor(y + d);
|
int j = PerlinNoiseSampler.floor(y + d);
|
||||||
final double e = (i + j) * UNSKEW_FACTOR_2D;
|
double e = (i + j) * UNSKEW_FACTOR_2D;
|
||||||
final double f = i - e;
|
double f = i - e;
|
||||||
final double g = j - e;
|
double g = j - e;
|
||||||
final double h = x - f;
|
double h = x - f;
|
||||||
final double k = y - g;
|
double k = y - g;
|
||||||
final byte n;
|
byte n;
|
||||||
final byte o;
|
byte o;
|
||||||
if (h > k)
|
if (h > k)
|
||||||
{
|
{
|
||||||
n = 1;
|
n = 1;
|
||||||
@@ -72,18 +72,18 @@ public class SimplexNoiseSampler extends PerlinNoiseSampler
|
|||||||
o = 1;
|
o = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
final double p = h - n + UNSKEW_FACTOR_2D;
|
double p = h - n + UNSKEW_FACTOR_2D;
|
||||||
final double q = k - o + UNSKEW_FACTOR_2D;
|
double q = k - o + UNSKEW_FACTOR_2D;
|
||||||
final double r = h - 1.0D + 2.0D * UNSKEW_FACTOR_2D;
|
double r = h - 1.0D + 2.0D * UNSKEW_FACTOR_2D;
|
||||||
final double s = k - 1.0D + 2.0D * UNSKEW_FACTOR_2D;
|
double s = k - 1.0D + 2.0D * UNSKEW_FACTOR_2D;
|
||||||
final int t = i & 255;
|
int t = i & 255;
|
||||||
final int u = j & 255;
|
int u = j & 255;
|
||||||
final int v = this.getGradient(t + this.getGradient(u)) % 12;
|
int v = this.getGradient(t + this.getGradient(u)) % 12;
|
||||||
final int w = this.getGradient(t + n + this.getGradient(u + o)) % 12;
|
int w = this.getGradient(t + n + this.getGradient(u + o)) % 12;
|
||||||
final int z = this.getGradient(t + 1 + this.getGradient(u + 1)) % 12;
|
int z = this.getGradient(t + 1 + this.getGradient(u + 1)) % 12;
|
||||||
final double aa = this.grad(v, h, k, 0.0D, 0.5D);
|
double aa = this.grad(v, h, k, 0.0D, 0.5D);
|
||||||
final double ab = this.grad(w, p, q, 0.0D, 0.5D);
|
double ab = this.grad(w, p, q, 0.0D, 0.5D);
|
||||||
final double ac = this.grad(z, r, s, 0.0D, 0.5D);
|
double ac = this.grad(z, r, s, 0.0D, 0.5D);
|
||||||
//return 70.0D * (aa + ab + ac);
|
//return 70.0D * (aa + ab + ac);
|
||||||
return 35.0D * (aa + ab + ac) + 0.5;
|
return 35.0D * (aa + ab + ac) + 0.5;
|
||||||
}
|
}
|
||||||
@@ -95,24 +95,24 @@ public class SimplexNoiseSampler extends PerlinNoiseSampler
|
|||||||
e = e / 2;
|
e = e / 2;
|
||||||
f = f / 2;
|
f = f / 2;
|
||||||
//final double g = 0.3333333333333333D;
|
//final double g = 0.3333333333333333D;
|
||||||
final double h = (d + e + f) * 0.3333333333333333D;
|
double h = (d + e + f) * 0.3333333333333333D;
|
||||||
final int i = floor(d + h);
|
int i = floor(d + h);
|
||||||
final int j = floor(e + h);
|
int j = floor(e + h);
|
||||||
final int k = floor(f + h);
|
int k = floor(f + h);
|
||||||
//final double l = 0.16666666666666666D;
|
//final double l = 0.16666666666666666D;
|
||||||
final double m = (i + j + k) * 0.16666666666666666D;
|
double m = (i + j + k) * 0.16666666666666666D;
|
||||||
final double n = i - m;
|
double n = i - m;
|
||||||
final double o = j - m;
|
double o = j - m;
|
||||||
final double p = k - m;
|
double p = k - m;
|
||||||
final double q = d - n;
|
double q = d - n;
|
||||||
final double r = e - o;
|
double r = e - o;
|
||||||
final double s = f - p;
|
double s = f - p;
|
||||||
final byte z;
|
byte z;
|
||||||
final byte aa;
|
byte aa;
|
||||||
final byte ab;
|
byte ab;
|
||||||
final byte ac;
|
byte ac;
|
||||||
final byte ad;
|
byte ad;
|
||||||
final byte bc;
|
byte bc;
|
||||||
if (q >= r)
|
if (q >= r)
|
||||||
{
|
{
|
||||||
if (r >= s)
|
if (r >= s)
|
||||||
@@ -171,26 +171,26 @@ public class SimplexNoiseSampler extends PerlinNoiseSampler
|
|||||||
bc = 0;
|
bc = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
final double bd = q - z + 0.16666666666666666D;
|
double bd = q - z + 0.16666666666666666D;
|
||||||
final double be = r - aa + 0.16666666666666666D;
|
double be = r - aa + 0.16666666666666666D;
|
||||||
final double bf = s - ab + 0.16666666666666666D;
|
double bf = s - ab + 0.16666666666666666D;
|
||||||
final double bg = q - ac + 0.3333333333333333D;
|
double bg = q - ac + 0.3333333333333333D;
|
||||||
final double bh = r - ad + 0.3333333333333333D;
|
double bh = r - ad + 0.3333333333333333D;
|
||||||
final double bi = s - bc + 0.3333333333333333D;
|
double bi = s - bc + 0.3333333333333333D;
|
||||||
final double bj = q - 1.0D + 0.5D;
|
double bj = q - 1.0D + 0.5D;
|
||||||
final double bk = r - 1.0D + 0.5D;
|
double bk = r - 1.0D + 0.5D;
|
||||||
final double bl = s - 1.0D + 0.5D;
|
double bl = s - 1.0D + 0.5D;
|
||||||
final int bm = i & 255;
|
int bm = i & 255;
|
||||||
final int bn = j & 255;
|
int bn = j & 255;
|
||||||
final int bo = k & 255;
|
int bo = k & 255;
|
||||||
final int bp = this.getGradient(bm + this.getGradient(bn + this.getGradient(bo))) % 12;
|
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;
|
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;
|
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;
|
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);
|
double bt = this.grad(bp, q, r, s, 0.6D);
|
||||||
final double bu = this.grad(bq, bd, be, bf, 0.6D);
|
double bu = this.grad(bq, bd, be, bf, 0.6D);
|
||||||
final double bv = this.grad(br, bg, bh, bi, 0.6D);
|
double bv = this.grad(br, bg, bh, bi, 0.6D);
|
||||||
final double bw = this.grad(bs, bj, bk, bl, 0.6D);
|
double bw = this.grad(bs, bj, bk, bl, 0.6D);
|
||||||
return 16.0D * (bt + bu + bv + bw) + 0.5;
|
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 List<Component> chatOutput;
|
||||||
private final CommandSigningContext signingContext;
|
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()),
|
super(CommandSource.NULL, original.getPosition(), original.getRotation(), original.getLevel(), Vanilla.MinecraftServer_getRunPermissionLevel(original.getServer()),
|
||||||
original.getTextName(), original.getDisplayName(), original.getServer(), original.getEntity(), false,
|
original.getTextName(), original.getDisplayName(), original.getServer(), original.getEntity(), false,
|
||||||
@@ -63,7 +63,7 @@ public class SnoopyCommandSource extends CommandSourceStack
|
|||||||
this.signingContext = original.getSigningContext();
|
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(),
|
super(player, player.position(), player.getRotationVector(),
|
||||||
player.level instanceof final ServerLevel serverLevel ? serverLevel : null,
|
player.level instanceof final ServerLevel serverLevel ? serverLevel : null,
|
||||||
@@ -86,8 +86,8 @@ public class SnoopyCommandSource extends CommandSourceStack
|
|||||||
this.signingContext = CommandSigningContext.ANONYMOUS;
|
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,
|
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,
|
||||||
final Component[] error, final List<Component> chatOutput
|
Component[] error, List<Component> chatOutput
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
super(output, pos, rot, world, level,
|
super(output, pos, rot, world, level,
|
||||||
@@ -110,33 +110,33 @@ public class SnoopyCommandSource extends CommandSourceStack
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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);
|
return new SnoopyCommandSource(output, position, rotation, world, level, entity.getName().getString(), entity.getDisplayName(), server, entity, resultConsumer, entityAnchor, signingContext, error, chatOutput);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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);
|
return new SnoopyCommandSource(output, position, rotation, world, level, simpleName, name, server, entity, resultConsumer, entityAnchor, signingContext, error, chatOutput);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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);
|
return new SnoopyCommandSource(output, position, rotation, world, level, simpleName, name, server, entity, resultConsumer, entityAnchor, signingContext, error, chatOutput);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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);
|
return new SnoopyCommandSource(output, position, rotation, world, level, simpleName, name, server, entity, consumer, entityAnchor, signingContext, error, chatOutput);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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);
|
return this.withCallback(resultConsumer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -145,58 +145,58 @@ public class SnoopyCommandSource extends CommandSourceStack
|
|||||||
//public ServerCommandSource withSilent() { return this; }
|
//public ServerCommandSource withSilent() { return this; }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CommandSourceStack withPermission(final int level)
|
public CommandSourceStack withPermission(int level)
|
||||||
{
|
{
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CommandSourceStack withMaximumPermission(final int level)
|
public CommandSourceStack withMaximumPermission(int level)
|
||||||
{
|
{
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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);
|
return new SnoopyCommandSource(output, position, rotation, world, level, simpleName, name, server, entity, resultConsumer, anchor, signingContext, error, chatOutput);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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);
|
return new SnoopyCommandSource(output, position, rotation, world, level, simpleName, name, server, entity, resultConsumer, entityAnchor, commandSigningContext, error, chatOutput);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CommandSourceStack withLevel(final ServerLevel world)
|
public CommandSourceStack withLevel(ServerLevel world)
|
||||||
{
|
{
|
||||||
final double d = DimensionType.getTeleportationScale(this.world.dimensionType(), world.dimensionType());
|
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);
|
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);
|
return new SnoopyCommandSource(output, position, rotation, world, level, simpleName, name, server, entity, resultConsumer, entityAnchor, signingContext, error, chatOutput);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CommandSourceStack facing(final Vec3 position)
|
public CommandSourceStack facing(Vec3 position)
|
||||||
{
|
{
|
||||||
final Vec3 vec3d = this.entityAnchor.apply(this);
|
Vec3 vec3d = this.entityAnchor.apply(this);
|
||||||
final double d = position.x - vec3d.x;
|
double d = position.x - vec3d.x;
|
||||||
final double e = position.y - vec3d.y;
|
double e = position.y - vec3d.y;
|
||||||
final double f = position.z - vec3d.z;
|
double f = position.z - vec3d.z;
|
||||||
final double g = Math.sqrt(d * d + f * f);
|
double g = Math.sqrt(d * d + f * f);
|
||||||
final float h = Mth.wrapDegrees((float) (-(Mth.atan2(e, g) * 57.2957763671875D)));
|
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);
|
float i = Mth.wrapDegrees((float) (Mth.atan2(f, d) * 57.2957763671875D) - 90.0F);
|
||||||
return this.withRotation(new Vec2(h, i));
|
return this.withRotation(new Vec2(h, i));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendFailure(final Component message)
|
public void sendFailure(Component message)
|
||||||
{
|
{
|
||||||
error[0] = message;
|
error[0] = message;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendSuccess(final Component message, final boolean broadcastToOps)
|
public void sendSuccess(Component message, boolean broadcastToOps)
|
||||||
{
|
{
|
||||||
chatOutput.add(message);
|
chatOutput.add(message);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ public class SystemInfo
|
|||||||
{{
|
{{
|
||||||
put("app_name", c ->
|
put("app_name", c ->
|
||||||
{
|
{
|
||||||
final String name = c.host.getName();
|
String name = c.host.getName();
|
||||||
return name == null ? Value.NULL : new StringValue(name);
|
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)));
|
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("server_motd", c -> StringValue.of(c.server().getMotd()));
|
||||||
put("world_path", c -> StringValue.of(c.server().getWorldPath(LevelResource.ROOT).toString()));
|
put("world_path", c -> StringValue.of(c.server().getWorldPath(LevelResource.ROOT).toString()));
|
||||||
put("world_folder", c -> {
|
put("world_folder", c -> {
|
||||||
final Path serverPath = c.server().getWorldPath(LevelResource.ROOT);
|
Path serverPath = c.server().getWorldPath(LevelResource.ROOT);
|
||||||
final int nodeCount = serverPath.getNameCount();
|
int nodeCount = serverPath.getNameCount();
|
||||||
if (nodeCount < 2)
|
if (nodeCount < 2)
|
||||||
{
|
{
|
||||||
return Value.NULL;
|
return Value.NULL;
|
||||||
}
|
}
|
||||||
final String tlf = serverPath.getName(nodeCount - 2).toString();
|
String tlf = serverPath.getName(nodeCount - 2).toString();
|
||||||
return StringValue.of(tlf);
|
return StringValue.of(tlf);
|
||||||
});
|
});
|
||||||
put("world_dimensions", c -> ListValue.wrap(c.server().levelKeys().stream().map(k -> ValueConversions.of(k.location()))));
|
put("world_dimensions", c -> ListValue.wrap(c.server().levelKeys().stream().map(k -> ValueConversions.of(k.location()))));
|
||||||
put("world_spawn_point", c -> {
|
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()));
|
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_top", c -> new NumericValue(c.level().getMaxBuildHeight()));
|
||||||
|
|
||||||
put("world_center", c -> {
|
put("world_center", c -> {
|
||||||
final WorldBorder worldBorder = c.level().getWorldBorder();
|
WorldBorder worldBorder = c.level().getWorldBorder();
|
||||||
return ListValue.fromTriple(worldBorder.getCenterX(), 0, worldBorder.getCenterZ());
|
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_target", c -> StringValue.of(Vanilla.MinecraftServer_getReleaseTarget(c.server())));
|
||||||
put("game_protocol", c -> NumericValue.of(SharedConstants.getProtocolVersion()));
|
put("game_protocol", c -> NumericValue.of(SharedConstants.getProtocolVersion()));
|
||||||
put("game_major_target", c -> {
|
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);
|
return NumericValue.of((vers.length > 1) ? Integer.parseInt(vers[1]) : 0);
|
||||||
});
|
});
|
||||||
put("game_minor_target", c -> {
|
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);
|
return NumericValue.of((vers.length > 2) ? Integer.parseInt(vers[2]) : 0);
|
||||||
});
|
});
|
||||||
put("game_stable", c -> BooleanValue.of(SharedConstants.getCurrentVersion().isStable()));
|
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_ip", c -> StringValue.of(c.server().getLocalIp()));
|
||||||
put("server_whitelisted", c -> BooleanValue.of(c.server().isEnforceWhitelist()));
|
put("server_whitelisted", c -> BooleanValue.of(c.server().isEnforceWhitelist()));
|
||||||
put("server_whitelist", c -> {
|
put("server_whitelist", c -> {
|
||||||
final MapValue whitelist = new MapValue(Collections.emptyList());
|
MapValue whitelist = new MapValue(Collections.emptyList());
|
||||||
for (final String s : c.server().getPlayerList().getWhiteListNames())
|
for (String s : c.server().getPlayerList().getWhiteListNames())
|
||||||
{
|
{
|
||||||
whitelist.append(StringValue.of(s));
|
whitelist.append(StringValue.of(s));
|
||||||
}
|
}
|
||||||
return whitelist;
|
return whitelist;
|
||||||
});
|
});
|
||||||
put("server_banned_players", c -> {
|
put("server_banned_players", c -> {
|
||||||
final MapValue whitelist = new MapValue(Collections.emptyList());
|
MapValue whitelist = new MapValue(Collections.emptyList());
|
||||||
for (final String s : c.server().getPlayerList().getBans().getUserList())
|
for (String s : c.server().getPlayerList().getBans().getUserList())
|
||||||
{
|
{
|
||||||
whitelist.append(StringValue.of(s));
|
whitelist.append(StringValue.of(s));
|
||||||
}
|
}
|
||||||
return whitelist;
|
return whitelist;
|
||||||
});
|
});
|
||||||
put("server_banned_ips", c -> {
|
put("server_banned_ips", c -> {
|
||||||
final MapValue whitelist = new MapValue(Collections.emptyList());
|
MapValue whitelist = new MapValue(Collections.emptyList());
|
||||||
for (final String s : c.server().getPlayerList().getIpBans().getUserList())
|
for (String s : c.server().getPlayerList().getIpBans().getUserList())
|
||||||
{
|
{
|
||||||
whitelist.append(StringValue.of(s));
|
whitelist.append(StringValue.of(s));
|
||||||
}
|
}
|
||||||
@@ -132,9 +132,9 @@ public class SystemInfo
|
|||||||
put("server_last_tick_times", c -> {
|
put("server_last_tick_times", c -> {
|
||||||
//assuming we are in the tick world section
|
//assuming we are in the tick world section
|
||||||
// might be off one tick when run in the off tasks or asynchronously.
|
// might be off one tick when run in the off tasks or asynchronously.
|
||||||
final int currentReportedTick = c.server().getTickCount() - 1;
|
int currentReportedTick = c.server().getTickCount() - 1;
|
||||||
final List<Value> ticks = new ArrayList<>(100);
|
List<Value> ticks = new ArrayList<>(100);
|
||||||
final long[] tickArray = c.server().tickTimes;
|
long[] tickArray = c.server().tickTimes;
|
||||||
for (int i = currentReportedTick + 100; i > currentReportedTick; i--)
|
for (int i = currentReportedTick + 100; i > currentReportedTick; i--)
|
||||||
{
|
{
|
||||||
ticks.add(new NumericValue((tickArray[i % 100]) / 1000000.0));
|
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_cpu_count", c -> new NumericValue(Runtime.getRuntime().availableProcessors()));
|
||||||
put("java_version", c -> StringValue.of(System.getProperty("java.version")));
|
put("java_version", c -> StringValue.of(System.getProperty("java.version")));
|
||||||
put("java_bits", c -> {
|
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"))
|
if (value != null && value.contains("64"))
|
||||||
{
|
{
|
||||||
return new NumericValue(64);
|
return new NumericValue(64);
|
||||||
@@ -159,23 +159,23 @@ public class SystemInfo
|
|||||||
return new NumericValue(32);
|
return new NumericValue(32);
|
||||||
});
|
});
|
||||||
put("java_system_cpu_load", c -> {
|
put("java_system_cpu_load", c -> {
|
||||||
final OperatingSystemMXBean osBean = ManagementFactory.getPlatformMXBean(
|
OperatingSystemMXBean osBean = ManagementFactory.getPlatformMXBean(
|
||||||
OperatingSystemMXBean.class);
|
OperatingSystemMXBean.class);
|
||||||
return new NumericValue(osBean.getCpuLoad());
|
return new NumericValue(osBean.getCpuLoad());
|
||||||
});
|
});
|
||||||
put("java_process_cpu_load", c -> {
|
put("java_process_cpu_load", c -> {
|
||||||
final OperatingSystemMXBean osBean = ManagementFactory.getPlatformMXBean(
|
OperatingSystemMXBean osBean = ManagementFactory.getPlatformMXBean(
|
||||||
OperatingSystemMXBean.class);
|
OperatingSystemMXBean.class);
|
||||||
return new NumericValue(osBean.getProcessCpuLoad());
|
return new NumericValue(osBean.getProcessCpuLoad());
|
||||||
});
|
});
|
||||||
put("world_carpet_rules", c -> Carpet.getAllCarpetRules());
|
put("world_carpet_rules", c -> Carpet.getAllCarpetRules());
|
||||||
put("world_gamerules", c -> {
|
put("world_gamerules", c -> {
|
||||||
final Map<Value, Value> rules = new HashMap<>();
|
Map<Value, Value> rules = new HashMap<>();
|
||||||
final GameRules gameRules = c.level().getGameRules();
|
GameRules gameRules = c.level().getGameRules();
|
||||||
GameRules.visitGameRuleTypes(new GameRules.GameRuleTypeVisitor()
|
GameRules.visitGameRuleTypes(new GameRules.GameRuleTypeVisitor()
|
||||||
{
|
{
|
||||||
@Override
|
@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()));
|
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_position", c -> ValueConversions.of(c.source().getPosition()));
|
||||||
put("source_dimension", c -> ValueConversions.of(c.level()));
|
put("source_dimension", c -> ValueConversions.of(c.level()));
|
||||||
put("source_rotation", c -> {
|
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));
|
return ListValue.of(new NumericValue(rotation.x), new NumericValue(rotation.y));
|
||||||
});
|
});
|
||||||
put("scarpet_version", c -> StringValue.of(Carpet.getCarpetVersion()));
|
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);
|
return options.getOrDefault(what, c -> null).apply(cc);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,45 +14,45 @@ import net.minecraft.world.phys.Vec3;
|
|||||||
|
|
||||||
public class Tracer
|
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;
|
double maxSqDist = reach * reach;
|
||||||
if (blockHit != null)
|
if (blockHit != null)
|
||||||
{
|
{
|
||||||
maxSqDist = blockHit.getLocation().distanceToSqr(source.getEyePosition(partialTicks));
|
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;
|
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);
|
Vec3 pos = source.getEyePosition(partialTicks);
|
||||||
final Vec3 rotation = source.getViewVector(partialTicks);
|
Vec3 rotation = source.getViewVector(partialTicks);
|
||||||
final Vec3 reachEnd = pos.add(rotation.x * reach, rotation.y * reach, rotation.z * reach);
|
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 ?
|
return source.level.clip(new ClipContext(pos, reachEnd, ClipContext.Block.OUTLINE, fluids ?
|
||||||
ClipContext.Fluid.ANY : ClipContext.Fluid.NONE, source));
|
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);
|
Vec3 pos = source.getEyePosition(partialTicks);
|
||||||
final Vec3 reachVec = source.getViewVector(partialTicks).scale(reach);
|
Vec3 reachVec = source.getViewVector(partialTicks).scale(reach);
|
||||||
final AABB box = source.getBoundingBox().expandTowards(reachVec).inflate(1);
|
AABB box = source.getBoundingBox().expandTowards(reachVec).inflate(1);
|
||||||
return rayTraceEntities(source, pos, pos.add(reachVec), box, e -> !e.isSpectator() && e.isPickable(), maxSqDist);
|
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;
|
double targetDistance = maxSqDistance;
|
||||||
Entity target = null;
|
Entity target = null;
|
||||||
Vec3 targetHitPos = 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());
|
AABB currentBox = current.getBoundingBox().inflate(current.getPickRadius());
|
||||||
final Optional<Vec3> currentHit = currentBox.clip(start, end);
|
Optional<Vec3> currentHit = currentBox.clip(start, end);
|
||||||
if (currentBox.contains(start))
|
if (currentBox.contains(start))
|
||||||
{
|
{
|
||||||
if (targetDistance >= 0)
|
if (targetDistance >= 0)
|
||||||
@@ -64,8 +64,8 @@ public class Tracer
|
|||||||
}
|
}
|
||||||
else if (currentHit.isPresent())
|
else if (currentHit.isPresent())
|
||||||
{
|
{
|
||||||
final Vec3 currentHitPos = currentHit.get();
|
Vec3 currentHitPos = currentHit.get();
|
||||||
final double currentDistance = start.distanceToSqr(currentHitPos);
|
double currentDistance = start.distanceToSqr(currentHitPos);
|
||||||
if (currentDistance < targetDistance || targetDistance == 0)
|
if (currentDistance < targetDistance || targetDistance == 0)
|
||||||
{
|
{
|
||||||
if (current.getRootVehicle() == source.getRootVehicle())
|
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.DerivedLevelData;
|
||||||
import net.minecraft.world.level.storage.ServerLevelData;
|
import net.minecraft.world.level.storage.ServerLevelData;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -44,24 +45,24 @@ import java.util.Set;
|
|||||||
public class WorldTools
|
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)
|
if (world.getChunk(chpos.x, chpos.z, ChunkStatus.STRUCTURE_STARTS, false) != null)
|
||||||
{
|
{
|
||||||
return true;
|
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))
|
if (regionCache != null && regionCache.containsKey(currentRegionName))
|
||||||
{
|
{
|
||||||
final RegionFile region = regionCache.get(currentRegionName);
|
RegionFile region = regionCache.get(currentRegionName);
|
||||||
if (region == null)
|
if (region == null)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return region.hasChunk(chpos);
|
return region.hasChunk(chpos);
|
||||||
}
|
}
|
||||||
final Path regionsFolder = Vanilla.MinecraftServer_storageSource(world.getServer()).getDimensionPath(world.dimension()).resolve("region");
|
Path regionsFolder = Vanilla.MinecraftServer_storageSource(world.getServer()).getDimensionPath(world.dimension()).resolve("region");
|
||||||
final Path regionPath = regionsFolder.resolve(currentRegionName);
|
Path regionPath = regionsFolder.resolve(currentRegionName);
|
||||||
if (!regionPath.toFile().exists())
|
if (!regionPath.toFile().exists())
|
||||||
{
|
{
|
||||||
if (regionCache != null)
|
if (regionCache != null)
|
||||||
@@ -76,14 +77,14 @@ public class WorldTools
|
|||||||
}
|
}
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
final RegionFile region = new RegionFile(regionPath, regionsFolder, true);
|
RegionFile region = new RegionFile(regionPath, regionsFolder, true);
|
||||||
if (regionCache != null)
|
if (regionCache != null)
|
||||||
{
|
{
|
||||||
regionCache.put(currentRegionName, region);
|
regionCache.put(currentRegionName, region);
|
||||||
}
|
}
|
||||||
return region.hasChunk(chpos);
|
return region.hasChunk(chpos);
|
||||||
}
|
}
|
||||||
catch (final IOException ignored)
|
catch (IOException ignored)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -155,16 +156,16 @@ public class WorldTools
|
|||||||
return true;
|
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);
|
ChunkPos chunkPos = new ChunkPos(pos);
|
||||||
final LevelChunk worldChunk = world.getChunkSource().getChunk(chunkPos.x, chunkPos.z, false);
|
LevelChunk worldChunk = world.getChunkSource().getChunk(chunkPos.x, chunkPos.z, false);
|
||||||
if (worldChunk != null)
|
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())
|
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));
|
players.forEach(p -> p.connection.send(packet));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import com.mojang.math.Axis;
|
|||||||
import net.minecraft.client.Camera;
|
import net.minecraft.client.Camera;
|
||||||
import net.minecraft.world.phys.Vec3;
|
import net.minecraft.world.phys.Vec3;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
public enum ShapeDirection
|
public enum ShapeDirection
|
||||||
@@ -18,7 +19,8 @@ public enum ShapeDirection
|
|||||||
CAMERA,
|
CAMERA,
|
||||||
PLAYER;
|
PLAYER;
|
||||||
|
|
||||||
public static ShapeDirection fromString(final String direction)
|
@Nullable
|
||||||
|
public static ShapeDirection fromString(String direction)
|
||||||
{
|
{
|
||||||
return switch (direction.toLowerCase(Locale.ROOT))
|
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)
|
switch (shapeDirection)
|
||||||
{
|
{
|
||||||
@@ -46,13 +48,13 @@ public enum ShapeDirection
|
|||||||
case DOWN -> poseStack.mulPose(Axis.XP.rotationDegrees(-90));
|
case DOWN -> poseStack.mulPose(Axis.XP.rotationDegrees(-90));
|
||||||
case CAMERA -> poseStack.mulPose(camera.rotation());
|
case CAMERA -> poseStack.mulPose(camera.rotation());
|
||||||
case PLAYER -> {
|
case PLAYER -> {
|
||||||
final Vec3 vector = objectPos.subtract(camera.getPosition());
|
Vec3 vector = objectPos.subtract(camera.getPosition());
|
||||||
final double x = vector.x;
|
double x = vector.x;
|
||||||
final double y = vector.y;
|
double y = vector.y;
|
||||||
final double z = vector.z;
|
double z = vector.z;
|
||||||
final double d = Math.sqrt(x * x + z * z);
|
double d = Math.sqrt(x * x + z * z);
|
||||||
final float rotX = (float) (Math.atan2(x, z));
|
float rotX = (float) (Math.atan2(x, z));
|
||||||
final float rotY = (float) (Math.atan2(y, d));
|
float rotY = (float) (Math.atan2(y, d));
|
||||||
|
|
||||||
// that should work somehow but it doesn't for some reason
|
// that should work somehow but it doesn't for some reason
|
||||||
//matrices.mulPose(new Quaternion( -rotY, rotX, 0, false));
|
//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()
|
public List<Value> unpack()
|
||||||
{
|
{
|
||||||
final List<Value> retVal = Lists.newArrayList(iterator());
|
List<Value> retVal = Lists.newArrayList(iterator());
|
||||||
fatality();
|
fatality();
|
||||||
return retVal;
|
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");
|
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.item.context.BlockPlaceContext;
|
||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.world.level.Level;
|
||||||
import net.minecraft.world.level.block.Block;
|
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.entity.BlockEntity;
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import net.minecraft.world.level.block.state.properties.Property;
|
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.BlockHitResult;
|
||||||
import net.minecraft.world.phys.Vec3;
|
import net.minecraft.world.phys.Vec3;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
import static carpet.script.value.NBTSerializableValue.nameFromRegistryId;
|
import static carpet.script.value.NBTSerializableValue.nameFromRegistryId;
|
||||||
|
import static carpet.script.value.NBTSerializableValue.nameFromResource;
|
||||||
|
|
||||||
public class BlockValue extends Value
|
public class BlockValue extends Value
|
||||||
{
|
{
|
||||||
private BlockState blockState;
|
private BlockState blockState;
|
||||||
private final BlockPos pos;
|
private final BlockPos pos;
|
||||||
private final Level world;
|
private final ServerLevel world;
|
||||||
private CompoundTag data;
|
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);
|
return new BlockValue(null, c.level(), pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final Map<String, BlockValue> bvCache = new HashMap<>();
|
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
|
try
|
||||||
{
|
{
|
||||||
@@ -64,7 +71,7 @@ public class BlockValue extends Value
|
|||||||
{
|
{
|
||||||
return bv;
|
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)
|
if (foo.blockState() != null)
|
||||||
{
|
{
|
||||||
CompoundTag bd = foo.nbt();
|
CompoundTag bd = foo.nbt();
|
||||||
@@ -81,15 +88,15 @@ public class BlockValue extends Value
|
|||||||
return bv;
|
return bv;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (final CommandSyntaxException ignored)
|
catch (CommandSyntaxException ignored)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
throw new ThrowStatement(str, Throwables.UNKNOWN_BLOCK);
|
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);
|
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");
|
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)
|
if (level instanceof final ServerLevel serverLevel)
|
||||||
{
|
{
|
||||||
@@ -127,7 +134,7 @@ public class BlockValue extends Value
|
|||||||
}
|
}
|
||||||
if (pos != null)
|
if (pos != null)
|
||||||
{
|
{
|
||||||
final BlockEntity be = getBlockEntity(world, pos);
|
BlockEntity be = getBlockEntity(world, pos);
|
||||||
if (be == null)
|
if (be == null)
|
||||||
{
|
{
|
||||||
data = new CompoundTag();
|
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;
|
this.world = world;
|
||||||
blockState = state;
|
blockState = state;
|
||||||
@@ -148,7 +155,39 @@ public class BlockValue extends Value
|
|||||||
data = null;
|
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;
|
this.world = world;
|
||||||
blockState = state;
|
blockState = state;
|
||||||
@@ -160,8 +199,8 @@ public class BlockValue extends Value
|
|||||||
@Override
|
@Override
|
||||||
public String getString()
|
public String getString()
|
||||||
{
|
{
|
||||||
final Registry<Block> blockRegistry = world.registryAccess().registryOrThrow(Registries.BLOCK);
|
Registry<Block> blockRegistry = world.registryAccess().registryOrThrow(Registries.BLOCK);
|
||||||
return nameFromRegistryId(blockRegistry.getKey(getBlockState().getBlock()));
|
return nameFromResource(blockRegistry.getKey(getBlockState().getBlock()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -201,29 +240,29 @@ public class BlockValue extends Value
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Tag toTag(final boolean force)
|
public Tag toTag(boolean force)
|
||||||
{
|
{
|
||||||
if (!force)
|
if (!force)
|
||||||
{
|
{
|
||||||
throw new NBTSerializableValue.IncompatibleTypeException(this);
|
throw new NBTSerializableValue.IncompatibleTypeException(this);
|
||||||
}
|
}
|
||||||
// follows falling block convertion
|
// follows falling block convertion
|
||||||
final CompoundTag tag = new CompoundTag();
|
CompoundTag tag = new CompoundTag();
|
||||||
final CompoundTag state = new CompoundTag();
|
CompoundTag state = new CompoundTag();
|
||||||
final BlockState s = getBlockState();
|
BlockState s = getBlockState();
|
||||||
state.put("Name", StringTag.valueOf(world.registryAccess().registryOrThrow(Registries.BLOCK).getKey(s.getBlock()).toString()));
|
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())
|
if (!properties.isEmpty())
|
||||||
{
|
{
|
||||||
final CompoundTag props = new CompoundTag();
|
CompoundTag props = new CompoundTag();
|
||||||
for (final Property<?> p : properties)
|
for (Property<?> p : properties)
|
||||||
{
|
{
|
||||||
props.put(p.getName(), StringTag.valueOf(s.getValue(p).toString().toLowerCase(Locale.ROOT)));
|
props.put(p.getName(), StringTag.valueOf(s.getValue(p).toString().toLowerCase(Locale.ROOT)));
|
||||||
}
|
}
|
||||||
state.put("Properties", props);
|
state.put("Properties", props);
|
||||||
}
|
}
|
||||||
tag.put("BlockState", state);
|
tag.put("BlockState", state);
|
||||||
final CompoundTag dataTag = getData();
|
CompoundTag dataTag = getData();
|
||||||
if (dataTag != null)
|
if (dataTag != null)
|
||||||
{
|
{
|
||||||
tag.put("TileEntityData", dataTag);
|
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));
|
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.name = name;
|
||||||
this.hitOffset = new Vec3(hitx, hity, hitz);
|
this.hitOffset = new Vec3(hitx, hity, hitz);
|
||||||
@@ -283,18 +322,18 @@ public class BlockValue extends Value
|
|||||||
private final Direction facing;
|
private final Direction facing;
|
||||||
private final boolean sneakPlace;
|
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)
|
if (dir == null)
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("unknown block placement direction: " + direction);
|
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);
|
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);
|
super(world_1, null, InteractionHand.MAIN_HAND, itemStack_1, hitres);
|
||||||
this.facing = direction_1;
|
this.facing = direction_1;
|
||||||
@@ -304,9 +343,9 @@ public class BlockValue extends Value
|
|||||||
@Override
|
@Override
|
||||||
public BlockPos getClickedPos()
|
public BlockPos getClickedPos()
|
||||||
{
|
{
|
||||||
final boolean prevcanReplaceExisting = replaceClicked;
|
boolean prevcanReplaceExisting = replaceClicked;
|
||||||
replaceClicked = true;
|
replaceClicked = true;
|
||||||
final BlockPos ret = super.getClickedPos();
|
BlockPos ret = super.getClickedPos();
|
||||||
replaceClicked = prevcanReplaceExisting;
|
replaceClicked = prevcanReplaceExisting;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,13 +12,13 @@ public class BooleanValue extends NumericValue
|
|||||||
|
|
||||||
boolean boolValue;
|
boolean boolValue;
|
||||||
|
|
||||||
private BooleanValue(final boolean boolval)
|
private BooleanValue(boolean boolval)
|
||||||
{
|
{
|
||||||
super(boolval ? 1L : 0L);
|
super(boolval ? 1L : 0L);
|
||||||
boolValue = boolval;
|
boolValue = boolval;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static BooleanValue of(final boolean value)
|
public static BooleanValue of(boolean value)
|
||||||
{
|
{
|
||||||
return value ? TRUE : FALSE;
|
return value ? TRUE : FALSE;
|
||||||
}
|
}
|
||||||
@@ -54,7 +54,7 @@ public class BooleanValue extends NumericValue
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Tag toTag(final boolean force)
|
public Tag toTag(boolean force)
|
||||||
{
|
{
|
||||||
return ByteTag.valueOf(boolValue);
|
return ByteTag.valueOf(boolValue);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ public interface ContainerValueInterface
|
|||||||
{
|
{
|
||||||
boolean put(Value where, Value value);
|
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);
|
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.HitResult;
|
||||||
import net.minecraft.world.phys.Vec3;
|
import net.minecraft.world.phys.Vec3;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
@@ -97,19 +98,19 @@ public class EntityValue extends Value
|
|||||||
{
|
{
|
||||||
private Entity entity;
|
private Entity entity;
|
||||||
|
|
||||||
public EntityValue(final Entity e)
|
public EntityValue(Entity e)
|
||||||
{
|
{
|
||||||
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);
|
return e == null ? Value.NULL : new EntityValue(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final Map<String, EntitySelector> selectorCache = new HashMap<>();
|
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
|
try
|
||||||
{
|
{
|
||||||
@@ -122,7 +123,7 @@ public class EntityValue extends Value
|
|||||||
selectorCache.put(selector, entitySelector);
|
selectorCache.put(selector, entitySelector);
|
||||||
return entitySelector.findEntities(source.withMaximumPermission(4));
|
return entitySelector.findEntities(source.withMaximumPermission(4));
|
||||||
}
|
}
|
||||||
catch (final CommandSyntaxException e)
|
catch (CommandSyntaxException e)
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("Cannot select entities from " + selector);
|
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))
|
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)
|
if (newPlayer != null)
|
||||||
{
|
{
|
||||||
entity = newPlayer;
|
entity = newPlayer;
|
||||||
@@ -141,7 +142,7 @@ public class EntityValue extends Value
|
|||||||
return entity;
|
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)
|
if (value instanceof final EntityValue ev && ev.getEntity() instanceof final ServerPlayer sp)
|
||||||
{
|
{
|
||||||
@@ -151,11 +152,11 @@ public class EntityValue extends Value
|
|||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
final String playerName = value.getString();
|
String playerName = value.getString();
|
||||||
return server.getPlayerList().getPlayerByName(playerName);
|
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)
|
if (value instanceof final EntityValue ev && ev.getEntity() instanceof final ServerPlayer sp)
|
||||||
{
|
{
|
||||||
@@ -181,7 +182,7 @@ public class EntityValue extends Value
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(final Object v)
|
public boolean equals(Object v)
|
||||||
{
|
{
|
||||||
if (v instanceof final EntityValue ev)
|
if (v instanceof final EntityValue ev)
|
||||||
{
|
{
|
||||||
@@ -191,12 +192,12 @@ public class EntityValue extends Value
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Value in(final Value v)
|
public Value in(Value v)
|
||||||
{
|
{
|
||||||
if (v instanceof final ListValue lv)
|
if (v instanceof final ListValue lv)
|
||||||
{
|
{
|
||||||
final List<Value> values = lv.getItems();
|
List<Value> values = lv.getItems();
|
||||||
final String what = values.get(0).getString();
|
String what = values.get(0).getString();
|
||||||
Value arg = null;
|
Value arg = null;
|
||||||
if (values.size() == 2)
|
if (values.size() == 2)
|
||||||
{
|
{
|
||||||
@@ -208,7 +209,7 @@ public class EntityValue extends Value
|
|||||||
}
|
}
|
||||||
return this.get(what, arg);
|
return this.get(what, arg);
|
||||||
}
|
}
|
||||||
final String what = v.getString();
|
String what = v.getString();
|
||||||
return this.get(what, null);
|
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 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)
|
if (eDesc == null)
|
||||||
{
|
{
|
||||||
boolean positive = true;
|
boolean positive = true;
|
||||||
@@ -237,16 +238,16 @@ public class EntityValue extends Value
|
|||||||
positive = false;
|
positive = false;
|
||||||
who = who.substring(1);
|
who = who.substring(1);
|
||||||
}
|
}
|
||||||
final String booWho = who;
|
String booWho = who;
|
||||||
final HolderSet.Named<EntityType<?>> eTagValue = server.registryAccess().registryOrThrow(Registries.ENTITY_TYPE)
|
HolderSet.Named<EntityType<?>> eTagValue = server.registryAccess().registryOrThrow(Registries.ENTITY_TYPE)
|
||||||
.getTag(TagKey.create(Registries.ENTITY_TYPE, InputValidator.identifierOf(who)))
|
.getTag(TagKey.create(Registries.ENTITY_TYPE, InputValidator.identifierOf(who)))
|
||||||
.orElseThrow(() -> new InternalExpressionException(booWho + " is not a valid entity descriptor"));
|
.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 (positive)
|
||||||
{
|
{
|
||||||
if (eTag.size() == 1)
|
if (eTag.size() == 1)
|
||||||
{
|
{
|
||||||
final EntityType<?> type = eTag.iterator().next();
|
EntityType<?> type = eTag.iterator().next();
|
||||||
return new EntityClassDescriptor(type, Entity::isAlive, eTag.stream());
|
return new EntityClassDescriptor(type, Entity::isAlive, eTag.stream());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -270,36 +271,36 @@ public class EntityValue extends Value
|
|||||||
public final Predicate<? super Entity> filteringPredicate;
|
public final Predicate<? super Entity> filteringPredicate;
|
||||||
public final List<EntityType<? extends Entity>> types;
|
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.directType = type;
|
||||||
this.filteringPredicate = predicate;
|
this.filteringPredicate = predicate;
|
||||||
this.types = types;
|
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());
|
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);
|
Registry<EntityType<?>> entityRegs = regs.registryOrThrow(Registries.ENTITY_TYPE);
|
||||||
return ListValue.wrap(types.stream().map(et -> StringValue.of(nameFromRegistryId(entityRegs.getKey(et)))));
|
return ListValue.wrap(types.stream().map(et -> nameFromRegistryId(entityRegs.getKey(et))));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final Map<String, EntityClassDescriptor> byName = new HashMap<>()
|
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
|
// nonliving types
|
||||||
final Set<EntityType<?>> projectiles = Set.of(
|
Set<EntityType<?>> projectiles = Set.of(
|
||||||
EntityType.ARROW, EntityType.DRAGON_FIREBALL, EntityType.FIREWORK_ROCKET,
|
EntityType.ARROW, EntityType.DRAGON_FIREBALL, EntityType.FIREWORK_ROCKET,
|
||||||
EntityType.FIREBALL, EntityType.LLAMA_SPIT, EntityType.SMALL_FIREBALL,
|
EntityType.FIREBALL, EntityType.LLAMA_SPIT, EntityType.SMALL_FIREBALL,
|
||||||
EntityType.SNOWBALL, EntityType.SPECTRAL_ARROW, EntityType.EGG,
|
EntityType.SNOWBALL, EntityType.SPECTRAL_ARROW, EntityType.EGG,
|
||||||
EntityType.ENDER_PEARL, EntityType.EXPERIENCE_BOTTLE, EntityType.POTION,
|
EntityType.ENDER_PEARL, EntityType.EXPERIENCE_BOTTLE, EntityType.POTION,
|
||||||
EntityType.TRIDENT, EntityType.WITHER_SKULL, EntityType.FISHING_BOBBER, EntityType.SHULKER_BULLET
|
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.AREA_EFFECT_CLOUD, EntityType.MARKER, EntityType.BOAT, EntityType.END_CRYSTAL,
|
||||||
EntityType.EVOKER_FANGS, EntityType.EXPERIENCE_ORB, EntityType.EYE_OF_ENDER,
|
EntityType.EVOKER_FANGS, EntityType.EXPERIENCE_ORB, EntityType.EYE_OF_ENDER,
|
||||||
EntityType.FALLING_BLOCK, EntityType.ITEM, EntityType.ITEM_FRAME, EntityType.GLOW_ITEM_FRAME,
|
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
|
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.MINECART, EntityType.CHEST_MINECART, EntityType.COMMAND_BLOCK_MINECART,
|
||||||
EntityType.FURNACE_MINECART, EntityType.HOPPER_MINECART,
|
EntityType.FURNACE_MINECART, EntityType.HOPPER_MINECART,
|
||||||
EntityType.SPAWNER_MINECART, EntityType.TNT_MINECART
|
EntityType.SPAWNER_MINECART, EntityType.TNT_MINECART
|
||||||
);
|
);
|
||||||
// living mob groups - non-defeault
|
// living mob groups - non-defeault
|
||||||
final Set<EntityType<?>> undeads = Set.of(
|
Set<EntityType<?>> undeads = Set.of(
|
||||||
EntityType.STRAY, EntityType.SKELETON, EntityType.WITHER_SKELETON,
|
EntityType.STRAY, EntityType.SKELETON, EntityType.WITHER_SKELETON,
|
||||||
EntityType.ZOMBIE, EntityType.DROWNED, EntityType.ZOMBIE_VILLAGER,
|
EntityType.ZOMBIE, EntityType.DROWNED, EntityType.ZOMBIE_VILLAGER,
|
||||||
EntityType.ZOMBIE_HORSE, EntityType.SKELETON_HORSE, EntityType.PHANTOM,
|
EntityType.ZOMBIE_HORSE, EntityType.SKELETON_HORSE, EntityType.PHANTOM,
|
||||||
EntityType.WITHER, EntityType.ZOGLIN, EntityType.HUSK, EntityType.ZOMBIFIED_PIGLIN
|
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.BEE, EntityType.ENDERMITE, EntityType.SILVERFISH, EntityType.SPIDER,
|
||||||
EntityType.CAVE_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.GUARDIAN, EntityType.TURTLE, EntityType.COD, EntityType.DOLPHIN, EntityType.PUFFERFISH,
|
||||||
EntityType.SALMON, EntityType.SQUID, EntityType.TROPICAL_FISH
|
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.PILLAGER, EntityType.ILLUSIONER, EntityType.VINDICATOR, EntityType.EVOKER,
|
||||||
EntityType.RAVAGER, EntityType.WITCH
|
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)
|
!deads.contains(et) && !projectiles.contains(et) && !minecarts.contains(et)
|
||||||
).collect(Collectors.toSet());
|
).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)
|
living.contains(et) && !undeads.contains(et) && !arthropods.contains(et) && !aquatique.contains(et) && !illagers.contains(et)
|
||||||
).collect(Collectors.toSet());
|
).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(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))));
|
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);
|
EntityType<?> type = BuiltInRegistries.ENTITY_TYPE.get(typeId);
|
||||||
final String mobType = ValueConversions.simplify(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(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)));
|
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)));
|
||||||
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)))
|
if (!(featureAccessors.containsKey(what)))
|
||||||
{
|
{
|
||||||
@@ -399,7 +400,7 @@ public class EntityValue extends Value
|
|||||||
{
|
{
|
||||||
return featureAccessors.get(what).apply(getEntity(), arg);
|
return featureAccessors.get(what).apply(getEntity(), arg);
|
||||||
}
|
}
|
||||||
catch (final NullPointerException npe)
|
catch (NullPointerException npe)
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("Cannot fetch '" + what + "' with these arguments");
|
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("z", (e, a) -> new NumericValue(e.getZ()));
|
||||||
put("motion", (e, a) ->
|
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));
|
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));
|
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("display_name", (e, a) -> new FormattedTextValue(e.getDisplayName()));
|
||||||
put("command_name", (e, a) -> new StringValue(e.getScoreboardName()));
|
put("command_name", (e, a) -> new StringValue(e.getScoreboardName()));
|
||||||
put("custom_name", (e, a) -> e.hasCustomName() ? new StringValue(e.getCustomName().getString()) : Value.NULL);
|
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_riding", (e, a) -> BooleanValue.of(e.isPassenger()));
|
||||||
put("is_ridden", (e, a) -> BooleanValue.of(e.isVehicle()));
|
put("is_ridden", (e, a) -> BooleanValue.of(e.isVehicle()));
|
||||||
put("passengers", (e, a) -> ListValue.wrap(e.getPassengers().stream().map(EntityValue::new)));
|
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("scoreboard_tags", (e, a) -> ListValue.wrap(e.getTags().stream().map(StringValue::new)));
|
||||||
put("entity_tags", (e, a) -> {
|
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())));
|
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
|
// 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_scoreboard_tag", (e, a) -> BooleanValue.of(e.getTags().contains(a.getString())));
|
||||||
put("has_entity_tag", (e, a) -> {
|
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())
|
if (tag.isEmpty())
|
||||||
{
|
{
|
||||||
return Value.NULL;
|
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()));
|
//Tag<EntityType<?>> tag = e.getServer().getTags().getOrEmpty(Registry.ENTITY_TYPE_REGISTRY).getTag(InputValidator.identifierOf(a.getString()));
|
||||||
//if (tag == null) return Value.NULL;
|
//if (tag == null) return Value.NULL;
|
||||||
//return BooleanValue.of(e.getType().is(tag));
|
//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));
|
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("pitch", (e, a) -> new NumericValue(e.getXRot()));
|
||||||
put("look", (e, a) -> {
|
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));
|
return ListValue.of(new NumericValue(look.x), new NumericValue(look.y), new NumericValue(look.z));
|
||||||
});
|
});
|
||||||
put("is_burning", (e, a) -> BooleanValue.of(e.isOnFire()));
|
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("immune_to_frost", (e, a) -> BooleanValue.of(!e.canFreeze()));
|
||||||
|
|
||||||
put("invulnerable", (e, a) -> BooleanValue.of(e.isInvulnerable()));
|
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("height", (e, a) -> new NumericValue(e.getDimensions(Pose.STANDING).height));
|
||||||
put("width", (e, a) -> new NumericValue(e.getDimensions(Pose.STANDING).width));
|
put("width", (e, a) -> new NumericValue(e.getDimensions(Pose.STANDING).width));
|
||||||
put("eye_height", (e, a) -> new NumericValue(e.getEyeHeight()));
|
put("eye_height", (e, a) -> new NumericValue(e.getEyeHeight()));
|
||||||
@@ -507,7 +508,7 @@ public class EntityValue extends Value
|
|||||||
put("target", (e, a) -> {
|
put("target", (e, a) -> {
|
||||||
if (e instanceof final Mob mob)
|
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)
|
if (target != null)
|
||||||
{
|
{
|
||||||
return new EntityValue(target);
|
return new EntityValue(target);
|
||||||
@@ -515,7 +516,7 @@ public class EntityValue extends Value
|
|||||||
}
|
}
|
||||||
return Value.NULL;
|
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) -> {
|
put("spawn_point", (e, a) -> {
|
||||||
if (e instanceof final ServerPlayer spe)
|
if (e instanceof final ServerPlayer spe)
|
||||||
{
|
{
|
||||||
@@ -553,7 +554,7 @@ public class EntityValue extends Value
|
|||||||
put("path", (e, a) -> {
|
put("path", (e, a) -> {
|
||||||
if (e instanceof final Mob mob)
|
if (e instanceof final Mob mob)
|
||||||
{
|
{
|
||||||
final Path path = mob.getNavigation().getPath();
|
Path path = mob.getNavigation().getPath();
|
||||||
if (path == null)
|
if (path == null)
|
||||||
{
|
{
|
||||||
return Value.NULL;
|
return Value.NULL;
|
||||||
@@ -564,22 +565,22 @@ public class EntityValue extends Value
|
|||||||
});
|
});
|
||||||
|
|
||||||
put("brain", (e, a) -> {
|
put("brain", (e, a) -> {
|
||||||
final String module = a.getString();
|
String module = a.getString();
|
||||||
final MemoryModuleType<?> moduleType = e.getLevel().registryAccess().registryOrThrow(Registries.MEMORY_MODULE_TYPE).get(InputValidator.identifierOf(module));
|
MemoryModuleType<?> moduleType = e.getLevel().registryAccess().registryOrThrow(Registries.MEMORY_MODULE_TYPE).get(InputValidator.identifierOf(module));
|
||||||
if (moduleType == MemoryModuleType.DUMMY)
|
if (moduleType == MemoryModuleType.DUMMY)
|
||||||
{
|
{
|
||||||
return Value.NULL;
|
return Value.NULL;
|
||||||
}
|
}
|
||||||
if (e instanceof final LivingEntity livingEntity)
|
if (e instanceof final LivingEntity livingEntity)
|
||||||
{
|
{
|
||||||
final Brain<?> brain = livingEntity.getBrain();
|
Brain<?> brain = livingEntity.getBrain();
|
||||||
final Map<MemoryModuleType<?>, Optional<? extends ExpirableValue<?>>> memories = brain.getMemories();
|
Map<MemoryModuleType<?>, Optional<? extends ExpirableValue<?>>> memories = brain.getMemories();
|
||||||
final Optional<? extends ExpirableValue<?>> optmemory = memories.get(moduleType);
|
Optional<? extends ExpirableValue<?>> optmemory = memories.get(moduleType);
|
||||||
if (optmemory == null || !optmemory.isPresent())
|
if (optmemory == null || !optmemory.isPresent())
|
||||||
{
|
{
|
||||||
return Value.NULL;
|
return Value.NULL;
|
||||||
}
|
}
|
||||||
final ExpirableValue<?> memory = optmemory.get();
|
ExpirableValue<?> memory = optmemory.get();
|
||||||
return ValueConversions.fromTimedMemory(e, memory.getTimeToLive(), memory.getValue());
|
return ValueConversions.fromTimedMemory(e, memory.getTimeToLive(), memory.getValue());
|
||||||
}
|
}
|
||||||
return Value.NULL;
|
return Value.NULL;
|
||||||
@@ -604,22 +605,22 @@ public class EntityValue extends Value
|
|||||||
put("player_type", (e, a) -> {
|
put("player_type", (e, a) -> {
|
||||||
if (e instanceof final Player p)
|
if (e instanceof final Player p)
|
||||||
{
|
{
|
||||||
final String moddedType = Carpet.isModdedPlayer(p);
|
String moddedType = Carpet.isModdedPlayer(p);
|
||||||
if (moddedType != null)
|
if (moddedType != null)
|
||||||
{
|
{
|
||||||
return StringValue.of(moddedType);
|
return StringValue.of(moddedType);
|
||||||
}
|
}
|
||||||
final MinecraftServer server = p.getCommandSenderWorld().getServer();
|
MinecraftServer server = p.getCommandSenderWorld().getServer();
|
||||||
if (server.isDedicatedServer())
|
if (server.isDedicatedServer())
|
||||||
{
|
{
|
||||||
return new StringValue("multiplayer");
|
return new StringValue("multiplayer");
|
||||||
}
|
}
|
||||||
final boolean runningLan = server.isPublished();
|
boolean runningLan = server.isPublished();
|
||||||
if (!runningLan)
|
if (!runningLan)
|
||||||
{
|
{
|
||||||
return new StringValue("singleplayer");
|
return new StringValue("singleplayer");
|
||||||
}
|
}
|
||||||
final boolean isowner = server.isSingleplayerOwner(p.getGameProfile());
|
boolean isowner = server.isSingleplayerOwner(p.getGameProfile());
|
||||||
if (isowner)
|
if (isowner)
|
||||||
{
|
{
|
||||||
return new StringValue("lan_host");
|
return new StringValue("lan_host");
|
||||||
@@ -644,8 +645,8 @@ public class EntityValue extends Value
|
|||||||
}
|
}
|
||||||
if (a == null)
|
if (a == null)
|
||||||
{
|
{
|
||||||
final List<Value> effects = new ArrayList<>();
|
List<Value> effects = new ArrayList<>();
|
||||||
for (final MobEffectInstance p : le.getActiveEffects())
|
for (MobEffectInstance p : le.getActiveEffects())
|
||||||
{
|
{
|
||||||
effects.add(ListValue.of(
|
effects.add(ListValue.of(
|
||||||
new StringValue(p.getDescriptionId().replaceFirst("^effect\\.minecraft\\.", "")),
|
new StringValue(p.getDescriptionId().replaceFirst("^effect\\.minecraft\\.", "")),
|
||||||
@@ -655,8 +656,8 @@ public class EntityValue extends Value
|
|||||||
}
|
}
|
||||||
return ListValue.wrap(effects);
|
return ListValue.wrap(effects);
|
||||||
}
|
}
|
||||||
final String effectName = a.getString();
|
String effectName = a.getString();
|
||||||
final MobEffect potion = BuiltInRegistries.MOB_EFFECT.get(InputValidator.identifierOf(effectName));
|
MobEffect potion = BuiltInRegistries.MOB_EFFECT.get(InputValidator.identifierOf(effectName));
|
||||||
if (potion == null)
|
if (potion == null)
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("No such an effect: " + effectName);
|
throw new InternalExpressionException("No such an effect: " + effectName);
|
||||||
@@ -665,7 +666,7 @@ public class EntityValue extends Value
|
|||||||
{
|
{
|
||||||
return Value.NULL;
|
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()));
|
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) -> {
|
put("active_block", (e, a) -> {
|
||||||
if (e instanceof final ServerPlayer sp)
|
if (e instanceof final ServerPlayer sp)
|
||||||
{
|
{
|
||||||
final BlockPos pos = Vanilla.ServerPlayerGameMode_getCurrentBlockPosition(sp.gameMode);
|
BlockPos pos = Vanilla.ServerPlayerGameMode_getCurrentBlockPosition(sp.gameMode);
|
||||||
if (pos == null)
|
if (pos == null)
|
||||||
{
|
{
|
||||||
return Value.NULL;
|
return Value.NULL;
|
||||||
}
|
}
|
||||||
return new BlockValue(null, e.level, pos);
|
return new BlockValue(null, sp.getLevel(), pos);
|
||||||
}
|
}
|
||||||
return Value.NULL;
|
return Value.NULL;
|
||||||
});
|
});
|
||||||
@@ -711,7 +712,7 @@ public class EntityValue extends Value
|
|||||||
put("breaking_progress", (e, a) -> {
|
put("breaking_progress", (e, a) -> {
|
||||||
if (e instanceof final ServerPlayer sp)
|
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 progress < 0 ? Value.NULL : new NumericValue(progress);
|
||||||
}
|
}
|
||||||
return Value.NULL;
|
return Value.NULL;
|
||||||
@@ -748,7 +749,7 @@ public class EntityValue extends Value
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
final List<Value> args = lv.getItems();
|
List<Value> args = lv.getItems();
|
||||||
if (args.size() == 0)
|
if (args.size() == 0)
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("'trace' needs more arguments");
|
throw new InternalExpressionException("'trace' needs more arguments");
|
||||||
@@ -760,7 +761,7 @@ public class EntityValue extends Value
|
|||||||
blocks = false;
|
blocks = false;
|
||||||
for (int i = 1; i < args.size(); i++)
|
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"))
|
if (what.equalsIgnoreCase("entities"))
|
||||||
{
|
{
|
||||||
entities = true;
|
entities = true;
|
||||||
@@ -791,7 +792,7 @@ public class EntityValue extends Value
|
|||||||
reach = 5.0f;
|
reach = 5.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
final HitResult hitres;
|
HitResult hitres;
|
||||||
if (entities && !blocks)
|
if (entities && !blocks)
|
||||||
{
|
{
|
||||||
hitres = Tracer.rayTraceEntities(e, 1, reach, reach * reach);
|
hitres = Tracer.rayTraceEntities(e, 1, reach, reach * reach);
|
||||||
@@ -818,7 +819,7 @@ public class EntityValue extends Value
|
|||||||
case MISS:
|
case MISS:
|
||||||
return Value.NULL;
|
return Value.NULL;
|
||||||
case BLOCK:
|
case BLOCK:
|
||||||
return new BlockValue(null, e.getCommandSenderWorld(), ((BlockHitResult) hitres).getBlockPos());
|
return new BlockValue((ServerLevel) e.getCommandSenderWorld(), ((BlockHitResult) hitres).getBlockPos());
|
||||||
case ENTITY:
|
case ENTITY:
|
||||||
return new EntityValue(((EntityHitResult) hitres).getEntity());
|
return new EntityValue(((EntityHitResult) hitres).getEntity());
|
||||||
}
|
}
|
||||||
@@ -830,14 +831,14 @@ public class EntityValue extends Value
|
|||||||
{
|
{
|
||||||
return Value.NULL;
|
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)
|
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)))));
|
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());
|
ResourceLocation id = InputValidator.identifierOf(a.getString());
|
||||||
final Attribute attrib = attributes.getOptional(id).orElseThrow(
|
Attribute attrib = attributes.getOptional(id).orElseThrow(
|
||||||
() -> new InternalExpressionException("Unknown attribute: " + a.getString())
|
() -> new InternalExpressionException("Unknown attribute: " + a.getString())
|
||||||
);
|
);
|
||||||
if (!el.getAttributes().hasAttribute(attrib))
|
if (!el.getAttributes().hasAttribute(attrib))
|
||||||
@@ -848,7 +849,7 @@ public class EntityValue extends Value
|
|||||||
});
|
});
|
||||||
|
|
||||||
put("nbt", (e, a) -> {
|
put("nbt", (e, a) -> {
|
||||||
final CompoundTag nbttagcompound = e.saveWithoutId((new CompoundTag()));
|
CompoundTag nbttagcompound = e.saveWithoutId((new CompoundTag()));
|
||||||
if (a == null)
|
if (a == null)
|
||||||
{
|
{
|
||||||
return new NBTSerializableValue(nbttagcompound);
|
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)))
|
if (!(featureModifiers.containsKey(what)))
|
||||||
{
|
{
|
||||||
@@ -871,17 +872,17 @@ public class EntityValue extends Value
|
|||||||
{
|
{
|
||||||
featureModifiers.get(what).accept(getEntity(), toWhat);
|
featureModifiers.get(what).accept(getEntity(), toWhat);
|
||||||
}
|
}
|
||||||
catch (final NullPointerException npe)
|
catch (NullPointerException npe)
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("'modify' for '" + what + "' expects a value");
|
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);
|
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 (
|
if (
|
||||||
!Double.isFinite(x) || Double.isNaN(x) ||
|
!Double.isFinite(x) || Double.isNaN(x) ||
|
||||||
@@ -896,7 +897,7 @@ public class EntityValue extends Value
|
|||||||
if (e instanceof final ServerPlayer sp)
|
if (e instanceof final ServerPlayer sp)
|
||||||
{
|
{
|
||||||
// this forces position but doesn't angles for some reason. Need both in the API in the future.
|
// 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.X_ROT);
|
||||||
set.add(RelativeMovement.Y_ROT);
|
set.add(RelativeMovement.Y_ROT);
|
||||||
sp.connection.teleport(x, y, z, yaw, pitch, set);
|
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;
|
e.hurtMarked = true;
|
||||||
if (Math.abs(scale) > 10000)
|
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("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("age", (e, v) -> e.tickCount = Math.abs((int) NumericValue.asNumber(v).getLong()));
|
||||||
put("health", (e, v) -> {
|
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 (health <= 0f && e instanceof final ServerPlayer player)
|
||||||
{
|
{
|
||||||
if (player.containerMenu != null)
|
if (player.containerMenu != null)
|
||||||
@@ -954,7 +955,7 @@ public class EntityValue extends Value
|
|||||||
});
|
});
|
||||||
|
|
||||||
put("may_fly", (e, v) -> {
|
put("may_fly", (e, v) -> {
|
||||||
final boolean mayFly = v.getBoolean();
|
boolean mayFly = v.getBoolean();
|
||||||
if (e instanceof final ServerPlayer player)
|
if (e instanceof final ServerPlayer player)
|
||||||
{
|
{
|
||||||
player.getAbilities().mayfly = mayFly;
|
player.getAbilities().mayfly = mayFly;
|
||||||
@@ -967,7 +968,7 @@ public class EntityValue extends Value
|
|||||||
});
|
});
|
||||||
|
|
||||||
put("flying", (e, v) -> {
|
put("flying", (e, v) -> {
|
||||||
final boolean flying = v.getBoolean();
|
boolean flying = v.getBoolean();
|
||||||
if (e instanceof final ServerPlayer player)
|
if (e instanceof final ServerPlayer player)
|
||||||
{
|
{
|
||||||
player.getAbilities().flying = flying;
|
player.getAbilities().flying = flying;
|
||||||
@@ -976,7 +977,7 @@ public class EntityValue extends Value
|
|||||||
});
|
});
|
||||||
|
|
||||||
put("may_build", (e, v) -> {
|
put("may_build", (e, v) -> {
|
||||||
final boolean mayBuild = v.getBoolean();
|
boolean mayBuild = v.getBoolean();
|
||||||
if (e instanceof final ServerPlayer player)
|
if (e instanceof final ServerPlayer player)
|
||||||
{
|
{
|
||||||
player.getAbilities().mayBuild = mayBuild;
|
player.getAbilities().mayBuild = mayBuild;
|
||||||
@@ -985,7 +986,7 @@ public class EntityValue extends Value
|
|||||||
});
|
});
|
||||||
|
|
||||||
put("insta_build", (e, v) -> {
|
put("insta_build", (e, v) -> {
|
||||||
final boolean instaBuild = v.getBoolean();
|
boolean instaBuild = v.getBoolean();
|
||||||
if (e instanceof final ServerPlayer player)
|
if (e instanceof final ServerPlayer player)
|
||||||
{
|
{
|
||||||
player.getAbilities().instabuild = instaBuild;
|
player.getAbilities().instabuild = instaBuild;
|
||||||
@@ -994,7 +995,7 @@ public class EntityValue extends Value
|
|||||||
});
|
});
|
||||||
|
|
||||||
put("fly_speed", (e, v) -> {
|
put("fly_speed", (e, v) -> {
|
||||||
final float flySpeed = NumericValue.asNumber(v).getFloat();
|
float flySpeed = NumericValue.asNumber(v).getFloat();
|
||||||
if (e instanceof final ServerPlayer player)
|
if (e instanceof final ServerPlayer player)
|
||||||
{
|
{
|
||||||
player.getAbilities().setFlyingSpeed(flySpeed);
|
player.getAbilities().setFlyingSpeed(flySpeed);
|
||||||
@@ -1003,7 +1004,7 @@ public class EntityValue extends Value
|
|||||||
});
|
});
|
||||||
|
|
||||||
put("walk_speed", (e, v) -> {
|
put("walk_speed", (e, v) -> {
|
||||||
final float walkSpeed = NumericValue.asNumber(v).getFloat();
|
float walkSpeed = NumericValue.asNumber(v).getFloat();
|
||||||
if (e instanceof final ServerPlayer player)
|
if (e instanceof final ServerPlayer player)
|
||||||
{
|
{
|
||||||
player.getAbilities().setWalkingSpeed(walkSpeed);
|
player.getAbilities().setWalkingSpeed(walkSpeed);
|
||||||
@@ -1015,7 +1016,7 @@ public class EntityValue extends Value
|
|||||||
{
|
{
|
||||||
if (e instanceof final ServerPlayer player)
|
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));
|
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");
|
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,
|
updatePosition(e,
|
||||||
NumericValue.asNumber(coords.get(0)).getDouble(),
|
NumericValue.asNumber(coords.get(0)).getDouble(),
|
||||||
NumericValue.asNumber(coords.get(1)).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");
|
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,
|
updatePosition(e,
|
||||||
NumericValue.asNumber(coords.get(0)).getDouble(),
|
NumericValue.asNumber(coords.get(0)).getDouble(),
|
||||||
NumericValue.asNumber(coords.get(1)).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");
|
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 x = NumericValue.asNumber(vec.get(0)).getFloat();
|
||||||
float y = NumericValue.asNumber(vec.get(1)).getFloat();
|
float y = NumericValue.asNumber(vec.get(1)).getFloat();
|
||||||
float z = NumericValue.asNumber(vec.get(2)).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)
|
if (l == 0)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@@ -1104,8 +1105,8 @@ public class EntityValue extends Value
|
|||||||
x /= l;
|
x /= l;
|
||||||
y /= l;
|
y /= l;
|
||||||
z /= l;
|
z /= l;
|
||||||
final float pitch = (float) -Math.asin(y) / 0.017453292F;
|
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 yaw = (float) (x == 0 && z == 0 ? e.getYRot() : Mth.atan2(-x, z) / 0.017453292F);
|
||||||
updatePosition(e, e.getX(), e.getY(), e.getZ(), yaw, pitch);
|
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");
|
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,
|
updatePosition(e,
|
||||||
e.getX() + NumericValue.asNumber(coords.get(0)).getDouble(),
|
e.getX() + NumericValue.asNumber(coords.get(0)).getDouble(),
|
||||||
e.getY() + NumericValue.asNumber(coords.get(1)).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");
|
throw new InternalExpressionException("Expected a list of 3 parameters as a second argument");
|
||||||
}
|
}
|
||||||
final List<Value> coords = lv.getItems();
|
List<Value> coords = lv.getItems();
|
||||||
final double dx = NumericValue.asNumber(coords.get(0)).getDouble();
|
double dx = NumericValue.asNumber(coords.get(0)).getDouble();
|
||||||
final double dy = NumericValue.asNumber(coords.get(1)).getDouble();
|
double dy = NumericValue.asNumber(coords.get(1)).getDouble();
|
||||||
final double dz = NumericValue.asNumber(coords.get(2)).getDouble();
|
double dz = NumericValue.asNumber(coords.get(2)).getDouble();
|
||||||
e.setDeltaMovement(dx, dy, dz);
|
e.setDeltaMovement(dx, dy, dz);
|
||||||
updateVelocity(e, Mth.absMax(Mth.absMax(dx, dy), dz));
|
updateVelocity(e, Mth.absMax(Mth.absMax(dx, dy), dz));
|
||||||
});
|
});
|
||||||
put("motion_x", (e, v) ->
|
put("motion_x", (e, v) ->
|
||||||
{
|
{
|
||||||
final Vec3 velocity = e.getDeltaMovement();
|
Vec3 velocity = e.getDeltaMovement();
|
||||||
final double dv = NumericValue.asNumber(v).getDouble();
|
double dv = NumericValue.asNumber(v).getDouble();
|
||||||
e.setDeltaMovement(dv, velocity.y, velocity.z);
|
e.setDeltaMovement(dv, velocity.y, velocity.z);
|
||||||
updateVelocity(e, dv);
|
updateVelocity(e, dv);
|
||||||
});
|
});
|
||||||
put("motion_y", (e, v) ->
|
put("motion_y", (e, v) ->
|
||||||
{
|
{
|
||||||
final Vec3 velocity = e.getDeltaMovement();
|
Vec3 velocity = e.getDeltaMovement();
|
||||||
final double dv = NumericValue.asNumber(v).getDouble();
|
double dv = NumericValue.asNumber(v).getDouble();
|
||||||
e.setDeltaMovement(velocity.x, dv, velocity.z);
|
e.setDeltaMovement(velocity.x, dv, velocity.z);
|
||||||
updateVelocity(e, dv);
|
updateVelocity(e, dv);
|
||||||
});
|
});
|
||||||
put("motion_z", (e, v) ->
|
put("motion_z", (e, v) ->
|
||||||
{
|
{
|
||||||
final Vec3 velocity = e.getDeltaMovement();
|
Vec3 velocity = e.getDeltaMovement();
|
||||||
final double dv = NumericValue.asNumber(v).getDouble();
|
double dv = NumericValue.asNumber(v).getDouble();
|
||||||
e.setDeltaMovement(velocity.x, velocity.y, dv);
|
e.setDeltaMovement(velocity.x, velocity.y, dv);
|
||||||
updateVelocity(e, 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");
|
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(
|
e.push(
|
||||||
NumericValue.asNumber(coords.get(0)).getDouble(),
|
NumericValue.asNumber(coords.get(0)).getDouble(),
|
||||||
NumericValue.asNumber(coords.get(1)).getDouble(),
|
NumericValue.asNumber(coords.get(1)).getDouble(),
|
||||||
@@ -1232,7 +1233,7 @@ public class EntityValue extends Value
|
|||||||
}
|
}
|
||||||
else if (v instanceof final ListValue lv)
|
else if (v instanceof final ListValue lv)
|
||||||
{
|
{
|
||||||
for (final Value element : lv.getItems())
|
for (Value element : lv.getItems())
|
||||||
{
|
{
|
||||||
if (element instanceof final EntityValue ev)
|
if (element instanceof final EntityValue ev)
|
||||||
{
|
{
|
||||||
@@ -1248,7 +1249,7 @@ public class EntityValue extends Value
|
|||||||
}
|
}
|
||||||
if (v instanceof final ListValue lv)
|
if (v instanceof final ListValue lv)
|
||||||
{
|
{
|
||||||
for (final Value element : lv.getItems())
|
for (Value element : lv.getItems())
|
||||||
{
|
{
|
||||||
e.addTag(element.getString());
|
e.addTag(element.getString());
|
||||||
}
|
}
|
||||||
@@ -1265,7 +1266,7 @@ public class EntityValue extends Value
|
|||||||
}
|
}
|
||||||
if (v instanceof final ListValue lv)
|
if (v instanceof final ListValue lv)
|
||||||
{
|
{
|
||||||
for (final Value element : lv.getItems())
|
for (Value element : lv.getItems())
|
||||||
{
|
{
|
||||||
e.removeTag(element.getString());
|
e.removeTag(element.getString());
|
||||||
}
|
}
|
||||||
@@ -1309,13 +1310,13 @@ public class EntityValue extends Value
|
|||||||
if (v.isNull())
|
if (v.isNull())
|
||||||
{
|
{
|
||||||
ec.restrictTo(BlockPos.ZERO, -1);
|
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"));
|
Vanilla.Mob_getAI(ec, false).removeGoal(tasks.get("home"));
|
||||||
tasks.remove("home");
|
tasks.remove("home");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final BlockPos pos;
|
BlockPos pos;
|
||||||
int distance = 16;
|
int distance = 16;
|
||||||
|
|
||||||
if (v instanceof final BlockValue bv)
|
if (v instanceof final BlockValue bv)
|
||||||
@@ -1328,8 +1329,8 @@ public class EntityValue extends Value
|
|||||||
}
|
}
|
||||||
else if (v instanceof final ListValue lv)
|
else if (v instanceof final ListValue lv)
|
||||||
{
|
{
|
||||||
final List<Value> list = lv.getItems();
|
List<Value> list = lv.getItems();
|
||||||
final Vector3Argument locator = Vector3Argument.findIn(list, 0, false, false);
|
Vector3Argument locator = Vector3Argument.findIn(list, 0, false, false);
|
||||||
pos = new BlockPos(locator.vec.x, locator.vec.y, locator.vec.z);
|
pos = new BlockPos(locator.vec.x, locator.vec.y, locator.vec.z);
|
||||||
if (list.size() > locator.offset)
|
if (list.size() > locator.offset)
|
||||||
{
|
{
|
||||||
@@ -1342,10 +1343,10 @@ public class EntityValue extends Value
|
|||||||
}
|
}
|
||||||
|
|
||||||
ec.restrictTo(pos, distance);
|
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"))
|
if (!tasks.containsKey("home"))
|
||||||
{
|
{
|
||||||
final Goal task = new MoveTowardsRestrictionGoal(ec, 1.0D);
|
Goal task = new MoveTowardsRestrictionGoal(ec, 1.0D);
|
||||||
tasks.put("home", task);
|
tasks.put("home", task);
|
||||||
Vanilla.Mob_getAI(ec, false).addGoal(10, 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)
|
else if (a instanceof final ListValue lv)
|
||||||
{
|
{
|
||||||
final List<Value> params = lv.getItems();
|
List<Value> params = lv.getItems();
|
||||||
final Vector3Argument blockLocator = Vector3Argument.findIn(params, 0, false, false);
|
Vector3Argument blockLocator = Vector3Argument.findIn(params, 0, false, false);
|
||||||
final BlockPos pos = new BlockPos(blockLocator.vec);
|
BlockPos pos = new BlockPos(blockLocator.vec);
|
||||||
ResourceKey<Level> world = spe.getCommandSenderWorld().dimension();
|
ResourceKey<Level> world = spe.getCommandSenderWorld().dimension();
|
||||||
float angle = spe.getYHeadRot();
|
float angle = spe.getYHeadRot();
|
||||||
boolean forced = false;
|
boolean forced = false;
|
||||||
if (params.size() > blockLocator.offset)
|
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();
|
world = ValueConversions.dimFromValue(worldValue, spe.getServer()).dimension();
|
||||||
if (params.size() > blockLocator.offset + 1)
|
if (params.size() > blockLocator.offset + 1)
|
||||||
{
|
{
|
||||||
@@ -1467,11 +1468,11 @@ public class EntityValue extends Value
|
|||||||
}
|
}
|
||||||
else if (v instanceof final ListValue lv)
|
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)
|
if (list.size() >= 1 && list.size() <= 6)
|
||||||
{
|
{
|
||||||
final String effectName = list.get(0).getString();
|
String effectName = list.get(0).getString();
|
||||||
final MobEffect effect = BuiltInRegistries.MOB_EFFECT.get(InputValidator.identifierOf(effectName));
|
MobEffect effect = BuiltInRegistries.MOB_EFFECT.get(InputValidator.identifierOf(effectName));
|
||||||
if (effect == null)
|
if (effect == null)
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("Wrong effect name: " + effectName);
|
throw new InternalExpressionException("Wrong effect name: " + effectName);
|
||||||
@@ -1481,7 +1482,7 @@ public class EntityValue extends Value
|
|||||||
le.removeEffect(effect);
|
le.removeEffect(effect);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final int duration = (int) NumericValue.asNumber(list.get(1)).getLong();
|
int duration = (int) NumericValue.asNumber(list.get(1)).getLong();
|
||||||
if (duration <= 0)
|
if (duration <= 0)
|
||||||
{
|
{
|
||||||
le.removeEffect(effect);
|
le.removeEffect(effect);
|
||||||
@@ -1513,8 +1514,8 @@ public class EntityValue extends Value
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
final String effectName = v.getString();
|
String effectName = v.getString();
|
||||||
final MobEffect effect = BuiltInRegistries.MOB_EFFECT.get(InputValidator.identifierOf(effectName));
|
MobEffect effect = BuiltInRegistries.MOB_EFFECT.get(InputValidator.identifierOf(effectName));
|
||||||
if (effect == null)
|
if (effect == null)
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("Wrong effect name: " + effectName);
|
throw new InternalExpressionException("Wrong effect name: " + effectName);
|
||||||
@@ -1530,7 +1531,7 @@ public class EntityValue extends Value
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final GameType toSet = v instanceof NumericValue ?
|
GameType toSet = v instanceof NumericValue ?
|
||||||
GameType.byId(((NumericValue) v).getInt()) :
|
GameType.byId(((NumericValue) v).getInt()) :
|
||||||
GameType.byName(v.getString().toLowerCase(Locale.ROOT), null);
|
GameType.byName(v.getString().toLowerCase(Locale.ROOT), null);
|
||||||
if (toSet != null)
|
if (toSet != null)
|
||||||
@@ -1564,7 +1565,7 @@ public class EntityValue extends Value
|
|||||||
InteractionHand hand = InteractionHand.MAIN_HAND;
|
InteractionHand hand = InteractionHand.MAIN_HAND;
|
||||||
if (v != null)
|
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"))
|
if (handString.equals("offhand") || handString.equals("off_hand"))
|
||||||
{
|
{
|
||||||
hand = InteractionHand.OFF_HAND;
|
hand = InteractionHand.OFF_HAND;
|
||||||
@@ -1579,7 +1580,7 @@ public class EntityValue extends Value
|
|||||||
put("gravity", (e, v) -> e.setNoGravity(!v.getBoolean()));
|
put("gravity", (e, v) -> e.setNoGravity(!v.getBoolean()));
|
||||||
|
|
||||||
put("invulnerable", (e, v) -> {
|
put("invulnerable", (e, v) -> {
|
||||||
final boolean invulnerable = v.getBoolean();
|
boolean invulnerable = v.getBoolean();
|
||||||
if (e instanceof final ServerPlayer player)
|
if (e instanceof final ServerPlayer player)
|
||||||
{
|
{
|
||||||
player.getAbilities().invulnerable = invulnerable;
|
player.getAbilities().invulnerable = invulnerable;
|
||||||
@@ -1663,7 +1664,7 @@ public class EntityValue extends Value
|
|||||||
put("breaking_progress", (e, a) -> {
|
put("breaking_progress", (e, a) -> {
|
||||||
if (e instanceof final ServerPlayer sp)
|
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);
|
Vanilla.ServerPlayerGameMode_setBlockBreakingProgress(sp.gameMode, progress);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -1671,8 +1672,8 @@ public class EntityValue extends Value
|
|||||||
put("nbt", (e, v) -> {
|
put("nbt", (e, v) -> {
|
||||||
if (!(e instanceof Player))
|
if (!(e instanceof Player))
|
||||||
{
|
{
|
||||||
final UUID uUID = e.getUUID();
|
UUID uUID = e.getUUID();
|
||||||
final Value tagValue = NBTSerializableValue.fromValue(v);
|
Value tagValue = NBTSerializableValue.fromValue(v);
|
||||||
if (tagValue instanceof final NBTSerializableValue nbtsv)
|
if (tagValue instanceof final NBTSerializableValue nbtsv)
|
||||||
{
|
{
|
||||||
e.load(nbtsv.getCompoundTag());
|
e.load(nbtsv.getCompoundTag());
|
||||||
@@ -1683,11 +1684,11 @@ public class EntityValue extends Value
|
|||||||
put("nbt_merge", (e, v) -> {
|
put("nbt_merge", (e, v) -> {
|
||||||
if (!(e instanceof Player))
|
if (!(e instanceof Player))
|
||||||
{
|
{
|
||||||
final UUID uUID = e.getUUID();
|
UUID uUID = e.getUUID();
|
||||||
final Value tagValue = NBTSerializableValue.fromValue(v);
|
Value tagValue = NBTSerializableValue.fromValue(v);
|
||||||
if (tagValue instanceof final NBTSerializableValue nbtsv)
|
if (tagValue instanceof final NBTSerializableValue nbtsv)
|
||||||
{
|
{
|
||||||
final CompoundTag nbttagcompound = e.saveWithoutId((new CompoundTag()));
|
CompoundTag nbttagcompound = e.saveWithoutId((new CompoundTag()));
|
||||||
nbttagcompound.merge(nbtsv.getCompoundTag());
|
nbttagcompound.merge(nbtsv.getCompoundTag());
|
||||||
e.load(nbttagcompound);
|
e.load(nbttagcompound);
|
||||||
e.setUUID(uUID);
|
e.setUUID(uUID);
|
||||||
@@ -1710,7 +1711,7 @@ public class EntityValue extends Value
|
|||||||
|
|
||||||
});
|
});
|
||||||
put("item", (e, v) -> {
|
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)
|
if (e instanceof final ItemEntity itementity)
|
||||||
{
|
{
|
||||||
itementity.setItem(item);
|
itementity.setItem(item);
|
||||||
@@ -1725,9 +1726,9 @@ public class EntityValue extends Value
|
|||||||
// "effect_"name []
|
// "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)
|
if (event == null)
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("Unknown entity event: " + eventName);
|
throw new InternalExpressionException("Unknown entity event: " + eventName);
|
||||||
@@ -1736,15 +1737,15 @@ public class EntityValue extends Value
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public net.minecraft.nbt.Tag toTag(final boolean force)
|
public net.minecraft.nbt.Tag toTag(boolean force)
|
||||||
{
|
{
|
||||||
if (!force)
|
if (!force)
|
||||||
{
|
{
|
||||||
throw new NBTSerializableValue.IncompatibleTypeException(this);
|
throw new NBTSerializableValue.IncompatibleTypeException(this);
|
||||||
}
|
}
|
||||||
final CompoundTag tag = new CompoundTag();
|
CompoundTag tag = new CompoundTag();
|
||||||
tag.put("Data", getEntity().saveWithoutId(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()));
|
tag.put("Name", StringTag.valueOf(reg.getKey(getEntity().getType()).toString()));
|
||||||
return tag;
|
return tag;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,15 +10,15 @@ public class FormattedTextValue extends StringValue
|
|||||||
{
|
{
|
||||||
Component text;
|
Component text;
|
||||||
|
|
||||||
public FormattedTextValue(final Component text)
|
public FormattedTextValue(Component text)
|
||||||
{
|
{
|
||||||
super(null);
|
super(null);
|
||||||
this.text = text;
|
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)
|
if (left instanceof final FormattedTextValue ftv)
|
||||||
{
|
{
|
||||||
text = ftv.getText().copy();
|
text = ftv.getText().copy();
|
||||||
@@ -45,7 +45,7 @@ public class FormattedTextValue extends StringValue
|
|||||||
return new FormattedTextValue(text);
|
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);
|
return text == null ? Value.NULL : new FormattedTextValue(text);
|
||||||
}
|
}
|
||||||
@@ -80,7 +80,7 @@ public class FormattedTextValue extends StringValue
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Tag toTag(final boolean force)
|
public Tag toTag(boolean force)
|
||||||
{
|
{
|
||||||
if (!force)
|
if (!force)
|
||||||
{
|
{
|
||||||
@@ -96,7 +96,7 @@ public class FormattedTextValue extends StringValue
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Value add(final Value o)
|
public Value add(Value o)
|
||||||
{
|
{
|
||||||
return combine(this, o);
|
return combine(this, o);
|
||||||
}
|
}
|
||||||
@@ -106,12 +106,12 @@ public class FormattedTextValue extends StringValue
|
|||||||
return Component.Serializer.toJson(text);
|
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));
|
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());
|
return (value instanceof final FormattedTextValue ftv) ? ftv.getText() : Component.literal(value.getString());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ public abstract class FrameworkValue extends Value
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Tag toTag(final boolean force)
|
public Tag toTag(boolean force)
|
||||||
{
|
{
|
||||||
throw new UnsupportedOperationException("Scarpet language component cannot be serialized to the tag");
|
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 Type type;
|
||||||
|
|
||||||
public FunctionAnnotationValue(final Value variable, final Type type)
|
public FunctionAnnotationValue(Value variable, Type type)
|
||||||
{
|
{
|
||||||
if (variable.boundVariable == null)
|
if (variable.boundVariable == null)
|
||||||
{
|
{
|
||||||
@@ -41,7 +41,7 @@ public class FunctionAnnotationValue extends Value
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Tag toTag(final boolean force)
|
public Tag toTag(boolean force)
|
||||||
{
|
{
|
||||||
throw new UnsupportedOperationException("Global value cannot be serialized to the tag");
|
throw new UnsupportedOperationException("Global value cannot be serialized to the tag");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,12 +4,12 @@ import java.util.List;
|
|||||||
|
|
||||||
public class FunctionSignatureValue extends FrameworkValue
|
public class FunctionSignatureValue extends FrameworkValue
|
||||||
{
|
{
|
||||||
private String identifier;
|
private final String identifier;
|
||||||
private List<String> arguments;
|
private final List<String> arguments;
|
||||||
private List<String> globals;
|
private final List<String> globals;
|
||||||
private String varArgs;
|
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.identifier = name;
|
||||||
this.arguments = args;
|
this.arguments = args;
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import java.util.List;
|
|||||||
|
|
||||||
public class FunctionUnpackedArgumentsValue extends ListValue
|
public class FunctionUnpackedArgumentsValue extends ListValue
|
||||||
{
|
{
|
||||||
public FunctionUnpackedArgumentsValue(final List<Value> list)
|
public FunctionUnpackedArgumentsValue(List<Value> list)
|
||||||
{
|
{
|
||||||
super(list);
|
super(list);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ public class FunctionValue extends Value implements Fluff.ILazyFunction
|
|||||||
private static long variantCounter = 1;
|
private static long variantCounter = 1;
|
||||||
private long variant;
|
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.expression = expression;
|
||||||
this.token = token;
|
this.token = token;
|
||||||
@@ -46,7 +46,7 @@ public class FunctionValue extends Value implements Fluff.ILazyFunction
|
|||||||
variant = 0L;
|
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.expression = expression;
|
||||||
this.token = token;
|
this.token = token;
|
||||||
@@ -72,7 +72,7 @@ public class FunctionValue extends Value implements Fluff.ILazyFunction
|
|||||||
@Override
|
@Override
|
||||||
public String getPrettyString()
|
public String getPrettyString()
|
||||||
{
|
{
|
||||||
final List<String> stringArgs = new ArrayList<>(args);
|
List<String> stringArgs = new ArrayList<>(args);
|
||||||
if (outerState != null)
|
if (outerState != null)
|
||||||
{
|
{
|
||||||
stringArgs.addAll(outerState.entrySet().stream().map(e ->
|
stringArgs.addAll(outerState.entrySet().stream().map(e ->
|
||||||
@@ -95,7 +95,7 @@ public class FunctionValue extends Value implements Fluff.ILazyFunction
|
|||||||
@Override
|
@Override
|
||||||
protected Value clone()
|
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.outerState = this.outerState;
|
||||||
ret.variant = this.variant;
|
ret.variant = this.variant;
|
||||||
return ret;
|
return ret;
|
||||||
@@ -108,17 +108,17 @@ public class FunctionValue extends Value implements Fluff.ILazyFunction
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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;
|
return o instanceof final FunctionValue fv && name.equals(fv.name) && variant == fv.variant;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int compareTo(final Value o)
|
public int compareTo(Value o)
|
||||||
{
|
{
|
||||||
if (o instanceof final FunctionValue fv)
|
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 nameSame != 0 ? nameSame : (int) (variant - fv.variant);
|
||||||
}
|
}
|
||||||
return getString().compareTo(o.getString());
|
return getString().compareTo(o.getString());
|
||||||
@@ -137,7 +137,7 @@ public class FunctionValue extends Value implements Fluff.ILazyFunction
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Value slice(final long from, final Long to)
|
public Value slice(long from, Long to)
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("Cannot slice a function");
|
throw new InternalExpressionException("Cannot slice a function");
|
||||||
}
|
}
|
||||||
@@ -154,31 +154,31 @@ public class FunctionValue extends Value implements Fluff.ILazyFunction
|
|||||||
return varArgs != null;
|
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
|
try
|
||||||
{
|
{
|
||||||
return execute(c, type, expression, token, params);
|
return execute(c, type, expression, token, params);
|
||||||
}
|
}
|
||||||
catch (final ExpressionException exc)
|
catch (ExpressionException exc)
|
||||||
{
|
{
|
||||||
exc.stack.add(this);
|
exc.stack.add(this);
|
||||||
throw exc;
|
throw exc;
|
||||||
}
|
}
|
||||||
catch (final InternalExpressionException exc)
|
catch (InternalExpressionException exc)
|
||||||
{
|
{
|
||||||
exc.stack.add(this);
|
exc.stack.add(this);
|
||||||
throw new ExpressionException(c, expression, token, exc.getMessage(), exc.stack);
|
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));
|
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)
|
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
|
// TODO we shoudn't need that if all fuctions are not lazy really
|
||||||
final List<Value> params = new ArrayList<>();
|
List<Value> params = new ArrayList<>();
|
||||||
for (final LazyValue lv : lazyParams)
|
for (LazyValue lv : lazyParams)
|
||||||
{
|
{
|
||||||
final Value param = lv.evalValue(c, Context.NONE);
|
Value param = lv.evalValue(c, Context.NONE);
|
||||||
if (param instanceof FunctionUnpackedArgumentsValue)
|
if (param instanceof FunctionUnpackedArgumentsValue)
|
||||||
{
|
{
|
||||||
CarpetScriptServer.LOG.error("How did we get here?");
|
CarpetScriptServer.LOG.error("How did we get here?");
|
||||||
@@ -211,13 +211,13 @@ public class FunctionValue extends Value implements Fluff.ILazyFunction
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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);
|
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 -> {
|
assertArgsOk(params, fixedArgs -> {
|
||||||
if (fixedArgs) // wrong number of args for fixed args
|
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
|
// too few args for varargs
|
||||||
|
|
||||||
final List<String> argList = new ArrayList<>(args);
|
List<String> argList = new ArrayList<>(args);
|
||||||
argList.add("... " + varArgs);
|
argList.add("... " + varArgs);
|
||||||
throw new ExpressionException(c, e, t,
|
throw new ExpressionException(c, e, t,
|
||||||
"Incorrect number of arguments for function " + name +
|
"Incorrect number of arguments for function " + name +
|
||||||
". Should be at least " + args.size() + ", not " + params.size() + " like " + argList
|
". Should be at least " + args.size() + ", not " + params.size() + " like " + argList
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
final Context newFrame = c.recreate();
|
Context newFrame = c.recreate();
|
||||||
|
|
||||||
if (outerState != null)
|
if (outerState != null)
|
||||||
{
|
{
|
||||||
@@ -244,18 +244,18 @@ public class FunctionValue extends Value implements Fluff.ILazyFunction
|
|||||||
}
|
}
|
||||||
for (int i = 0; i < args.size(); i++)
|
for (int i = 0; i < args.size(); i++)
|
||||||
{
|
{
|
||||||
final String arg = args.get(i);
|
String arg = args.get(i);
|
||||||
final Value val = params.get(i).reboundedTo(arg); // todo check if we need to copy that
|
Value val = params.get(i).reboundedTo(arg); // todo check if we need to copy that
|
||||||
newFrame.setVariable(arg, (cc, tt) -> val);
|
newFrame.setVariable(arg, (cc, tt) -> val);
|
||||||
}
|
}
|
||||||
if (varArgs != null)
|
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++)
|
for (int i = args.size(), mx = params.size(); i < mx; i++)
|
||||||
{
|
{
|
||||||
extraParams.add(params.get(i).reboundedTo(null)); // copy by value I guess
|
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);
|
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
|
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");
|
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;
|
retVal = returnStatement.retval;
|
||||||
}
|
}
|
||||||
final Value otherRetVal = retVal;
|
Value otherRetVal = retVal;
|
||||||
return (cc, tt) -> otherRetVal;
|
return (cc, tt) -> otherRetVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -297,7 +297,7 @@ public class FunctionValue extends Value implements Fluff.ILazyFunction
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Tag toTag(final boolean force)
|
public Tag toTag(boolean force)
|
||||||
{
|
{
|
||||||
if (!force)
|
if (!force)
|
||||||
{
|
{
|
||||||
@@ -306,9 +306,9 @@ public class FunctionValue extends Value implements Fluff.ILazyFunction
|
|||||||
return StringTag.valueOf(getString());
|
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
|
if (varArgs == null && args.size() != size) // wrong number of args for fixed args
|
||||||
{
|
{
|
||||||
feedback.accept(true);
|
feedback.accept(true);
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ public class LContainerValue extends FrameworkValue
|
|||||||
private final Value address;
|
private final Value address;
|
||||||
public static final LContainerValue NULL_CONTAINER = new LContainerValue(null, null);
|
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;
|
container = c;
|
||||||
address = v;
|
address = v;
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import net.minecraft.nbt.Tag;
|
|||||||
|
|
||||||
public abstract class LazyListValue extends AbstractListValue implements Iterator<Value>
|
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()
|
return new LazyListValue()
|
||||||
{
|
{
|
||||||
@@ -35,7 +35,7 @@ public abstract class LazyListValue extends AbstractListValue implements Iterato
|
|||||||
@Override
|
@Override
|
||||||
public Value next()
|
public Value next()
|
||||||
{
|
{
|
||||||
final Value val = new NumericValue(current);
|
Value val = new NumericValue(current);
|
||||||
current += stepp;
|
current += stepp;
|
||||||
return val;
|
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()
|
return new LazyListValue()
|
||||||
{
|
{
|
||||||
@@ -83,7 +83,7 @@ public abstract class LazyListValue extends AbstractListValue implements Iterato
|
|||||||
@Override
|
@Override
|
||||||
public Value next()
|
public Value next()
|
||||||
{
|
{
|
||||||
final Value val = new NumericValue(current);
|
Value val = new NumericValue(current);
|
||||||
current += stepp;
|
current += stepp;
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
@@ -136,7 +136,7 @@ public abstract class LazyListValue extends AbstractListValue implements Iterato
|
|||||||
|
|
||||||
public List<Value> unroll()
|
public List<Value> unroll()
|
||||||
{
|
{
|
||||||
final List<Value> result = new ArrayList<>();
|
List<Value> result = new ArrayList<>();
|
||||||
this.forEachRemaining(result::add);
|
this.forEachRemaining(result::add);
|
||||||
fatality();
|
fatality();
|
||||||
return result;
|
return result;
|
||||||
@@ -157,7 +157,7 @@ public abstract class LazyListValue extends AbstractListValue implements Iterato
|
|||||||
{
|
{
|
||||||
return ListValue.of();
|
return ListValue.of();
|
||||||
}
|
}
|
||||||
final List<Value> result = new ArrayList<>();
|
List<Value> result = new ArrayList<>();
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < from; i++)
|
for (i = 0; i < from; i++)
|
||||||
{
|
{
|
||||||
@@ -187,13 +187,13 @@ public abstract class LazyListValue extends AbstractListValue implements Iterato
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Value add(final Value other)
|
public Value add(Value other)
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("Cannot add to iterators");
|
throw new InternalExpressionException("Cannot add to iterators");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(final Object o)
|
public boolean equals(Object o)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -207,12 +207,12 @@ public abstract class LazyListValue extends AbstractListValue implements Iterato
|
|||||||
@Override
|
@Override
|
||||||
public Object clone()
|
public Object clone()
|
||||||
{
|
{
|
||||||
final Object copy;
|
Object copy;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
copy = super.clone();
|
copy = super.clone();
|
||||||
}
|
}
|
||||||
catch (final CloneNotSupportedException e)
|
catch (CloneNotSupportedException e)
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("Cannot copy iterators");
|
throw new InternalExpressionException("Cannot copy iterators");
|
||||||
}
|
}
|
||||||
@@ -233,7 +233,7 @@ public abstract class LazyListValue extends AbstractListValue implements Iterato
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Tag toTag(final boolean force)
|
public Tag toTag(boolean force)
|
||||||
{
|
{
|
||||||
if (!force)
|
if (!force)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -60,54 +60,54 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
|
|||||||
@Override
|
@Override
|
||||||
public Value deepcopy()
|
public Value deepcopy()
|
||||||
{
|
{
|
||||||
final List<Value> copyItems = new ArrayList<>(items.size());
|
List<Value> copyItems = new ArrayList<>(items.size());
|
||||||
for (final Value entry : items)
|
for (Value entry : items)
|
||||||
{
|
{
|
||||||
copyItems.add(entry.deepcopy());
|
copyItems.add(entry.deepcopy());
|
||||||
}
|
}
|
||||||
return new ListValue(copyItems);
|
return new ListValue(copyItems);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ListValue(final Collection<? extends Value> list)
|
public ListValue(Collection<? extends Value> list)
|
||||||
{
|
{
|
||||||
items = new ArrayList<>(list);
|
items = new ArrayList<>(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected ListValue(final List<Value> list)
|
protected ListValue(List<Value> list)
|
||||||
{
|
{
|
||||||
items = 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));
|
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);
|
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()));
|
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);
|
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)));
|
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<>();
|
List<Value> valList = new ArrayList<>();
|
||||||
for (final Number i : list)
|
for (Number i : list)
|
||||||
{
|
{
|
||||||
valList.add(new NumericValue(i.doubleValue()));
|
valList.add(new NumericValue(i.doubleValue()));
|
||||||
}
|
}
|
||||||
@@ -116,7 +116,7 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
|
|||||||
|
|
||||||
public static LazyValue lazyEmpty()
|
public static LazyValue lazyEmpty()
|
||||||
{
|
{
|
||||||
final Value ret = new ListValue();
|
Value ret = new ListValue();
|
||||||
return (c, t) -> ret;
|
return (c, t) -> ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -126,12 +126,12 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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)
|
if (other instanceof final ListValue list)
|
||||||
{
|
{
|
||||||
final List<Value> otherItems = list.items;
|
List<Value> otherItems = list.items;
|
||||||
if (otherItems.size() == items.size())
|
if (otherItems.size() == items.size())
|
||||||
{
|
{
|
||||||
for (int i = 0, size = items.size(); i < size; i++)
|
for (int i = 0, size = items.size(); i < size; i++)
|
||||||
@@ -146,7 +146,7 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (final Value v : items)
|
for (Value v : items)
|
||||||
{
|
{
|
||||||
output.items.add(v.add(other));
|
output.items.add(v.add(other));
|
||||||
}
|
}
|
||||||
@@ -155,18 +155,18 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void append(final Value v)
|
public void append(Value v)
|
||||||
{
|
{
|
||||||
items.add(v);
|
items.add(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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)
|
if (other instanceof final ListValue list)
|
||||||
{
|
{
|
||||||
final List<Value> otherItems = list.items;
|
List<Value> otherItems = list.items;
|
||||||
if (otherItems.size() == items.size())
|
if (otherItems.size() == items.size())
|
||||||
{
|
{
|
||||||
for (int i = 0, size = items.size(); i < size; i++)
|
for (int i = 0, size = items.size(); i < size; i++)
|
||||||
@@ -181,7 +181,7 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (final Value v : items)
|
for (Value v : items)
|
||||||
{
|
{
|
||||||
output.items.add(v.subtract(other));
|
output.items.add(v.subtract(other));
|
||||||
}
|
}
|
||||||
@@ -189,19 +189,19 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
|
|||||||
return output;
|
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
|
throw new UnsupportedOperationException(); // TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@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)
|
if (other instanceof final ListValue list)
|
||||||
{
|
{
|
||||||
final List<Value> otherItems = list.items;
|
List<Value> otherItems = list.items;
|
||||||
if (otherItems.size() == items.size())
|
if (otherItems.size() == items.size())
|
||||||
{
|
{
|
||||||
for (int i = 0, size = items.size(); i < size; i++)
|
for (int i = 0, size = items.size(); i < size; i++)
|
||||||
@@ -216,7 +216,7 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (final Value v : items)
|
for (Value v : items)
|
||||||
{
|
{
|
||||||
output.items.add(v.multiply(other));
|
output.items.add(v.multiply(other));
|
||||||
}
|
}
|
||||||
@@ -225,12 +225,12 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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)
|
if (other instanceof final ListValue list)
|
||||||
{
|
{
|
||||||
final List<Value> otherItems = list.items;
|
List<Value> otherItems = list.items;
|
||||||
if (otherItems.size() == items.size())
|
if (otherItems.size() == items.size())
|
||||||
{
|
{
|
||||||
for (int i = 0, size = items.size(); i < size; i++)
|
for (int i = 0, size = items.size(); i < size; i++)
|
||||||
@@ -245,7 +245,7 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (final Value v : items)
|
for (Value v : items)
|
||||||
{
|
{
|
||||||
output.items.add(v.divide(other));
|
output.items.add(v.divide(other));
|
||||||
}
|
}
|
||||||
@@ -254,12 +254,12 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int compareTo(final Value o)
|
public int compareTo(Value o)
|
||||||
{
|
{
|
||||||
if (o instanceof final ListValue ol)
|
if (o instanceof final ListValue ol)
|
||||||
{
|
{
|
||||||
final int size = this.getItems().size();
|
int size = this.getItems().size();
|
||||||
final int otherSize = ol.getItems().size();
|
int otherSize = ol.getItems().size();
|
||||||
if (size != otherSize)
|
if (size != otherSize)
|
||||||
{
|
{
|
||||||
return size - otherSize;
|
return size - otherSize;
|
||||||
@@ -270,7 +270,7 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
|
|||||||
}
|
}
|
||||||
for (int i = 0; i < size; i++)
|
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)
|
if (res != 0)
|
||||||
{
|
{
|
||||||
return res;
|
return res;
|
||||||
@@ -282,7 +282,7 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(final Object o)
|
public boolean equals(Object o)
|
||||||
{
|
{
|
||||||
return o instanceof final ListValue list && getItems().equals(list.getItems());
|
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);
|
return new ArrayList<>(items);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void extend(final List<Value> subList)
|
public void extend(List<Value> subList)
|
||||||
{
|
{
|
||||||
items.addAll(subList);
|
items.addAll(subList);
|
||||||
}
|
}
|
||||||
@@ -316,13 +316,13 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
|
|||||||
* @param len
|
* @param len
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public static int normalizeIndex(long idx, final int len)
|
public static int normalizeIndex(long idx, int len)
|
||||||
{
|
{
|
||||||
if (idx >= 0 && idx < len)
|
if (idx >= 0 && idx < len)
|
||||||
{
|
{
|
||||||
return (int) idx;
|
return (int) idx;
|
||||||
}
|
}
|
||||||
final long range = abs(idx) / len;
|
long range = abs(idx) / len;
|
||||||
idx += (range + 2) * len;
|
idx += (range + 2) * len;
|
||||||
idx = idx % len;
|
idx = idx % len;
|
||||||
return (int) idx;
|
return (int) idx;
|
||||||
@@ -330,7 +330,7 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
|
|||||||
|
|
||||||
public static class ListConstructorValue extends ListValue
|
public static class ListConstructorValue extends ListValue
|
||||||
{
|
{
|
||||||
public ListConstructorValue(final Collection<? extends Value> list)
|
public ListConstructorValue(Collection<? extends Value> list)
|
||||||
{
|
{
|
||||||
super(list);
|
super(list);
|
||||||
}
|
}
|
||||||
@@ -343,11 +343,11 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Value in(final Value value1)
|
public Value in(Value value1)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < items.size(); i++)
|
for (int i = 0; i < items.size(); i++)
|
||||||
{
|
{
|
||||||
final Value v = items.get(i);
|
Value v = items.get(i);
|
||||||
if (v.equals(value1))
|
if (v.equals(value1))
|
||||||
{
|
{
|
||||||
return new NumericValue(i);
|
return new NumericValue(i);
|
||||||
@@ -357,16 +357,16 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Value slice(final long fromDesc, final Long toDesc)
|
public Value slice(long fromDesc, Long toDesc)
|
||||||
{
|
{
|
||||||
final List<Value> items = getItems();
|
List<Value> items = getItems();
|
||||||
final int size = items.size();
|
int size = items.size();
|
||||||
final int from = normalizeIndex(fromDesc, size);
|
int from = normalizeIndex(fromDesc, size);
|
||||||
if (toDesc == null)
|
if (toDesc == null)
|
||||||
{
|
{
|
||||||
return new ListValue(new ArrayList<>(getItems().subList(from, size)));
|
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)
|
if (from > to)
|
||||||
{
|
{
|
||||||
return ListValue.of();
|
return ListValue.of();
|
||||||
@@ -375,9 +375,9 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Value split(final Value delimiter)
|
public Value split(Value delimiter)
|
||||||
{
|
{
|
||||||
final ListValue result = new ListValue();
|
ListValue result = new ListValue();
|
||||||
if (delimiter == null)
|
if (delimiter == null)
|
||||||
{
|
{
|
||||||
this.forEach(item -> result.items.add(of(item)));
|
this.forEach(item -> result.items.add(of(item)));
|
||||||
@@ -385,7 +385,7 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
|
|||||||
}
|
}
|
||||||
int startIndex = 0;
|
int startIndex = 0;
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for (final Value val : this.items)
|
for (Value val : this.items)
|
||||||
{
|
{
|
||||||
index++;
|
index++;
|
||||||
if (val.equals(delimiter))
|
if (val.equals(delimiter))
|
||||||
@@ -405,9 +405,9 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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"))
|
if (condition.equalsIgnoreCase("insert"))
|
||||||
{
|
{
|
||||||
return put(where, value, false, false);
|
return put(where, value, false, false);
|
||||||
@@ -424,12 +424,12 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean put(final Value ind, final Value value)
|
public boolean put(Value ind, Value value)
|
||||||
{
|
{
|
||||||
return put(ind, value, true, false);
|
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())
|
if (ind.isNull())
|
||||||
{
|
{
|
||||||
@@ -444,7 +444,7 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
final int numitems = items.size();
|
int numitems = items.size();
|
||||||
if (!(ind instanceof NumericValue))
|
if (!(ind instanceof NumericValue))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@@ -470,8 +470,8 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
|
|||||||
|
|
||||||
if (extend && value instanceof AbstractListValue)
|
if (extend && value instanceof AbstractListValue)
|
||||||
{
|
{
|
||||||
final Iterable<Value> iterable = ((AbstractListValue) value)::iterator;
|
Iterable<Value> iterable = ((AbstractListValue) value)::iterator;
|
||||||
final List<Value> appendix = StreamSupport.stream(iterable.spliterator(), false).collect(Collectors.toList());
|
List<Value> appendix = StreamSupport.stream(iterable.spliterator(), false).collect(Collectors.toList());
|
||||||
items.addAll(index, appendix);
|
items.addAll(index, appendix);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -481,27 +481,27 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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));
|
return size == 0 ? Value.NULL : items.get(normalizeIndex(NumericValue.asNumber(value, "'address' to a list index").getLong(), size));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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();
|
return index >= 0 && index < items.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean delete(final Value where)
|
public boolean delete(Value where)
|
||||||
{
|
{
|
||||||
if (!(where instanceof NumericValue) || items.isEmpty())
|
if (!(where instanceof NumericValue) || items.isEmpty())
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
final long index = ((NumericValue) where).getLong();
|
long index = ((NumericValue) where).getLong();
|
||||||
items.remove(normalizeIndex(index, items.size()));
|
items.remove(normalizeIndex(index, items.size()));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -527,7 +527,7 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
|
|||||||
MAP,
|
MAP,
|
||||||
STRING;
|
STRING;
|
||||||
|
|
||||||
private static TagTypeCompat getType(final Tag tag)
|
private static TagTypeCompat getType(Tag tag)
|
||||||
{
|
{
|
||||||
if (tag instanceof IntTag)
|
if (tag instanceof IntTag)
|
||||||
{
|
{
|
||||||
@@ -555,23 +555,23 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
|
|||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Tag toTag(final boolean force)
|
public Tag toTag(boolean force)
|
||||||
{
|
{
|
||||||
final int argSize = items.size();
|
int argSize = items.size();
|
||||||
if (argSize == 0)
|
if (argSize == 0)
|
||||||
{
|
{
|
||||||
return new ListTag();
|
return new ListTag();
|
||||||
}
|
}
|
||||||
final ListTag tag = new ListTag();
|
ListTag tag = new ListTag();
|
||||||
if (argSize == 1)
|
if (argSize == 1)
|
||||||
{
|
{
|
||||||
tag.add(items.get(0).toTag(force));
|
tag.add(items.get(0).toTag(force));
|
||||||
return tag;
|
return tag;
|
||||||
}
|
}
|
||||||
// figuring out the types
|
// figuring out the types
|
||||||
final List<Tag> tags = new ArrayList<>();
|
List<Tag> tags = new ArrayList<>();
|
||||||
items.forEach(v -> tags.add(v.toTag(force)));
|
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)));
|
tags.forEach(t -> cases.add(TagTypeCompat.getType(t)));
|
||||||
if (cases.size() == 1) // well, one type of items
|
if (cases.size() == 1) // well, one type of items
|
||||||
{
|
{
|
||||||
@@ -599,8 +599,8 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
|
|||||||
@Override
|
@Override
|
||||||
public JsonElement toJson()
|
public JsonElement toJson()
|
||||||
{
|
{
|
||||||
final JsonArray array = new JsonArray();
|
JsonArray array = new JsonArray();
|
||||||
for (final Value el : items)
|
for (Value el : items)
|
||||||
{
|
{
|
||||||
array.add(el.toJson());
|
array.add(el.toJson());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,13 +25,13 @@ public class MapValue extends AbstractListValue implements ContainerValueInterfa
|
|||||||
map = new HashMap<>();
|
map = new HashMap<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public MapValue(final List<Value> kvPairs)
|
public MapValue(List<Value> kvPairs)
|
||||||
{
|
{
|
||||||
this();
|
this();
|
||||||
kvPairs.forEach(this::put);
|
kvPairs.forEach(this::put);
|
||||||
}
|
}
|
||||||
|
|
||||||
public MapValue(final Set<Value> keySet)
|
public MapValue(Set<Value> keySet)
|
||||||
{
|
{
|
||||||
this();
|
this();
|
||||||
keySet.forEach(v -> map.put(v, Value.NULL));
|
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(", ")) + "}";
|
return "{" + map.entrySet().stream().map(p -> p.getKey().getPrettyString() + ": " + p.getValue().getPrettyString()).collect(Collectors.joining(", ")) + "}";
|
||||||
}
|
}
|
||||||
final List<Value> keys = new ArrayList<>(map.keySet());
|
List<Value> keys = new ArrayList<>(map.keySet());
|
||||||
final int max = keys.size();
|
int max = keys.size();
|
||||||
return "{" + keys.get(0).getPrettyString() + ": " + map.get(keys.get(0)).getPrettyString() + ", " +
|
return "{" + keys.get(0).getPrettyString() + ": " + map.get(keys.get(0)).getPrettyString() + ", " +
|
||||||
keys.get(1).getPrettyString() + ": " + map.get(keys.get(1)).getPrettyString() + ", ..., " +
|
keys.get(1).getPrettyString() + ": " + map.get(keys.get(1)).getPrettyString() + ", ..., " +
|
||||||
keys.get(max - 2).getPrettyString() + ": " + map.get(keys.get(max - 2)).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
|
@Override
|
||||||
public Value deepcopy()
|
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()));
|
map.forEach((key, value) -> copyMap.put(key.deepcopy(), value.deepcopy()));
|
||||||
return new MapValue(copyMap);
|
return new MapValue(copyMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
private MapValue(final Map<Value, Value> other)
|
private MapValue(Map<Value, Value> other)
|
||||||
{
|
{
|
||||||
map = other;
|
map = other;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static MapValue wrap(final Map<Value, Value> other)
|
public static MapValue wrap(Map<Value, Value> other)
|
||||||
{
|
{
|
||||||
return new MapValue(other);
|
return new MapValue(other);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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)
|
if (o instanceof final MapValue mapValue)
|
||||||
{
|
{
|
||||||
newItems.putAll(mapValue.map);
|
newItems.putAll(mapValue.map);
|
||||||
}
|
}
|
||||||
else if (o instanceof final AbstractListValue alv)
|
else if (o instanceof final AbstractListValue alv)
|
||||||
{
|
{
|
||||||
for (final Value value : alv)
|
for (Value value : alv)
|
||||||
{
|
{
|
||||||
newItems.put(value, Value.NULL);
|
newItems.put(value, Value.NULL);
|
||||||
}
|
}
|
||||||
@@ -123,24 +123,24 @@ public class MapValue extends AbstractListValue implements ContainerValueInterfa
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Value subtract(final Value v)
|
public Value subtract(Value v)
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("Cannot subtract from a map value");
|
throw new InternalExpressionException("Cannot subtract from a map value");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Value multiply(final Value v)
|
public Value multiply(Value v)
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("Cannot multiply with a map value");
|
throw new InternalExpressionException("Cannot multiply with a map value");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Value divide(final Value v)
|
public Value divide(Value v)
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("Cannot divide a map value");
|
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))
|
if (!(v instanceof final ListValue pair))
|
||||||
{
|
{
|
||||||
@@ -155,19 +155,19 @@ public class MapValue extends AbstractListValue implements ContainerValueInterfa
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void append(final Value v)
|
public void append(Value v)
|
||||||
{
|
{
|
||||||
map.put(v, Value.NULL);
|
map.put(v, Value.NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int compareTo(final Value o)
|
public int compareTo(Value o)
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("Cannot compare with a map value");
|
throw new InternalExpressionException("Cannot compare with a map value");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(final Object o)
|
public boolean equals(Object o)
|
||||||
{
|
{
|
||||||
return o instanceof final MapValue mapValue && map.equals(mapValue.map);
|
return o instanceof final MapValue mapValue && map.equals(mapValue.map);
|
||||||
}
|
}
|
||||||
@@ -177,7 +177,7 @@ public class MapValue extends AbstractListValue implements ContainerValueInterfa
|
|||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void extend(final List<Value> subList)
|
public void extend(List<Value> subList)
|
||||||
{
|
{
|
||||||
subList.forEach(this::put);
|
subList.forEach(this::put);
|
||||||
}
|
}
|
||||||
@@ -189,19 +189,19 @@ public class MapValue extends AbstractListValue implements ContainerValueInterfa
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Value in(final Value value)
|
public Value in(Value value)
|
||||||
{
|
{
|
||||||
return map.containsKey(value) ? value : Value.NULL;
|
return map.containsKey(value) ? value : Value.NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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");
|
throw new InternalExpressionException("Cannot slice a map value");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Value split(final Value delimiter)
|
public Value split(Value delimiter)
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("Cannot split a map value");
|
throw new InternalExpressionException("Cannot split a map value");
|
||||||
}
|
}
|
||||||
@@ -213,25 +213,25 @@ public class MapValue extends AbstractListValue implements ContainerValueInterfa
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Value get(final Value v2)
|
public Value get(Value v2)
|
||||||
{
|
{
|
||||||
return map.getOrDefault(v2, Value.NULL);
|
return map.getOrDefault(v2, Value.NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean has(final Value where)
|
public boolean has(Value where)
|
||||||
{
|
{
|
||||||
return map.containsKey(where);
|
return map.containsKey(where);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean delete(final Value where)
|
public boolean delete(Value where)
|
||||||
{
|
{
|
||||||
return map.remove(where) != null;
|
return map.remove(where) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean put(final Value key, final Value value)
|
public boolean put(Value key, Value value)
|
||||||
{
|
{
|
||||||
return map.put(key, value) != null;
|
return map.put(key, value) != null;
|
||||||
}
|
}
|
||||||
@@ -249,9 +249,9 @@ public class MapValue extends AbstractListValue implements ContainerValueInterfa
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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) ->
|
map.forEach((k, v) ->
|
||||||
{
|
{
|
||||||
if (!force && !(k instanceof StringValue))
|
if (!force && !(k instanceof StringValue))
|
||||||
@@ -266,8 +266,8 @@ public class MapValue extends AbstractListValue implements ContainerValueInterfa
|
|||||||
@Override
|
@Override
|
||||||
public JsonElement toJson()
|
public JsonElement toJson()
|
||||||
{
|
{
|
||||||
final JsonObject jsonMap = new JsonObject();
|
JsonObject jsonMap = new JsonObject();
|
||||||
final List<Value> keys = new ArrayList<>(map.keySet());
|
List<Value> keys = new ArrayList<>(map.keySet());
|
||||||
Collections.sort(keys);
|
Collections.sort(keys);
|
||||||
keys.forEach(k -> jsonMap.add(k.getString(), map.get(k).toJson()));
|
keys.forEach(k -> jsonMap.add(k.getString(), map.get(k).toJson()));
|
||||||
return jsonMap;
|
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.level.block.state.BlockState;
|
||||||
import net.minecraft.world.phys.AABB;
|
import net.minecraft.world.phys.AABB;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
public class NBTSerializableValue extends Value implements ContainerValueInterface
|
public class NBTSerializableValue extends Value implements ContainerValueInterface
|
||||||
{
|
{
|
||||||
private String nbtString = null;
|
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 = () ->
|
nbtSupplier = () ->
|
||||||
{
|
{
|
||||||
@@ -74,7 +76,7 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa
|
|||||||
{
|
{
|
||||||
return (new TagParser(new StringReader(nbtString))).readValue();
|
return (new TagParser(new StringReader(nbtString))).readValue();
|
||||||
}
|
}
|
||||||
catch (final CommandSyntaxException e)
|
catch (CommandSyntaxException e)
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("Incorrect NBT data: " + nbtString);
|
throw new InternalExpressionException("Incorrect NBT data: " + nbtString);
|
||||||
}
|
}
|
||||||
@@ -82,13 +84,13 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa
|
|||||||
owned = true;
|
owned = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public NBTSerializableValue(final Tag tag)
|
public NBTSerializableValue(Tag tag)
|
||||||
{
|
{
|
||||||
nbtTag = tag;
|
nbtTag = tag;
|
||||||
owned = true;
|
owned = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Value of(final Tag tag)
|
public static Value of(Tag tag)
|
||||||
{
|
{
|
||||||
if (tag == null)
|
if (tag == null)
|
||||||
{
|
{
|
||||||
@@ -97,49 +99,57 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa
|
|||||||
return new NBTSerializableValue(tag);
|
return new NBTSerializableValue(tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
public NBTSerializableValue(final Supplier<Tag> tagSupplier)
|
public NBTSerializableValue(Supplier<Tag> tagSupplier)
|
||||||
{
|
{
|
||||||
nbtSupplier = tagSupplier;
|
nbtSupplier = tagSupplier;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Value fromStack(final ItemStack stack)
|
public static Value fromStack(ItemStack stack)
|
||||||
{
|
{
|
||||||
if (stack.hasTag())
|
if (stack.hasTag())
|
||||||
{
|
{
|
||||||
final NBTSerializableValue value = new NBTSerializableValue();
|
NBTSerializableValue value = new NBTSerializableValue();
|
||||||
value.nbtSupplier = stack::getTag;
|
value.nbtSupplier = stack::getTag;
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
return Value.NULL;
|
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 StringValue.of(nameFromResource(id));
|
||||||
{
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
return id.getNamespace().equals("minecraft") ? id.getPath() : id.toString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
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;
|
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()
|
public Value clone()
|
||||||
{
|
{
|
||||||
// sets only nbttag, even if emtpy;
|
// sets only nbttag, even if emtpy;
|
||||||
final NBTSerializableValue copy = new NBTSerializableValue(nbtTag);
|
NBTSerializableValue copy = new NBTSerializableValue(nbtTag);
|
||||||
copy.nbtSupplier = this.nbtSupplier;
|
copy.nbtSupplier = this.nbtSupplier;
|
||||||
copy.nbtString = this.nbtString;
|
copy.nbtString = this.nbtString;
|
||||||
copy.owned = this.owned;
|
copy.owned = this.owned;
|
||||||
@@ -157,7 +167,7 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa
|
|||||||
@Override
|
@Override
|
||||||
public Value deepcopy()
|
public Value deepcopy()
|
||||||
{
|
{
|
||||||
final NBTSerializableValue copy = (NBTSerializableValue) clone();
|
NBTSerializableValue copy = (NBTSerializableValue) clone();
|
||||||
copy.owned = false;
|
copy.owned = false;
|
||||||
ensureOwnership();
|
ensureOwnership();
|
||||||
return copy;
|
return copy;
|
||||||
@@ -170,18 +180,18 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa
|
|||||||
}
|
}
|
||||||
|
|
||||||
// stolen from HopperBlockEntity, adjusted for threaded operation
|
// 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;
|
Container inventory = null;
|
||||||
final BlockState blockState = world.getBlockState(blockPos);
|
BlockState blockState = world.getBlockState(blockPos);
|
||||||
final Block block = blockState.getBlock();
|
Block block = blockState.getBlock();
|
||||||
if (block instanceof final WorldlyContainerHolder containerHolder)
|
if (block instanceof final WorldlyContainerHolder containerHolder)
|
||||||
{
|
{
|
||||||
inventory = containerHolder.getContainer(blockState, world, blockPos);
|
inventory = containerHolder.getContainer(blockState, world, blockPos);
|
||||||
}
|
}
|
||||||
else if (blockState.hasBlockEntity())
|
else if (blockState.hasBlockEntity())
|
||||||
{
|
{
|
||||||
final BlockEntity blockEntity = BlockValue.getBlockEntity(world, blockPos);
|
BlockEntity blockEntity = BlockValue.getBlockEntity(world, blockPos);
|
||||||
if (blockEntity instanceof final Container inventoryHolder)
|
if (blockEntity instanceof final Container inventoryHolder)
|
||||||
{
|
{
|
||||||
inventory = inventoryHolder;
|
inventory = inventoryHolder;
|
||||||
@@ -194,7 +204,7 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa
|
|||||||
|
|
||||||
if (inventory == null)
|
if (inventory == null)
|
||||||
{
|
{
|
||||||
final List<Entity> list = world.getEntities(
|
List<Entity> list = world.getEntities(
|
||||||
(Entity) null, //TODO check this matches the correct method
|
(Entity) null, //TODO check this matches the correct method
|
||||||
new AABB(
|
new AABB(
|
||||||
blockPos.getX() - 0.5D, blockPos.getY() - 0.5D, blockPos.getZ() - 0.5D,
|
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;
|
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
|
try
|
||||||
{
|
{
|
||||||
@@ -225,8 +235,8 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa
|
|||||||
String strVal = v1.getString().toLowerCase(Locale.ROOT);
|
String strVal = v1.getString().toLowerCase(Locale.ROOT);
|
||||||
if (strVal.equals("enderchest"))
|
if (strVal.equals("enderchest"))
|
||||||
{
|
{
|
||||||
final Value v2 = params.get(1 + offset);
|
Value v2 = params.get(1 + offset);
|
||||||
final ServerPlayer player = EntityValue.getPlayerByValue(c.server(), v2);
|
ServerPlayer player = EntityValue.getPlayerByValue(c.server(), v2);
|
||||||
if (player == null)
|
if (player == null)
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("enderchest inventory requires player argument");
|
throw new InternalExpressionException("enderchest inventory requires player argument");
|
||||||
@@ -235,24 +245,24 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa
|
|||||||
}
|
}
|
||||||
if (strVal.equals("equipment"))
|
if (strVal.equals("equipment"))
|
||||||
{
|
{
|
||||||
final Value v2 = params.get(1 + offset);
|
Value v2 = params.get(1 + offset);
|
||||||
if (!(v2 instanceof final EntityValue ev))
|
if (!(v2 instanceof final EntityValue ev))
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("Equipment inventory requires a living entity argument");
|
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))
|
if (!(e instanceof final LivingEntity le))
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("Equipment inventory requires a living entity argument");
|
throw new InternalExpressionException("Equipment inventory requires a living entity argument");
|
||||||
}
|
}
|
||||||
return new InventoryLocator(e, e.blockPosition(), new EquipmentInventory(le), offset + 2);
|
return new InventoryLocator(e, e.blockPosition(), new EquipmentInventory(le), offset + 2);
|
||||||
}
|
}
|
||||||
final boolean isEnder = strVal.startsWith("enderchest_");
|
boolean isEnder = strVal.startsWith("enderchest_");
|
||||||
if (isEnder)
|
if (isEnder)
|
||||||
{
|
{
|
||||||
strVal = strVal.substring(11); // len("enderchest_")
|
strVal = strVal.substring(11); // len("enderchest_")
|
||||||
}
|
}
|
||||||
final ServerPlayer player = c.server().getPlayerList().getPlayerByName(strVal);
|
ServerPlayer player = c.server().getPlayerList().getPlayerByName(strVal);
|
||||||
if (player == null)
|
if (player == null)
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("String description of an inventory should either denote a player or player's enderchest");
|
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)
|
if (v1 instanceof final EntityValue ev)
|
||||||
{
|
{
|
||||||
Container inv = null;
|
Container inv = null;
|
||||||
final Entity e = ev.getEntity();
|
Entity e = ev.getEntity();
|
||||||
if (e instanceof final Player pe)
|
if (e instanceof final Player pe)
|
||||||
{
|
{
|
||||||
inv = pe.getInventory();
|
inv = pe.getInventory();
|
||||||
@@ -294,36 +304,36 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa
|
|||||||
}
|
}
|
||||||
if (v1 instanceof final BlockValue bv)
|
if (v1 instanceof final BlockValue bv)
|
||||||
{
|
{
|
||||||
final BlockPos pos = bv.getPos();
|
BlockPos pos = bv.getPos();
|
||||||
if (pos == null)
|
if (pos == null)
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("Block to access inventory needs to be positioned in the world");
|
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);
|
return inv == null ? null : new InventoryLocator(pos, pos, inv, offset + 1);
|
||||||
}
|
}
|
||||||
if (v1 instanceof final ListValue lv)
|
if (v1 instanceof final ListValue lv)
|
||||||
{
|
{
|
||||||
final List<Value> args = lv.getItems();
|
List<Value> args = lv.getItems();
|
||||||
final BlockPos pos = new BlockPos(
|
BlockPos pos = new BlockPos(
|
||||||
NumericValue.asNumber(args.get(0)).getDouble(),
|
NumericValue.asNumber(args.get(0)).getDouble(),
|
||||||
NumericValue.asNumber(args.get(1)).getDouble(),
|
NumericValue.asNumber(args.get(1)).getDouble(),
|
||||||
NumericValue.asNumber(args.get(2)).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);
|
return inv == null ? null : new InventoryLocator(pos, pos, inv, offset + 1);
|
||||||
}
|
}
|
||||||
if (v1 instanceof final ScreenValue screenValue)
|
if (v1 instanceof final ScreenValue screenValue)
|
||||||
{
|
{
|
||||||
return !screenValue.isOpen() ? null : new InventoryLocator(screenValue.getPlayer(), screenValue.getPlayer().blockPosition(), screenValue.getInventory(), offset + 1);
|
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(v1).getDouble(),
|
||||||
NumericValue.asNumber(params.get(1 + offset)).getDouble(),
|
NumericValue.asNumber(params.get(1 + offset)).getDouble(),
|
||||||
NumericValue.asNumber(params.get(2 + 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);
|
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");
|
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<>();
|
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);
|
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
|
try
|
||||||
{
|
{
|
||||||
@@ -345,7 +355,7 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa
|
|||||||
{
|
{
|
||||||
return customTag == null ? res : new ItemInput(Holder.direct(res.getItem()), customTag);
|
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());
|
res = new ItemInput(parser.item(), parser.nbt());
|
||||||
|
|
||||||
itemCache.put(itemString, res);
|
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);
|
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);
|
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)
|
if (slot < 0)
|
||||||
{
|
{
|
||||||
slot = invSize + slot;
|
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
|
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)
|
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());
|
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);
|
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)
|
if (t instanceof final CompoundTag ctag)
|
||||||
{
|
{
|
||||||
final Map<Value, Value> pairs = new HashMap<>();
|
Map<Value, Value> pairs = new HashMap<>();
|
||||||
for (final String key : ctag.getAllKeys())
|
for (String key : ctag.getAllKeys())
|
||||||
{
|
{
|
||||||
pairs.put(new StringValue(key), decodeTagDeep(ctag.get(key)));
|
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)
|
if (t instanceof final CollectionTag<?> ltag)
|
||||||
{
|
{
|
||||||
final List<Value> elems = new ArrayList<>();
|
List<Value> elems = new ArrayList<>();
|
||||||
for (final Tag elem : ltag)
|
for (Tag elem : ltag)
|
||||||
{
|
{
|
||||||
elems.add(decodeTagDeep(elem));
|
elems.add(decodeTagDeep(elem));
|
||||||
}
|
}
|
||||||
@@ -422,7 +432,7 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa
|
|||||||
return decodeTagDeep(this.getTag());
|
return decodeTagDeep(this.getTag());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Value fromValue(final Value v)
|
public static Value fromValue(Value v)
|
||||||
{
|
{
|
||||||
if (v instanceof NBTSerializableValue)
|
if (v instanceof NBTSerializableValue)
|
||||||
{
|
{
|
||||||
@@ -432,7 +442,7 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa
|
|||||||
{
|
{
|
||||||
return Value.NULL;
|
return Value.NULL;
|
||||||
}
|
}
|
||||||
return NBTSerializableValue.parseString(v.getString(), true);
|
return NBTSerializableValue.parseStringOrFail(v.getString());
|
||||||
}
|
}
|
||||||
|
|
||||||
public Tag getTag()
|
public Tag getTag()
|
||||||
@@ -445,7 +455,7 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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);
|
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
|
@Override
|
||||||
public boolean getBoolean()
|
public boolean getBoolean()
|
||||||
{
|
{
|
||||||
final Tag tag = getTag();
|
Tag tag = getTag();
|
||||||
if (tag instanceof final CompoundTag ctag)
|
if (tag instanceof final CompoundTag ctag)
|
||||||
{
|
{
|
||||||
return !(ctag).isEmpty();
|
return !(ctag).isEmpty();
|
||||||
@@ -490,35 +500,35 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa
|
|||||||
ensureOwnership();
|
ensureOwnership();
|
||||||
return (CompoundTag) getTag();
|
return (CompoundTag) getTag();
|
||||||
}
|
}
|
||||||
catch (final ClassCastException e)
|
catch (ClassCastException e)
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException(getString() + " is not a valid compound tag");
|
throw new InternalExpressionException(getString() + " is not a valid compound tag");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean put(final Value where, final Value value)
|
public boolean put(Value where, Value value)
|
||||||
{
|
{
|
||||||
return put(where, value, new StringValue("replace"));
|
return put(where, value, new StringValue("replace"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean put(final Value where, final Value value, final Value conditions)
|
public boolean put(Value where, Value value, Value conditions)
|
||||||
{
|
{
|
||||||
/// WIP
|
/// WIP
|
||||||
ensureOwnership();
|
ensureOwnership();
|
||||||
final NbtPathArgument.NbtPath path = cachePath(where.getString());
|
NbtPathArgument.NbtPath path = cachePath(where.getString());
|
||||||
final Tag tagToInsert = value instanceof final NBTSerializableValue nbtsv
|
Tag tagToInsert = value instanceof final NBTSerializableValue nbtsv
|
||||||
? nbtsv.getTag()
|
? nbtsv.getTag()
|
||||||
: new NBTSerializableValue(value.getString()).getTag();
|
: new NBTSerializableValue(value.getString()).getTag();
|
||||||
final boolean modifiedTag;
|
boolean modifiedTag;
|
||||||
if (conditions instanceof final NumericValue number)
|
if (conditions instanceof final NumericValue number)
|
||||||
{
|
{
|
||||||
modifiedTag = modifyInsert((int) number.getLong(), path, tagToInsert);
|
modifiedTag = modifyInsert((int) number.getLong(), path, tagToInsert);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
final String ops = conditions.getString();
|
String ops = conditions.getString();
|
||||||
if (ops.equalsIgnoreCase("merge"))
|
if (ops.equalsIgnoreCase("merge"))
|
||||||
{
|
{
|
||||||
modifiedTag = modifyMerge(path, tagToInsert);
|
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());
|
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
|
try
|
||||||
{
|
{
|
||||||
targets = nbtPath.getOrCreate(currentTag, ListTag::new);
|
targets = nbtPath.getOrCreate(currentTag, ListTag::new);
|
||||||
}
|
}
|
||||||
catch (final CommandSyntaxException e)
|
catch (CommandSyntaxException e)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean modified = false;
|
boolean modified = false;
|
||||||
for (final Tag target : targets)
|
for (Tag target : targets)
|
||||||
{
|
{
|
||||||
if (!(target instanceof final CollectionTag<?> targetList))
|
if (!(target instanceof final CollectionTag<?> targetList))
|
||||||
{
|
{
|
||||||
@@ -572,7 +582,7 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa
|
|||||||
}
|
}
|
||||||
modified = true;
|
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))
|
if (!(replacement instanceof final CompoundTag replacementCompound))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
final Tag ownTag = getTag();
|
Tag ownTag = getTag();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
for (final Tag target : nbtPath.getOrCreate(ownTag, CompoundTag::new))
|
for (Tag target : nbtPath.getOrCreate(ownTag, CompoundTag::new))
|
||||||
{
|
{
|
||||||
if (!(target instanceof final CompoundTag targetCompound))
|
if (!(target instanceof final CompoundTag targetCompound))
|
||||||
{
|
{
|
||||||
@@ -598,31 +608,31 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa
|
|||||||
targetCompound.merge(replacementCompound);
|
targetCompound.merge(replacementCompound);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (final CommandSyntaxException ignored)
|
catch (CommandSyntaxException ignored)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
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();
|
Tag tag = getTag();
|
||||||
final String pathText = nbtPath.toString();
|
String pathText = nbtPath.toString();
|
||||||
if (pathText.endsWith("]")) // workaround for array replacement or item in the array replacement
|
if (pathText.endsWith("]")) // workaround for array replacement or item in the array replacement
|
||||||
{
|
{
|
||||||
if (nbtPath.remove(tag) == 0)
|
if (nbtPath.remove(tag) == 0)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
final Pattern pattern = Pattern.compile("\\[[^\\[]*]$");
|
Pattern pattern = Pattern.compile("\\[[^\\[]*]$");
|
||||||
final Matcher matcher = pattern.matcher(pathText);
|
Matcher matcher = pattern.matcher(pathText);
|
||||||
if (!matcher.find()) // malformed path
|
if (!matcher.find()) // malformed path
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
final String arrAccess = matcher.group();
|
String arrAccess = matcher.group();
|
||||||
final int pos;
|
int pos;
|
||||||
if (arrAccess.length() == 2) // we just removed entire array
|
if (arrAccess.length() == 2) // we just removed entire array
|
||||||
{
|
{
|
||||||
pos = 0;
|
pos = 0;
|
||||||
@@ -633,19 +643,19 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa
|
|||||||
{
|
{
|
||||||
pos = Integer.parseInt(arrAccess.substring(1, arrAccess.length() - 1));
|
pos = Integer.parseInt(arrAccess.substring(1, arrAccess.length() - 1));
|
||||||
}
|
}
|
||||||
catch (final NumberFormatException e)
|
catch (NumberFormatException e)
|
||||||
{
|
{
|
||||||
return false;
|
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);
|
return modifyInsert(pos, newPath, replacement, tag);
|
||||||
}
|
}
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
nbtPath.set(tag, replacement);
|
nbtPath.set(tag, replacement);
|
||||||
}
|
}
|
||||||
catch (final CommandSyntaxException e)
|
catch (CommandSyntaxException e)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -653,13 +663,13 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Value get(final Value value)
|
public Value get(Value value)
|
||||||
{
|
{
|
||||||
final String valString = value.getString();
|
String valString = value.getString();
|
||||||
final NbtPathArgument.NbtPath path = cachePath(valString);
|
NbtPathArgument.NbtPath path = cachePath(valString);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
final List<Tag> tags = path.get(getTag());
|
List<Tag> tags = path.get(getTag());
|
||||||
if (tags.isEmpty())
|
if (tags.isEmpty())
|
||||||
{
|
{
|
||||||
return Value.NULL;
|
return Value.NULL;
|
||||||
@@ -670,14 +680,14 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa
|
|||||||
}
|
}
|
||||||
return ListValue.wrap(tags.stream().map(NBTSerializableValue::decodeTag));
|
return ListValue.wrap(tags.stream().map(NBTSerializableValue::decodeTag));
|
||||||
}
|
}
|
||||||
catch (final CommandSyntaxException ignored)
|
catch (CommandSyntaxException ignored)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
return Value.NULL;
|
return Value.NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean has(final Value where)
|
public boolean has(Value where)
|
||||||
{
|
{
|
||||||
return cachePath(where.getString()).countMatching(getTag()) > 0;
|
return cachePath(where.getString()).countMatching(getTag()) > 0;
|
||||||
}
|
}
|
||||||
@@ -699,11 +709,11 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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();
|
ensureOwnership();
|
||||||
final int removed = path.remove(getTag());
|
int removed = path.remove(getTag());
|
||||||
if (removed > 0)
|
if (removed > 0)
|
||||||
{
|
{
|
||||||
dirty();
|
dirty();
|
||||||
@@ -715,7 +725,7 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa
|
|||||||
public record InventoryLocator(Object owner, BlockPos position, Container inventory, int offset,
|
public record InventoryLocator(Object owner, BlockPos position, Container inventory, int offset,
|
||||||
boolean isEnder)
|
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);
|
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 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);
|
NbtPathArgument.NbtPath res = pathCache.get(arg);
|
||||||
if (res != null)
|
if (res != null)
|
||||||
@@ -734,7 +744,7 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa
|
|||||||
{
|
{
|
||||||
res = NbtPathArgument.nbtPath().parse(new StringReader(arg));
|
res = NbtPathArgument.nbtPath().parse(new StringReader(arg));
|
||||||
}
|
}
|
||||||
catch (final CommandSyntaxException exc)
|
catch (CommandSyntaxException exc)
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("Incorrect nbt path: " + arg);
|
throw new InternalExpressionException("Incorrect nbt path: " + arg);
|
||||||
}
|
}
|
||||||
@@ -754,7 +764,7 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa
|
|||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Tag toTag(final boolean force)
|
public Tag toTag(boolean force)
|
||||||
{
|
{
|
||||||
if (!force)
|
if (!force)
|
||||||
{
|
{
|
||||||
@@ -768,7 +778,7 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa
|
|||||||
{
|
{
|
||||||
public final Value val;
|
public final Value val;
|
||||||
|
|
||||||
public IncompatibleTypeException(final Value val)
|
public IncompatibleTypeException(Value val)
|
||||||
{
|
{
|
||||||
this.val = val;
|
this.val = val;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,13 +41,13 @@ public class NullValue extends NumericValue // TODO check nonsingleton code
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(final Object o)
|
public boolean equals(Object o)
|
||||||
{
|
{
|
||||||
return o instanceof Value value && value.isNull();
|
return o instanceof Value value && value.isNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Value slice(final long fromDesc, final Long toDesc)
|
public Value slice(long fromDesc, Long toDesc)
|
||||||
{
|
{
|
||||||
return Value.NULL;
|
return Value.NULL;
|
||||||
}
|
}
|
||||||
@@ -65,13 +65,13 @@ public class NullValue extends NumericValue // TODO check nonsingleton code
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int compareTo(final Value o)
|
public int compareTo(Value o)
|
||||||
{
|
{
|
||||||
return o.isNull() ? 0 : -1;
|
return o.isNull() ? 0 : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Value in(final Value value)
|
public Value in(Value value)
|
||||||
{
|
{
|
||||||
return Value.NULL;
|
return Value.NULL;
|
||||||
}
|
}
|
||||||
@@ -89,7 +89,7 @@ public class NullValue extends NumericValue // TODO check nonsingleton code
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Tag toTag(final boolean force)
|
public Tag toTag(boolean force)
|
||||||
{
|
{
|
||||||
if (!force)
|
if (!force)
|
||||||
{
|
{
|
||||||
@@ -99,7 +99,7 @@ public class NullValue extends NumericValue // TODO check nonsingleton code
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Value split(final Value delimiter)
|
public Value split(Value delimiter)
|
||||||
{
|
{
|
||||||
return ListValue.wrap(new ArrayList<>());
|
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 double epsilon = abs(32 * ((7 * 0.1) * 10 - 7));
|
||||||
private static final MathContext displayRounding = new MathContext(12, RoundingMode.HALF_EVEN);
|
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)
|
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");
|
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)
|
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");
|
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)
|
if (value == null)
|
||||||
{
|
{
|
||||||
@@ -85,7 +85,7 @@ public class NumericValue extends Value
|
|||||||
// dobules have 16 point precision, 12 is plenty to display
|
// dobules have 16 point precision, 12 is plenty to display
|
||||||
return BigDecimal.valueOf(value).round(displayRounding).stripTrailingZeros().toPlainString();
|
return BigDecimal.valueOf(value).round(displayRounding).stripTrailingZeros().toPlainString();
|
||||||
}
|
}
|
||||||
catch (final NumberFormatException exc)
|
catch (NumberFormatException exc)
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("Incorrect number format for " + value);
|
throw new InternalExpressionException("Incorrect number format for " + value);
|
||||||
}
|
}
|
||||||
@@ -115,9 +115,9 @@ public class NumericValue extends Value
|
|||||||
return (float) 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;
|
return v < invValue ? invValue - 1 : invValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -127,7 +127,7 @@ public class NumericValue extends Value
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Value add(final Value v)
|
public Value add(Value v)
|
||||||
{ // TODO test if definintn add(NumericVlaue) woud solve the casting
|
{ // TODO test if definintn add(NumericVlaue) woud solve the casting
|
||||||
if (v instanceof final NumericValue nv)
|
if (v instanceof final NumericValue nv)
|
||||||
{
|
{
|
||||||
@@ -137,7 +137,7 @@ public class NumericValue extends Value
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Value subtract(final Value v)
|
public Value subtract(Value v)
|
||||||
{ // TODO test if definintn add(NumericVlaue) woud solve the casting
|
{ // TODO test if definintn add(NumericVlaue) woud solve the casting
|
||||||
if (v instanceof final NumericValue nv)
|
if (v instanceof final NumericValue nv)
|
||||||
{
|
{
|
||||||
@@ -147,7 +147,7 @@ public class NumericValue extends Value
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Value multiply(final Value v)
|
public Value multiply(Value v)
|
||||||
{
|
{
|
||||||
if (v instanceof final NumericValue nv)
|
if (v instanceof final NumericValue nv)
|
||||||
{
|
{
|
||||||
@@ -157,7 +157,7 @@ public class NumericValue extends Value
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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);
|
return v instanceof final NumericValue nv ? new NumericValue(getDouble() / nv.getDouble()) : super.divide(v);
|
||||||
}
|
}
|
||||||
@@ -169,7 +169,7 @@ public class NumericValue extends Value
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int compareTo(final Value o)
|
public int compareTo(Value o)
|
||||||
{
|
{
|
||||||
if (o.isNull())
|
if (o.isNull())
|
||||||
{
|
{
|
||||||
@@ -183,7 +183,7 @@ public class NumericValue extends Value
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(final Object o)
|
public boolean equals(Object o)
|
||||||
{
|
{
|
||||||
if (o instanceof final Value otherValue)
|
if (o instanceof final Value otherValue)
|
||||||
{
|
{
|
||||||
@@ -200,34 +200,34 @@ public class NumericValue extends Value
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public NumericValue(final double value)
|
public NumericValue(double value)
|
||||||
{
|
{
|
||||||
this.value = value;
|
this.value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
private NumericValue(final double value, final Long longValue)
|
private NumericValue(double value, Long longValue)
|
||||||
{
|
{
|
||||||
this.value = value;
|
this.value = value;
|
||||||
this.longValue = longValue;
|
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)
|
if (decimal.stripTrailingZeros().scale() <= 0)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
longValue = decimal.longValueExact();
|
longValue = decimal.longValueExact();
|
||||||
}
|
}
|
||||||
catch (final ArithmeticException ignored)
|
catch (ArithmeticException ignored)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.value = decimal.doubleValue();
|
this.value = decimal.doubleValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
public NumericValue(final long value)
|
public NumericValue(long value)
|
||||||
{
|
{
|
||||||
this.longValue = value;
|
this.longValue = value;
|
||||||
this.value = (double) value;
|
this.value = (double) value;
|
||||||
@@ -271,7 +271,7 @@ public class NumericValue extends Value
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Tag toTag(final boolean force)
|
public Tag toTag(boolean force)
|
||||||
{
|
{
|
||||||
if (longValue != null)
|
if (longValue != null)
|
||||||
{
|
{
|
||||||
@@ -281,7 +281,7 @@ public class NumericValue extends Value
|
|||||||
}
|
}
|
||||||
return LongTag.valueOf(longValue);
|
return LongTag.valueOf(longValue);
|
||||||
}
|
}
|
||||||
final long lv = getLong();
|
long lv = getLong();
|
||||||
if (value == (double) lv)
|
if (value == (double) lv)
|
||||||
{
|
{
|
||||||
if (abs(value) < Integer.MAX_VALUE - 2)
|
if (abs(value) < Integer.MAX_VALUE - 2)
|
||||||
@@ -303,7 +303,7 @@ public class NumericValue extends Value
|
|||||||
{
|
{
|
||||||
return new JsonPrimitive(longValue);
|
return new JsonPrimitive(longValue);
|
||||||
}
|
}
|
||||||
final long lv = getLong();
|
long lv = getLong();
|
||||||
return new JsonPrimitive(value == lv ? getLong() : value);
|
return new JsonPrimitive(value == lv ? getLong() : value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -317,14 +317,14 @@ public class NumericValue extends Value
|
|||||||
return longValue != null || getDouble() == getLong();
|
return longValue != null || getDouble() == getLong();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Value mod(final NumericValue n2)
|
public Value mod(NumericValue n2)
|
||||||
{
|
{
|
||||||
if (this.longValue != null && n2.longValue != null)
|
if (this.longValue != null && n2.longValue != null)
|
||||||
{
|
{
|
||||||
return new NumericValue(Math.floorMod(longValue, n2.longValue));
|
return new NumericValue(Math.floorMod(longValue, n2.longValue));
|
||||||
}
|
}
|
||||||
final double x = value;
|
double x = value;
|
||||||
final double y = n2.value;
|
double y = n2.value;
|
||||||
if (y == 0)
|
if (y == 0)
|
||||||
{
|
{
|
||||||
throw new ArithmeticException("Division by zero");
|
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