2 local do_effects = false
5 local weather_update_timer = 0
8 local rain_sound_handle = nil
10 local spawn_snow = function(player)
11 local pos = player:get_pos()
13 local particle_table = {}
15 local area = vector.new(10,10,10)
17 local min = vector.subtract(pos, area)
18 local max = vector.add(pos, area)
21 local area_index = minetest.find_nodes_in_area_under_air(min, max, all_nodes)
23 local spawn_table = {}
24 --find the highest y value
25 for _,index in pairs(area_index) do
26 if not spawn_table[index.x] then spawn_table[index.x] = {} end
27 if not spawn_table[index.x][index.z] then
28 spawn_table[index.x][index.z] = index.y
29 elseif spawn_table[index.x][index.z] < index.y then
30 spawn_table[index.x][index.z] = index.y
34 for x,x_index in pairs(spawn_table) do
35 for z,y in pairs(x_index) do
36 if minetest.get_node_or_nil(vector.new(x,y+1,z)) ~= nil then
37 local pos = vector.new(x,y+1,z)
38 local lightlevel = minetest.get_node_light(pos, 0.5)
39 if lightlevel >= 14 then
40 minetest.add_particlespawner({
43 minpos = vector.new(x-0.5,y,z-0.5),
44 maxpos = vector.new(x+0.5,y+20,z+0.5),
45 minvel = {x=-0.2, y=-0.2, z=-0.2},
46 maxvel = {x=0.2, y=-0.5, z=0.2},
47 minacc = {x=0, y=0, z=0},
48 maxacc = {x=0, y=0, z=0},
53 collisiondetection = true,
54 collision_removal = true,
55 object_collision = false,
56 texture = "snowflake_"..math.random(1,2)..".png",
57 playername = player:get_name(),
65 local spawn_ichor = function(player)
66 local pos = player:get_pos()
68 local particle_table = {}
70 local area = vector.new(10,10,10)
72 local min = vector.subtract(pos, area)
73 local max = vector.add(pos, area)
76 local area_index = minetest.find_nodes_in_area_under_air(min, max, all_nodes)
78 local spawn_table = {}
79 --find the highest y value
80 for _,index in pairs(area_index) do
81 if not spawn_table[index.x] then spawn_table[index.x] = {} end
82 if not spawn_table[index.x][index.z] then
83 spawn_table[index.x][index.z] = index.y
84 elseif spawn_table[index.x][index.z] < index.y then
85 spawn_table[index.x][index.z] = index.y
89 for x,x_index in pairs(spawn_table) do
90 for z,y in pairs(x_index) do
91 if minetest.get_node_or_nil(vector.new(x,y+1,z)) ~= nil then
92 local pos = vector.new(x,y+1,z)
93 minetest.add_particlespawner({
96 minpos = vector.new(x-0.5,y,z-0.5),
97 maxpos = vector.new(x+0.5,y+20,z+0.5),
98 minvel = {x=-0.2, y=0.2, z=-0.2},
99 maxvel = {x=0.2, y=0.5, z=0.2},
100 minacc = {x=0, y=0, z=0},
101 maxacc = {x=0, y=0, z=0},
106 collisiondetection = true,
107 collision_removal = true,
108 object_collision = false,
109 texture = "ichor_"..math.random(1,2)..".png",
110 playername = player:get_name(),
117 local spawn_rain = function(player)
118 local pos = player:get_pos()
120 local particle_table = {}
122 local area = vector.new(10,10,10)
124 local min = vector.subtract(pos, area)
125 local max = vector.add(pos, area)
128 local area_index = minetest.find_nodes_in_area_under_air(min, max, all_nodes)
130 local spawn_table = {}
131 --find the highest y value
132 for _,index in pairs(area_index) do
133 if not spawn_table[index.x] then spawn_table[index.x] = {} end
134 if not spawn_table[index.x][index.z] then
135 spawn_table[index.x][index.z] = index.y
136 elseif spawn_table[index.x][index.z] < index.y then
137 spawn_table[index.x][index.z] = index.y
141 for x,x_index in pairs(spawn_table) do
142 for z,y in pairs(x_index) do
143 if minetest.get_node_or_nil(vector.new(x,y+1,z)) ~= nil then
144 local pos = vector.new(x,y+1,z)
145 local lightlevel = minetest.get_node_light(pos, 0.5)
146 if lightlevel >= 14 then
147 minetest.add_particlespawner({
150 minpos = vector.new(x-0.5,y,z-0.5),
151 maxpos = vector.new(x+0.5,y+20,z+0.5),
152 minvel = {x=0, y=-20, z=0},
153 maxvel = {x=0, y=-20, z=0},
154 minacc = {x=0, y=0, z=0},
155 maxacc = {x=0, y=0, z=0},
160 collisiondetection = true,
161 collision_removal = true,
162 object_collision = false,
164 texture = "raindrop.png^[opacity:80",
165 playername = player:get_name(),
173 --client runs through spawning weather particles
175 local function update_weather()
176 player_pos = minetest.localplayer:get_pos()
180 if player_pos.y > -10033 then
182 spawn_snow(minetest.localplayer)
183 elseif rain == true then
184 spawn_rain(minetest.localplayer)
186 --rain blood upwards in the nether
188 if snow == true or rain == true then
189 spawn_ichor(minetest.localplayer)
192 --stop the rain sound effect
193 if rain_sound_handle then
194 minetest.sound_fade(rain_sound_handle, -0.5, 0)
195 rain_sound_handle = nil
200 --do again every half second
201 minetest.after(0.5, function()
208 minetest.register_on_modchannel_message(function(channel_name, sender, message)
209 --receive the initial packet which tells the client which nodes
210 --to spawn weather columns on
211 if channel_name == "weather_nodes" then
212 all_nodes = minetest.deserialize(message)
214 weather:leave() --leave the channel
216 --receive the weather type
217 if channel_name == "weather_type" then
218 if message == "1" then
221 elseif message == "2" then
230 if not rain_sound_handle and rain == true then
231 rain_sound_handle = minetest.sound_play("rain", {loop=true,gain=0})
232 minetest.sound_fade(rain_sound_handle, 0.5, 0.5)
233 elseif rain_sound_handle and rain == false then
234 minetest.sound_fade(rain_sound_handle, -0.5, 0)
235 rain_sound_handle = nil
240 --We must tell the server that we're ready
241 minetest.after(0,function()
242 weather_intake:send_all("READY")
243 weather_intake:leave()
244 weather_intake = nil --leave the channel
246 --begin weather update