Merge branch 'master' into 1.17
This commit is contained in:
commit
6108cdce23
17 files changed
+170
-62
No files matched your search
@@ -159,7 +159,8 @@ jobs:
|
|||||||
"id": "carpet",
|
"id": "carpet",
|
||||||
"version": "1.4.11",
|
"version": "1.4.11",
|
||||||
"entrypoints": {
|
"entrypoints": {
|
||||||
"preLaunch": [ "carpet.utils.RulePrinter" ]
|
"server": [ "carpet.utils.CarpetRulePrinter" ],
|
||||||
|
"preLaunch": [ "carpet.utils.CarpetRulePrinter" ]
|
||||||
}
|
}
|
||||||
}' > fabric.mod.json
|
}' > fabric.mod.json
|
||||||
cd ../../../
|
cd ../../../
|
||||||
|
|||||||
@@ -4183,7 +4183,7 @@ ingested by the player. The exact position of these items is unknown as technica
|
|||||||
items could be spread all across the inventory.
|
items could be spread all across the inventory.
|
||||||
|
|
||||||
### `__on_player_connects(player)`
|
### `__on_player_connects(player)`
|
||||||
Triggered when the player has successfully logged in and was placed in the gaem.
|
Triggered when the player has successfully logged in and was placed in the game.
|
||||||
|
|
||||||
### `__on_player_disconnects(player, reason)`
|
### `__on_player_disconnects(player, reason)`
|
||||||
Triggered when a player sends a disconnect package or is forcefully disconnected from the server.
|
Triggered when a player sends a disconnect package or is forcefully disconnected from the server.
|
||||||
|
|||||||
@@ -27,11 +27,32 @@ Here is a list of events that are handled by default in scarpet. This list inclu
|
|||||||
to autoload them, but you can always add any function to any event (using `/script event` command)
|
to autoload them, but you can always add any function to any event (using `/script event` command)
|
||||||
if it accepts required number of parameters.
|
if it accepts required number of parameters.
|
||||||
|
|
||||||
|
## Meta-events
|
||||||
|
|
||||||
|
These events are not controlled / triggered by the game per se, but are important for the flow of the apps, however for all
|
||||||
|
intent and purpose can be treated as regular events. Unlike regular events, they cannot be hooked up to with 'handle_event',
|
||||||
|
but the apps themselves need to have them defined as distinct function definitions, same they cannot be signalled.
|
||||||
|
|
||||||
|
### `__on_start()`
|
||||||
|
Called once per app in its logical execution run. For `'global'` scope apps its executed right after the app is loaded. For
|
||||||
|
`'player'` scope apps, it is triggered once per player before the app can be used by that player. Since each player app acts
|
||||||
|
independently from other player apps, this is probably the best location to include some player specific initializations. Static
|
||||||
|
code (i.e. code typed directly in the app code that executes immediately, outside of function definitions), will only execute once
|
||||||
|
per app, regardless of scope, `'__on_start()'` allows to reliably call player specific initializations.
|
||||||
|
|
||||||
|
### `__on_close()`
|
||||||
|
|
||||||
|
Called once per app when the app is closing or reloading, right before the app is removed.
|
||||||
|
For player scoped apps, its called once per player. Scarpet app engine will attempt to call `'__on_close()'` even if
|
||||||
|
the system is closing down exceptionally.
|
||||||
|
|
||||||
|
|
||||||
## Built-in global events
|
## Built-in global events
|
||||||
|
|
||||||
Global events will be handled once per app that is with `'global'` scope. With `player` scoped apps, each player instance
|
Global events will be handled once per app that is with `'global'` scope. With `player` scoped apps, each player instance
|
||||||
is responsible independently from handling their events, so a global event may be executed multiple times for each player.
|
is responsible independently from handling their events, so a global event may be executed multiple times for each player.
|
||||||
|
|
||||||
|
|
||||||
### `__on_server_starts()`
|
### `__on_server_starts()`
|
||||||
Event triggers after world is loaded and after all startup apps have started. It won't be triggered with `/reload`.
|
Event triggers after world is loaded and after all startup apps have started. It won't be triggered with `/reload`.
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,11 @@ When loaded (via `/script load` command, etc.), the game will run the content of
|
|||||||
`__config()` function, if present, which will be executed once. Loading the app will also bind specific
|
`__config()` function, if present, which will be executed once. Loading the app will also bind specific
|
||||||
events to the event system (check Events section for details).
|
events to the event system (check Events section for details).
|
||||||
|
|
||||||
|
If an app defines `__on_start()` function, it will be executed once before running anything else. For global scoped apps,
|
||||||
|
this is just after they are loaded, and for player scoped apps, before they are used first time by a player.
|
||||||
|
Unlike static code (written directly in the body of the app code), that always run once per app, this may run multiple times if
|
||||||
|
its a player app nd multiple players are on the server.
|
||||||
|
|
||||||
Unloading an app removes all of its state from the game, disables commands, removes bounded events, and
|
Unloading an app removes all of its state from the game, disables commands, removes bounded events, and
|
||||||
saves its global state. If more cleanup is needed, one can define `__on_close()` function which will be
|
saves its global state. If more cleanup is needed, one can define `__on_close()` function which will be
|
||||||
executed when the module is unloaded, or server is closing or crashing. However, there is no need to do that
|
executed when the module is unloaded, or server is closing or crashing. However, there is no need to do that
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ __on_player_uses_item(player, item_tuple, hand) ->
|
|||||||
__on_player_wakes_up(player) ->
|
__on_player_wakes_up(player) ->
|
||||||
__on_player_escapes_sleep(player) ->
|
__on_player_escapes_sleep(player) ->
|
||||||
__on_statistic(player, category, event, value) ->
|
__on_statistic(player, category, event, value) ->
|
||||||
|
__on_start() ->
|
||||||
__on_tick() ->
|
__on_tick() ->
|
||||||
__on_tick_ender() ->
|
__on_tick_ender() ->
|
||||||
__on_tick_nether() ->
|
__on_tick_nether() ->
|
||||||
|
|||||||
@@ -129,6 +129,7 @@
|
|||||||
__on_player_wakes_up
|
__on_player_wakes_up
|
||||||
__on_player_escapes_sleep
|
__on_player_escapes_sleep
|
||||||
__on_statistic
|
__on_statistic
|
||||||
|
__on_start
|
||||||
__on_tick
|
__on_tick
|
||||||
__on_tick_ender
|
__on_tick_ender
|
||||||
__on_tick_nether
|
__on_tick_nether
|
||||||
|
|||||||
@@ -171,14 +171,22 @@ public class CarpetServer implements ClientModInitializer,DedicatedServerModInit
|
|||||||
|
|
||||||
public static void onServerClosed(MinecraftServer server)
|
public static void onServerClosed(MinecraftServer server)
|
||||||
{
|
{
|
||||||
if (scriptServer != null) scriptServer.onClose();
|
// this for whatever reason gets called multiple times even when joining on SP
|
||||||
ServerNetworkHandler.close();
|
// so we allow to pass multiple times gating it only on existing server ref
|
||||||
currentCommandDispatcher = null;
|
if (minecraft_server != null)
|
||||||
|
{
|
||||||
|
if (scriptServer != null) scriptServer.onClose();
|
||||||
|
ServerNetworkHandler.close();
|
||||||
|
currentCommandDispatcher = null;
|
||||||
|
|
||||||
LoggerRegistry.stopLoggers();
|
LoggerRegistry.stopLoggers();
|
||||||
extensions.forEach(e -> e.onServerClosed(server));
|
extensions.forEach(e -> e.onServerClosed(server));
|
||||||
minecraft_server = null;
|
minecraft_server = null;
|
||||||
disconnect();
|
}
|
||||||
|
|
||||||
|
// this for whatever reason gets called multiple times even when joining;
|
||||||
|
TickSpeed.reset();
|
||||||
|
settingsManager.detachServer();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void registerExtensionLoggers()
|
public static void registerExtensionLoggers()
|
||||||
@@ -186,13 +194,6 @@ public class CarpetServer implements ClientModInitializer,DedicatedServerModInit
|
|||||||
extensions.forEach(CarpetExtension::registerLoggers);
|
extensions.forEach(CarpetExtension::registerLoggers);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void disconnect()
|
|
||||||
{
|
|
||||||
// this for whatever reason gets called multiple times even when joining;
|
|
||||||
TickSpeed.reset();
|
|
||||||
settingsManager.detachServer();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void onReload(MinecraftServer server)
|
public static void onReload(MinecraftServer server)
|
||||||
{
|
{
|
||||||
scriptServer.reload(server);
|
scriptServer.reload(server);
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import carpet.script.utils.ShapesRenderer;
|
|||||||
import carpet.utils.FabricAPIHooks;
|
import carpet.utils.FabricAPIHooks;
|
||||||
import com.mojang.blaze3d.systems.RenderSystem;
|
import com.mojang.blaze3d.systems.RenderSystem;
|
||||||
import net.minecraft.client.MinecraftClient;
|
import net.minecraft.client.MinecraftClient;
|
||||||
|
import net.minecraft.client.gl.ShaderEffect;
|
||||||
import net.minecraft.client.render.BufferBuilderStorage;
|
import net.minecraft.client.render.BufferBuilderStorage;
|
||||||
import net.minecraft.client.render.Camera;
|
import net.minecraft.client.render.Camera;
|
||||||
import net.minecraft.client.render.GameRenderer;
|
import net.minecraft.client.render.GameRenderer;
|
||||||
@@ -13,6 +14,7 @@ import net.minecraft.client.render.WorldRenderer;
|
|||||||
import net.minecraft.client.util.math.MatrixStack;
|
import net.minecraft.client.util.math.MatrixStack;
|
||||||
import net.minecraft.util.math.Matrix4f;
|
import net.minecraft.util.math.Matrix4f;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
@@ -20,16 +22,39 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|||||||
@Mixin(WorldRenderer.class)
|
@Mixin(WorldRenderer.class)
|
||||||
public class WorldRenderer_scarpetRenderMixin
|
public class WorldRenderer_scarpetRenderMixin
|
||||||
{
|
{
|
||||||
|
@Shadow private /*@Nullable*/ ShaderEffect transparencyShader;
|
||||||
|
|
||||||
@Inject(method = "<init>", at = @At("RETURN"))
|
@Inject(method = "<init>", at = @At("RETURN"))
|
||||||
private void addRenderers(MinecraftClient client, BufferBuilderStorage bufferBuilders, CallbackInfo ci)
|
private void addRenderers(MinecraftClient client, BufferBuilderStorage bufferBuilders, CallbackInfo ci)
|
||||||
{
|
{
|
||||||
CarpetClient.shapes = new ShapesRenderer(client);
|
CarpetClient.shapes = new ShapesRenderer(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/debug/DebugRenderer;render(Lnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider$Immediate;DDD)V"))
|
@Inject(method = "render", at = @At(
|
||||||
|
value = "INVOKE",
|
||||||
|
target = "Lnet/minecraft/client/render/WorldRenderer;renderChunkDebugInfo(Lnet/minecraft/client/render/Camera;)V",
|
||||||
|
shift = At.Shift.AFTER
|
||||||
|
))
|
||||||
private void renderScarpetThings(MatrixStack matrices, float tickDelta, long limitTime, boolean renderBlockOutline, Camera camera, GameRenderer gameRenderer, LightmapTextureManager lightmapTextureManager, Matrix4f matrix4f, CallbackInfo ci)
|
private void renderScarpetThings(MatrixStack matrices, float tickDelta, long limitTime, boolean renderBlockOutline, Camera camera, GameRenderer gameRenderer, LightmapTextureManager lightmapTextureManager, Matrix4f matrix4f, CallbackInfo ci)
|
||||||
{
|
{
|
||||||
if (!FabricAPIHooks.WORLD_RENDER_EVENTS && CarpetClient.shapes != null)
|
// in normal circumstances we want to render shapes at the very end so it appears correctly behind stuff.
|
||||||
|
if (!FabricAPIHooks.WORLD_RENDER_EVENTS && CarpetClient.shapes != null && transparencyShader == null)
|
||||||
|
{
|
||||||
|
RenderSystem.pushMatrix();
|
||||||
|
CarpetClient.shapes.render(camera, tickDelta);
|
||||||
|
RenderSystem.popMatrix();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject(method = "render", at = @At(
|
||||||
|
value = "INVOKE",
|
||||||
|
target = "Lnet/minecraft/client/render/debug/DebugRenderer;render(Lnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider$Immediate;DDD)V",
|
||||||
|
shift = At.Shift.AFTER
|
||||||
|
))
|
||||||
|
private void renderScarpetThingsFabulously(MatrixStack matrices, float tickDelta, long limitTime, boolean renderBlockOutline, Camera camera, GameRenderer gameRenderer, LightmapTextureManager lightmapTextureManager, Matrix4f matrix4f, CallbackInfo ci)
|
||||||
|
{
|
||||||
|
// with fabulous graphics - stuff doesn't work this way for some reason - need to render with chunk lines.
|
||||||
|
if (!FabricAPIHooks.WORLD_RENDER_EVENTS && CarpetClient.shapes != null && transparencyShader != null)
|
||||||
{
|
{
|
||||||
RenderSystem.pushMatrix();
|
RenderSystem.pushMatrix();
|
||||||
CarpetClient.shapes.render(camera, tickDelta);
|
CarpetClient.shapes.render(camera, tickDelta);
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ public class CarpetClient
|
|||||||
{
|
{
|
||||||
isServerCarpet = false;
|
isServerCarpet = false;
|
||||||
clientPlayer = null;
|
clientPlayer = null;
|
||||||
CarpetServer.disconnect();
|
CarpetServer.onServerClosed(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void setCarpet()
|
public static void setCarpet()
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ public class CarpetScriptHost extends ScriptHost
|
|||||||
|
|
||||||
public static CarpetScriptHost create(CarpetScriptServer scriptServer, Module module, boolean perPlayer, ServerCommandSource source, Function<ServerCommandSource, Boolean> commandValidator, boolean isRuleApp)
|
public static CarpetScriptHost create(CarpetScriptServer scriptServer, Module module, boolean perPlayer, ServerCommandSource source, Function<ServerCommandSource, Boolean> commandValidator, boolean isRuleApp)
|
||||||
{
|
{
|
||||||
CarpetScriptHost host = new CarpetScriptHost(scriptServer, module, perPlayer, null, Collections.emptyMap(), new HashMap<>(), commandValidator, isRuleApp);
|
CarpetScriptHost host = new CarpetScriptHost(scriptServer, module, perPlayer, null, Collections.emptyMap(), new HashMap<>(), commandValidator, isRuleApp);
|
||||||
// parse code and convert to expression
|
// parse code and convert to expression
|
||||||
if (module != null)
|
if (module != null)
|
||||||
{
|
{
|
||||||
@@ -227,11 +227,14 @@ public class CarpetScriptHost extends ScriptHost
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void transferToChild(ScriptHost host)
|
protected void setupUserHost(ScriptHost host)
|
||||||
{
|
{
|
||||||
super.transferToChild(host);
|
super.setupUserHost(host);
|
||||||
// transfer Events
|
// transfer Events
|
||||||
CarpetEventServer.Event.transferAllHostEventsToChild((CarpetScriptHost) host);
|
CarpetScriptHost child = (CarpetScriptHost) host;
|
||||||
|
CarpetEventServer.Event.transferAllHostEventsToChild(child);
|
||||||
|
FunctionValue onStart = child.getFunction("__on_start");
|
||||||
|
if (onStart != null) child.callNow(onStart, Collections.emptyList());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -261,7 +264,9 @@ public class CarpetScriptHost extends ScriptHost
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Value ret = callUDF(BlockPos.ORIGIN, scriptServer.server.getCommandSource(), getFunction("__config"), Collections.emptyList());
|
FunctionValue configFunction = getFunction("__config");
|
||||||
|
if (configFunction == null) return false;
|
||||||
|
Value ret = callNow(configFunction, Collections.emptyList());
|
||||||
if (!(ret instanceof MapValue)) return false;
|
if (!(ret instanceof MapValue)) return false;
|
||||||
Map<Value, Value> config = ((MapValue) ret).getMap();
|
Map<Value, Value> config = ((MapValue) ret).getMap();
|
||||||
setPerPlayer(config.getOrDefault(new StringValue("scope"), new StringValue("player")).getString().equalsIgnoreCase("player"));
|
setPerPlayer(config.getOrDefault(new StringValue("scope"), new StringValue("player")).getString().equalsIgnoreCase("player"));
|
||||||
@@ -283,7 +288,7 @@ public class CarpetScriptHost extends ScriptHost
|
|||||||
}
|
}
|
||||||
appConfig = config;
|
appConfig = config;
|
||||||
}
|
}
|
||||||
catch (NullPointerException | InvalidCallbackException ignored)
|
catch (NullPointerException ignored)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -631,23 +636,31 @@ public class CarpetScriptHost extends ScriptHost
|
|||||||
return Value.NULL;
|
return Value.NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Value callNow(FunctionValue fun, List<Value> arguments)
|
||||||
|
{
|
||||||
|
ServerPlayerEntity player = (user==null)?null:scriptServer.server.getPlayerManager().getPlayer(user);
|
||||||
|
ServerCommandSource source = (player != null)?player.getCommandSource():scriptServer.server.getCommandSource();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return callUDF(BlockPos.ORIGIN, source, fun, arguments);
|
||||||
|
}
|
||||||
|
catch (InvalidCallbackException ignored)
|
||||||
|
{
|
||||||
|
return Value.NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onClose()
|
public void onClose()
|
||||||
{
|
{
|
||||||
super.onClose();
|
super.onClose();
|
||||||
FunctionValue closing = getFunction("__on_close");
|
FunctionValue closing = getFunction("__on_close");
|
||||||
if (closing != null)
|
if (closing != null && (parent != null || !isPerUser()))
|
||||||
|
// either global instance of a global task, or
|
||||||
|
// user host in player scoped app
|
||||||
{
|
{
|
||||||
ServerPlayerEntity player = (user==null)?null:scriptServer.server.getPlayerManager().getPlayer(user);
|
callNow(closing, Collections.emptyList());
|
||||||
ServerCommandSource source = (player != null)?player.getCommandSource():scriptServer.server.getCommandSource();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
callUDF(BlockPos.ORIGIN, source, closing, Collections.emptyList());
|
|
||||||
}
|
|
||||||
catch (InvalidCallbackException ignored)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (user == null)
|
if (user == null)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import java.io.IOException;
|
|||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -300,6 +301,12 @@ public class CarpetScriptServer
|
|||||||
// that will provide player hosts right at the startup
|
// that will provide player hosts right at the startup
|
||||||
newHost.retrieveForExecution(source, null);
|
newHost.retrieveForExecution(source, null);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// global app - calling start now.
|
||||||
|
FunctionValue onStart = newHost.getFunction("__on_start");
|
||||||
|
if (onStart != null) newHost.callNow(onStart, Collections.emptyList());
|
||||||
|
}
|
||||||
long end = System.nanoTime();
|
long end = System.nanoTime();
|
||||||
CarpetSettings.LOG.info("App "+name+" loaded in "+(end-start)/1000000+" ms");
|
CarpetSettings.LOG.info("App "+name+" loaded in "+(end-start)/1000000+" ms");
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -149,7 +149,7 @@ public abstract class Fluff
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return (c, type_ignored) -> AbstractOperator.this.eval(v1.evalValue(c, type), v2.evalValue(c, type));
|
return (c, type_ignored) -> AbstractOperator.this.eval(v1.evalValue(c, Context.NONE), v2.evalValue(c, Context.NONE));
|
||||||
}
|
}
|
||||||
catch (RuntimeException exc)
|
catch (RuntimeException exc)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -322,12 +322,12 @@ public abstract class ScriptHost
|
|||||||
if (oldUserHost != null) return oldUserHost;
|
if (oldUserHost != null) return oldUserHost;
|
||||||
ScriptHost userHost = this.duplicate();
|
ScriptHost userHost = this.duplicate();
|
||||||
userHost.user = user;
|
userHost.user = user;
|
||||||
this.transferToChild(userHost);
|
this.setupUserHost(userHost);
|
||||||
userHosts.put(user, userHost);
|
userHosts.put(user, userHost);
|
||||||
return userHost;
|
return userHost;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void transferToChild(ScriptHost host)
|
protected void setupUserHost(ScriptHost host)
|
||||||
{
|
{
|
||||||
// adding imports
|
// adding imports
|
||||||
host.modules.putAll(this.modules);
|
host.modules.putAll(this.modules);
|
||||||
|
|||||||
@@ -100,6 +100,7 @@ public class Loops {
|
|||||||
expression.addLazyFunction("map", 2, (c, t, lv) ->
|
expression.addLazyFunction("map", 2, (c, t, lv) ->
|
||||||
{
|
{
|
||||||
Value rval= lv.get(0).evalValue(c, Context.NONE);
|
Value rval= lv.get(0).evalValue(c, Context.NONE);
|
||||||
|
if (rval.isNull()) return ListValue.lazyEmpty();
|
||||||
if (!(rval instanceof AbstractListValue))
|
if (!(rval instanceof AbstractListValue))
|
||||||
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");
|
||||||
Iterator<Value> iterator = ((AbstractListValue) rval).iterator();
|
Iterator<Value> iterator = ((AbstractListValue) rval).iterator();
|
||||||
@@ -145,6 +146,7 @@ public class Loops {
|
|||||||
expression.addLazyFunction("filter", 2, (c, t, lv) ->
|
expression.addLazyFunction("filter", 2, (c, t, lv) ->
|
||||||
{
|
{
|
||||||
Value rval= lv.get(0).evalValue(c, Context.NONE);
|
Value rval= lv.get(0).evalValue(c, Context.NONE);
|
||||||
|
if (rval.isNull()) return ListValue.lazyEmpty();
|
||||||
if (!(rval instanceof AbstractListValue))
|
if (!(rval instanceof AbstractListValue))
|
||||||
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");
|
||||||
Iterator<Value> iterator = ((AbstractListValue) rval).iterator();
|
Iterator<Value> iterator = ((AbstractListValue) rval).iterator();
|
||||||
@@ -192,6 +194,7 @@ public class Loops {
|
|||||||
{
|
{
|
||||||
|
|
||||||
Value rval= lv.get(0).evalValue(c, Context.NONE);
|
Value rval= lv.get(0).evalValue(c, Context.NONE);
|
||||||
|
if (rval.isNull()) return LazyValue.NULL;
|
||||||
if (!(rval instanceof AbstractListValue))
|
if (!(rval instanceof AbstractListValue))
|
||||||
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");
|
||||||
Iterator<Value> iterator = ((AbstractListValue) rval).iterator();
|
Iterator<Value> iterator = ((AbstractListValue) rval).iterator();
|
||||||
@@ -243,6 +246,7 @@ public class Loops {
|
|||||||
expression.addLazyFunction("all", 2, (c, t, lv) ->
|
expression.addLazyFunction("all", 2, (c, t, lv) ->
|
||||||
{
|
{
|
||||||
Value rval= lv.get(0).evalValue(c, Context.NONE);
|
Value rval= lv.get(0).evalValue(c, Context.NONE);
|
||||||
|
if (rval.isNull()) return LazyValue.TRUE;
|
||||||
if (!(rval instanceof AbstractListValue))
|
if (!(rval instanceof AbstractListValue))
|
||||||
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");
|
||||||
Iterator<Value> iterator = ((AbstractListValue) rval).iterator();
|
Iterator<Value> iterator = ((AbstractListValue) rval).iterator();
|
||||||
@@ -307,6 +311,7 @@ public class Loops {
|
|||||||
expression.addLazyFunction("for", 2, (c, t, lv) ->
|
expression.addLazyFunction("for", 2, (c, t, lv) ->
|
||||||
{
|
{
|
||||||
Value rval= lv.get(0).evalValue(c, Context.NONE);
|
Value rval= lv.get(0).evalValue(c, Context.NONE);
|
||||||
|
if (rval.isNull()) return LazyValue.ZERO;
|
||||||
if (!(rval instanceof AbstractListValue))
|
if (!(rval instanceof AbstractListValue))
|
||||||
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");
|
||||||
Iterator<Value> iterator = ((AbstractListValue) rval).iterator();
|
Iterator<Value> iterator = ((AbstractListValue) rval).iterator();
|
||||||
@@ -356,12 +361,13 @@ public class Loops {
|
|||||||
// returned value is substituted to the accumulator
|
// returned value is substituted to the accumulator
|
||||||
expression.addLazyFunction("reduce", 3, (c, t, lv) ->
|
expression.addLazyFunction("reduce", 3, (c, t, lv) ->
|
||||||
{
|
{
|
||||||
LazyValue expr = lv.get(1);
|
|
||||||
|
|
||||||
Value acc = lv.get(2).evalValue(c, Context.NONE);
|
|
||||||
Value rval= lv.get(0).evalValue(c, Context.NONE);
|
Value rval= lv.get(0).evalValue(c, Context.NONE);
|
||||||
|
if (rval.isNull()) return ListValue.lazyEmpty();
|
||||||
if (!(rval instanceof AbstractListValue))
|
if (!(rval instanceof AbstractListValue))
|
||||||
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");
|
||||||
|
LazyValue expr = lv.get(1);
|
||||||
|
Value acc = lv.get(2).evalValue(c, Context.NONE);
|
||||||
Iterator<Value> iterator = ((AbstractListValue) rval).iterator();
|
Iterator<Value> iterator = ((AbstractListValue) rval).iterator();
|
||||||
|
|
||||||
if (!iterator.hasNext())
|
if (!iterator.hasNext())
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
package carpet.utils;
|
||||||
|
|
||||||
|
import carpet.CarpetServer;
|
||||||
|
import net.fabricmc.api.DedicatedServerModInitializer;
|
||||||
|
import net.fabricmc.loader.api.entrypoint.PreLaunchEntrypoint;
|
||||||
|
|
||||||
|
import java.io.PrintStream;
|
||||||
|
import java.lang.System;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runs only from GitHub Actions to generate the wiki
|
||||||
|
* page with all Carpet rules on it.
|
||||||
|
* It is here so it can be managed by the IDE
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class CarpetRulePrinter implements DedicatedServerModInitializer, PreLaunchEntrypoint {
|
||||||
|
public static final PrintStream OLD_OUT = System.out;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onInitializeServer() {
|
||||||
|
// Minecraft (or whatever) changes the System.out to have prefixes,
|
||||||
|
// our simple parser doesn't like that. So we change it back
|
||||||
|
System.setOut(OLD_OUT);
|
||||||
|
CarpetServer.onGameStarted();
|
||||||
|
CarpetServer.settingsManager.printAllRulesToLog(null);
|
||||||
|
System.exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPreLaunch() {
|
||||||
|
// Just initializes our OLD_OUT by nooping the class
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
package carpet.utils;
|
|
||||||
|
|
||||||
import carpet.CarpetServer;
|
|
||||||
import net.fabricmc.loader.api.entrypoint.PreLaunchEntrypoint;
|
|
||||||
import java.lang.System;
|
|
||||||
/**
|
|
||||||
* Runs only from GitHub Actions to generate the wiki
|
|
||||||
* page with all Carpet rules on it.
|
|
||||||
* It is here so it can be managed by the IDE
|
|
||||||
*
|
|
||||||
* @author altrisi
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class RulePrinter implements PreLaunchEntrypoint {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onPreLaunch() {
|
|
||||||
CarpetServer.onGameStarted();
|
|
||||||
CarpetServer.settingsManager.printAllRulesToLog(null);
|
|
||||||
System.exit(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -312,3 +312,19 @@ __on_player_swings_hand(player, hand) ->
|
|||||||
print(' - player: '+player);
|
print(' - player: '+player);
|
||||||
print(' - hand: '+hand);
|
print(' - hand: '+hand);
|
||||||
);
|
);
|
||||||
|
|
||||||
|
__on_start() ->
|
||||||
|
(
|
||||||
|
print('');
|
||||||
|
print('__on_start(player)');
|
||||||
|
print('App is starting for '+player());
|
||||||
|
logger('starting for '+player());
|
||||||
|
);
|
||||||
|
|
||||||
|
__on_close() ->
|
||||||
|
(
|
||||||
|
print('');
|
||||||
|
print('__on_close(player)');
|
||||||
|
print('App is closing for '+player());
|
||||||
|
logger('App is closing for '+player());
|
||||||
|
);
|
||||||
Reference in new issue
Block a user