commit | author | age
|
ee0765
|
1 |
|
S |
2 |
minetest.register_craft({ |
|
3 |
recipe = { |
|
4 |
{"default:steelblock", "pipeworks:filter", "default:steelblock"}, |
|
5 |
{"default:steelblock", "technic:motor", "default:steelblock"}, |
|
6 |
{"default:steelblock", "technic:diamond_drill_head", "default:steelblock"}}, |
|
7 |
output = "technic:quarry", |
|
8 |
}) |
|
9 |
|
|
10 |
local quarry_dig_above_nodes = 3 -- How far above the quarry we will dig nodes |
|
11 |
local quarry_max_depth = 100 |
|
12 |
|
|
13 |
local function get_quarry_formspec(size) |
|
14 |
return "size[3,1.5]".. |
|
15 |
"field[1,0.5;2,1;size;Radius;"..size.."]".. |
|
16 |
"button[0,1;3,1;toggle;Enable/Disable]" |
|
17 |
end |
|
18 |
|
|
19 |
local function quarry_receive_fields(pos, formname, fields, sender) |
|
20 |
local meta = minetest.get_meta(pos) |
|
21 |
local size = tonumber(fields.size) |
|
22 |
|
|
23 |
if fields.toggle then |
|
24 |
if meta:get_int("enabled") == 0 then |
|
25 |
meta:set_int("enabled", 1) |
|
26 |
else |
|
27 |
meta:set_int("enabled", 0) |
|
28 |
end |
|
29 |
end |
|
30 |
|
|
31 |
-- Smallest size is 2. Anything less is asking for trouble. |
|
32 |
-- Largest is 8. It is a matter of pratical node handling. |
|
33 |
size = math.max(size, 2) |
|
34 |
size = math.min(size, 8) |
|
35 |
|
|
36 |
if meta:get_int("size") ~= size then |
|
37 |
meta:set_int("size", size) |
|
38 |
meta:set_string("formspec", get_quarry_formspec(size)) |
|
39 |
end |
|
40 |
end |
|
41 |
|
|
42 |
local function get_quarry_center(pos, size) |
|
43 |
local node = minetest.get_node(pos) |
|
44 |
local back_dir = minetest.facedir_to_dir(node.param2) |
|
45 |
local relative_center = vector.multiply(back_dir, size + 1) |
|
46 |
local center = vector.add(pos, relative_center) |
|
47 |
return center |
|
48 |
end |
|
49 |
|
|
50 |
local function gen_next_digpos(center, digpos, size) |
|
51 |
digpos.x = digpos.x + 1 |
|
52 |
if digpos.x > center.x + size then |
|
53 |
digpos.x = center.x - size |
|
54 |
digpos.z = digpos.z + 1 |
|
55 |
end |
|
56 |
if digpos.z > center.z + size then |
|
57 |
digpos.x = center.x - size |
|
58 |
digpos.z = center.z - size |
|
59 |
digpos.y = digpos.y - 1 |
|
60 |
end |
|
61 |
end |
|
62 |
|
|
63 |
local function find_next_digpos(data, area, center, dig_y, size) |
|
64 |
local c_air = minetest.get_content_id("air") |
|
65 |
|
|
66 |
for y = center.y + quarry_dig_above_nodes, dig_y - 1, -1 do |
|
67 |
for z = center.z - size, center.z + size do |
|
68 |
for x = center.x - size, center.x + size do |
|
69 |
if data[area:index(x, y, z)] ~= c_air then |
|
70 |
return vector.new(x, y, z) |
|
71 |
end |
|
72 |
end |
|
73 |
end |
|
74 |
end |
|
75 |
end |
|
76 |
|
|
77 |
local function quarry_dig(pos, center, size) |
|
78 |
local meta = minetest.get_meta(pos) |
|
79 |
local drops = {} |
|
80 |
local dig_y = meta:get_int("dig_y") |
|
81 |
local owner = meta:get_int("owner") |
|
82 |
|
|
83 |
local vm = VoxelManip() |
|
84 |
local p1 = vector.new( |
|
85 |
center.x - size, |
|
86 |
center.y + quarry_dig_above_nodes, |
|
87 |
center.z - size) |
|
88 |
local p2 = vector.new( |
|
89 |
center.x + size, |
|
90 |
dig_y - 1, -- One node lower in case we have finished the current layer |
|
91 |
center.z + size) |
|
92 |
local e1, e2 = vm:read_from_map(p1, p2) |
|
93 |
local area = VoxelArea:new({MinEdge=e1, MaxEdge=e2}) |
|
94 |
local data = vm:get_data() |
|
95 |
|
|
96 |
local digpos = find_next_digpos(data, area, center, dig_y, size) |
|
97 |
|
|
98 |
if digpos then |
|
99 |
if digpos.y < pos.y - quarry_max_depth then |
|
100 |
meta:set_int("dig_y", digpos.y) |
|
101 |
return drops |
|
102 |
end |
|
103 |
if minetest.is_protected and minetest.is_protected(digpos, owner) then |
|
104 |
meta:set_int("enabled", 0) |
|
105 |
return |
|
106 |
end |
|
107 |
dig_y = digpos.y |
|
108 |
local node = minetest.get_node(digpos) |
|
109 |
drops = minetest.get_node_drops(node.name, "") |
|
110 |
minetest.dig_node(digpos) |
|
111 |
if minetest.get_node(digpos).name == node.name then |
|
112 |
-- We tried to dig something undigable like a |
|
113 |
-- filled chest. Notice that we check for a node |
|
114 |
-- change, not for air. This is so that we get drops |
|
115 |
-- from things like concrete posts with platforms, |
|
116 |
-- which turn into regular concrete posts when dug. |
|
117 |
drops = {} |
|
118 |
end |
|
119 |
elseif not (dig_y < pos.y - quarry_max_depth) then |
|
120 |
dig_y = dig_y - 16 |
|
121 |
end |
|
122 |
|
|
123 |
meta:set_int("dig_y", dig_y) |
|
124 |
return drops |
|
125 |
end |
|
126 |
|
|
127 |
local function send_items(items, pos, node) |
|
128 |
for _, item in pairs(items) do |
|
129 |
local tube_item = tube_item(vector.new(pos), item) |
|
130 |
tube_item:get_luaentity().start_pos = vector.new(pos) |
|
131 |
tube_item:setvelocity(vector.new(0, 1, 0)) |
|
132 |
tube_item:setacceleration({x=0, y=0, z=0}) |
|
133 |
end |
|
134 |
end |
|
135 |
|
|
136 |
minetest.register_node("technic:quarry", { |
|
137 |
description = "Quarry", |
|
138 |
tiles = {"default_steel_block.png", "default_steel_block.png", |
|
139 |
"default_steel_block.png", "default_steel_block.png", |
|
140 |
"default_steel_block.png^default_tool_mesepick.png", "default_steel_block.png"}, |
|
141 |
paramtype2 = "facedir", |
|
142 |
groups = {cracky=2, tubedevice=1}, |
|
143 |
tube = { |
|
144 |
connect_sides = {top = 1}, |
|
145 |
}, |
|
146 |
on_construct = function(pos) |
|
147 |
local size = 4 |
|
148 |
local meta = minetest.get_meta(pos) |
|
149 |
meta:set_string("infotext", "Quarry") |
|
150 |
meta:set_string("formspec", get_quarry_formspec(4)) |
|
151 |
meta:set_int("size", size) |
|
152 |
meta:set_int("dig_y", pos.y) |
|
153 |
end, |
|
154 |
after_place_node = function(pos, placer, itemstack) |
|
155 |
local meta = minetest.get_meta(pos) |
|
156 |
meta:set_string("owner", placer:get_player_name()) |
|
157 |
tube_scanforobjects(pos) |
|
158 |
end, |
|
159 |
after_dig_node = tube_scanforobjects, |
|
160 |
on_receive_fields = quarry_receive_fields, |
|
161 |
}) |
|
162 |
|
|
163 |
minetest.register_abm({ |
|
164 |
nodenames = {"technic:quarry"}, |
|
165 |
interval = 1, |
|
166 |
chance = 1, |
|
167 |
action = function(pos, node, active_object_count, active_object_count_wider) |
|
168 |
local meta = minetest.get_meta(pos) |
|
169 |
local size = meta:get_int("size") |
|
170 |
local eu_input = meta:get_int("HV_EU_input") |
|
171 |
local demand = 10000 |
|
172 |
local center = get_quarry_center(pos, size) |
|
173 |
local dig_y = meta:get_int("dig_y") |
|
174 |
|
|
175 |
technic.switching_station_timeout_count(pos, "HV") |
|
176 |
|
|
177 |
if meta:get_int("enabled") == 0 then |
|
178 |
meta:set_string("infotext", "Quarry Disabled") |
|
179 |
meta:set_int("HV_EU_demand", 0) |
|
180 |
return |
|
181 |
end |
|
182 |
|
|
183 |
if eu_input < demand then |
|
184 |
meta:set_string("infotext", "Quarry Unpowered") |
|
185 |
elseif eu_input >= demand then |
|
186 |
meta:set_string("infotext", "Quarry Active") |
|
187 |
|
|
188 |
local items = quarry_dig(pos, center, size) |
|
189 |
send_items(items, pos, node) |
|
190 |
|
|
191 |
if dig_y < pos.y - quarry_max_depth then |
|
192 |
meta:set_string("infotext", "Quarry Finished") |
|
193 |
end |
|
194 |
end |
|
195 |
meta:set_int("HV_EU_demand", demand) |
|
196 |
end |
|
197 |
}) |
|
198 |
|
|
199 |
technic.register_machine("HV", "technic:quarry", technic.receiver) |
|
200 |
|