init.lua 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. -- Localize for performance.
  2. local math_floor = math.floor
  3. local math_random = math.random
  4. local math_min = math.min
  5. local math_max = math.max
  6. local set_node = minetest.set_node
  7. local vector_round = vector.round
  8. local hash_pos = minetest.hash_node_position
  9. local unhash_pos = minetest.get_position_from_hash
  10. minetest.register_node("rosestone:head", {
  11. description = "Glowing Rosestone Seed",
  12. tiles = {"nyancat_side.png^[transformR90", "nyancat_side.png^[transformR90",
  13. "nyancat_side.png",
  14. "nyancat_side.png", "nyancat_side.png", "nyancat_side.png"},
  15. paramtype2 = "facedir",
  16. groups = utility.dig_groups("nyan"),
  17. is_ground_content = false,
  18. legacy_facedir_simple = true,
  19. light_source = 10,
  20. sounds = default.node_sound_glass_defaults(),
  21. silverpick_drop = true,
  22. drop = "default:glass",
  23. })
  24. minetest.register_node("rosestone:tail", {
  25. description = "Glowing Rosestone Tail",
  26. tiles = {
  27. "nyancat_rainbow.png^[transformR90",
  28. "nyancat_rainbow.png^[transformR90",
  29. "nyancat_rainbow.png"
  30. },
  31. paramtype2 = "facedir",
  32. groups = utility.dig_groups("nyan"),
  33. is_ground_content = false,
  34. light_source = 10,
  35. sounds = default.node_sound_glass_defaults(),
  36. })
  37. rosestone = {}
  38. local crystal_dirs1 = {
  39. {x=1, y=0, z=0},
  40. {x=1, y=0, z=0},
  41. {x=1, y=0, z=0},
  42. {x=-1, y=0, z=0},
  43. {x=0, y=0, z=1},
  44. {x=0, y=0, z=-1},
  45. {x=0, y=1, z=0},
  46. {x=0, y=-1, z=0},
  47. }
  48. local crystal_dirs2 = {
  49. {x=1, y=0, z=0},
  50. {x=-1, y=0, z=0},
  51. {x=-1, y=0, z=0},
  52. {x=-1, y=0, z=0},
  53. {x=0, y=0, z=1},
  54. {x=0, y=0, z=-1},
  55. {x=0, y=1, z=0},
  56. {x=0, y=-1, z=0},
  57. }
  58. local crystal_dirs3 = {
  59. {x=1, y=0, z=0},
  60. {x=-1, y=0, z=0},
  61. {x=0, y=0, z=1},
  62. {x=0, y=0, z=1},
  63. {x=0, y=0, z=1},
  64. {x=0, y=0, z=-1},
  65. {x=0, y=1, z=0},
  66. {x=0, y=-1, z=0},
  67. }
  68. local crystal_dirs4 = {
  69. {x=1, y=0, z=0},
  70. {x=-1, y=0, z=0},
  71. {x=0, y=0, z=1},
  72. {x=0, y=0, z=-1},
  73. {x=0, y=0, z=-1},
  74. {x=0, y=0, z=-1},
  75. {x=0, y=1, z=0},
  76. {x=0, y=-1, z=0},
  77. }
  78. local all_dirs = {
  79. crystal_dirs1,
  80. crystal_dirs2,
  81. crystal_dirs3,
  82. crystal_dirs4,
  83. }
  84. local generate_crystal -- Forward declaration needed for recursion.
  85. generate_crystal = function(pos, rec_, tot_, has_, dirs)
  86. local rec = rec_ or 0
  87. local tot = tot_ or math_random(3, 10)
  88. local has = has_ or {}
  89. local key = hash_pos(pos)
  90. local gud = false
  91. if not has[key] then
  92. if rec == 0 then
  93. set_node(pos, {name="rosestone:head"})
  94. has[key] = true
  95. gud = true
  96. else
  97. set_node(pos, {name="rosestone:tail", param2=math_random(0, 3)})
  98. has[key] = true
  99. gud = true
  100. end
  101. end
  102. -- Do not generate crystal larger than max num blocks.
  103. if rec >= tot then return end
  104. local d1 = dirs[math_random(1, #dirs)]
  105. local p1 = {x=pos.x+d1.x, y=pos.y+d1.y, z=pos.z+d1.z}
  106. -- Recursive call.
  107. if gud then
  108. generate_crystal(p1, rec+1, tot, has, dirs)
  109. else
  110. local t = {}
  111. for k, v in pairs(has) do
  112. t[#t+1] = k
  113. end
  114. if #t > 0 then
  115. local x2 = unhash_pos(t[math_random(1, #t)])
  116. local d2 = dirs[math_random(1, #dirs)]
  117. local p2 = {x=x2.x+d1.x, y=x2.y+d1.y, z=x2.z+d1.z}
  118. generate_crystal(p2, rec+0, tot, has, dirs)
  119. end
  120. end
  121. end
  122. rosestone.place = function(pos, count)
  123. local which = all_dirs[math_random(1, 4)]
  124. generate_crystal(vector_round(pos), nil, count, nil, which)
  125. end
  126. function rosestone.generate(minp, maxp, seed)
  127. local height_min = -25000 -- Don't generate rosestone crystals in the nether.
  128. local height_max = -32
  129. if maxp.y < height_min or minp.y > height_max then
  130. return
  131. end
  132. local y_min = math_max(minp.y, height_min)
  133. local y_max = math_min(maxp.y, height_max)
  134. local volume = (maxp.x - minp.x + 1) * (y_max - y_min + 1) * (maxp.z - minp.z + 1)
  135. local pr = PseudoRandom(seed + 9324342)
  136. local max_num_nyancats = math_floor(volume / (16 * 16 * 16))
  137. for i = 1, max_num_nyancats do
  138. if pr:next(0, 1000) == 0 then
  139. local x0 = pr:next(minp.x, maxp.x)
  140. local y0 = pr:next(minp.y, maxp.y)
  141. local z0 = pr:next(minp.z, maxp.z)
  142. local p0 = {x = x0, y = y0, z = z0}
  143. rosestone.place(p0, pr:next(3, 16))
  144. end
  145. end
  146. end
  147. minetest.register_on_generated(function(minp, maxp, seed)
  148. rosestone.generate(minp, maxp, seed)
  149. end)
  150. -- Legacy
  151. minetest.register_alias("nyancat:nyancat", "rosestone:head")
  152. minetest.register_alias("nyancat:nyancat_rainbow", "rosestone:tail")
  153. minetest.register_alias("default:nyancat", "rosestone:head")
  154. minetest.register_alias("default:nyancat_rainbow", "rosestone:tail")
  155. minetest.register_alias("nyancat", "rosestone:head")
  156. minetest.register_alias("nyancat_rainbow", "rosestone:tail")