Merge branch 'main' into VorTechnix

This commit is contained in:
VorTechnix 2021-09-05 09:34:54 -07:00
commit a5960983e7
25 changed files with 316 additions and 80 deletions

View file

@ -1,6 +1,6 @@
const fs = require("fs");
const path = require("path");
const htmlentities = require("htmlentities");
const htmlentities = require("html-entities");
function read_contributors() {
return fs.readFileSync(path.resolve(__dirname, "../../CONTRIBUTORS.tsv"), "utf-8")

BIN
.docs/images/gallery-d.jpeg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 708 KiB

BIN
.docs/images/gallery-e.jpeg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 615 KiB

View file

@ -16,7 +16,9 @@ date: 2000-01-01
</p>
<p><em>Extra tools and commands to extend <a href="https://github.com/Uberi/Minetest-WorldEdit">WorldEdit</a> for <a href="https://www.minetest.net/">Minetest</a></em></p>
<p>If you can dream of it, it probably belongs here!</p>
<p><a href="#download" class="bigbutton">Get Started</a></p>
<p>
<a href="#download" class="bigbutton">Get Started</a>
</p>
</section>
<section class="features-large">
@ -62,12 +64,18 @@ date: 2000-01-01
{% gallerybox "images/gallery-a.jpeg" "image-first" "image-last" "image-b" %}
A scene demonstrating <code>//replacemix</code>, <code>//ellipsoid</code>, <code>//layers</code>, <code>smoothadv</code> (aka <code>convolve</code> and <code>conv</code>), and <code>//floodfill</code> - all of which are provided by WorldEditAdditions.
{% endgallerybox %}
{% gallerybox "images/gallery-b.jpeg" "image-b" "image-first" "image-last" %}
{% gallerybox "images/gallery-b.jpeg" "image-b" "image-first" "image-c" %}
The inside of a 3d maze made with <code>//maze3d</code>. Lighting was placed manually to improve screenshot quality.
{% endgallerybox %}
{% gallerybox "images/gallery-c.jpeg" "image-last" "image-b" "image-first" %}
{% gallerybox "images/gallery-c.jpeg" "image-c" "image-b" "image-d" %}
A cliff made with <code>//layers</code> and <code>//erode</code>. A <code>//forest</code> has been applied on top with multiple sapling / tree types.
{% endgallerybox %}
{% gallerybox "images/gallery-d.jpeg" "image-d" "image-c" "image-e" %}
A small mountain made with <code>//layers</code> and <code>//erode</code>, using the new optional <code>//layers</code> slope constraints in WorldEditAdditions v1.13.
{% endgallerybox %}
{% gallerybox "images/gallery-e.jpeg" "image-e" "image-d" "image-first" %}
A small mesa canyons terrain scene made with <code>//erode</code>, the new optional <code>//layers</code> slope contraints, and <code>//noiseapply2d</code> - the latter 2 of which are new in WorldEditAdditions v1.13. Minimal manual tuning was required.
{% endgallerybox %}
</section>
</section>
@ -105,7 +113,7 @@ git clone https://github.com/sbrl/Minetest-WorldEditAdditions.git worldeditaddit
<ul class="bigbutton-list">
<li><a class="bigbutton" href="/Reference">Reference</a></li>
<li><a class="bigbutton" href="/Cookbook">Cookbook</a></li>
<li><a class="bigbutton" href="/Tutorial">Tutorial for Beginners</a></li>
<li><a class="bigbutton" href="/Tutorial">Tutorial</a></li>
</ul>
</div>
</section>

View file

@ -1,4 +1,4 @@
const htmlentities = require("htmlentities");
const htmlentities = require("html-entities");
const markdown = require("markdown-it")({
xhtmlOut: true
});

View file

@ -8,11 +8,12 @@
"name": "worldeditadditions",
"version": "1.0.0",
"license": "MPL-2.0",
"dependencies": {
"html-entities": "^2.3.2"
},
"devDependencies": {
"@11ty/eleventy": "^0.12.1",
"@11ty/eleventy-img": "^0.9.0",
"html-entities": "^2.3.2",
"htmlentities": "^1.0.0",
"markdown-it-prism": "^2.1.8",
"phin": "^3.6.0"
}
@ -1870,14 +1871,7 @@
"node_modules/html-entities": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.3.2.tgz",
"integrity": "sha512-c3Ab/url5ksaT0WyleslpBEthOzWhrjQbg75y7XUsfSzi3Dgzt0l8w5e7DylRn15MTlMMD58dTfzddNS2kcAjQ==",
"dev": true
},
"node_modules/htmlentities": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/htmlentities/-/htmlentities-1.0.0.tgz",
"integrity": "sha1-CTqMH7Cd/l4Wn8M9CVdIJdYeQKQ=",
"dev": true
"integrity": "sha512-c3Ab/url5ksaT0WyleslpBEthOzWhrjQbg75y7XUsfSzi3Dgzt0l8w5e7DylRn15MTlMMD58dTfzddNS2kcAjQ=="
},
"node_modules/http-errors": {
"version": "1.7.3",
@ -6169,14 +6163,7 @@
"html-entities": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.3.2.tgz",
"integrity": "sha512-c3Ab/url5ksaT0WyleslpBEthOzWhrjQbg75y7XUsfSzi3Dgzt0l8w5e7DylRn15MTlMMD58dTfzddNS2kcAjQ==",
"dev": true
},
"htmlentities": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/htmlentities/-/htmlentities-1.0.0.tgz",
"integrity": "sha1-CTqMH7Cd/l4Wn8M9CVdIJdYeQKQ=",
"dev": true
"integrity": "sha512-c3Ab/url5ksaT0WyleslpBEthOzWhrjQbg75y7XUsfSzi3Dgzt0l8w5e7DylRn15MTlMMD58dTfzddNS2kcAjQ=="
},
"http-errors": {
"version": "1.7.3",

View file

@ -22,9 +22,10 @@
"devDependencies": {
"@11ty/eleventy": "^0.12.1",
"@11ty/eleventy-img": "^0.9.0",
"html-entities": "^2.3.2",
"htmlentities": "^1.0.0",
"markdown-it-prism": "^2.1.8",
"phin": "^3.6.0"
},
"dependencies": {
"html-entities": "^2.3.2"
}
}

View file

@ -31,6 +31,7 @@ read_globals = {
"it",
"describe",
"bonemeal",
"dofile"
"dofile",
"PerlinNoise"
}
std = "max"

View file

@ -10,11 +10,25 @@ Note to self: See the bottom of this file for the release template text.
- Add `//wcorner` (_wireframe corners_), `//wbox` (_wireframe box_), `//compass` (_wireframe compass_) - Wireframes implemented by @VorTechnix.
- Add `//for` for executing commands while changing their arguments - Implemented by @VorTechnix.
- Add `//sshift` (_selection shift_) - WorldEdit cuboid manipulator replacements implemented by @VorTechnix.
- Add `//noise2d` for perturbing terrain with multiple different noise functions
- Add `//noiseapply2d` for running commands on columns where a noise value is over a threshold
- Use [luacheck](https://github.com/mpeterv/luacheck) to find and fix a large number of bugs and other issues
- Multiple commands: Allow using quotes (`"thing"`, `'thing'`) to quote values when splitting
- `//layers`: Add optional slope constraint (inspired by [WorldPainter](https://worldpainter.net/))
- `//bonemeal`: Add optional node list constraint
- `//walls`: Add optional thickness argument
- `//sstack`: Add human-readable approx volumes of regions in the selection stack
### Bugfixes
- `//airapply`: Improve error handling, fix safe_region node counter
- `//floodfill`: Fix crash caused by internal refactoring of the `Queue` data structure
- `//spop`: Fix wording in displayed message
- Sapling alias compatibility:
- Correct alias of `default:sapling` from `oak` to `apple` (since it produces apples)
- `moretrees:apple_tree_sapling_ongen` from `apple` to `apple_moretrees`
- Add `plum``plumtree:sapling`
- Add `holly``hollytree:sapling`
## v1.12: The selection tools update (26th June 2021)

View file

@ -532,7 +532,7 @@ Applies 2D noise to the terrain in the defined region. Like `//erode`, this comm
Parameter | Type | Default Value | Description
------------|-----------|---------------|-----------------------
algorithm | `string` | perlin | The 2D noise algorithm to apply - see below.
algorithm | `string` | perlinmt | The 2D noise algorithm to apply - see below.
apply | `string|integer` | 5 | How to apply the noise to the terrain - see below.
scalex | `float` | 1 | The scale of the noise on the x axis.
scaley | `float` | 1 | The scale of the noise on the y axis.
@ -555,7 +555,8 @@ The following algorithms are currently available:
Algorithm | Description
------------|--------------------------
`perlin` | Perlin noise. Functional, but currently contains artefacts I'm having difficulty tracking down.
`perlinmt` | **Default**.Perlin noise, backed by Minetest's inbuilt `PerlinNoise` class.
`perlin` | Perlin noise, backed by a pure Lua perlin noise implementation. Functional, but currently contains artefacts I'm having difficulty tracking down.
`sin` | A sine wave created with `math.sin()`.
`white` | Random white noise.
`red` | Red noise - has a lower frequency than white noise. Ref [Noise Functions and Map Generation by Red Blob Games](https://www.redblobgames.com/articles/noise/introduction.html).
@ -681,6 +682,21 @@ As with `//ellipsoidapply` for advanced users `//multi` is also supported - but
```
## `//noiseapply2d <threshold> <scale> <command_name> <args>`
Like [`//ellipsoidapply`](#ellipsoidapply), but instead only keeps changes where a noise function (defaults to `perlinmt`, see [`//noise2d`](#noise2d)) returns a value greater than a given threshold value.
Also takes a scale value that controls the scale of the noise - -higher values result in smaller "blobs". If you're operating on small areas, then a value of at least 10 is advised as "blobs" are by default on the scale of ~50 nodes.
As with `//ellipsoidapply` for advanced users `//multi` is also supported - but make sure your modifications stay within the defined region - otherwise they be kept regardless, as `//noiseapply2d` only applies the masking to the nodes in the defined region.
Any suggestions on how to provide more customisability without making this command more difficult to use or significantly more inconsistent with other `//*apply` functions are welcome - please [open an issue](https://github.com/sbrl/Minetest-WorldEditAdditions/issues/new).
```weacmd
//noiseapply2d 0.5 10 set dirt
//noiseapply2d 0.4 3 layers dirt_with_snow dirt 3 stone 10
```
## `//scol [<axis1> ] <length>`
Short for _select column_. Sets the pos2 at a set distance along 1 axis from pos1. If the axis isn't specified, defaults the direction you are facing. Implementation thanks to @VorTechnix.

View file

@ -43,7 +43,13 @@ The following brushes together can make large-scale terrain sculpting easy:
```
## En-mass Foliage clearing
Clearing large amounts of foliage is easy!
Clearing large amounts of foliage is easy with the new `//subdivide` function!
```
//subdivide 20 20 20 //clearcut
```
Another good way to clear large chunk of land is with `//many`:
```
//many 25 //multi //clearcut //y //shift x 10

View file

@ -28,59 +28,62 @@ _(Do you have a cool build that you used WorldEditAdditions to build? [Get in to
The detailed explanations have moved! Check them out [here](https://github.com/sbrl/Minetest-WorldEditAdditions/blob/main/Chat-Command-Reference.md), or click the links below.
### Geometry
- [`//ellipsoid <rx> <ry> <rz> <node_name> [h[ollow]]`](https://github.com/sbrl/Minetest-WorldEditAdditions/blob/main/Chat-Command-Reference.md#ellipsoid-rx-ry-rz-node_name-hollow)
- [`//hollowellipsoid <rx> <ry> <rz> <node_name>`](https://github.com/sbrl/Minetest-WorldEditAdditions/blob/main/Chat-Command-Reference.md#hollowellipsoid-rx-ry-rz-node_name)
- [`//torus <major_radius> <minor_radius> <node_name> [<axes=xy> [h[ollow]]]`](https://github.com/sbrl/Minetest-WorldEditAdditions/blob/main/Chat-Command-Reference.md#torus-major_radius-minor_radius-node_name-axesxy-hollow)
- [`//hollowtorus <major_radius> <minor_radius> <node_name> [<axes=xy>]`](https://github.com/sbrl/Minetest-WorldEditAdditions/blob/main/Chat-Command-Reference.md#hollowtorus-major_radius-minor_radius-node_name-axesxy)
- [`//walls <replace_node>`](https://github.com/sbrl/Minetest-WorldEditAdditions/blob/main/Chat-Command-Reference.md#walls-replace_node)
- [`//line [<replace_node> [<radius>]]`](https://github.com/sbrl/Minetest-WorldEditAdditions/blob/main/Chat-Command-Reference.md#line-replace_node-radius)
- [`//hollow [<wall_thickness>]`](https://github.com/sbrl/Minetest-WorldEditAdditions/blob/main/Chat-Command-Reference.md#hollow-wall_thickness)
- [`//maze <replace_node> [<path_length> [<path_width> [<seed>]]]`](https://github.com/sbrl/Minetest-WorldEditAdditions/blob/main/Chat-Command-Reference.md#maze-replace_node-path_length-path_width-seed)
- [`//maze3d <replace_node> [<path_length> [<path_width> [<path_depth> [<seed>]]]]`](https://github.com/sbrl/Minetest-WorldEditAdditions/blob/main/Chat-Command-Reference.md#maze3d-replace_node-path_length-path_width-path_depth-seed)
- [`//ellipsoid <rx> <ry> <rz> <node_name> [h[ollow]]`](https://worldeditadditions.mooncarrot.space/Reference/#ellipsoid)
- [`//hollowellipsoid <rx> <ry> <rz> <node_name>`](https://worldeditadditions.mooncarrot.space/Reference/#hollowellipsoid)
- [`//torus <major_radius> <minor_radius> <node_name> [<axes=xy> [h[ollow]]]`](https://worldeditadditions.mooncarrot.space/Reference/#torus)
- [`//hollowtorus <major_radius> <minor_radius> <node_name> [<axes=xy>]`](https://worldeditadditions.mooncarrot.space/Reference/#hollowtorus)
- [`//walls <replace_node>`](https://worldeditadditions.mooncarrot.space/Reference/#walls)
- [`//line [<replace_node> [<radius>]]`](https://worldeditadditions.mooncarrot.space/Reference/#line)
- [`//hollow [<wall_thickness>]`](https://worldeditadditions.mooncarrot.space/Reference/#hollow)
- [`//maze <replace_node> [<path_length> [<path_width> [<seed>]]]`](https://worldeditadditions.mooncarrot.space/Reference/#maze)
- [`//maze3d <replace_node> [<path_length> [<path_width> [<path_depth> [<seed>]]]]`](https://worldeditadditions.mooncarrot.space/Reference/#maze3d)
### Misc
- [`//replacemix <target_node> [<chance>] <replace_node_a> [<chance_a>] [<replace_node_b> [<chance_b>]] [<replace_node_N> [<chance_N>]] ....`](https://github.com/sbrl/Minetest-WorldEditAdditions/blob/main/Chat-Command-Reference.md#replacemix-target_node-chance-replace_node_a-chance_a-replace_node_b-chance_b-replace_node_n-chance_n-)
- [`//floodfill [<replace_node> [<radius>]]`](https://github.com/sbrl/Minetest-WorldEditAdditions/blob/main/Chat-Command-Reference.md#floodfill-replace_node-radius-floodfill)
- [`//scale <axis> <scale_factor> | <factor_x> [<factor_y> <factor_z> [<anchor_x> <anchor_y> <anchor_z>]]`](https://github.com/sbrl/Minetest-WorldEditAdditions/blob/main/Chat-Command-Reference.md#scale-axis-scale_factor--factor_x-factor_y-factor_z-anchor_x-anchor_y-anchor_z) **experimental**
- [`//replacemix <target_node> [<chance>] <replace_node_a> [<chance_a>] [<replace_node_b> [<chance_b>]] [<replace_node_N> [<chance_N>]] ....`](https://worldeditadditions.mooncarrot.space/Reference/#replacemix)
- [`//floodfill [<replace_node> [<radius>]]`](https://worldeditadditions.mooncarrot.space/Reference/#floodfill)
- [`//scale <axis> <scale_factor> | <factor_x> [<factor_y> <factor_z> [<anchor_x> <anchor_y> <anchor_z>]]`](https://worldeditadditions.mooncarrot.space/Reference/#scale) **experimental**
### Terrain
- [`//overlay <node_name_a> [<chance_a>] <node_name_b> [<chance_b>] [<node_name_N> [<chance_N>]] ...`](https://github.com/sbrl/Minetest-WorldEditAdditions/blob/main/Chat-Command-Reference.md#overlay-node_name_a-chance_a-node_name_b-chance_b-node_name_n-chance_n-)
- [`//layers [<node_name_1> [<layer_count_1>]] [<node_name_2> [<layer_count_2>]] ...`](https://github.com/sbrl/Minetest-WorldEditAdditions/blob/main/Chat-Command-Reference.md#layers-node_name_1-layer_count_1-node_name_2-layer_count_2-)
- [`//fillcaves [<node_name>]`](https://github.com/sbrl/Minetest-WorldEditAdditions/blob/main/Chat-Command-Reference.md#fillcaves-node_name)
- [`//convolve <kernel> [<width>[,<height>]] [<sigma>]`](https://github.com/sbrl/Minetest-WorldEditAdditions/blob/main/Chat-Command-Reference.md#convolve-kernel-widthheight-sigma)
- [`//erode [<snowballs|river> [<key_1> [<value_1>]] [<key_2> [<value_2>]] ...]`](https://github.com/sbrl/Minetest-WorldEditAdditions/blob/main/Chat-Command-Reference.md#erode-snowballsriver-key_1-value_1-key_2-value_2-) **experimental**
- [`//overlay <node_name_a> [<chance_a>] <node_name_b> [<chance_b>] [<node_name_N> [<chance_N>]] ...`](https://worldeditadditions.mooncarrot.space/Reference/#overlay)
- [`//layers [<node_name_1> [<layer_count_1>]] [<node_name_2> [<layer_count_2>]] ...`](https://worldeditadditions.mooncarrot.space/Reference/#layers)
- [`//fillcaves [<node_name>]`](https://worldeditadditions.mooncarrot.space/Reference/#fillcaves)
- [`//convolve <kernel> [<width>[,<height>]] [<sigma>]`](https://worldeditadditions.mooncarrot.space/Reference/#convolve)
- [`//erode [<snowballs|river> [<key_1> [<value_1>]] [<key_2> [<value_2>]] ...]`](https://worldeditadditions.mooncarrot.space/Reference/#erode) **experimental**
- [`//noise2d [<key_1> [<value_1>]] [<key_2> [<value_2>]] ...]`](https://worldeditadditions.mooncarrot.space/Reference/#noise2d)
### Flora
- [`//bonemeal [<strength> [<chance>]]`](https://github.com/sbrl/Minetest-WorldEditAdditions/blob/main/Chat-Command-Reference.md#bonemeal-strength-chance)
- [`//forest [<density>] <sapling_a> [<chance_a>] <sapling_b> [<chance_b>] [<sapling_N> [<chance_N>]] ...`](https://github.com/sbrl/Minetest-WorldEditAdditions/blob/main/Chat-Command-Reference.md#forest-density-sapling_a-chance_a-sapling_b-chance_b-sapling_N-chance_N-) _(new in v1.9)_
- [`//saplingaliases [aliases|all_saplings]`](https://github.com/sbrl/Minetest-WorldEditAdditions/blob/main/Chat-Command-Reference.md#saplingaliases-aliasesall_saplings) _(new in v1.9)_
- [`//forest [<density>] <sapling_a> [<chance_a>] <sapling_b> [<chance_b>] [<sapling_N> [<chance_N>]] ...`](https://worldeditadditions.mooncarrot.space/Reference/#forest) _(new in v1.9)_
- [`//saplingaliases [aliases|all_saplings]`](https://worldeditadditions.mooncarrot.space/Reference/#saplingaliases) _(new in v1.9)_
### Statistics
- [`//count`](https://github.com/sbrl/Minetest-WorldEditAdditions/blob/main/Chat-Command-Reference.md#count)
- [`//count`](https://worldeditadditions.mooncarrot.space/Reference/#count)
### Selection
- [`//scol [<axis1> ] <length>`](https://github.com/sbrl/Minetest-WorldEditAdditions/blob/main/Chat-Command-Reference.md#scol-axis1--length)
- [`//srect [<axis1> [<axis2>]] <length>`](https://github.com/sbrl/Minetest-WorldEditAdditions/blob/main/Chat-Command-Reference.md#srect-axis1-axis2-length)
- [`//scube [<axis1> [<axis2> [<axis3>]]] <length>`](https://github.com/sbrl/Minetest-WorldEditAdditions/blob/main/Chat-Command-Reference.md#scube-axis1-axis2-axis3-length)
- [`//scloud <0-6|stop|reset>`](https://github.com/sbrl/Minetest-WorldEditAdditions/blob/main/Chat-Command-Reference.md#scloud-0-6stopreset)
- [`//scentre`](https://github.com/sbrl/Minetest-WorldEditAdditions/blob/main/Chat-Command-Reference.md#scentre)
- [`//srel <axis1> <length1> [<axis2> <length2> [<axis3> <length3>]]`](https://github.com/sbrl/Minetest-WorldEditAdditions/blob/main/Chat-Command-Reference.md#srel-axis1-length1-axis2-length2-axis3-length3)
- [`//smake <operation:odd|even|equal> <mode:grow|shrink|average> [<target=xz> [<base>]]`](https://github.com/sbrl/Minetest-WorldEditAdditions/blob/main/Chat-Command-Reference.md#smake-operationoddevenequal-modegrowshrinkaverage-targetxz-base)
- [`//sstack`](https://github.com/sbrl/Minetest-WorldEditAdditions/blob/main/Chat-Command-Reference.md#sstack)
- [`//spush`](https://github.com/sbrl/Minetest-WorldEditAdditions/blob/main/Chat-Command-Reference.md#spush)
- [`//spop`](https://github.com/sbrl/Minetest-WorldEditAdditions/blob/main/Chat-Command-Reference.md#spop)
- [`//scol [<axis1> ] <length>`](https://worldeditadditions.mooncarrot.space/Reference/#scol)
- [`//srect [<axis1> [<axis2>]] <length>`](https://worldeditadditions.mooncarrot.space/Reference/#srect)
- [`//scube [<axis1> [<axis2> [<axis3>]]] <length>`](https://worldeditadditions.mooncarrot.space/Reference/#scube)
- [`//scloud <0-6|stop|reset>`](https://worldeditadditions.mooncarrot.space/Reference/#scloud)
- [`//scentre`](https://worldeditadditions.mooncarrot.space/Reference/#scentre)
- [`//srel <axis1> <length1> [<axis2> <length2> [<axis3> <length3>]]`](https://worldeditadditions.mooncarrot.space/Reference/#srel)
- [`//smake <operation:odd|even|equal> <mode:grow|shrink|average> [<target=xz> [<base>]]`](https://worldeditadditions.mooncarrot.space/Reference/#smake)
- [`//sstack`](https://worldeditadditions.mooncarrot.space/Reference/#sstack)
- [`//spush`](https://worldeditadditions.mooncarrot.space/Reference/#spush)
- [`//spop`](https://worldeditadditions.mooncarrot.space/Reference/#spop)
### Measure
- [`//mface`](Chat-Command-Reference.md#mface)
- [`//midpos`](Chat-Command-Reference.md#midpos)
- [`//msize`](Chat-Command-Reference.md#msize)
- [`//mtrig`](Chat-Command-Reference.md#mtrig)
- [`//mface`](https://worldeditadditions.mooncarrot.space/Reference/#mface) _(new in v1.13)_
- [`//midpos`](https://worldeditadditions.mooncarrot.space/Reference/#midpos) _(new in v1.13)_
- [`//msize`](https://worldeditadditions.mooncarrot.space/Reference/#msize) _(new in v1.13)_
- [`//mtrig`](https://worldeditadditions.mooncarrot.space/Reference/#mtrig) _(new in v1.13)_
### Meta
- [`//multi <command_a> <command_b> ....`](https://github.com/sbrl/Minetest-WorldEditAdditions/blob/main/Chat-Command-Reference.md#multi-command_a-command_b-command_c-)
- [`//many <times> <command>`](https://github.com/sbrl/Minetest-WorldEditAdditions/blob/main/Chat-Command-Reference.md#many-times-command) _(new in v1.9)_
- [`//subdivide <size_x> <size_y> <size_z> <cmd_name> <args>`](https://github.com/sbrl/Minetest-WorldEditAdditions/blob/main/Chat-Command-Reference.md#subdivide-size_x-size_y-size_z-cmd_name-args) **experimental**
- [`//ellipsoidapply <command_name> <args>`](https://github.com/sbrl/Minetest-WorldEditAdditions/blob/main/Chat-Command-Reference.md#ellipsoidapply-command_name-args) _(new in v1.9)_
- [`//multi <command_a> <command_b> ....`](https://worldeditadditions.mooncarrot.space/Reference/#multi)
- [`//many <times> <command>`](https://worldeditadditions.mooncarrot.space/Reference/#many) _(new in v1.9)_
- [`//subdivide <size_x> <size_y> <size_z> <cmd_name> <args>`](https://worldeditadditions.mooncarrot.space/Reference/#subdivide)
- [`//ellipsoidapply <command_name> <args>`](https://worldeditadditions.mooncarrot.space/Reference/#ellipsoidapply) _(new in v1.9)_
- [`//airapply <command_name> <args>`](https://worldeditadditions.mooncarrot.space/Reference/#airapply) _(new in v1.9)_
- [`//noiseapply2d <threshold> <scale> <command_name> <args>`](https://worldeditadditions.mooncarrot.space/Reference/#noiseapply2d) _(new in v1.13)_
### Extras
- [`//y`](https://github.com/sbrl/Minetest-WorldEditAdditions/blob/main/Chat-Command-Reference.md#y)

View file

@ -62,6 +62,7 @@ dofile(wea.modpath.."/lib/forest.lua")
dofile(wea.modpath.."/lib/ellipsoidapply.lua")
dofile(wea.modpath.."/lib/airapply.lua")
dofile(wea.modpath.."/lib/noiseapply2d.lua")
dofile(wea.modpath.."/lib/subdivide.lua")

View file

@ -16,7 +16,7 @@ Alternatively, you can register support in your mod directly. Do that by adding
if minetest.get_modpath("default") then
worldeditadditions.register_sapling_alias_many({
{ "default:sapling", "oak" },
{ "default:sapling", "apple" },
{ "default:bush_sapling", "bush" },
{ "default:pine_sapling", "pine" },
{ "default:pine_bush_sapling", "pine_bush" },
@ -40,7 +40,7 @@ if minetest.get_modpath("moretrees") then
{ "moretrees:willow_sapling_ongen", "willow_moretrees" },
{ "moretrees:poplar_sapling_ongen", "poplar" },
{ "moretrees:poplar_small_sapling_ongen", "poplar_small" },
{ "moretrees:apple_tree_sapling_ongen", "apple" },
{ "moretrees:apple_tree_sapling_ongen", "apple_moretrees" },
{ "moretrees:birch_sapling_ongen", "birch_moretrees" },
{ "moretrees:palm_sapling_ongen", "palm_moretrees" },
{ "moretrees:date_palm_sapling_ongen", "palm_date" },
@ -110,6 +110,12 @@ end
if minetest.get_modpath("palm") then
worldeditadditions.register_sapling_alias("palm:sapling", "palm")
end
if minetest.get_modpath("plumtree") then
worldeditadditions.register_sapling_alias("plumtree:sapling", "plum")
end
if minetest.get_modpath("hollytree") then
worldeditadditions.register_sapling_alias("hollytree:sapling", "holly")
end
if minetest.get_modpath("pomegranate") then
worldeditadditions.register_sapling_alias("pomegranate:sapling", "pomegranate")
end

View file

@ -27,8 +27,7 @@ function worldeditadditions.floodfill(start_pos, radius, replace_node)
end
local count = 0
local remaining_nodes = wea.Queue.new()
remaining_nodes:enqueue(start_pos_index)
local remaining_nodes = wea.Queue.new() remaining_nodes:enqueue(start_pos_index)
-- Do the floodfill
while remaining_nodes:is_empty() == false do

View file

@ -2,8 +2,9 @@ local wea = worldeditadditions
return {
available = { "perlin", "sin", "white", "red", "infrared" },
available = { "perlin", "perlinmt", "sin", "white", "red", "infrared" },
Perlin = dofile(wea.modpath.."/lib/noise/engines/perlin.lua"),
PerlinMT = dofile(wea.modpath.."/lib/noise/engines/perlinmt.lua"),
Sin = dofile(wea.modpath.."/lib/noise/engines/sin.lua"),
White = dofile(wea.modpath.."/lib/noise/engines/white.lua"),
Red = dofile(wea.modpath.."/lib/noise/engines/red.lua"),

View file

@ -0,0 +1,32 @@
local wea = worldeditadditions
local PerlinMT = {}
PerlinMT.__index = PerlinMT
function PerlinMT.new(seed, params)
if not seed then seed = 0 end
local result = {
-- Provided by Minetest
engine = PerlinNoise({
offset = 0,
scale = 1,
spread = {x = 50, y = 50, z = 50},
seed = seed,
octaves = 1,
persistence = 0.63,
lacunarity = 2.0,
flags = "defaults,absvalue",
})
}
setmetatable(result, PerlinMT)
return result
end
function PerlinMT:noise( x, y, z )
local value = self.engine:get_3d(wea.Vector3.new(x, y, z))
return value
end
return PerlinMT

View file

@ -11,12 +11,16 @@ local wea = worldeditadditions
-- @param size Vector An x/y vector representing the size of the noise area to generate.
-- @param params table|table<table> A table of noise params to use to generate the noise. Values that aren't specified are filled in automatically. If a table of tables is specified, it is interpreted as multiple octaves of noise to apply in sequence.
function worldeditadditions.noise.make_2d(size, start_pos, params)
params = worldeditadditions.noise.params_apply_default(params)
local result = {}
for layer_i, layer in ipairs(params) do
local generator
if layer.algorithm == "perlin" then
generator = wea.noise.engines.Perlin.new()
elseif layer.algorithm == "perlinmt" then
generator = wea.noise.engines.PerlinMT.new()
elseif layer.algorithm == "sin" then
generator = wea.noise.engines.Sin.new()
elseif layer.algorithm == "white" then

View file

@ -13,7 +13,7 @@ function worldeditadditions.noise.params_apply_default(params)
-- - A string in the form of digits followed, then the noise will is remapped from the range 0 - 1 to the range -1 - +1 and multiplied by this number / 2, and then for each pixel in the heightmap the corresponding noise value will be added to it.
apply = 5,
-- The backend noise algorithm to use
algorithm = "perlin",
algorithm = "perlinmt",
-- Zooms in and out
scale = wea.Vector3.new(1, 1, 1),
-- Offset the generated noise by this vector.

View file

@ -0,0 +1,60 @@
-- ███ ██ ██████ ██ ███████ ███████ █████ ██████ ██████ ██ ██ ██ ██████ ██████
-- ████ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
-- ██ ██ ██ ██ ██ ██ ███████ █████ ███████ ██████ ██████ ██ ████ █████ ██ ██
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
-- ██ ████ ██████ ██ ███████ ███████ ██ ██ ██ ██ ███████ ██ ███████ ██████
--- Similar to cubeapply, except that it takes 2 positions and randomly keeps changes based on a noise pattern.
-- Takes a backup copy of the defined region, runs the given function, and then
-- restores the bits that aren't above the nosie threshold.
-- @param {Position} pos1 The 1st position defining the region boundary
-- @param {Position} pos2 The 2nd positioon defining the region boundary
-- @param {Function} func The function to call that performs the action in question. It is expected that the given function will accept no arguments.
function worldeditadditions.noiseapply2d(pos1, pos2, threshold, scale, func)
local time_taken_all = worldeditadditions.get_ms_time()
pos1, pos2 = worldeditadditions.Vector3.sort(pos1, pos2)
if not threshold then threshold = 0.5 end
-- pos2 will always have the highest co-ordinates now
-- Fetch the nodes in the specified area
local manip_before, area_before = worldedit.manip_helpers.init(pos1, pos2)
local data_before = manip_before:get_data()
local time_taken_fn = worldeditadditions.get_ms_time()
func()
time_taken_fn = worldeditadditions.get_ms_time() - time_taken_fn
local manip_after, area_after = worldedit.manip_helpers.init(pos1, pos2)
local data_after = manip_after:get_data()
local size2d = pos2 - pos1 + worldeditadditions.Vector3.new(1, 1, 1)
print("DEBUG pos1", pos1, "pos2", pos2, "size2d", size2d)
local success, noise = worldeditadditions.noise.make_2d(size2d, pos1, {
algorithm = "perlinmt",
scale = scale
})
if not success then return success, noise end
for z = pos2.z, pos1.z, -1 do
for y = pos2.y, pos1.y, -1 do
for x = pos2.x, pos1.x, -1 do
local i_before = area_before:index(x, y, z)
local i_after = area_after:index(x, y, z)
local i_noise = (z-pos1.z)*size2d.x + (x-pos1.x)
-- Roll everything where the noise function returns less than 0.5
if noise[i_noise] < threshold then
data_after[i_after] = data_before[i_before]
end
end
end
end
-- Save the modified nodes back to disk & return
-- No need to save - this function doesn't actually change anything
worldedit.manip_helpers.finish(manip_after, data_after)
time_taken_all = worldeditadditions.get_ms_time() - time_taken_all
return true, { all = time_taken_all, fn = time_taken_fn }
end

View file

@ -61,7 +61,7 @@ function Queue:dequeue()
-- Find the next non-nil item
local value
while value == nil do
if first >= self.last then return nil end
if first > self.last then return nil end
value = self.items[first]
self.items[first] = nil -- Help the garbage collector out
first = first + 1

View file

@ -38,8 +38,10 @@ worldedit.register_command("airapply", {
return true, cmd_we, args_parsed
end,
nodes_needed = function(name)
local pos1, pos2 = worldedit.sort_pos(worldedit.pos1[name], worldedit.pos2[name])
return math.ceil(4/3 * math.pi * (pos2.x - pos1.x)/2 * (pos2.y - pos1.y)/2 * (pos2.z - pos1.z)/2)
return worldedit.volume(
worldedit.pos1[name],
worldedit.pos2[name]
)
end,
func = function(name, cmd, args_parsed)
if not minetest.check_player_privs(name, cmd.privs) then
@ -56,8 +58,9 @@ worldedit.register_command("airapply", {
pos1, pos2,
function()
cmd.func(name, worldeditadditions.table.unpack(args_parsed))
end, args_parsed
end
)
if not success then return success, stats_time end
local time_overhead = 100 - worldeditadditions.round((stats_time.fn / stats_time.all) * 100, 3)

View file

@ -0,0 +1,87 @@
-- ███ ██ ██████ ██ ███████ ███████ █████ ██████ ██████ ██ ██ ██ ██████ ██████
-- ████ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
-- ██ ██ ██ ██ ██ ██ ███████ █████ ███████ ██████ ██████ ██ ████ █████ ██ ██
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
-- ██ ████ ██████ ██ ███████ ███████ ██ ██ ██ ██ ███████ ██ ███████ ██████
worldedit.register_command("noiseapply2d", {
params = "<threshold> <scale> <command_name> <args>",
description = "Executes the given command (automatically prepending '//'), but uses a 2d noise function with both a threshold value (a number between 0 and 1) and a scale value (number, 1 = normal scale, for small areas 10+ is recommended) to filter where in the defined region it's applied.",
privs = { worldedit = true },
require_pos = 2,
parse = function(params_text)
if params_text == "" then return false, "Error: No command specified." end
local threshold_text, scale_text, cmd_name, args_text = params_text:match("([^%s]+)%s+([^%s]+)%s+([^%s]+)%s*(.*)")
if not args_text then
args_text = ""
end
-- Note that we search the worldedit commands here, not the minetest ones
local cmd_we = worldedit.registered_commands[cmd_name]
if cmd_we == nil then
return false, "Error: "..cmd_name.." isn't a valid command."
end
if cmd_we.require_pos ~= 2 and cmd_name ~= "multi" then
return false, "Error: The command "..cmd_name.." exists, but doesn't take 2 positions and so can't be used with //noiseapply2d."
end
-- Run parsing of target command
-- Lifted from cubeapply in WorldEdit
local args_parsed = {cmd_we.parse(args_text)}
if not table.remove(args_parsed, 1) then
return false, args_parsed[1]
end
local threshold = tonumber(threshold_text)
if not threshold then
return false, "Error: Invalid threshold value '"..threshold_text.."'. Threshold values should be a floating-point number between 0 and 1."
end
if threshold < 0 or threshold > 1 then
return false, "Error: The threshold value '"..threshold.."' is out of bounds. Threshold values should be floating-point numbers between 0 and 1."
end
local scale = tonumber(scale_text)
if not scale then
return false, "Error: Invalid scale value '"..threshold_text.."'. Threshold values should be a floating-point number between 0 and 1."
end
return true, 1 - threshold, scale, cmd_we, args_parsed
end,
nodes_needed = function(name)
return worldedit.volume(
worldedit.pos1[name],
worldedit.pos2[name]
)
end,
func = function(name, threshold, scale, cmd, args_parsed)
if not minetest.check_player_privs(name, cmd.privs) then
return false, "Your privileges are insufficient to execute the command '"..cmd.."'."
end
local pos1, pos2 = worldeditadditions.Vector3.sort(
worldedit.pos1[name],
worldedit.pos2[name]
)
local success, stats_time = worldeditadditions.noiseapply2d(
pos1, pos2,
threshold,
worldeditadditions.Vector3.new(
scale, scale, scale
),
function()
cmd.func(name, worldeditadditions.table.unpack(args_parsed))
end
)
if not success then return success, stats_time end
local time_overhead = 100 - worldeditadditions.round((stats_time.fn / stats_time.all) * 100, 3)
local text_time_all = worldeditadditions.format.human_time(stats_time.all)
local text_time_fn = worldeditadditions.format.human_time(stats_time.fn)
minetest.log("action", name.." used //noiseapply2d at "..pos1.." - "..pos2.." in "..text_time_all)
return true, "Complete in "..text_time_all.." ("..text_time_fn.." fn, "..time_overhead.."% noiseapply2d overhead)"
end
})

View file

@ -27,7 +27,7 @@ worldedit.register_command("spop", {
local region_text = worldeditadditions.vector.tostring(worldedit.pos1[name]).." - "..worldeditadditions.vector.tostring(worldedit.pos2[name])
minetest.log("action", name .. " used //spush at "..region_text..". Stack height is now " .. new_count.." regions")
return true, "Region "..region_text.." pushed onto selection stack; "..new_count.." region"..plural.." now in the stack"
minetest.log("action", name .. " used //spopped at "..region_text..". Stack height is now " .. new_count.." regions")
return true, "Region "..region_text.." popped from selection stack; "..new_count.." region"..plural.." now in the stack"
end
})

View file

@ -20,8 +20,15 @@ worldedit.register_command("sstack", {
table.insert(result, "(empty)")
else
for i,item in ipairs(worldeditadditions.sstack[name]) do
local volume = worldedit.volume(item[1], item[2])
local volume_text = worldeditadditions.format.human_size(volume, 2)
if volume > 1000 then volume_text = "~"..volume_text end
table.insert(result, i)
table.insert(result, ": ")
table.insert(result, volume_text)
table.insert(result, " nodes - ")
table.insert(result, worldeditadditions.vector.tostring(item[1]))
table.insert(result, " - ")
table.insert(result, worldeditadditions.vector.tostring(item[2]))