2 local weather_type = math.random(0,weather_max)
3 local weather_timer = 0
7 --this updates players skys since it cannot be done clientside
8 local update_player_sky = function()
9 for _,player in ipairs(minetest.get_connected_players()) do
10 if weather_type ~= 0 then
17 dawn_horizon = "#808080",
19 fog_sun_tint = "#808080",
22 night_horizon="#808080"
24 player:set_sun({visible=false,sunrise_visible=false})
25 player:set_moon({visible=false})
26 player:set_stars({visible=false})
35 dawn_horizon = "#bac1f0",
39 night_horizon="#4090ff"
42 player:set_sun({visible=true,sunrise_visible=true})
43 player:set_moon({visible=true})
44 player:set_stars({visible=true})
49 --this tells the client mod to update the weather type
50 local function_send_weather_type = function()
51 local channel = minetest.mod_channel_join("weather_type")
52 channel:send_all(tostring(weather_type))
58 minetest.register_on_mods_loaded(function()
59 for name in pairs(minetest.registered_nodes) do
60 if name ~= "air" and name ~= "ignore" then
61 table.insert(all_nodes,name)
66 --this sends the client all nodes that weather can be on top of
69 --have the client send the server the ready signal
70 minetest.register_on_joinplayer(function(player)
71 minetest.after(5, function()
73 local text = minetest.serialize(all_nodes)
74 local channel = minetest.mod_channel_join("weather_nodes")
75 channel:send_all(text)
78 function_send_weather_type()
86 local do_snow = function(dtime)
87 snow_timer = snow_timer + dtime
88 if snow_timer > 3 then
90 for _,player in ipairs(minetest.get_connected_players()) do
92 local pos = player:get_pos()
94 local meta = player:get_meta()
95 local particle_table = {}
97 local area = vector.new(40,40,40)
99 local min = vector.subtract(pos, area)
100 local max = vector.add(pos, area)
103 local area_index = minetest.find_nodes_in_area_under_air(min, max, all_nodes)
106 local spawn_table = {}
107 for _,index in pairs(area_index) do
108 if not spawn_table[index.x] then spawn_table[index.x] = {} end
109 if not spawn_table[index.x][index.z] then
110 spawn_table[index.x][index.z] = index.y
111 elseif spawn_table[index.x][index.z] < index.y then
112 spawn_table[index.x][index.z] = index.y
117 --find the highest y value
119 for x,x_index in pairs(spawn_table) do
120 for z,y in pairs(x_index) do
121 if math.random() > 0.995 then
122 local lightlevel = minetest.get_node_light(vector.new(x,y+1,z), 0.5)
123 if lightlevel >= 14 then
124 --make it so buildable to nodes get replaced
125 local node = minetest.get_node(vector.new(x,y,z)).name
126 local def = minetest.registered_nodes[node]
127 local buildable = def.buildable_to
128 local walkable = def.walkable
129 local liquid = (def.liquidtype ~= "none")
132 if not buildable and minetest.get_node(vector.new(x,y+1,z)).name ~= "weather:snow" and walkable == true then
133 table.insert(bulk_list, vector.new(x,y+1,z))
134 elseif buildable == true and node ~= "weather:snow" then
135 table.insert(bulk_list, vector.new(x,y,z))
143 minetest.bulk_set_node(bulk_list, {name="weather:snow"})
151 --this sets random weather
152 local weather_timer_goal = (math.random(5,7)+math.random())*60
153 minetest.register_globalstep(function(dtime)
154 weather_timer = weather_timer + dtime
155 if weather_timer >= weather_timer_goal then
156 weather_timer_goal = (math.random(5,7)+math.random())*60
158 weather_type = math.random(0,weather_max)
159 function_send_weather_type()
163 if weather_type == 1 then
168 local snowball_throw = function(player)
169 local pos = player:get_pos()
170 pos.y = pos.y + 1.625
171 --let other players hear the noise too
172 minetest.sound_play("woosh",{to_player=player:get_player_name(), pitch = math.random(80,100)/100})
173 minetest.sound_play("woosh",{pos=pos, exclude_player = player:get_player_name(), pitch = math.random(80,100)/100})
174 local snowball = minetest.add_entity(pos,"weather:snowball")
176 local vel = player:get_player_velocity()
177 snowball:set_velocity(vector.add(vel,vector.multiply(player:get_look_dir(),20)))
178 snowball:get_luaentity().thrower = player:get_player_name()
184 minetest.register_node("weather:snow", {
185 description = "Snow",
186 tiles = {"snow_block.png"},
187 groups = {soft = 1, shovel = 1, hand = 1,pathable = 1,wool=1,dirt=1,falling_node=1},
188 sounds = main.woolSound(),
190 drawtype = "nodebox",
196 items = {"weather:snowball"},
199 items = {"weather:snowball"},
202 items = {"weather:snowball"},
205 items = {"weather:snowball"},
209 items = {"weather:snowball"},
217 {-8/16, -8/16, -8/16, 8/16, -6/16, 8/16},
222 minetest.register_craftitem("weather:snowball", {
223 description = "Snowball",
224 inventory_image = "snowball.png",
227 on_place = function(itemstack, placer, pointed_thing)
228 local worked = snowball_throw(placer)
230 itemstack:take_item()
234 on_secondary_use = function(itemstack, user, pointed_thing)
235 local worked = snowball_throw(user)
237 itemstack:take_item()
245 snowball.initial_properties = {
248 collide_with_objects = false,
249 collisionbox = {-0.1, -0.1, -0.1, 0.1, 0.1, 0.1},
251 visual_size = {x = 0.5, y = 0.5},
259 snowball.snowball = true
261 snowball.on_activate = function(self)
262 self.object:set_acceleration(vector.new(0,-9.81,0))
265 --make this as efficient as possible
266 --make it so you can hit one snowball with another
267 snowball.on_step = function(self, dtime)
268 local vel = self.object:get_velocity()
270 local pos = self.object:get_pos()
272 --hit object with the snowball
273 for _,object in ipairs(minetest.get_objects_inside_radius(pos, 1)) do
274 if (object:is_player() and object:get_hp() > 0 and object:get_player_name() ~= self.thrower) or (object:get_luaentity() and object:get_luaentity().mob == true) then
275 object:punch(self.object, 2,
277 full_punch_interval=1.5,
278 damage_groups = {fleshy=0},
285 if (self.oldvel and ((vel.x == 0 and self.oldvel.x ~= 0) or (vel.y == 0 and self.oldvel.y ~= 0) or (vel.z == 0 and self.oldvel.z ~= 0))) or hit == true then
287 minetest.sound_play("wool",{pos=pos, pitch = math.random(80,100)/100})
288 minetest.add_particlespawner({
290 -- Number of particles spawned over the time period `time`.
293 -- Lifespan of spawner in seconds.
294 -- If time is 0 spawner has infinite lifespan and spawns the `amount` on
295 -- a per-second basis.
299 minvel = {x=-2, y=3, z=-2},
300 maxvel = {x=2, y=5, z=2},
301 minacc = {x=0, y=-9.81, z=0},
302 maxacc = {x=0, y=-9.81, z=0},
307 -- The particles' properties are random values between the min and max
309 -- pos, velocity, acceleration, expirationtime, size
311 collisiondetection = true,
313 collision_removal = true,
315 object_collision = false,
317 texture = "snowflake_"..math.random(1,2)..".png",
327 minetest.register_entity("weather:snowball", snowball)