init.lua 3.3 KB

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