diff options
Diffstat (limited to 'worldedit_brush/init.lua')
-rw-r--r-- | worldedit_brush/init.lua | 144 |
1 files changed, 144 insertions, 0 deletions
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, +}) |