doors_chest.lua 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803
  1. -- Since the doors mod has changed in the latest daily builds I have taken the
  2. -- WTFPL licenced code from the old doors mod and included an edited version
  3. -- within this mod for local use.
  4. local S = protector.intllib
  5. local F = minetest.formspec_escape
  6. -- MineClone2 support
  7. local mcl = minetest.get_modpath("mcl_core")
  8. local mcf = minetest.get_modpath("mcl_formspec")
  9. -- Are crafts enabled?
  10. local protector_crafts = minetest.settings:get_bool("protector_crafts") ~= false
  11. -- Registers a door
  12. function register_door(name, def)
  13. def.groups.not_in_creative_inventory = 1
  14. local box = {{-0.5, -0.5, -0.5, 0.5, 0.5, -0.5+1.5/16}}
  15. def.node_box_bottom = box
  16. def.node_box_top = box
  17. def.selection_box_bottom = box
  18. def.selection_box_top = box
  19. def.sound_close_door = "doors_door_close"
  20. def.sound_open_door = "doors_door_open"
  21. minetest.register_craftitem(name, {
  22. description = def.description,
  23. inventory_image = def.inventory_image,
  24. on_place = function(itemstack, placer, pointed_thing)
  25. if not pointed_thing.type == "node" then
  26. return itemstack
  27. end
  28. local ptu = pointed_thing.under
  29. local nu = minetest.get_node(ptu)
  30. if minetest.registered_nodes[nu.name]
  31. and minetest.registered_nodes[nu.name].on_rightclick then
  32. return minetest.registered_nodes[nu.name].on_rightclick(ptu, nu, placer, itemstack)
  33. end
  34. local pt = pointed_thing.above
  35. local pt2 = {x=pt.x, y=pt.y, z=pt.z}
  36. pt2.y = pt2.y+1
  37. if
  38. not minetest.registered_nodes[minetest.get_node(pt).name].buildable_to or
  39. not minetest.registered_nodes[minetest.get_node(pt2).name].buildable_to or
  40. not placer or
  41. not placer:is_player()
  42. then
  43. return itemstack
  44. end
  45. if minetest.is_protected(pt, placer:get_player_name()) or
  46. minetest.is_protected(pt2, placer:get_player_name()) then
  47. minetest.record_protection_violation(pt, placer:get_player_name())
  48. return itemstack
  49. end
  50. local p2 = minetest.dir_to_facedir(placer:get_look_dir())
  51. local pt3 = {x=pt.x, y=pt.y, z=pt.z}
  52. if p2 == 0 then
  53. pt3.x = pt3.x-1
  54. elseif p2 == 1 then
  55. pt3.z = pt3.z+1
  56. elseif p2 == 2 then
  57. pt3.x = pt3.x+1
  58. elseif p2 == 3 then
  59. pt3.z = pt3.z-1
  60. end
  61. if minetest.get_item_group(minetest.get_node(pt3).name, "door") == 0 then
  62. minetest.set_node(pt, {name=name.."_b_1", param2=p2})
  63. minetest.set_node(pt2, {name=name.."_t_1", param2=p2})
  64. else
  65. minetest.set_node(pt, {name=name.."_b_2", param2=p2})
  66. minetest.set_node(pt2, {name=name.."_t_2", param2=p2})
  67. minetest.get_meta(pt):set_int("right", 1)
  68. minetest.get_meta(pt2):set_int("right", 1)
  69. end
  70. if not minetest.settings:get_bool("creative_mode") then
  71. itemstack:take_item()
  72. end
  73. return itemstack
  74. end,
  75. })
  76. local tt = def.tiles_top
  77. local tb = def.tiles_bottom
  78. local function after_dig_node(pos, name, digger)
  79. local node = minetest.get_node(pos)
  80. if node.name == name then
  81. minetest.node_dig(pos, node, digger)
  82. end
  83. end
  84. local function on_rightclick(pos, dir, check_name, replace, replace_dir, params)
  85. pos.y = pos.y+dir
  86. if minetest.get_node(pos).name ~= check_name then
  87. return
  88. end
  89. local p2 = minetest.get_node(pos).param2
  90. p2 = params[p2+1]
  91. minetest.swap_node(pos, {name=replace_dir, param2=p2})
  92. pos.y = pos.y-dir
  93. minetest.swap_node(pos, {name=replace, param2=p2})
  94. local snd_1 = def.sound_close_door
  95. local snd_2 = def.sound_open_door
  96. if params[1] == 3 then
  97. snd_1 = def.sound_open_door
  98. snd_2 = def.sound_close_door
  99. end
  100. if minetest.get_meta(pos):get_int("right") ~= 0 then
  101. minetest.sound_play(snd_1, {pos = pos, gain = 0.3, max_hear_distance = 10})
  102. else
  103. minetest.sound_play(snd_2, {pos = pos, gain = 0.3, max_hear_distance = 10})
  104. end
  105. end
  106. local function on_rotate(pos, node, dir, user, check_name, mode, new_param2)
  107. if mode ~= screwdriver.ROTATE_FACE then
  108. return false
  109. end
  110. pos.y = pos.y + dir
  111. if not minetest.get_node(pos).name == check_name then
  112. return false
  113. end
  114. if minetest.is_protected(pos, user:get_player_name()) then
  115. minetest.record_protection_violation(pos, user:get_player_name())
  116. return false
  117. end
  118. local node2 = minetest.get_node(pos)
  119. node2.param2 = (node2.param2 + 1) % 4
  120. minetest.swap_node(pos, node2)
  121. pos.y = pos.y - dir
  122. node.param2 = (node.param2 + 1) % 4
  123. minetest.swap_node(pos, node)
  124. return true
  125. end
  126. minetest.register_node(name.."_b_1", {
  127. tiles = {tb[2], tb[2], tb[2], tb[2], tb[1], tb[1].."^[transformfx"},
  128. paramtype = "light",
  129. paramtype2 = "facedir",
  130. use_texture_alpha = "clip",
  131. is_ground_content = false,
  132. drop = name,
  133. drawtype = "nodebox",
  134. node_box = {
  135. type = "fixed",
  136. fixed = def.node_box_bottom
  137. },
  138. selection_box = {
  139. type = "fixed",
  140. fixed = def.selection_box_bottom
  141. },
  142. groups = def.groups,
  143. _mcl_hardness = 0.8,
  144. _mcl_blast_resistance = 1,
  145. after_dig_node = function(pos, oldnode, oldmetadata, digger)
  146. pos.y = pos.y+1
  147. after_dig_node(pos, name.."_t_1", digger)
  148. end,
  149. on_rightclick = function(pos, node, clicker)
  150. if not minetest.is_protected(pos, clicker:get_player_name()) then
  151. on_rightclick(pos, 1, name.."_t_1", name.."_b_2", name.."_t_2", {1,2,3,0})
  152. end
  153. end,
  154. on_rotate = function(pos, node, user, mode, new_param2)
  155. return on_rotate(pos, node, 1, user, name.."_t_1", mode)
  156. end,
  157. sounds = def.sounds,
  158. sunlight_propagates = def.sunlight,
  159. on_blast = function() end,
  160. })
  161. minetest.register_node(name.."_t_1", {
  162. tiles = {tt[2], tt[2], tt[2], tt[2], tt[1], tt[1].."^[transformfx"},
  163. paramtype = "light",
  164. paramtype2 = "facedir",
  165. use_texture_alpha = "clip",
  166. is_ground_content = false,
  167. drop = "",
  168. drawtype = "nodebox",
  169. node_box = {
  170. type = "fixed",
  171. fixed = def.node_box_top
  172. },
  173. selection_box = {
  174. type = "fixed",
  175. fixed = def.selection_box_top
  176. },
  177. groups = def.groups,
  178. _mcl_hardness = 0.8,
  179. _mcl_blast_resistance = 1,
  180. after_dig_node = function(pos, oldnode, oldmetadata, digger)
  181. pos.y = pos.y-1
  182. after_dig_node(pos, name.."_b_1", digger)
  183. end,
  184. on_rightclick = function(pos, node, clicker)
  185. if not minetest.is_protected(pos, clicker:get_player_name()) then
  186. on_rightclick(pos, -1, name.."_b_1", name.."_t_2", name.."_b_2", {1,2,3,0})
  187. end
  188. end,
  189. on_rotate = function(pos, node, user, mode, new_param2)
  190. return on_rotate(pos, node, -1, user, name.."_b_1", mode)
  191. end,
  192. sounds = def.sounds,
  193. sunlight_propagates = def.sunlight,
  194. on_blast = function() end,
  195. })
  196. minetest.register_node(name.."_b_2", {
  197. tiles = {tb[2], tb[2], tb[2], tb[2], tb[1].."^[transformfx", tb[1]},
  198. paramtype = "light",
  199. paramtype2 = "facedir",
  200. use_texture_alpha = "clip",
  201. is_ground_content = false,
  202. drop = name,
  203. drawtype = "nodebox",
  204. node_box = {
  205. type = "fixed",
  206. fixed = def.node_box_bottom
  207. },
  208. selection_box = {
  209. type = "fixed",
  210. fixed = def.selection_box_bottom
  211. },
  212. groups = def.groups,
  213. _mcl_hardness = 0.8,
  214. _mcl_blast_resistance = 1,
  215. after_dig_node = function(pos, oldnode, oldmetadata, digger)
  216. pos.y = pos.y+1
  217. after_dig_node(pos, name.."_t_2", digger)
  218. end,
  219. on_rightclick = function(pos, node, clicker)
  220. if not minetest.is_protected(pos, clicker:get_player_name()) then
  221. on_rightclick(pos, 1, name.."_t_2", name.."_b_1", name.."_t_1", {3,0,1,2})
  222. end
  223. end,
  224. on_rotate = function(pos, node, user, mode, new_param2)
  225. return on_rotate(pos, node, 1, user, name.."_t_2", mode)
  226. end,
  227. sounds = def.sounds,
  228. sunlight_propagates = def.sunlight,
  229. on_blast = function() end,
  230. })
  231. minetest.register_node(name.."_t_2", {
  232. tiles = {tt[2], tt[2], tt[2], tt[2], tt[1].."^[transformfx", tt[1]},
  233. paramtype = "light",
  234. paramtype2 = "facedir",
  235. use_texture_alpha = "clip",
  236. is_ground_content = false,
  237. drop = "",
  238. drawtype = "nodebox",
  239. node_box = {
  240. type = "fixed",
  241. fixed = def.node_box_top
  242. },
  243. selection_box = {
  244. type = "fixed",
  245. fixed = def.selection_box_top
  246. },
  247. groups = def.groups,
  248. _mcl_hardness = 0.8,
  249. _mcl_blast_resistance = 1,
  250. after_dig_node = function(pos, oldnode, oldmetadata, digger)
  251. pos.y = pos.y-1
  252. after_dig_node(pos, name.."_b_2", digger)
  253. end,
  254. on_rightclick = function(pos, node, clicker)
  255. if not minetest.is_protected(pos, clicker:get_player_name()) then
  256. on_rightclick(pos, -1, name.."_b_2", name.."_t_1", name.."_b_1", {3,0,1,2})
  257. end
  258. end,
  259. on_rotate = function(pos, node, user, mode, new_param2)
  260. return on_rotate(pos, node, -1, user, name.."_b_2", mode)
  261. end,
  262. sounds = def.sounds,
  263. sunlight_propagates = def.sunlight,
  264. on_blast = function() end,
  265. })
  266. end
  267. -- Protected Wooden Door
  268. local name = "protector:door_wood"
  269. register_door(name, {
  270. description = S("Protected Wooden Door"),
  271. inventory_image = "doors_wood.png^protector_logo.png",
  272. groups = {
  273. snappy = 1, choppy = 2, dig_immediate = 2,
  274. unbreakable = 1, axey = 1, --door = 1
  275. },
  276. tiles_bottom = {"doors_wood_b.png^protector_logo.png", "doors_brown.png"},
  277. tiles_top = {"doors_wood_a.png", "doors_brown.png"},
  278. sounds = default.node_sound_wood_defaults(),
  279. sunlight = false
  280. })
  281. if protector_crafts then
  282. if mcl then
  283. minetest.register_craft({
  284. output = name,
  285. recipe = {
  286. {"mcl_doors:wooden_door", "mcl_core:gold_ingot"}
  287. }
  288. })
  289. else
  290. minetest.register_craft({
  291. output = name,
  292. recipe = {
  293. {"group:wood", "group:wood"},
  294. {"group:wood", "default:copper_ingot"},
  295. {"group:wood", "group:wood"}
  296. }
  297. })
  298. minetest.register_craft({
  299. output = name,
  300. recipe = {
  301. {"doors:door_wood", "default:copper_ingot"}
  302. }
  303. })
  304. end
  305. end
  306. -- Protected Steel Door
  307. local name = "protector:door_steel"
  308. register_door(name, {
  309. description = S("Protected Steel Door"),
  310. inventory_image = "doors_steel.png^protector_logo.png",
  311. groups = {
  312. snappy = 1, bendy = 2, cracky = 1,
  313. level = mcl and 0 or 2, pickaxey = 2, unbreakable = 1, -- door = 1
  314. },
  315. tiles_bottom = {"doors_steel_b.png^protector_logo.png", "doors_grey.png"},
  316. tiles_top = {"doors_steel_a.png", "doors_grey.png"},
  317. sounds = default.node_sound_metal_defaults(),
  318. sunlight = false,
  319. })
  320. if protector_crafts then
  321. if mcl then
  322. minetest.register_craft({
  323. output = name,
  324. recipe = {
  325. {"mcl_doors:iron_door", "mcl_core:gold_ingot"}
  326. }
  327. })
  328. else
  329. minetest.register_craft({
  330. output = name,
  331. recipe = {
  332. {"default:steel_ingot", "default:steel_ingot"},
  333. {"default:steel_ingot", "default:copper_ingot"},
  334. {"default:steel_ingot", "default:steel_ingot"}
  335. }
  336. })
  337. minetest.register_craft({
  338. output = name,
  339. recipe = {
  340. {"doors:door_steel", "default:copper_ingot"}
  341. }
  342. })
  343. end
  344. end
  345. ----trapdoor----
  346. function register_trapdoor(name, def)
  347. local name_closed = name
  348. local name_opened = name.."_open"
  349. def.on_rightclick = function (pos, node, clicker, itemstack, pointed_thing)
  350. if minetest.is_protected(pos, clicker:get_player_name()) then
  351. return
  352. end
  353. local newname = node.name == name_closed and name_opened or name_closed
  354. local sound = false
  355. if node.name == name_closed then sound = "doors_door_open" end
  356. if node.name == name_opened then sound = "doors_door_close" end
  357. if sound then
  358. minetest.sound_play(sound, {pos = pos, gain = 0.3, max_hear_distance = 10})
  359. end
  360. minetest.swap_node(pos, {name = newname, param1 = node.param1, param2 = node.param2})
  361. end
  362. -- Common trapdoor configuration
  363. def.drawtype = "nodebox"
  364. def.paramtype = "light"
  365. def.paramtype2 = "facedir"
  366. def.use_texture_alpha = "clip"
  367. def.is_ground_content = false
  368. local def_opened = table.copy(def)
  369. local def_closed = table.copy(def)
  370. def_closed.node_box = {
  371. type = "fixed",
  372. fixed = {-0.5, -0.5, -0.5, 0.5, -6/16, 0.5}
  373. }
  374. def_closed.selection_box = {
  375. type = "fixed",
  376. fixed = {-0.5, -0.5, -0.5, 0.5, -6/16, 0.5}
  377. }
  378. def_closed.tiles = { def.tile_front, def.tile_front, def.tile_side, def.tile_side,
  379. def.tile_side, def.tile_side }
  380. def_opened.node_box = {
  381. type = "fixed",
  382. fixed = {-0.5, -0.5, 6/16, 0.5, 0.5, 0.5}
  383. }
  384. def_opened.selection_box = {
  385. type = "fixed",
  386. fixed = {-0.5, -0.5, 6/16, 0.5, 0.5, 0.5}
  387. }
  388. def_opened.tiles = { def.tile_side, def.tile_side,
  389. def.tile_side .. "^[transform3",
  390. def.tile_side .. "^[transform1",
  391. def.tile_front, def.tile_front }
  392. def_opened.drop = name_closed
  393. def_opened.groups.not_in_creative_inventory = 1
  394. minetest.register_node(name_opened, def_opened)
  395. minetest.register_node(name_closed, def_closed)
  396. end
  397. -- Protected Wooden Trapdoor
  398. register_trapdoor("protector:trapdoor", {
  399. description = S("Protected Trapdoor"),
  400. inventory_image = "doors_trapdoor.png^protector_logo.png",
  401. wield_image = "doors_trapdoor.png^protector_logo.png",
  402. tile_front = "doors_trapdoor.png^protector_logo.png",
  403. tile_side = "doors_trapdoor_side.png",
  404. groups = {
  405. snappy = 1, choppy = 2, dig_immediate = 2,
  406. unbreakable = 1, axey = 1, --door = 1
  407. },
  408. _mcl_hardness = 0.8,
  409. _mcl_blast_resistance = 1,
  410. sounds = default.node_sound_wood_defaults(),
  411. })
  412. if protector_crafts then
  413. if mcl then
  414. minetest.register_craft({
  415. output = "protector:trapdoor",
  416. recipe = {
  417. {"mcl_doors:trapdoor", "mcl_core:gold_ingot"}
  418. }
  419. })
  420. else
  421. minetest.register_craft({
  422. output = "protector:trapdoor 2",
  423. recipe = {
  424. {"group:wood", "default:copper_ingot", "group:wood"},
  425. {"group:wood", "group:wood", "group:wood"}
  426. }
  427. })
  428. minetest.register_craft({
  429. output = "protector:trapdoor",
  430. recipe = {
  431. {"doors:trapdoor", "default:copper_ingot"}
  432. }
  433. })
  434. end
  435. end
  436. -- Protected Steel Trapdoor
  437. register_trapdoor("protector:trapdoor_steel", {
  438. description = S("Protected Steel Trapdoor"),
  439. inventory_image = "doors_trapdoor_steel.png^protector_logo.png",
  440. wield_image = "doors_trapdoor_steel.png^protector_logo.png",
  441. tile_front = "doors_trapdoor_steel.png^protector_logo.png",
  442. tile_side = "doors_trapdoor_steel_side.png",
  443. groups = {
  444. snappy = 1, bendy = 2, cracky = 1, melty = 2, level = mcl and 0 or 2,
  445. unbreakable = 1, pickaxey = 2, --door = 1
  446. },
  447. _mcl_hardness = 1,
  448. _mcl_blast_resistance = 1,
  449. sounds = default.node_sound_metal_defaults(),
  450. })
  451. if protector_crafts then
  452. if mcl then
  453. minetest.register_craft({
  454. output = "protector:trapdoor_steel",
  455. recipe = {
  456. {"mcl_doors:iron_trapdoor", "mcl_core:gold_ingot"}
  457. }
  458. })
  459. else
  460. minetest.register_craft({
  461. output = "protector:trapdoor_steel",
  462. recipe = {
  463. {"default:copper_ingot", "default:steel_ingot"},
  464. {"default:steel_ingot", "default:steel_ingot"}
  465. }
  466. })
  467. minetest.register_craft({
  468. output = "protector:trapdoor_steel",
  469. recipe = {
  470. {"doors:trapdoor_steel", "default:copper_ingot"}
  471. }
  472. })
  473. end
  474. end
  475. -- Protected Chest
  476. minetest.register_node("protector:chest", {
  477. description = S("Protected Chest"),
  478. tiles = {
  479. "default_chest_top.png", "default_chest_top.png",
  480. "default_chest_side.png", "default_chest_side.png",
  481. "default_chest_side.png", "default_chest_front.png^protector_logo.png"
  482. },
  483. paramtype2 = "facedir",
  484. groups = {dig_immediate = 2, unbreakable = 1},
  485. legacy_facedir_simple = true,
  486. is_ground_content = false,
  487. sounds = default.node_sound_wood_defaults(),
  488. on_construct = function(pos)
  489. local meta = minetest.get_meta(pos)
  490. local inv = meta:get_inventory()
  491. meta:set_string("infotext", S("Protected Chest"))
  492. meta:set_string("name", S("Protected Chest"))
  493. inv:set_size("main", 8 * 4)
  494. end,
  495. can_dig = function(pos,player)
  496. local meta = minetest.get_meta(pos)
  497. local inv = meta:get_inventory()
  498. if inv:is_empty("main") then
  499. if not minetest.is_protected(pos, player:get_player_name()) then
  500. return true
  501. end
  502. end
  503. end,
  504. on_metadata_inventory_put = function(pos, listname, index, stack, player)
  505. minetest.log("action", player:get_player_name() ..
  506. " moves stuff to protected chest at " ..
  507. minetest.pos_to_string(pos))
  508. end,
  509. on_metadata_inventory_take = function(pos, listname, index, stack, player)
  510. minetest.log("action", player:get_player_name() ..
  511. " takes stuff from protected chest at " ..
  512. minetest.pos_to_string(pos))
  513. end,
  514. on_metadata_inventory_move = function(
  515. pos, from_list, from_index, to_list, to_index, count, player)
  516. minetest.log("action", player:get_player_name() ..
  517. " moves stuff inside protected chest at " ..
  518. minetest.pos_to_string(pos))
  519. end,
  520. allow_metadata_inventory_put = function(pos, listname, index, stack, player)
  521. if minetest.is_protected(pos, player:get_player_name()) then
  522. return 0
  523. end
  524. return stack:get_count()
  525. end,
  526. allow_metadata_inventory_take = function(pos, listname, index, stack, player)
  527. if minetest.is_protected(pos, player:get_player_name()) then
  528. return 0
  529. end
  530. return stack:get_count()
  531. end,
  532. allow_metadata_inventory_move = function(
  533. pos, from_list, from_index, to_list, to_index, count, player)
  534. if minetest.is_protected(pos, player:get_player_name()) then
  535. return 0
  536. end
  537. return count
  538. end,
  539. on_rightclick = function(pos, node, clicker)
  540. if minetest.is_protected(pos, clicker:get_player_name()) then
  541. return
  542. end
  543. local meta = minetest.get_meta(pos)
  544. if not meta then
  545. return
  546. end
  547. local spos = pos.x .. "," .. pos.y .. "," ..pos.z
  548. local formspec
  549. -- mineclone support
  550. if mcl and mcf then
  551. formspec = "size[9,8.75]"
  552. .. "label[0,0;" .. minetest.formspec_escape(
  553. minetest.colorize("#313131", "Protected Chest")) .. "]"
  554. .. "list[nodemeta:" .. spos .. ";main;0,0.5;9,3;]"
  555. .. mcl_formspec.get_itemslot_bg(0,0.5,9,3)
  556. .. "image_button[3.0,3.5;1.05,0.8;protector_up_icon.png;protect_up;]"
  557. .. "image_button[4.0,3.5;1.05,0.8;protector_down_icon.png;protect_down;]"
  558. .. "label[0,4.0;" .. minetest.formspec_escape(
  559. minetest.colorize("#313131", "Inventory")) .. "]"
  560. .. "list[current_player;main;0,4.5;9,3;9]"
  561. .. mcl_formspec.get_itemslot_bg(0,4.5,9,3)
  562. .. "list[current_player;main;0,7.74;9,1;]"
  563. .. mcl_formspec.get_itemslot_bg(0,7.74,9,1)
  564. .. "listring[nodemeta:" .. spos .. ";main]"
  565. .. "listring[current_player;main]"
  566. else -- default formspec
  567. formspec = "size[8,9]"
  568. .. "list[nodemeta:".. spos .. ";main;0,0.3;8,4;]"
  569. .. "image_button[-0.01,4.26;1.05,0.8;protector_up_icon.png;protect_up;]"
  570. .. "image_button[0.98,4.26;1.05,0.8;protector_down_icon.png;protect_down;]"
  571. .. "tooltip[protect_up;" .. S("To Chest") .. "]"
  572. .. "tooltip[protect_down;" .. S("To Inventory") .. "]"
  573. .. "field[2.3,4.8;4,0.25;protect_name;;"
  574. .. meta:get_string("name") .. "]"
  575. .. "button[5.99,4.5;2.05,0.25;protect_rename;" .. S("Rename") .. "]"
  576. .. "list[current_player;main;0,5;8,1;]"
  577. .. "list[current_player;main;0,6.08;8,3;8]"
  578. .. "listring[nodemeta:" .. spos .. ";main]"
  579. .. "listring[current_player;main]"
  580. end
  581. minetest.show_formspec(clicker:get_player_name(),
  582. "protector:chest_" .. minetest.pos_to_string(pos), formspec)
  583. end,
  584. on_blast = function() end,
  585. })
  586. -- Container transfer helper
  587. local to_from = function(src, dst)
  588. local stack, item, leftover
  589. local size = dst:get_size("main")
  590. for i = 1, size do
  591. stack = src:get_stack("main", i)
  592. item = stack:get_name()
  593. if item ~= "" and dst:room_for_item("main", item) then
  594. leftover = dst:add_item("main", stack)
  595. if leftover and not leftover:is_empty() then
  596. src:set_stack("main", i, leftover)
  597. else
  598. src:set_stack("main", i, nil)
  599. end
  600. end
  601. end
  602. end
  603. -- Protected Chest formspec buttons
  604. minetest.register_on_player_receive_fields(function(player, formname, fields)
  605. if string.sub(formname, 0, 16) ~= "protector:chest_" then
  606. return
  607. end
  608. local pos_s = string.sub(formname, 17)
  609. local pos = minetest.string_to_pos(pos_s)
  610. if minetest.is_protected(pos, player:get_player_name()) then
  611. return
  612. end
  613. local meta = minetest.get_meta(pos) ; if not meta then return end
  614. local chest_inv = meta:get_inventory() ; if not chest_inv then return end
  615. local player_inv = player:get_inventory()
  616. -- copy contents of player inventory to chest
  617. if fields.protect_up then
  618. to_from(player_inv, chest_inv)
  619. -- copy contents of chest to player inventory
  620. elseif fields.protect_down then
  621. to_from(chest_inv, player_inv)
  622. elseif fields.protect_name or fields.protect_rename then
  623. -- change chest infotext to display name
  624. if fields.protect_name ~= "" then
  625. if fields.protect_name ~= string.match(fields.protect_name, "[%w%s_-]+")
  626. or fields.protect_name:len() > 35 then
  627. return
  628. end
  629. meta:set_string("name", fields.protect_name)
  630. meta:set_string("infotext", fields.protect_name)
  631. else
  632. meta:set_string("name", S("Protected Chest"))
  633. meta:set_string("infotext", S("Protected Chest"))
  634. end
  635. end
  636. end)
  637. -- Protected Chest recipes
  638. if protector_crafts then
  639. if mcl then
  640. minetest.register_craft({
  641. output = "protector:chest",
  642. recipe = {
  643. {"mcl_chests:chest", "mcl_core:gold_ingot"}
  644. }
  645. })
  646. else
  647. minetest.register_craft({
  648. output = "protector:chest",
  649. recipe = {
  650. {"group:wood", "group:wood", "group:wood"},
  651. {"group:wood", "default:copper_ingot", "group:wood"},
  652. {"group:wood", "group:wood", "group:wood"}
  653. }
  654. })
  655. minetest.register_craft({
  656. output = "protector:chest",
  657. recipe = {
  658. {"default:chest", "default:copper_ingot"}
  659. }
  660. })
  661. end
  662. end