Cristiano Magro
2020-12-03 905be0e9e35f56ae6f71847019dfd8b3853c3554
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
-- Configuration
 
local xnopick_max_charge      = 30000 -- Maximum charge of the saw
-- Gives 2500 nodes on a single charge
local xnopick_charge_per_node = 12
-- Dig node cost
 
 
local S = technic.getter
 
technic.register_power_tool("technic:xnopick", xnopick_max_charge)
 
local mesecons_materials = minetest.get_modpath("mesecons_materials")
 
-- This function checks if the specified node should be dig
local function check_if_node_picked(pos)
  local node = minetest.get_node(pos)
  local node_name = node.name
 
  if node_name:match("default:.*_with_.*") or
    node_name:match("default:coalblock") or
    node_name:match("default:mese") or
    node_name:match("technic:mineral_.*") or
    node_name:match("xtraores:.*_ore") or
    node_name:match("underch:.*_ore") or
    -- underch:black_eye_ore
    node_name:match("underch:coal_dust") or
    node_name:match("underch:coal_diamond") or
    node_name:match("moreores:mineral_.*") or
    node_name:match(".*coal_dense_ore")
  then
    minetest.log("action", "[Xno Pick Magic] "..node_name.." good node to collect.") --print to log
    return true
  end
 
  return false
end
 
function handle_node_drops(pos, drops, digger)
  -- Add dropped items to object's inventory
  local inv = digger and digger:get_inventory()
  local give_item
  if inv then
    give_item = function(item)
      return inv:add_item("main", item)
    end
  else
    give_item = function(item)
      -- itemstring to ItemStack for left:is_empty()
      return ItemStack(item)
    end
  end
 
  for _, dropped_item in pairs(drops) do
    local left = give_item(dropped_item)
    if not left:is_empty() then
      local p = {
        x = pos.x + math.random()/2-0.25,
        y = pos.y + math.random()/2-0.25,
        z = pos.z + math.random()/2-0.25,
      }
      minetest.add_item(p, left)
      minetest.sound_play("item_drop_pickup", {pos = pos, gain = 1.0, max_hear_distance = 10})
    end
  end
end 
 
 
local function collect_node(user, pos, current_charge)
  if current_charge < xnopick_charge_per_node then
    minetest.sound_play("technic_prospector_miss", {pos = pos, gain = 1.0, max_hear_distance = 10})
    return current_charge
  end
 
  local node_name = minetest.get_node(pos).name
  local droped = minetest.get_node_drops(node_name)
 
  -- add to inventory
--  minetest.handle_node_drops(user:getpos(), droped, user)
  handle_node_drops(user:getpos(), droped, user)
 
  minetest.remove_node(pos)
  local remain_charge = current_charge - xnopick_charge_per_node
 
  return remain_charge
end
 
local function collect_block_node(user, pos, current_charge)
  local radius = 4
  local dropPos = {}
  local remain_charge = current_charge
  for z = -radius, radius do
    dropPos.z = pos.z + z
    for y = -radius, radius do
      dropPos.y = pos.y + y
      for x = -radius, radius do
        dropPos.x = pos.x + x
 
        if check_if_node_picked(dropPos) then
          remain_charge = collect_node(user, dropPos, remain_charge)
        end
      end
    end
  end
 
  return remain_charge
end
 
 
 
minetest.register_tool("technic:xnopick", {
  description = S("Xno Pick Magic"),
  inventory_image = "xno_superpick.png",
 
  stack_max = 1,
 
  wear_represents = "technic_RE_charge",
  on_refill = technic.refill_RE_charge,
 
  on_use = function(itemstack, user, pointed_thing)
    local pos = pointed_thing.under
 
    if pointed_thing.type ~= "node" then
      return itemstack
    end
 
    --check tool charge
    local meta = minetest.deserialize(itemstack:get_metadata())
    if not meta or not meta.charge or
      meta.charge < xnopick_charge_per_node
    then
      minetest.sound_play("technic_prospector_miss", {pos = pos, gain = 1.0, max_hear_distance = 10})
 
      return
    end
 
    --check node protection
    if minetest.is_protected(pos, user:get_player_name()) then
      minetest.record_protection_violation(pos, user:get_player_name())
      return
    end
 
    --reinizializze visited struct
    nodeVisited = Pointset.create()
 
    --can collect only digging node
    if not check_if_node_picked(pos) then
      return itemstack
    end
 
 
    -- Send current charge to digging function so that the
    -- chainsaw will stop after digging a number of nodes
    meta.charge = collect_block_node(user, pos, meta.charge)
    minetest.sound_play("technic_laser_mk3", {pos = pos, gain = 1.0, max_hear_distance = 10})
    
    if not technic.creative_mode then
      technic.set_RE_wear(itemstack, meta.charge, xnopick_max_charge)
      itemstack:set_metadata(minetest.serialize(meta))
    end
    return itemstack
 
  end,
})
 
minetest.register_craft({
  output = "technic:xnopick",
  recipe = {
    {"group:wood",       "group:wood",    "group:wood",},
    {"technic:battery",  "default:stick", "pipeworks:tube_1"},
    {"technic:battery",  "default:stick", "pipeworks:tube_1"},
  },
})