commit | author | age
|
ee0765
|
1 |
|
be2f30
|
2 |
local S = technic.getter |
S |
3 |
|
0e9caf
|
4 |
local tube_entry = "^pipeworks_tube_connection_metallic.png" |
54004f
|
5 |
local cable_entry = "^technic_cable_connection_overlay.png" |
0e9caf
|
6 |
|
ee0765
|
7 |
minetest.register_craft({ |
S |
8 |
recipe = { |
5e4a87
|
9 |
{"technic:carbon_plate", "pipeworks:filter", "technic:composite_plate"}, |
44cb8d
|
10 |
{"basic_materials:motor", "technic:machine_casing", "technic:diamond_drill_head"}, |
83c649
|
11 |
{"technic:carbon_steel_block", "technic:hv_cable", "technic:carbon_steel_block"}}, |
ee0765
|
12 |
output = "technic:quarry", |
S |
13 |
}) |
|
14 |
|
|
15 |
local quarry_dig_above_nodes = 3 -- How far above the quarry we will dig nodes |
|
16 |
local quarry_max_depth = 100 |
d0efa1
|
17 |
local quarry_demand = 10000 |
428b1b
|
18 |
local quarry_eject_dir = vector.new(0, 1, 0) |
ee0765
|
19 |
|
b74c2d
|
20 |
local function set_quarry_formspec(meta) |
d0efa1
|
21 |
local radius = meta:get_int("size") |
86dd58
|
22 |
local formspec = "size[6,4.3]".. |
E |
23 |
"list[context;cache;0,1;4,3;]".. |
|
24 |
"item_image[4.8,0;1,1;technic:quarry]".. |
|
25 |
"label[0,0.2;"..S("%s Quarry"):format("HV").."]".. |
|
26 |
"field[4.3,3.5;2,1;size;"..S("Radius:")..";"..radius.."]" |
b74c2d
|
27 |
if meta:get_int("enabled") == 0 then |
86dd58
|
28 |
formspec = formspec.."button[4,1;2,1;enable;"..S("Disabled").."]" |
b74c2d
|
29 |
else |
86dd58
|
30 |
formspec = formspec.."button[4,1;2,1;disable;"..S("Enabled").."]" |
b74c2d
|
31 |
end |
d0efa1
|
32 |
local diameter = radius*2 + 1 |
Z |
33 |
local nd = meta:get_int("dug") |
|
34 |
local rel_y = quarry_dig_above_nodes - math.floor(nd / (diameter*diameter)) |
86dd58
|
35 |
formspec = formspec.."label[0,4;"..minetest.formspec_escape( |
d0efa1
|
36 |
nd == 0 and S("Digging not started") or |
Z |
37 |
(rel_y < -quarry_max_depth and S("Digging finished") or |
86dd58
|
38 |
(meta:get_int("purge_on") == 1 and S("Purging cache") or |
d0efa1
|
39 |
S("Digging %d m "..(rel_y > 0 and "above" or "below").." machine") |
86dd58
|
40 |
:format(math.abs(rel_y)))) |
d0efa1
|
41 |
).."]" |
Z |
42 |
formspec = formspec.."button[4,2;2,1;restart;"..S("Restart").."]" |
b74c2d
|
43 |
meta:set_string("formspec", formspec) |
d0efa1
|
44 |
end |
Z |
45 |
|
|
46 |
local function set_quarry_demand(meta) |
|
47 |
local radius = meta:get_int("size") |
|
48 |
local diameter = radius*2 + 1 |
|
49 |
local machine_name = S("%s Quarry"):format("HV") |
0f6bdb
|
50 |
local do_purge = meta:get_int("purge_on") == 1 |
S |
51 |
if meta:get_int("enabled") == 0 or do_purge then |
|
52 |
local infotext = do_purge and |
|
53 |
S("%s purging cache") or S("%s Disabled") |
|
54 |
meta:set_string("infotext", infotext:format(machine_name)) |
d0efa1
|
55 |
meta:set_int("HV_EU_demand", 0) |
Z |
56 |
elseif meta:get_int("dug") == diameter*diameter * (quarry_dig_above_nodes+1+quarry_max_depth) then |
|
57 |
meta:set_string("infotext", S("%s Finished"):format(machine_name)) |
|
58 |
meta:set_int("HV_EU_demand", 0) |
|
59 |
else |
0f6bdb
|
60 |
local infotext = meta:get_int("HV_EU_input") >= quarry_demand |
S |
61 |
and S("%s Active") or S("%s Unpowered") |
|
62 |
meta:set_string("infotext", infotext:format(machine_name)) |
d0efa1
|
63 |
meta:set_int("HV_EU_demand", quarry_demand) |
Z |
64 |
end |
ee0765
|
65 |
end |
S |
66 |
|
|
67 |
local function quarry_receive_fields(pos, formname, fields, sender) |
b81d1d
|
68 |
local player_name = sender:get_player_name() |
L |
69 |
if minetest.is_protected(pos, player_name) then |
|
70 |
minetest.chat_send_player(player_name, "You are not allowed to edit this!") |
|
71 |
minetest.record_protection_violation(pos, player_name) |
|
72 |
return |
|
73 |
end |
ee0765
|
74 |
local meta = minetest.get_meta(pos) |
d0efa1
|
75 |
if fields.size and string.find(fields.size, "^[0-9]+$") then |
Z |
76 |
local size = tonumber(fields.size) |
|
77 |
if size >= 2 and size <= 8 and size ~= meta:get_int("size") then |
|
78 |
meta:set_int("size", size) |
|
79 |
meta:set_int("dug", 0) |
|
80 |
end |
ee0765
|
81 |
end |
b74c2d
|
82 |
if fields.enable then meta:set_int("enabled", 1) end |
Z |
83 |
if fields.disable then meta:set_int("enabled", 0) end |
86dd58
|
84 |
if fields.restart then |
E |
85 |
meta:set_int("dug", 0) |
|
86 |
meta:set_int("purge_on", 1) |
|
87 |
end |
b74c2d
|
88 |
set_quarry_formspec(meta) |
d0efa1
|
89 |
set_quarry_demand(meta) |
ee0765
|
90 |
end |
S |
91 |
|
86dd58
|
92 |
local function quarry_handle_purge(pos) |
E |
93 |
local meta = minetest.get_meta(pos) |
|
94 |
local inv = meta:get_inventory() |
|
95 |
local i = 0 |
|
96 |
for _,stack in ipairs(inv:get_list("cache")) do |
|
97 |
i = i + 1 |
|
98 |
if stack then |
|
99 |
local item = stack:to_table() |
|
100 |
if item then |
428b1b
|
101 |
technic.tube_inject_item(pos, pos, quarry_eject_dir, item) |
86dd58
|
102 |
stack:clear() |
E |
103 |
inv:set_stack("cache", i, stack) |
|
104 |
break |
|
105 |
end |
|
106 |
end |
|
107 |
end |
|
108 |
if inv:is_empty("cache") then |
|
109 |
meta:set_int("purge_on", 0) |
|
110 |
end |
|
111 |
end |
|
112 |
|
d0efa1
|
113 |
local function quarry_run(pos, node) |
ee0765
|
114 |
local meta = minetest.get_meta(pos) |
86dd58
|
115 |
local inv = meta:get_inventory() |
E |
116 |
-- initialize cache for the case we load an older world |
|
117 |
inv:set_size("cache", 12) |
|
118 |
-- toss a coin whether we do an automatic purge. Chance 1:200 |
|
119 |
local purge_rand = math.random() |
|
120 |
if purge_rand <= 0.005 then |
|
121 |
meta:set_int("purge_on", 1) |
|
122 |
end |
|
123 |
|
|
124 |
if meta:get_int("enabled") and meta:get_int("HV_EU_input") >= quarry_demand and meta:get_int("purge_on") == 0 then |
d0efa1
|
125 |
local pdir = minetest.facedir_to_dir(node.param2) |
701240
|
126 |
if pdir.y ~= 0 then |
TR |
127 |
-- faces up or down, not valid, otherwise depth-check would run endless and hang up the server |
|
128 |
return |
|
129 |
end |
|
130 |
|
d0efa1
|
131 |
local qdir = pdir.x == 1 and vector.new(0,0,-1) or |
Z |
132 |
(pdir.z == -1 and vector.new(-1,0,0) or |
|
133 |
(pdir.x == -1 and vector.new(0,0,1) or |
|
134 |
vector.new(1,0,0))) |
|
135 |
local radius = meta:get_int("size") |
|
136 |
local diameter = radius*2 + 1 |
|
137 |
local startpos = vector.add(vector.add(vector.add(pos, |
|
138 |
vector.new(0, quarry_dig_above_nodes, 0)), |
|
139 |
pdir), |
|
140 |
vector.multiply(qdir, -radius)) |
|
141 |
local owner = meta:get_string("owner") |
|
142 |
local nd = meta:get_int("dug") |
c14521
|
143 |
while nd < diameter*diameter * (quarry_dig_above_nodes+1+quarry_max_depth) do |
d0efa1
|
144 |
local ry = math.floor(nd / (diameter*diameter)) |
Z |
145 |
local ndl = nd % (diameter*diameter) |
|
146 |
if ry % 2 == 1 then |
|
147 |
ndl = diameter*diameter - 1 - ndl |
|
148 |
end |
|
149 |
local rq = math.floor(ndl / diameter) |
|
150 |
local rp = ndl % diameter |
|
151 |
if rq % 2 == 1 then rp = diameter - 1 - rp end |
|
152 |
local digpos = vector.add(vector.add(vector.add(startpos, |
|
153 |
vector.new(0, -ry, 0)), |
|
154 |
vector.multiply(pdir, rp)), |
|
155 |
vector.multiply(qdir, rq)) |
|
156 |
local can_dig = true |
|
157 |
if can_dig and minetest.is_protected and minetest.is_protected(digpos, owner) then |
|
158 |
can_dig = false |
|
159 |
end |
|
160 |
local dignode |
|
161 |
if can_dig then |
c38da0
|
162 |
dignode = technic.get_or_load_node(digpos) or minetest.get_node(digpos) |
d0efa1
|
163 |
local dignodedef = minetest.registered_nodes[dignode.name] or {diggable=false} |
c93bfe
|
164 |
-- doors mod among other thing does NOT like a nil digger... |
3d52b6
|
165 |
local fakedigger = pipeworks.create_fake_player({ |
TR |
166 |
name = owner |
|
167 |
}) |
c93bfe
|
168 |
if not dignodedef.diggable or (dignodedef.can_dig and not dignodedef.can_dig(digpos, fakedigger)) then |
d0efa1
|
169 |
can_dig = false |
Z |
170 |
end |
|
171 |
end |
c38da0
|
172 |
|
E |
173 |
if can_dig then |
|
174 |
for ay = startpos.y, digpos.y+1, -1 do |
|
175 |
local checkpos = {x=digpos.x, y=ay, z=digpos.z} |
|
176 |
local checknode = technic.get_or_load_node(checkpos) or minetest.get_node(checkpos) |
|
177 |
if checknode.name ~= "air" then |
|
178 |
can_dig = false |
|
179 |
break |
|
180 |
end |
|
181 |
end |
|
182 |
end |
d0efa1
|
183 |
nd = nd + 1 |
Z |
184 |
if can_dig then |
|
185 |
minetest.remove_node(digpos) |
86dd58
|
186 |
local drops = minetest.get_node_drops(dignode.name, "") |
E |
187 |
for _, dropped_item in ipairs(drops) do |
|
188 |
local left = inv:add_item("cache", dropped_item) |
|
189 |
while not left:is_empty() do |
|
190 |
meta:set_int("purge_on", 1) |
|
191 |
quarry_handle_purge(pos) |
|
192 |
left = inv:add_item("cache", left) |
|
193 |
end |
d0efa1
|
194 |
end |
Z |
195 |
break |
|
196 |
end |
ee0765
|
197 |
end |
86dd58
|
198 |
if nd == diameter*diameter * (quarry_dig_above_nodes+1+quarry_max_depth) then |
E |
199 |
-- if a quarry is finished, we enable purge mode |
|
200 |
meta:set_int("purge_on", 1) |
|
201 |
end |
d0efa1
|
202 |
meta:set_int("dug", nd) |
86dd58
|
203 |
else |
E |
204 |
-- if a quarry is disabled or has no power, we enable purge mode |
|
205 |
meta:set_int("purge_on", 1) |
|
206 |
end |
|
207 |
-- if something triggered a purge, we handle it |
|
208 |
if meta:get_int("purge_on") == 1 then |
|
209 |
quarry_handle_purge(pos) |
ee0765
|
210 |
end |
d0efa1
|
211 |
set_quarry_formspec(meta) |
Z |
212 |
set_quarry_demand(meta) |
86dd58
|
213 |
end |
E |
214 |
|
|
215 |
local function send_move_error(player) |
|
216 |
minetest.chat_send_player(player:get_player_name(), |
|
217 |
S("Manually taking/removing from cache by hand is not possible. ".. |
|
218 |
"If you can't wait, restart or disable the quarry to start automatic purge.")) |
|
219 |
return 0 |
563a4c
|
220 |
end |
N |
221 |
|
ee0765
|
222 |
minetest.register_node("technic:quarry", { |
7c4b70
|
223 |
description = S("%s Quarry"):format("HV"), |
0e9caf
|
224 |
tiles = { |
VE |
225 |
"technic_carbon_steel_block.png"..tube_entry, |
54004f
|
226 |
"technic_carbon_steel_block.png"..cable_entry, |
VE |
227 |
"technic_carbon_steel_block.png"..cable_entry, |
|
228 |
"technic_carbon_steel_block.png"..cable_entry, |
0e9caf
|
229 |
"technic_carbon_steel_block.png^default_tool_mesepick.png", |
54004f
|
230 |
"technic_carbon_steel_block.png"..cable_entry |
0e9caf
|
231 |
}, |
ee0765
|
232 |
paramtype2 = "facedir", |
83c649
|
233 |
groups = {cracky=2, tubedevice=1, technic_machine=1, technic_hv=1}, |
S |
234 |
connect_sides = {"bottom", "front", "left", "right"}, |
ee0765
|
235 |
tube = { |
S |
236 |
connect_sides = {top = 1}, |
428b1b
|
237 |
-- lower priority than other tubes, so that quarries will prefer any |
T |
238 |
-- other tube to another quarry, which could lead to server freezes |
|
239 |
-- in certain quarry placements (2x2 for example would never eject) |
|
240 |
priority = 10, |
|
241 |
can_go = function(pos, node, velocity, stack) |
|
242 |
-- always eject the same, even if items came in another way |
|
243 |
-- this further mitigates loops and generally avoids random sideway movement |
|
244 |
-- that can be expected in certain quarry placements |
|
245 |
return { quarry_eject_dir } |
|
246 |
end |
ee0765
|
247 |
}, |
S |
248 |
on_construct = function(pos) |
|
249 |
local meta = minetest.get_meta(pos) |
7c4b70
|
250 |
meta:set_string("infotext", S("%s Quarry"):format("HV")) |
b74c2d
|
251 |
meta:set_int("size", 4) |
Z |
252 |
set_quarry_formspec(meta) |
d0efa1
|
253 |
set_quarry_demand(meta) |
ee0765
|
254 |
end, |
S |
255 |
after_place_node = function(pos, placer, itemstack) |
|
256 |
local meta = minetest.get_meta(pos) |
|
257 |
meta:set_string("owner", placer:get_player_name()) |
ae235e
|
258 |
pipeworks.scan_for_tube_objects(pos) |
ee0765
|
259 |
end, |
86dd58
|
260 |
can_dig = function(pos,player) |
E |
261 |
local meta = minetest.get_meta(pos); |
|
262 |
local inv = meta:get_inventory() |
|
263 |
return inv:is_empty("cache") |
|
264 |
end, |
ae235e
|
265 |
after_dig_node = pipeworks.scan_for_tube_objects, |
ee0765
|
266 |
on_receive_fields = quarry_receive_fields, |
d0efa1
|
267 |
technic_run = quarry_run, |
86dd58
|
268 |
allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) |
E |
269 |
return send_move_error(player) |
|
270 |
end, |
|
271 |
allow_metadata_inventory_put = function(pos, listname, index, stack, player) |
|
272 |
return send_move_error(player) |
|
273 |
end, |
|
274 |
allow_metadata_inventory_take = function(pos, listname, index, stack, player) |
|
275 |
return send_move_error(player) |
|
276 |
end |
ee0765
|
277 |
}) |
S |
278 |
|
|
279 |
technic.register_machine("HV", "technic:quarry", technic.receiver) |