Compare commits

...

8 Commits

Author SHA1 Message Date
Starbeamrainbowlabs 7236232dc0
docs: fix the 1st command documented not showing up in the site
Rogue .slice(1)
2023-07-11 00:52:04 +01:00
Starbeamrainbowlabs c8e717a6d6
typo 2023-07-11 00:39:48 +01:00
Starbeamrainbowlabs 4745009632
//saplingaliases: update moretrees aliases
Alias to normal rather than *_ongen
2023-07-10 21:33:37 +01:00
Starbeamrainbowlabs f7429fa40e
//move+, //copy+ override //move, //copy by default 2023-07-10 21:12:54 +01:00
Starbeamrainbowlabs 277f3a8155
//move+: respect param2
Also update changelog
2023-07-10 21:08:17 +01:00
Starbeamrainbowlabs d63400e697
//copy+: respect param2 2023-07-10 21:02:03 +01:00
Starbeamrainbowlabs 5c632df658
Override basic selection commands
//mark
//unmark
//pos1 //1
//pos2 //2
//reset
Also add //pos <index>
2023-07-10 20:17:28 +01:00
Starbeamrainbowlabs 693fc145d5
pos: avoid calling worldedit.marker_update unless necessary 2023-07-10 19:25:48 +01:00
16 changed files with 307 additions and 53 deletions

View File

@ -17,7 +17,7 @@ let { sections, categories } = parse_sections(fs.readFileSync(
"utf-8"
))
sections = sections.slice(1).sort((a, b) => a.title.replace(/^\/+/g, "").localeCompare(
sections = sections.sort((a, b) => a.title.replace(/^\/+/g, "").localeCompare(
b.title.replace(/^\/+/g, "")));

View File

@ -1,7 +1,7 @@
{%
# Lists of axes
In various commands such as `//copy+`, `//move+`, and others lists of axes are used. These are all underpinned by a single grammar and a single parser (located in `worldeditadditions/utils/parse/axes.lua`). While the parser itself requires pre-split tokens (see `split_shell` for that), the grammar which it parses is documnted here.
In various commands such as `//copy+`, `//move+`, and others lists of axes are used. These are all underpinned by a single grammar and a single parser (located in `worldeditadditions/utils/parse/axes.lua`). While the parser itself requires pre-split tokens (see `split_shell` for that), the grammar which it parses is documented here.
Examples:

View File

@ -57,7 +57,7 @@ module.exports = function parse_sections(source) {
for(let line of lines) {
if(line.startsWith(`#`)) {
let heading_level = line.match(/^#+/)[0].length
let heading_level = line.match(/^#+/)[0].length;
// 1: Deal with the previous section
if(acc.length > 0) {

View File

@ -12,9 +12,13 @@ Note to self: See the bottom of this file for the release template text.
- Implement custom region boxing UI, which replaces the WorldEdit region box when using WorldEditAdditions wands.
- Is backwards compatible with regular WorldEdit wands and tools, as WorldEditAdditions keeps the new positioning system in sync with WorldEdit's.
- The new multipoint wand required this as a prerequisite
- Add [`//pos`](https://worldeditadditions.mooncarrot.space/Reference/#pos), for setting any numbered point (i.e. not just pos1 and pos2, but pos3 and beyond)
- Add [`//spline`](https://worldeditadditions.mooncarrot.space/Reference/#spline), for drawing curved lines with an arbitrary number of points **(uses the new multi-point wand)**
- Add [`//revolve`](https://worldeditadditions.mooncarrot.space/Reference/#revolve), which makes multiple evenly-spaced rotated copies of the defined region **(uses the new multi-point wand)**
- [`//copy+`](https://worldeditadditions.mooncarrot.space/Reference/#copy), [`//move+`](https://worldeditadditions.mooncarrot.space/Reference/#move): Added support for integrated `airapply` mode, which replaces nodes at the target only if they are air - append `airapply`/`aa` to the command to use
- [`//copy+`](https://worldeditadditions.mooncarrot.space/Reference/#copy), [`//move+`](https://worldeditadditions.mooncarrot.space/Reference/#move):
- Added support for integrated `airapply` mode, which replaces nodes at the target only if they are air - append `airapply`/`aa` to the command to use
- Respect node rotation (i.e. param2) when copying/moving
- Override `//move` and `//copy` by default
### Bugfixes and changes
- Migrate from `depends.txt` to `mod.conf`

View File

@ -868,7 +868,75 @@ Returns the absolute canonical name of a node, given an alias or partial node na
███████ ███████ ███████ ███████ ██████ ██ ██ ██████ ██ ████
-->
### `//unmark`
Hides the in-game UI that indicates where the current positions and region are located.
This hides both the WorldEditAdditions *and* the WorldEdit UI if displayed, but does **not** change or remove any points that are registered.
Should more than 2 points be defined, they are all hidden.
```weacmd
//unmark
```
### `//mark`
Shows the in-game UI that indicates where the current positions and region are located once more.
Should more than 2 points be defined, they are all shown once more.
Often used after calling [`//unmark`](#unmark)
```weacmd
//mark
```
### `//pos1`
Sets pos1 to the location of the calling player.
This is, as with all other WorldEditAdditions commands, seamlessly synchronised with WorldEdit, allowing you to use any combination of WorldEditAdditions and WorldEdit commands and tools without them desynchronising from one another.
**Aliases:** `//1`
```weacmd
//pos2
```
### `//pos2`
Sets pos1 to the location of the calling player.
This is, as with all other WorldEditAdditions commands, seamlessly synchronised with WorldEdit, allowing you to use any combination of WorldEditAdditions and WorldEdit commands and tools without them desynchronising from one another.
**Aliases:** `//2`
```weacmd
//pos2
```
### `//pos <index>`
Sets position with the given index `<index>` to the location of the calling player.
Should the index be less than or equal to 2, then as with all other WorldEditAdditions commands, seamlessly synchronised with WorldEdit, allowing you to use any combination of WorldEditAdditions and WorldEdit commands and tools without them desynchronising from one another.
Should the index be greater than 2, the position will only be registered in WorldEditAdditions, as WorldEdit does not support defining more than 2 points.
If no index is specified, an error is returned and nothing is done.
```weacmd
//pos 1
//pos 3
//pos 45
//pos 2
```
### `//reset`
Clears all positions defined and the defined region.
This also synchronises with WorldEdit, as all other WorldEditAdditions commands do.
```weacmd
//reset
```
### `//scol [<axis1> ] <length>`

View File

@ -34,21 +34,21 @@ end
if minetest.get_modpath("moretrees") then
wea_c.register_sapling_alias_many({
{ "moretrees:spruce_sapling_ongen", "spruce" },
{ "moretrees:rubber_tree_sapling_ongen", "rubber" },
{ "moretrees:beech_sapling_ongen", "beech" },
{ "moretrees:jungletree_sapling_ongen", "jungle_moretrees" },
{ "moretrees:fir_sapling_ongen", "fir" },
{ "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" },
{ "moretrees:birch_sapling_ongen", "birch_moretrees" },
{ "moretrees:palm_sapling_ongen", "palm_moretrees" },
{ "moretrees:date_palm_sapling_ongen", "palm_date" },
{ "moretrees:sequoia_sapling_ongen", "sequoia" },
{ "moretrees:oak_sapling_ongen", "oak_moretrees" },
{ "moretrees:cedar_sapling_ongen", "cedar" }
{ "moretrees:spruce_sapling", "spruce" },
{ "moretrees:rubber_tree_sapling", "rubber" },
{ "moretrees:beech_sapling", "beech" },
{ "moretrees:jungletree_sapling", "jungle_moretrees" },
{ "moretrees:fir_sapling", "fir" },
{ "moretrees:willow_sapling", "willow_moretrees" },
{ "moretrees:poplar_sapling", "poplar" },
{ "moretrees:poplar_small_sapling", "poplar_small" },
{ "moretrees:apple_tree_sapling", "apple_moretrees" },
{ "moretrees:birch_sapling", "birch_moretrees" },
{ "moretrees:palm_sapling", "palm_moretrees" },
{ "moretrees:date_palm_sapling", "palm_date" },
{ "moretrees:sequoia_sapling", "sequoia" },
{ "moretrees:oak_sapling", "oak_moretrees" },
{ "moretrees:cedar_sapling", "cedar" }
})
end

View File

@ -27,10 +27,12 @@ function worldeditadditions.copy(source_pos1, source_pos2, target_pos1, target_p
-- Fetch the nodes in the source area
local manip_source, area_source = worldedit.manip_helpers.init(source_pos1, source_pos2)
local data_source = manip_source:get_data()
local data_source_param2 = manip_source:get_param2_data()
-- Fetch a manip for the target area
local manip_target, area_target = worldedit.manip_helpers.init(target_pos1, target_pos2)
local data_target = manip_target:get_data()
local data_target_param2 = manip_target:get_param2_data()
-- z y x is the preferred loop order (because CPU cache, since then we're iterating linearly through the data array backwards. This only holds true for little-endian machines however)
local total_replaced = 0
@ -48,6 +50,7 @@ function worldeditadditions.copy(source_pos1, source_pos2, target_pos1, target_p
end
if should_replace then
data_target[target_i] = data_source[source_i]
data_target_param2[target_i] = data_source_param2[source_i]
total_replaced = total_replaced + 1
end
end
@ -55,6 +58,7 @@ function worldeditadditions.copy(source_pos1, source_pos2, target_pos1, target_p
end
-- Save the modified nodes back to disk & return
manip_target:set_param2_data(data_target_param2)
worldedit.manip_helpers.finish(manip_target, data_target)
return true, total_replaced

View File

@ -34,10 +34,12 @@ function worldeditadditions.move(source_pos1, source_pos2, target_pos1, target_p
-- Fetch the nodes in the source area
local manip_source, area_source = worldedit.manip_helpers.init(source_pos1, source_pos2)
local data_source = manip_source:get_data()
local data_source_param2 = manip_source:get_param2_data()
-- Fetch a manip for the target area
local manip_target, area_target = worldedit.manip_helpers.init(target_pos1, target_pos2)
local data_target = manip_target:get_data()
local data_target_param2 = manip_target:get_param2_data()
---
@ -60,6 +62,7 @@ function worldeditadditions.move(source_pos1, source_pos2, target_pos1, target_p
end
if should_replace then
data_target[target_i] = data_source[source_i]
data_target_param2[target_i] = data_source_param2[source_i]
total_placed = total_placed + 1
end
end
@ -83,7 +86,7 @@ function worldeditadditions.move(source_pos1, source_pos2, target_pos1, target_p
---
-- 2: Save target
---
manip_target:set_param2_data(data_target_param2)
worldedit.manip_helpers.finish(manip_target, data_target)
@ -93,6 +96,7 @@ function worldeditadditions.move(source_pos1, source_pos2, target_pos1, target_p
manip_source, area_source = worldedit.manip_helpers.init(source_pos1, source_pos2)
data_source = manip_source:get_data()
data_source_param2 = manip_source:get_param2_data()
---
@ -108,6 +112,7 @@ function worldeditadditions.move(source_pos1, source_pos2, target_pos1, target_p
if not source:is_contained(target_pos1, target_pos2) then
data_source[source_i] = node_id_air
data_source_param2[source_i] = 0
end
end
end
@ -118,6 +123,7 @@ function worldeditadditions.move(source_pos1, source_pos2, target_pos1, target_p
-- 5: Save source
---
manip_source:set_param2_data(data_source_param2)
worldedit.manip_helpers.finish(manip_source, data_source)

View File

@ -14,6 +14,12 @@ wea_c.register_alias("mcount", "count")
wea_c.register_alias("mfacing", "mface")
--- Overrides to core WorldEdit commands that have been thoroughly tested
-- These are now enabled by default, but if you find a bug please report and
-- it will be fixed as a matter of priority.
wea_c.register_alias("copy", "copy+", true)
wea_c.register_alias("move", "move+", true)
--- Overrides to core WorldEdit commands
-- These are disabled by default for now, as they could be potentially dangerous to stability
-- Thorough testing is required of our replacement commands before these are enabled by default
@ -21,7 +27,5 @@ local worldmt_settings = Settings(minetest.get_worldpath().."/world.mt")
local should_override = worldmt_settings:get_bool("worldeditadditions_override_commands", false)
if should_override then
minetest.log("info", "[WorldEditAdditions] Enabling override aliases")
wea_c.register_alias("copy", "copy+", true)
wea_c.register_alias("move", "move+", true)
wea_c.register_alias("replace", "replacemix", true)
end

View File

@ -6,21 +6,29 @@
-- Chat commands that operate on selections.
local we_cmdpath = worldeditadditions_commands.modpath .. "/commands/selectors/"
local wea_cmdpath = worldeditadditions_commands.modpath .. "/commands/selectors/"
local weac = worldeditadditions_core
dofile(we_cmdpath.."srel.lua")
dofile(we_cmdpath.."scentre.lua")
dofile(we_cmdpath.."scloud.lua")
dofile(we_cmdpath.."scol.lua")
dofile(we_cmdpath.."scube.lua")
dofile(we_cmdpath.."sfactor.lua")
dofile(we_cmdpath.."smake.lua")
dofile(we_cmdpath.."spop.lua")
dofile(we_cmdpath.."spush.lua")
dofile(we_cmdpath.."srect.lua")
dofile(we_cmdpath.."sshift.lua")
dofile(we_cmdpath.."sstack.lua")
dofile(we_cmdpath.."unmark.lua")
dofile(wea_cmdpath.."srel.lua")
dofile(wea_cmdpath.."scentre.lua")
dofile(wea_cmdpath.."scloud.lua")
dofile(wea_cmdpath.."scol.lua")
dofile(wea_cmdpath.."scube.lua")
dofile(wea_cmdpath.."sfactor.lua")
dofile(wea_cmdpath.."smake.lua")
dofile(wea_cmdpath.."spop.lua")
dofile(wea_cmdpath.."spush.lua")
dofile(wea_cmdpath.."srect.lua")
dofile(wea_cmdpath.."sshift.lua")
dofile(wea_cmdpath.."sstack.lua")
dofile(wea_cmdpath.."unmark.lua")
dofile(wea_cmdpath.."mark.lua")
dofile(wea_cmdpath.."pos1-2.lua")
dofile(wea_cmdpath.."reset.lua")
-- Aliases
worldedit.alias_command("sfac", "sfactor")
weac.register_alias("sfac", "sfactor")
weac.register_alias("1", "pos1", true) -- true = override target
weac.register_alias("2", "pos2", true) -- true = override target

View File

@ -0,0 +1,23 @@
local weac = worldeditadditions_core
local function do_mark(name, params_text)
-- TODO: Decide whether we need to hided the worldeditadditions marker here or not.
-- Show the WorldEditAdditions marker
weac.pos.mark(name)
end
if minetest.registered_chatcommands["/mark"] then
minetest.override_chatcommand("/mark", {
params = "",
description = "Show the markers for the defined region (and any other positions) once more.",
func = do_mark
})
else
minetest.register_chatcommand("/mark", {
params = "",
description = "Show the markers for the defined region (and any other positions) once more.",
privs = { worldedit = true },
func = do_mark
})
end

View File

@ -0,0 +1,63 @@
local weac = worldeditadditions_core
local Vector3 = weac.Vector3
local function do_set(name, i)
local player = minetest.get_player_by_name(name)
weac.pos.set(name, i, Vector3.clone(player:get_pos()))
end
local function do_set1(name, params_text)
do_set(name, 1)
end
local function do_set2(name, params_text)
do_set(name, 2)
end
if minetest.registered_chatcommands["/pos1"] then
minetest.override_chatcommand("/pos1", {
params = "",
description =
"Sets pos1 to the current position of the calling player.",
func = do_set1
})
else
minetest.register_chatcommand("/pos1", {
params = "",
description =
"Sets pos1 to the current position of the calling player.",
privs = { worldedit = true },
func = do_set1
})
end
if minetest.registered_chatcommands["/pos2"] then
minetest.override_chatcommand("/pos2", {
params = "",
description = "Sets pos2 to the current position of the calling player.",
func = do_set2
})
else
minetest.register_chatcommand("/pos2", {
params = "",
description = "Sets pos2 to the current position of the calling player.",
privs = { worldedit = true },
func = do_set2
})
end
minetest.register_chatcommand("//pos", {
params = "<index>",
description = "Sets position <index> to the current position of the calling player.",
privs = { worldedit = true },
func = function(name, params_text)
local i = tonumber(params_text)
if type(i) ~= "number" then
worldedit.player_notify(name, "Error: Invalid index number given.")
return
end
i = math.floor(i)
do_set(name, i)
end
})

View File

@ -0,0 +1,32 @@
local weac = worldeditadditions_core
local worldedit_reset
if minetest.registered_chatcommands["/reset"] then
worldedit_reset = minetest.registered_chatcommands["/reset"].func
end
local function do_reset(name, params_text)
-- Hide the WorldEdit marker, if appropriate
if type(worldedit_reset) == "function" then
worldedit_reset(name, params_text)
end
-- Hide the WorldEditAdditions marker
weac.pos.clear(name)
end
if minetest.registered_chatcommands["/reset"] then
minetest.override_chatcommand("/reset", {
params = "",
description = "Clears all defined points and the currently defined region.",
func = do_reset
})
else
minetest.register_chatcommand("/reset", {
params = "",
description = "Clears all defined points and the currently defined region.",
privs = { worldedit = true },
func = do_reset
})
end

View File

@ -31,6 +31,14 @@ local anchor = nil
-- @event clear
-- @format { player_name: string }
--- It is requested that all position/region marker UI elements be hidden for the given player.
-- @event unmark
-- @format { player_name: string }
--- It is requested that all position/region marker UI elements be shown once more for the given player.
-- @event mark
-- @format { player_name: string }
--- Ensures that a table exists for the given player.
-- @param player_name string The name of the player to check.
local function ensure_player(player_name)
@ -78,16 +86,21 @@ end
--- Sets pos1/pos2 in worldedit for compatibility.
-- @param player_name string The name of the player to set the position for.
-- @param i number The index of the position to set.
-- @returns Vector3? The position to set.
local function compat_worldedit_set(player_name, i, pos)
-- @param pos Vector3 The position to set.
-- @param do_update=true bool Whether to call worldedit.marker_update() or not.
-- @returns nil
local function compat_worldedit_set(player_name, i, pos, do_update)
if do_update == nil then do_update = false end
if not worldedit then return end
if i == 1 and worldedit.pos1 then
worldedit.pos1[player_name] = nil
if worldedit.marker_update then worldedit.marker_update(player_name) end
if do_update and worldedit.marker_update then
worldedit.marker_update(player_name) end
worldedit.pos1[player_name] = pos:clone()
elseif i == 2 and worldedit.pos2 then
worldedit.pos2[player_name] = nil
if worldedit.marker_update then worldedit.marker_update(player_name) end
if do_update and worldedit.marker_update then
worldedit.marker_update(player_name) end
worldedit.pos2[player_name] = pos:clone()
end
end
@ -231,7 +244,10 @@ local function pop(player_name)
local last_pos = table.remove(positions[player_name])
if worldedit then
if pos_count == 2 and worldedit.pos2 then worldedit.pos2[player_name] = nil
elseif pos_count == 1 and worldedit.pos1 then worldedit.pos1[player_name] = nil end
elseif pos_count == 1 and worldedit.pos1 then
worldedit.pos1[player_name] = nil
worldedit.marker_update(player_name)
end
end
anchor:emit("pop", { player_name = player_name, pos = last_pos, i = pos_count })
@ -258,6 +274,14 @@ local function unmark(player_name)
})
end
--- Shows the visual markers for the given player's positions and defined region once more.
-- Often used some time after calling worldeditadditions_core.pos.unmark().
-- @param player_name string The name of the player to operate on.
local function mark(player_name)
anchor:emit("mark", {
player_name = player_name
})
end
anchor = wea_c.EventEmitter.new({
get = get,
@ -274,6 +298,7 @@ anchor = wea_c.EventEmitter.new({
set2 = set2,
set_all = set_all,
unmark = unmark,
mark = mark,
compat_worldedit_get = compat_worldedit_get,
})
anchor.debug = false

View File

@ -43,6 +43,15 @@ local function do_create(event)
position_entities[event.player_name][event.i] = new_entity
end
local function do_delete_all(player_name)
if #position_entities[player_name] > 0 then
for _, entity in pairs(position_entities[player_name]) do
wea_c.entities.pos_marker.delete(entity)
end
end
position_entities[player_name] = nil
end
wea_c.pos:addEventListener("push", function(event)
do_create(event)
end)
@ -72,26 +81,32 @@ end)
wea_c.pos:addEventListener("clear", function(event)
ensure_player(event.player_name)
if #position_entities[event.player_name] > 0 then
for _, entity in pairs(position_entities[event.player_name]) do
wea_c.entities.pos_marker.delete(entity)
end
end
do_delete_all(event.player_name)
-- For compatibility, ensure that we also clear the legacy worldedit region too
if worldedit and worldedit.marker_update then
worldedit.marker_update(event.player_name)
end
position_entities[event.player_name] = nil
end)
wea_c.pos:addEventListener("unmark", function(event)
ensure_player(event.player_name)
if #position_entities[event.player_name] > 0 then
for _, entity in pairs(position_entities[event.player_name]) do
wea_c.entities.pos_marker.delete(entity)
end
end
do_delete_all(event.player_name)
-- Note that this function is NOT WorldEdit compatible, because it is only called through our override of WorldEdit's `//unmark`, and WorldEdit doesn't have an API function to call to unmark and everything is complicated.
end)
wea_c.pos:addEventListener("mark", function(event)
ensure_player(event.player_name)
do_delete_all(event.player_name)
for i, pos in pairs(wea_c.pos.get_all(event.player_name)) do
do_create({
player_name = event.player_name,
i = i,
pos = pos
})
end
end)

View File

@ -70,4 +70,6 @@ weac.pos:addEventListener("set", handle_event)
weac.pos:addEventListener("pop", handle_event)
weac.pos:addEventListener("push", handle_event)
weac.pos:addEventListener("clear", do_delete)
weac.pos:addEventListener("unmark", do_delete)
weac.pos:addEventListener("mark", do_update)