mirror of
https://github.com/sbrl/Minetest-WorldEditAdditions.git
synced 2024-12-22 19:45:02 +00:00
Merge branch 'main' into VorTechnix
This commit is contained in:
commit
a5960983e7
25 changed files with 316 additions and 80 deletions
|
@ -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
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
BIN
.docs/images/gallery-e.jpeg
Normal file
Binary file not shown.
After Width: | Height: | Size: 615 KiB |
|
@ -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>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
const htmlentities = require("htmlentities");
|
||||
const htmlentities = require("html-entities");
|
||||
const markdown = require("markdown-it")({
|
||||
xhtmlOut: true
|
||||
});
|
||||
|
|
23
.docs/package-lock.json
generated
23
.docs/package-lock.json
generated
|
@ -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",
|
||||
|
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@ read_globals = {
|
|||
"it",
|
||||
"describe",
|
||||
"bonemeal",
|
||||
"dofile"
|
||||
"dofile",
|
||||
"PerlinNoise"
|
||||
}
|
||||
std = "max"
|
||||
|
|
14
CHANGELOG.md
14
CHANGELOG.md
|
@ -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)
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
79
README.md
79
README.md
|
@ -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)
|
||||
|
|
|
@ -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")
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"),
|
||||
|
|
32
worldeditadditions/lib/noise/engines/perlinmt.lua
Normal file
32
worldeditadditions/lib/noise/engines/perlinmt.lua
Normal 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
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
60
worldeditadditions/lib/noiseapply2d.lua
Normal file
60
worldeditadditions/lib/noiseapply2d.lua
Normal 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
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
87
worldeditadditions_commands/commands/meta/noiseapply2d.lua
Normal file
87
worldeditadditions_commands/commands/meta/noiseapply2d.lua
Normal 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
|
||||
})
|
|
@ -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
|
||||
})
|
||||
|
|
|
@ -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]))
|
||||
|
|
Loading…
Reference in a new issue