]> git.lizzy.rs Git - crafter_client.git/blob - weather_handling.lua
Fix minetest.camera not initializing before client runs globalstep
[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_rain = 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                                 local lightlevel = minetest.get_node_light(pos, 0.5)
94                                 if lightlevel >= 14 then
95                                         minetest.add_particlespawner({
96                                                 amount = 3,
97                                                 time = 0.5,
98                                                 minpos = vector.new(x-0.5,y,z-0.5),
99                                                 maxpos = vector.new(x+0.5,y+20,z+0.5),
100                                                 minvel = {x=0, y=-20, z=0},
101                                                 maxvel = {x=0, y=-20, z=0},
102                                                 minacc = {x=0, y=0, z=0},
103                                                 maxacc = {x=0, y=0, z=0},
104                                                 minexptime = 1,
105                                                 maxexptime = 2,
106                                                 minsize = 1,
107                                                 maxsize = 1,
108                                                 collisiondetection = true,
109                                                 collision_removal = true,
110                                                 object_collision = false,
111                                                 vertical = true,
112                                                 texture = "raindrop.png",
113                                                 playername = player:get_name(),
114                                         })
115                                 end
116                         end
117                 end
118         end
119 end
120
121 --client runs through spawning weather particles
122 minetest.register_globalstep(function(dtime)
123         if do_effects then
124                 if snow or rain then
125                         weather_update_timer = weather_update_timer + dtime
126                         if weather_update_timer >= 0.5 then
127                                 weather_update_timer = 0
128                                 local player = minetest.localplayer
129                                 if snow == true then
130                                         spawn_snow(minetest.localplayer)
131                                 elseif rain == true then
132                                         spawn_rain(minetest.localplayer)
133                                 end
134                         end
135                 end
136         end
137 end)
138
139
140
141 minetest.register_on_modchannel_message(function(channel_name, sender, message)
142         --receive the initial packet which tells the client which nodes
143         --to spawn weather columns on
144         if channel_name == "weather_nodes" then
145                 all_nodes = minetest.deserialize(message)
146                 do_effects = true
147                 weather:leave() --leave the channel
148         end
149         --receive the weather type
150         if channel_name == "weather_type" then
151                 if message == "1" then
152                         rain = false
153                         snow = true
154                 elseif message == "2" then
155                         rain = true
156                         snow = false
157                 else
158                         rain = false
159                         snow = false
160                 end
161         end
162         --rain sound effect
163         if not rain_sound_handle and rain == true then
164                 rain_sound_handle = minetest.sound_play("rain", {loop=true,gain=0})
165                 minetest.sound_fade(rain_sound_handle, 0.5, 0.5)
166         elseif rain_sound_handle and rain == false then
167                 minetest.sound_fade(rain_sound_handle, -0.5, 0)
168                 rain_sound_handle = nil
169         end
170 end)