Skip to content

Commit 7b1deb1

Browse files
committedSep 17, 2017
Add configurable brush item
texture was supposed to be a brush, i suck at this :(
1 parent 4605596 commit 7b1deb1

File tree

5 files changed

+164
-4
lines changed

5 files changed

+164
-4
lines changed
 

‎ChatCommands.md

+11
Original file line numberDiff line numberDiff line change
@@ -463,3 +463,14 @@ Contracts the selection in all directions by `<amount>`. If specified, the selec
463463
or vertically in the y axis `[v]`.
464464

465465
//outset v 5
466+
467+
### `//brush none/<command> [parameters]`
468+
469+
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
470+
WorldEdit position 1 when using that specific brush item.
471+
Passing `none` instead clears the command assigned to the currently held brush item.
472+
Note that this functionality requires the `worldedit_brush` mod enabled.
473+
474+
//brush cube 8 8 8 Cobblestone
475+
//brush spr 12 glass
476+
//brush none

‎worldedit_brush/depends.txt

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
worldedit
2+
worldedit_commands

‎worldedit_brush/init.lua

+144
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
if minetest.raycast == nil then
2+
error(
3+
"================================\n"..
4+
"This mod requires a suitable version of 0.4.16-dev/0.5.0-dev\n"..
5+
"that includes support for minetest.raycast() [since 7th July 2017]\n"..
6+
"================================\n"
7+
)
8+
end
9+
10+
local BRUSH_MAX_DIST = 150
11+
local BRUSH_ALLOWED_COMMANDS = {
12+
-- basically everything that only needs pos1
13+
"cube",
14+
"cylinder",
15+
"dome",
16+
"hollowcube",
17+
"hollowcylinder",
18+
"hollowdome",
19+
"hollowpyramid",
20+
"hollowsphere",
21+
"load",
22+
"pyramid",
23+
"sphere",
24+
"spiral",
25+
26+
"cyl",
27+
"do",
28+
"hcube",
29+
"hcyl",
30+
"hdo",
31+
"hpyr",
32+
"hspr",
33+
"l",
34+
"pyr",
35+
"spr",
36+
"spl",
37+
}
38+
local brush_on_use = function(itemstack, placer)
39+
local meta = itemstack:get_meta()
40+
local name = placer:get_player_name()
41+
42+
local cmd = meta:get_string("command")
43+
if cmd == "" then
44+
worldedit.player_notify(name,
45+
"This brush is not bound, use //brush to bind a command to it.")
46+
return false
47+
end
48+
local cmddef = minetest.registered_chatcommands["/" .. cmd]
49+
if cmddef == nil then return false end -- shouldn't happen as //brush checks this
50+
local has_privs, missing_privs = minetest.check_player_privs(name, cmddef.privs)
51+
if not has_privs then
52+
worldedit.player_notify(name,
53+
"Missing privileges: " .. table.concat(missing_privs, ", "))
54+
return false
55+
end
56+
57+
local raybegin = vector.add(placer:get_pos(), {x=0, y=2, z=0}) -- player head
58+
local rayend = vector.add(raybegin, vector.multiply(placer:get_look_dir(), BRUSH_MAX_DIST))
59+
local ray = minetest.raycast(raybegin, rayend, false, true)
60+
local pointed_thing = ray:next()
61+
if pointed_thing == nil then
62+
worldedit.player_notify(name, "Too far away.")
63+
return false
64+
end
65+
66+
assert(pointed_thing.type == "node")
67+
worldedit.pos1[name] = pointed_thing.under
68+
worldedit.pos2[name] = nil
69+
worldedit.mark_region(name)
70+
-- is this a horrible hack? oh yes.
71+
worldedit._override_safe_regions = true
72+
local player_notify_old = worldedit.player_notify
73+
worldedit.player_notify = function(name, msg)
74+
if string.match(msg, "^%d") then return end -- discard "1234 nodes added."
75+
return player_notify_old(name, msg)
76+
end
77+
78+
minetest.log("action", string.format("%s uses WorldEdit brush (//%s) at %s",
79+
name, cmd, minetest.pos_to_string(pointed_thing.under)))
80+
cmddef.func(name, meta:get_string("params"))
81+
82+
worldedit._override_safe_regions = false
83+
worldedit.player_notify = player_notify_old
84+
return true
85+
end
86+
87+
minetest.register_tool(":worldedit:brush", {
88+
description = "WorldEdit Brush",
89+
inventory_image = "worldedit_brush.png",
90+
stack_max = 1, -- no need to stack these (metadata prevents this anyway)
91+
range = 0,
92+
on_use = function(itemstack, placer, pointed_thing)
93+
brush_on_use(itemstack, placer)
94+
return itemstack -- nothing consumed, nothing changed
95+
end,
96+
})
97+
98+
minetest.register_chatcommand("/brush", {
99+
privs = {worldedit=true},
100+
params = "none/<cmd> [parameters]",
101+
description = "Assign command to WorldEdit brush item",
102+
func = function(name, param)
103+
local found, _, cmd, params = param:find("^([^%s]+)%s+(.+)$")
104+
if not found then
105+
params = ""
106+
found, _, cmd = param:find("^(.+)$")
107+
end
108+
if not found then
109+
worldedit.player_notify(name, "Invalid usage.")
110+
return
111+
end
112+
113+
local itemstack = minetest.get_player_by_name(name):get_wielded_item()
114+
if itemstack == nil or itemstack:get_name() ~= "worldedit:brush" then
115+
worldedit.player_notify(name, "Not holding brush item.")
116+
return
117+
end
118+
119+
cmd = cmd:lower()
120+
local meta = itemstack:get_meta()
121+
if cmd == "none" then
122+
meta:from_table(nil)
123+
worldedit.player_notify(name, "Brush assignment cleared.")
124+
else
125+
local cmddef
126+
if table.indexof(BRUSH_ALLOWED_COMMANDS, cmd) ~= -1 then
127+
cmddef = minetest.registered_chatcommands["/" .. cmd]
128+
else
129+
cmddef = nil
130+
end
131+
if cmddef == nil then
132+
worldedit.player_notify(name, "Invalid command for brush use: //" .. cmd)
133+
return
134+
end
135+
meta:set_string("command", cmd)
136+
meta:set_string("params", params)
137+
local fullcmd = "//" .. cmd .. " " .. params
138+
meta:set_string("description",
139+
minetest.registered_tools["worldedit:brush"].description .. ": " .. fullcmd)
140+
worldedit.player_notify(name, "Brush assigned to command: " .. fullcmd)
141+
end
142+
minetest.get_player_by_name(name):set_wielded_item(itemstack)
143+
end,
144+
})
337 Bytes
Loading

‎worldedit_commands/safe.lua

+7-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
local safe_region_callback = {}
22
local safe_region_param = {}
33

4+
worldedit._override_safe_regions = false -- internal use ONLY!
5+
46
local function check_region(name, param)
57
local pos1, pos2 = worldedit.pos1[name], worldedit.pos2[name] --obtain positions
68
if pos1 == nil or pos2 == nil then
@@ -20,7 +22,7 @@ local function safe_region(callback, nodes_needed)
2022
--check if the operation applies to a safe number of nodes
2123
local count = nodes_needed(name, param)
2224
if count == nil then return end --invalid command
23-
if count < 10000 then
25+
if worldedit._override_safe_regions or count < 10000 then
2426
return callback(name, param)
2527
end
2628

@@ -44,20 +46,21 @@ minetest.register_chatcommand("/y", {
4446
return
4547
end
4648

47-
safe_region_callback[name], safe_region_param[name] = nil, nil --reset pending operation
49+
reset_pending(name)
4850
callback(name, param)
4951
end,
5052
})
5153

5254
minetest.register_chatcommand("/n", {
5355
params = "",
54-
description = "Confirm a pending operation",
56+
description = "Abort a pending operation",
5557
func = function(name)
5658
if not safe_region_callback[name] then
5759
worldedit.player_notify(name, "no operation pending")
5860
return
5961
end
60-
safe_region_callback[name], safe_region_param[name] = nil, nil
62+
63+
reset_pending(name)
6164
end,
6265
})
6366

0 commit comments

Comments
 (0)
Please sign in to comment.