techage/basis/assemble.lua
2020-10-19 19:09:17 +02:00

127 lines
3.2 KiB
Lua

--[[
TechAge
=======
Copyright (C) 2019-2020 Joachim Stolberg
AGPL v3
See LICENSE.txt for more information
Assemble routines
]]--
-- for lazy programmers
local P = minetest.string_to_pos
local M = minetest.get_meta
local S = techage.S
techage.assemble = {}
local Face2Dir = {[0]=
{x=0, y=0, z=1},
{x=1, y=0, z=0},
{x=0, y=0, z=-1},
{x=-1, y=0, z=0},
{x=0, y=-1, z=0},
{x=0, y=1, z=0}
}
-- Determine the destination position based on the base position,
-- param2, and a route table like : {0,3}
-- 0 = forward, 1 = right, 2 = backward, 3 = left
local function dest_pos(pos, param2, route, y_offs)
local p2 = param2
local pos1 = {x=pos.x, y=pos.y+y_offs, z=pos.z}
for _,dir in ipairs(route) do
p2 = (param2 + dir) % 4
pos1 = vector.add(pos1, Face2Dir[p2])
end
return pos1, p2
end
-- timer based function
local function build(pos, param2, AssemblyPlan, idx)
local item = AssemblyPlan[idx]
if item ~= nil then
local y, path, fd_offs, node_name = item[1], item[2], item[3], item[4]
local pos1 = dest_pos(pos, param2, path, y)
minetest.add_node(pos1, {name=node_name, param2=(param2 + fd_offs) % 4})
minetest.after(0.5, build, pos, param2, AssemblyPlan, idx+1)
else
local nvm = techage.get_nvm(pos)
nvm.assemble_locked = false
end
end
-- timer based function
local function remove(pos, param2, AssemblyPlan, idx)
local item = AssemblyPlan[idx]
if item ~= nil then
local y, path = item[1], item[2]
local pos1 = dest_pos(pos, param2, path, y)
minetest.remove_node(pos1)
minetest.after(0.5, remove, pos, param2, AssemblyPlan, idx-1)
else
local nvm = techage.get_nvm(pos)
nvm.assemble_locked = false
end
end
local function check_space(pos, param2, AssemblyPlan, player_name)
for _,item in ipairs(AssemblyPlan) do
local y, path, node_name = item[1], item[2], item[4]
local pos1 = dest_pos(pos, param2, path, y)
if minetest.is_protected(pos1, player_name) then
minetest.chat_send_player(player_name, S("[TA] Area is protected!"))
return false
end
local node = techage.get_node_lvm(pos1)
local ndef = minetest.registered_nodes[node.name]
if not ndef or not ndef.buildable_to and node.name ~= node_name then
minetest.chat_send_player(player_name, S("[TA] Not enough space!"))
return false
end
end
return true
end
-- Two important flags:
-- 1) nvm.assemble_locked is true while the object is being assembled/disassembled
-- 2) nvm.assemble_build is true if the object is assembled
function techage.assemble.build(pos, AssemblyPlan, player_name)
-- check protection
if minetest.is_protected(pos, player_name) then
return
end
local nvm = techage.get_nvm(pos)
if nvm.assemble_locked then
return
end
local node = minetest.get_node(pos)
if check_space(pos, node.param2, AssemblyPlan, player_name) then
nvm.assemble_locked = true
build(pos, node.param2, AssemblyPlan, 1)
nvm.assemble_build = true
end
end
function techage.assemble.remove(pos, AssemblyPlan, player_name)
-- check protection
if minetest.is_protected(pos, player_name) then
return
end
local nvm = techage.get_nvm(pos)
if nvm.assemble_locked then
return
end
local node = minetest.get_node(pos)
nvm.assemble_locked = true
remove(pos, node.param2, AssemblyPlan, #AssemblyPlan)
nvm.assemble_build = false
end