Merge branch 'master' into more-throwables

This commit is contained in:
gnembon authored and GitHub committed 2021-03-07 17:52:10 -04:00
commit 25eccc9569
36 files changed
+610 -129

No files matched your search

+78
View File
@@ -398,6 +398,83 @@ Returns `true` if the file was saved successfully, `false` otherwise.
Uses the same file structure for exclusive app data, and shared data folder as `load_app_data`.
### `create_datapack(name, data)`
Creates and loads custom datapack. The data has to be a map representing the file structure and the content of the
json files of the target pack.
Returns `null` if the pack with this name already exists or is loaded, meaning no change has been made.
Returns `false` if adding of the datapack wasn't successful.
Returns `true` if creation and loading of the datapack was successful. Loading of a datapack results in
reloading of all other datapacks (vanilla restrictions, identical to /datapack enable), however unlike with `/reload`
command, scarpet apps will not be reloaded by adding a datapack using `create_datapack`.
Currently, only json files are supported in the packs. `'pack.mcmeta'` file is added automatically.
Reloading of datapacks that define new dimensions is not implemented in vanilla. Vanilla game only loads
dimension information on server start. `create_datapack` is therefore a direct replacement of manually ploping of the specified
file structure in a datapack file and calling `/datapack enable` on the new datapack with all its quirks and sideeffects
(like no worldgen changes, reloading all other datapacks, etc.). To enable newly added custom dimensions, call much more
experimental `check_hidden_dimensions()` after adding a datapack if needed.
Synopsis:
<pre>
script run create_datapack('foo',
{
'foo' -> {
'bar.json' -> {
'c' -> true,
'd' -> false,
'e' -> {'foo' -> [1,2,3]},
'a' -> 'foobar',
'b' -> 5
}
}
})
script run create_datapack('funky_world', {
'data' -> {
'minecraft' -> {
'dimension' -> {
'custom_ow.json' -> {
'type' -> 'minecraft:the_end',
'generator' -> {
'biome_source' -> {
'seed' -> 0,
'large_biomes' -> false,
'type' -> 'minecraft:vanilla_layered'
},
'seed' -> 0,
'settings' -> 'minecraft:nether',
'type' -> 'minecraft:noise'
}
}
}
}
}
});
check_hidden_dimensions(); => ['funky_world']
</pre>
### `enable_hidden_dimensions()`
The function reads current datapack settings detecting new dimensions defined by these datapacks that have not yet been added
to the list of current dimensions and adds them so that they can be used and accessed right away. It doesn't matter how the
datapacks have been added to the game, either with 'create_datapack()' or manually by dropping a datapack file and calling
`/datapack enable` on it. Returns the list of valid dimension names / identifiers that has been added in the process.
Fine print: The function should be
considered experimental. There 'should not be' (famous last words) any side-effects if no worlds are added. Already connected
clients will not see suggestions for commands that use dimensions `/execute in <dim>` (vanilla client limitation)
but all commands should work just fine with
the new dimensions. Existing worlds that have gotten modified settings by the datapacks will not be reloaded or replaced.
The usability of the dimensions added this way has not been fully tested, but it seems it works just fine. Generator settings
for the new dimensions will not be added to `'level.dat'` but it will be added there automatically next time the game restarts by
vanilla. One could have said to use this method with caution, and the authors take no responsibility of any losses incurred due to
mis-handlilng of the temporary added dimensions, yet the feature itself (custom dimensions) is clearly experimental for Mojang
themselves, so that's about it.
### `tick_time()`
Returns server tick counter. Can be used to run certain operations every n-th ticks, or to count in-game time.
@@ -517,6 +594,7 @@ Available options in the scarpet app space:
Relevant world related properties
* `world_name` - name of the world
* `world_seed` - a numeric seed of the world
* `world_dimensions` - a list of dimensions in the world
* `world_path` - full path to the world saves folder
* `world_folder` - name of the direct folder in the saves that holds world files
* `world_carpet_rules` - returns all Carpet rules in a map form (`rule`->`value`). Note that the values are always returned as strings, so you can't do boolean comparisons directly. Includes rules from extensions with their namespace (`namespace:rule`->`value`). You can later listen to rule changes with the `on_carpet_rule_changes(rule, newValue)` event.
+3 -1
View File
@@ -792,7 +792,9 @@ All generated structures will retain their properties, like mob spawning, howeve
itself has certain rules to spawn mobs, like plopping a nether fortress in the overworld will not spawn nether mobs,
because nether mobs can spawn only in the nether, but plopped in the nether - will behave like a valid nether fortress.
### `custom_dimension(name, seed?)`
### (deprecated) `custom_dimension(name, seed?)`
Deprecated by `create_datapack()` which can be used to setup custom dimensions
Ensures the dimension with the given `'name'` is available and configured with the given seed. It merely sets the world
generator settings to the overworld, and the optional custom seed (or using current world seed, if not provided).
+1 -1
View File
@@ -177,7 +177,7 @@ Returns `true` if en entity is standing on firm ground and falling down due to t
### `query(e, 'name'), query(e, 'display_name'), query(e, 'custom_name'), query(e, 'type')`
String of entity name
String of entity name or formatted text in the case of `display_name`
<pre>
query(e,'name') => Leatherworker
+15 -15
View File
@@ -23,12 +23,12 @@ In case to simplify the access with nested objects, you can add chain of address
than calling it multiple times. `get(get(foo,a),b)` is equivalent to `get(foo, a, b)`, or `foo:a:b`.
<pre>
get(l(range(10)), 5) => 5
get(l(range(10)), -1) => 9
get(l(range(10)), 10) => 0
l(range(10)):93 => 3
get([range(10)], 5) => 5
get([range(10)], -1) => 9
get([range(10)], 10) => 0
[range(10)]:93 => 3
get(player() ~ 'nbt', 'Health') => 20 // inefficient way to get player health, use player() ~ 'health' instead
get(m( l('foo',2), l('bar',3), l('baz',4) ), 'bar') => 3
get({ 'foo' -> 2, 'bar' -> 3, 'baz' -> 4 }, 'bar') => 3
</pre>
### `has(container, address, ...), has(lvalue)`
@@ -100,13 +100,13 @@ of the existing elements. Use `replace` to remove and replace existing element.
and merges keys from `value` with the compound tag under the path
<pre>
a = l(1, 2, 3); put(a, 1, 4); a => [1, 4, 3]
a = l(1, 2, 3); put(a, null, 4); a => [1, 2, 3, 4]
a = l(1, 2, 3); put(a, 1, 4, 'insert'); a => [1, 4, 2, 3]
a = l(1, 2, 3); put(a, null, l(4, 5, 6), 'extend'); a => [1, 2, 3, 4, 5, 6]
a = l(1, 2, 3); put(a, 1, l(4, 5, 6), 'extend'); a => [1, 4, 5, 6, 2, 3]
a = l(l(0,0,0),l(0,0,0),l(0,0,0)); put(a.1, 1, 1); a => [[0, 0, 0], [0, 1, 0], [0, 0, 0]]
a = m(1,2,3,4); put(a, 5, null); a => {1: null, 2: null, 3: null, 4: null, 5: null}
a = [1, 2, 3]; put(a, 1, 4); a => [1, 4, 3]
a = [1, 2, 3]; put(a, null, 4); a => [1, 2, 3, 4]
a = [1, 2, 3]; put(a, 1, 4, 'insert'); a => [1, 4, 2, 3]
a = [1, 2, 3]; put(a, null, [4, 5, 6], 'extend'); a => [1, 2, 3, 4, 5, 6]
a = [1, 2, 3]; put(a, 1, [4, 5, 6], 'extend'); a => [1, 4, 5, 6, 2, 3]
a = [[0,0,0],[0,0,0],[0,0,0]]; put(a:1, 1, 1); a => [[0, 0, 0], [0, 1, 0], [0, 0, 0]]
a = {1,2,3,4}; put(a, 5, null); a => {1: null, 2: null, 3: null, 4: null, 5: null}
tag = nbt('{}'); put(tag, 'BlockData.Properties', '[1,2,3,4]'); tag => {BlockData:{Properties:[1,2,3,4]}}
tag = nbt('{a:[{lvl:3},{lvl:5},{lvl:2}]}'); put(tag, 'a[].lvl', 1); tag => {a:[{lvl:1},{lvl:1},{lvl:1}]}
tag = nbt('{a:[{lvl:[1,2,3]},{lvl:[3,2,1]},{lvl:[4,5,6]}]}'); put(tag, 'a[].lvl', 1, 2); tag
@@ -187,10 +187,10 @@ other parts. In that case consecutive calls to `slice` will refer to index `0` t
cannot go back nor track where they are in the sequence (see examples).
<pre>
slice([0,1,2,3,4,5], 1, 3) => [1, 2, 3]
slice([0,1,2,3,4,5], 1, 3) => [1, 2]
slice('foobar', 0, 1) => 'f'
slice('foobar', 3) => 'bar'
slice(range(10), 3, 5) => [3, 4, 5]
slice(range(10), 3, 5) => [3, 4]
slice(range(10), 5) => [5, 6, 7, 8, 9]
r = range(100); [slice(r, 5, 7), slice(r, 1, 3)] => [[5, 6], [8, 9]]
</pre>
@@ -225,7 +225,7 @@ Primarily to be used in higher order functions
<pre>
range(10) => [...]
l(range(10)) => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[range(10)] => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
map(range(10),_*_) => [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
reduce(range(10),_a+_, 0) => 45
range(5,10) => [5, 6, 7, 8, 9]
@@ -124,12 +124,12 @@ to `all(list,expr) <=> for(list,expr)==length(list)`. `expr` also receives bound
and `continue` have no sense and cannot be used inside of `expr` body.
<pre>
all([1,2,3], check_prime(_)) => 1
all(neighbours(x,y,z), _=='stone') => 1 // if all neighbours of [x, y, z] are stone
map(filter(rect(0,4,0,1000,0,1000), l(x,y,z)=pos(_); all(rect(x,y,z,1,0,1),_=='bedrock') ), pos(_) )
all([1,2,3], check_prime(_)) => true
all(neighbours(x,y,z), _=='stone') => true // if all neighbours of [x, y, z] are stone
map(filter(rect(0,4,0,1000,0,1000), [x,y,z]=pos(_); all(rect(x,y,z,1,0,1),_=='bedrock') ), pos(_) )
=> [[-298, 4, -703], [-287, 4, -156], [-269, 4, 104], [242, 4, 250], [-159, 4, 335], [-208, 4, 416], [-510, 4, 546], [376, 4, 806]]
// find all 3x3 bedrock structures in the top bedrock layer
map( filter( rect(0,4,0,1000,1,1000,1000,0,1000), l(x,y,z)=pos(_);
map( filter( rect(0,4,0,1000,1,1000,1000,0,1000), [x,y,z]=pos(_);
all(rect(x,y,z,1,0,1),_=='bedrock') && for(rect(x,y-1,z,1,1,1,1,0,1),_=='bedrock')<8),
pos(_) ) => [[343, 3, -642], [153, 3, -285], [674, 3, 167], [-710, 3, 398]]
// ditto, but requiring at most 7 bedrock block in the 18 blocks below them
+24 -23
View File
@@ -16,7 +16,7 @@ in [User Defined Functions and Program Control Flow](docs/scarpet/language/Funct
1357-5 => 1352
1357-'5' => 137
3*'foo'-'o' => 'fff'
l(1,3,5)+7 => l(8,10,12)
[1,3,5]+7 => [8,10,12]
</pre>
As you can see, values can behave differently when mixed with other types in the same expression.
@@ -76,8 +76,8 @@ In Minecraft API portion `entity ~ feature` is a shortcode for `query(entity,fea
any extra arguments.
<pre>
l(1,2,3) ~ 2 => 1
l(1,2,3) ~ 4 => null
[1,2,3] ~ 2 => 1
[1,2,3] ~ 4 => null
'foobar' ~ 'baz' => null
'foobar' ~ '.b' => 'ob'
@@ -103,10 +103,10 @@ Or an example to find if a player has specific enchantment on a held axe (either
<pre>
global_get_enchantment(p, ench) -> (
$ for(l('main','offhand'),
$ for(['main','offhand'],
$ holds = query(p, 'holds', _);
$ if( holds,
$ l(what, count, nbt) = holds;
$ [what, count, nbt] = holds;
$ if( what ~ '_axe' && nbt ~ ench,
$ lvl = max(lvl, number(nbt ~ '(?<=lvl:)\\d') )
$ )
@@ -143,8 +143,8 @@ Examples:
'foo'*3 => 'foofoofoo'
'foofoofoo' / 3 => 'foo'
'foofoofoo'-'o' => 'fff'
l(1,2,3)+1 => l(2,3,4)
b = l(100,63,100); b+l(10,0,10) => l(110,63,110)
[1,2,3]+1 => [2,3,4]
b = [100,63,100]; b+[10,0,10] => [110,63,110]
{'a' -> 1} + {'b' -> 2} => {'a' -> 1, 'b' -> 2}
</pre>
@@ -186,11 +186,12 @@ second operand is not necessary, it won't be evaluated, which means one can use
case of success returns first positive operand (`||`) or last one (`&&`).
<pre>
true || false => 1
null || false => 0
null != false || run('kill gnembon') => 1 // gnembon survives
null != false && run('kill gnembon') => 0 // when cheats not allowed
null != false && run('kill gnembon') => 1 // gnembon dies, cheats allowed
true || false => true
null || false => false
false || null => null
null != false || run('kill gnembon') // gnembon survives
null != false && run('kill gnembon') // when cheats not allowed
null != false && run('kill gnembon') // gnembon dies, cheats allowed
</pre>
### `Assignment Operators = <> +=`
@@ -204,11 +205,11 @@ require rewriting of the array anyways.
<pre>
a = 5 => a == 5
l(a,b,c) = l(3,4,5) => a==3, b==4, c==5
l(minx,maxx) = sort(xi,xj); // minx assumes min(xi, xj) and maxx, max(xi, xj)
l(a,b,c,d,e,f) = l(range(6)); l(a,b,c) <> l(d,e,f); l(a,b,c,d,e,f) => [3,4,5,0,1,2]
a = l(1,2,3); a += 4 => [1,2,3,4]
a = l(1,2,3,4); a = filter(a,_!=2) => [1,3,4]
[a,b,c] = [3,4,5] => a==3, b==4, c==5
[minx,maxx] = sort(xi,xj); // minx assumes min(xi, xj) and maxx, max(xi, xj)
[a,b,c,d,e,f] = [range(6)]; [a,b,c] <> [d,e,f]; [a,b,c,d,e,f] => [3,4,5,0,1,2]
a = [1,2,3]; a += 4 => [1,2,3,4]
a = [1,2,3,4]; a = filter(a,_!=2) => [1,3,4]
</pre>
### `Unary Operators - +`
@@ -226,10 +227,10 @@ Require a number, flips the sign. One way to assert it's a number is by crashing
flips boolean condition of the expression. Equivalent of `bool(expr)==false`
<pre>
!true => 0
!false => 1
!null => 1
!5 => 0
!l() => 1
!l(null) => 0
!true => false
!false => true
!null => true
!5 => false
!l() => true
!l(null) => false
</pre>
+25 -24
View File
@@ -14,30 +14,31 @@ as well as minecraft related concepts like `block`, `entity`, `nbt`, `text`.
### `bool(expr)`
Returns a boolean context of the expression. Note that there are no true/false values in scarpet. `true` is
alias of 1, and `false` is 0\. Bool is also interpreting string values as boolean, which is different from other
Returns a boolean context of the expression.
Bool is also interpreting string values as boolean, which is different from other
places where boolean context can be used. This can be used in places where API functions return string values to
represent binary values
represent binary values.
<pre>
bool(pi) => 1
bool(false) => 0
bool('') => 0
bool(l()) => 0
bool(l('')) => 1
bool('foo') => 1
bool('false') => 0
bool('nulL') => 0
if('false',1,0) => 1
bool(pi) => true
bool(false) => false
bool('') => false
bool(l()) => false
bool(l('')) => true
bool('foo') => true
bool('false') => false
bool('nulL') => false
if('false',1,0) => true
</pre>
### `number(expr)`
Returns a numeric context of the expression. Can be used to read numbers from strings
Returns a numeric context of the expression. Can be used to read numbers from strings, or other types
<pre>
number(null) => null
number(null) => 0
number(false) => 0
number(true) => 1
number('') => null
number('3.14') => 3.14
number(l()) => 0
@@ -65,15 +66,15 @@ Supported types (with `"%<?>"` syntax):
* `%%`: '%' character
<pre>
str(null) => null
str(false) => 0
str('') => null
str('3.14') => 3.14
str(l()) => 0
str(l('')) => 1
str('foo') => null
str('3bar') => null
str(2)+str(2) => 22
str(null) => 'null'
str(false) => 'false'
str('') => ''
str('3.14') => '3.14'
str([]) => '[]'
str(['']) => '[]'
str('foo') => 'foo'
str('3bar') => '3bar'
str(2)+str(2) => '22'
str('pi: %.2f',pi) => 'pi: 3.14'
str('player at: %d %d %d',pos(player())) => 'player at: 567, -2423, 124'
</pre>
@@ -234,7 +235,7 @@ same random object. Scarpet keeps track of up to 1024 custom random number gener
<pre>
map(range(10), floor(rand(10))) => [5, 8, 0, 6, 9, 3, 9, 9, 1, 8]
map(range(10), bool(rand(2))) => [1, 1, 1, 0, 0, 1, 1, 0, 0, 0]
map(range(10), bool(rand(2))) => [false, false, true, false, false, false, true, false, true, false]
map(range(10), str('%.1f',rand(_))) => [0.0, 0.4, 0.6, 1.9, 2.8, 3.8, 5.3, 2.2, 1.6, 5.6]
</pre>
@@ -3,8 +3,8 @@
`scarpet` provides a number of constants that can be used literally in scripts
* `null`: nothing, zilch, not even false
* `true`: pure true, or just 1 (one)
* `false`: false truth, or true falsth, 0 (zero) actually
* `true`: pure true, can act as `1`
* `false`: false truth, or true falsth, equals to `0`
* `pi`: for the fans of perimeters, its a perimeter of an apple pi of diameter 1\. About 3.14
* `euler`: clever guy. Derivative of its exponent is goto 1\. About 2.72
+2 -1
View File
@@ -17,9 +17,9 @@ brightness
chunk_tickets
convert_date
crafting_remaining_item
create_datapack
create_marker
current_dimension
custom_dimension
day_time
delete_file
destroy
@@ -28,6 +28,7 @@ display_title
draw_shape
drop_item
emitted_light
enable_hidden_dimensions
encode_nbt
entity_area
entity_event
@@ -55,7 +55,7 @@
set without_updates
blocks_movement block_sound material map_colour block_state block_list block_tags block_data poi set_poi
place_item set_biome biome loaded_status generation_status inhabited_time spawn_potential chunk_tickets
structure_eligibility structures structure_references set_structure reset_chunk reload_chunk custom_dimension
structure_eligibility structures structure_references set_structure reset_chunk reload_chunk create_datapack enable_hidden_dimensions
add_chunk_ticket
convert_date unix_time