init.lua 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. local modname = minetest.get_current_modname()
  2. --localize some stuff for performance
  3. local Random = PcgRandom
  4. local floor = math.floor
  5. local table_insert = table.insert
  6. local ipairs = ipairs
  7. local registered_populators = {}
  8. local accumulated_weight = 0
  9. --test seed: 6888913275966624651
  10. _G[modname] = {}
  11. _G[modname].register_dungeon_populator = function(weight, func)
  12. --we add weight to 0 so it's converted to number if it's a string
  13. weight = 0 + weight
  14. assert(weight > 0 and floor(weight) == weight,
  15. "Error registering dungeon populator: weight must be a positive whole number")
  16. accumulated_weight = accumulated_weight + weight
  17. for i = 1, #registered_populators + 1
  18. do
  19. local v = registered_populators[i]
  20. if not v or v[1] < weight
  21. then
  22. table_insert(registered_populators, i, {weight, func})
  23. return
  24. end
  25. end
  26. end
  27. --1/3 of rooms are empty by default
  28. minetest.register_on_mods_loaded(function()
  29. if accumulated_weight == 0
  30. then
  31. accumulated_weight = 1
  32. end
  33. _G[modname].register_dungeon_populator(accumulated_weight * 2, function()end) --TODO: make setting
  34. end)
  35. do
  36. local _, gennotify = minetest.get_gen_notify()
  37. gennotify.dungeon = true
  38. minetest.set_gen_notify(gennotify)
  39. end
  40. local function populate_dungeon(pos, rand)
  41. local roll = rand:next(1, accumulated_weight)
  42. for i, v in ipairs(registered_populators)
  43. do
  44. roll = roll - v[1]
  45. if roll < 1
  46. then
  47. v[2](pos, rand)
  48. return
  49. end
  50. end
  51. end
  52. minetest.register_on_generated(function(minp, maxp, blockseed)
  53. local gennotify = minetest.get_mapgen_object("gennotify")
  54. local poslist = gennotify["dungeon"] or {}
  55. local rand = Random(blockseed)
  56. for i, pos in ipairs(poslist)
  57. do
  58. populate_dungeon(pos, rand)
  59. end
  60. end)