Coding - help with pickaxes

Post Reply
kosmonautik
Member
Posts: 30
Joined: Fri Jun 24, 2016 10:40
In-game: kosmonautik
Location: Czech Republic
Contact:

Coding - help with pickaxes

by kosmonautik » Post

Hello everyone.

In past I got an idea which doesn't let me sleep. I would like to make a mod containing a special pickaxe. It's function would be when you dig a node it will also dig nodes around (like the player is going to break the yellow cube and when he does so the red cubes will dissapear and drop resources:
Image

Do you know how to do it?

Thanks

User avatar
Pyrollo
Developer
Posts: 385
Joined: Mon Jan 08, 2018 15:14
GitHub: pyrollo
In-game: Naj
Location: Paris

Re: Coding - help with pickaxes

by Pyrollo » Post

In Technic mod, Mk2/Mk3 Drills are able to do that. You could have a look at that code.
[ Display Modpack ] - [ Digiterms ] - [ Crater MG ] - [ LATE ]

User avatar
cx384
Member
Posts: 654
Joined: Wed Apr 23, 2014 09:38
GitHub: cx384
IRC: cx384

Re: Coding - help with pickaxes

by cx384 » Post

How I would do this:

Code: Select all

local dig_range_increase = {}
dig_range_increase["test_3x3:pick_3x3"] = 1

local dig_hand_digable = true

minetest.register_tool("test_3x3:pick_3x3", {
	description = "3x3 Pick",
	inventory_image = "gui_furnace_arrow_fg.png^default_tool_diamondpick.png",
	tool_capabilities = {
		full_punch_interval = 0.9,
		max_drop_level=3,
		groupcaps={
			cracky = {times={[1]=2.0, [2]=1.0, [3]=0.50}, uses=30, maxlevel=3},
		},
		damage_groups = {fleshy=5},
	},
	sound = {breaks = "default_tool_breaks"},
	-- on_use =  function(itemstack, user, pointed_thing)
	-- cant use because it overwrites digging
	-- after_use = function(itemstack, user, node, digparams)
	-- cant use because no pos ._.
})

minetest.register_on_dignode(function(pos, oldnode, digger)
	-- check if player
	if not digger then
		return
	end
	
	-- disabled on sneak
	if digger:get_player_control().sneak then
		return
	end
	
	-- check if proper tool
	local wielded = digger:get_wielded_item()
	local wielded_name = wielded:get_name()
	local dri = dig_range_increase[wielded_name]
	if not dri then
		return
	end
	
	-- check if already dig range increased
	if digger:get_attribute("already_dried") == "true" then
		return
	else
		-- prevent multiple dris
		digger:set_attribute("already_dried", "true")
	end
	
	-- get direction
	local l = digger:get_look_dir()
	local d = "x"
	if math.abs(l.x) < math.abs(l.y) then
		d = "y"
	else
		d = "x"
	end
	if math.abs(l[d]) < math.abs(l.z) then
		d = "z"
	end
	
	-- get node poses
	local node_poses = {}
	local yddri = dri
	local yudri = dri
	if yddri > 1 then -- adjust high for higher ranges
		yddri = 1
		yudri = dri*2-1
	end
	for x= -dri, dri do
		if x == 0 or d ~= "x" then
			for y = -yddri, yudri do
				if y == 0 or d ~= "y" then
					for z = -dri, dri do
						if z == 0 or d ~= "z" then
							local dig_pos = {x = pos.x+x, y = pos.y+y, z = pos.z+z}
							table.insert(node_poses, dig_pos)
						end
					end
				end
			end
		end
	end
	
	-- get tool_capabilities
	local tool_capabilities = wielded:get_tool_capabilities().groupcaps
	if dig_hand_digable then
		for i, e in pairs(ItemStack(":"):get_tool_capabilities().groupcaps) do
			if not tool_capabilities[i] then
				tool_capabilities[i] = e
			end
		end
	end
	
	-- dig nodes
	for _, dig_pos in pairs(node_poses) do
		local node = minetest.get_node(dig_pos)
		for i, e in pairs(tool_capabilities) do -- check if tool_capabilities fit
			if e.times[minetest.get_item_group(node.name, i)] and
					minetest.get_item_group(node.name, "level") <= e.maxlevel then
				minetest.node_dig(dig_pos, node, digger) -- dig
				break
			end
		end
	end
	
	digger:set_attribute("already_dried", "false")
end)

-- to be save
minetest.register_on_joinplayer(function(player)
	player:set_attribute("already_dried", "false")
end)
In former times I wanted to use this for one of my mods and maybe I will, but feel free to use this. It should work fine.
Can your read this?

kosmonautik
Member
Posts: 30
Joined: Fri Jun 24, 2016 10:40
In-game: kosmonautik
Location: Czech Republic
Contact:

Re: Coding - help with pickaxes

by kosmonautik » Post

cx384 wrote:How I would do this:

Code: Select all

local dig_range_increase = {}
dig_range_increase["test_3x3:pick_3x3"] = 1

local dig_hand_digable = true

minetest.register_tool("test_3x3:pick_3x3", {
	description = "3x3 Pick",
	inventory_image = "gui_furnace_arrow_fg.png^default_tool_diamondpick.png",
	tool_capabilities = {
		full_punch_interval = 0.9,
		max_drop_level=3,
		groupcaps={
			cracky = {times={[1]=2.0, [2]=1.0, [3]=0.50}, uses=30, maxlevel=3},
		},
		damage_groups = {fleshy=5},
	},
	sound = {breaks = "default_tool_breaks"},
	-- on_use =  function(itemstack, user, pointed_thing)
	-- cant use because it overwrites digging
	-- after_use = function(itemstack, user, node, digparams)
	-- cant use because no pos ._.
})

minetest.register_on_dignode(function(pos, oldnode, digger)
	-- check if player
	if not digger then
		return
	end
	
	-- disabled on sneak
	if digger:get_player_control().sneak then
		return
	end
	
	-- check if proper tool
	local wielded = digger:get_wielded_item()
	local wielded_name = wielded:get_name()
	local dri = dig_range_increase[wielded_name]
	if not dri then
		return
	end
	
	-- check if already dig range increased
	if digger:get_attribute("already_dried") == "true" then
		return
	else
		-- prevent multiple dris
		digger:set_attribute("already_dried", "true")
	end
	
	-- get direction
	local l = digger:get_look_dir()
	local d = "x"
	if math.abs(l.x) < math.abs(l.y) then
		d = "y"
	else
		d = "x"
	end
	if math.abs(l[d]) < math.abs(l.z) then
		d = "z"
	end
	
	-- get node poses
	local node_poses = {}
	local yddri = dri
	local yudri = dri
	if yddri > 1 then -- adjust high for higher ranges
		yddri = 1
		yudri = dri*2-1
	end
	for x= -dri, dri do
		if x == 0 or d ~= "x" then
			for y = -yddri, yudri do
				if y == 0 or d ~= "y" then
					for z = -dri, dri do
						if z == 0 or d ~= "z" then
							local dig_pos = {x = pos.x+x, y = pos.y+y, z = pos.z+z}
							table.insert(node_poses, dig_pos)
						end
					end
				end
			end
		end
	end
	
	-- get tool_capabilities
	local tool_capabilities = wielded:get_tool_capabilities().groupcaps
	if dig_hand_digable then
		for i, e in pairs(ItemStack(":"):get_tool_capabilities().groupcaps) do
			if not tool_capabilities[i] then
				tool_capabilities[i] = e
			end
		end
	end
	
	-- dig nodes
	for _, dig_pos in pairs(node_poses) do
		local node = minetest.get_node(dig_pos)
		for i, e in pairs(tool_capabilities) do -- check if tool_capabilities fit
			if e.times[minetest.get_item_group(node.name, i)] and
					minetest.get_item_group(node.name, "level") <= e.maxlevel then
				minetest.node_dig(dig_pos, node, digger) -- dig
				break
			end
		end
	end
	
	digger:set_attribute("already_dried", "false")
end)

-- to be save
minetest.register_on_joinplayer(function(player)
	player:set_attribute("already_dried", "false")
end)
In former times I wanted to use this for one of my mods and maybe I will, but feel free to use this. It should work fine.
Thank you very much.

User avatar
cx384
Member
Posts: 654
Joined: Wed Apr 23, 2014 09:38
GitHub: cx384
IRC: cx384

Re: Coding - help with pickaxes

by cx384 » Post

kosmonautik wrote:
cx384 wrote:How I would do this:

Code: Select all

local dig_range_increase = {}
dig_range_increase["test_3x3:pick_3x3"] = 1

local dig_hand_digable = true

minetest.register_tool("test_3x3:pick_3x3", {
	description = "3x3 Pick",
	inventory_image = "gui_furnace_arrow_fg.png^default_tool_diamondpick.png",
	tool_capabilities = {
		full_punch_interval = 0.9,
		max_drop_level=3,
		groupcaps={
			cracky = {times={[1]=2.0, [2]=1.0, [3]=0.50}, uses=30, maxlevel=3},
		},
		damage_groups = {fleshy=5},
	},
	sound = {breaks = "default_tool_breaks"},
	-- on_use =  function(itemstack, user, pointed_thing)
	-- cant use because it overwrites digging
	-- after_use = function(itemstack, user, node, digparams)
	-- cant use because no pos ._.
})

minetest.register_on_dignode(function(pos, oldnode, digger)
	-- check if player
	if not digger then
		return
	end
	
	-- disabled on sneak
	if digger:get_player_control().sneak then
		return
	end
	
	-- check if proper tool
	local wielded = digger:get_wielded_item()
	local wielded_name = wielded:get_name()
	local dri = dig_range_increase[wielded_name]
	if not dri then
		return
	end
	
	-- check if already dig range increased
	if digger:get_attribute("already_dried") == "true" then
		return
	else
		-- prevent multiple dris
		digger:set_attribute("already_dried", "true")
	end
	
	-- get direction
	local l = digger:get_look_dir()
	local d = "x"
	if math.abs(l.x) < math.abs(l.y) then
		d = "y"
	else
		d = "x"
	end
	if math.abs(l[d]) < math.abs(l.z) then
		d = "z"
	end
	
	-- get node poses
	local node_poses = {}
	local yddri = dri
	local yudri = dri
	if yddri > 1 then -- adjust high for higher ranges
		yddri = 1
		yudri = dri*2-1
	end
	for x= -dri, dri do
		if x == 0 or d ~= "x" then
			for y = -yddri, yudri do
				if y == 0 or d ~= "y" then
					for z = -dri, dri do
						if z == 0 or d ~= "z" then
							local dig_pos = {x = pos.x+x, y = pos.y+y, z = pos.z+z}
							table.insert(node_poses, dig_pos)
						end
					end
				end
			end
		end
	end
	
	-- get tool_capabilities
	local tool_capabilities = wielded:get_tool_capabilities().groupcaps
	if dig_hand_digable then
		for i, e in pairs(ItemStack(":"):get_tool_capabilities().groupcaps) do
			if not tool_capabilities[i] then
				tool_capabilities[i] = e
			end
		end
	end
	
	-- dig nodes
	for _, dig_pos in pairs(node_poses) do
		local node = minetest.get_node(dig_pos)
		for i, e in pairs(tool_capabilities) do -- check if tool_capabilities fit
			if e.times[minetest.get_item_group(node.name, i)] and
					minetest.get_item_group(node.name, "level") <= e.maxlevel then
				minetest.node_dig(dig_pos, node, digger) -- dig
				break
			end
		end
	end
	
	digger:set_attribute("already_dried", "false")
end)

-- to be save
minetest.register_on_joinplayer(function(player)
	player:set_attribute("already_dried", "false")
end)
In former times I wanted to use this for one of my mods and maybe I will, but feel free to use this. It should work fine.
Thank you very much.
You are welcome. :-)
Can your read this?

Post Reply

Who is online

Users browsing this forum: No registered users and 7 guests