Coding - help with pickaxes

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

Coding - help with pickaxes

by kosmonautik » Thu Mar 29, 2018 07:55

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
Member
 
Posts: 180
Joined: Mon Jan 08, 2018 15:14
Location: Paris
GitHub: pyrollo
In-game: Naj

Re: Coding - help with pickaxes

by Pyrollo » Thu Mar 29, 2018 08:51

In Technic mod, Mk2/Mk3 Drills are able to do that. You could have a look at that code.
 

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

Re: Coding - help with pickaxes

by cx384 » Wed Apr 04, 2018 15:43

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: 28
Joined: Fri Jun 24, 2016 10:40
Location: Czech Republic
In-game: kosmonautik

Re: Coding - help with pickaxes

by kosmonautik » Mon Apr 16, 2018 06:37

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: 492
Joined: Wed Apr 23, 2014 09:38
GitHub: cx384
IRC: cx384

Re: Coding - help with pickaxes

by cx384 » Mon Apr 16, 2018 14:40

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?
 


Return to Modding Discussion



Who is online

Users browsing this forum: No registered users and 3 guests