-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathshaper.lua
370 lines (288 loc) · 10.4 KB
/
shaper.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
-- Facade Shaper
-- This machine serves the same purpose as the circular saw from moreblocks or the milling
-- maching from mymillwork. Namely, it provides a tool for creating shaped blocks that does
-- not rely on using recipes.
-- Balancing output per 1 input block with respect to apparent volume of output shape.
-- All current shapes are added, but shapes not present in this table will still be produced
-- one at a time — if that is the desired quantity, adding them is not required.
local output_ratios = {
bannerstone = 1,
bannerstone_corner = 1,
centerstone = 1,
column = 1,
column_corner = 1,
corbel = 1,
corbel_corner = 1,
corbel_corner_inner = 1,
carved_stone_a = 1,
carved_stone_a_corner = 1,
rgspro = 2,
rgspro_inner_corner = 1,
rgspro_outer_corner = 1,
corner_bricks = 2,
columnia_mid = 4,
columnia_bottom = 1,
columnia_top = 1,
columnia_crosslink = 1,
columnia_link = 4,
columnia_linkdown = 4,
}
-- The material to be used for buttons when no material is actually loaded.
-- It should be a generic material for which all the facade shapes are defined.
local demo_material = "default:stone"
-- Whether the facade should obey area protection for the inventories (as machines in technic mod)
-- or allow anybody to use them, but disallow the removal of machine itself (like circular saw in moreblocks)
local protect_inventories = false
local function prepare_formspec (material_name)
local output = string.gsub(material_name, "^.*:", "facade:")
local shaper_formspec =
"size[8,11;]"..
"label[0,0;" .. "Choose shape to produce:" .. "]"..
-- row 1, blocky shapes
"item_image_button[0,0.5;1,1;" .. output .. "_bannerstone" .. ";bannerstone; ]"..
"item_image_button[1,0.5;1,1;" .. output .. "_bannerstone_corner" .. ";bannerstone_corner; ]"..
"item_image_button[2,0.5;1,1;" .. output .. "_centerstone" .. ";centerstone; ]"..
"item_image_button[3,0.5;1,1;" .. output .. "_carved_stone_a" .. ";carved_stone_a; ]"..
"item_image_button[4,0.5;1,1;" .. output .. "_carved_stone_a_corner" .. ";carved_stone_a_corner; ]"..
"item_image_button[5,0.5;1,1;" .. output .. "_column" .. ";column; ]"..
"item_image_button[6,0.5;1,1;" .. output .. "_column_corner" .. ";column_corner; ]"..
-- row 2, corbel
"item_image_button[0,1.5;1,1;" .. output .. "_corbel" .. ";corbel; ]"..
"item_image_button[1,1.5;1,1;" .. output .. "_corbel_corner_inner" .. ";corbel_corner_inner; ]"..
"item_image_button[2,1.5;1,1;" .. output .. "_corbel_corner" .. ";corbel_corner; ]"..
-- row 3, cornice
"item_image_button[0,2.5;1,1;" .. output .. "_rgspro" .. ";rgspro; ]"..
"item_image_button[1,2.5;1,1;" .. output .. "_rgspro_inner_corner" .. ";rgspro_inner_corner; ]"..
"item_image_button[2,2.5;1,1;" .. output .. "_rgspro_outer_corner" .. ";rgspro_outer_corner; ]"
-- row 4, columnia
if not minetest.get_modpath("columnia") then
shaper_formspec = shaper_formspec ..
"item_image_button[0,3.5;1,1;" .. output .. "_columnia_mid" .. ";columnia_mid; ]"..
"item_image_button[1,3.5;1,1;" .. output .. "_columnia_bottom" .. ";columnia_bottom; ]"..
"item_image_button[2,3.5;1,1;" .. output .. "_columnia_crosslink" .. ";columnia_crosslink; ]"..
"item_image_button[3,3.5;1,1;" .. output .. "_columnia_link" .. ";columnia_link; ]"..
"item_image_button[4,3.5;1,1;" .. output .. "_columnia_linkdown" .. ";columnia_linkdown; ]"
-- this code is a provision in case top column pieces enter service
if minetest.registered_nodes[output .. "_columnia_top"] then
shaper_formspec = shaper_formspec ..
"item_image_button[5,3.5;1,1;" .. output .. "_columnia_top" .. ";columnia_top; ]"
end
end
-- row 5 for shapes which are not available for all materials
-- only one such shape exists so far, but more should be easy to add here
if minetest.registered_nodes[output .. "_corner_bricks"] then
shaper_formspec = shaper_formspec ..
"item_image_button[0,4.5;1,1;" .. output .. "_corner_bricks" .. ";corner_bricks; ]"
end
-- inventory part
shaper_formspec = shaper_formspec ..
"label[0, 5.5;".."In:".."]"..
"list[current_name;src;1,5.5;1,1;]"..
"label[3, 5.5;".."Out:".."]"..
"list[current_name;dst;4,5.5;4,1;]"..
"list[current_player;main;0,7;8,4;]"..
"listring[current_name;dst]"..
"listring[current_player;main]"..
"listring[current_name;src]"..
"listring[current_player;main]"
return(shaper_formspec)
end
-- a simple check for compatibile materials
local function check_material_applicability (material)
-- using centerstone node here, since it appears to be both one of the oldest
-- and defined for all materials as well, making it suitable for a quick check
if minetest.registered_nodes[string.gsub(material, "^.*:", "facade:") .. "_centerstone"] then
return true
else
return false
end
end
-- update the buttons to show shapes made from the actual material
local function update_formspec_put (pos, listname, index, stack, player)
if protect_inventories and minetest.is_protected(pos, player:get_player_name()) then
return
end
if listname ~= "src" then
return
end
local meta = minetest.get_meta(pos)
local material_name = stack:get_name()
if check_material_applicability(material_name) then
meta:set_string("formspec", prepare_formspec(material_name))
else
return
end
end
-- update the buttons to show shapes made from demo material if all material is removed
local function update_formspec_take (pos, listname, index, stack, player)
if protect_inventories and minetest.is_protected(pos, player:get_player_name()) then
return
end
if listname ~= "src" then
return
end
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
if inv:is_empty("src") then
meta:set_string("formspec", prepare_formspec(demo_material))
end
return
end
-- disallow putting in materials which are not supported
local function check_inventory_put (pos, listname, index, stack, player)
if protect_inventories and minetest.is_protected(pos, player:get_player_name()) then
return 0
end
if listname ~= "src" then
return 0
end
local material_name = stack:get_name()
if check_material_applicability(material_name) then
return(stack:get_count())
else
return 0
end
end
local function check_inventory_take (pos, listname, index, stack, player)
if protect_inventories and minetest.is_protected(pos, player:get_player_name()) then
return 0
end
if listname ~= "src" and listname ~= "dst" then
return 0
end
return(stack:get_count())
end
local function check_inventory_move (pos, from_list, from_index, to_list, to_index, count, player)
if protect_inventories and minetest.is_protected(pos, player:get_player_name()) then
return 0
end
return(stack:get_count())
end
-- process the form fields and convert source material to desired shapes
local function form_handler(pos, formname, fields, sender)
if protect_inventories and minetest.is_protected(pos, sender:get_player_name()) then
return
end
if fields.quit then
return
end
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
if inv:is_empty("src") then
return
end
local inputstack = inv:get_stack("src", 1)
local inputname = inputstack:get_name()
for shape,_ in pairs(fields) do
local result = string.gsub(inputname, "^.*:", "facade:") .. "_" .. shape
-- one can never be overly paranoid, unlike the quick check before, this one is precise
if not minetest.registered_nodes[result] then
return
end
-- output quantities are adjusted to preserve roughly same mass of resulting products
if output_ratios[shape] then
result = result .. " " .. output_ratios[shape]
end
if not inv:room_for_item("dst", result) then
return
end
inputstack:take_item(1)
inv:set_stack("src", 1, inputstack)
inv:add_item("dst", result)
end
return
end
local function check_removability (pos, player)
local meta = minetest.get_meta(pos)
local owner = meta:set_string("owner")
local pname = player:get_player_name()
local inv = meta:get_inventory()
-- owner may always remove the device
if owner and owner ~= "" and pname and pname ~= "" and owner == pname then
if inv:is_empty("src") and inv:is_empty("dst") then
return true
else
return false
end
end
if minetest.is_protected(pos, player:get_player_name()) then
return false
end
if inv:is_empty("src") and inv:is_empty("dst") then
return true
end
return false
end
minetest.register_node("facade:shaper", {
description = "Shaper Machine",
drawtype = "nodebox",
node_box = {
type = "fixed",
fixed = {
-- base
{-1/2, -1/2, -1/2, 1/2, -14/32, 1/2},
-- back
{-8/32, -1/2, 12/32, 8/32, 1/2, 16/32},
-- table
{-8/32, -4/32, -16/32, 8/32, 4/32, 16/32},
-- rear table sliding support
{-16/32, -4/32, 12/32, 16/32, 4/32, 16/32},
-- front table sliding support
{-8/32, -14/32, -12/32, 8/32, -4/32, -16/32},
-- top tool beam
{-4/32, 16/32, -8/32, 4/32, 12/32, 12/32},
-- cutter holder
{-2/32, 7/32, -2/32, 2/32, 14/32, 2/32},
-- cutter
{-1/128, 6/32, -1/32, 1/128, 7/32, 1/32},
},
},
selection_box = {
type = "fixed",
fixed = {
{-1/2, -1/2, -1/2, 1/2, 1/2, 1/2},
},
},
tiles = { "facade_shaper_top.png",
"facade_shaper_bottom.png",
"facade_shaper_right.png",
"facade_shaper_left.png",
"facade_shaper_back.png",
"facade_shaper_front.png"},
groups = { oddly_breakable_by_hand=2, cracky=3, dig_immediate=1 },
paramtype = "light",
paramtype2 = "facedir",
legacy_facedir_simple = true,
on_construct = function(pos)
local meta = minetest.get_meta(pos)
meta:set_string("formspec", prepare_formspec(demo_material))
local inv = meta:get_inventory()
inv:set_size("src", 1)
inv:set_size("dst", 4)
end,
after_place_node = function(pos, placer)
local meta = minetest.get_meta(pos)
local owner = placer and placer:get_player_name() or ""
meta:set_string("owner", owner)
if owner then
meta:set_string("infotext", ("Facade Shaper (owned by %s)"):format(owner))
else
meta:set_string("infotext", "Facade Shaper")
end
end,
can_dig = check_removability,
allow_metadata_inventory_put = check_inventory_put,
allow_metadata_inventory_take = check_inventory_take,
allow_metadata_inventory_move = check_inventory_move,
on_metadata_inventory_put = update_formspec_put,
on_metadata_inventory_take = update_formspec_take,
on_receive_fields = form_handler,
})
minetest.register_craft({
output = 'facade:shaper',
recipe = {
{'', 'default:diamond', '' },
{'default:steel_ingot', 'default:steelblock', 'default:steel_ingot' },
{'', 'default:steelblock' , '' },
},
})