local lib = starlit.mod.lib
local B = {}
starlit.mod.building = B
B.path = {}
-- this maps stage IDs to tables of the following form
--[[ {
part = {
['starlit_building:pipe'] = 'myMod:stage3';
};
tool = {
['starlit:screwdriver'] = 'myMod:otherThing_stage1';
['starlit:saw'] = function(node, tool)
core.replace_node(node, {name='myMod:stage1'})
core.drop_item(node, 'starlit_building:pipe')
end;
['myMod:laserWrench'] = {
allow = function(node, tool) ... end;
handle = function(node, tool) ... end;
};
};
} ]]
-- it should only be written by special accessor functions!
B.begin = {part = {}, tool = {}}
-- this maps parts/tools to the new nodes they create
--[[
part = {
['starlit_building:concrete'] = 'starlit_building:stage_foundation';
-- or function(...)
};
tool = {
-- for consistency's sake -- can't quite imagine a valid use
-- for this but im sure it'll bite me eventually if i leave it out
};
]]
B.stage = lib.registry.mk 'starlit_building:stage'
-- a stage consists of a node definition and maps from possible materials
-- / tool usages to succeeding stages in the build tree
--[[
starlit.mod.building.stage.link(id, {
tex = { ... };
box = { ... }; -- nodebox def, or
mesh = '...'; -- mesh name
begin = {
part = {...};
tool = {...};
}
build = {
part = {
['starlit_building:insulation'] = 'starlit_building:foundation_with_insulation';
};
tool = {
['starlit_building:screwdriver'] = {id = 'air', drop = 'starlit_building:foundation'};
};
};
})
]]
B.part = lib.registry.mk 'starlit_building:part'
-- a part is implemented as a special craftitem with the proper callbacks
-- to index the registries and place/replace nodes by reference to the
-- build tree.
--[[
starlit.mod.building.part.link(id, {
name = ''; -- display name
desc = ''; -- display desc
img = ''; -- display image
mass = 0;
fab = {}; -- (optional) auto-gen schematic
rarity = 0;
})
]]
B.part.foreach('starlit:partGen', {}, function(id, e)
local props = {}
if e.mass then
table.insert(props, {title='Mass', desc=lib.math.siUI('g',e.mass), affinity='info'})
end
local rev, scmID
if e.fab then
scmID = string.format('%s_schematic', id)
rev = {
sw = scmID;
complexity = e.complexity or 1;
}
end
core.register_craftitem(id, {
short_description = e.name;
description = starlit.ui.tooltip {
title = e.name;
desc = e.desc;
props = props;
};
stack_max = e.max or (e.mass and math.min(math.max(math.floor(500 / e.mass), 1), 500)) or 10;
inventory_image = e.img;
on_place = function(stack, luser, point)
local node = core.get_node(point.under)
local function tryBuild()
local p = B.path[node.name]
if not p then return nil end
if (not p.part) or (not p.part[id]) then return nil end
local n = p.part[id]
local obj
if type(n) == 'function' then
obj = n(stack, node, point)
if obj == nil then return nil end
else
obj = ItemStack(n)
stack:take_item(1)
end
local pname = obj:get_name()
local stg = B.stage.db[pname]
node.name = pname
core.swap_node(point.under, node)
-- TODO make a noise
if stg.onBuild then
stg.onBuild(point.under, luser, stack)
end
return stack
end
local function tryBegin()
local p = B.begin.part[stack:get_name()]
if not p then return nil end
if type(p) == 'function' then
p = p(stack, node, point)
if p == nil then return nil end
else
stack:take_item(1)
end
core.rotate_and_place(ItemStack(p), luser, point, true)
-- TODO make a noise
return stack
end
return tryBuild() or tryBegin() or stack
end;
_starlit = {
mass = e.mass;
reverseEngineer = rev;
recover = e.recover or e.fab;
};
})
if e.fab then
starlit.item.sw.link(scmID, {
kind = 'schematic';
name = string.format('%s Schematic', e.name);
size = e.size or 32e6;
input = e.fab;
output = id;
cost = e.cost or {
cycles = 4e9;
ram = 1e9;
};
rarity = e.rarity or 0;
})
end
end)
function B.pathLink(from, kind, what, to)
if not B.path[from] then
B.path[from] = {part={}, tool={}}
end
local k = B.path[from][kind]
assert(k[what] == nil, 'attempted to overwrite an existing build path')
k[what] = to
end
function B.pathFind(from, kind, what)
if not B.path[from] then return nil end
return B.path[from][kind][what]
end
B.stage.foreach('starlit:stageGen', {}, function(id, e)
local grp = e.groups and table.copy(e.groups) or {}
grp.stage = 1
local meta = {
stage = id;
recover = e.recover;
}
for k,v in pairs(e.meta or {}) do meta[k] = v end
core.register_node(id, {
description = 'Construction';
drawtype = (e.box and 'nodebox')
or (e.mesh and 'mesh')
or 'regular';
paramtype = e.paramtype or (e.box or e.mesh or e.light) and 'light' or nil;
paramtype2 = e.paramtype2 or 'none';
tiles = e.tex;
node_box = e.box;
mesh = e.mesh;
groups = grp;
_starlit = meta;
})
if e.begin then
for _, kind in ipairs {'part', 'tool'} do
for i, v in ipairs(e.begin[kind] or {}) do
assert(B.begin[kind][v] == nil, 'attempted to overwrite buildpath beginning')
B.begin[kind][v] = id
end
end
end
if e.build then
for _, kind in ipairs {'part', 'tool'} do
for what, to in pairs(e.build[kind] or {}) do
B.pathLink(id, kind, what, to)
end
end
end
end)
starlit.include 'parts'
starlit.include 'stages/arch'