diff options
| -rw-r--r-- | ChatCommands.md | 11 | ||||
| -rw-r--r-- | worldedit_brush/depends.txt | 2 | ||||
| -rw-r--r-- | worldedit_brush/init.lua | 144 | ||||
| -rw-r--r-- | worldedit_brush/textures/worldedit_brush.png | bin | 0 -> 337 bytes | |||
| -rw-r--r-- | worldedit_commands/safe.lua | 11 | 
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.pngBinary files differ new file mode 100644 index 0000000..03785ff --- /dev/null +++ b/worldedit_brush/textures/worldedit_brush.png 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,
  })
 | 
