init.lua 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. -- liblevelup mod for Minetest
  2. -- Copyright © 2017-2019 Alex Yst <mailto:copyright@y.st>
  3. -- This program is free software; you can redistribute it and/or
  4. -- modify it under the terms of the GNU Lesser General Public
  5. -- License as published by the Free Software Foundation; either
  6. -- version 2.1 of the License, or (at your option) any later version.
  7. -- This software is distributed in the hope that it will be useful,
  8. -- but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  10. -- Lesser General Public License for more details.
  11. -- You should have received a copy of the GNU Lesser General Public
  12. -- License along with this program. If not, see
  13. -- <https://www.gnu.org./licenses/>.
  14. dofile(minetest.get_modpath("liblevelup").."/API.lua")
  15. -- This constant tells other mods that depend on this one that the
  16. -- minerals, saplings, seeds, and spores from Minetest Game versions
  17. -- 0.4.0 through 5.4.1, Minimal 0.4.0 through 5.2.0, Development Test
  18. -- 5.3.0 through 5.4.2, Build 0.4.6, and Survival 0.4.6 are properly
  19. -- detected. Each time a new version of the engine is released with
  20. -- corresponding versions of is official subgames, this number will be
  21. -- incremented by one. Normally, it's best to compare using the
  22. -- greater-than-or-equal-to operator. All past versions of the official
  23. -- subgames will remain supported, so it doesn't make sense to require
  24. -- an exact match when determining whether this mod has support for
  25. -- detecting the countables in a given Minetest Game version.
  26. --
  27. -- Version 0.4.0 was the first to support mods, and corresponds to 0 as
  28. -- this mod's detection level for that version. There have been 27
  29. -- versions released since then, all of which are properly detected
  30. -- with the below algorithm, so we're now at detection level 27. (This
  31. -- is Development Test version 5.4.2; this engine version has no
  32. -- corresponding Minetest Game version.)
  33. liblevelup.meta.minetest_game_detection = 27
  34. local debug_table = false
  35. -- Uncomment this line for testing.
  36. --debug_table = dofile(minetest.get_modpath("liblevelup").."/debug.lua")
  37. local function generic_default_is_countable_function(node_string, drops, drop_opts, drop_key)
  38. -- If multiple items are dropped, this is probably something we should
  39. -- count.
  40. if #drops > 1 then
  41. return true
  42. end
  43. local drop_stack = ItemStack(drops[1])
  44. local drop_def = drop_stack:get_definition()
  45. local node_stack = ItemStack(node_string)
  46. local node_def = node_stack:get_definition()
  47. if drop_def.type ~= "node" then
  48. -- If it's not a node and doesn't place as a node, count it.
  49. if drop_def.on_place == minetest.craftitemdef_default.on_place then
  50. return true
  51. -- If it's not a node but does place as one, it's probably a door or a
  52. -- 0.4.7 seed.
  53. --
  54. -- Seeds should be counted if they're dropped by non-farm plants,
  55. -- dropped in multiples, or dropped along with other items. If dropped
  56. -- with other items, they'll be taken care of by an above block.
  57. else
  58. -- Doors can be interacted with, so check for that.
  59. if node_def.on_rightclick then
  60. return false
  61. end
  62. -- Checking for multiples is easy.
  63. if drop_stack:get_count() > 1 then
  64. return true
  65. end
  66. -- Checking for farm plants isn't so easy. What we want to determine is
  67. -- whether the single seed came from a plant that can be grown from
  68. -- that single seed, but there's no way to do this as growth is handled
  69. -- in another function, not handled by a string property of the seed.
  70. -- Instead, we check to see if the plant's drop table seems similar to
  71. -- that of a farm plant, and if it is, assume the seed-like item it
  72. -- dropped was the single seed needed to regrow that same plant.
  73. --
  74. -- Basically, wild grasses tend to drop themselves if not their seed,
  75. -- so only the grass *or* the seed will drop. This should be counted,
  76. -- as the seed cannot be used to regrow the grass. Farm crops can drop
  77. -- multiple items though, and they should all be counted unless only
  78. -- one item drops and that one item is a single seed. This is because
  79. -- that single seed could be converted back into the original farm
  80. -- plant by planting it and waiting for it to grow, so it's not a true
  81. -- drop.
  82. if type(node_def.drop) == "table" and node_def.drop.max_items ~= 1 then
  83. return false
  84. end
  85. return true
  86. end
  87. end
  88. -- This prevents the catching of 0.4.0-style doors.
  89. if node_def.legacy_wallmounted then
  90. return false
  91. end
  92. -- Nodes often get swapped for other nodes when interacted with, while
  93. -- the new nodes drop the original ones for better stacking. This is
  94. -- case with doors, gates, and chests, for example.
  95. if drop_def.on_rightclick then
  96. return false
  97. end
  98. -- Prevent grass from being caught.
  99. if node_def.drawtype ~= "normal" and node_def.drawtype == drop_def.drawtype then
  100. -- This prevents catching of 0.4.15 xpanes. Again, xpanes are a pain.
  101. if node_def.drawtype == "nodebox" then
  102. return false
  103. end
  104. -- We still want to catch mushrooms though.
  105. if node_def.tiles and node_def.tiles[1] == drop_def.tiles[1] then
  106. return true
  107. else
  108. return false
  109. end
  110. end
  111. -- The only way to prevent catching wet-soil-to-dirt drops when dealing
  112. -- with 0.4.7 soil without hard-coding specific node names seems to be
  113. -- to hard-code the soil group, which is far from ideal.
  114. if minetest.get_item_group(node_stack:get_name(), "soil") > minetest.get_item_group(drop_stack:get_name(), "soil") then
  115. return false
  116. end
  117. -- xpanes are such a pain. This check for the "airlike" draw type
  118. -- prevents catching of 0.4.10 xpanes.
  119. if drop_def.drawtype == "airlike" then
  120. return false
  121. end
  122. -- This catches things such as saplings and modern seeds. We don't want
  123. -- to catch single seeds dropped by farm plants though.
  124. if node_def.drawtype ~= drop_def.drawtype then
  125. if drop_stack:get_count() > 1 then
  126. return true
  127. end
  128. if type(node_def.drop) == "table" and node_def.drop.max_items ~= 1 then
  129. return false
  130. end
  131. return true
  132. end
  133. local drop_tiles = drop_def.tiles or drop_def.tile_images or {}
  134. local node_tiles = node_def.tiles or node_def.tile_images or {}
  135. if #drop_tiles == 1 then
  136. -- This catches ice.
  137. if #node_tiles == 1 then
  138. return true
  139. end
  140. -- This catches sand without catching dirt.
  141. for _, tile in next, node_tiles do
  142. if tile:split("^")[1] == drop_tiles[1] then
  143. -- Instead of outright rejecting dirt though, we need to see if the
  144. -- dirt likely converts itself to other forms. That lets us catch dry
  145. -- dirt without catching regular dirt.
  146. for _, def in next, minetest.registered_abms do
  147. for _, node in next, def.nodenames do
  148. if node == drops[1] then
  149. return false
  150. end
  151. end
  152. end
  153. return true
  154. end
  155. end
  156. return true
  157. end
  158. end
  159. if debug_table then
  160. -- For debugging purposes
  161. liblevelup.register.is_countable(function(node_string, drop, drop_opts, drop_key)
  162. local result = generic_default_is_countable_function(node_string, drop, drop_opts, drop_key)
  163. local key = "["..node_string.."]["..drop_key.."]"
  164. if debug_table[key] == nil or debug_table[key] ~= result then
  165. minetest.debug(key.." => "..dump(result == true))
  166. end
  167. return result
  168. end)
  169. else
  170. liblevelup.register.is_countable(generic_default_is_countable_function)
  171. end