2013-07-17 21:34:35 +02:00
|
|
|
|
2013-10-30 18:45:32 +01:00
|
|
|
local S = technic.getter
|
|
|
|
|
2017-04-11 14:09:53 +02:00
|
|
|
local tube_entry = "^pipeworks_tube_connection_metallic.png"
|
2017-04-11 14:31:17 +02:00
|
|
|
local cable_entry = "^technic_cable_connection_overlay.png"
|
2017-04-11 14:09:53 +02:00
|
|
|
|
2019-03-04 09:06:54 +01:00
|
|
|
local has_monitoring = minetest.get_modpath("monitoring")
|
|
|
|
local metric_dig_count
|
|
|
|
|
|
|
|
if has_monitoring then
|
|
|
|
metric_dig_count = monitoring.counter("technic_quarry_dig_count",
|
|
|
|
"number of technic quarry digs")
|
|
|
|
|
|
|
|
end
|
|
|
|
|
2013-07-17 21:34:35 +02:00
|
|
|
minetest.register_craft({
|
|
|
|
recipe = {
|
2014-07-07 22:48:38 +02:00
|
|
|
{"technic:carbon_plate", "pipeworks:filter", "technic:composite_plate"},
|
2018-10-31 01:29:28 +01:00
|
|
|
{"basic_materials:motor", "technic:machine_casing", "technic:diamond_drill_head"},
|
2016-03-20 02:34:56 +01:00
|
|
|
{"technic:carbon_steel_block", "technic:hv_cable", "technic:carbon_steel_block"}},
|
2013-07-17 21:34:35 +02:00
|
|
|
output = "technic:quarry",
|
|
|
|
})
|
|
|
|
|
|
|
|
local quarry_dig_above_nodes = 3 -- How far above the quarry we will dig nodes
|
2019-03-01 19:13:59 +01:00
|
|
|
local quarry_max_depth = 50
|
2014-08-17 20:19:11 +02:00
|
|
|
local quarry_demand = 10000
|
2016-09-25 21:40:17 +02:00
|
|
|
local quarry_eject_dir = vector.new(0, 1, 0)
|
2013-07-17 21:34:35 +02:00
|
|
|
|
2018-12-14 08:31:14 +01:00
|
|
|
|
|
|
|
-- per player quota
|
|
|
|
local quota_map = {}
|
|
|
|
local timer = 0
|
|
|
|
|
|
|
|
-- quota reset timer
|
|
|
|
minetest.register_globalstep(function(dtime)
|
|
|
|
timer = timer + dtime
|
|
|
|
if timer < 1 then return end
|
|
|
|
timer=0
|
|
|
|
|
|
|
|
-- reset quota map
|
|
|
|
quota_map = {}
|
|
|
|
|
|
|
|
-- this many blocks per second
|
2018-12-20 08:27:35 +01:00
|
|
|
local init_quota = minetest.settings:get("technic.quarry.quota") or 10
|
2018-12-14 08:31:14 +01:00
|
|
|
|
|
|
|
local players = minetest.get_connected_players()
|
|
|
|
for i, player in pairs(players) do
|
|
|
|
local name = player:get_player_name()
|
|
|
|
quota_map[name] = init_quota
|
|
|
|
end
|
|
|
|
end)
|
|
|
|
|
|
|
|
|
2014-05-23 23:37:44 +02:00
|
|
|
local function set_quarry_formspec(meta)
|
2014-08-17 20:19:11 +02:00
|
|
|
local radius = meta:get_int("size")
|
2015-01-24 11:46:47 +01:00
|
|
|
local formspec = "size[6,4.3]"..
|
|
|
|
"list[context;cache;0,1;4,3;]"..
|
|
|
|
"item_image[4.8,0;1,1;technic:quarry]"..
|
|
|
|
"label[0,0.2;"..S("%s Quarry"):format("HV").."]"..
|
|
|
|
"field[4.3,3.5;2,1;size;"..S("Radius:")..";"..radius.."]"
|
2014-05-23 23:37:44 +02:00
|
|
|
if meta:get_int("enabled") == 0 then
|
2015-01-24 11:46:47 +01:00
|
|
|
formspec = formspec.."button[4,1;2,1;enable;"..S("Disabled").."]"
|
2014-05-23 23:37:44 +02:00
|
|
|
else
|
2015-01-24 11:46:47 +01:00
|
|
|
formspec = formspec.."button[4,1;2,1;disable;"..S("Enabled").."]"
|
2014-05-23 23:37:44 +02:00
|
|
|
end
|
2014-08-17 20:19:11 +02:00
|
|
|
local diameter = radius*2 + 1
|
|
|
|
local nd = meta:get_int("dug")
|
|
|
|
local rel_y = quarry_dig_above_nodes - math.floor(nd / (diameter*diameter))
|
2015-01-24 11:46:47 +01:00
|
|
|
formspec = formspec.."label[0,4;"..minetest.formspec_escape(
|
2014-08-17 20:19:11 +02:00
|
|
|
nd == 0 and S("Digging not started") or
|
|
|
|
(rel_y < -quarry_max_depth and S("Digging finished") or
|
2015-01-24 11:46:47 +01:00
|
|
|
(meta:get_int("purge_on") == 1 and S("Purging cache") or
|
2014-08-17 20:19:11 +02:00
|
|
|
S("Digging %d m "..(rel_y > 0 and "above" or "below").." machine")
|
2015-01-24 11:46:47 +01:00
|
|
|
:format(math.abs(rel_y))))
|
2014-08-17 20:19:11 +02:00
|
|
|
).."]"
|
|
|
|
formspec = formspec.."button[4,2;2,1;restart;"..S("Restart").."]"
|
2014-05-23 23:37:44 +02:00
|
|
|
meta:set_string("formspec", formspec)
|
2013-07-17 21:34:35 +02:00
|
|
|
end
|
|
|
|
|
2014-08-17 20:19:11 +02:00
|
|
|
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")
|
2015-01-24 11:46:47 +01:00
|
|
|
if meta:get_int("enabled") == 0 or meta:get_int("purge_on") == 1 then
|
|
|
|
meta:set_string("infotext", S(meta:get_int("purge_on") == 1 and "%s purging cache" or "%s Disabled"):format(machine_name))
|
2014-08-17 20:19:11 +02:00
|
|
|
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)
|
2013-07-17 21:34:35 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2014-08-17 20:19:11 +02:00
|
|
|
local function quarry_receive_fields(pos, formname, fields, sender)
|
2018-12-11 16:27:08 +01:00
|
|
|
local player_name = sender:get_player_name()
|
|
|
|
if minetest.is_protected(pos, player_name) then
|
|
|
|
minetest.chat_send_player(player_name, "You are not allowed to edit this!")
|
|
|
|
minetest.record_protection_violation(pos, player_name)
|
|
|
|
return
|
|
|
|
end
|
2013-07-17 21:34:35 +02:00
|
|
|
local meta = minetest.get_meta(pos)
|
2014-08-17 20:19:11 +02:00
|
|
|
if fields.size and string.find(fields.size, "^[0-9]+$") then
|
|
|
|
local size = tonumber(fields.size)
|
|
|
|
if size >= 2 and size <= 8 and size ~= meta:get_int("size") then
|
|
|
|
meta:set_int("size", size)
|
|
|
|
meta:set_int("dug", 0)
|
2013-07-17 21:34:35 +02:00
|
|
|
end
|
|
|
|
end
|
2014-08-17 20:19:11 +02:00
|
|
|
if fields.enable then meta:set_int("enabled", 1) end
|
|
|
|
if fields.disable then meta:set_int("enabled", 0) end
|
2015-01-24 11:46:47 +01:00
|
|
|
if fields.restart then
|
|
|
|
meta:set_int("dug", 0)
|
|
|
|
meta:set_int("purge_on", 1)
|
|
|
|
end
|
2014-08-17 20:19:11 +02:00
|
|
|
set_quarry_formspec(meta)
|
|
|
|
set_quarry_demand(meta)
|
2013-07-17 21:34:35 +02:00
|
|
|
end
|
|
|
|
|
2015-01-24 11:46:47 +01:00
|
|
|
local function quarry_handle_purge(pos)
|
|
|
|
local meta = minetest.get_meta(pos)
|
|
|
|
local inv = meta:get_inventory()
|
2018-11-28 08:36:10 +01:00
|
|
|
local cache = inv:get_list("cache")
|
|
|
|
if not cache then
|
|
|
|
return
|
|
|
|
end
|
2015-01-24 11:46:47 +01:00
|
|
|
local i = 0
|
2018-11-28 08:36:10 +01:00
|
|
|
for _,stack in ipairs(cache) do
|
2015-01-24 11:46:47 +01:00
|
|
|
i = i + 1
|
|
|
|
if stack then
|
|
|
|
local item = stack:to_table()
|
|
|
|
if item then
|
2016-09-25 21:40:17 +02:00
|
|
|
technic.tube_inject_item(pos, pos, quarry_eject_dir, item)
|
2015-01-24 11:46:47 +01:00
|
|
|
stack:clear()
|
|
|
|
inv:set_stack("cache", i, stack)
|
|
|
|
break
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
if inv:is_empty("cache") then
|
|
|
|
meta:set_int("purge_on", 0)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2014-08-17 20:19:11 +02:00
|
|
|
local function quarry_run(pos, node)
|
2019-03-04 09:06:54 +01:00
|
|
|
if metric_dig_count ~= nil then
|
|
|
|
metric_dig_count.inc()
|
|
|
|
end
|
|
|
|
|
2014-07-11 11:00:46 +02:00
|
|
|
local meta = minetest.get_meta(pos)
|
2018-12-14 08:31:14 +01:00
|
|
|
local owner = meta:get_string("owner")
|
|
|
|
|
2015-01-24 11:46:47 +01:00
|
|
|
local inv = meta:get_inventory()
|
|
|
|
-- initialize cache for the case we load an older world
|
|
|
|
inv:set_size("cache", 12)
|
|
|
|
-- toss a coin whether we do an automatic purge. Chance 1:200
|
|
|
|
local purge_rand = math.random()
|
|
|
|
if purge_rand <= 0.005 then
|
|
|
|
meta:set_int("purge_on", 1)
|
|
|
|
end
|
|
|
|
|
2018-12-14 08:31:14 +01:00
|
|
|
local digging_allowed = false
|
|
|
|
local quota = quota_map[owner]
|
2018-12-20 08:27:35 +01:00
|
|
|
digging_allowed = quota and quota > 0
|
|
|
|
|
|
|
|
|
|
|
|
if digging_allowed and meta:get_int("enabled") and meta:get_int("HV_EU_input") >= quarry_demand and meta:get_int("purge_on") == 0 then
|
|
|
|
|
2018-12-14 08:31:14 +01:00
|
|
|
-- decrement quota
|
|
|
|
quota = quota - 1
|
|
|
|
quota_map[owner] = quota
|
|
|
|
|
2014-08-17 20:19:11 +02:00
|
|
|
local pdir = minetest.facedir_to_dir(node.param2)
|
2018-12-09 16:01:10 +01:00
|
|
|
if pdir.y ~= 0 then
|
2018-12-03 10:49:41 +01:00
|
|
|
-- faces up or down, not valid, otherwise depth-check would run endless and hang up the server
|
|
|
|
return
|
|
|
|
end
|
|
|
|
|
2014-08-17 20:19:11 +02:00
|
|
|
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 owner = meta:get_string("owner")
|
|
|
|
local nd = meta:get_int("dug")
|
2019-01-30 19:55:18 +01:00
|
|
|
while nd < diameter*diameter * (quarry_dig_above_nodes+1+quarry_max_depth) do
|
2014-08-17 20:19:11 +02:00
|
|
|
local ry = math.floor(nd / (diameter*diameter))
|
|
|
|
local ndl = nd % (diameter*diameter)
|
|
|
|
if ry % 2 == 1 then
|
|
|
|
ndl = diameter*diameter - 1 - ndl
|
|
|
|
end
|
|
|
|
local rq = math.floor(ndl / diameter)
|
|
|
|
local rp = ndl % diameter
|
|
|
|
if rq % 2 == 1 then rp = diameter - 1 - rp end
|
|
|
|
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
|
|
|
|
if can_dig and minetest.is_protected and minetest.is_protected(digpos, owner) then
|
|
|
|
can_dig = false
|
|
|
|
end
|
|
|
|
local dignode
|
|
|
|
if can_dig then
|
2015-01-24 04:30:48 +01:00
|
|
|
dignode = technic.get_or_load_node(digpos) or minetest.get_node(digpos)
|
2014-08-17 20:19:11 +02:00
|
|
|
local dignodedef = minetest.registered_nodes[dignode.name] or {diggable=false}
|
2018-05-19 22:06:00 +02:00
|
|
|
-- doors mod among other thing does NOT like a nil digger...
|
2018-11-09 07:56:18 +01:00
|
|
|
local fakedigger = pipeworks.create_fake_player({
|
|
|
|
name = owner
|
|
|
|
})
|
2018-05-19 22:06:00 +02:00
|
|
|
if not dignodedef.diggable or (dignodedef.can_dig and not dignodedef.can_dig(digpos, fakedigger)) then
|
2014-08-17 20:19:11 +02:00
|
|
|
can_dig = false
|
|
|
|
end
|
|
|
|
end
|
2015-01-24 04:30:48 +01:00
|
|
|
|
|
|
|
if can_dig then
|
2018-07-26 15:58:50 +02:00
|
|
|
-- test above blocks if diggable
|
2015-01-24 04:30:48 +01:00
|
|
|
for ay = startpos.y, digpos.y+1, -1 do
|
|
|
|
local checkpos = {x=digpos.x, y=ay, z=digpos.z}
|
|
|
|
local checknode = technic.get_or_load_node(checkpos) or minetest.get_node(checkpos)
|
2018-07-26 15:58:50 +02:00
|
|
|
if checknode.name ~= "air" and checknode.name ~= "vacuum:vacuum" then
|
2015-01-24 04:30:48 +01:00
|
|
|
can_dig = false
|
|
|
|
break
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2014-08-17 20:19:11 +02:00
|
|
|
nd = nd + 1
|
|
|
|
if can_dig then
|
|
|
|
minetest.remove_node(digpos)
|
2015-01-24 11:46:47 +01:00
|
|
|
local drops = minetest.get_node_drops(dignode.name, "")
|
|
|
|
for _, dropped_item in ipairs(drops) do
|
|
|
|
local left = inv:add_item("cache", dropped_item)
|
|
|
|
while not left:is_empty() do
|
|
|
|
meta:set_int("purge_on", 1)
|
|
|
|
quarry_handle_purge(pos)
|
|
|
|
left = inv:add_item("cache", left)
|
|
|
|
end
|
2014-08-17 20:19:11 +02:00
|
|
|
end
|
|
|
|
break
|
|
|
|
end
|
2014-07-11 11:00:46 +02:00
|
|
|
end
|
2015-01-24 11:46:47 +01:00
|
|
|
if nd == diameter*diameter * (quarry_dig_above_nodes+1+quarry_max_depth) then
|
|
|
|
-- if a quarry is finished, we enable purge mode
|
|
|
|
meta:set_int("purge_on", 1)
|
|
|
|
end
|
2014-08-17 20:19:11 +02:00
|
|
|
meta:set_int("dug", nd)
|
2015-01-24 11:46:47 +01:00
|
|
|
else
|
|
|
|
-- if a quarry is disabled or has no power, we enable purge mode
|
|
|
|
meta:set_int("purge_on", 1)
|
|
|
|
end
|
|
|
|
-- if something triggered a purge, we handle it
|
|
|
|
if meta:get_int("purge_on") == 1 then
|
|
|
|
quarry_handle_purge(pos)
|
2014-07-11 11:00:46 +02:00
|
|
|
end
|
2014-08-17 20:19:11 +02:00
|
|
|
set_quarry_formspec(meta)
|
|
|
|
set_quarry_demand(meta)
|
2014-07-11 11:00:46 +02:00
|
|
|
end
|
|
|
|
|
2015-01-24 11:46:47 +01:00
|
|
|
local function send_move_error(player)
|
|
|
|
minetest.chat_send_player(player:get_player_name(),
|
|
|
|
S("Manually taking/removing from cache by hand is not possible. "..
|
|
|
|
"If you can't wait, restart or disable the quarry to start automatic purge."))
|
|
|
|
return 0
|
|
|
|
end
|
|
|
|
|
2013-07-17 21:34:35 +02:00
|
|
|
minetest.register_node("technic:quarry", {
|
Rationalise machine terminology
All electrically-powered machines now consistently indicate their
tier (supply voltage) in their names. As this implies that they are
electrically powered, the furnaces no longer have "Electric" in their
names. The fuel-fired equivalents of electric machines, which exist
for alloy furnace and furnace, now say "Fuel-Fired" to distinguish them.
(The fuel-fired alloy furnace used to say "Coal", which was inaccurate
because it uses any fuel. The fuel-fired furnace, from the default mod,
used to just be called "Furnace", which is ambiguous.)
Electric power generators now consistently indicate their tier and have
the word "Generator" in their names. This makes their purpose much
clearer, and makes obvious craft guide searches produce useful results.
The fuel-fired generators, previously just (ambiguously) called
"Generator", are now explicitly "Fuel-Fired".
2014-06-20 17:58:52 +02:00
|
|
|
description = S("%s Quarry"):format("HV"),
|
2017-04-11 14:09:53 +02:00
|
|
|
tiles = {
|
|
|
|
"technic_carbon_steel_block.png"..tube_entry,
|
2017-04-11 14:31:17 +02:00
|
|
|
"technic_carbon_steel_block.png"..cable_entry,
|
|
|
|
"technic_carbon_steel_block.png"..cable_entry,
|
|
|
|
"technic_carbon_steel_block.png"..cable_entry,
|
2017-04-11 14:09:53 +02:00
|
|
|
"technic_carbon_steel_block.png^default_tool_mesepick.png",
|
2017-04-11 14:31:17 +02:00
|
|
|
"technic_carbon_steel_block.png"..cable_entry
|
2017-04-11 14:09:53 +02:00
|
|
|
},
|
2013-07-17 21:34:35 +02:00
|
|
|
paramtype2 = "facedir",
|
2016-03-20 02:34:56 +01:00
|
|
|
groups = {cracky=2, tubedevice=1, technic_machine=1, technic_hv=1},
|
|
|
|
connect_sides = {"bottom", "front", "left", "right"},
|
2013-07-17 21:34:35 +02:00
|
|
|
tube = {
|
|
|
|
connect_sides = {top = 1},
|
2016-09-25 21:40:17 +02:00
|
|
|
-- lower priority than other tubes, so that quarries will prefer any
|
|
|
|
-- other tube to another quarry, which could lead to server freezes
|
|
|
|
-- in certain quarry placements (2x2 for example would never eject)
|
|
|
|
priority = 10,
|
|
|
|
can_go = function(pos, node, velocity, stack)
|
|
|
|
-- always eject the same, even if items came in another way
|
|
|
|
-- this further mitigates loops and generally avoids random sideway movement
|
|
|
|
-- that can be expected in certain quarry placements
|
|
|
|
return { quarry_eject_dir }
|
|
|
|
end
|
2013-07-17 21:34:35 +02:00
|
|
|
},
|
|
|
|
on_construct = function(pos)
|
|
|
|
local meta = minetest.get_meta(pos)
|
Rationalise machine terminology
All electrically-powered machines now consistently indicate their
tier (supply voltage) in their names. As this implies that they are
electrically powered, the furnaces no longer have "Electric" in their
names. The fuel-fired equivalents of electric machines, which exist
for alloy furnace and furnace, now say "Fuel-Fired" to distinguish them.
(The fuel-fired alloy furnace used to say "Coal", which was inaccurate
because it uses any fuel. The fuel-fired furnace, from the default mod,
used to just be called "Furnace", which is ambiguous.)
Electric power generators now consistently indicate their tier and have
the word "Generator" in their names. This makes their purpose much
clearer, and makes obvious craft guide searches produce useful results.
The fuel-fired generators, previously just (ambiguously) called
"Generator", are now explicitly "Fuel-Fired".
2014-06-20 17:58:52 +02:00
|
|
|
meta:set_string("infotext", S("%s Quarry"):format("HV"))
|
2014-05-23 23:37:44 +02:00
|
|
|
meta:set_int("size", 4)
|
|
|
|
set_quarry_formspec(meta)
|
2014-08-17 20:19:11 +02:00
|
|
|
set_quarry_demand(meta)
|
2013-07-17 21:34:35 +02:00
|
|
|
end,
|
|
|
|
after_place_node = function(pos, placer, itemstack)
|
|
|
|
local meta = minetest.get_meta(pos)
|
|
|
|
meta:set_string("owner", placer:get_player_name())
|
2013-12-15 21:49:28 +01:00
|
|
|
pipeworks.scan_for_tube_objects(pos)
|
2013-07-17 21:34:35 +02:00
|
|
|
end,
|
2015-01-24 11:46:47 +01:00
|
|
|
can_dig = function(pos,player)
|
|
|
|
local meta = minetest.get_meta(pos);
|
|
|
|
local inv = meta:get_inventory()
|
|
|
|
return inv:is_empty("cache")
|
|
|
|
end,
|
2013-12-15 21:49:28 +01:00
|
|
|
after_dig_node = pipeworks.scan_for_tube_objects,
|
2013-07-17 21:34:35 +02:00
|
|
|
on_receive_fields = quarry_receive_fields,
|
2014-08-17 20:19:11 +02:00
|
|
|
technic_run = quarry_run,
|
2015-01-24 11:46:47 +01:00
|
|
|
allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
|
|
|
|
return send_move_error(player)
|
|
|
|
end,
|
|
|
|
allow_metadata_inventory_put = function(pos, listname, index, stack, player)
|
|
|
|
return send_move_error(player)
|
|
|
|
end,
|
|
|
|
allow_metadata_inventory_take = function(pos, listname, index, stack, player)
|
|
|
|
return send_move_error(player)
|
|
|
|
end
|
2013-07-17 21:34:35 +02:00
|
|
|
})
|
|
|
|
|
|
|
|
technic.register_machine("HV", "technic:quarry", technic.receiver)
|