2 minetest,name,vector,math,pairs
4 minetest,minetest.localplayer:get_name(),vector,math,pairs
6 local weather_intake = minetest.mod_channel_join("weather_intake")
7 local weather = minetest.mod_channel_join("weather_nodes")
8 local weather_type = minetest.mod_channel_join("weather_type")
11 local do_effects = false
14 local weather_update_timer = 0
17 local rain_sound_handle = nil
33 local distance = vector.distance
34 local weather_effects = function(player,defined_type)
35 pos = vector.round(player:get_pos())
36 area = vector.new(10,10,10)
37 min = vector.subtract(pos, area)
38 max = vector.add(pos, area)
39 area_index = minetest.find_nodes_in_area_under_air(min, max, all_nodes)
41 --find the highest y value
42 for _,index in pairs(area_index) do
43 if not spawn_table[index.x] then spawn_table[index.x] = {} end
44 if not spawn_table[index.x][index.z] then
45 spawn_table[index.x][index.z] = index.y
46 elseif spawn_table[index.x][index.z] < index.y then
47 spawn_table[index.x][index.z] = index.y
51 if defined_type == "rain" then
52 curr_light = minetest.get_node_light({x=pos.x,y=pos.y+1,z=pos.z},0.5)
55 if curr_light >= 15 then
56 if not rain_sound_handle then
57 rain_sound_handle = minetest.sound_play("rain", {loop=true,gain=0})
59 minetest.sound_fade(rain_sound_handle, 0.5, 1)
60 elseif curr_light < 15 and rain_sound_handle then
61 minetest.sound_fade(rain_sound_handle, -0.5, 0)
62 rain_sound_handle = nil
69 minvel = {x=0, y=-30, z=0},
70 maxvel = {x=0, y=-30, z=0},
71 minacc = {x=0, y=0, z=0},
72 maxacc = {x=0, y=0, z=0},
77 collisiondetection = true,
78 collision_removal = true,
79 object_collision = false,
81 texture = "raindrop.png^[opacity:80",
83 elseif defined_type == "snow" then
87 minvel = {x=-0.2, y=-0.2, z=-0.2},
88 maxvel = {x=0.2, y=-0.5, z=0.2},
89 minacc = {x=0, y=0, z=0},
90 maxacc = {x=0, y=0, z=0},
95 collisiondetection = true,
96 collision_removal = true,
97 object_collision = false,
98 texture = "snowflake_"..math.random(1,2)..".png",
100 elseif defined_type == "ichor" then
104 minvel = {x=-0.2, y=0.2, z=-0.2},
105 maxvel = {x=0.2, y=0.5, z=0.2},
106 minacc = {x=0, y=0, z=0},
107 maxacc = {x=0, y=0, z=0},
112 collisiondetection = true,
113 collision_removal = true,
114 object_collision = false,
115 texture = "ichor_"..math.random(1,2)..".png",
120 for x = min.x,max.x do
121 for z = min.z,max.z do
122 if distance({x=x,y=0,z=z},{x=pos.x,y=0,z=pos.z}) <= 10 then
124 if spawn_table[x] and spawn_table[x][z] then
125 y = spawn_table[x][z]
127 if minetest.get_node_or_nil(vector.new(x,y+1,z)) ~= nil then
128 lightlevel = minetest.get_node_light(vector.new(x,y+1,z), 0.5)
129 if lightlevel >= 14 or defined_type == "ichor" then
131 particle_table.minpos = vector.new(x-0.5,y,z-0.5)
132 particle_table.maxpos = vector.new(x+0.5,y+20,z+0.5)
134 null = minetest.add_particlespawner(particle_table)
144 --client runs through spawning weather particles
146 local function update_weather()
147 player_pos = minetest.localplayer:get_pos()
151 if player_pos.y > -10033 then
153 weather_effects(minetest.localplayer, "snow")
154 elseif rain == true then
155 weather_effects(minetest.localplayer, "rain")
157 --rain blood upwards in the nether
159 if snow == true or rain == true then
160 weather_effects(minetest.localplayer, "ichor")
163 --stop the rain sound effect
164 if rain_sound_handle then
165 minetest.sound_fade(rain_sound_handle, -0.5, 0)
166 rain_sound_handle = nil
171 if not rain and rain_sound_handle then
172 minetest.sound_fade(rain_sound_handle, -0.5, 0)
173 rain_sound_handle = nil
175 --do again every half second
176 minetest.after(0.5, function()
181 minetest.register_on_modchannel_message(function(channel_name, sender, message)
182 --receive the initial packet which tells the client which nodes
183 --to spawn weather columns on
184 if sender == "" and channel_name == "weather_nodes" then
185 all_nodes = minetest.deserialize(message)
187 weather:leave() --leave the channel
189 --receive the weather type
190 if sender == "" and channel_name == "weather_type" then
191 if message == "1" then
194 elseif message == "2" then
205 --We must tell the server that we're ready
206 minetest.after(0,function()
207 weather_intake:send_all("READY")
208 weather_intake:leave()
209 weather_intake = nil --leave the channel
211 --begin weather update