diff --git a/.gitignore b/.gitignore index 2105712d..7c9ff93b 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ build/ out/ classes/ publish/ +docs/ # idea diff --git a/src/main/java/carpet/script/CarpetExpression.java b/src/main/java/carpet/script/CarpetExpression.java index 4f63e39e..c9eeb038 100644 --- a/src/main/java/carpet/script/CarpetExpression.java +++ b/src/main/java/carpet/script/CarpetExpression.java @@ -281,12 +281,13 @@ public class CarpetExpression *
block(x, y, z), block(state)Returns either a block from specified location, or block with a specific state
- * (as used by /setblock command), so allowing for block properties etc.
- * Blocks can be referenced everywhere by its simple name, but its only used in its default state
/setblock command), so allowing for block properties, block entity data etc.
+ * Blocks otherwise can be referenced everywhere by its simple string name, but its only used in its default state
*
* block('air') => air
* block('iron_trapdoor[half=top]') => iron_trapdoor
* block(0,0,0) == block('bedrock') => 1
+ * block('hopper[facing=north]{Items:[{Slot:1b,id:"minecraft:slime_ball",Count:16b}]}') => hopper
*
* All the functions below can be used with block value, queried with coord triple, or 3-long list. @@ -315,6 +316,21 @@ public class CarpetExpression * set(x,y,z,'iron_trapdoor[half=top]') // Incorrect. sets bottom iron trapdoor - no parsing of properties * set(x,y,z,'iron_trapdoor','half','top') // correct - top trapdoor * set(x,y,z,block('iron_trapdoor[half=top]')) // also correct, block() provides extra parsing + * set(x,y,z,'hopper[facing=north]{Items:[{Slot:1b,id:"minecraft:slime_ball",Count:16b}]}') // extra block data + * + *
place_item(item, pos, facing?, sneak?)Places a given item in the world like it was placed by a player. Item names are default minecraft item name, + * less the minecraft prefix. Default facing is 'up', but there are other options: 'down', 'north', 'east', + * 'south', 'west', but also there are other secondary directions important for placement of blocks like stairs, doors, etc. + * Try experiment with options like 'north-up' which is placed facing north with cursor pointing to the upper part of the block, + * or 'up-north', which means a block placed facing up (player looking down) and placed smidge away of the block center + * towards north. Optional sneak is a boolean indicating if a player would be sneaking while placing the block - + * this option only affects placement of chests and scaffolding at the moment. + * Returns true if placement was successful, false otherwise.
+ *
+ * place_item('stone',x,y,z) // places a stone block on x,y,z block
+ * place_item('piston,x,y,z,'down') // places a piston facing down
+ * place_item('carrot',x,y,z) // attempts to plant a carrot plant. Returns true if could place carrots at that position.
*
* update(pos)Causes a block update at position.
@@ -352,7 +368,12 @@ public class CarpetExpression * property(block('iron_trapdoor[half=top]'),'powered') => false * bool(property(block('iron_trapdoor[half=top]'),'powered')) => 0 * - * + *block_data(pos)Return NBT string associated with specific location, or null if the block does not carry block data. + * Can be currently used to match specific information from it, or use it to copy to another block
+ *
+ * block_data(x,y,z) => '{TransferCooldown:0,x:450,y:68, ... }'
+ *
* solid(pos)Boolean function, true if the block is solid
*air(pos)Most functions in this category require inventory as the first argument. Inventory could be specified by + * an entity, or a block, or position (three coordinates) of a potential block with inventory. + * If the entity or a block doesn't + * have an inventory, they typically do nothing and return null.
+ *Most items returned are in the form of + * a triple of item name, count, and nbt or the extra data associated with an item. + * Manipulating of the nbt data can be costly, but retrieving them from the tuple to match other aspects is cheap
+ *stack_limit(item)Returns number indicating what is the stack limit for the item. Its typically 1 (non-stackable), + * 16 (like buckets), or 64 - rest. It is recommended to consult this, as other inventory API functions + * ignore normal stack limits, and it is up to the programmer to keep it at bay. As of 1.13, game checks for negative + * numbers and setting an item to negative is the same as empty.
+ *
+ * stack_limit('wooden_axe') => 1
+ * stack_limit('ender_pearl') => 16
+ * stack_limit('stone') => 64
+ *
+ * inventory_size(inventory)Returns the size of the inventory for the entity or block in question. Returns null if the block or entity + * don't have an inventory
+ *+ * inventory_size(player()) => 41 + * inventory_size(x,y,z) => 27 // chest + * inventory_size(block(pos)) => 5 // hopper + *+ *
inventory_get(inventory, slot)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'.
+ *
+ * inventory_get(player(), 0) => null // nothing in first hotbar slot
+ * inventory_get(x,y,z, 5) => ['stone', 1, {}]
+ * inventory_get(player(), -1) => ['diamond_pickaxe', 1, {Damage:4}] // slightly damaged diamond pick in the offhand
+ *
+ *
+ * inventory_set(inventory, slot, count, item?, nbt?) Modifies or sets a stack in inventory. specify count 0 to empty the slot. + * If item is not specified, keeps existing item, just modifies the count. If item is provided - replaces current item. + * If nbt is provided - adds a tag to the stack at slot. Returns previous stack in that slot.
+ *
+ * inventory_set(player(), 0, 0) => ['stone', 64, {}] // player had a stack of stone in first hotbar slot
+ * inventory_set(player(), 0, 6) => ['diamond', 64, {}] // changed stack of diamonds in player slot to 6
+ * inventory_set(player(), 0, 1, 'diamond_axe','{Damage:5}') => null //added slightly damaged pick to first player slot
+ *
+ *
+ * inventory_find(inventory, item, start_slot?, ), inventory_find(inventory, null, start_slot?) Finds the first slot with a corresponding item in the inventory, or if queried with null: the first empty slot. + * Returns slot number if found, or null otherwise. Optional start_slot argument allows to skip all preceeding slots + * allowing for efficient (so not slot-by-slot) inventory search for items.
+ *+ * inventory_find(player(), 'stone') => 0 // player has stone in first hotbar slot + * inventory_find(player(), null) => null // player's inventory has no empty spot + * while( (slot = inventory_find(p, 'diamond', slot)) != null, 41, drop_item(p, slot) ) + * // spits all diamonds from player inventory wherever they are + * inventory_drop(x,y,z, 0) => 64 // removed and spawned in the world a full stack of items + *+ * + *
inventory_remove(inventory, item, amount?) Removes amount (defaults to 1) of item from inventory. If the inventory doesn't have the defined amount, nothing + * happens, otherwise the given amount of items is removed wherever they are in the inventory. Returns boolean whether + * the removal operation was successful. Easiest way to remove a specific item from player inventory without specifying + * the slot.
+ *+ * inventory_remove(player(), 'diamond') => 1 // removed diamond from player inventory + * inventory_remove(player(), 'diamond', 100) => 0 // player doesn't have 100 diamonds, nothing happened + *+ * + *
drop_item(inventory, slot, amount?, )Drops the items from indicated inventory slot, like player that Q's an item or villager, that exchanges food. + * You can Q items from block inventories as well. default amount is 0 - which is all from the slot. NOTE: hoppers are quick + * enough to pick all the queued items from their inventory anyways. + * Returns size of the actual dropped items.
+ *+ * inventory_drop(player(), 0, 1) => 1 // Q's one item on the ground + * inventory_drop(x,y,z, 0) => 64 // removed and spawned in the world a full stack of items + *+ *
Unlike with blocks, that use plethora of vastly different querying functions, entities are queried with
* query function and altered via modify function. Type of information needed or
* values to be modified are different for each call
Using ~ (in) operator is an alias for query. Especially useful if a statement has
+ * no arguments, which in this case can be radically simplified
+ * query(p, 'name') <=> p ~ 'name' // much shorter and cleaner
+ * query(p, 'holds', 'offhand') <=> p ~ l('holds', 'offhand') // not really but can be done
+ *
* query(e,'removed')Boolean. True if the entity is removed
*query(e,'id')feetIf slot is not specified, it defaults to the main hand.
query(e,'selected_slot')Number indicating the selected slot of entity inventory. Currently only applicable to players.
+ *query(e,'facing', order?)Returns where the entity is facing. optional order (number from 0 to 5, and negative), indicating + * primary directions where entity is looking at. From most prominent (order 0) to opposite (order 5, or -1)
+ * *query(e,'nbt',path?)Returns full NBT of the entity. If path is specified, it fetches only that portion of the NBT,
* that corresponds to the path. For specification of path attribute, consult
@@ -2419,6 +2538,7 @@ public class CarpetExpression
*
The last method is the one that world edit is using (part of carpet mod). It turns out that the outline method with 32.5 radius,
* fill method with round function and draw command are equivalent
/script run commandprimary way to input commands. The command executes in the context, position, and dimension of the executing + *
Primary way to input commands. The command executes in the context, position, and dimension of the executing
* player, commandblock, etc... The command receives 4 variables, x, y, z
* and p indicating position and the executing entity of the command.
+ * You will receive tab completion suggestions as you type your code suggesting functions and global variables.
* It is advisable to use /execute in ... at ... as ... run script run ... or similar, to simulate running
* commands in a different scope
Ability to combine more statements into one expression, with functions, passing parameters, and global and outer * scoping allow to organize even larger scripts
*return(expr)return(expr?)Sometimes its convenient to break the organized control flow, or it is not practical to pass * the final result value of a function to the last statement, in this case a return statement can be used
+ *If no argument is provided - returns null value.
*
* def() -> (
* expr1;
@@ -873,12 +874,14 @@ public class Expression implements Cloneable
*
* In general its cheaper to leave the last expression as a return value, rather than calling returns everywhere, * but it would often lead to a messy code.
- *exit(expr)It terminates entire program passing expr as the result of the program execution.
try(expr, catch_expr(_)) ... throw(value)exit(expr?)It terminates entire program passing expr as the result of the program execution, or null if omitted.
try(expr, catch_expr(_)?) ... throw(value?)try function evaluates expression, and continues further unless throw function is called
* anywhere inside expr. In that case the catch_expr is evaluates with _ set
- * to the argument throw was called with. This mechanism allows to terminate large portion of a convoluted
+ * to the argument throw was called with.
+ * This mechanic accepts skipping thrown value - it throws null instead, and catch expression - then try returns null as well
+ * This mechanism allows to terminate large portion of a convoluted
* call stack and continue program execution. There is only one level of exceptions currently in carpet, so if the inner
* function also defines the try catchment area, it will received the exception first, but it can technically
* rethrow the value its getting for the outer scope. Unhandled throw acts like an exit statement.
element(list, index)get(list, index), element(list, index)(deprecated)Returns the value at index element from the list.
- * use negative numbers to reach elements from the end of the list. element
+ * 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
- * element(l(range(10)), 5) => 5
- * element(l(range(10)), -1) => 9
- * element(l(range(10)), 10) => 0
- * element(l(range(10)), 93) => 3
+ * get(l(range(10)), 5) => 5
+ * get(l(range(10)), -1) => 9
+ * get(l(range(10)), 10) => 0
+ * get(l(range(10)), 93) => 3
*
*
* put(list, index, values ...), put(list, null, values ...)