advparticles/api.lua

106 lines
3.1 KiB
Lua

-- LUALOCALS < ---------------------------------------------------------
local math, minetest
= math, minetest
local math_floor, math_min, math_random
= math.floor, math.min, math.random
-- LUALOCALS > ---------------------------------------------------------
local modname = minetest.get_current_modname()
local spawners = {}
local function calc_scalar(params, def)
if not def then return 0 end
local total = 0
for i = 1, math_min(#params, #def) do
total = total + params[i] * def[i]
end
return total
end
local function calc_vector(params, def)
if not def then return {x = 0, y = 0, z = 0} end
return {
x = calc_scalar(params, def.x),
y = calc_scalar(params, def.y),
z = calc_scalar(params, def.z)
}
end
local function spawn(def, pnum)
local params = {1, pnum / def.amount}
for _ = 1, 12 do params[#params + 1] = math_random() end
minetest.add_particle({
pos = calc_vector(params, def.pos),
velocity = calc_vector(params, def.velocity),
acceleration = calc_vector(params, def.acceleration),
expirationtime = calc_scalar(params, def.expirationtime),
size = calc_scalar(params, def.size),
glow = calc_scalar(params, def.glow),
collisiondetection = def.collisiondetection,
collision_removal = def.collision_removal,
object_collision = def.object_collision,
vertical = def.vertical,
texture = def.texture,
playername = def.playername,
animation = def.animation
})
end
minetest.register_entity(modname .. ":spawner", {
initial_properties = {
physical = false,
collide_with_objects = false,
collisionbox = {0, 0, 0, 0, 0, 0},
visual_size = {x = 0, y = 0},
is_visible = false,
static_save = false
},
on_activate = function(self, data)
if not data then return self.object:remove() end
data = minetest.deserialize(data)
self.id = data.id
self.def = data.def
self.age = 0
if self.def.time <= 0 then -- corner case
for i = 1, self.def.amount do spawn(self.def, i) end
spawners[self.id] = nil
return self.object:remove()
end
end,
on_step = function(self, dtime)
local start = self.age
self.age = self.age + dtime
if self.age > self.def.time then self.age = self.def.time end
local pstart = math_floor(self.def.amount * start / self.def.time)
local pend = math_floor(self.def.amount * self.age / self.def.time)
for i = pstart + 1, pend do spawn(self.def, i) end
if self.age >= self.def.time then
spawners[self.id] = nil
return self.object:remove()
end
end
})
minetest.add_particlespawner_advanced = minetest.add_particlespawner_advanced or function(def)
local params = {1, 0.5}
for _ = 1, 12 do params[#params + 1] = 0.5 end
local pos = calc_vector(params, def.pos)
local id = #spawners + 1
local obj = minetest.add_entity(pos, modname .. ":spawner",
minetest.serialize({id = id, def = def}))
if not obj then return end
spawners[id] = obj
return id
end
minetest.delete_particlespawner_advanced = minetest.delete_particlespawner_advanced or function(id)
if not id then return end
local obj = spawners[id]
if not obj then return end
obj:remove()
spawners[id] = nil
end