]> git.lizzy.rs Git - crafter_client.git/blob - weather_handling.lua
Overhaul client version checking
[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
11 --this is rice but it boosts the FPS slightly
12 local y
13 local find_em = minetest.find_nodes_in_area_under_air
14 local pos
15 local radius = 10
16 local particle_table
17 local area
18 local min
19 local max
20 local round_it = vector.round
21 local new_vec  = vector.new
22 local add_it   = vector.add
23 local sub_it   = vector.subtract
24 local area_index
25 local spawn_table
26 local get_the_node = minetest.get_node_or_nil
27 local get_the_light = minetest.get_node_light
28 local lightlevel
29 local add_ps = minetest.add_particlespawner
30 local l_name = name
31 -------
32 local weather_effects = function(player,defined_type)
33         pos = round_it(player:get_pos())
34         particle_table = {}
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
40         spawn_table = {}
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
48                 end
49         end
50         for x = min.x,max.x do
51                 for z = min.z,max.z do
52                         y = pos.y - 5
53                         if spawn_table[x] and spawn_table[x][z] then
54                                 y = spawn_table[x][z]
55                         end
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
60                                                 add_ps({
61                                                         amount = 3,
62                                                         time = 0.5,
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},
69                                                         minexptime = 0.5,
70                                                         maxexptime = 0.5,
71                                                         minsize = 4,
72                                                         maxsize = 4,
73                                                         collisiondetection = true,
74                                                         collision_removal = true,
75                                                         object_collision = false,
76                                                         vertical = true,
77                                                         texture = "raindrop.png^[opacity:80",
78                                                         playername = l_name,
79                                                 })
80                                         elseif defined_type == "snow" then
81                                                 add_ps({
82                                                         amount = 1,
83                                                         time = 0.5,
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},
90                                                         minexptime = 1,
91                                                         maxexptime = 1,
92                                                         minsize = 1,
93                                                         maxsize = 1,
94                                                         collisiondetection = true,
95                                                         collision_removal = true,
96                                                         object_collision = false,
97                                                         texture = "snowflake_"..math.random(1,2)..".png",
98                                                         playername = l_name,
99                                                 })
100                                         elseif defined_type == "ichor" then
101                                                 add_ps({
102                                                         amount = 1,
103                                                         time = 0.5,
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},
110                                                         minexptime = 1,
111                                                         maxexptime = 1,
112                                                         minsize = 1,
113                                                         maxsize = 1,
114                                                         collisiondetection = true,
115                                                         collision_removal = true,
116                                                         object_collision = false,
117                                                         texture = "ichor_"..math.random(1,2)..".png",
118                                                         playername = player:get_name(),
119                                                 })
120                                         end
121                                 end
122                         end
123                 end
124         end
125 end
126
127
128
129 --client runs through spawning weather particles
130 local player_pos
131 local function update_weather()
132         player_pos = minetest.localplayer:get_pos()
133         if do_effects then
134                 if snow or rain then
135                         --do normal weather
136                         if player_pos.y > -10033 then
137                                 if snow == true then
138                                         weather_effects(minetest.localplayer, "snow")
139                                 elseif rain == true then
140                                         weather_effects(minetest.localplayer, "rain")
141                                 end
142                         --rain blood upwards in the nether
143                         else
144                                 if snow == true or rain == true then
145                                         weather_effects(minetest.localplayer, "ichor")
146                                 end
147                         
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
152                                 end
153                         end
154                 end
155         end
156         --do again every half second
157         minetest.after(0.5, function()
158                 update_weather()
159         end)
160 end
161
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)
167                 do_effects = true
168                 weather:leave() --leave the channel
169         end
170         --receive the weather type
171         if sender == "" and channel_name == "weather_type" then
172                 if message == "1" then
173                         rain = false
174                         snow = true
175                 elseif message == "2" then
176                         rain = true
177                         snow = false
178                 else
179                         rain = false
180                         snow = false
181                 end
182         end
183         --rain sound effect
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
190         end
191 end)
192
193
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
199         
200         --begin weather update
201         update_weather()
202 end)