Skip to content

Commit

Permalink
Add configurable brush item
Browse files Browse the repository at this point in the history
texture was supposed to be a brush, i suck at this :(
  • Loading branch information
sfan5 committed Sep 17, 2017
1 parent 4605596 commit 7b1deb1
Show file tree
Hide file tree
Showing 5 changed files with 164 additions and 4 deletions.
11 changes: 11 additions & 0 deletions ChatCommands.md
Expand Up @@ -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
2 changes: 2 additions & 0 deletions worldedit_brush/depends.txt
@@ -0,0 +1,2 @@
worldedit
worldedit_commands
144 changes: 144 additions & 0 deletions 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,
})
Binary file added worldedit_brush/textures/worldedit_brush.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 7 additions & 4 deletions 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
Expand All @@ -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

Expand All @@ -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,
})

Expand Down

0 comments on commit 7b1deb1

Please sign in to comment.