upgrades.lua 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671
  1. local function register_upgrade(data)
  2. minetest.register_craftitem(data.name, {
  3. description = data.description,
  4. inventory_image = data.inventory_image,
  5. groups = {inventorybags_upgrade = 1}
  6. })
  7. if not data.meta_string then
  8. data.meta_string = "true"
  9. end
  10. local setting = ""
  11. if not data.help_setting then
  12. setting = "#7bff00Setting:,Irrelevant"
  13. else
  14. setting = "#7bff00Setting:," .. data.help_setting
  15. end
  16. inventorybags.bud_recipes[data.name] = {
  17. name = data.name,
  18. meta_name = data.meta_name,
  19. meta_string = data.meta_string,
  20. setting_meta_name = data.setting_meta_name,
  21. setting_type = data.setting_type
  22. }
  23. inventorybags.upgrade_help_string =
  24. inventorybags.upgrade_help_string .."," ..
  25. "#ffa500" .. data.description .. ": ,".. data.help .. "," ..
  26. setting .. ","
  27. end
  28. local function string_list_to_table(setstring)
  29. local new_table = {}
  30. local notstop = true
  31. while notstop do
  32. local numstring = string.find(setstring, ",")
  33. if numstring then
  34. table.insert(new_table, string.sub(setstring, 1, numstring-1))
  35. setstring = string.sub(setstring, numstring+1)
  36. else
  37. table.insert(new_table, setstring)
  38. notstop = false
  39. end
  40. end
  41. return new_table
  42. end
  43. local function get_omodname(stackname)
  44. return string.sub(stackname, 1, string.find(stackname, ":")-1)
  45. end
  46. local function get_oname(stackname)
  47. return string.sub(stackname, string.find(stackname, ":")+1)
  48. end
  49. local function table_contains(v, t)
  50. for _, i in pairs(t) do
  51. if i == v then
  52. return true
  53. end
  54. end
  55. return false
  56. end
  57. local function match_filter(filter_table, stackname)
  58. if stackname == "" or not stackname then
  59. return false
  60. end
  61. -- blacklist
  62. local blacklist_match = 0
  63. if type(filter_table.blacklist_items) == "table" and table.maxn(filter_table.blacklist_items) ~= 0 then
  64. if table_contains(stackname, filter_table.blacklist_items) then
  65. blacklist_match = blacklist_match + 1
  66. end
  67. end
  68. if type(filter_table.group_filter_blacklist) == "string" and filter_table.group_filter_blacklist ~= "" then
  69. for _, group in pairs(string_list_to_table(filter_table.group_filter_blacklist)) do
  70. if minetest.get_item_group(stackname, group) > 0 then
  71. blacklist_match = blacklist_match + 1
  72. end
  73. end
  74. end
  75. if type(filter_table.mod_filter_blacklist) == "string" and filter_table.mod_filter_blacklist ~= "" then
  76. if table_contains(get_omodname(stackname), string_list_to_table(filter_table.mod_filter_blacklist)) then
  77. blacklist_match = blacklist_match + 1
  78. end
  79. end
  80. if type(filter_table.name_filter_blacklist) == "string" and filter_table.name_filter_blacklist ~= "" then
  81. for _, text in pairs(string_list_to_table(filter_table.name_filter_blacklist)) do
  82. if string.find(get_oname(stackname),text) then
  83. blacklist_match = blacklist_match + 1
  84. end
  85. end
  86. end
  87. -- whitelist
  88. local whitelist_match = 0
  89. local whitelist_exist = false
  90. if type(filter_table.whitelist_items) == "table" and table.maxn(filter_table.whitelist_items) ~= 0 then
  91. whitelist_exist = true
  92. if table_contains(stackname, filter_table.whitelist_items) then
  93. whitelist_match = whitelist_match + 1
  94. end
  95. end
  96. if type(filter_table.group_filter_whitelist) == "string" and filter_table.group_filter_whitelist ~= "" then
  97. whitelist_exist = true
  98. for _, group in pairs(string_list_to_table(filter_table.group_filter_whitelist)) do
  99. if minetest.get_item_group(stackname, group) > 0 then
  100. whitelist_match = whitelist_match + 1
  101. end
  102. end
  103. end
  104. if type(filter_table.mod_filter_whitelist) == "string" and filter_table.mod_filter_whitelist ~= "" then
  105. whitelist_exist = true
  106. if table_contains(get_omodname(stackname), string_list_to_table(filter_table.mod_filter_whitelist)) then
  107. whitelist_match = whitelist_match + 1
  108. end
  109. end
  110. if type(filter_table.name_filter_whitelist) == "string" and filter_table.name_filter_whitelist ~= "" then
  111. whitelist_exist = true
  112. for _, text in pairs(string_list_to_table(filter_table.name_filter_whitelist)) do
  113. if string.find(get_oname(stackname),text) then
  114. whitelist_match = whitelist_match + 1
  115. end
  116. end
  117. end
  118. if blacklist_match > 0 or (whitelist_exist and whitelist_match == 0) then
  119. return false
  120. else
  121. return true
  122. end
  123. end
  124. -- Rename Upgrade
  125. register_upgrade({
  126. name = "inventorybags:rename_upgrade",
  127. description = "Rename Upgrade",
  128. inventory_image = "inventorybags_upgrade_base.png^inventorybags_rename_upgrade.png",
  129. meta_name = "inventorybags_rename_upgrade",
  130. help = "Renames your bag.",
  131. setting_meta_name = "description",
  132. help_setting = 'The new name of your bag. ( Example: "The best bag in the world" )'
  133. })
  134. -- Coloring Upgrade
  135. register_upgrade({
  136. name = "inventorybags:coloring_upgrade",
  137. description = "Coloring Upgrade",
  138. inventory_image = "inventorybags_upgrade_base.png^inventorybags_coloring_upgrade.png",
  139. meta_name = "inventorybags_coloring_upgrade",
  140. help = "Colors your bag.",
  141. setting_meta_name = "color",
  142. setting_type = "color",
  143. help_setting = 'The color of your bag. ( You can use the setting creator. )'
  144. })
  145. -- Storage Upgrades
  146. register_upgrade({
  147. name = "inventorybags:storage_upgrade_tier_1",
  148. description = "Storage Upgrade Tier 1",
  149. inventory_image = "inventorybags_upgrade_base.png^inventorybags_storage_upgrade_tier_1.png",
  150. meta_name = "inventorybags_storage_upgrade_tier_1",
  151. help = "Increases the inventory height and width by at least one.",
  152. })
  153. register_upgrade({
  154. name = "inventorybags:storage_upgrade_tier_2",
  155. description = "Storage Upgrade Tier 2",
  156. inventory_image = "inventorybags_upgrade_base.png^inventorybags_storage_upgrade_tier_2.png",
  157. meta_name = "inventorybags_storage_upgrade_tier_2",
  158. help = "Increases the inventory height and width by at least one. ( You have to install all tiers. )",
  159. })
  160. register_upgrade({
  161. name = "inventorybags:storage_upgrade_tier_3",
  162. description = "Storage Upgrade Tier 3",
  163. inventory_image = "inventorybags_upgrade_base.png^inventorybags_storage_upgrade_tier_3.png",
  164. meta_name = "inventorybags_storage_upgrade_tier_3",
  165. help = "Increases the inventory height and width by at least one. ( You have to install all tiers. )",
  166. })
  167. local function increase_bag_size(width, height, bwidth, bheight)
  168. if bwidth > bheight then
  169. local wdh = bwidth / bheight
  170. height = height + 1
  171. width = bwidth + math.floor((height - bheight) * wdh)
  172. else
  173. local hdw = bheight / bwidth
  174. width = width + 1
  175. height = bheight + math.floor((width - bwidth) * hdw)
  176. end
  177. return width, height
  178. end
  179. local old_before_open_bag = inventorybags.before_open_bag
  180. function inventorybags.before_open_bag(itemstack, user, width, height, sound)
  181. local meta = itemstack:get_meta()
  182. local bwidth, bheight = width, height
  183. if meta:get_string("inventorybags_storage_upgrade_tier_1") == "true" then
  184. width, height = increase_bag_size(width, height, bwidth, bheight)
  185. end
  186. if meta:get_string("inventorybags_storage_upgrade_tier_2") == "true" then
  187. width, height = increase_bag_size(width, height, bwidth, bheight)
  188. end
  189. if meta:get_string("inventorybags_storage_upgrade_tier_3") == "true" then
  190. width, height = increase_bag_size(width, height, bwidth, bheight)
  191. end
  192. return old_before_open_bag(itemstack, user, width, height, sound)
  193. end
  194. -- Collecting Upgrades
  195. register_upgrade({
  196. name = "inventorybags:collecting_upgrade",
  197. description = "Collecting Upgrade",
  198. inventory_image = "inventorybags_upgrade_base.png^inventorybags_collecting_upgrade.png",
  199. meta_name = "inventorybags_collecting_upgrade",
  200. help = "Puts node drops into your bag.",
  201. setting_meta_name = "inventorybags_collecting_filter",
  202. setting_type = "filter",
  203. help_setting = 'A filter string ( use the setting creator ).'
  204. })
  205. register_upgrade({
  206. name = "inventorybags:advanced_collecting_upgrade",
  207. description = "Advanced Collecting Upgrade",
  208. inventory_image = "inventorybags_upgrade_base.png^inventorybags_advanced_collecting_upgrade.png",
  209. meta_name = "inventorybags_advanced_collecting_upgrade",
  210. help = "Puts all items into your bag.",
  211. setting_meta_name = "inventorybags_advanced_collecting_filter",
  212. setting_type = "filter",
  213. help_setting = 'A filter string ( use the setting creator ).'
  214. })
  215. local old_on_open_bag = inventorybags.on_open_bag
  216. function inventorybags.on_open_bag(bagstack, baginv, player)
  217. local meta = bagstack:get_meta()
  218. local inv = player:get_inventory()
  219. local size = inv:get_size("main")
  220. if meta:get_string("inventorybags_advanced_collecting_upgrade") == "true" then
  221. for k = 1, size, 1 do
  222. local astack = inv:get_stack("main", k)
  223. if astack and minetest.get_item_group(astack:get_name(), "bag") == 0 then
  224. local fadd_item = true
  225. local filter_table = minetest.deserialize(meta:get_string("inventorybags_advanced_collecting_filter"))
  226. if filter_table then
  227. if not match_filter(filter_table, astack:get_name()) then
  228. fadd_item = false
  229. end
  230. end
  231. if fadd_item == true then
  232. if inv:room_for_item("main", astack) then
  233. inv:remove_item("main", astack)
  234. baginv:add_item("main", astack)
  235. end
  236. end
  237. end
  238. end
  239. end
  240. return old_on_open_bag(bagstack, baginv, player)
  241. end
  242. minetest.register_on_dignode(function(pos, oldnode, digger)
  243. if not digger then
  244. return
  245. end
  246. local inv = digger:get_inventory()
  247. if not inv then
  248. return
  249. end
  250. local drops = minetest.get_node_drops(oldnode.name, digger:get_wielded_item():get_name())
  251. local size = inv:get_size("main")
  252. local done_coll = false
  253. local done_acoll = false
  254. for i = 1, size, 1 do
  255. local stack = inv:get_stack("main", i)
  256. local meta = stack:get_meta()
  257. if minetest.get_item_group(stack:get_name(), "bag") > 0 then
  258. if meta:get_string("inventorybags_collecting_upgrade") == "true" and not done_coll then
  259. for drn, drop in pairs(drops) do
  260. if inv:contains_item("main", drop) and minetest.get_item_group(drop, "bag") == 0 then
  261. local fadd_item = true
  262. local filter_table = minetest.deserialize(meta:get_string("inventorybags_collecting_filter"))
  263. if filter_table then
  264. if not match_filter(filter_table, drop) then
  265. fadd_item = false
  266. end
  267. end
  268. if fadd_item == true then
  269. local newstack = inventorybags.bag_inv_add_item(stack, drop)
  270. if newstack then
  271. inv:remove_item("main", drop)
  272. inv:set_stack("main", i, newstack)
  273. done_coll = true
  274. end
  275. end
  276. end
  277. end
  278. end
  279. if meta:get_string("inventorybags_advanced_collecting_upgrade") == "true" and not done_acoll then
  280. for k = 1, size, 1 do
  281. local astack = inv:get_stack("main", k)
  282. if astack and minetest.get_item_group(astack:get_name(), "bag") == 0 then
  283. local fadd_item = true
  284. local filter_table = minetest.deserialize(meta:get_string("inventorybags_advanced_collecting_filter"))
  285. if filter_table then
  286. if not match_filter(filter_table, astack:get_name()) then
  287. fadd_item = false
  288. end
  289. end
  290. if fadd_item == true then
  291. local newstack = inventorybags.bag_inv_add_item(stack, astack)
  292. if newstack then
  293. inv:remove_item("main", astack)
  294. inv:set_stack("main", i, newstack)
  295. done_acoll = true
  296. end
  297. end
  298. end
  299. end
  300. end
  301. end
  302. end
  303. end)
  304. -- Sorting Upgrade
  305. register_upgrade({
  306. name = "inventorybags:sorting_upgrade",
  307. description = "Sorting Upgrade",
  308. inventory_image = "inventorybags_upgrade_base.png^inventorybags_sorting_upgrade.png",
  309. meta_name = "inventorybags_sorting_upgrade",
  310. help = "Sorts all items in your bag."
  311. })
  312. local old_on_open_bag = inventorybags.on_open_bag
  313. function inventorybags.on_open_bag(bagstack, baginv, player)
  314. local meta = bagstack:get_meta()
  315. if meta:get_string("inventorybags_sorting_upgrade") == "true" then
  316. inventorybags.sort_inventory(baginv)
  317. end
  318. return old_on_open_bag(bagstack, baginv, player)
  319. end
  320. -- Dumping Upgrade
  321. register_upgrade({
  322. name = "inventorybags:dumping_upgrade",
  323. description = "Dumping Upgrade",
  324. inventory_image = "inventorybags_upgrade_base.png^inventorybags_dumping_upgrade.png",
  325. meta_name = "inventorybags_dumping_upgrade",
  326. help = "Destroys every item in your bag.",
  327. setting_meta_name = "inventorybags_dumping_filter",
  328. setting_type = "filter",
  329. help_setting = 'A filter string ( use the setting creator ).'
  330. })
  331. local old_on_change_bag_inv = inventorybags.on_change_bag_inv
  332. function inventorybags.on_change_bag_inv(bagstack, baginv)
  333. local meta = bagstack:get_meta()
  334. if meta:get_string("inventorybags_dumping_upgrade") == "true" then
  335. local size = baginv:get_size("main")
  336. local filter_table = minetest.deserialize(meta:get_string("inventorybags_dumping_filter"))
  337. if filter_table then
  338. for i = 1, size, 1 do
  339. local stack = baginv:get_stack("main", i)
  340. if match_filter(filter_table, stack:get_name()) then
  341. baginv:set_stack("main", i, "")
  342. end
  343. end
  344. else
  345. for i = 1, size, 1 do
  346. baginv:set_stack("main", i, "")
  347. end
  348. end
  349. end
  350. return old_on_change_bag_inv(bagstack, baginv)
  351. end
  352. -- Sound Upgrades
  353. register_upgrade({
  354. name = "inventorybags:opening_sound_upgrade",
  355. description = "Opening Sound Upgrade",
  356. inventory_image = "inventorybags_upgrade_base.png^inventorybags_sound_upgrade.png",
  357. meta_name = "inventorybags_opening_sound_upgrade",
  358. help = "Plays a sound when you are opening your bag.",
  359. setting_meta_name = "inventorybags_opening_sound",
  360. help_setting = 'The name of a sound. ( Examples: "inventorybags_open_zipper" "default_break_glass" "tnt_explode" )'
  361. })
  362. local old_before_open_bag = inventorybags.before_open_bag
  363. function inventorybags.before_open_bag(itemstack, user, width, height, sound)
  364. local meta = itemstack:get_meta()
  365. if meta:get_string("inventorybags_opening_sound_upgrade") == "true" then
  366. sound = meta:get_string("inventorybags_opening_sound")
  367. end
  368. return old_before_open_bag(itemstack, user, width, height, sound)
  369. end
  370. register_upgrade({
  371. name = "inventorybags:closing_sound_upgrade",
  372. description = "Closing Sound Upgrade",
  373. inventory_image = "inventorybags_upgrade_base.png^(inventorybags_sound_upgrade.png^[transform2)",
  374. meta_name = "inventorybags_closing_sound_upgrade",
  375. help = "Plays a sound when you are closing your bag.",
  376. setting_meta_name = "inventorybags_closing_sound",
  377. help_setting = 'The name of a sound. ( Examples: "inventorybags_close_zipper" "default_dig_metal" "player_damage" )'
  378. })
  379. local old_on_close_bag = inventorybags.on_close_bag
  380. function inventorybags.on_close_bag(player, fields, name, formname, sound)
  381. local inv = player:get_inventory()
  382. local size = inv:get_size("main")
  383. local bagstacki = nil
  384. for i = 1, size, 1 do
  385. local stack = inv:get_stack("main", i)
  386. local meta = stack:get_meta()
  387. if stack:get_name() == name and meta:get_string("inventorybags_bag_identity") == formname then
  388. bagstacki = i
  389. break
  390. end
  391. end
  392. if bagstacki then
  393. local itemstack = inv:get_stack("main", bagstacki)
  394. local meta = itemstack:get_meta()
  395. if meta:get_string("inventorybags_closing_sound_upgrade") == "true" then
  396. sound = meta:get_string("inventorybags_closing_sound")
  397. end
  398. end
  399. return old_on_close_bag(player, fields, name, formname, sound)
  400. end
  401. -- Autocrafting Upgrade
  402. register_upgrade({
  403. name = "inventorybags:autocrafting_upgrade",
  404. description = "Autocrafting Upgrade",
  405. inventory_image = "inventorybags_upgrade_base.png^inventorybags_autocrafting_upgrade.png",
  406. meta_name = "inventorybags_autocrafting_upgrade",
  407. help = "Crafts items automatically.",
  408. setting_meta_name = "inventorybags_autocrafting_recipes",
  409. setting_type = "crafting",
  410. help_setting = 'A list of crafting recipes ( use the setting creator ).'
  411. })
  412. local function make_max_crafting(inv, recipes)
  413. local size = inv:get_size("main")
  414. local inv_table = {}
  415. for i = 1, size, 1 do
  416. local stack = inv:get_stack("main", i)
  417. local stack_name = stack:get_name()
  418. local stack_count = stack:get_count()
  419. if stack_count > 0 then
  420. if inv_table[stack_name] then
  421. inv_table[stack_name] = inv_table[stack_name] + stack_count
  422. else
  423. inv_table[stack_name] = stack_count
  424. end
  425. end
  426. end
  427. local recipes_table = {}
  428. for j, recipe in pairs(recipes) do
  429. local craft_result = minetest.get_craft_result({items = recipe, method = "normal", width = 3}).item
  430. if craft_result:get_count() > 0 then
  431. recipes_table[j] = {}
  432. for k, citem in pairs(recipe) do
  433. if citem ~= "" then
  434. if recipes_table[j][citem] then
  435. recipes_table[j][citem] = recipes_table[j][citem] + 1
  436. else
  437. recipes_table[j][citem] = 1
  438. end
  439. end
  440. end
  441. end
  442. end
  443. local rcounter = 1
  444. local nrecipes = #recipes_table
  445. while nrecipes > 0 do
  446. if rcounter > nrecipes then
  447. rcounter = 1
  448. end
  449. local recipe = recipes_table[nrecipes]
  450. local craft_results = minetest.get_craft_result({items = recipes[nrecipes], method = "normal", width = 3})
  451. local stop_sequence = false
  452. if not inv:room_for_item("main", craft_results.item) then
  453. stop_sequence = true
  454. elseif craft_results.replacements then
  455. for _, replacement in pairs(craft_results.replacements) do
  456. if not inv:room_for_item("main", replacement) then
  457. stop_sequence = true
  458. end
  459. end
  460. end
  461. if not stop_sequence then
  462. for citem, count in pairs(recipe) do
  463. if not( inv_table[citem] and inv_table[citem] >= count ) then
  464. stop_sequence = true
  465. end
  466. end
  467. end
  468. if not stop_sequence then
  469. for citem, count in pairs(recipe) do
  470. inv_table[citem] = inv_table[citem] - count
  471. inv:remove_item("main", {name = citem, count = count})
  472. end
  473. inv:add_item("main", craft_results.item)
  474. for _, replacement in pairs(craft_results.replacements) do
  475. inv:add_item("main", replacement)
  476. end
  477. else
  478. recipes_table[nrecipes] = nil
  479. nrecipes = nrecipes -1
  480. end
  481. rcounter = rcounter+1
  482. end
  483. end
  484. local old_on_change_bag_inv = inventorybags.on_change_bag_inv
  485. function inventorybags.on_change_bag_inv(bagstack, baginv)
  486. local meta = bagstack:get_meta()
  487. if meta:get_string("inventorybags_autocrafting_upgrade") == "true" then
  488. local setting_table = minetest.deserialize(meta:get_string("inventorybags_autocrafting_recipes"))
  489. if setting_table then
  490. local recipes = setting_table.recipe_items
  491. if recipes then
  492. make_max_crafting(baginv, recipes)
  493. end
  494. end
  495. end
  496. return old_on_change_bag_inv(bagstack, baginv)
  497. end
  498. -- Refilling Upgrade
  499. register_upgrade({
  500. name = "inventorybags:refilling_upgrade",
  501. description = "Refilling Upgrade",
  502. inventory_image = "inventorybags_upgrade_base.png^inventorybags_refilling_upgrade.png",
  503. meta_name = "inventorybags_refilling_upgrade",
  504. help = "Automatically refills your stack on placing.",
  505. })
  506. minetest.register_on_placenode(function(pos, newnode, placer, oldnode, itemstack, pointed_thing)
  507. if not placer then
  508. return
  509. end
  510. local inv = placer:get_inventory()
  511. if not inv then
  512. return
  513. end
  514. local size = inv:get_size("main")
  515. for i = 1, size, 1 do
  516. local bagstack = inv:get_stack("main", i)
  517. local meta = bagstack:get_meta()
  518. if minetest.get_item_group(bagstack:get_name(), "bag") > 0 and
  519. meta:get_string("inventorybags_refilling_upgrade") == "true" then
  520. local free_space = itemstack:get_free_space()
  521. local rem_bagstack = nil
  522. if free_space > 0 then
  523. rem_bagstack = inventorybags.bag_inv_remove_item(bagstack, itemstack:peek_item(1))
  524. if rem_bagstack then
  525. itemstack:set_count(itemstack:get_count()+1)
  526. free_space = itemstack:get_free_space()
  527. end
  528. end
  529. while free_space > 0 and rem_bagstack do
  530. bagstack = rem_bagstack
  531. itemstack:set_count(itemstack:get_count()+1)
  532. free_space = itemstack:get_free_space()
  533. rem_bagstack = inventorybags.bag_inv_remove_item(bagstack, itemstack:peek_item(1))
  534. end
  535. inv:set_stack("main", i, bagstack)
  536. end
  537. end
  538. end)
  539. -- Explosion Upgrade
  540. local enable_tnt = minetest.settings:get_bool("enable_tnt")
  541. if enable_tnt == nil then
  542. enable_tnt = minetest.is_singleplayer()
  543. end
  544. if minetest.get_modpath("tnt") and enable_tnt then
  545. register_upgrade({
  546. name = "inventorybags:explosion_upgrade",
  547. description = "Explosion Upgrade",
  548. inventory_image = "inventorybags_upgrade_base.png^inventorybags_explosion_upgrade.png",
  549. meta_name = "inventorybags_explosion_upgrade",
  550. help = "If you drop your bag it explodes after some time. ( You will lose the bag. ),"..
  551. "You can also hold sneak and left click to blast the bag instantly.,"..
  552. "The explosion radius depends on how much TNT do you have in your bag.",
  553. setting_meta_name = "inventorybags_explosion_upgrade_time",
  554. help_setting = 'The time before the bag explodes in seconds (1-30). (default 4)'
  555. })
  556. local old_on_drop_bag = inventorybags.on_drop_bag
  557. function inventorybags.on_drop_bag(itemstack, dropper, pos)
  558. local meta = itemstack:get_meta()
  559. if meta:get_string("inventorybags_explosion_upgrade") == "true" then
  560. local dtime = tonumber(meta:get_string("inventorybags_explosion_upgrade_time")) or 4
  561. if dtime > 30 then
  562. dtime = 30
  563. end
  564. local itemname = itemstack:get_name()
  565. local color = meta:get_string("color") or ""
  566. if color ~= "" and string.len(color) == 7 and string.sub(color,1,1) == "#" then
  567. color = "^[multiply:"..color
  568. else
  569. color = ""
  570. end
  571. local def = {}
  572. local tnt_radius = tonumber(minetest.settings:get("tnt_radius") or 3)
  573. local n = 0 --n >= 1
  574. local old_itemstack = itemstack
  575. while old_itemstack do
  576. n = n + 1
  577. old_itemstack = inventorybags.bag_inv_remove_item(itemstack, "tnt:tnt")
  578. end
  579. itemstack:take_item()
  580. def.radius = tnt_radius*(n^(1/3))
  581. def.damage_radius = def.radius * 2
  582. minetest.sound_play("tnt_ignite", {pos = pos})
  583. minetest.after(dtime, tnt.boom, pos, def)
  584. minetest.add_particle({
  585. pos = pos,
  586. expirationtime = dtime,
  587. size = def.radius * 2,
  588. collisiondetection = false,
  589. vertical = false,
  590. texture = minetest.registered_items[itemname].inventory_image..color,
  591. })
  592. return itemstack, dropper, pos
  593. end
  594. return old_on_drop_bag(itemstack, dropper, pos)
  595. end
  596. local old_on_use_bag = inventorybags.on_use_bag
  597. function inventorybags.on_use_bag(itemstack, user, pointed_thing)
  598. local meta = itemstack:get_meta()
  599. if meta:get_string("inventorybags_explosion_upgrade") == "true" and user:get_player_control().sneak == true then
  600. local pos = user:get_pos()
  601. local def = {}
  602. local tnt_radius = tonumber(minetest.settings:get("tnt_radius") or 3)
  603. local n = 0 --n >= 1
  604. local old_itemstack = itemstack
  605. while old_itemstack do
  606. n = n + 1
  607. old_itemstack = inventorybags.bag_inv_remove_item(itemstack, "tnt:tnt")
  608. end
  609. itemstack:take_item()
  610. def.radius = tnt_radius*(n^(1/3))
  611. def.damage_radius = def.radius * 2
  612. tnt.boom(pos, def)
  613. return itemstack, dropper, pos
  614. end
  615. return old_on_use_bag(itemstack, user, pointed_thing)
  616. end
  617. end