init.lua 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741
  1. --[[
  2. More Blocks: circular saw
  3. Copyright (c) 2011-2015 Calinou and contributors.
  4. Licensed under the zlib license. See LICENSE.md for more information.
  5. --]]
  6. -- Localize for performance.
  7. local math_floor = math.floor
  8. local math_min = math.min
  9. local math_max = math.max
  10. -- Must be enough space to hold all possible variants of a material.
  11. local INVENTORY_SIZE = 138
  12. local S = function(str) return str end
  13. if not minetest.global_exists("circular_saw") then circular_saw = {} end
  14. circular_saw.modpath = minetest.get_modpath("circular_saw")
  15. circular_saw.known_nodes = circular_saw.known_nodes or {}
  16. function circular_saw.register_node(recipeitem, subname)
  17. circular_saw.known_nodes[recipeitem] = circular_saw.known_nodes[recipeitem] or {}
  18. local d = circular_saw.known_nodes[recipeitem]
  19. d[#d + 1] = subname
  20. end
  21. -- 3rd parameter: how many microblocks does this shape cost:
  22. -- It may cause slight loss, but no gain.
  23. -- 1st and 2nd parameters are nodename prefix/postfixes.
  24. -- All entries of this form assume the modname is "stairs".
  25. circular_saw.names = {
  26. {"micro", "_1", 1},
  27. {"micro", "_1s", 1},
  28. {"micro", "_1c", 1},
  29. {"micro", "_c", 1},
  30. {"panel", "_1", 1},
  31. {"micro", "_2", 1},
  32. {"panel", "_2", 1},
  33. {"micro", "_4", 1},
  34. {"panel", "_4", 1},
  35. {"micro", "", 1},
  36. {"panel", "", 2},
  37. {"micro", "_12", 2},
  38. {"panel", "_12", 2},
  39. {"micro", "_14", 3},
  40. {"panel", "_14", 2},
  41. {"micro", "_15", 4},
  42. {"panel", "_15", 2},
  43. {"micro", "_16", 4},
  44. {"micro", "_16s", 2},
  45. {"panel", "_16", 4},
  46. {"stair", "_outer", 5},
  47. {"stair", "_outer2", 4},
  48. {"stair", "", 6},
  49. {"stair", "_inner", 7},
  50. {"$newslopes", "_01", 3},
  51. {"$newslopes", "_02", 1},
  52. {"slab", "_1", 1},
  53. {"slab", "_2", 1},
  54. {"slab", "_quarter", 2},
  55. {"slab", "", 4},
  56. {"slab", "_three_quarter", 6},
  57. {"slab", "_14", 7},
  58. {"slab", "_15", 8},
  59. {"stair", "_half", 3},
  60. {"stair", "_right_half", 3},
  61. {"stair", "_alt_1", 1},
  62. {"stair", "_alt_2", 1},
  63. {"stair", "_alt_4", 2},
  64. {"stair", "_alt_5", 1},
  65. {"stair", "_alt_6", 2},
  66. {"stair", "_alt", 4},
  67. {"slope", "", 4},
  68. {"slope", "_half", 2},
  69. {"slope", "_half_raised", 6},
  70. {"slope", "_inner", 7},
  71. {"slope", "_inner_half", 3},
  72. {"slope", "_inner_half_raised", 7},
  73. {"slope", "_inner_cut", 7},
  74. {"slope", "_inner_cut2", 8},
  75. {"slope", "_inner_cut3", 8},
  76. {"slope", "_inner_cut4", 4},
  77. {"slope", "_inner_cut5", 4},
  78. {"slope", "_inner_cut6", 7},
  79. {"slope", "_inner_cut7", 8},
  80. {"slope", "_inner_cut_half", 4},
  81. {"slope", "_inner_cut_half_raised", 8},
  82. {"slope", "_outer", 3},
  83. {"slope", "_outer_half", 2},
  84. {"slope", "_outer_half_raised", 6},
  85. {"slope", "_outer_cut", 2},
  86. {"slope", "_outer_cut_half", 1},
  87. {"slope", "_outer_cut_half_raised", 3},
  88. {"slope", "_cut", 4},
  89. {"slope", "_xslope_quarter", 2},
  90. {"slope", "_xslope_quarter2", 2},
  91. {"slope", "_xslope_three_quarter", 6},
  92. {"slope", "_xslope_three_quarter_half", 4},
  93. {"slope", "_xslope_cut", 4},
  94. {"slope", "_xslope_slope", 1},
  95. {"slab", "_two_sides", 1},
  96. {"slab", "_three_sides", 2},
  97. {"slab", "_three_sides_u", 2},
  98. {"slab", "_four_sides", 3},
  99. {"slab", "_hole", 3},
  100. {"slab", "_two_opposite", 1},
  101. {"slab", "_pit", 3},
  102. {"slab", "_pit_half", 2},
  103. {"stair", "_half_1", 1},
  104. {"stair", "_right_half_1", 1},
  105. {"slope", "_xslope_peak", 4},
  106. {"slope", "_xslope_peak_half", 2},
  107. {"slope", "_lh", 2},
  108. {"slope", "_half_lh", 1},
  109. {"slope", "_half_raised_lh", 3},
  110. {"slope", "_xslope_slope_lh", 1},
  111. {"slope", "_xslope_peak_lh", 2},
  112. {"slope", "_xslope_peak_half_lh", 1},
  113. {"slope", "_rh", 2},
  114. {"slope", "_half_rh", 1},
  115. {"slope", "_half_raised_rh", 3},
  116. {"slope", "_xslope_slope_rh", 1},
  117. {"slab", "_hole_half", 2},
  118. {"slope", "_astair_1", 6},
  119. {"slope", "_astair_2", 5},
  120. {"slope", "_astair_3", 6},
  121. {"slope", "_astair_4", 6},
  122. {"slope", "_astair_5", 8},
  123. {"panel", "_pillar", 8},
  124. {"panel", "_pcend", 8},
  125. -- Note: the leading $ means the name is a modname, NOT a prefix!
  126. -- This lets us import nodes from mods OTHER than the "stairs" mod.
  127. {"$walls", "", 8},
  128. {"$walls", "_noconnect", 8},
  129. {"$walls", "_noconnect_wide", 8},
  130. {"$walls", "_half", 4},
  131. {"$pillars", "_bottom", 8},
  132. {"$pillars", "_bottom_half", 4},
  133. {"$pillars", "_top", 8},
  134. {"$pillars", "_top_half", 4},
  135. {"$pillars", "_bottom_full", 6},
  136. {"$pillars", "_top_full", 6},
  137. {"$pillars", "_bottom_back", 7},
  138. {"$pillars", "_top_back", 7},
  139. {"$murderhole", "", 6},
  140. {"$machicolation", "", 6},
  141. {"$arrowslit", "", 4},
  142. {"$arrowslit", "_cross", 4},
  143. {"$arrowslit", "_hole", 4},
  144. {"$arrowslit", "_embrasure", 4},
  145. }
  146. function circular_saw:get_cost(inv, stackname)
  147. for i, item in pairs(inv:get_list("output")) do
  148. if item:get_name() == stackname then
  149. return circular_saw.names[i][3]
  150. end
  151. end
  152. end
  153. function circular_saw:get_valid_microblock(materials)
  154. for k, v in ipairs(materials) do
  155. local item = "stairs:micro_" .. v
  156. if minetest.registered_nodes[item] then
  157. return item
  158. end
  159. end
  160. end
  161. function circular_saw:get_output_inv(parent_material, materials, amount, max)
  162. if (not max or max < 1 or max > 64) then max = 64 end
  163. local vcount = 0
  164. local list = {}
  165. -- If there is nothing inside, display empty inventory:
  166. if amount < 1 then
  167. return list, vcount
  168. end
  169. -- Table of nodenames we've seen already, to avoid adding duplicates to
  170. -- the circular saw's output inventory list.
  171. local seen = {}
  172. for _, material in ipairs(materials) do
  173. for i = 1, #circular_saw.names do
  174. local t = circular_saw.names[i]
  175. local cost = t[3]
  176. local balance = math_min(math_floor(amount/cost), max)
  177. local nodename
  178. -- If the prefix begins with a $, then it's actually a modname.
  179. -- This is needed because some shapes (like walls and castle stuff) don't
  180. -- have proper prefixes, and their names would otherwise collide with
  181. -- stairs stuff if we don't take precautions.
  182. if t[1]:sub(1, 1) == "$" then
  183. nodename = t[1]:sub(2) .. ":" .. material .. t[2]
  184. else
  185. nodename = "stairs:" .. t[1] .. "_" .. material .. t[2]
  186. end
  187. local ndef = minetest.registered_nodes[nodename]
  188. if ndef and ndef._stairs_parent_material == parent_material and not seen[nodename] then
  189. list[#list + 1] = nodename .. " " .. balance
  190. seen[nodename] = true
  191. if balance > 0 then
  192. vcount = vcount + 1
  193. end
  194. end
  195. end
  196. end
  197. return list, vcount
  198. end
  199. -- Reset empty circular_saw after last full block has been taken out
  200. -- (or the circular_saw has been placed the first time)
  201. -- Note: max_offered is not reset:
  202. function circular_saw:reset(pos)
  203. local meta = minetest.get_meta(pos)
  204. local inv = meta:get_inventory()
  205. inv:set_stack("input", 1, "")
  206. inv:set_stack("micro", 1, "")
  207. inv:set_list("output", {})
  208. meta:set_int("anz", 0)
  209. circular_saw.update_formspec(pos)
  210. circular_saw.update_infotext(pos)
  211. end
  212. function circular_saw.update_infotext(pos)
  213. local meta = minetest.get_meta(pos)
  214. local inv = meta:get_inventory()
  215. local stack = inv:get_stack("input", 1)
  216. local pname = meta:get_string("owner")
  217. if stack:get_count() > 0 then
  218. local desc = stack:get_name()
  219. local idef = stack:get_definition()
  220. if idef and idef.description then
  221. desc = utility.get_short_desc(idef.description)
  222. end
  223. meta:set_string("infotext",
  224. "Circular Saw is Working on \"" .. desc .. "\".\nOwned by <" .. rename.gpn(pname) .. ">!")
  225. else
  226. meta:set_string("infotext",
  227. "Circular Saw is Empty.\nOwned by <" .. rename.gpn(pname) .. ">!")
  228. end
  229. end
  230. -- Player has taken something out of the box or placed something inside
  231. -- that amounts to 'amount' microblocks (full block count * 8):
  232. function circular_saw:update_inventory(pos, amount)
  233. local meta = minetest.get_meta(pos)
  234. local inv = meta:get_inventory()
  235. amount = meta:get_int("anz") + amount
  236. -- The material is recycled automatically
  237. inv:set_stack("recycle", 1, ItemStack())
  238. if amount < 1 then -- If the last block is taken out.
  239. --minetest.log('action', 'amount is zero!')
  240. meta:set_int("variant_count", 0)
  241. self:reset(pos)
  242. return
  243. end
  244. local stack = inv:get_stack("input", 1)
  245. -- At least one "normal" block is necessary to see what kind of stairs are requested.
  246. if stack:is_empty() then
  247. --minetest.log('action', 'stack is empty!')
  248. -- Any microblocks not taken out yet are now lost.
  249. -- (covers material loss in the machine)
  250. meta:set_int("variant_count", 0)
  251. self:reset(pos)
  252. return
  253. end
  254. local node_name = stack:get_name() or ""
  255. local input_count = math_floor(amount / 8)
  256. local input_item = node_name .. " " .. input_count
  257. -- Display as many full blocks as possible.
  258. inv:set_stack("input", 1, input_item)
  259. local noutlist = {}
  260. local total_available = 0
  261. local materials = circular_saw.known_nodes[node_name]
  262. if materials then
  263. local leftover_item = self:get_valid_microblock(materials)
  264. if leftover_item then
  265. -- 0-7 microblocks may remain left-over:
  266. inv:set_stack("micro", 1, (leftover_item .. " " .. (amount % 8)))
  267. else
  268. -- Erase stack because this microblock doesn't exist.
  269. -- This generally shouldn't happen; this is for safety.
  270. inv:set_stack("micro", 1, ItemStack(""))
  271. end
  272. -- Display:
  273. noutlist, total_available = self:get_output_inv(node_name, materials, amount, meta:get_int("max_offered"))
  274. end
  275. ------------------------------------------------------------------------------
  276. -- So the devs broke the engine again.
  277. --inv:set_list("output", noutlist)
  278. local output_size = inv:get_size("output")
  279. for k = 1, output_size do
  280. if noutlist[k] then
  281. inv:set_stack("output", k, noutlist[k])
  282. else
  283. inv:set_stack("output", k, ItemStack())
  284. end
  285. end
  286. ------------------------------------------------------------------------------
  287. -- Store how many microblocks are available:
  288. meta:set_int("anz", amount)
  289. meta:set_int("variant_count", total_available)
  290. circular_saw.update_formspec(pos)
  291. circular_saw.update_infotext(pos)
  292. end
  293. -- The amount of items offered per shape can be configured:
  294. function circular_saw.on_receive_fields(pos, formname, fields, sender)
  295. -- Ignore scroll events.
  296. if fields.output_grid then
  297. local data = minetest.explode_scrollbar_event(fields.output_grid)
  298. if data and data.type == "CHG" then
  299. local meta = minetest.get_meta(pos)
  300. meta:set_string("scrollbar_val", tostring(data.value))
  301. --circular_saw.update_formspec(pos)
  302. --minetest.chat_send_all('test scroll event')
  303. return
  304. end
  305. end
  306. local meta = minetest.get_meta(pos)
  307. local max = tonumber(fields.max_offered)
  308. if max and max > 0 then
  309. meta:set_string("max_offered", max)
  310. -- Update to show the correct number of items:
  311. circular_saw:update_inventory(pos, 0)
  312. end
  313. if fields.quit then
  314. -- Needed so the form remembers its scroll position.
  315. circular_saw.update_formspec(pos)
  316. --minetest.chat_send_all('test quit event')
  317. end
  318. end
  319. local function has_saw_privilege(meta, player)
  320. if not meta then return false end
  321. if not player then return false end
  322. if minetest.check_player_privs(player, "protection_bypass") then
  323. return true
  324. end
  325. local owner = (meta:get_string("owner") or "")
  326. if player:get_player_name() == owner then
  327. return true
  328. end
  329. return false
  330. end
  331. -- Moving the inventory of the circular_saw around is not allowed because it
  332. -- is a fictional inventory. Moving inventory around would be rather
  333. -- impractical and make things more difficult to calculate:
  334. function circular_saw.allow_metadata_inventory_move(
  335. pos, from_list, from_index, to_list, to_index, count, player)
  336. return 0
  337. end
  338. -- Only input- and recycle-slot are intended as input slots:
  339. function circular_saw.allow_metadata_inventory_put(pos, listname, index, stack, player)
  340. local meta = minetest.get_meta(pos)
  341. if not has_saw_privilege(meta, player) then return 0 end
  342. if listname == "fuel" then
  343. if stack:get_name() == "default:mese_crystal_fragment" then
  344. return stack:get_count()
  345. else
  346. return 0
  347. end
  348. end
  349. -- The player is not allowed to put something in there:
  350. if listname == "output" or listname == "micro" then
  351. return 0
  352. end
  353. local inv = meta:get_inventory()
  354. local stackname = stack:get_name()
  355. local count = stack:get_count()
  356. -- Only alow those items that are offered in the output inventory to be recycled:
  357. if listname == "recycle" then
  358. if not inv:contains_item("output", stackname) then
  359. return 0
  360. end
  361. local stackmax = stack:get_stack_max()
  362. local instack = inv:get_stack("input", 1)
  363. local microstack = inv:get_stack("micro", 1)
  364. local incount = instack:get_count()
  365. local incost = (incount * 8) + microstack:get_count()
  366. local maxcost = (stackmax * 8) + 7
  367. local cost = circular_saw:get_cost(inv, stackname)
  368. if (incost + cost) > maxcost then
  369. return math_max((maxcost - incost) / cost, 0)
  370. end
  371. return count
  372. end
  373. -- Only accept certain blocks as input which are known to be craftable into stairs:
  374. if listname == "input" then
  375. if not inv:is_empty("input") then
  376. if inv:get_stack("input", index):get_name() ~= stackname then
  377. return 0
  378. end
  379. end
  380. if not inv:is_empty("micro") then
  381. local microstackname = inv:get_stack("micro", 1):get_name():gsub("^.+:micro_", "", 1)
  382. local cutstackname = stackname:gsub("^.+:", "", 1)
  383. if microstackname ~= cutstackname then
  384. return 0
  385. end
  386. end
  387. -- Check if this nodename is known to us.
  388. for registered_name, _ in pairs(circular_saw.known_nodes) do
  389. if registered_name == stackname and inv:room_for_item("input", stack) then
  390. return count
  391. end
  392. end
  393. return 0
  394. end
  395. end
  396. -- Taking is allowed from all slots (even the internal microblock slot).
  397. -- Putting something in is slightly more complicated than taking anything
  398. -- because we have to make sure it is of a suitable material:
  399. function circular_saw.on_metadata_inventory_put(
  400. pos, listname, index, stack, player)
  401. -- We need to find out if the circular_saw is already set to a
  402. -- specific material or not:
  403. local meta = minetest.get_meta(pos)
  404. local inv = meta:get_inventory()
  405. local stackname = stack:get_name()
  406. local count = stack:get_count()
  407. -- Putting something into the input slot is only possible if that had
  408. -- been empty before or did contain something of the same material:
  409. if listname == "input" then
  410. -- Each new block is worth 8 microblocks:
  411. circular_saw:update_inventory(pos, 8 * count)
  412. elseif listname == "recycle" then
  413. -- Lets look which shape this represents:
  414. local cost = circular_saw:get_cost(inv, stackname)
  415. local input_stack = inv:get_stack("input", 1)
  416. -- check if this would not exceed input itemstack max_stacks
  417. if input_stack:get_count() + ((cost * count) / 8) <= input_stack:get_stack_max() then
  418. circular_saw:update_inventory(pos, cost * count)
  419. end
  420. end
  421. end
  422. local mese_to_cut_ratio = 32
  423. function circular_saw.allow_metadata_inventory_take(pos, listname, index, stack, player)
  424. local meta = minetest.get_meta(pos)
  425. if not has_saw_privilege(meta, player) then return 0 end
  426. if listname == "output" then
  427. local inv = meta:get_inventory()
  428. if inv:is_empty("fuel") then
  429. minetest.chat_send_player(player:get_player_name(), "# Server: No power to saw!")
  430. easyvend.sound_error(player:get_player_name())
  431. return 0
  432. else
  433. -- We do know how much each block at each position costs:
  434. local cost = circular_saw.names[index][3] * stack:get_count()
  435. local fuel = math.ceil(cost / mese_to_cut_ratio)
  436. if fuel < 1 then fuel = 1 end
  437. local fstack = inv:get_stack("fuel", 1)
  438. if fstack:get_count() < fuel then
  439. minetest.chat_send_player(player:get_player_name(), "# Server: Not enough energy!")
  440. easyvend.sound_error(player:get_player_name())
  441. return 0
  442. end
  443. end
  444. end
  445. return stack:get_count()
  446. end
  447. function circular_saw.on_metadata_inventory_take(
  448. pos, listname, index, stack, player)
  449. -- Prevent (inbuilt) swapping between inventories with different blocks
  450. -- corrupting player inventory or Saw with 'unknown' items.
  451. local meta = minetest.get_meta(pos)
  452. local inv = meta:get_inventory()
  453. local input_stack = inv:get_stack(listname, index)
  454. if not input_stack:is_empty() and input_stack:get_name()~=stack:get_name() then
  455. local player_inv = player:get_inventory()
  456. if player_inv:room_for_item("main", input_stack) then
  457. player_inv:add_item("main", input_stack)
  458. end
  459. circular_saw:reset(pos)
  460. return
  461. end
  462. -- If it is one of the offered stairs: find out how many
  463. -- microblocks have to be substracted:
  464. if listname == "output" then
  465. -- We do know how much each block at each position costs:
  466. local cost = circular_saw.names[index][3] * stack:get_count()
  467. local fuel = math.ceil(cost / mese_to_cut_ratio)
  468. if fuel < 1 then fuel = 1 end
  469. inv:remove_item("fuel", ItemStack("default:mese_crystal_fragment " .. fuel))
  470. circular_saw:update_inventory(pos, -cost)
  471. elseif listname == "micro" then
  472. -- Each microblock costs 1 microblock:
  473. circular_saw:update_inventory(pos, -stack:get_count())
  474. elseif listname == "input" then
  475. -- Each normal (= full) block taken costs 8 microblocks:
  476. circular_saw:update_inventory(pos, 8 * -stack:get_count())
  477. end
  478. -- The recycle field plays no role here since it is processed immediately.
  479. end
  480. function circular_saw.update_formspec(pos)
  481. local fancy_inv = default.gui_bg..default.gui_bg_img..default.gui_slots
  482. local meta = minetest.get_meta(pos)
  483. local scrollval = meta:get_string("scrollbar_val")
  484. local vcount = meta:get_int("variant_count")
  485. --minetest.chat_send_all('test2')
  486. -- Modify formspec size and inventory size in order to make room for more blocks.
  487. meta:set_string("formspec", "size[9,10]"..fancy_inv..
  488. "label[0,0.15;" ..S("Input\nMaterial").. "]" ..
  489. "list[context;input;1.2,0.15;1,1;]" ..
  490. "label[0,1.15;" ..S("Left-Over").. "]" ..
  491. "list[context;micro;1.2,1.15;1,1;]" ..
  492. "label[0,2.15;" ..S("Recycle\nOutput").. "]" ..
  493. "list[context;recycle;1.2,2.15;1,1;]" ..
  494. "field[0.3,4.0;1,1;max_offered;" ..S("Max").. ":;${max_offered}]" ..
  495. "field_close_on_enter[max_offered;false]" ..
  496. "button[1.2,3.7;1,1;Set;" ..S("Set").. "]" ..
  497. "real_coordinates[true]" ..
  498. "scroll_container[3.5,0.5;7.8,6.05;output_grid;vertical]" ..
  499. "list[context;output;0.03,0.03;6,23;]" ..
  500. "scroll_container_end[]" ..
  501. "scrollbaroptions[max=225;thumbsize=70;largestep=50;smallstep=3]" ..
  502. "scrollbar[11.0,0.5;0.4,6.05;vertical;output_grid;" .. scrollval .. "]" ..
  503. "label[3.5,6.85;Material variants: " .. vcount .. "]" ..
  504. "real_coordinates[false]" ..
  505. "list[current_player;main;0.5,6.25;8,4;]" ..
  506. "label[0,4.85;Mese Fuel\nStorage]" ..
  507. "list[context;fuel;1.2,4.85;1,1;]"
  508. )
  509. local inv = meta:get_inventory()
  510. if inv:get_size("output") ~= INVENTORY_SIZE then
  511. inv:set_size("output", INVENTORY_SIZE)
  512. end
  513. end
  514. function circular_saw.on_construct(pos)
  515. local meta = minetest.get_meta(pos)
  516. circular_saw.update_formspec(pos)
  517. meta:set_int("anz", 0) -- No microblocks inside yet.
  518. meta:set_string("max_offered", 64) -- How many items of this kind are offered by default?
  519. local inv = meta:get_inventory()
  520. inv:set_size("input", 1) -- Input slot for full blocks of material x.
  521. inv:set_size("micro", 1) -- Storage for 1-7 surplus microblocks.
  522. inv:set_size("recycle", 1) -- Surplus partial blocks can be placed here.
  523. inv:set_size("output", INVENTORY_SIZE) -- Many versions of stair-parts of material x.
  524. inv:set_size("fuel", 1)
  525. circular_saw:reset(pos)
  526. end
  527. function circular_saw.can_dig(pos,player)
  528. local meta = minetest.get_meta(pos)
  529. local inv = meta:get_inventory()
  530. if not inv:is_empty("input") or
  531. not inv:is_empty("micro") or
  532. not inv:is_empty("recycle") or
  533. not inv:is_empty("fuel") then
  534. return false
  535. end
  536. -- Can be dug by anyone when empty, not only by the owner:
  537. return true
  538. end
  539. function circular_saw.after_place_node(pos, placer)
  540. local meta = minetest.get_meta(pos)
  541. local owner = placer and placer:get_player_name() or ""
  542. local dname = rename.gpn(owner)
  543. meta:set_string("owner", owner)
  544. meta:set_string("rename", dname)
  545. circular_saw.update_infotext(pos)
  546. end
  547. if not circular_saw.loaded then
  548. local c = "circular_saw:core"
  549. local f = circular_saw.modpath .. "/init.lua"
  550. reload.register_file(c, f, false)
  551. circular_saw.loaded = true
  552. minetest.register_node("circular_saw:circular_saw", {
  553. description = "Circular Table Saw\n\nRequires mese fragments to power the saw wheel.\nDo not allow children to use.",
  554. drawtype = "nodebox",
  555. node_box = {
  556. type = "fixed",
  557. fixed = {
  558. {-0.4, -0.5, -0.4, -0.25, 0.25, -0.25}, -- Leg
  559. {0.25, -0.5, 0.25, 0.4, 0.25, 0.4}, -- Leg
  560. {-0.4, -0.5, 0.25, -0.25, 0.25, 0.4}, -- Leg
  561. {0.25, -0.5, -0.4, 0.4, 0.25, -0.25}, -- Leg
  562. {-0.5, 0.25, -0.5, 0.5, 0.375, 0.5}, -- Tabletop
  563. {-0.01, 0.4375, -0.125, 0.01, 0.5, 0.125}, -- Saw blade (top)
  564. {-0.01, 0.375, -0.1875, 0.01, 0.4375, 0.1875}, -- Saw blade (bottom)
  565. {-0.25, -0.0625, -0.25, 0.25, 0.25, 0.25}, -- Motor case
  566. },
  567. },
  568. dumpnodes_tile = {"default_wood.png"},
  569. tiles = {
  570. "moreblocks_circular_saw_top.png",
  571. "moreblocks_circular_saw_bottom.png",
  572. "moreblocks_circular_saw_side.png"
  573. },
  574. paramtype = "light",
  575. sunlight_propagates = true,
  576. paramtype2 = "facedir",
  577. on_rotate = function(...)
  578. return screwdriver.rotate_simple(...)
  579. end,
  580. groups = utility.dig_groups("furniture", {
  581. immovable = 1,
  582. }),
  583. sounds = default.node_sound_wood_defaults(),
  584. on_construct = function(...) return circular_saw.on_construct(...) end,
  585. can_dig = function(...) return circular_saw.can_dig(...) end,
  586. stack_max = 1,
  587. -- Set the owner of this circular saw.
  588. after_place_node = function(...) return circular_saw.after_place_node(...) end,
  589. -- The amount of items offered per shape can be configured:
  590. on_receive_fields = function(...) return circular_saw.on_receive_fields(...) end,
  591. allow_metadata_inventory_move = function(...) return circular_saw.allow_metadata_inventory_move(...) end,
  592. -- Only input- and recycle-slot are intended as input slots:
  593. allow_metadata_inventory_put = function(...) return circular_saw.allow_metadata_inventory_put(...) end,
  594. allow_metadata_inventory_take = function(...) return circular_saw.allow_metadata_inventory_take(...) end,
  595. -- Taking is allowed from all slots (even the internal microblock slot). Moving is forbidden.
  596. -- Putting something in is slightly more complicated than taking anything because we have to make sure it is of a suitable material:
  597. on_metadata_inventory_put = function(...) return circular_saw.on_metadata_inventory_put(...) end,
  598. on_metadata_inventory_take = function(...) return circular_saw.on_metadata_inventory_take(...) end,
  599. -- Called by rename LBM.
  600. _on_update_infotext = function(pos)
  601. circular_saw.update_infotext(pos)
  602. end,
  603. _on_update_formspec = function(pos)
  604. -- Update circular saw.
  605. circular_saw.update_formspec(pos)
  606. circular_saw:update_inventory(pos, 0)
  607. end,
  608. })
  609. minetest.register_craft({
  610. output = "circular_saw:circular_saw",
  611. recipe = {
  612. {'', 'gem_cutter:blade', ''},
  613. {'group:wood', 'group:wood', 'group:wood'},
  614. {'cast_iron:ingot', 'techcrafts:electric_motor', 'cast_iron:ingot'},
  615. }
  616. })
  617. end