init.lua 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  1. -- Trace Minerals mod for Minetest
  2. -- Copyright © 2018 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. -----------------------------------------------------------------------
  15. -- We'll read the settings only once at load time. No need to read them
  16. -- every time a "default:stone" is dug, that'd just be slow.
  17. local config = {
  18. renew_minerals = minetest.settings:get_bool("trace_minerals.renew_minerals"),
  19. renew_soils = minetest.settings:get_bool("trace_minerals.renew_soils"),
  20. renew_living = minetest.settings:get_bool("trace_minerals.renew_living"),
  21. renew_liquids = minetest.settings:get_bool("trace_minerals.renew_liquids"),
  22. renew_gunpowder = minetest.settings:get("trace_minerals.renew_gunpowder"),
  23. drops = {}, -- will be used later
  24. can_harvest = {}, -- will be used later
  25. mapgen = minetest.get_mapgen_params().mgname,
  26. }
  27. -- These settings are booleans, but it looks lime we don't have a way
  28. -- to set default values. We set defaults in settingtypes.txt, but it
  29. -- looks like those only apply in the menu, not in the actual game.
  30. -- Let's set some values if none are found.
  31. if config.renew_minerals == nil then
  32. config.renew_minerals = true
  33. end
  34. if config.renew_soils == nil then
  35. config.renew_soils = true
  36. end
  37. if config.renew_living == nil then
  38. config.renew_living = false
  39. end
  40. if config.renew_liquids == nil then
  41. config.renew_liquids = false
  42. end
  43. -- This setting is read as a string. We need to make sure it has a sane
  44. -- value so we can avoid strange behaviour.
  45. if (config.renew_gunpowder == "Flint" and not config.renew_minerals) or
  46. (config.renew_gunpowder == "Gravel" and not config.renew_soils) or
  47. (config.renew_gunpowder ~= "Flint" and config.renew_gunpowder ~= "Gravel") then
  48. config.renew_gunpowder = "None"
  49. end
  50. -- For randomisation, we need to know how many possible drops can be
  51. -- had, based on the administrator's settings. Let's add them up.
  52. -- Remember, we need to take the map generator into consideration. This
  53. -- mod intends to make existing obtainable materials renewable, not
  54. -- provide access to otherwise-unobtainable materials.
  55. minetest.debug(dump(config.renew_minerals))
  56. if config.mapgen ~= "singlenode" then
  57. if config.renew_minerals then
  58. config.can_harvest["default:clay_lump"] = true
  59. config.can_harvest["default:coal_lump"] = true
  60. config.can_harvest["default:copper_lump"] = true
  61. config.can_harvest["default:diamond"] = true
  62. config.can_harvest["default:gold_lump"] = true
  63. config.can_harvest["default:iron_lump"] = true
  64. config.can_harvest["default:mese_crystal_fragment"] = true
  65. config.can_harvest["default:tin_lump"] = true
  66. if config.renew_gunpowder ~= "Gravel" then
  67. config.can_harvest["default:flint"] = true
  68. end
  69. if not minetest.registered_items["bucket:bucket_lava"] or not config.renew_liquids then
  70. config.can_harvest["default:obsidian_shard"] = true
  71. end
  72. end
  73. if config.renew_soils then
  74. config.can_harvest["default:desert_sand"] = true
  75. config.can_harvest["default:dirt"] = true
  76. config.can_harvest["default:sand"] = true
  77. config.can_harvest["default:silver_sand"] = true
  78. config.can_harvest["default:ice"] = true
  79. config.can_harvest["default:desert_cobble"] = true
  80. if config.renew_gunpowder == "Gravel" then
  81. config.can_harvest["default:gravel"] = true
  82. end
  83. end
  84. if config.renew_liquids then
  85. if minetest.registered_items["bucket:bucket_lava"] then
  86. config.can_harvest["default:lava_source"] = false
  87. end
  88. if config.mapgen == "valleys" and minetest.registered_items["bucket:bucket_river_water"] then
  89. config.can_harvest["default:river_water_source"] = false
  90. end
  91. end
  92. if config.renew_living then
  93. config.can_harvest["flowers:waterlily"] = true
  94. if config.mapgen ~= "v6" then
  95. config.can_harvest["default:coral_skeleton"] = true
  96. end
  97. end
  98. end
  99. -- We've composed a list of things we want stone to sometimes drop, and
  100. -- that's all well and good. However, do we really know if all (or any)
  101. -- of these have been defined? Due to a hard dependency on default
  102. -- (required because this mod is useless if we don't redefine
  103. -- "default:stone"), we can be fairly sure any of these items from
  104. -- default are present, but this mod might be assuming a different
  105. -- version of Minetest Game than is present. If Minetest Game is too
  106. -- old, some of these might not be defined. Additionally, some of these
  107. -- items are from mods that are only softly depended on. Let's try not
  108. -- to drop unknown items; we should check to be sure of which items are
  109. -- present. This mod is totally going to crash your server at load time
  110. -- if "default:stone" isn't defined though. Just sayin'. But for all
  111. -- other items, we'll check instead of assuming.
  112. minetest.debug(dump(config.can_harvest))
  113. for item, _ in next, config.can_harvest do
  114. if minetest.registered_items[item] then
  115. config.drops[#config.drops+1] = item
  116. else
  117. config.can_harvest[item] = nil
  118. end
  119. end
  120. -- This should be less verbose.
  121. local get_drop_stats = {
  122. ["default:coal_lump"] = function(player_name)
  123. return {
  124. player = __minestats__.get_stacks_mined(player_name, "default:coal_lump"),
  125. max = __minestats__.level_max("default:coal_lump"),
  126. }
  127. end,
  128. ["default:copper_lump"] = function(player_name)
  129. return {
  130. player = __minestats__.get_stacks_mined(player_name, "default:copper_lump"),
  131. max = __minestats__.level_max("default:copper_lump"),
  132. }
  133. end,
  134. ["default:diamond"] = function(player_name)
  135. return {
  136. player = __minestats__.get_stacks_mined(player_name, "default:diamond"),
  137. max = __minestats__.level_max("default:diamond"),
  138. }
  139. end,
  140. ["default:flint"] = function(player_name)
  141. return {
  142. player = __minestats__.get_stacks_mined(player_name, "default:flint"),
  143. max = __minestats__.level_max("default:flint"),
  144. }
  145. end,
  146. ["default:gold_lump"] = function(player_name)
  147. return {
  148. player = __minestats__.get_stacks_mined(player_name, "default:gold_lump"),
  149. max = __minestats__.level_max("default:gold_lump"),
  150. }
  151. end,
  152. ["default:iron_lump"] = function(player_name)
  153. return {
  154. player = __minestats__.get_stacks_mined(player_name, "default:iron_lump"),
  155. max = __minestats__.level_max("default:iron_lump"),
  156. }
  157. end,
  158. ["default:mese_crystal_fragment"] = function(player_name)
  159. return {
  160. player = __minestats__.get_stacks_mined(player_name, "default:mese_crystal"),
  161. max = __minestats__.level_max("default:mese_crystal"),
  162. }
  163. end,
  164. ["default:tin_lump"] = function(player_name)
  165. return {
  166. player = __minestats__.get_stacks_mined(player_name, "default:tin_lump"),
  167. max = __minestats__.level_max("default:tin_lump"),
  168. }
  169. end,
  170. ["default:obsidian_shard"] = function(player_name)
  171. return {
  172. player = __minestats__.get_stacks_mined(player_name, "farming:wheat"),
  173. max = __minestats__.level_max("farming:wheat"),
  174. }
  175. end,
  176. ["default:clay_lump"] = function(player_name)
  177. return {
  178. player = __minestats__.get_stacks_mined(player_name, "farming:cotton"),
  179. max = __minestats__.level_max("farming:cotton"),
  180. }
  181. end,
  182. ["default:dirt"] = function(player_name)
  183. return {
  184. player = __minestats__.get_stacks_mined(player_name, "farming:cotton") + __minestats__.get_stacks_mined(player_name, "farming:wheat"),
  185. max = __minestats__.level_max("farming:cotton") + __minestats__.level_max("farming:wheat"),
  186. }
  187. end,
  188. ["default:sand"] = function(player_name)
  189. return {
  190. player = __minestats__.get_stacks_mined(player_name, "default:coal_lump") + __minestats__.get_stacks_mined(player_name, "farming:cotton"),
  191. max = __minestats__.level_max("default:coal_lump") + __minestats__.level_max("farming:cotton"),
  192. }
  193. end,
  194. ["default:silver_sand"] = function(player_name)
  195. return {
  196. player = __minestats__.get_stacks_mined(player_name, "default:iron_lump") + __minestats__.get_stacks_mined(player_name, "farming:wheat"),
  197. max = __minestats__.level_max("default:iron_lump") + __minestats__.level_max("farming:wheat"),
  198. }
  199. end,
  200. ["default:desert_cobble"] = function(player_name)
  201. return {
  202. player = __minestats__.get_stacks_mined(player_name, "default:copper_lump") + __minestats__.get_stacks_mined(player_name, "farming:wheat"),
  203. max = __minestats__.level_max("default:copper_lump") + __minestats__.level_max("farming:wheat"),
  204. }
  205. end,
  206. ["default:desert_sand"] = function(player_name)
  207. return {
  208. player = __minestats__.get_stacks_mined(player_name, "default:tin_lump") + __minestats__.get_stacks_mined(player_name, "farming:cotton"),
  209. max = __minestats__.level_max("default:tin_lump") + __minestats__.level_max("farming:cotton"),
  210. }
  211. end,
  212. ["default:ice"] = function(player_name)
  213. return {
  214. player = __minestats__.get_stacks_mined(player_name, "default:gold_lump") + __minestats__.get_stacks_mined(player_name, "farming:wheat"),
  215. max = __minestats__.level_max("default:gold_lump") + __minestats__.level_max("farming:wheat"),
  216. }
  217. end,
  218. ["default:river_water_source"] = function(player_name)
  219. return {
  220. player = __minestats__.get_stacks_mined(player_name, "default:flint") + __minestats__.get_stacks_mined(player_name, "farming:cotton"),
  221. max = __minestats__.level_max("default:flint") + __minestats__.level_max("farming:cotton"),
  222. }
  223. end,
  224. ["flowers:waterlily"] = function(player_name)
  225. return {
  226. player = __minestats__.get_stacks_mined(player_name, "default:mese_crystal") + __minestats__.get_stacks_mined(player_name, "farming:wheat"),
  227. max = __minestats__.level_max("default:mese_crystal") + __minestats__.level_max("farming:wheat"),
  228. }
  229. end,
  230. ["default:coral_skeleton"] = function(player_name)
  231. return {
  232. player = __minestats__.get_stacks_mined(player_name, "default:diamond") + __minestats__.get_stacks_mined(player_name, "farming:cotton"),
  233. max = __minestats__.level_max("default:diamond") + __minestats__.level_max("farming:cotton"),
  234. }
  235. end,
  236. }
  237. get_drop_stats["default:lava_source"] = get_drop_stats["default:obsidian_shard"]
  238. get_drop_stats["default:gravel"] = get_drop_stats["default:flint"]
  239. if #config.drops > 0 then
  240. minetest.override_item("default:stone", {
  241. on_dig = function(pos, node, digger)
  242. if math.random(0, 99) == 0 then
  243. local player_name = digger:get_player_name()
  244. if not minetest.is_protected(pos, player_name) then
  245. local random_drop = config.drops[math.random(#config.drops)]
  246. local drop_stats = get_drop_stats[random_drop](player_name)
  247. -- Lua's math.random() is weird. If we don't specify a minimum but we
  248. -- do specify a maximum, Lua uses one, not zero, as the minimum. Lua
  249. -- really loves to give zero the shaft every chance it gets. Anyway, in
  250. -- this particular case, we need to make sure the random number chosen
  251. -- is greater than zero, as at level zero, you should fail to get any
  252. -- bonuses at all. So because of Lua's default minimum of one, we don't
  253. -- really need to do anything else. This time.
  254. if drop_stats.player > math.random(drop_stats.max) then
  255. local tool = digger:get_wielded_item()
  256. local tooldef = tool:get_definition()
  257. local capabilities = tool:get_tool_capabilities()
  258. local params = core.get_dig_params(minetest.registered_nodes["default:stone"].groups, capabilities)
  259. tool:add_wear(params.wear)
  260. digger:set_wielded_item(tool)
  261. if config.can_harvest[random_drop] then
  262. minetest.handle_node_drops(pos, {random_drop}, digger)
  263. minetest.remove_node(pos)
  264. else
  265. minetest.set_node(pos, {name=random_drop})
  266. end
  267. else
  268. minetest.node_dig(pos, node, digger)
  269. end
  270. end
  271. else
  272. minetest.node_dig(pos, node, digger)
  273. end
  274. end,
  275. })
  276. end
  277. if config.renew_gunpowder == "Flint" then
  278. minetest.clear_craft({
  279. type = "shapeless",
  280. recipe = {"default:coal_lump", "default:gravel"},
  281. })
  282. minetest.register_craft({
  283. type = "shapeless",
  284. recipe = {"default:coal_lump", "default:flint"},
  285. output = {"tnt:gunpowder"},
  286. })
  287. end