182 lines
5.2 KiB
Lua
182 lines
5.2 KiB
Lua
--local dprint = townchest.dprint
|
|
local dprint = townchest.dprint_off --debug
|
|
|
|
local smartfs = townchest.smartfs
|
|
|
|
--------------------------------------
|
|
-- Chest class and interface
|
|
--------------------------------------
|
|
local chest = {}
|
|
townchest.chest = chest
|
|
local chest_class = {}
|
|
local chest_class_mt = {__index = chest_class}
|
|
|
|
--------------------------------------
|
|
-- object constructor
|
|
--------------------------------------
|
|
function chest.new()
|
|
return setmetatable({}, chest_class_mt)
|
|
end
|
|
|
|
--------------------------------------
|
|
-- Get or create new chest object for position
|
|
--------------------------------------
|
|
function chest.get(pos)
|
|
local key = "townchest:"..minetest.pos_to_string(pos)
|
|
local self = chest.new()
|
|
self.pos = pos
|
|
self.meta = minetest.get_meta(pos)
|
|
self.plan = schemlib.plan_manager.get_plan(key)
|
|
if not self.plan then
|
|
self.plan = schemlib.plan.new(key, pos)
|
|
schemlib.plan_manager.set_plan(self.plan)
|
|
end
|
|
self.info = self.plan.data
|
|
self.info.facedir = minetest.get_node(pos).param2
|
|
return self
|
|
end
|
|
|
|
--------------------------------------
|
|
-- Initialize new chest object
|
|
--------------------------------------
|
|
function chest.create(pos)
|
|
local key = "townchest:"..minetest.pos_to_string(pos)
|
|
schemlib.plan_manager.delete_plan(key)
|
|
local self = chest.get(pos)
|
|
return self
|
|
end
|
|
|
|
--------------------------------------
|
|
-- set_plan_form - set formspec to specific widget in plan processing chain
|
|
--------------------------------------
|
|
function chest_class:set_plan_form()
|
|
local status = self.plan:get_status()
|
|
if status == "finished" then -- no updates if finished
|
|
smartfs.get("townchest:build_finished"):attach_to_node(self.pos)
|
|
self.meta:set_string("infotext", "Building finished")
|
|
elseif status == "build" or status == "pause" then
|
|
smartfs.get("townchest:build_status"):attach_to_node(self.pos)
|
|
self.meta:set_string("infotext", "Plan size:"..self.info.nodecount)
|
|
elseif self.info.nodecount > 0 then
|
|
smartfs.get("townchest:configure"):attach_to_node(self.pos)
|
|
self.meta:set_string("infotext", "Configure - Plan size:"..self.info.nodecount)
|
|
else
|
|
smartfs.get("townchest:plan"):attach_to_node(self.pos)
|
|
self.meta:set_string("infotext", "please select a building plan")
|
|
end
|
|
end
|
|
|
|
--------------------------------------
|
|
-- Show message - set formspec to specific widget for 2 seconds
|
|
--------------------------------------
|
|
function chest_class:show_message(message, stop)
|
|
self.meta:set_string("infotext", message)
|
|
smartfs.get("townchest:status"):attach_to_node(self.pos)
|
|
|
|
if stop == false then
|
|
self:run_async(function(chest)
|
|
chest:set_plan_form()
|
|
end, 2)
|
|
end
|
|
end
|
|
|
|
--------------------------------------
|
|
-- update informations on formspecs during build process (called by nodetimer)
|
|
--------------------------------------
|
|
function chest_class:update_info()
|
|
local status = self.plan:get_status()
|
|
if status == "pause" and self.info.npc_build and self.info.nodecount == 0 then
|
|
self.info.npc_build = false
|
|
self.plan:set_status("finished")
|
|
end
|
|
if status == "build" or self.info.npc_build then
|
|
minetest.get_node_timer(self.pos):start(2)
|
|
end
|
|
if self.info.ui_updates then
|
|
self:set_plan_form()
|
|
end
|
|
end
|
|
|
|
--------------------------------------
|
|
-- Run chest method async
|
|
--------------------------------------
|
|
function chest_class:run_async(func, delay)
|
|
local function async_call(pos)
|
|
local key = "townchest:"..minetest.pos_to_string(pos)
|
|
local plan = schemlib.plan_manager.get_plan(key)
|
|
if not plan then
|
|
return
|
|
end
|
|
local chest = townchest.chest.get(pos)
|
|
if func(chest) then
|
|
chest:run_async(func, delay or 0.2)
|
|
end
|
|
end
|
|
|
|
minetest.after(delay or 0.2, async_call, self.pos)
|
|
end
|
|
|
|
--------------------------------------
|
|
-- Generate simple form
|
|
--------------------------------------
|
|
function chest_class:generate_simple_form()
|
|
local genblock = self.info.genblock
|
|
-- set directly instead of counting each step
|
|
self.info.min_pos = { x=1, y=1, z=1 }
|
|
self.info.max_pos = { x=genblock.x, y=genblock.y, z=genblock.z}
|
|
self.info.ground_y = 0
|
|
local filler_node = "default:cobble"
|
|
if genblock.variant == 1 then
|
|
for x = 1, genblock.x do
|
|
for y = 1, genblock.y do
|
|
for z = 1, genblock.z do
|
|
if x == 1 or x == genblock.x or
|
|
y == 1 or y == genblock.y or
|
|
z == 1 or z == genblock.z then
|
|
self.plan:add_node({x=x,y=y,z=z}, "air")
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
elseif genblock.variant == 2 then
|
|
-- Fill with stone
|
|
for x = 1, genblock.x do
|
|
for y = 1, genblock.y do
|
|
for z = 1, genblock.z do
|
|
self.plan:add_node({x=x,y=y,z=z}, filler_node)
|
|
end
|
|
end
|
|
end
|
|
|
|
elseif genblock.variant == 3 then
|
|
-- Build a box
|
|
for x = 1, genblock.x do
|
|
for y = 1, genblock.y do
|
|
for z = 1, genblock.z do
|
|
if x == 1 or x == genblock.x or
|
|
y == 1 or y == genblock.y or
|
|
z == 1 or z == genblock.z then
|
|
self.plan:add_node({x=x,y=y,z=z}, filler_node)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
-- build ground level under chest
|
|
self.info.ground_y = 1
|
|
|
|
-- Build a plate
|
|
elseif genblock.variant == 4 then
|
|
local y = self.info.min_pos.y
|
|
self.info.max_pos.y = self.info.min_pos.y
|
|
for x = 1, genblock.x do
|
|
for z = 1, genblock.z do
|
|
self.plan:add_node({x=x,y=y,z=z}, filler_node)
|
|
end
|
|
end
|
|
-- build ground level under chest
|
|
self.info.ground_y = 1
|
|
end
|
|
end
|