erosion.lua 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. local erosions = {}
  2. local resistances = {}
  3. --only available on init,
  4. erosion.register_erosion = function(order)
  5. for i, nodename in ipairs(order)
  6. do
  7. nodename = minetest.registered_aliases[nodename] or nodename
  8. assert(type(nodename) == "string",
  9. "erosion orders must only contain strings")
  10. assert(not (erosions[nodename] and erosions[nodename] ~= nodename and i ~= #order),
  11. "Erosion trees can join but not branch. Relevant node: " .. nodename)
  12. if order[i + 1]
  13. then
  14. erosions[nodename] = order[i + 1]
  15. elseif not erosions[nodename]
  16. then
  17. erosions[nodename] = nodename
  18. end
  19. end
  20. end
  21. --while initiating display an error when anything is trying to erode
  22. erosion.get_erosion_result = function()
  23. assert(false, "Cannot erode anything on init")
  24. end
  25. local function get_erosion_result(cid, power)
  26. while power > 0 and erosions[cid]
  27. do
  28. power = power - resistances[cid]
  29. if power > 0
  30. then
  31. cid = erosions[cid]
  32. end
  33. end
  34. return cid
  35. end
  36. do
  37. todo_on_done_postprocessing = {}
  38. erosion.do_once_postprocessing_done = function(func)
  39. assert(type(func) == "function", "complaint from erosion mod: " ..
  40. "tried to register value of type " .. type(func) ..
  41. " as do_once_postprocessing_is_done, must be function")
  42. table.insert(todo_on_done_postprocessing, func)
  43. end
  44. local function done_postprocessing()
  45. for i, f in ipairs(todo_on_done_postprocessing)
  46. do
  47. f() --respecc
  48. end
  49. todo_on_done_postprocessing = nil
  50. erosion.do_once_postprocessing_done = function(func)
  51. f()
  52. end
  53. end
  54. local relevant_groups =
  55. {
  56. crumbly = 0.5,
  57. cracky = 0.5,
  58. snappy = 0.1,
  59. explody = 0.1,
  60. choppy = 0.3,
  61. }
  62. --convert node names to content ids
  63. local function postprocess_erosions()
  64. local new_erosions = {}
  65. local function calculate_resistance_from_groups(groups)
  66. local resistance = 0
  67. for groupname, weight in pairs(relevant_groups)
  68. do
  69. local g = groups[groupname]
  70. if g
  71. then
  72. resistance = resistance + (4 - g) * weight
  73. end
  74. end
  75. return resistance
  76. end
  77. for this, next in pairs(erosions)
  78. do
  79. local ind = minetest.get_content_id(this)
  80. new_erosions[ind] = minetest.get_content_id(next)
  81. local def = minetest.registered_nodes[this]
  82. assert(def, "No registered node with name " .. this)
  83. local groups = def.groups or {}
  84. resistances[ind] =
  85. calculate_resistance_from_groups(groups)
  86. if resistances[ind] < 1 then resistances[ind] = 1 end
  87. resistances[this] = resistances[ind]
  88. end
  89. for k, v in pairs(new_erosions)
  90. do
  91. erosions[k] = v
  92. end
  93. new_erosions = nil
  94. --disable registering erosions late
  95. erosion.register_erosion =
  96. function()
  97. assert(false, "Cannot register erosions after init")
  98. end
  99. erosion.get_erosion_result = get_erosion_result
  100. done_postprocessing()
  101. end
  102. --run this right after init, before any barrels can explode
  103. --but after aliases are all registered
  104. minetest.after(0.1, postprocess_erosions)
  105. end