Compare commits

...

4 Commits

1 changed files with 179 additions and 91 deletions

View File

@ -1,11 +1,57 @@
local NAME = minetest.get_current_modname()
local ENERGYCOST = {
static_struts = 20,
static_strut = 20,
dynamic_struct = 24,
hardness_mod = 1
hardness_mod = 1,
mining_cost = 25,
}
local FORMSPEC = sparktech.add_inventory(32,8,
"list[current_name;quarry;0,0;32,4;]")
local FORMSPEC = sparktech.add_inventory(19.8,8,
"list[current_name;quarry;0,0;16,6;]")
local MAX_SIZE = 64
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 order(x, y) ---
--- Returns (smaller, bigger)
if x <= y then
return x, y
else
return y,x
end
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
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
local function on_construct(pos, player)
player:get_meta():set_string(NAME .. ":quarry_pos" , minetest.pos_to_string(pos))
@ -13,23 +59,30 @@ local function on_construct(pos, player)
local meta = minetest.get_meta(pos)
meta:set_string("formspec", FORMSPEC)
local inventory = meta:get_inventory()
inventory:set_size('quarry', 128)
inventory:set_size('quarry', 96)
end
local function dig_node(pos, quarrypos)
--[[ local node = minetest.get_node(pos)
local quarryinv = minetest.get_meta(pos):get_inventory()
minetest.debug(ItemStack(node.name):get_name())
local itemstack = ItemStack(nil)
itemstack:add_item(node.name)
minetest.debug(itemstack:to_string())
if quarryinv:room_for_item("quarry", itemstack) then
quarryinv:add_item("quarry", itemstack) ]]--
--
-- Pretend this puts items in the quarry inventory, okay?
minetest.set_node(pos, {name = "air"})
--end
local node = minetest.get_node(pos)
if node.name ~= "air" and try_drain_energy(quarrypos, ENERGYCOST.mining_cost) then
local quarry = minetest.get_meta(quarrypos)
local quarry_inv = quarry:get_inventory()
local drops = minetest.get_node_drops(node.name);
local drops_added = 0
for _, item in pairs(drops) do
if quarry_inv:add_item("quarry", item) then
drops_added = drops_added + 1
end
end
if drops_added ~= 0 or #drops == 0 then
minetest.set_node(pos, {name = "air"})
end
end
return node.name ~= "air"
end
local function on_marker_placed(pos, quarry_pos, player)
@ -42,12 +95,28 @@ local function on_marker_placed(pos, quarry_pos, player)
-- TODO clear clipboard in quarry on_break
end
-- TODO Possibly do a size check
local minx, maxx = order(pos.x, quarry_pos.x)
local miny, maxy = order(pos.y, quarry_pos.y)
local minz, maxz = 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")
-- minetest.chat_send_player(player:get_player_name(), "Invalid dimensions for quarry")
return
end
-- Set quarry metadata
local meta = minetest.get_meta(quarry_pos)
meta:set_string("marker", minetest.pos_to_string(pos))
meta:set_int("current_frame", 13)
meta:set_int("current_frame", 1)
minetest.get_node_timer(quarry_pos):start(1.0)
end
@ -58,14 +127,6 @@ local function marker_construct(pos, player)
on_marker_placed(pos, quarry_pos, player)
end
local function order(x, y)
if x <= y then
return x, y
else
return y,x
end
end
local function clear_area(pos, pos2)
local minx, maxx = order(pos.x, pos2.x)
local miny, maxy = order(pos.y, pos2.y)
@ -75,110 +136,137 @@ local function clear_area(pos, pos2)
for z=minz, maxz do
-- dont remove quarry or marker
if not ((x == pos.x and y == pos.y and z == pos.z) or
(x == pos2.x and y == pos2.y and z == pos2.z))
(x == pos2.x and y == pos2.y and z == pos2.z))
then
dig_node({x=x, y=y, z=z}, pos)
if dig_node(Position(x, y, z), pos) then
return false
end
end
end
end
end
return true
end
local function place_strut(x, y, z)
local position = { x=x, y=y, z=z }
local function place_strut(position, quarrypos)
if minetest.get_node(position).name == "air" then
minetest.set_node(position, { name = NAME .. ":static_strut"})
minetest.debug("PLACE")
if try_remove_item(quarrypos, "quarry", NAME .. ":static_strut") then
minetest.debug("ENERGY")
if try_drain_energy(quarrypos, ENERGYCOST.static_strut) then
minetest.debug("CONFIRM")
minetest.set_node(position, { name = NAME .. ":static_strut"})
else
-- Restore items
end
end
return true
end
return false
end
local function strut_line_x(x, y, z, x2)
local function strut_line_x(x, y, z, x2, quarrypos)
local minx, maxx = order(x, x2)
for x3=minx, maxx do
place_strut(x3, y, z)
if place_strut(Position(x3, y, z), quarrypos) then
return false
end
end
return true
end
local function strut_line_y(x, y, z, y2)
local function strut_line_y(x, y, z, y2, quarrypos)
local miny, maxy = order(y, y2)
for y3=miny, maxy do
place_strut(x, y3, z)
if place_strut(Position(x, y3, z), quarrypos) then
return false
end
end
return true
end
local function strut_line_z(x, y, z, z2)
local function strut_line_z(x, y, z, z2, quarrypos)
local minz, maxz = order(z, z2)
for z3=minz, maxz do
place_strut(x, y, z3)
if place_strut(Position(x, y, z3), quarrypos) then
return false
end
end
return true
end
local function timer_trigger(pos, elapsed)
local meta = minetest.get_meta(pos)
local framenum = meta:get_int("current_frame")
local marker_pos = minetest.string_to_pos(meta:get_string("marker"))
if not framenum then
framenum = 13
end
if framenum < 0 then
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
minetest.debug(start_pos.y .. ": " .. height)
for x=start_pos.x, end_pos.x do
for z=start_pos.z, end_pos.z do
dig_node({x, height, z}, pos)
while true do -- Make this section breakable
if framenum < 0 then
minetest.debug("Mine layer")
-- 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
minetest.debug("Next layer")
framenum = framenum - 1
end
end
-- Operation Phase
--
else
-- preparation phase
if framenum == 13 then -- stripmine area
clear_area(pos, marker_pos)
elseif framenum == 12 then
strut_line_x(pos.x, pos.y, pos.z, marker_pos.x)
elseif framenum == 11 then
strut_line_x(pos.x, marker_pos.y, pos.z, marker_pos.x)
elseif framenum == 10 then
strut_line_x(pos.x, pos.y, marker_pos.z, marker_pos.x)
elseif framenum == 9 then
strut_line_x(pos.x, marker_pos.y, marker_pos.z, marker_pos.x)
elseif framenum == 8 then
strut_line_z(pos.x, pos.y, pos.z, marker_pos.z)
elseif framenum == 7 then
strut_line_z(marker_pos.x, pos.y, pos.z, marker_pos.z)
elseif framenum == 6 then
strut_line_z(pos.x, marker_pos.y, pos.z, marker_pos.z)
elseif framenum == 5 then
strut_line_z(marker_pos.x, marker_pos.y, pos.z, marker_pos.z)
elseif framenum == 4 then
strut_line_y(marker_pos.x, pos.y, marker_pos.z, marker_pos.y)
elseif framenum == 3 then
strut_line_y(pos.x, pos.y, marker_pos.z, marker_pos.y)
elseif framenum == 2 then
strut_line_y(marker_pos.x, pos.y, pos.z, marker_pos.y)
elseif framenum == 1 then
strut_line_y(pos.x, pos.y, pos.z, marker_pos.y)
elseif framenum == 0 then
minetest.debug("Clear area")
-- preparation phase
if clear_area(pos, marker_pos) then
framenum = 0
end
else
minetest.debug("Build strats")
if not strut_line_x(pos.x, pos.y, pos.z, marker_pos.x, pos) then break end
if not strut_line_x(pos.x, marker_pos.y, pos.z, marker_pos.x, pos) then break end
if not strut_line_x(pos.x, pos.y, marker_pos.z, marker_pos.x, pos) then break end
if not strut_line_x(pos.x, marker_pos.y, marker_pos.z, marker_pos.x, pos) then break end
if not strut_line_z(pos.x, pos.y, pos.z, marker_pos.z, pos) then break end
if not strut_line_z(marker_pos.x, pos.y, pos.z, marker_pos.z, pos) then break end
if not strut_line_z(pos.x, marker_pos.y, pos.z, marker_pos.z, pos) then break end
if not strut_line_z(marker_pos.x, marker_pos.y, pos.z, marker_pos.z, pos) then break end
if not strut_line_y(marker_pos.x, pos.y, marker_pos.z, marker_pos.y, pos) then break end
if not strut_line_y(pos.x, pos.y, marker_pos.z, marker_pos.y, pos) then break end
if not strut_line_y(marker_pos.x, pos.y, pos.z, marker_pos.y, pos) then break end
if not strut_line_y(pos.x, pos.y, pos.z, marker_pos.y, pos) then break end
--shrink the operational area here to a 2d space with one piece of border taken away to drill there
--
local posx, pos2x = order(pos.x, marker_pos.x)
local posy, pos2y = order(pos.y, marker_pos.y)
local posz, pos2z = order(pos.z, marker_pos.z)
posx = posx +1
pos2x = pos2x -1
posy = posy + 1
pos2y = pos2y -1
meta:set_string("dig_area_start", minetest.pos_to_string({ x= posx, y= posy, z= posz}))
meta:set_string("dig_area_end", minetest.pos_to_string({ x= pos2x, y= posy, z= pos2z})) -- can use this last z as counter, or ignore it
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
minetest.debug("setup complete")
framenum = -1
end
end
meta:set_int("current_frame", framenum -1)
minetest.get_node_timer(pos):start(1.0)
break
end
meta:set_int("current_frame", framenum)
if framenum >= -MAX_SIZE then minetest.get_node_timer(pos):start(0.1) end
end
minetest.register_node( NAME .. ":quarry_marker", {
@ -246,6 +334,6 @@ minetest.register_node( NAME .. ":lv_quarry", {
after_place_node = on_construct,
--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,
allow_metadata_inventory_put = function(_,_,_, stack) return stack:get_count() end,
allow_metadata_inventory_take = function(_, _, _, stack) return stack:get_count() end
})