From 82dfb8266c8718707e079fe6f2a67fb6628c54bf Mon Sep 17 00:00:00 2001
From: gnembon Returns a coords triple that is offset in a specified Returns a list of available block properties for a particular block. If a block has no properties, returns an empty list. Returns true, if the inventory is not empty, false if it is empty, and null, if its not an inventory. Returns the item in the corresponding inventory slot, or null if slot empty or inventory is invalid.
* You can use negative numbers to indicate slots counted from 'the back'. Displays the result of the expression to the chat. Overrides default Prints the message to system logs, and not to chat. Runs a command from the string result of the Performs autosave, saves all chunks, player data, etc. Useful for programs where autosave is disabled
* due to performance reasons and saves the world only on demand. Loads the app data associated with the app from the world /scripts folder. Without argument returns the memory
+ * managed and buffered / throttled NBT tag. With a file name - reads explicitly a file with that name from the scripts
+ * floder. You can use app data to save non-vanilla information separately from the world and other scripts. Stores the app data associated with the app from the world /scripts folder. With the Returns game tick counter. Can be used to run certain operations every n-th ticks, or to count in-game time Loading a module, if it contains a If an app defines Unloading a module removes all of its state from the game, disables commands, and removes bounded events Scripts can be loaded in shared and player mode. Default is player, so all globals and stored functions are
* individual for each player, meaning scripts don't need to worry about making sure they store some intermittent data
diff --git a/src/main/java/carpet/script/Expression.java b/src/main/java/carpet/script/Expression.java
index de69545f..572233fc 100644
--- a/src/main/java/carpet/script/Expression.java
+++ b/src/main/java/carpet/script/Expression.java
@@ -1090,12 +1090,14 @@ public class Expression implements Cloneable
* Operator version of the WARNING: Unlike for some languages, where item access operator can be an L-value, to assign new values to
- * container elements, use For certain operators and functions (get, put, delete, has, =, +=) objects can use TODO: add more information about l-value behaviour. This operator should be understood as 'matches', 'contains', 'is_in',
@@ -2025,7 +2027,7 @@ public class Expression implements Cloneable
* Here is a list of operations that work on all types of containers: lists, maps, as well as other Minecraft
* specific modifyable containers, like NBTs Returns the value at
+ * pos_offset(pos, direction, amount?)direction by amount of blocks.
+ * The default offset amount is 1 block. To offset into opposite facing, use negative numbers for the amount.
+ *
+ * pos_offset(block(0,5,0), 'up', 2) => l(0,7,0)
+ * pos_offset(l(0,5,0), 'up', -2 ) => l(0,3,0)
+ *
*
* block_properties(pos)
@@ -1087,6 +1095,13 @@ public class CarpetExpression
* inventory_size(x,y,z) => 27 // chest
* inventory_size(block(pos)) => 5 // hopper
*
+ * property(pos, name)
+ * inventory_has_items(inventory)
+ * inventory_has_items(player()) => true
+ * inventory_has_items(x,y,z) => false // empty chest
+ * inventory_has_items(block(pos)) => null // stone
+ *
*
* inventory_get(inventory, slot)
* print(expr)scarpet behaviour of
* sending everyting to stderr.
+ * logger(expr)
* run(expr)expr expression, and returns its success count
* save()
+ * load_app_data(), load_app_data(file)
+ * store_app_data(tag), store_app_data(tag, file)file parameter
+ * saves immediately and with every call, without file parameter, it may take up to 10 seconds for the output
+ * file to sync preventing flickering in case this tag changes frequently. It will be synced when server closes.
* tick_time()
@@ -3148,6 +3174,19 @@ public class CarpetExpression
* game_tick(mstime?)__command() method, will attempt to registed a command with that
* module name, and register all public (no underscore) functions available in the module as subcommands. It will also
* bind specific events to the event system (check Events section for details).__config method, and that method returns a map, it will be used to apply custom
+ * settings for this app. Currently the following options are supported:
+ *
* scope: default scope for global variables for the app, Default is 'player' which means
+ * that globals and defined functions will be unique for each player so that apps for each player will run in
+ * isolation. This is useful in tool-like applications. Another option is 'global' which shares global state for all
+ * runs on the server - applicable to 'block' like solutions, where custom behaviours are applied to blocks.stay_loaded: defaults to false. If true, and /carpet scriptsAutoload is turned on,
+ * the following apps will stay loaded after startup. Otherwise, after reading a code, and fetching the config, server
+ * will drop them down. This is to allow to store multiple apps on the server/world and selectively decide which one
+ * should be running at startup. WARNING: all apps will run once at startup anyways, so be aware that their actions
+ * that are called statically, will be performed once anyways.
* Get, Accessor Operator :get(...) function to access elements of lists, maps, and potentially other
* containers (i.e. NBTs). It is important to distinguish from ~ operator, which is a matching operator,
- * which is expected to perform some extra computations to retrieve the result, while . should be
+ * which is expected to perform some extra computations to retrieve the result, while : should be
* straightforward and immediate, and the source object should behave like a container and support full container
* API, meaning get(...), put(...), delete(...),
* and has(...) functionsput function instead, i.e. a:1='foo' won't work.: annotated
+ * fields as l-values, meaning construct like foo:0 = 5, would act like put(foo, 0, 5),
+ * rather than get(foo, 0) = 5, which would result in an error.
* Matching Operator ~
+ * get(container, address), ':' operator
* get(container, address, ...), get(lvalue), ':' operatoraddress element from the value.
* For lists it indicates an index, use negative numbers to reach elements from the end of the list. get
* call will always be able to find the index. In case there is few items, it will loop over
In case to simplify the access with nested objects, you can add chain of addresses to the arguments of
+ * get rather than calling it multiple times. get(get(foo,a),b) is equivalent to
+ * get(foo, a, b), or foo:a:b.
* get(l(range(10)), 5) => 5
* get(l(range(10)), -1) => 9
@@ -2045,17 +2050,24 @@ public class Expression implements Cloneable
* get(m( l('foo',2), l('bar',3), l('baz',4) ), 'bar') => 3
*
*
- * has(container, address)has(container, address, ...), has(lvalue)Similar to get, but returns boolean value indicating if the given index / key / path is in the
* container. Can be used to determine if get(...)==null means the element doesn't exist, or the stored value
- * for this address is null, and is cheaper to run than get
null, and is cheaper to run than get.
+ * Like get, it can accept multiple addresses for chains in nested containers. In this case has(foo:a:b)
+ * is equivalent to has(get(foo,a), b) or has(foo, a, b)
delete(container, address)delete(container, address, ...), delete(lvalue)Removes specific entry from the container. For the lists - removes the element and shrinks it. For maps, it * removes the key from the map, and for nbt - removes content from a given path. For lists and maps returns previous * entry at the address, for nbt's - number of removed objects, with 0 indicating that the original value was unaffected.
+ *Like with the get and has, delete can accept chained addresses, as well as
+ * l-value container access, removing the value
+ * from the leaf of the path provided, so delete(foo, a, b) is the same as delete(get(foo,a),b)
+ * or delete(foo:a:b)
Returns true, if container was changed, false, if it was left unchanged, and null if operation was invalid.
* - *put(container, address, value), put(container, address, value, mode)put(container, address, value), put(container, address, value, mode), put(lvalue, value)Lists
*Modifies the container by replacing the value under the address with the supplied value.
* For lists, a valid index is required, but can be negative as well to indicate positions from the end of the list.
@@ -2072,6 +2084,11 @@ public class Expression implements Cloneable
* extending the list by this amount of items. Again use null address/index to point to the end of
* the list
*
+ *
Due to the extra mode parameter, there is no chaining for put, but you can still use l-value
+ * container access to indicate container and address, so put(foo, key, value) is the same as
+ * put(foo:key, value) or foo:key=value
Returns true, if container got modified, false otherwise, and null if operation was invalid.
+ * *Maps
*For maps there are no modes available (yet, seems there is no reason to). It replaces the value under the supplied * key (address), or sets it if not currently present.
diff --git a/src/main/java/carpet/settings/SettingsManager.java b/src/main/java/carpet/settings/SettingsManager.java index 349850d4..96467342 100644 --- a/src/main/java/carpet/settings/SettingsManager.java +++ b/src/main/java/carpet/settings/SettingsManager.java @@ -171,7 +171,7 @@ public class SettingsManager public void notifyPlayersCommandsChanged() { - if (server.getPlayerManager() == null) + if (server == null || server.getPlayerManager() == null) { return; }