This repository has been archived on 2020-05-24. You can view files and clone it, but cannot push or open issues or pull requests.
minetest-mod-sparktech/sparkmachine/lua/quarry.lua

310 lines
8.6 KiB
Lua
Raw Permalink Normal View History

2019-09-30 05:30:56 +00:00
local NAME = minetest.get_current_modname()
2019-09-30 03:46:05 +00:00
local ENERGYCOST = {
2019-10-01 23:28:03 +00:00
static_strut = 20,
2019-09-30 01:49:55 +00:00
dynamic_struct = 24,
hardness_mod = 1,
2019-10-04 03:13:42 +00:00
mining = 25,
2019-09-30 01:49:55 +00:00
}
2019-10-04 03:13:42 +00:00
local MAX_ENERGY = 3000
2019-10-01 23:28:03 +00:00
local FORMSPEC = sparktech.add_inventory(19.8,8,
"list[current_name;quarry;0,0;16,6;]")
local MAX_SIZE = 64
2019-09-30 01:49:55 +00:00
local function Position(x, y, z) ---
--- Returns a valid pos as used by the game
return {x=x, y=y, z=z}
end
local function try_drain_energy(target_pos, amount) ---
--- Returns true if drained, false otherwise
--- Removes amount energy from target_pos if energy >= amount
local target = minetest.get_meta(target_pos)
local current = target:get_int("energy")
if current >= amount then
target:set_int("energy", current - amount)
return true
else
return false
end
end
2019-10-02 00:36:49 +00:00
local function try_remove_item(target_pos, listname, itemname, amount)
local inv = minetest.get_inventory({type="node", pos=target_pos})
local stack = ItemStack(itemname)
local amount = amount or 1
stack:set_count(amount)
local result = inv:remove_item(listname, stack)
if result:get_count() ~= amount then
inv:add_item(listname, result)
else
return true
end
return false
end
2019-09-30 01:49:55 +00:00
local function on_construct(pos, player)
2019-09-30 05:30:56 +00:00
player:get_meta():set_string(NAME .. ":quarry_pos" , minetest.pos_to_string(pos))
2019-09-30 01:49:55 +00:00
local meta = minetest.get_meta(pos)
meta:set_string("formspec", FORMSPEC)
local inventory = meta:get_inventory()
2019-10-01 23:28:03 +00:00
inventory:set_size('quarry', 96)
end
local function dig_node(pos, quarrypos)
local node = minetest.get_node(pos)
if node.name ~= "air" and sparktech.drain_energy(quarrypos, ENERGYCOST.mining) then
2019-10-04 00:41:29 +00:00
local quarry = minetest.get_meta(quarrypos)
local quarry_inv = quarry:get_inventory()
2019-12-19 19:45:59 +00:00
sparktech.dig_node(pos, quarry_inv, "quarry", nil)
end
return node.name ~= "air"
2019-09-30 01:49:55 +00:00
end
local function on_marker_placed(pos, quarry_pos, player)
2019-09-30 03:06:48 +00:00
-- Validate position
if quarry_pos.x == pos.x and
quarry_pos.y == pos.y and
quarry_pos.z == pos.z then
-- Invalid position, marker replaced quarry somehow
return -- TODO Report failure?
-- TODO clear clipboard in quarry on_break
2019-09-30 01:49:55 +00:00
2019-09-30 03:06:48 +00:00
end
local minx, maxx = math.order(pos.x, quarry_pos.x)
local miny, maxy = math.order(pos.y, quarry_pos.y)
local minz, maxz = math.order(pos.z, quarry_pos.z)
local diffx = maxx - minx
local diffy = maxy - miny
local diffz = maxz - minz
if diffx < 2 or diffx >= MAX_SIZE or
diffy < 2 or diffy >= MAX_SIZE or
diffz < 2 or diffz >= MAX_SIZE
then
notify.hud.sendtext(player, "Invalid dimensions for quarry 3x3x3")
return
end
2019-09-30 01:49:55 +00:00
2019-09-30 03:06:48 +00:00
-- Set quarry metadata
local meta = minetest.get_meta(quarry_pos)
2019-09-30 03:46:05 +00:00
meta:set_string("marker", minetest.pos_to_string(pos))
meta:set_int("current_frame", 1)
2019-09-30 03:46:05 +00:00
2019-09-30 05:10:03 +00:00
minetest.get_node_timer(quarry_pos):start(1.0)
2019-09-30 03:46:05 +00:00
end
2019-09-30 03:06:48 +00:00
2019-09-30 03:46:05 +00:00
local function marker_construct(pos, player)
2019-09-30 05:30:56 +00:00
local quarry_pos = minetest.string_to_pos(player:get_meta():get_string(NAME .. ":quarry_pos"))
2019-09-30 03:46:05 +00:00
local quarry = minetest.get_node(quarry_pos)
on_marker_placed(pos, quarry_pos, player)
2019-09-30 03:06:48 +00:00
end
2019-10-02 02:07:03 +00:00
local function place_strut(position, quarrypos)
if minetest.get_node(position).name == "air" then
local placed = false
2019-12-19 19:45:59 +00:00
if try_drain_energy(quarrypos, ENERGYCOST.static_strut) then
if try_remove_item(quarrypos, "quarry", NAME .. ":static_strut") then
2019-10-02 02:07:03 +00:00
minetest.set_node(position, { name = NAME .. ":static_strut"})
placed = true
end
end
return true, placed
end
return false, false
end
local function prepare_area(pos, pos2)
local placement_done = true
local minx, maxx = math.order(pos.x, pos2.x)
local miny, maxy = math.order(pos.y, pos2.y)
local minz, maxz = math.order(pos.z, pos2.z)
2019-09-30 05:10:03 +00:00
for x=minx , maxx do
for y=miny, maxy do
for z=minz, maxz do
2019-09-30 03:46:05 +00:00
-- dont remove quarry or marker
2019-10-02 02:07:03 +00:00
if not (x == pos.x and y == pos.y and z == pos.z) then
2019-10-02 00:51:29 +00:00
local count = 0
if x == pos.x then count = count +1 end
if x == pos2.x then count = count +1 end
if y == pos.y then count = count +1 end
if y == pos2.y then count = count +1 end
if z == pos.z then count = count +1 end
if z == pos2.z then count = count +1 end
if count >= 2 then
2019-10-02 02:07:03 +00:00
local node = minetest.get_node(Position(x, y, z))
if node.name ~= NAME .. ":static_strut" then
if node.name ~= "air" then
dig_node(Position(x, y, z), pos)
return false
end
local incomplete, placed = place_strut(Position(x, y, z), pos)
if placed then
2019-10-02 00:51:29 +00:00
return false
end
2019-10-02 02:07:03 +00:00
if incomplete then
placement_done = false
end
2019-10-02 00:51:29 +00:00
end
else
if dig_node(Position(x, y, z), pos) then
return false
end
end
2019-09-30 03:46:05 +00:00
end
2019-09-30 03:06:48 +00:00
end
end
end
2019-10-02 02:07:03 +00:00
return placement_done --true: cleared
2019-09-30 03:06:48 +00:00
end
2019-09-30 16:24:12 +00:00
2019-09-30 03:06:48 +00:00
local function timer_trigger(pos, elapsed)
local meta = minetest.get_meta(pos)
2019-10-04 00:41:29 +00:00
if not meta then assert("FUCK") end
2019-09-30 03:46:05 +00:00
local framenum = meta:get_int("current_frame")
local marker_pos = minetest.string_to_pos(meta:get_string("marker"))
while true do -- Make this section breakable
if framenum < 0 then
-- Operation Phase
--
local start_pos = minetest.string_to_pos(meta:get_string("dig_area_start"))
local end_pos = minetest.string_to_pos(meta:get_string("dig_area_end"))
if not start_pos or not end_pos then return end
local height = start_pos.y + framenum
local exitloop = false
for x=start_pos.x, end_pos.x do
for z=start_pos.z, end_pos.z do
if dig_node(Position(x, height, z), pos) then
exitloop = true
end
if exitloop then break end
end
if exitloop then break end
end
if not exitloop then
-- Layer cleared, next layer
framenum = framenum - 1
end
2019-09-30 03:06:48 +00:00
elseif framenum == 1 then
-- preparation phase
2019-10-02 02:07:03 +00:00
if prepare_area(pos, marker_pos) then
framenum = 0
end
else
2019-09-30 05:10:03 +00:00
--shrink the operational area here to a 2d space with one piece of border taken away to drill there
--
local posx, pos2x = math.order(pos.x, marker_pos.x)
local posy, pos2y = math.order(pos.y, marker_pos.y)
local posz, pos2z = math.order(pos.z, marker_pos.z)
2019-09-30 17:29:35 +00:00
posx = posx +1
pos2x = pos2x -1
posz = posz + 1
pos2z = pos2z -1
meta:set_string("dig_area_start", minetest.pos_to_string(Position(posx, posy, posz)))
meta:set_string("dig_area_end", minetest.pos_to_string(Position(pos2x, posy, pos2z))) -- can use this last z as counter, or ignore it
framenum = -1
2019-09-30 03:06:48 +00:00
end
break
2019-09-30 03:06:48 +00:00
end
meta:set_int("current_frame", framenum)
2019-10-01 23:28:03 +00:00
if framenum >= -MAX_SIZE then minetest.get_node_timer(pos):start(0.1) end
2019-09-30 01:49:55 +00:00
end
2019-09-30 05:30:56 +00:00
minetest.register_node( NAME .. ":quarry_marker", {
2019-09-30 01:49:55 +00:00
descritption = "quarry marker",
2019-09-30 05:10:03 +00:00
tiles = {
2019-10-04 00:41:29 +00:00
NAME .. "marker.png"
},
2019-10-04 00:41:29 +00:00
groups = { sparktech_techy = 1 },
2019-09-30 03:46:05 +00:00
after_place_node = marker_construct,
2019-09-30 01:49:55 +00:00
})
2019-09-30 05:30:56 +00:00
minetest.register_node( NAME .. ":static_strut", {
description = "supporting strut",
drawtype = "nodebox",
paramtype = "light",
connects_to = {
NAME .. ":static_strut",
NAME .. ":quarry_marker",
NAME .. ":lv_quarry"
},
2019-09-30 05:10:03 +00:00
tiles = {
2019-10-04 00:41:29 +00:00
NAME .. "_strut.png"
},
node_box = {
type = "connected",
fixed = {-0.2, -0.2, -0.2, 0.2, 0.2, 0.2},
connect_top = {-0.2, 0.2, -0.2, 0.2, 0.5, 0.2},
connect_bottom = {-0.2, -0.5, -0.2, 0.2, -0.2, 0.2},
connect_back = {-0.2, -0.2, 0.2, 0.2, 0.2, 0.5},
connect_right = {0.2, -0.2, -0.2, 0.5, 0.2, 0.2},
connect_front = {-0.2, -0.2, -0.5, 0.2, 0.2, -0.2},
connect_left = {-0.5, -0.2, -0.2, -0.2, 0.2, 0.2},
},
2019-10-04 00:41:29 +00:00
groups = { sparktech_techy = 1 }
2019-09-30 01:49:55 +00:00
})
2019-09-30 05:30:56 +00:00
minetest.register_node( NAME .. ":lv_quarry", {
2019-09-30 01:49:55 +00:00
description = "Electric Quarry",
tiles = {
2019-10-04 00:41:29 +00:00
NAME .. "_steel_sideplate.png",
NAME .. "_steel_sideplate.png",
NAME .. "_steel_sideplate.png",
NAME .. "_steel_sideplate.png",
NAME .. "_steel_backplate.png",
NAME .. "_quarry_frontplate.png"
2019-09-30 01:49:55 +00:00
},
paramtype2 = "facedir",
groups = {
2019-10-04 03:13:42 +00:00
sparktech_techy = WRENCHABLE,
sparktech_energy_type = ENERGY_CONSUMER,
sparktech_net_trigger = TRUE,
sparktech_energy_max = MAX_ENERGY,
sparktech_energy_wakeup = ENERGYCOST.mining
2019-09-30 01:49:55 +00:00
},
2019-09-30 03:06:48 +00:00
on_timer = timer_trigger,
2019-09-30 01:49:55 +00:00
2019-09-30 03:46:05 +00:00
after_place_node = on_construct,
2019-09-30 01:49:55 +00:00
2019-09-30 05:30:56 +00:00
--on_destruct = function(pos, player) player:get_meta():set_string(NAME .. ":quarry_pos" , "") end,
allow_metadata_inventory_put = function(_,_,_, stack) return stack:get_count() end,
2019-09-30 03:46:05 +00:00
allow_metadata_inventory_take = function(_, _, _, stack) return stack:get_count() end
2019-09-30 01:49:55 +00:00
})
2019-10-02 01:09:30 +00:00
minetest.register_craft({
output = NAME .. ":lv_quarry",
recipe = {
{ NAME .. ":static_strut", "sparktool:handdrill", NAME .. ":static_strut" },
{ NAME .. ":static_strut", "group:steel_chasis", NAME .. ":static_strut" },
{ NAME .. ":static_strut", "sparkcore:cable", NAME .. ":static_strut" }
}
})
minetest.register_craft({
output = NAME .. ":static_strut 16",
recipe = {
{ "group:steel_plate", "group:steel_plate", "group:steel_plate" },
{ "", "", "" },
{ "group:steel_plate", "group:steel_plate", "group:steel_plate" }
}
})