mirror of
https://github.com/minetest-mods/technic.git
synced 2024-12-26 02:40:29 +01:00
In quarry, skip past undiggable nodes
The quarry used to get stuck when it encountered an undiggable node. Change it to skip past that node, digging whatever later stuff it can. Necessarily, the current digging position becomes semantically-significant state: it is no longer sufficient to search the quarry cuboid from the top on each iteration. The current digging height is reported in the quarry's interaction form, and can be reset to the top using a button on the form. Where there is a non-air node within the quarry directly above the next node to dig, it blocks the quarry's access to that node, even if everything involved is diggable. Thus an undiggable node casts a shadow of undug nodes below it. Resolving undiggability of a node is a major reason to use the restart button.
This commit is contained in:
parent
390ade6e54
commit
d0efa15b98
@ -115,6 +115,10 @@ Slim Elements half / normal height: = Schmale Elemente von halber / normaler Hoe
|
|||||||
Current track %s = Aktueller Titel %s
|
Current track %s = Aktueller Titel %s
|
||||||
Stopped =
|
Stopped =
|
||||||
Keeping %d/%d map blocks loaded =
|
Keeping %d/%d map blocks loaded =
|
||||||
|
Digging not started =
|
||||||
|
Digging finished =
|
||||||
|
Digging %d m above machine =
|
||||||
|
Digging %d m below machine =
|
||||||
|
|
||||||
## CNC
|
## CNC
|
||||||
Cylinder = Zylinder
|
Cylinder = Zylinder
|
||||||
|
@ -109,6 +109,10 @@ Power level = Nivel de Poder
|
|||||||
Production at %d%% = Produccion en %d%%
|
Production at %d%% = Produccion en %d%%
|
||||||
Stopped =
|
Stopped =
|
||||||
Keeping %d/%d map blocks loaded =
|
Keeping %d/%d map blocks loaded =
|
||||||
|
Digging not started =
|
||||||
|
Digging finished =
|
||||||
|
Digging %d m above machine =
|
||||||
|
Digging %d m below machine =
|
||||||
|
|
||||||
## CNC Machine
|
## CNC Machine
|
||||||
Element Edge = Elemento Borde
|
Element Edge = Elemento Borde
|
||||||
|
@ -112,6 +112,10 @@ Slim Elements half / normal height: = Metà elementi sottili / altezza normale:
|
|||||||
Current track %s = Traccia corrente %s
|
Current track %s = Traccia corrente %s
|
||||||
Stopped =
|
Stopped =
|
||||||
Keeping %d/%d map blocks loaded =
|
Keeping %d/%d map blocks loaded =
|
||||||
|
Digging not started =
|
||||||
|
Digging finished =
|
||||||
|
Digging %d m above machine =
|
||||||
|
Digging %d m below machine =
|
||||||
|
|
||||||
## CNC
|
## CNC
|
||||||
Cylinder = Cilindro
|
Cylinder = Cilindro
|
||||||
|
@ -120,6 +120,10 @@ Slim Elements half / normal height: =
|
|||||||
Current track %s =
|
Current track %s =
|
||||||
Stopped =
|
Stopped =
|
||||||
Keeping %d/%d map blocks loaded =
|
Keeping %d/%d map blocks loaded =
|
||||||
|
Digging not started =
|
||||||
|
Digging finished =
|
||||||
|
Digging %d m above machine =
|
||||||
|
Digging %d m below machine =
|
||||||
|
|
||||||
## CNC
|
## CNC
|
||||||
Cylinder =
|
Cylinder =
|
||||||
|
@ -11,146 +11,133 @@ minetest.register_craft({
|
|||||||
|
|
||||||
local quarry_dig_above_nodes = 3 -- How far above the quarry we will dig nodes
|
local quarry_dig_above_nodes = 3 -- How far above the quarry we will dig nodes
|
||||||
local quarry_max_depth = 100
|
local quarry_max_depth = 100
|
||||||
|
local quarry_demand = 10000
|
||||||
|
|
||||||
local function set_quarry_formspec(meta)
|
local function set_quarry_formspec(meta)
|
||||||
local formspec = "size[3,1.5]"..
|
local radius = meta:get_int("size")
|
||||||
"field[1,0.5;2,1;size;Radius;"..meta:get_int("size").."]"
|
local formspec = "size[6,2.5]"..
|
||||||
|
"item_image[0,0;1,1;technic:quarry]"..
|
||||||
|
"label[1,0;"..S("%s Quarry"):format("HV").."]"..
|
||||||
|
"field[0.3,1.5;2,1;size;"..S("Radius:")..";"..radius.."]"
|
||||||
if meta:get_int("enabled") == 0 then
|
if meta:get_int("enabled") == 0 then
|
||||||
formspec = formspec.."button[0,1;3,1;enable;"..S("%s Disabled"):format(S("%s Quarry"):format("HV")).."]"
|
formspec = formspec.."button[4,1.2;2,1;enable;"..S("Disabled").."]"
|
||||||
else
|
else
|
||||||
formspec = formspec.."button[0,1;3,1;disable;"..S("%s Enabled"):format(S("%s Quarry"):format("HV")).."]"
|
formspec = formspec.."button[4,1.2;2,1;disable;"..S("Enabled").."]"
|
||||||
end
|
end
|
||||||
|
local diameter = radius*2 + 1
|
||||||
|
local nd = meta:get_int("dug")
|
||||||
|
local rel_y = quarry_dig_above_nodes - math.floor(nd / (diameter*diameter))
|
||||||
|
formspec = formspec.."label[0,2;"..minetest.formspec_escape(
|
||||||
|
nd == 0 and S("Digging not started") or
|
||||||
|
(rel_y < -quarry_max_depth and S("Digging finished") or
|
||||||
|
S("Digging %d m "..(rel_y > 0 and "above" or "below").." machine")
|
||||||
|
:format(math.abs(rel_y)))
|
||||||
|
).."]"
|
||||||
|
formspec = formspec.."button[4,2;2,1;restart;"..S("Restart").."]"
|
||||||
meta:set_string("formspec", formspec)
|
meta:set_string("formspec", formspec)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function set_quarry_demand(meta)
|
||||||
|
local radius = meta:get_int("size")
|
||||||
|
local diameter = radius*2 + 1
|
||||||
|
local machine_name = S("%s Quarry"):format("HV")
|
||||||
|
if meta:get_int("enabled") == 0 then
|
||||||
|
meta:set_string("infotext", S("%s Disabled"):format(machine_name))
|
||||||
|
meta:set_int("HV_EU_demand", 0)
|
||||||
|
elseif meta:get_int("dug") == diameter*diameter * (quarry_dig_above_nodes+1+quarry_max_depth) then
|
||||||
|
meta:set_string("infotext", S("%s Finished"):format(machine_name))
|
||||||
|
meta:set_int("HV_EU_demand", 0)
|
||||||
|
else
|
||||||
|
meta:set_string("infotext", S(meta:get_int("HV_EU_input") >= quarry_demand and "%s Active" or "%s Unpowered"):format(machine_name))
|
||||||
|
meta:set_int("HV_EU_demand", quarry_demand)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
local function quarry_receive_fields(pos, formname, fields, sender)
|
local function quarry_receive_fields(pos, formname, fields, sender)
|
||||||
local meta = minetest.get_meta(pos)
|
local meta = minetest.get_meta(pos)
|
||||||
if fields.size then
|
if fields.size and string.find(fields.size, "^[0-9]+$") then
|
||||||
local size = tonumber(fields.size) or 0
|
local size = tonumber(fields.size)
|
||||||
size = math.max(size, 2)
|
if size >= 2 and size <= 8 and size ~= meta:get_int("size") then
|
||||||
size = math.min(size, 8)
|
|
||||||
meta:set_int("size", size)
|
meta:set_int("size", size)
|
||||||
|
meta:set_int("dug", 0)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
if fields.enable then meta:set_int("enabled", 1) end
|
if fields.enable then meta:set_int("enabled", 1) end
|
||||||
if fields.disable then meta:set_int("enabled", 0) end
|
if fields.disable then meta:set_int("enabled", 0) end
|
||||||
|
if fields.restart then meta:set_int("dug", 0) end
|
||||||
set_quarry_formspec(meta)
|
set_quarry_formspec(meta)
|
||||||
|
set_quarry_demand(meta)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function get_quarry_center(pos, size)
|
local function quarry_run(pos, node)
|
||||||
local node = minetest.get_node(pos)
|
|
||||||
local back_dir = minetest.facedir_to_dir(node.param2)
|
|
||||||
local relative_center = vector.multiply(back_dir, size + 1)
|
|
||||||
local center = vector.add(pos, relative_center)
|
|
||||||
return center
|
|
||||||
end
|
|
||||||
|
|
||||||
local function gen_next_digpos(center, digpos, size)
|
|
||||||
digpos.x = digpos.x + 1
|
|
||||||
if digpos.x > center.x + size then
|
|
||||||
digpos.x = center.x - size
|
|
||||||
digpos.z = digpos.z + 1
|
|
||||||
end
|
|
||||||
if digpos.z > center.z + size then
|
|
||||||
digpos.x = center.x - size
|
|
||||||
digpos.z = center.z - size
|
|
||||||
digpos.y = digpos.y - 1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local function find_next_digpos(data, area, center, dig_y, size)
|
|
||||||
local c_air = minetest.get_content_id("air")
|
|
||||||
|
|
||||||
for y = center.y + quarry_dig_above_nodes, dig_y - 1, -1 do
|
|
||||||
for z = center.z - size, center.z + size do
|
|
||||||
for x = center.x - size, center.x + size do
|
|
||||||
if data[area:index(x, y, z)] ~= c_air then
|
|
||||||
return vector.new(x, y, z)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local function quarry_dig(pos, center, size)
|
|
||||||
local meta = minetest.get_meta(pos)
|
local meta = minetest.get_meta(pos)
|
||||||
local drops = {}
|
if meta:get_int("enabled") and meta:get_int("HV_EU_input") >= quarry_demand then
|
||||||
local dig_y = meta:get_int("dig_y")
|
local pdir = minetest.facedir_to_dir(node.param2)
|
||||||
local owner = meta:get_string("owner")
|
local qdir = pdir.x == 1 and vector.new(0,0,-1) or
|
||||||
|
(pdir.z == -1 and vector.new(-1,0,0) or
|
||||||
|
(pdir.x == -1 and vector.new(0,0,1) or
|
||||||
|
vector.new(1,0,0)))
|
||||||
|
local radius = meta:get_int("size")
|
||||||
|
local diameter = radius*2 + 1
|
||||||
|
local startpos = vector.add(vector.add(vector.add(pos,
|
||||||
|
vector.new(0, quarry_dig_above_nodes, 0)),
|
||||||
|
pdir),
|
||||||
|
vector.multiply(qdir, -radius))
|
||||||
|
local endpos = vector.add(vector.add(vector.add(startpos,
|
||||||
|
vector.new(0, -quarry_dig_above_nodes-quarry_max_depth, 0)),
|
||||||
|
vector.multiply(pdir, diameter-1)),
|
||||||
|
vector.multiply(qdir, diameter-1))
|
||||||
local vm = VoxelManip()
|
local vm = VoxelManip()
|
||||||
local p1 = vector.new(
|
local minpos, maxpos = vm:read_from_map(startpos, endpos)
|
||||||
center.x - size,
|
local area = VoxelArea:new({MinEdge=minpos, MaxEdge=maxpos})
|
||||||
center.y + quarry_dig_above_nodes,
|
|
||||||
center.z - size)
|
|
||||||
local p2 = vector.new(
|
|
||||||
center.x + size,
|
|
||||||
dig_y - 1, -- One node lower in case we have finished the current layer
|
|
||||||
center.z + size)
|
|
||||||
local e1, e2 = vm:read_from_map(p1, p2)
|
|
||||||
local area = VoxelArea:new({MinEdge=e1, MaxEdge=e2})
|
|
||||||
local data = vm:get_data()
|
local data = vm:get_data()
|
||||||
|
local c_air = minetest.get_content_id("air")
|
||||||
local digpos = find_next_digpos(data, area, center, dig_y, size)
|
local owner = meta:get_string("owner")
|
||||||
|
local nd = meta:get_int("dug")
|
||||||
if digpos then
|
while nd ~= diameter*diameter * (quarry_dig_above_nodes+1+quarry_max_depth) do
|
||||||
if digpos.y < pos.y - quarry_max_depth then
|
local ry = math.floor(nd / (diameter*diameter))
|
||||||
meta:set_int("dig_y", digpos.y)
|
local ndl = nd % (diameter*diameter)
|
||||||
return drops
|
if ry % 2 == 1 then
|
||||||
|
ndl = diameter*diameter - 1 - ndl
|
||||||
end
|
end
|
||||||
if minetest.is_protected and minetest.is_protected(digpos, owner) then
|
local rq = math.floor(ndl / diameter)
|
||||||
meta:set_int("enabled", 0)
|
local rp = ndl % diameter
|
||||||
set_quarry_formspec(meta)
|
if rq % 2 == 1 then rp = diameter - 1 - rp end
|
||||||
return {}
|
local digpos = vector.add(vector.add(vector.add(startpos,
|
||||||
|
vector.new(0, -ry, 0)),
|
||||||
|
vector.multiply(pdir, rp)),
|
||||||
|
vector.multiply(qdir, rq))
|
||||||
|
local can_dig = true
|
||||||
|
for ay = startpos.y, digpos.y+1, -1 do
|
||||||
|
if data[area:index(digpos.x, ay, digpos.z)] ~= c_air then
|
||||||
|
can_dig = false
|
||||||
|
break
|
||||||
end
|
end
|
||||||
dig_y = digpos.y
|
end
|
||||||
local node = minetest.get_node(digpos)
|
if can_dig and minetest.is_protected and minetest.is_protected(digpos, owner) then
|
||||||
local node_def = minetest.registered_nodes[node.name] or { diggable = false }
|
can_dig = false
|
||||||
if node_def.diggable and ((not node_def.can_dig) or node_def.can_dig(digpos, nil)) then
|
end
|
||||||
|
local dignode
|
||||||
|
if can_dig then
|
||||||
|
dignode = minetest.get_node(digpos)
|
||||||
|
local dignodedef = minetest.registered_nodes[dignode.name] or {diggable=false}
|
||||||
|
if not dignodedef.diggable or (dignodedef.can_dig and not dignodedef.can_dig(digpos, nil)) then
|
||||||
|
can_dig = false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
nd = nd + 1
|
||||||
|
if can_dig then
|
||||||
minetest.remove_node(digpos)
|
minetest.remove_node(digpos)
|
||||||
drops = minetest.get_node_drops(node.name, "")
|
for _, item in ipairs(minetest.get_node_drops(dignode.name, "")) do
|
||||||
end
|
|
||||||
elseif not (dig_y < pos.y - quarry_max_depth) then
|
|
||||||
dig_y = dig_y - 16
|
|
||||||
end
|
|
||||||
|
|
||||||
meta:set_int("dig_y", dig_y)
|
|
||||||
return drops
|
|
||||||
end
|
|
||||||
|
|
||||||
local function send_items(items, pos, node)
|
|
||||||
for _, item in pairs(items) do
|
|
||||||
technic.tube_inject_item(pos, pos, vector.new(0, 1, 0), item)
|
technic.tube_inject_item(pos, pos, vector.new(0, 1, 0), item)
|
||||||
end
|
end
|
||||||
end
|
break
|
||||||
|
|
||||||
local run = function(pos, node)
|
|
||||||
local meta = minetest.get_meta(pos)
|
|
||||||
local size = meta:get_int("size")
|
|
||||||
local eu_input = meta:get_int("HV_EU_input")
|
|
||||||
local demand = 10000
|
|
||||||
local center = get_quarry_center(pos, size)
|
|
||||||
local dig_y = meta:get_int("dig_y")
|
|
||||||
local machine_name = S("%s Quarry"):format("HV")
|
|
||||||
|
|
||||||
if meta:get_int("enabled") == 0 then
|
|
||||||
meta:set_string("infotext", S("%s Disabled"):format(machine_name))
|
|
||||||
meta:set_int("HV_EU_demand", 0)
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
if eu_input < demand then
|
|
||||||
meta:set_string("infotext", S("%s Unpowered"):format(machine_name))
|
|
||||||
elseif eu_input >= demand then
|
|
||||||
meta:set_string("infotext", S("%s Active"):format(machine_name))
|
|
||||||
|
|
||||||
local items = quarry_dig(pos, center, size)
|
|
||||||
send_items(items, pos, node)
|
|
||||||
|
|
||||||
if dig_y < pos.y - quarry_max_depth then
|
|
||||||
meta:set_string("infotext", S("%s Finished"):format(machine_name))
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
meta:set_int("HV_EU_demand", demand)
|
meta:set_int("dug", nd)
|
||||||
|
end
|
||||||
|
set_quarry_formspec(meta)
|
||||||
|
set_quarry_demand(meta)
|
||||||
end
|
end
|
||||||
|
|
||||||
minetest.register_node("technic:quarry", {
|
minetest.register_node("technic:quarry", {
|
||||||
@ -168,7 +155,7 @@ minetest.register_node("technic:quarry", {
|
|||||||
meta:set_string("infotext", S("%s Quarry"):format("HV"))
|
meta:set_string("infotext", S("%s Quarry"):format("HV"))
|
||||||
meta:set_int("size", 4)
|
meta:set_int("size", 4)
|
||||||
set_quarry_formspec(meta)
|
set_quarry_formspec(meta)
|
||||||
meta:set_int("dig_y", pos.y)
|
set_quarry_demand(meta)
|
||||||
end,
|
end,
|
||||||
after_place_node = function(pos, placer, itemstack)
|
after_place_node = function(pos, placer, itemstack)
|
||||||
local meta = minetest.get_meta(pos)
|
local meta = minetest.get_meta(pos)
|
||||||
@ -177,7 +164,7 @@ minetest.register_node("technic:quarry", {
|
|||||||
end,
|
end,
|
||||||
after_dig_node = pipeworks.scan_for_tube_objects,
|
after_dig_node = pipeworks.scan_for_tube_objects,
|
||||||
on_receive_fields = quarry_receive_fields,
|
on_receive_fields = quarry_receive_fields,
|
||||||
technic_run = run,
|
technic_run = quarry_run,
|
||||||
})
|
})
|
||||||
|
|
||||||
technic.register_machine("HV", "technic:quarry", technic.receiver)
|
technic.register_machine("HV", "technic:quarry", technic.receiver)
|
||||||
|
Loading…
Reference in New Issue
Block a user