X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=weather_handling.lua;h=65ca36cf2d5a268c91c17b184ac12ea7bd0c8359;hb=HEAD;hp=1aca8e4fcca685870b792cf8338663f64f57e102;hpb=cdb5ae719961cf77035187babf1d57be3dbf98d4;p=crafter_client.git diff --git a/weather_handling.lua b/weather_handling.lua index 1aca8e4..65ca36c 100644 --- a/weather_handling.lua +++ b/weather_handling.lua @@ -1,3 +1,12 @@ +local +minetest,name,vector,math,pairs += +minetest,minetest.localplayer:get_name(),vector,math,pairs + +local weather_intake = minetest.mod_channel_join("weather_intake") +local weather = minetest.mod_channel_join("weather_nodes") +local weather_type = minetest.mod_channel_join("weather_type") + local all_nodes = {} local do_effects = false local snow = false @@ -7,20 +16,37 @@ local id_table = {} local rain_sound_handle = nil -local spawn_snow = function(player) - local pos = player:get_pos() - local radius = 10 - local particle_table = {} - - local area = vector.new(10,10,10) - - local min = vector.subtract(pos, area) - local max = vector.add(pos, area) - - - local area_index = minetest.find_nodes_in_area_under_air(min, max, all_nodes) - - local spawn_table = {} +local liquids = { + ["main:water"] = true, + ["main:waterflow"] = true, + ["main:lava"] = true, + ["main:lavaflow"] = true, + ["nether:lava"] = true, + ["nether:lavaflow"] = true, +} + + +local y +local pos +local radius = 10 +local particle_table +local area +local min +local max +local area_index +local spawn_table +local lightlevel +local null +local curr_light +local distance = vector.distance +local current_node +local weather_effects = function(player,defined_type) + pos = vector.round(player:get_pos()) + area = vector.new(10,10,10) + min = vector.subtract(pos, area) + max = vector.add(pos, area) + area_index = minetest.find_nodes_in_area_under_air(min, max, all_nodes) + spawn_table = {} --find the highest y value for _,index in pairs(area_index) do if not spawn_table[index.x] then spawn_table[index.x] = {} end @@ -30,119 +56,162 @@ local spawn_snow = function(player) spawn_table[index.x][index.z] = index.y end end - - for x,x_index in pairs(spawn_table) do - for z,y in pairs(x_index) do - if minetest.get_node_or_nil(vector.new(x,y+1,z)) ~= nil then - local pos = vector.new(x,y+1,z) - local lightlevel = minetest.get_node_light(pos, 0.5) - if lightlevel >= 14 then - minetest.add_particlespawner({ - amount = 1, - time = 0.5, - minpos = vector.new(x-0.5,y,z-0.5), - maxpos = vector.new(x+0.5,y+20,z+0.5), - minvel = {x=-0.2, y=-0.2, z=-0.2}, - maxvel = {x=0.2, y=-0.5, z=0.2}, - minacc = {x=0, y=0, z=0}, - maxacc = {x=0, y=0, z=0}, - minexptime = 1, - maxexptime = 1, - minsize = 1, - maxsize = 1, - collisiondetection = true, - collision_removal = true, - object_collision = false, - texture = "snowflake_"..math.random(1,2)..".png", - playername = player:get_name(), - }) - end + + if defined_type == "rain" then + curr_light = minetest.get_node_light(minetest.camera:get_pos(),0.5) + --rain sound effect + if curr_light then + current_node = minetest.get_node_or_nil(minetest.camera:get_pos()) + + if curr_light >= 15 and current_node and not liquids[current_node.name] then + if not rain_sound_handle then + rain_sound_handle = minetest.sound_play("rain", {loop=true,gain=0}) end + minetest.sound_fade(rain_sound_handle, 0.5, 1) + elseif rain_sound_handle then + minetest.sound_fade(rain_sound_handle, -0.5, 0) + rain_sound_handle = nil end end -end -local spawn_rain = function(player) - local pos = player:get_pos() - local radius = 10 - local particle_table = {} - - local area = vector.new(10,10,10) - - local min = vector.subtract(pos, area) - local max = vector.add(pos, area) - - - local area_index = minetest.find_nodes_in_area_under_air(min, max, all_nodes) - - local spawn_table = {} - --find the highest y value - for _,index in pairs(area_index) do - if not spawn_table[index.x] then spawn_table[index.x] = {} end - if not spawn_table[index.x][index.z] then - spawn_table[index.x][index.z] = index.y - elseif spawn_table[index.x][index.z] < index.y then - spawn_table[index.x][index.z] = index.y - end + particle_table = { + amount = 3, + time = 0.5, + minvel = {x=0, y=-30, z=0}, + maxvel = {x=0, y=-30, z=0}, + minacc = {x=0, y=0, z=0}, + maxacc = {x=0, y=0, z=0}, + minexptime = 0.5, + maxexptime = 0.5, + minsize = 4, + maxsize = 4, + collisiondetection = true, + collision_removal = true, + object_collision = false, + vertical = true, + texture = "raindrop.png^[opacity:80", + } + elseif defined_type == "snow" then + particle_table = { + amount = 1, + time = 0.5, + minvel = {x=-0.2, y=-0.2, z=-0.2}, + maxvel = {x=0.2, y=-0.5, z=0.2}, + minacc = {x=0, y=0, z=0}, + maxacc = {x=0, y=0, z=0}, + minexptime = 1, + maxexptime = 1, + minsize = 1, + maxsize = 1, + collisiondetection = true, + collision_removal = true, + object_collision = false, + texture = "snowflake_"..math.random(1,2)..".png", + } + elseif defined_type == "ichor" then + particle_table = { + amount = 1, + time = 0.5, + minvel = {x=-0.2, y=0.2, z=-0.2}, + maxvel = {x=0.2, y=0.5, z=0.2}, + minacc = {x=0, y=0, z=0}, + maxacc = {x=0, y=0, z=0}, + minexptime = 1, + maxexptime = 1, + minsize = 1, + maxsize = 1, + collisiondetection = true, + collision_removal = true, + object_collision = false, + texture = "ichor_"..math.random(1,2)..".png", + } end - - for x,x_index in pairs(spawn_table) do - for z,y in pairs(x_index) do - if minetest.get_node_or_nil(vector.new(x,y+1,z)) ~= nil then - local pos = vector.new(x,y+1,z) - local lightlevel = minetest.get_node_light(pos, 0.5) - if lightlevel >= 14 then - minetest.add_particlespawner({ - amount = 3, - time = 0.5, - minpos = vector.new(x-0.5,y,z-0.5), - maxpos = vector.new(x+0.5,y+20,z+0.5), - minvel = {x=0, y=-20, z=0}, - maxvel = {x=0, y=-20, z=0}, - minacc = {x=0, y=0, z=0}, - maxacc = {x=0, y=0, z=0}, - minexptime = 1, - maxexptime = 2, - minsize = 1, - maxsize = 1, - collisiondetection = true, - collision_removal = true, - object_collision = false, - vertical = true, - texture = "raindrop.png", - playername = player:get_name(), - }) + + + for x = min.x,max.x do + for z = min.z,max.z do + if distance({x=x,y=0,z=z},{x=pos.x,y=0,z=pos.z}) <= 10 then + y = pos.y - 5 + if spawn_table[x] and spawn_table[x][z] then + y = spawn_table[x][z] + end + if minetest.get_node_or_nil(vector.new(x,y+1,z)) ~= nil then + lightlevel = minetest.get_node_light(vector.new(x,y+1,z), 0.5) + if lightlevel >= 14 or defined_type == "ichor" then + + particle_table.minpos = vector.new(x-0.5,y,z-0.5) + particle_table.maxpos = vector.new(x+0.5,y+20,z+0.5) + + null = minetest.add_particlespawner(particle_table) + end end end end end end -minetest.register_globalstep(function(dtime) + + + +--client runs through spawning weather particles +local player_pos +local current_node +local function update_weather() + player_pos = minetest.localplayer:get_pos() if do_effects then if snow or rain then - weather_update_timer = weather_update_timer + dtime - if weather_update_timer >= 0.5 then - weather_update_timer = 0 - local player = minetest.localplayer - if snow == true then - spawn_snow(minetest.localplayer) - elseif rain == true then - spawn_rain(minetest.localplayer) + current_node = minetest.get_node_or_nil(minetest.camera:get_pos()) + if current_node and not liquids[current_node.name] then + --do normal weather + if player_pos.y > -10033 then + if snow == true then + weather_effects(minetest.localplayer, "snow") + elseif rain == true then + weather_effects(minetest.localplayer, "rain") + end + --rain blood upwards in the nether + else + if snow == true or rain == true then + weather_effects(minetest.localplayer, "ichor") + end + + --stop the rain sound effect + if rain_sound_handle then + minetest.sound_fade(rain_sound_handle, -0.5, 0) + rain_sound_handle = nil + end end + elseif rain_sound_handle then + minetest.sound_fade(rain_sound_handle, -0.5, 0) + rain_sound_handle = nil end end end -end) - + if not rain and rain_sound_handle then + minetest.sound_fade(rain_sound_handle, -0.5, 0) + rain_sound_handle = nil + end + --do again every half second + minetest.after(0.5, function() + update_weather() + end) +end minetest.register_on_modchannel_message(function(channel_name, sender, message) - if channel_name == "weather_nodes" then + --receive the initial packet which tells the client which nodes + --to spawn weather columns on + if sender == "" and channel_name == "weather_nodes" then all_nodes = minetest.deserialize(message) + nodes = {} + for _,key in pairs(all_nodes) do + nodes[key] = true + end do_effects = true + weather:leave() --leave the channel end - if channel_name == "weather_type" then + --receive the weather type + if sender == "" and channel_name == "weather_type" then if message == "1" then rain = false snow = true @@ -154,11 +223,15 @@ minetest.register_on_modchannel_message(function(channel_name, sender, message) snow = false end end - if not rain_sound_handle and rain == true then - rain_sound_handle = minetest.sound_play("rain", {loop=true,gain=0}) - minetest.sound_fade(rain_sound_handle, 0.5, 0.5) - elseif rain_sound_handle and rain == false then - minetest.sound_fade(rain_sound_handle, -0.5, 0) - rain_sound_handle = nil - end +end) + + +--We must tell the server that we're ready +minetest.after(0,function() + weather_intake:send_all("READY") + weather_intake:leave() + weather_intake = nil --leave the channel + + --begin weather update + update_weather() end)