init.lua 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. snowscatter = snowscatter or {}
  2. snowscatter.modpath = minetest.get_modpath("snowscatter")
  3. -- Localize for performance.
  4. local vector_round = vector.round
  5. local math_random = math.random
  6. local find_floor = function(x, ybot, ytop, z)
  7. for y = ytop, ybot, -1 do
  8. local p1 = {x=x, y=y, z=z}
  9. local p2 = {x=x, y=y-1, z=z}
  10. local n1 = minetest.get_node(p1).name
  11. local n2 = minetest.get_node(p2).name
  12. if n1 == "air" and n2 ~= "air" and n2 ~= "ignore" then
  13. local node = minetest.reg_ns_nodes[n2]
  14. if not node then break end
  15. if not node.walkable then break end -- Don't dump snow on non-walkable things.
  16. local good = false
  17. local dt = node.drawtype
  18. if dt == "normal" then good = true end
  19. if dt == "allfaces" then good = true end
  20. if dt == "allfaces_optional" then good = true end
  21. if dt == "glasslike" then good = true end
  22. if dt == "glasslike_framed" then good = true end
  23. if dt == "glasslike_framed_optional" then good = true end
  24. if dt == "airlike" then good = true end
  25. if good == false then break end
  26. return p1, p2
  27. elseif n1 == "ignore" or n1 ~= "air" then
  28. break
  29. end
  30. end
  31. end
  32. -- API function which dumps snow dust in an area.
  33. snowscatter.dump_snowdust = function(minp_, maxp_, chance, avoidXZ)
  34. local minp, maxp = utility.sort_positions(minp_, maxp_)
  35. local random = math_random
  36. for x = minp.x, maxp.x, 1 do
  37. for z = minp.z, maxp.z, 1 do
  38. -- If avoidance column is specificed, do not place snow in that column.
  39. local cando = true
  40. if avoidXZ then
  41. if x == avoidXZ.x and z == avoidXZ.z then
  42. cando = false
  43. end
  44. end
  45. if random(1, chance) == 1 and cando == true then
  46. local p1, p2 = find_floor(x, minp.y, maxp.y, z)
  47. if p1 then
  48. if not rc.ice_melts_at_pos(p1) then
  49. minetest.set_node(p1, {name="snow:tree"})
  50. core.check_for_falling(p1)
  51. end
  52. end
  53. end
  54. end
  55. end
  56. end
  57. -- This API is designed to be called by tree mods.
  58. snowscatter.dump_snowdust_on_tree = function(pos, minp, maxp)
  59. local sminp = {x=pos.x+minp.x, y=pos.y+minp.y, z=pos.z+minp.z}
  60. local smaxp = {x=pos.x+maxp.x, y=pos.y+maxp.y+1, z=pos.z+maxp.z}
  61. snowscatter.dump_snowdust(sminp, smaxp, math_random(5, 20), {x=pos.x, z=pos.z})
  62. end
  63. snowscatter.execute_chatcommand = function(name, param)
  64. local p = vector_round(minetest.get_player_by_name(name):get_pos())
  65. local r = 10
  66. snowscatter.dump_snowdust({x=p.x-r, y=p.y-r, z=p.z-r}, {x=p.x+r, y=p.y+r, z=p.z+r}, 5, nil)
  67. minetest.chat_send_player(name, "# Server: Scattered snow!")
  68. return true
  69. end
  70. if not snowscatter.registered then
  71. minetest.register_privilege("snowscatter", {
  72. "Player can scatter snow in area around self.",
  73. give_to_singleplayer = false,
  74. })
  75. minetest.register_chatcommand("snowscatter", {
  76. params = "",
  77. description = "Scatter snow around self.",
  78. privs = {snowscatter=true},
  79. func = function(...) return snowscatter.execute_chatcommand(...) end,
  80. })
  81. reload.register_file("snowscatter:core", snowscatter.modpath .. "/init.lua", false)
  82. snowscatter.registered = true
  83. end