2 local do_effects = false
5 local weather_update_timer = 0
8 local rain_sound_handle = nil
11 --this is rice but it boosts the FPS slightly
13 local find_em = minetest.find_nodes_in_area_under_air
20 local round_it = vector.round
21 local new_vec = vector.new
22 local add_it = vector.add
23 local sub_it = vector.subtract
26 local get_the_node = minetest.get_node_or_nil
27 local get_the_light = minetest.get_node_light
29 local add_ps = minetest.add_particlespawner
32 local weather_effects = function(player,defined_type)
33 pos = round_it(player:get_pos())
35 area = new_vec(10,10,10)
36 min = sub_it(pos, area)
37 max = add_it(pos, area)
38 area_index = find_em(min, max, all_nodes)
39 spawn_table = nil -- this has to be terminated before reassignment
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
50 for x = min.x,max.x do
51 for z = min.z,max.z do
53 if spawn_table[x] and spawn_table[x][z] then
56 if get_the_node(new_vec(x,y+1,z)) ~= nil then
57 lightlevel = get_the_light(new_vec(x,y+1,z), 0.5)
58 if lightlevel >= 14 or defined_type == "ichor" then
59 if defined_type == "rain" then
63 minpos = new_vec(x-0.5,y,z-0.5),
64 maxpos = new_vec(x+0.5,y+20,z+0.5),
65 minvel = {x=0, y=-20, z=0},
66 maxvel = {x=0, y=-20, z=0},
67 minacc = {x=0, y=0, z=0},
68 maxacc = {x=0, y=0, z=0},
73 collisiondetection = true,
74 collision_removal = true,
75 object_collision = false,
77 texture = "raindrop.png^[opacity:80",
80 elseif defined_type == "snow" then
84 minpos = vector.new(x-0.5,y,z-0.5),
85 maxpos = vector.new(x+0.5,y+20,z+0.5),
86 minvel = {x=-0.2, y=-0.2, z=-0.2},
87 maxvel = {x=0.2, y=-0.5, z=0.2},
88 minacc = {x=0, y=0, z=0},
89 maxacc = {x=0, y=0, z=0},
94 collisiondetection = true,
95 collision_removal = true,
96 object_collision = false,
97 texture = "snowflake_"..math.random(1,2)..".png",
100 elseif defined_type == "ichor" then
104 minpos = vector.new(x-0.5,y,z-0.5),
105 maxpos = vector.new(x+0.5,y+20,z+0.5),
106 minvel = {x=-0.2, y=0.2, z=-0.2},
107 maxvel = {x=0.2, y=0.5, z=0.2},
108 minacc = {x=0, y=0, z=0},
109 maxacc = {x=0, y=0, z=0},
114 collisiondetection = true,
115 collision_removal = true,
116 object_collision = false,
117 texture = "ichor_"..math.random(1,2)..".png",
118 playername = player:get_name(),
129 --client runs through spawning weather particles
131 local function update_weather()
132 player_pos = minetest.localplayer:get_pos()
136 if player_pos.y > -10033 then
138 weather_effects(minetest.localplayer, "snow")
139 elseif rain == true then
140 weather_effects(minetest.localplayer, "rain")
142 --rain blood upwards in the nether
144 if snow == true or rain == true then
145 weather_effects(minetest.localplayer, "ichor")
148 --stop the rain sound effect
149 if rain_sound_handle then
150 minetest.sound_fade(rain_sound_handle, -0.5, 0)
151 rain_sound_handle = nil
156 --do again every half second
157 minetest.after(0.5, function()
162 minetest.register_on_modchannel_message(function(channel_name, sender, message)
163 --receive the initial packet which tells the client which nodes
164 --to spawn weather columns on
165 if sender == "" and channel_name == "weather_nodes" then
166 all_nodes = minetest.deserialize(message)
168 weather:leave() --leave the channel
170 --receive the weather type
171 if sender == "" and channel_name == "weather_type" then
172 if message == "1" then
175 elseif message == "2" then
184 if not rain_sound_handle and rain == true then
185 rain_sound_handle = minetest.sound_play("rain", {loop=true,gain=0})
186 minetest.sound_fade(rain_sound_handle, 0.5, 0.5)
187 elseif rain_sound_handle and rain == false then
188 minetest.sound_fade(rain_sound_handle, -0.5, 0)
189 rain_sound_handle = nil
194 --We must tell the server that we're ready
195 minetest.after(0,function()
196 weather_intake:send_all("READY")
197 weather_intake:leave()
198 weather_intake = nil --leave the channel
200 --begin weather update