bags.lua 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730
  1. local function get_formspec(name, width, height)
  2. local sizewidth = 8
  3. local txpos = (sizewidth-width)/2
  4. if width >= 8 then
  5. sizewidth = width
  6. txpos = 0
  7. end
  8. local bag_formspec =
  9. "size[".. sizewidth ..",".. height+5 .."]" ..
  10. default.gui_bg ..
  11. default.gui_bg_img ..
  12. default.gui_slots ..
  13. "list[detached:"..name..";main;".. txpos ..",0;".. width ..",".. height ..";]"..
  14. "list[current_player;main;".. (sizewidth-8)/2 ..",".. height+0.85 ..";8,1;]" ..
  15. "list[current_player;main;".. (sizewidth-8)/2 ..",".. height+2.08 ..";8,3;8]" ..
  16. "listring[detached:"..name..";main]"..
  17. "listring[current_player;main]" ..
  18. default.get_hotbar_bg((sizewidth-8)/2,height+0.85)
  19. return bag_formspec
  20. end
  21. local function inv_to_table(inv)
  22. local t = {}
  23. for listname, list in pairs(inv:get_lists()) do
  24. local size = inv:get_size(listname)
  25. if size then
  26. t[listname] = {}
  27. for i = 1, size, 1 do
  28. t[listname][i] = inv:get_stack(listname, i):to_table()
  29. end
  30. end
  31. end
  32. return t
  33. end
  34. local function table_to_inv(inv, t)
  35. for listname, list in pairs(t) do
  36. for i, stack in pairs(list) do
  37. inv:set_stack(listname, i, stack)
  38. end
  39. end
  40. end
  41. -- functions to handle upgrades (can be overridden)
  42. -- called on bag_inv_add_item, bag_inv_remove_item and save_bag_inv_itemstack (called on on_move, on_put and on_take)
  43. function inventorybags.on_change_bag_inv(bagstack, baginv)
  44. return bagstack, baginv
  45. end
  46. -- called on open bag
  47. function inventorybags.on_open_bag(bagstack, baginv, player)
  48. return bagstack, baginv, player
  49. end
  50. -- called on close bag
  51. function inventorybags.on_close_bag(player, fields, name, formname, sound)
  52. return player, fields, name, formname, sound
  53. end
  54. -- called before open bag
  55. function inventorybags.before_open_bag(itemstack, user, width, height, sound)
  56. return itemstack, user, width, height, sound
  57. end
  58. -- called on use bag
  59. function inventorybags.on_use_bag(itemstack, user, pointed_thing)
  60. return itemstack, user, pointed_thing
  61. end
  62. -- called on drop bag
  63. function inventorybags.on_drop_bag(itemstack, dropper, pos)
  64. minetest.item_drop(itemstack, dropper, pos)
  65. return itemstack, dropper, pos
  66. end
  67. local function save_bag_inv_itemstack(inv, stack)
  68. stack, inv = inventorybags.on_change_bag_inv(stack, inv)
  69. local meta = stack:get_meta()
  70. meta:set_string("inventorybags_inv_content", minetest.serialize(inv_to_table(inv)))
  71. return stack
  72. end
  73. local function save_bag_inv(inv, player)
  74. local playerinv = minetest.get_inventory{type="player", name=player:get_player_name()}
  75. local bag_id = inv:get_location().name
  76. local listname = "main"
  77. local size = playerinv:get_size(listname)
  78. for i = 1, size, 1 do
  79. local stack = playerinv:get_stack(listname, i)
  80. local meta = stack:get_meta()
  81. if meta:get_string("inventorybags_bag_identity") == bag_id then
  82. stack = save_bag_inv_itemstack(inv, stack)
  83. playerinv:set_stack(listname, i, stack)
  84. end
  85. end
  86. end
  87. local mod_storage = minetest.get_mod_storage()
  88. local function create_invname(itemstack)
  89. local counter = mod_storage:get_int("counter", value) or 0
  90. counter = counter + 1
  91. mod_storage:set_int("counter", counter)
  92. return itemstack:get_name().."_C_"..counter
  93. end
  94. local function stack_to_player_inv(stack, player)
  95. local payerinv = player:get_inventory()
  96. if payerinv:room_for_item("main", stack) then
  97. payerinv:add_item("main", stack)
  98. else
  99. minetest.item_drop(stack, player, player:get_pos())
  100. end
  101. end
  102. local function open_bag(itemstack, user, width, height, sound)
  103. itemstack, user, width, height, sound = inventorybags.before_open_bag(itemstack, user, width, height, sound)
  104. local allow_bag_input = false
  105. if minetest.get_item_group(itemstack:get_name(), "bag_bag") > 0 then
  106. allow_bag_input = true
  107. end
  108. local meta = itemstack:get_meta()
  109. local playername = user:get_player_name()
  110. local invname = meta:get_string("inventorybags_bag_identity")
  111. -- bag identity
  112. if invname == "" then
  113. local item_count = itemstack:get_count()
  114. if item_count > 1 then
  115. local newitemstack = itemstack:take_item(item_count-1)
  116. minetest.after(0.01, stack_to_player_inv, newitemstack, user)
  117. end
  118. invname = create_invname(itemstack)
  119. meta:set_string("inventorybags_bag_identity", invname)
  120. end
  121. meta:set_int("inventorybags_width", width)
  122. meta:set_int("inventorybags_height", height)
  123. local inv = minetest.create_detached_inventory(invname, {
  124. allow_put = function(inv, listname, index, stack, player)
  125. if allow_bag_input then
  126. if minetest.get_item_group(stack:get_name(), "bag_bag") > 0 then
  127. return 0
  128. end
  129. else
  130. if minetest.get_item_group(stack:get_name(), "bag") > 0 then
  131. return 0
  132. end
  133. end
  134. return stack:get_count()
  135. end,
  136. on_move = function(inv, from_list, from_index, to_list, to_index, count, player)
  137. save_bag_inv(inv, player)
  138. end,
  139. on_put = function(inv, listname, index, stack, player)
  140. save_bag_inv(inv, player)
  141. end,
  142. on_take = function(inv, listname, index, stack, player)
  143. -- fix swap bug
  144. local size = inv:get_size(listname)
  145. for i = 1, size, 1 do
  146. local stack = inv:get_stack(listname, i)
  147. local remove_stack = false
  148. if allow_bag_input then
  149. if minetest.get_item_group(stack:get_name(), "bag_bag") > 0 then
  150. remove_stack = true
  151. end
  152. else
  153. if minetest.get_item_group(stack:get_name(), "bag") > 0 then
  154. remove_stack = true
  155. end
  156. end
  157. if remove_stack == true then
  158. inv:set_stack(listname, i, "")
  159. local playerinv = player:get_inventory()
  160. if playerinv:room_for_item("main", stack) then
  161. playerinv:add_item("main", stack)
  162. else
  163. minetest.item_drop(save_bag_inv_itemstack(inv, stack), player, player:get_pos())
  164. minetest.close_formspec(player:get_player_name(), inv:get_location().name)
  165. end
  166. end
  167. end
  168. save_bag_inv(inv, player)
  169. end,
  170. }, playername)
  171. inv:set_size("main", width*height)
  172. local invmetastring = meta:get_string("inventorybags_inv_content")
  173. if invmetastring ~= "" then
  174. table_to_inv(inv, minetest.deserialize(invmetastring))
  175. itemstack, inv, user = inventorybags.on_open_bag(itemstack, inv, user)
  176. save_bag_inv_itemstack(inv, itemstack)
  177. end
  178. if sound then
  179. minetest.sound_play(sound, {gain = 0.8, object = user, max_hear_distance = 5})
  180. end
  181. minetest.show_formspec(playername, invname, get_formspec(invname, width, height))
  182. return itemstack
  183. end
  184. function inventorybags.bag_inv_add_item(bagstack, itemstack)
  185. local meta = bagstack:get_meta()
  186. local invname = meta:get_string("inventorybags_bag_identity")
  187. if not invname then
  188. return false
  189. end
  190. local inv = minetest.create_detached_inventory(invname, {})
  191. local width = meta:get_int("inventorybags_width")
  192. local height = meta:get_int("inventorybags_height")
  193. inv:set_size("main", width*height)
  194. local invmetastring = meta:get_string("inventorybags_inv_content")
  195. if invmetastring ~= "" then
  196. table_to_inv(inv, minetest.deserialize(invmetastring))
  197. bagstack, inv = inventorybags.on_change_bag_inv(bagstack, inv)
  198. end
  199. if inv:room_for_item("main", itemstack) then
  200. inv:add_item("main", itemstack)
  201. return save_bag_inv_itemstack(inv, bagstack)
  202. end
  203. return false
  204. end
  205. function inventorybags.bag_inv_remove_item(bagstack, itemstack)
  206. local meta = bagstack:get_meta()
  207. local invname = meta:get_string("inventorybags_bag_identity")
  208. if not invname then
  209. return false
  210. end
  211. local inv = minetest.create_detached_inventory(invname, {})
  212. local width = meta:get_int("inventorybags_width")
  213. local height = meta:get_int("inventorybags_height")
  214. inv:set_size("main", width*height)
  215. local invmetastring = meta:get_string("inventorybags_inv_content")
  216. if invmetastring ~= "" then
  217. table_to_inv(inv, minetest.deserialize(invmetastring))
  218. bagstack, inv = inventorybags.on_change_bag_inv(bagstack, inv)
  219. end
  220. if inv:contains_item("main", itemstack) then
  221. inv:remove_item("main", itemstack)
  222. return save_bag_inv_itemstack(inv, bagstack)
  223. end
  224. return false
  225. end
  226. function inventorybags.register_bag(name, bagtable)
  227. minetest.register_craftitem(name, {
  228. description = bagtable.description,
  229. inventory_image = bagtable.inventory_image,
  230. groups = {bag = 1},
  231. on_secondary_use = function(itemstack, user)
  232. return open_bag(itemstack, user, bagtable.width, bagtable.height, bagtable.sound_open)
  233. end,
  234. on_place = function(itemstack, placer, pointed_thing)
  235. return open_bag(itemstack, placer, bagtable.width, bagtable.height, bagtable.sound_open)
  236. end,
  237. on_use = function(itemstack, user, pointed_thing)
  238. return inventorybags.on_use_bag(itemstack, user, pointed_thing)
  239. end,
  240. on_drop = function(itemstack, dropper, pos)
  241. return inventorybags.on_drop_bag(itemstack, dropper, pos)
  242. end
  243. })
  244. minetest.register_on_player_receive_fields(function(player, formname, fields)
  245. local nisformn = string.find(formname, name.."_C_")
  246. if nisformn == 1 then
  247. if fields.quit then
  248. player, fields, name, formname, sound = inventorybags.on_close_bag(player, fields, name, formname, bagtable.sound_close)
  249. if bagtable.sound_close then
  250. minetest.sound_play(sound, {gain = 0.8, object = player, max_hear_distance = 5})
  251. end
  252. end
  253. end
  254. return
  255. end)
  256. end
  257. inventorybags.register_bag("inventorybags:tiny_pouch", {
  258. description = "Tiny Pouch",
  259. inventory_image = "inventorybags_tiny_pouch.png",
  260. width = 1,
  261. height = 1,
  262. sound_open = "inventorybags_open_bag",
  263. sound_close = "inventorybags_close_bag"
  264. })
  265. inventorybags.register_bag("inventorybags:small_pouch", {
  266. description = "Small Pouch",
  267. inventory_image = "inventorybags_small_pouch.png",
  268. width = 2,
  269. height = 2,
  270. sound_open = "inventorybags_open_bag",
  271. sound_close = "inventorybags_close_bag"
  272. })
  273. inventorybags.register_bag("inventorybags:medium_pouch", {
  274. description = "Medium Pouch",
  275. inventory_image = "inventorybags_medium_pouch.png",
  276. width = 3,
  277. height = 3,
  278. sound_open = "inventorybags_open_bag",
  279. sound_close = "inventorybags_close_bag"
  280. })
  281. inventorybags.register_bag("inventorybags:large_pouch", {
  282. description = "Large Pouch",
  283. inventory_image = "inventorybags_large_pouch.png",
  284. width = 4,
  285. height = 4,
  286. sound_open = "inventorybags_open_bag",
  287. sound_close = "inventorybags_close_bag"
  288. })
  289. inventorybags.register_bag("inventorybags:backpack", {
  290. description = "Backpack",
  291. inventory_image = "inventorybags_backpack.png",
  292. width = 8,
  293. height = 4,
  294. sound_open = "inventorybags_open_bag",
  295. sound_close = "inventorybags_close_bag"
  296. })
  297. inventorybags.register_bag("inventorybags:suitcase", {
  298. description = "Suitcase",
  299. inventory_image = "inventorybags_suitcase.png",
  300. width = 8,
  301. height = 4,
  302. sound_open = "inventorybags_open_suitcase",
  303. sound_close = "inventorybags_open_suitcase"
  304. })
  305. inventorybags.register_bag("inventorybags:bag_on_a_stick", {
  306. description = "Bag on a Stick",
  307. inventory_image = "inventorybags_bag_on_a_stick.png",
  308. width = 8,
  309. height = 4,
  310. sound_open = "inventorybags_open_bag",
  311. sound_close = "inventorybags_close_bag"
  312. })
  313. inventorybags.register_bag("inventorybags:belt_bag", {
  314. description = "Belt Bag",
  315. inventory_image = "inventorybags_belt_bag.png",
  316. width = 8,
  317. height = 4,
  318. sound_open = "inventorybags_open_zipper",
  319. sound_close = "inventorybags_close_zipper"
  320. })
  321. inventorybags.register_bag("inventorybags:chest_bag", {
  322. description = "Chest Bag",
  323. inventory_image = "inventorybags_chest_bag.png",
  324. width = 8,
  325. height = 4,
  326. sound_open = "default_chest_open",
  327. sound_close = "default_chest_close"
  328. })
  329. inventorybags.register_bag("inventorybags:hand_bag", {
  330. description = "Hand Bag",
  331. inventory_image = "inventorybags_hand_bag.png",
  332. width = 8,
  333. height = 4,
  334. sound_open = "inventorybags_open_bag",
  335. sound_close = "inventorybags_close_bag"
  336. })
  337. inventorybags.register_bag("inventorybags:satchel", {
  338. description = "Satchel",
  339. inventory_image = "inventorybags_satchel.png",
  340. width = 8,
  341. height = 4,
  342. sound_open = "inventorybags_open_bag",
  343. sound_close = "inventorybags_close_bag"
  344. })
  345. inventorybags.register_bag("inventorybags:paper_bag", {
  346. description = "Paper Bag",
  347. inventory_image = "inventorybags_paper_bag.png",
  348. width = 2,
  349. height = 3,
  350. sound_open = "inventorybags_open_plastic_bag",
  351. sound_close = "inventorybags_close_plastic_bag"
  352. })
  353. if minetest.registered_items["homedecor:plastic_sheeting"] then
  354. inventorybags.register_bag("inventorybags:plastic_bag", {
  355. description = "Plastic Bag",
  356. inventory_image = "inventorybags_plastic_bag.png",
  357. width = 2,
  358. height = 3,
  359. sound_open = "inventorybags_open_plastic_bag",
  360. sound_close = "inventorybags_close_plastic_bag"
  361. })
  362. end
  363. -- special bags
  364. minetest.register_craftitem("inventorybags:bag_transporting_bag", {
  365. description = "Bag Transporting Bag",
  366. inventory_image = "inventorybags_bag_transporting_bag.png",
  367. groups = {bag = 1, bag_bag = 1},
  368. on_secondary_use = function(itemstack, user)
  369. return open_bag(itemstack, user, 2, 2, "inventorybags_open_bag")
  370. end,
  371. on_place = function(itemstack, placer, pointed_thing)
  372. return open_bag(itemstack, placer, 2, 2, "inventorybags_open_bag")
  373. end,
  374. on_use = function(itemstack, user, pointed_thing)
  375. return inventorybags.on_use_bag(itemstack, user, pointed_thing)
  376. end,
  377. on_drop = function(itemstack, dropper, pos)
  378. return inventorybags.on_drop_bag(itemstack, dropper, pos)
  379. end
  380. })
  381. minetest.register_on_player_receive_fields(function(player, formname, fields)
  382. local nisformn = string.find(formname, "inventorybags:bag_transporting_bag_C_")
  383. if nisformn == 1 then
  384. if fields.quit then
  385. player, fields, name, formname, sound = inventorybags.on_close_bag(player, fields, name, formname, "inventorybags_close_bag")
  386. minetest.sound_play(sound, {gain = 0.8, object = player, max_hear_distance = 5})
  387. end
  388. end
  389. return
  390. end)
  391. if minetest.setting_getbool("inventorybags_enable_item_teleportation_bag") then
  392. local function open_teleport_bag_inv(itemstack, placer, pointed_thing)
  393. local location = minetest.deserialize(itemstack:get_meta():get_string("inventorybags_formspec_location"))
  394. if location then
  395. minetest.sound_play("inventorybags_open_teleportation_bag", {gain = 0.8, object = placer, max_hear_distance = 5})
  396. local node = minetest.get_node(location)
  397. -- load the area
  398. local vmie, vmae = VoxelManip():read_from_map(location, location)
  399. if not node then
  400. minetest.chat_send_player(placer:get_player_name(), "Error: area not loaded")
  401. return itemstack
  402. end
  403. local rkfunction = minetest.registered_nodes[node.name].on_rightclick
  404. if rkfunction then
  405. rkfunction(location, node, placer, itemstack, pointed_thing)
  406. else
  407. local nodemeta = minetest.get_meta(location)
  408. local formspec = nodemeta:get_string("formspec")
  409. if formspec then
  410. -- set inv locations
  411. local textbnc = string.find(formspec, "context;")
  412. while textbnc and string.sub(formspec, textbnc-5, textbnc-1) == "list[" do
  413. formspec = string.sub(formspec, 1, textbnc-1).."nodemeta:"..
  414. location.x..","..location.y..","..location.z..string.sub(formspec, textbnc+7)
  415. textbnc = string.find(formspec, "context;")
  416. end
  417. -- deprecated but still used
  418. local textbnd = string.find(formspec, "current_name;")
  419. while textbnd and string.sub(formspec, textbnd-5, textbnd-1) == "list[" do
  420. formspec = string.sub(formspec, 1, textbnd-1).."nodemeta:"..
  421. location.x..","..location.y..","..location.z..string.sub(formspec, textbnd+12)
  422. textbnd = string.find(formspec, "current_name;")
  423. end
  424. minetest.show_formspec(placer:get_player_name(), "inventorybags:item_teleportation_bag", formspec)
  425. end
  426. end
  427. end
  428. return itemstack
  429. end
  430. minetest.register_craftitem("inventorybags:item_teleportation_bag", {
  431. description = "Item Teleportation Bag",
  432. inventory_image = "inventorybags_item_teleportation_bag.png",
  433. groups = {bag = 1},
  434. on_use = function(itemstack, user, pointed_thing)
  435. if user:get_player_control().sneak == true then
  436. if pointed_thing and pointed_thing.type == "node" then
  437. itemstack:get_meta():set_string("inventorybags_formspec_location", minetest.serialize(pointed_thing.under))
  438. minetest.chat_send_player(user:get_player_name(), "Item Teleportation Bag target set to: "..
  439. pointed_thing.under.x..", "..pointed_thing.under.y..", "..pointed_thing.under.z..
  440. " ("..minetest.get_node(pointed_thing.under).name..")"
  441. )
  442. end
  443. else
  444. minetest.chat_send_player(user:get_player_name(), "Hold sneak and left click to set the target of your Item Teleportation Bag")
  445. end
  446. return itemstack
  447. end,
  448. on_secondary_use = function(itemstack, user, pointed_thing)
  449. return open_teleport_bag_inv(itemstack, user, pointed_thing)
  450. end,
  451. on_place = function(itemstack, placer, pointed_thing)
  452. return open_teleport_bag_inv(itemstack, placer, pointed_thing)
  453. end,
  454. })
  455. minetest.register_on_player_receive_fields(function(player, formname, fields)
  456. local nisformn = string.find(formname, "inventorybags:item_teleportation_bag")
  457. if nisformn == 1 then
  458. if fields.quit then
  459. minetest.sound_play("inventorybags_close_teleportation_bag", {gain = 0.8, object = player, max_hear_distance = 5})
  460. end
  461. end
  462. return
  463. end)
  464. end
  465. if minetest.get_modpath("xdecor") then
  466. minetest.register_craftitem("inventorybags:ender_bag", {
  467. description = "Ender Bag",
  468. inventory_image = "inventorybags_ender_bag.png",
  469. groups = {bag = 1},
  470. on_secondary_use = function(itemstack, user)
  471. minetest.sound_play("inventorybags_open_teleportation_bag", {gain = 0.8, object = user, max_hear_distance = 5})
  472. minetest.show_formspec(user:get_player_name(), "inventorybags:ender_bag",
  473. "size[8,9]" ..
  474. default.gui_bg ..
  475. default.gui_bg_img ..
  476. default.gui_slots ..
  477. "list[current_player;enderchest;0,0.3;8,4;]" ..
  478. "list[current_player;main;0,4.85;8,1;]" ..
  479. "list[current_player;main;0,6.08;8,3;8]" ..
  480. "listring[current_player;enderchest]" ..
  481. "listring[current_player;main]" ..
  482. default.get_hotbar_bg(0,4.85)
  483. )
  484. return itemstack
  485. end,
  486. on_place = function(itemstack, placer, pointed_thing)
  487. minetest.sound_play("inventorybags_open_teleportation_bag", {gain = 0.8, object = placer, max_hear_distance = 5})
  488. minetest.show_formspec(placer:get_player_name(), "inventorybags:ender_bag",
  489. "size[8,9]" ..
  490. default.gui_bg ..
  491. default.gui_bg_img ..
  492. default.gui_slots ..
  493. "list[current_player;enderchest;0,0.3;8,4;]" ..
  494. "list[current_player;main;0,4.85;8,1;]" ..
  495. "list[current_player;main;0,6.08;8,3;8]" ..
  496. "listring[current_player;enderchest]" ..
  497. "listring[current_player;main]" ..
  498. default.get_hotbar_bg(0,4.85)
  499. )
  500. return itemstack
  501. end
  502. })
  503. minetest.register_on_player_receive_fields(function(player, formname, fields)
  504. local nisformn = string.find(formname, "inventorybags:ender_bag")
  505. if nisformn == 1 then
  506. if fields.quit then
  507. minetest.sound_play("inventorybags_close_teleportation_bag", {gain = 0.8, object = player, max_hear_distance = 5})
  508. end
  509. end
  510. return
  511. end)
  512. end
  513. if minetest.get_modpath("more_chests") then
  514. minetest.register_craftitem("inventorybags:wifi_bag", {
  515. description = "Wifi Bag",
  516. inventory_image = "inventorybags_wifi_bag.png",
  517. groups = {bag = 1},
  518. on_secondary_use = function(itemstack, user)
  519. minetest.sound_play("inventorybags_open_teleportation_bag", {gain = 0.8, object = user, max_hear_distance = 5})
  520. minetest.show_formspec(user:get_player_name(), "inventorybags:wifi_bag",
  521. "size[8,9]" ..
  522. default.gui_bg ..
  523. default.gui_bg_img ..
  524. default.gui_slots ..
  525. "list[current_player;more_chests:wifi;0,0.3;8,4;]" ..
  526. "list[current_player;main;0,4.85;8,1;]" ..
  527. "list[current_player;main;0,6.08;8,3;8]" ..
  528. "listring[current_player;more_chests:wifi]" ..
  529. "listring[current_player;main]" ..
  530. default.get_hotbar_bg(0,4.85)
  531. )
  532. return itemstack
  533. end,
  534. on_place = function(itemstack, placer, pointed_thing)
  535. minetest.sound_play("inventorybags_open_teleportation_bag", {gain = 0.8, object = placer, max_hear_distance = 5})
  536. minetest.show_formspec(placer:get_player_name(), "inventorybags:wifi_bag",
  537. "size[8,9]" ..
  538. default.gui_bg ..
  539. default.gui_bg_img ..
  540. default.gui_slots ..
  541. "list[current_player;more_chests:wifi;0,0.3;8,4;]" ..
  542. "list[current_player;main;0,4.85;8,1;]" ..
  543. "list[current_player;main;0,6.08;8,3;8]" ..
  544. "listring[current_player;more_chests:wifi]" ..
  545. "listring[current_player;main]" ..
  546. default.get_hotbar_bg(0,4.85)
  547. )
  548. return itemstack
  549. end
  550. })
  551. minetest.register_on_player_receive_fields(function(player, formname, fields)
  552. local nisformn = string.find(formname, "inventorybags:wifi_bag")
  553. if nisformn == 1 then
  554. if fields.quit then
  555. minetest.sound_play("inventorybags_close_teleportation_bag", {gain = 0.8, object = player, max_hear_distance = 5})
  556. end
  557. end
  558. return
  559. end)
  560. end
  561. if minetest.get_modpath("beds") then
  562. minetest.register_craftitem("inventorybags:sleeping_bag", {
  563. description = "Sleeping Bag",
  564. inventory_image = "inventorybags_sleeping_bag.png",
  565. groups = {bag = 1},
  566. on_secondary_use = function(itemstack, user)
  567. minetest.sound_play("inventorybags_sleeping", {gain = 1, object = user, max_hear_distance = 5})
  568. beds.on_rightclick(user:get_pos(), user)
  569. end,
  570. on_place = function(itemstack, placer, pointed_thing)
  571. minetest.sound_play("inventorybags_sleeping", {gain = 1, object = placer, max_hear_distance = 5})
  572. beds.on_rightclick(placer:get_pos(), placer)
  573. end
  574. })
  575. end
  576. if not minetest.setting_getbool("inventorybags_dialable_bag_of_winds") then
  577. local gravity_change = -1.5
  578. local function set_physics_normal(player)
  579. local physics = player:get_physics_override()
  580. physics.gravity = 1
  581. player:set_physics_override(physics)
  582. end
  583. local function set_physics_normal_inv_check(player, extratable)
  584. if player:get_wielded_item():get_name() == "inventorybags:bag_of_winds_opened" then
  585. minetest.after(1, set_physics_normal_inv_check, player, extratable)
  586. else
  587. set_physics_normal(player)
  588. minetest.sound_stop(extratable.handle)
  589. local inv = player:get_inventory()
  590. local lostbag = false
  591. while inv:contains_item("main", "inventorybags:bag_of_winds_opened") do
  592. lostbag = true
  593. local itemstack = inv:remove_item("main", "inventorybags:bag_of_winds_opened")
  594. itemstack:set_name("inventorybags:bag_of_winds_closed")
  595. minetest.item_drop(itemstack, player, player:get_pos())
  596. end
  597. while inv:contains_item("craft", "inventorybags:bag_of_winds_opened") do
  598. lostbag = true
  599. local itemstack = inv:remove_item("craft", "inventorybags:bag_of_winds_opened")
  600. itemstack:set_name("inventorybags:bag_of_winds_closed")
  601. minetest.item_drop(itemstack, player, player:get_pos())
  602. end
  603. if lostbag then
  604. minetest.chat_send_player(player:get_player_name(), "You lost your Bag of Winds.")
  605. end
  606. end
  607. end
  608. local function set_new_physics(player, itemstack)
  609. local physics = player:get_physics_override()
  610. local extratable = {}
  611. extratable.handle = minetest.sound_play("inventorybags_wind", {gain = 1, object = player, max_hear_distance = 5, loop = true})
  612. physics.gravity = 1*gravity_change+physics.gravity
  613. player:set_physics_override(physics)
  614. minetest.after(1, set_physics_normal_inv_check, player, extratable)
  615. end
  616. local function open_bag_of_winds(player, itemstack)
  617. local meta = itemstack:get_meta()
  618. set_new_physics(player, itemstack)
  619. itemstack:set_name("inventorybags:bag_of_winds_opened")
  620. return itemstack
  621. end
  622. local function close_bag_of_winds(player, itemstack)
  623. set_physics_normal(player)
  624. itemstack:set_name("inventorybags:bag_of_winds_closed")
  625. return itemstack
  626. end
  627. minetest.register_craftitem("inventorybags:bag_of_winds_closed", {
  628. description = "Bag of Winds",
  629. inventory_image = "inventorybags_bag_of_winds_closed.png",
  630. groups = {bag = 1},
  631. on_secondary_use = function(itemstack, user, pointed_thing)
  632. itemstack = open_bag_of_winds(user, itemstack)
  633. return itemstack
  634. end,
  635. on_place = function(itemstack, placer, pointed_thing)
  636. itemstack = open_bag_of_winds(placer, itemstack)
  637. return itemstack
  638. end,
  639. })
  640. minetest.register_craftitem("inventorybags:bag_of_winds_opened", {
  641. description = "Bag of Winds",
  642. inventory_image = "inventorybags_bag_of_winds_opened.png",
  643. groups = {bag = 1, not_in_creative_inventory = 1},
  644. on_secondary_use = function(itemstack, user, pointed_thing)
  645. itemstack = close_bag_of_winds(user, itemstack)
  646. return itemstack
  647. end,
  648. on_place = function(itemstack, placer, pointed_thing)
  649. itemstack = close_bag_of_winds(placer, itemstack)
  650. return itemstack
  651. end,
  652. on_drop = function(itemstack, dropper, pos)
  653. itemstack:set_name("inventorybags:bag_of_winds_closed")
  654. minetest.item_drop(itemstack, dropper, pos)
  655. return itemstack
  656. end
  657. })
  658. end