Differences From
Artifact [35031ce713]:
18 18 allow = function(node, tool) ... end;
19 19 handle = function(node, tool) ... end;
20 20 };
21 21 };
22 22 } ]]
23 23 -- it should only be written by special accessor functions!
24 24
25 -B.stage = lib.registry.mk 'starlit_building:stage'
26 --- a stage consists of a list of pieces and maps from possible materials
27 --- / tool usages to succeeding stages in the build tree. note that all
28 --- used pieces must be defined before a stage is defined currently, due
29 --- to a lack of cross-registry dependency mechanisms. i will hopefully
30 --- improve vtlib to handle this condition eventually.
25 +B.begin = {part = {}, tool = {}}
26 +-- this maps parts/tools to the new nodes they create
31 27 --[[
32 - starlit.mod.building.stage.link(id, {
33 - pieces = {
34 - 'starlit_building:foundation';
35 - 'starlit_building:insulation'; -- offset ofsFac
36 - {'starlit_building:pipe', vector.new(-.5, 0, 0), 0};--
37 - {'starlit_building:pipe', vector.new(-.5, 0, 0), 1};
38 - 'starlit_building:insulation';
39 - 'starlit_building:panel';
40 - };
41 - })
28 + part = {
29 + ['starlit_building:concrete'] = 'starlit_building:stage_foundation';
30 + -- or function(...)
31 + };
32 + tool = {
33 + -- for consistency's sake -- can't quite imagine a valid use
34 + -- for this but im sure it'll bite me eventually if i leave it out
35 + };
42 36 ]]
43 37
44 -B.piece = lib.registry.mk 'starlit_building:piece'
45 --- a piece is used to produce stage definitions, by means of appending
46 --- nodeboxes with appropriate offsets. it also lists the recoverable
47 --- materials which can be obtained by destroying a stage containing
48 --- this piece using nano. part IDs should correspond with piece IDs
49 --- where possible
38 +B.stage = lib.registry.mk 'starlit_building:stage'
39 +-- a stage consists of a node definition and maps from possible materials
40 +-- / tool usages to succeeding stages in the build tree
50 41 --[[
51 - starlit.mod.building.piece.link(id, {
52 - tex = 'myMod_part.png';
53 - height = 0.1; -- used for auto-offset
54 - fab = {
55 - element = {iron=10};
56 - };
57 - shape = {
58 - type = "fixed";
59 - fixed = { ... };
42 + starlit.mod.building.stage.link(id, {
43 + tex = { ... };
44 + box = { ... }; -- nodebox def, or
45 + mesh = '...'; -- mesh name
46 + begin = {
47 + part = {...};
48 + tool = {...};
49 + }
50 + build = {
51 + part = {
52 + ['starlit_building:insulation'] = 'starlit_building:foundation_with_insulation';
53 + };
54 + tool = {
55 + ['starlit_building:screwdriver'] = {id = 'air', drop = 'starlit_building:foundation'};
56 + };
60 57 };
61 58 })
62 59 ]]
63 60
64 61 B.part = lib.registry.mk 'starlit_building:part'
65 62 -- a part is implemented as a special craftitem with the proper callbacks
66 63 -- to index the registries and place/replace nodes by reference to the
................................................................................
92 89 short_description = e.name;
93 90 description = starlit.ui.tooltip {
94 91 title = e.name;
95 92 desc = e.desc;
96 93 props = props;
97 94 };
98 95 inventory_image = e.img;
96 + on_place = function(stack, luser, point)
97 + local node = minetest.get_node(point.under)
98 + local function tryBuild()
99 + local p = B.path[node.name]
100 + if not p then return nil end
101 + if (not p.part) or (not p.part[id]) then return nil end
102 + local n = p.part[id]
103 + local obj
104 + if type(n) == 'function' then
105 + obj = n(stack, node, point)
106 + if obj == nil then return nil end
107 + else
108 + obj = ItemStack(n)
109 + stack:take_item(1)
110 + end
111 + local pname = obj:get_name()
112 + local stg = B.stage.db[pname]
113 + node.name = pname
114 + minetest.swap_node(point.under, node)
115 + -- TODO make a noise
116 + if stg.onBuild then
117 + stg.onBuild(point.under, luser, stack)
118 + end
119 + return stack
120 + end
121 +
122 + local function tryBegin()
123 + local p = B.begin.part[stack:get_name()]
124 + if not p then return nil end
125 + if type(p) == 'function' then
126 + p = p(stack, node, point)
127 + if p == nil then return nil end
128 + else
129 + stack:take_item(1)
130 + end
131 + minetest.rotate_and_place(ItemStack(p), luser, point, true)
132 + -- TODO make a noise
133 + return stack
134 + end
135 +
136 + return tryBuild() or tryBegin() or stack
137 + end;
99 138 _starlit = {
100 139 mass = e.mass;
101 140 reverseEngineer = rev;
102 141 recover = e.recover or e.fab;
103 142 };
104 143 })
105 144 if e.fab then
................................................................................
115 154 };
116 155 rarity = e.rarity or 0;
117 156 })
118 157 end
119 158
120 159 end)
121 160
122 -B.stage.foreach('starlit:stageGen', {}, function(id, e)
123 - local box = {type = 'fixed', fixed = {}}
124 - local tex = {}
125 - local ofs = vector.new(0,0,0)
126 - for idx, p in ipairs(e.pieces) do
127 - local ho, pieceID, pos
128 - if type(p) == 'string' then
129 - pieceID, pos, ho = p, vector.zero(), 1.0
130 - else
131 - pieceID, pos, ho = pc[1],pc[2],pc[3]
132 - end
133 - local pc = B.piece.db[pieceID]
134 - pos = pos + ofs
135 - if ho ~= 0.0 then
136 - ofs = vector.offset(ofs, 0, pc.height)
137 - end
138 - local sh = lib.node.boxwarped(pc.shape, function(b)
139 - -- { -x, -y, -z;
140 - -- +x, +y, +z }
141 - b[1] = b[1] + ofs.x b[4] = b[4] + ofs.x
142 - b[2] = b[2] + ofs.y b[5] = b[5] + ofs.y
143 - b[3] = b[3] + ofs.z b[6] = b[6] + ofs.z
144 - end)
145 - table.insert(box, sh)
146 - if type(pc.tex) == 'string' then
147 - table.insert(tex, pc.tex)
148 - else
149 - for i,t in ipairs(pc.tex) do
150 - table.insert(tex, t or '')
151 - end
152 - end
153 - end
154 - minetest.register_node(id, {
155 - description = 'Construction';
156 - drawtype = 'nodebox';
157 - paramtype = 'light';
158 - paramtype2 = e.stateful or 'none';
159 - textures = tex;
160 - node_box = box;
161 - group = { stage = 1 };
162 - _starlit = {
163 - stage = id;
164 - };
165 - })
166 -end)
167 -
168 161 function B.pathLink(from, kind, what, to)
169 162 if not B.path[from] then
170 163 B.path[from] = {part={}, tool={}}
171 164 end
172 165 local k = B.path[from][kind]
173 - assert(k[what] == nil)
166 + assert(k[what] == nil, 'attempted to overwrite an existing build path')
174 167 k[what] = to
175 168 end
176 169
177 170 function B.pathFind(from, kind, what)
178 171 if not B.path[from] then return nil end
179 172 return B.path[from][kind][what]
180 173 end
174 +
175 +B.stage.foreach('starlit:stageGen', {}, function(id, e)
176 + local grp = e.groups and table.copy(e.groups) or {}
177 + grp.stage = 1
178 + minetest.register_node(id, {
179 + description = 'Construction';
180 + drawtype = (e.box and 'nodebox')
181 + or (e.mesh and 'mesh')
182 + or 'regular';
183 + paramtype = (e.box or e.mesh or e.light) and 'light' or nil;
184 + paramtype2 = e.stateful or 'none';
185 + tiles = e.tex;
186 + node_box = e.box;
187 + mesh = e.mesh;
188 + groups = grp;
189 + _starlit = {
190 + stage = id;
191 + };
192 + })
193 + if e.begin then
194 + for _, kind in ipairs {'part', 'tool'} do
195 + for i, v in ipairs(e.begin[kind] or {}) do
196 + assert(B.begin[kind][v] == nil, 'attempted to overwrite buildpath beginning')
197 + B.begin[kind][v] = id
198 + end
199 + end
200 + end
201 + if e.build then
202 + for _, kind in ipairs {'part', 'tool'} do
203 + for what, to in pairs(e.build[kind] or {}) do
204 + B.pathLink(id, kind, what, to)
205 + end
206 + end
207 + end
208 +end)
209 +
181 210
182 211 starlit.include 'parts'
212 +starlit.include 'stages'