summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChatCommands.md11
-rw-r--r--worldedit_brush/depends.txt2
-rw-r--r--worldedit_brush/init.lua144
-rw-r--r--worldedit_brush/textures/worldedit_brush.pngbin0 -> 337 bytes
-rw-r--r--worldedit_commands/safe.lua11
5 files changed, 164 insertions, 4 deletions
diff --git a/ChatCommands.md b/ChatCommands.md
index 03db302..47a100f 100644
--- a/ChatCommands.md
+++ b/ChatCommands.md
@@ -463,3 +463,14 @@ Contracts the selection in all directions by `<amount>`. If specified, the selec
or vertically in the y axis `[v]`.
//outset v 5
+
+### `//brush none/<command> [parameters]`
+
+Assigns the given `<command>` to the currently held brush item, it will be ran with the first pointed solid node (as determined via raycast) as
+WorldEdit position 1 when using that specific brush item.
+Passing `none` instead clears the command assigned to the currently held brush item.
+Note that this functionality requires the `worldedit_brush` mod enabled.
+
+ //brush cube 8 8 8 Cobblestone
+ //brush spr 12 glass
+ //brush none
diff --git a/worldedit_brush/depends.txt b/worldedit_brush/depends.txt
new file mode 100644
index 0000000..f886436
--- /dev/null
+++ b/worldedit_brush/depends.txt
@@ -0,0 +1,2 @@
+worldedit
+worldedit_commands
diff --git a/worldedit_brush/init.lua b/worldedit_brush/init.lua
new file mode 100644
index 0000000..b73a402
--- /dev/null
+++ b/worldedit_brush/init.lua
@@ -0,0 +1,144 @@
+if minetest.raycast == nil then
+ error(
+ "================================\n"..
+ "This mod requires a suitable version of 0.4.16-dev/0.5.0-dev\n"..
+ "that includes support for minetest.raycast() [since 7th July 2017]\n"..
+ "================================\n"
+ )
+end
+
+local BRUSH_MAX_DIST = 150
+local BRUSH_ALLOWED_COMMANDS = {
+ -- basically everything that only needs pos1
+ "cube",
+ "cylinder",
+ "dome",
+ "hollowcube",
+ "hollowcylinder",
+ "hollowdome",
+ "hollowpyramid",
+ "hollowsphere",
+ "load",
+ "pyramid",
+ "sphere",
+ "spiral",
+
+ "cyl",
+ "do",
+ "hcube",
+ "hcyl",
+ "hdo",
+ "hpyr",
+ "hspr",
+ "l",
+ "pyr",
+ "spr",
+ "spl",
+}
+local brush_on_use = function(itemstack, placer)
+ local meta = itemstack:get_meta()
+ local name = placer:get_player_name()
+
+ local cmd = meta:get_string("command")
+ if cmd == "" then
+ worldedit.player_notify(name,
+ "This brush is not bound, use //brush to bind a command to it.")
+ return false
+ end
+ local cmddef = minetest.registered_chatcommands["/" .. cmd]
+ if cmddef == nil then return false end -- shouldn't happen as //brush checks this
+ local has_privs, missing_privs = minetest.check_player_privs(name, cmddef.privs)
+ if not has_privs then
+ worldedit.player_notify(name,
+ "Missing privileges: " .. table.concat(missing_privs, ", "))
+ return false
+ end
+
+ local raybegin = vector.add(placer:get_pos(), {x=0, y=2, z=0}) -- player head
+ local rayend = vector.add(raybegin, vector.multiply(placer:get_look_dir(), BRUSH_MAX_DIST))
+ local ray = minetest.raycast(raybegin, rayend, false, true)
+ local pointed_thing = ray:next()
+ if pointed_thing == nil then
+ worldedit.player_notify(name, "Too far away.")
+ return false
+ end
+
+ assert(pointed_thing.type == "node")
+ worldedit.pos1[name] = pointed_thing.under
+ worldedit.pos2[name] = nil
+ worldedit.mark_region(name)
+ -- is this a horrible hack? oh yes.
+ worldedit._override_safe_regions = true
+ local player_notify_old = worldedit.player_notify
+ worldedit.player_notify = function(name, msg)
+ if string.match(msg, "^%d") then return end -- discard "1234 nodes added."
+ return player_notify_old(name, msg)
+ end
+
+ minetest.log("action", string.format("%s uses WorldEdit brush (//%s) at %s",
+ name, cmd, minetest.pos_to_string(pointed_thing.under)))
+ cmddef.func(name, meta:get_string("params"))
+
+ worldedit._override_safe_regions = false
+ worldedit.player_notify = player_notify_old
+ return true
+end
+
+minetest.register_tool(":worldedit:brush", {
+ description = "WorldEdit Brush",
+ inventory_image = "worldedit_brush.png",
+ stack_max = 1, -- no need to stack these (metadata prevents this anyway)
+ range = 0,
+ on_use = function(itemstack, placer, pointed_thing)
+ brush_on_use(itemstack, placer)
+ return itemstack -- nothing consumed, nothing changed
+ end,
+})
+
+minetest.register_chatcommand("/brush", {
+ privs = {worldedit=true},
+ params = "none/<cmd> [parameters]",
+ description = "Assign command to WorldEdit brush item",
+ func = function(name, param)
+ local found, _, cmd, params = param:find("^([^%s]+)%s+(.+)$")
+ if not found then
+ params = ""
+ found, _, cmd = param:find("^(.+)$")
+ end
+ if not found then
+ worldedit.player_notify(name, "Invalid usage.")
+ return
+ end
+
+ local itemstack = minetest.get_player_by_name(name):get_wielded_item()
+ if itemstack == nil or itemstack:get_name() ~= "worldedit:brush" then
+ worldedit.player_notify(name, "Not holding brush item.")
+ return
+ end
+
+ cmd = cmd:lower()
+ local meta = itemstack:get_meta()
+ if cmd == "none" then
+ meta:from_table(nil)
+ worldedit.player_notify(name, "Brush assignment cleared.")
+ else
+ local cmddef
+ if table.indexof(BRUSH_ALLOWED_COMMANDS, cmd) ~= -1 then
+ cmddef = minetest.registered_chatcommands["/" .. cmd]
+ else
+ cmddef = nil
+ end
+ if cmddef == nil then
+ worldedit.player_notify(name, "Invalid command for brush use: //" .. cmd)
+ return
+ end
+ meta:set_string("command", cmd)
+ meta:set_string("params", params)
+ local fullcmd = "//" .. cmd .. " " .. params
+ meta:set_string("description",
+ minetest.registered_tools["worldedit:brush"].description .. ": " .. fullcmd)
+ worldedit.player_notify(name, "Brush assigned to command: " .. fullcmd)
+ end
+ minetest.get_player_by_name(name):set_wielded_item(itemstack)
+ end,
+})
diff --git a/worldedit_brush/textures/worldedit_brush.png b/worldedit_brush/textures/worldedit_brush.png
new file mode 100644
index 0000000..03785ff
--- /dev/null
+++ b/worldedit_brush/textures/worldedit_brush.png
Binary files differ
diff --git a/worldedit_commands/safe.lua b/worldedit_commands/safe.lua
index a93e393..0bd30d7 100644
--- a/worldedit_commands/safe.lua
+++ b/worldedit_commands/safe.lua
@@ -1,6 +1,8 @@
local safe_region_callback = {}
local safe_region_param = {}
+worldedit._override_safe_regions = false -- internal use ONLY!
+
local function check_region(name, param)
local pos1, pos2 = worldedit.pos1[name], worldedit.pos2[name] --obtain positions
if pos1 == nil or pos2 == nil then
@@ -20,7 +22,7 @@ local function safe_region(callback, nodes_needed)
--check if the operation applies to a safe number of nodes
local count = nodes_needed(name, param)
if count == nil then return end --invalid command
- if count < 10000 then
+ if worldedit._override_safe_regions or count < 10000 then
return callback(name, param)
end
@@ -44,20 +46,21 @@ minetest.register_chatcommand("/y", {
return
end
- safe_region_callback[name], safe_region_param[name] = nil, nil --reset pending operation
+ reset_pending(name)
callback(name, param)
end,
})
minetest.register_chatcommand("/n", {
params = "",
- description = "Confirm a pending operation",
+ description = "Abort a pending operation",
func = function(name)
if not safe_region_callback[name] then
worldedit.player_notify(name, "no operation pending")
return
end
- safe_region_callback[name], safe_region_param[name] = nil, nil
+
+ reset_pending(name)
end,
})