diff --git a/homedecor/bathroom_sanitation.lua b/homedecor/bathroom_sanitation.lua index 6bad1f61..702298af 100644 --- a/homedecor/bathroom_sanitation.lua +++ b/homedecor/bathroom_sanitation.lua @@ -168,33 +168,12 @@ homedecor.register("shower_tray", { sounds = default.node_sound_stone_defaults(), on_destruct = function(pos) headpos = {x=pos.x, y=pos.y+2, z=pos.z} - local above_spawner_meta = minetest.get_meta(headpos) - - local id = above_spawner_meta:get_int("active") - local s_handle = above_spawner_meta:get_int("sound") - - if id ~= 0 then - minetest.delete_particlespawner(id) - end - - if s_handle then - minetest.after(0, function(s_handle) - minetest.sound_stop(s_handle) - end, s_handle) - end - - above_spawner_meta:set_int("active", nil) - above_spawner_meta:set_int("sound", nil) + homedecor.stop_particle_spawner(headpos) end }) --Shower Head -local fdir_to_flowpos = { - minx = { 0.15, 0.05, -0.15, -0.05 }, maxx = { -0.15, -0.3, 0.15, 0.3 }, - minz = { 0.05, 0.15, -0.05, -0.15 }, maxz = { -0.3, -0.15, 0.3, 0.15 }, - velx = { 0, -0.2, 0, 0.2 }, velz = { -0.2, 0, 0.2, 0 } -} local sh_cbox = { type = "fixed", @@ -214,69 +193,21 @@ homedecor.register("shower_head", { selection_box = sh_cbox, walkable = false, on_rightclick = function (pos, node, clicker) - local below = minetest.get_node({x=pos.x, y=pos.y-2.0, z=pos.z}) - local is_tray = string.find(below.name, "homedecor:shower_tray") - local fdir = node.param2 - local minx = fdir_to_flowpos.minx[fdir + 1] - local maxx = fdir_to_flowpos.maxx[fdir + 1] - local minz = fdir_to_flowpos.minz[fdir + 1] - local maxz = fdir_to_flowpos.maxz[fdir + 1] - local velx = fdir_to_flowpos.velx[fdir + 1] - local velz = fdir_to_flowpos.velz[fdir + 1] - - local this_spawner_meta = minetest.get_meta(pos) - local id = this_spawner_meta:get_int("active") - local s_handle = this_spawner_meta:get_int("sound") - - if id ~= 0 then - if s_handle then - minetest.after(0, function(s_handle) - minetest.sound_stop(s_handle) - end, s_handle) - end - minetest.delete_particlespawner(id) - this_spawner_meta:set_int("active", nil) - this_spawner_meta:set_int("sound", nil) - return - end - - if fdir and fdir < 4 and is_tray and (not id or id == 0) then - id = minetest.add_particlespawner({ - amount = 60, time = 0, collisiondetection = true, - minpos = {x=pos.x - minx, y=pos.y-0.45, z=pos.z - minz}, - maxpos = {x=pos.x - maxx, y=pos.y-0.45, z=pos.z - maxz}, - minvel = {x=velx, y=-2, z=velz}, maxvel = {x=velx, y=-2, z=velz}, - minacc = {x=0, y=0, z=0}, maxacc = {x=0, y=-0.05, z=0}, - minexptime = 2, maxexptime = 4, minsize = 0.5, maxsize = 1, - texture = "homedecor_water_particle.png", - }) - s_handle = minetest.sound_play("homedecor_shower", { - pos = pos, - max_hear_distance = 5, - loop = true - }) - this_spawner_meta:set_int("active", id) - this_spawner_meta:set_int("sound", s_handle) - return + local below = minetest.get_node_or_nil({x=pos.x, y=pos.y-2.0, z=pos.z}) + if below and string.find(below.name, "homedecor:shower_tray") then + local particledef = { + outlet_x = 0, + outlet_y = -0.42, + outlet_z = 0.1, + velocity_x = { min = -0.15, max = 0.15 }, + velocity_z = { min = -0.3, max = 0.1 }, + spread = 0.12 + } + homedecor.start_particle_spawner(pos, node, particledef, "homedecor_shower") end end, on_destruct = function(pos) - local this_spawner_meta = minetest.get_meta(pos) - local id = this_spawner_meta:get_int("active") - local s_handle = this_spawner_meta:get_int("sound") - - if id ~= 0 then - minetest.delete_particlespawner(id) - end - - if s_handle then - minetest.after(0, function(s_handle) - minetest.sound_stop(s_handle) - end, s_handle) - end - - this_spawner_meta:set_int("active", nil) - this_spawner_meta:set_int("sound", nil) + homedecor.stop_particle_spawner(pos) end }) diff --git a/homedecor/handlers/water_particles.lua b/homedecor/handlers/water_particles.lua new file mode 100644 index 00000000..7bbe9688 --- /dev/null +++ b/homedecor/handlers/water_particles.lua @@ -0,0 +1,113 @@ +-- variables taken by the start... function +-- +-- pos and node are as usual, from e.g. on_rightclick. +-- +-- in the { particledef } table: +-- +-- outletx/y/z are the exact coords of the starting point +-- for the spawner, relative to the center of the node +-- +-- velocityx/y are the speed of the particles, +-- relative to a node placed while looking north (facedir 0) +-- +-- spread is the radius from the starting point, +-- along X and Z only, to randomly spawn particles. +-- +-- soundname is the filename (without .ogg) of the sound file +-- to be played along with the particle stream + +function homedecor.start_particle_spawner(pos, node, particledef, soundname) + + local this_spawner_meta = minetest.get_meta(pos) + local id = this_spawner_meta:get_int("active") + local s_handle = this_spawner_meta:get_int("sound") + + if id ~= 0 then + if s_handle then + minetest.after(0, function(s_handle) + minetest.sound_stop(s_handle) + end, s_handle) + end + minetest.delete_particlespawner(id) + this_spawner_meta:set_int("active", nil) + this_spawner_meta:set_int("sound", nil) + return + end + + local fdir = node.param2 + + if fdir and fdir < 4 and (not id or id == 0) then + + local outletx = particledef.outlet_x + local outlety = particledef.outlet_y + local outletz = particledef.outlet_z + local velocityx = particledef.velocity_x + local velocityz = particledef.velocity_z + local spread = particledef.spread + + local minx_t = { outletx - spread, -outletz - spread, outletx - spread, outletz - spread } + local maxx_t = { outletx + spread, -outletz + spread, outletx + spread, outletz + spread } + local minz_t = { -outletz - spread, outletx - spread, outletz - spread, outletx - spread } + local maxz_t = { -outletz + spread, outletx + spread, outletz + spread, outletx + spread } + + local minvelx_t = { velocityx.min, velocityz.min, -velocityx.max, -velocityz.max } + local maxvelx_t = { velocityx.max, velocityz.max, -velocityx.min, -velocityz.min } + local minvelz_t = { velocityz.min, velocityx.min, -velocityz.max, velocityx.min } + local maxvelz_t = { velocityz.max, velocityx.max, -velocityz.min, velocityx.max } + + local minx = minx_t[fdir + 1] + local maxx = maxx_t[fdir + 1] + local minz = minz_t[fdir + 1] + local maxz = maxz_t[fdir + 1] + + local minvelx = minvelx_t[fdir + 1] + local minvelz = minvelz_t[fdir + 1] + local maxvelx = maxvelx_t[fdir + 1] + local maxvelz = maxvelz_t[fdir + 1] + + id = minetest.add_particlespawner({ + amount = 60, + time = 0, + collisiondetection = true, + minpos = {x=pos.x - minx, y=pos.y + outlety, z=pos.z - minz}, + maxpos = {x=pos.x - maxx, y=pos.y + outlety, z=pos.z - maxz}, + minvel = {x = minvelx, y=-2, z = minvelz}, + maxvel = {x = maxvelx, y=-2, z = maxvelz}, + minacc = {x=0, y=0, z=0}, + maxacc = {x=0, y=-0.05, z=0}, + minexptime = 2, + maxexptime = 4, + minsize = 0.5, + maxsize = 1, + texture = "homedecor_water_particle.png", + }) + s_handle = minetest.sound_play(soundname, { + pos = pos, + max_hear_distance = 5, + loop = true + }) + this_spawner_meta:set_int("active", id) + this_spawner_meta:set_int("sound", s_handle) + return + end +end + +function homedecor.stop_particle_spawner(pos) + local this_spawner_meta = minetest.get_meta(pos) + local id = this_spawner_meta:get_int("active") + local s_handle = this_spawner_meta:get_int("sound") + + if id ~= 0 then + minetest.delete_particlespawner(id) + end + + if s_handle then + minetest.after(0, function(s_handle) + minetest.sound_stop(s_handle) + end, s_handle) + end + + this_spawner_meta:set_int("active", nil) + this_spawner_meta:set_int("sound", nil) +end + diff --git a/homedecor/init.lua b/homedecor/init.lua index 901e3132..489fd2ac 100644 --- a/homedecor/init.lua +++ b/homedecor/init.lua @@ -120,6 +120,8 @@ dofile(homedecor.modpath.."/handlers/expansion.lua") dofile(homedecor.modpath.."/handlers/furnaces.lua") -- glue it all together into a registration function dofile(homedecor.modpath.."/handlers/registration.lua") +-- some nodes have particle spawners +dofile(homedecor.modpath.."/handlers/water_particles.lua") -- load various other components dofile(homedecor.modpath.."/misc-nodes.lua") -- the catch-all for all misc nodes