]> git.lizzy.rs Git - crafter_client.git/blob - weather_handling.lua
ea1128b1879c39244ee98abdb48378d16785b9dd
[crafter_client.git] / weather_handling.lua
1 local all_nodes = {}
2 local do_effects = false
3 local snow = false
4 local rain = false
5 local weather_update_timer = 0
6 local id_table = {}
7
8 local rain_sound_handle = nil
9
10 local spawn_snow = function(player)
11         local pos = player:get_pos()
12         local radius = 10
13         local particle_table = {}
14         
15         local area = vector.new(10,10,10)
16         
17         local min = vector.subtract(pos, area)
18         local max = vector.add(pos, area)
19         
20         
21         local area_index = minetest.find_nodes_in_area_under_air(min, max, all_nodes)
22         
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
31                 end
32         end
33         
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({
41                                                 amount = 1,
42                                                 time = 0.5,
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},
49                                                 minexptime = 1,
50                                                 maxexptime = 1,
51                                                 minsize = 1,
52                                                 maxsize = 1,
53                                                 collisiondetection = true,
54                                                 collision_removal = true,
55                                                 object_collision = false,
56                                                 texture = "snowflake_"..math.random(1,2)..".png",
57                                                 playername = player:get_name(),
58                                         })
59                                 end
60                         end
61                 end
62         end
63 end
64
65 local spawn_ichor = function(player)
66         local pos = player:get_pos()
67         local radius = 10
68         local particle_table = {}
69         
70         local area = vector.new(10,10,10)
71         
72         local min = vector.subtract(pos, area)
73         local max = vector.add(pos, area)
74         
75         
76         local area_index = minetest.find_nodes_in_area_under_air(min, max, all_nodes)
77         
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
86                 end
87         end
88         
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({
94                                         amount = 1,
95                                         time = 0.5,
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},
102                                         minexptime = 1,
103                                         maxexptime = 1,
104                                         minsize = 1,
105                                         maxsize = 1,
106                                         collisiondetection = true,
107                                         collision_removal = true,
108                                         object_collision = false,
109                                         texture = "ichor_"..math.random(1,2)..".png",
110                                         playername = player:get_name(),
111                                 })
112                         end
113                 end
114         end
115 end
116
117 local spawn_rain = function(player)
118         local pos = player:get_pos()
119         local radius = 10
120         local particle_table = {}
121         
122         local area = vector.new(10,10,10)
123         
124         local min = vector.subtract(pos, area)
125         local max = vector.add(pos, area)
126         
127         
128         local area_index = minetest.find_nodes_in_area_under_air(min, max, all_nodes)
129         
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
138                 end
139         end
140         
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({
148                                                 amount = 3,
149                                                 time = 0.5,
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},
156                                                 minexptime = 1,
157                                                 maxexptime = 2,
158                                                 minsize = 1,
159                                                 maxsize = 1,
160                                                 collisiondetection = true,
161                                                 collision_removal = true,
162                                                 object_collision = false,
163                                                 vertical = true,
164                                                 texture = "raindrop.png",
165                                                 playername = player:get_name(),
166                                         })
167                                 end
168                         end
169                 end
170         end
171 end
172
173 --client runs through spawning weather particles
174 local player_pos
175 minetest.register_globalstep(function(dtime)
176         player_pos = minetest.localplayer:get_pos()
177         if do_effects then
178                 if snow or rain then
179                         weather_update_timer = weather_update_timer + dtime
180                         if weather_update_timer >= 0.5 then
181                                 weather_update_timer = 0
182                                 --do normal weather
183                                 if player_pos.y > -10033 then
184                                         if snow == true then
185                                                 spawn_snow(minetest.localplayer)
186                                         elseif rain == true then
187                                                 spawn_rain(minetest.localplayer)
188                                         end
189                                 --rain blood upwards in the nether
190                                 else
191                                         if snow == true or rain == true then
192                                                 spawn_ichor(minetest.localplayer)
193                                         end
194                                 
195                                         --stop the rain sound effect
196                                         if rain_sound_handle then
197                                                 minetest.sound_fade(rain_sound_handle, -0.5, 0)
198                                                 rain_sound_handle = nil
199                                         end
200                                 end
201                         end
202                 end
203         end
204 end)
205
206
207
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)
213                 do_effects = true
214                 weather:leave() --leave the channel
215         end
216         --receive the weather type
217         if channel_name == "weather_type" then
218                 if message == "1" then
219                         rain = false
220                         snow = true
221                 elseif message == "2" then
222                         rain = true
223                         snow = false
224                 else
225                         rain = false
226                         snow = false
227                 end
228         end
229         --rain sound effect
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
236         end
237 end)
238
239
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
245 end)