765 lines
28 KiB
Lua
765 lines
28 KiB
Lua
------------------------------------------
|
|
--Construct
|
|
--Adds a way for 3d recipes to be built
|
|
--and then when hit by a hammer on the
|
|
--it will convert to the the chosen construct
|
|
------------------------------------------
|
|
local Constructs = {}
|
|
local Reverting = {}
|
|
local nodeReg = minetest.register_node
|
|
local Alias = {}
|
|
local def = {}
|
|
local pipeworks = minetest.get_modpath("pipeworks")
|
|
--Hammer Metadata
|
|
--TL,TR,BL,BR,C,Recipe
|
|
------------------------------------------------------------
|
|
-- _ _ _______ _____ _ _____ _______ _____ ______ _____
|
|
--| | | |__ __|_ _| | |_ _|__ __|_ _| ____|/ ____|
|
|
--| | | | | | | | | | | | | | | | | |__ | (___
|
|
--| | | | | | | | | | | | | | | | | __| \___ \
|
|
--| |__| | | | _| |_| |____ _| |_ | | _| |_| |____ ____) |
|
|
-- \____/ |_| |_____|______|_____| |_| |_____|______|_____/
|
|
--
|
|
------------------------------------------------------------
|
|
function register_construct_alias(from, to)
|
|
Alias[from] = to
|
|
end
|
|
local function register_construct(name, wear, r, b)
|
|
Constructs[name] = {recipe=r, build=b, wear=wear}
|
|
end
|
|
|
|
local function parseMetadata(tool)
|
|
local data = tool:get_metadata()
|
|
if data == "" then data = "00100construct:furnace" end
|
|
local m = {
|
|
TL = data:sub(1,1),
|
|
TR = data:sub(2,2),
|
|
BL = data:sub(3,3),
|
|
BR = data:sub(4,4),
|
|
C = data:sub(5,5),
|
|
Recipe = data:sub(6),
|
|
}
|
|
--print(m.TL..m.TR..m.BL..m.BR..m.C..m.Recipe)
|
|
return m
|
|
end
|
|
local function hacky_swap_node(pos,name)
|
|
local node = minetest.env:get_node(pos)
|
|
local meta = minetest.env:get_meta(pos)
|
|
local meta0 = meta:to_table()
|
|
if node.name == name then
|
|
return
|
|
end
|
|
node.name = name
|
|
local meta0 = meta:to_table()
|
|
minetest.env:set_node(pos,node)
|
|
meta = minetest.env:get_meta(pos)
|
|
meta:from_table(meta0)
|
|
end
|
|
local function setConstructFormspec(start, name, str)
|
|
local env = minetest.env
|
|
local recipe = Constructs[name]
|
|
local l,w,h = #recipe.recipe,#recipe.recipe[1][1],#recipe.recipe[1]
|
|
local meta
|
|
for z=1,l do
|
|
for y=1,h do
|
|
for x=1,w do
|
|
meta = env:get_meta({x=start.x+x-1,y=start.y+y-1,z=start.z+z-1})
|
|
meta:set_string("formspec", str)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
------------------------------------------------------------
|
|
-- ______ ____ _____ __ __ _____ _____ ______ _____ _____
|
|
--| ____/ __ \| __ \| \/ |/ ____| __ \| ____/ ____|/ ____|
|
|
--| |__ | | | | |__) | \ / | (___ | |__) | |__ | | | (___
|
|
--| __|| | | | _ /| |\/| |\___ \| ___/| __|| | \___ \
|
|
--| | | |__| | | \ \| | | |____) | | | |___| |____ ____) |
|
|
--|_| \____/|_| \_\_| |_|_____/|_| |______\_____|_____/
|
|
--
|
|
------------------------------------------------------------
|
|
local function showHammerFormspec(tool)
|
|
local meta = parseMetadata(tool)
|
|
return "size[3,4]button[0,0;1,1;topleft;"..meta.TL.."]button[2,0;1,1;topright;"..meta.TR.."]"..
|
|
"button[1,1;1,1;center;"..meta.C.."]button[0,2;1,1;botleft;"..meta.BL.."]button[2,2;1,1;botright;"..meta.BR.."]"..
|
|
"button[0,3;3,1;recipe;"..meta.Recipe.."]"
|
|
end
|
|
local function showRecipeList()
|
|
local row = 6
|
|
local width = 3
|
|
local col = math.floor(#Constructs/row)+1
|
|
local str = "size["..(width*col)..","..row.."]"
|
|
local x,y = 0,0
|
|
for recipe,_ in pairs(Constructs) do
|
|
str = str.."button["..x..","..y..";"..width..",1;"..recipe..";"..recipe:sub(11).."]"
|
|
y=y+1
|
|
if y == row-1 then y=0 x=x+1 end
|
|
end
|
|
return str
|
|
end
|
|
------------------------------------------------------------
|
|
-- _ _____ ____ _____ _____ _______ _ _ __ __ _____
|
|
-- /\ | | / ____|/ __ \| __ \|_ _|__ __| | | | \/ |/ ____|
|
|
-- / \ | | | | __| | | | |__) | | | | | | |__| | \ / | (___
|
|
-- / /\ \ | | | | |_ | | | | _ / | | | | | __ | |\/| |\___ \
|
|
-- / ____ \| |___| |__| | |__| | | \ \ _| |_ | | | | | | | | |____) |
|
|
--/_/ \_\______\_____|\____/|_| \_\_____| |_| |_| |_|_| |_|_____/
|
|
|
|
------------------------------------------------------------
|
|
local function revertConstruct(start, destroyed, recipe)
|
|
local r = Constructs[recipe]
|
|
if r == nil then return end
|
|
Reverting[minetest.pos_to_string(start)] = 1
|
|
local env = minetest.env
|
|
local l,w,h = #r.recipe,#r.recipe[1][1],#r.recipe[1]
|
|
local pos
|
|
for z=1,l do
|
|
for y=1,h do
|
|
for x=1,w do
|
|
pos = {x=start.x+x-1,y=start.y+y-1,z=start.z+z-1}
|
|
if pos ~= destroyed then
|
|
env:set_node(pos, {name=r.recipe[z][y][x]})
|
|
end
|
|
end
|
|
end
|
|
end
|
|
Reverting[minetest.pos_to_string(start)] = nil
|
|
end
|
|
local function createConstruct(player, start, recipe)
|
|
local r = Constructs[recipe]
|
|
if r == nil then return end
|
|
local env = minetest.env
|
|
local i=1
|
|
local pos
|
|
local l,w,h = #r.recipe,#r.recipe[1][1],#r.recipe[1]
|
|
local meta
|
|
for z=1,l do
|
|
for y=1,h do
|
|
for x=1,w do
|
|
pos = {x=start.x+x-1,y=start.y+y-1,z=start.z+z-1}
|
|
if r.build[i].name ~= "air" then
|
|
meta = env:get_meta(pos)
|
|
env:set_node(pos, r.build[i])
|
|
meta:set_int("x", start.x)
|
|
meta:set_int("y", start.y)
|
|
meta:set_int("z", start.z)
|
|
else
|
|
env:set_node(pos, {name="air"})
|
|
end
|
|
i = i+1
|
|
end
|
|
end
|
|
end
|
|
local tool = player:get_wielded_item()
|
|
tool:add_wear(r.wear)
|
|
player:set_wielded_item(tool)
|
|
end
|
|
local function checkRecipe(tool,pos,player)
|
|
if pos == nil then return end
|
|
local env = minetest.env
|
|
local node = env:get_node(pos)
|
|
local meta = parseMetadata(tool)
|
|
local recipe = Constructs[meta.Recipe]
|
|
if recipe == "" or recipe == nil or recipe == {} then return end
|
|
local l,w,h = #recipe.recipe,#recipe.recipe[1][1],#recipe.recipe[1]
|
|
local dx,dy,dz = 0,0,0
|
|
local px,py,pz = 1,1,1
|
|
--Bottom Left is desired start position
|
|
if meta.TR == "1" then dx = -(w-1) px = -1 dy = -(h-1) py = -1 end
|
|
if meta.TL == "1" then dy = -(h-1) py = -1 end
|
|
if meta.BR == "1" then dx = -(w-1) px = -1 end
|
|
if meta.C == "1" then dz = -(l-1) pz = -1 end
|
|
local zero = {x=0,y=0,z=0}
|
|
minetest.add_particle({x=pos.x-(px*0.6),y=pos.y,z=pos.z}, zero, zero, 1, 2, false, "construct_trail.png", player:get_player_name())
|
|
minetest.add_particle({x=pos.x,y=pos.y-(py*0.6),z=pos.z}, zero, zero, 1, 2, false, "construct_trail.png", player:get_player_name())
|
|
minetest.add_particle({x=pos.x,y=pos.y,z=pos.z-(pz*0.6)}, zero, zero, 1, 2, false, "construct_trail.png", player:get_player_name())
|
|
local start = {x=pos.x+dx,y=pos.y+dy,z=pos.z+dz}
|
|
local name
|
|
for z=1,l do
|
|
for y=1,h do
|
|
for x=1,w do
|
|
node = env:get_node({x=start.x+x-1,y=start.y+y-1,z=start.z+z-1})
|
|
name = recipe.recipe[z][y][x]
|
|
if node.name ~= name and Alias[node.name] ~= name then return false end
|
|
end
|
|
end
|
|
end
|
|
return true
|
|
end
|
|
------------------------------------------------------------
|
|
-- _______ ____ ____ _ _____
|
|
-- |__ __/ __ \ / __ \| | / ____|
|
|
-- | | | | | | | | | | | (___
|
|
-- | | | | | | | | | | \___ \
|
|
-- | | | |__| | |__| | |____ ____) |
|
|
-- |_| \____/ \____/|______|_____/
|
|
--
|
|
------------------------------------------------------------
|
|
minetest.register_tool("construct:hammer", {
|
|
description = "Construction Hammer",
|
|
inventory_image = "construct_tool_hammer.png",
|
|
on_place = function(itemstack, placer, pointed_thing)
|
|
minetest.show_formspec(placer:get_player_name(), "construct:hammer", showHammerFormspec(itemstack))
|
|
end,
|
|
on_use = function(itemstack, user, pointed_thing)
|
|
if checkRecipe(itemstack, pointed_thing.under, user) then
|
|
local meta = parseMetadata(itemstack)
|
|
local recipe = Constructs[meta.Recipe]
|
|
local l,w,h = #recipe.recipe,#recipe.recipe[1][1],#recipe.recipe[1]
|
|
local dx,dy,dz = 0,0,0
|
|
local px,py,pz = 1,1,1
|
|
--Bottom Left is desired start position
|
|
if meta.TR == "1" then dx = -(w-1) px = -1 dy = -(h-1) py = -1 end
|
|
if meta.TL == "1" then dy = -(h-1) py = -1 end
|
|
if meta.BR == "1" then dx = -(w-1) px = -1 end
|
|
if meta.C == "1" then dz = -(l-1) pz = -1 end
|
|
local start = {x=pointed_thing.under.x+dx,y=pointed_thing.under.y+dy,z=pointed_thing.under.z+dz}
|
|
createConstruct(user, start, meta.Recipe)
|
|
itemstack:add_wear(Constructs[meta.Recipe].wear)
|
|
return itemstack
|
|
end
|
|
return nil
|
|
end,
|
|
})
|
|
minetest.register_craft({
|
|
output = "construct:hammer",
|
|
recipe = {
|
|
{"","default:steel_ingot",""},
|
|
{"default:steel_ingot","default:stick","default:steel_ingot"},
|
|
{"","default:stick",""},
|
|
},
|
|
})
|
|
------------------------------------------------------------
|
|
-- _____ ______ _____ _____ _____ _______ ______ _____ _____
|
|
--| __ \| ____/ ____|_ _|/ ____|__ __| ____| __ \ / ____|
|
|
--| |__) | |__ | | __ | | | (___ | | | |__ | |__) | (___
|
|
--| _ /| __|| | |_ | | | \___ \ | | | __| | _ / \___ \
|
|
--| | \ \| |___| |__| |_| |_ ____) | | | | |____| | \ \ ____) |
|
|
--|_| \_\______\_____|_____|_____/ |_| |______|_| \_\_____/
|
|
--
|
|
------------------------------------------------------------
|
|
minetest.register_on_player_receive_fields(function(player, formname, fields)
|
|
if formname ~= "construct:hammer" then return false end
|
|
local tool = player:get_wielded_item()
|
|
local meta = parseMetadata(tool)
|
|
if fields.topleft then meta.TL,meta.TR,meta.BL,meta.BR = 1,0,0,0 end
|
|
if fields.topright then meta.TL,meta.TR,meta.BL,meta.BR = 0,1,0,0 end
|
|
if fields.botleft then meta.TL,meta.TR,meta.BL,meta.BR = 0,0,1,0 end
|
|
if fields.botright then meta.TL,meta.TR,meta.BL,meta.BR = 0,0,0,1 end
|
|
if fields.center then if meta.C == "0" then meta.C = "1" else meta.C = "0" end end
|
|
if fields.recipe then minetest.show_formspec(player:get_player_name(), "construct:hammer", showRecipeList()) return end
|
|
for recipe,_ in pairs(Constructs) do
|
|
if fields[recipe] then meta.Recipe = recipe end
|
|
end
|
|
local ttool = tool:to_table()
|
|
ttool.metadata = meta.TL..meta.TR..meta.BL..meta.BR..meta.C..meta.Recipe
|
|
player:set_wielded_item(ttool)
|
|
minetest.show_formspec(player:get_player_name(), "construct:hammer", showHammerFormspec(player:get_wielded_item()))
|
|
return true
|
|
end)
|
|
------------------------------------------------------------
|
|
-- _____ _______ ____ _____ _ _______ _____ _ ______
|
|
-- / ____|__ __/ __ \ / ____| |/ / __ \_ _| | | ____|
|
|
--| (___ | | | | | | | | ' /| |__) || | | | | |__
|
|
-- \___ \ | | | | | | | | < | ___/ | | | | | __|
|
|
-- ____) | | | | |__| | |____| . \| | _| |_| |____| |____
|
|
--|_____/ |_| \____/ \_____|_|\_\_| |_____|______|______|
|
|
--
|
|
------------------------------------------------------------
|
|
local function getStockpileFormspec(meta, page)
|
|
local str = "size[8,9]"..
|
|
"list[current_player;main;0,5;8,4;]"..
|
|
"button[3,4.125;.75,.75;previous;<]label[3.8,4.125;"..(math.floor(page/32)+1).."]button[4.25,4.125;.75,.75;next;>]"..
|
|
"button[7.325,4.125;.6,.75;linear;=]button[6.75,4.125;.6,.75;vertical;||]"
|
|
if meta == nil then
|
|
str = str.."list[context;main;0,0;8,4;"..page.."]"
|
|
else
|
|
str = str.."list[nodemeta:"..meta:get_int("x")..","..meta:get_int("y")..","..meta:get_int("z")..";main;0,0;8,4;"..page.."]"
|
|
end
|
|
return str
|
|
end
|
|
local function GeneralSort(pos)
|
|
local meta = minetest.env:get_meta(pos)
|
|
local inv = meta:to_table().inventory.main
|
|
table.sort(inv, function(a,b)
|
|
if a:is_empty() then return false end
|
|
if b:is_empty() then return true end
|
|
if a:get_name()==b:get_name() then
|
|
return a:get_count()>b:get_count()
|
|
end
|
|
return a:get_name()<b:get_name()
|
|
end)
|
|
return inv
|
|
end
|
|
local function LinearSort(meta, list)
|
|
meta:get_inventory():set_list("main", list)
|
|
end
|
|
local function VerticalSort(meta, list)
|
|
local inv = meta:get_inventory()
|
|
local i,x,y,page = 1,0,1,0
|
|
while page<2 do
|
|
while x<8 do
|
|
inv:set_stack("main", y+x+(page*32), list[i])
|
|
i=i+1
|
|
if y>=25 then
|
|
y=1
|
|
x=x+1
|
|
else
|
|
y=y+8
|
|
end
|
|
end
|
|
page = page+1
|
|
x = 0
|
|
y = 1
|
|
end
|
|
end
|
|
register_construct("construct:stockpile", 500,
|
|
{{{"default:wood","default:wood"},{"default:wood","default:wood"}},{{"default:wood","default:wood"},{"default:wood","default:wood"}}},
|
|
{{name="construct:stockpile_source", param2=0},{name="construct:stockpile_corner", param2=3},
|
|
{name="construct:stockpile_corner", param2=23},{name="construct:stockpile_corner", param2=20},
|
|
{name="construct:stockpile_corner", param2=1},{name="construct:stockpile_corner", param2=2},
|
|
{name="construct:stockpile_corner", param2=22},{name="construct:stockpile_corner", param2=21}})
|
|
def = {description = "Stockpile",
|
|
tiles = {"construct_stockpile_top.png","construct_stockpile_top.png","construct_stockpile_top.png","construct_stockpile_side2.png","construct_stockpile_top.png","construct_stockpile_side.png"},
|
|
groups = {choppy=2,oddly_breakable_by_hand=2, not_in_creative_inventory=1},
|
|
sounds = default.node_sound_wood_defaults(),
|
|
drop = "default:wood",
|
|
paramtype2 = "facedir",
|
|
on_construct = function(pos)
|
|
local meta = minetest.env:get_meta(pos)
|
|
meta:set_string("formspec", getStockpileFormspec(nil, 0))
|
|
meta:set_string("infotext", "Stockpile")
|
|
local inv = meta:get_inventory()
|
|
inv:set_size("main", 64)
|
|
end,
|
|
on_destruct = function(pos)
|
|
if Reverting[minetest.pos_to_string(pos)] == 1 then return end
|
|
revertConstruct(pos, pos, "construct:stockpile")
|
|
end,
|
|
can_dig = function(pos,player)
|
|
return minetest.env:get_meta(pos):get_inventory():is_empty("main")
|
|
end,
|
|
on_receive_fields = function(pos, formname, fields, sender)
|
|
local meta = minetest.env:get_meta(pos)
|
|
if fields.linear then
|
|
LinearSort(meta, GeneralSort(pos))
|
|
end
|
|
if fields.vertical then
|
|
VerticalSort(meta, GeneralSort(pos))
|
|
end
|
|
if fields.next then
|
|
setConstructFormspec(pos, "construct:stockpile", getStockpileFormspec(nil, 32))
|
|
end
|
|
if fields.previous then
|
|
setConstructFormspec(pos, "construct:stockpile", getStockpileFormspec(nil, 0))
|
|
end
|
|
end,
|
|
}
|
|
if pipeworks ~= nil then
|
|
def.groups.tubedevice=1
|
|
def.groups.tubedevice_receiver=1
|
|
def.tube = {
|
|
insert_object=function(pos,node,stack,direction)
|
|
local meta=minetest.env:get_meta(pos)
|
|
local inv=meta:get_inventory()
|
|
return inv:add_item("main",stack)
|
|
end,
|
|
can_insert=function(pos,node,stack,direction)
|
|
local meta=minetest.env:get_meta(pos)
|
|
local inv=meta:get_inventory()
|
|
return inv:room_for_item("main",stack)
|
|
end,
|
|
input_inventory="main"
|
|
}
|
|
def.after_place_node = function(pos)
|
|
tube_scanforobjects(pos)
|
|
end
|
|
def.after_dig_node = function(pos)
|
|
tube_scanforobjects(pos)
|
|
end
|
|
end
|
|
nodeReg("construct:stockpile_source", def)
|
|
local function register_stockpile_meta(pos)
|
|
local meta = minetest.env:get_meta(pos)
|
|
meta:set_string("formspec", getStockpileFormspec(meta, 0))
|
|
meta:set_string("infotext", "Stockpile")
|
|
meta:get_inventory():set_size("main", 64)
|
|
end
|
|
def.on_construct = function(pos)
|
|
minetest.after(.5, register_stockpile_meta, pos)
|
|
end
|
|
def.on_destruct = function(pos)
|
|
local meta = minetest.env:get_meta(pos)
|
|
local start = {x=meta:get_int("x"),y=meta:get_int("y"),z=meta:get_int("z")}
|
|
if Reverting[minetest.pos_to_string(start)] == 1 then return end
|
|
revertConstruct(start, pos, "construct:stockpile")
|
|
end
|
|
def.can_dig = function(pos,player)
|
|
local meta = minetest.env:get_meta(pos)
|
|
local inv = minetest.get_inventory({type="node", pos={x=meta:get_int("x"),y=meta:get_int("y"),z=meta:get_int("z")}})
|
|
return inv:is_empty("main")
|
|
end
|
|
def.on_receive_fields = function(pos, formname, fields, sender)
|
|
local meta = minetest.env:get_meta(pos)
|
|
local spos = {x=meta:get_int("x"),y=meta:get_int("y"),z=meta:get_int("z")}
|
|
local inv = GeneralSort(spos)
|
|
if fields.linear then
|
|
LinearSort(minetest.env:get_meta(spos), inv)
|
|
end
|
|
if fields.vertical then
|
|
VerticalSort(minetest.env:get_meta(spos), inv)
|
|
end
|
|
if fields.next then
|
|
setConstructFormspec({x=meta:get_int("x"),y=meta:get_int("y"),z=meta:get_int("z")}, "construct:stockpile", getStockpileFormspec(meta, 32))
|
|
end
|
|
if fields.previous then
|
|
setConstructFormspec({x=meta:get_int("x"),y=meta:get_int("y"),z=meta:get_int("z")}, "construct:stockpile", getStockpileFormspec(meta, 0))
|
|
end
|
|
end
|
|
if pipeworks ~= nil then
|
|
def.tube = {
|
|
insert_object=function(pos,node,stack,direction)
|
|
local meta = minetest.env:get_meta(pos)
|
|
local metapos = {x=meta:get_int("x"),y=meta:get_int("y"),z=meta:get_int("z")}
|
|
local inv = minetest.env:get_meta(metapos):get_inventory()
|
|
return inv:add_item("main",stack)
|
|
end,
|
|
can_insert=function(pos,node,stack,direction)
|
|
local meta=minetest.env:get_meta(pos)
|
|
local metapos = {x=meta:get_int("x"),y=meta:get_int("y"),z=meta:get_int("z")}
|
|
local inv = minetest.env:get_meta(metapos):get_inventory()
|
|
return inv:room_for_item("main",stack)
|
|
end,
|
|
input_inventory="main"
|
|
}
|
|
end
|
|
nodeReg("construct:stockpile_corner", def)
|
|
------------------------------------------------------------
|
|
-- ______ _ _ _____ _ _ _____ ______
|
|
--| ____| | | | __ \| \ | | /\ / ____| ____|
|
|
--| |__ | | | | |__) | \| | / \ | | | |__
|
|
--| __| | | | | _ /| . ` | / /\ \| | | __|
|
|
--| | | |__| | | \ \| |\ |/ ____ \ |____| |____
|
|
--|_| \____/|_| \_\_| \_/_/ \_\_____|______|
|
|
--
|
|
------------------------------------------------------------
|
|
register_construct("construct:furnace", 5000,
|
|
{{{"default:cobble","default:cobble","default:cobble"},{"default:cobble","default:cobble","default:cobble"},{"default:cobble","default:cobble","default:cobble"}},
|
|
{{"default:cobble","default:cobble","default:cobble"},{"default:cobble","default:torch","default:cobble"},{"default:cobble","default:cobble","default:cobble"}},
|
|
{{"default:cobble","default:cobble","default:cobble"},{"default:cobble","default:cobble","default:cobble"},{"default:cobble","default:cobble","default:cobble"}}},
|
|
{{name="construct:furnace_source", param2=0},{name="construct:furnace_side", param2=0},{name="construct:furnace_side", param2=0},
|
|
{name="construct:furnace_side", param2=0},{name="construct:furnace_idle", param2=0},{name="construct:furnace_side", param2=0},
|
|
{name="construct:furnace_side", param2=0},{name="construct:furnace_side", param2=0},{name="construct:furnace_side", param2=0},
|
|
{name="construct:furnace_side", param2=0},{name="construct:furnace_side", param2=0},{name="construct:furnace_side", param2=0},
|
|
{name="construct:furnace_idle", param2=0},{name="air", param2=0},{name="construct:furnace_idle", param2=0},
|
|
{name="construct:furnace_side", param2=0},{name="construct:furnace_side", param2=0},{name="construct:furnace_side", param2=0},
|
|
{name="construct:furnace_side", param2=0},{name="construct:furnace_side", param2=0},{name="construct:furnace_side", param2=0},
|
|
{name="construct:furnace_side", param2=0},{name="construct:furnace_idle", param2=0},{name="construct:furnace_side", param2=0},
|
|
{name="construct:furnace_side", param2=0},{name="construct:furnace_side", param2=0},{name="construct:furnace_side", param2=0}})
|
|
local furnace_formspec = function(pos, percent)
|
|
local str = "size[8,9]list[current_player;main;0,5;8,4;]"
|
|
if pos==nil then
|
|
str = str.."list[context;fuel;2,3;1,1;]"..
|
|
"list[context;src;2,1;1,1;]"..
|
|
"list[context;dst;5,1;2,2;]"
|
|
else
|
|
str = str.."list[nodemeta:"..pos..";fuel;2,3;1,1;]"..
|
|
"list[nodemeta:"..pos..";src;2,1;1,1;]"..
|
|
"list[nodemeta:"..pos..";dst;5,1;2,2;]"
|
|
end
|
|
if percent > 0 then
|
|
str = str.."image[2,2;1,1;default_furnace_fire_bg.png^[lowpart:"..(100-percent)..":default_furnace_fire_fg.png]"
|
|
else
|
|
str = str.."image[2,2;1,1;default_furnace_fire_bg.png]"
|
|
end
|
|
return str
|
|
end
|
|
def = {description = "Furnace",
|
|
tiles = {"construct_furnace_top.png","construct_furnace_top.png","construct_furnace_side.png","construct_furnace_side.png","construct_furnace_side.png","construct_furnace_side.png"},
|
|
groups = {choppy=2,oddly_breakable_by_hand=2, not_in_creative_inventory=1,tubedevice=1,tubedevice_receiver=1},
|
|
paramtype = "none",
|
|
light_source = 0,
|
|
sounds = default.node_sound_wood_defaults(),
|
|
drop = "default:cobble",
|
|
on_construct = function(pos)
|
|
local meta = minetest.env:get_meta(pos)
|
|
meta:set_string("formspec", furnace_formspec(nil, 0))
|
|
meta:set_string("infotext", "Furnace")
|
|
local inv = meta:get_inventory()
|
|
inv:set_size("fuel", 1)
|
|
inv:set_size("src", 1)
|
|
inv:set_size("dst", 4)
|
|
meta:set_float("fuel", 0.0)
|
|
end,
|
|
can_dig = function(pos,player)
|
|
local meta = minetest.env:get_meta(pos)
|
|
local inv = meta:get_inventory()
|
|
if inv:is_empty("fuel") and inv:is_empty("dst") and inv:is_empty("src") then
|
|
local start = {x=meta:get_int("x"),y=meta:get_int("y"),z=meta:get_int("z")}
|
|
if Reverting[minetest.pos_to_string(start)] == 1 then return end
|
|
revertConstruct(start, pos, "construct:furnace")
|
|
return true
|
|
else
|
|
return false
|
|
end
|
|
end,
|
|
on_dig = function(pos, node, digger)
|
|
if digger == nil then return end
|
|
minetest.node_dig(pos, node, digger)
|
|
end,
|
|
allow_metadata_inventory_put = function(pos, listname, index, stack, player)
|
|
local meta = minetest.env:get_meta(pos)
|
|
local inv = meta:get_inventory()
|
|
if listname == "fuel" then
|
|
if minetest.get_craft_result({method="fuel",width=1,items={stack}}).time ~= 0 then
|
|
if inv:is_empty("src") then
|
|
meta:set_string("infotext","Furnace is empty")
|
|
end
|
|
return stack:get_count()
|
|
else
|
|
return 0
|
|
end
|
|
elseif listname == "src" then
|
|
return stack:get_count()
|
|
elseif listname == "dst" then
|
|
return 0
|
|
end
|
|
end,
|
|
allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
|
|
local meta = minetest.env:get_meta(pos)
|
|
local inv = meta:get_inventory()
|
|
local stack = inv:get_stack(from_list, from_index)
|
|
if to_list == "fuel" then
|
|
if minetest.get_craft_result({method="fuel",width=1,items={stack}}).time ~= 0 then
|
|
if inv:is_empty("src") then
|
|
meta:set_string("infotext","Furnace is empty")
|
|
end
|
|
return count
|
|
else
|
|
return 0
|
|
end
|
|
elseif to_list == "src" then
|
|
return count
|
|
elseif to_list == "dst" then
|
|
return 0
|
|
end
|
|
end,
|
|
}
|
|
if pipeworks ~= nil then
|
|
def.tube = {
|
|
insert_object=function(pos,node,stack,direction)
|
|
local meta=minetest.env:get_meta(pos)
|
|
local inv=meta:get_inventory()
|
|
if direction.y==1 then
|
|
return inv:add_item("fuel",stack)
|
|
else
|
|
return inv:add_item("src",stack)
|
|
end
|
|
end,
|
|
can_insert=function(pos,node,stack,direction)
|
|
local meta=minetest.env:get_meta(pos)
|
|
local inv=meta:get_inventory()
|
|
if direction.y==1 then
|
|
return inv:room_for_item("fuel",stack)
|
|
elseif direction.y==-1 then
|
|
return inv:room_for_item("src",stack)
|
|
else
|
|
return 0
|
|
end
|
|
end,
|
|
input_inventory="dst"
|
|
}
|
|
def.after_place_node = function(pos)
|
|
tube_scanforobjects(pos)
|
|
end
|
|
def.after_dig_node = function(pos)
|
|
tube_scanforobjects(pos)
|
|
end
|
|
end
|
|
nodeReg("construct:furnace_source", def)
|
|
local function register_furnace_meta(pos)
|
|
local meta = minetest.env:get_meta(pos)
|
|
local metapos = meta:get_int("x")..","..meta:get_int("y")..","..meta:get_int("z")
|
|
meta:set_string("formspec", furnace_formspec(metapos, 0))
|
|
meta:set_string("infotext", "Furnace is empty")
|
|
local inv = meta:get_inventory()
|
|
inv:set_size("fuel", 1)
|
|
inv:set_size("src", 1)
|
|
inv:set_size("dst", 4)
|
|
end
|
|
def.on_construct = function(pos)
|
|
minetest.after(.5, register_furnace_meta, pos)
|
|
end
|
|
def.can_dig = function(pos,player)
|
|
local meta = minetest.env:get_meta(pos)
|
|
local start = {x=meta:get_int("x"),y=meta:get_int("y"),z=meta:get_int("z")}
|
|
local inv = minetest.get_inventory({type="node", pos=start})
|
|
if inv:is_empty("fuel")==true and inv:is_empty("dst")==true and inv:is_empty("src")==true then
|
|
if Reverting[minetest.pos_to_string(start)] == 1 then return false end
|
|
revertConstruct(start, pos, "construct:furnace")
|
|
return true
|
|
else
|
|
return false
|
|
end
|
|
end
|
|
if pipeworks ~= nil then
|
|
def.tube = {
|
|
insert_object=function(pos,node,stack,direction)
|
|
local meta=minetest.env:get_meta(pos)
|
|
local start = {x=meta:get_int("x"),y=meta:get_int("y"),z=meta:get_int("z")}
|
|
local inv = minetest.get_inventory({type="node", pos=start})
|
|
if direction.y==1 then
|
|
return inv:add_item("fuel",stack)
|
|
else
|
|
return inv:add_item("src",stack)
|
|
end
|
|
end,
|
|
can_insert=function(pos,node,stack,direction)
|
|
local meta=minetest.env:get_meta(pos)
|
|
local start = {x=meta:get_int("x"),y=meta:get_int("y"),z=meta:get_int("z")}
|
|
local inv = minetest.get_inventory({type="node", pos=start})
|
|
if direction.y==1 then
|
|
return inv:room_for_item("fuel",stack)
|
|
elseif direction.y==-1 then
|
|
return inv:room_for_item("src",stack)
|
|
else
|
|
return 0
|
|
end
|
|
end,
|
|
input_inventory="dst"
|
|
}
|
|
end
|
|
nodeReg("construct:furnace_side", def)
|
|
def.tiles = {"construct_furnace_top.png","construct_furnace_top.png","construct_furnace_front.png","construct_furnace_front.png","construct_furnace_front.png","construct_furnace_front.png"}
|
|
nodeReg("construct:furnace_idle", def)
|
|
def.tiles = {"construct_furnace_top.png","construct_furnace_top.png","construct_furnace_front_active.png","construct_furnace_front_active.png","construct_furnace_front_active.png","construct_furnace_front_active.png"}
|
|
def.paramtype = "light"
|
|
def.light_source = 8
|
|
nodeReg("construct:furnace_active", def)
|
|
local function swap_furnace_nodes(pos, percent, infotext, active)
|
|
local recipe = Constructs["construct:furnace"]
|
|
local l,w,h = #recipe.recipe,#recipe.recipe[1][1],#recipe.recipe[1]
|
|
local meta, metapos, currpos
|
|
local i = 0
|
|
for z=1,l do
|
|
for y=1,h do
|
|
for x=1,w do
|
|
currpos = {x=pos.x+x-1,y=pos.y+y-1,z=pos.z+z-1}
|
|
meta = minetest.env:get_meta(currpos)
|
|
metapos = pos.x..","..pos.y..","..pos.z
|
|
meta:set_string("infotext",infotext)
|
|
if i==4 or i==12 or i==14 or i==22 then
|
|
if active == 0 then
|
|
hacky_swap_node(currpos,"construct:furnace_idle")
|
|
else
|
|
hacky_swap_node(currpos,"construct:furnace_active")
|
|
end
|
|
end
|
|
if percent > 0 and active == 1 then
|
|
meta:set_string("formspec", furnace_formspec(metapos, percent))
|
|
else
|
|
meta:set_string("formspec", furnace_formspec(metapos, 0))
|
|
end
|
|
i = i+1
|
|
end
|
|
end
|
|
end
|
|
end
|
|
minetest.register_abm({
|
|
nodenames = {"construct:furnace_source"},
|
|
interval = 1.0,
|
|
chance = 1,
|
|
action = function(pos, node, active_object_count, active_object_count_wider)
|
|
local meta = minetest.env:get_meta(pos)
|
|
for i, name in ipairs({
|
|
"fuel_totaltime",
|
|
"fuel_time",
|
|
"src_totaltime",
|
|
"src_time"
|
|
}) do
|
|
if meta:get_string(name) == "" then
|
|
meta:set_float(name, 0.0)
|
|
end
|
|
end
|
|
|
|
local inv = meta:get_inventory()
|
|
|
|
local srclist = inv:get_list("src")
|
|
local cooked = nil
|
|
local aftercooked
|
|
|
|
if srclist then
|
|
cooked, aftercooked = minetest.get_craft_result({method = "cooking", width = 1, items = srclist})
|
|
end
|
|
|
|
local was_active = false
|
|
|
|
if meta:get_float("fuel_time") < meta:get_float("fuel_totaltime") then
|
|
was_active = true
|
|
meta:set_float("fuel_time", meta:get_float("fuel_time") + 1)
|
|
meta:set_float("src_time", meta:get_float("src_time") + 1)
|
|
if cooked and cooked.item and meta:get_float("src_time") >= cooked.time then
|
|
-- check if there's room for output in "dst" list
|
|
if inv:room_for_item("dst",cooked.item) then
|
|
-- Put result in "dst" list
|
|
inv:add_item("dst", cooked.item)
|
|
-- take stuff from "src" list
|
|
inv:set_stack("src", 1, aftercooked.items[1])
|
|
else
|
|
print("Could not insert '"..cooked.item:to_string().."'")
|
|
end
|
|
meta:set_string("src_time", 0)
|
|
end
|
|
end
|
|
|
|
if meta:get_float("fuel_time") < meta:get_float("fuel_totaltime") then
|
|
local percent = math.floor(meta:get_float("fuel_time") /
|
|
meta:get_float("fuel_totaltime") * 100)
|
|
meta:set_string("infotext","Furnace active: "..percent.."%")
|
|
swap_furnace_nodes(pos, percent, "Furnace active: "..percent.."%", 1)
|
|
meta:set_string("formspec", furnace_formspec(nil, percent))
|
|
return
|
|
end
|
|
|
|
local fuel = nil
|
|
local afterfuel
|
|
local cooked = nil
|
|
local fuellist = inv:get_list("fuel")
|
|
local srclist = inv:get_list("src")
|
|
|
|
if srclist then
|
|
cooked = minetest.get_craft_result({method = "cooking", width = 1, items = srclist})
|
|
end
|
|
if fuellist then
|
|
fuel, afterfuel = minetest.get_craft_result({method = "fuel", width = 1, items = fuellist})
|
|
end
|
|
|
|
if fuel and fuel.time and fuel.time <= 0 then
|
|
meta:set_string("infotext","Furnace out of fuel")
|
|
swap_furnace_nodes(pos, 0, "Furnace out of fuel", 0)
|
|
local metapos = pos.x..","..pos.y..","..pos.z
|
|
meta:set_string("formspec", furnace_formspec(nil, 0))
|
|
return
|
|
end
|
|
|
|
if cooked and cooked .item and cooked.item:is_empty() then
|
|
if was_active then
|
|
meta:set_string("infotext","Furnace is empty")
|
|
swap_furnace_nodes(pos, 0, "Furnace is empty", 0)
|
|
local metapos = pos.x..","..pos.y..","..pos.z
|
|
meta:set_string("formspec", furnace_formspec(nil, 0))
|
|
end
|
|
return
|
|
end
|
|
|
|
if fuel and fuel.time then
|
|
meta:set_string("fuel_totaltime", fuel.time*2)
|
|
end
|
|
meta:set_string("fuel_time", 0)
|
|
|
|
if afterfuel and afterfuel.items and afterfuel.items[1] then
|
|
inv:set_stack("fuel", 1, afterfuel.items[1])
|
|
end
|
|
end,
|
|
})
|
|
def = nil |