Initial commit with working proof-of-concept.
commit
146b4af7ae
|
@ -0,0 +1,3 @@
|
|||
globals = {"minetest", "ItemStack", "VoxelArea", "vector", "nodecore", "include", "SecureRandom"}
|
||||
color = false
|
||||
quiet = 1
|
|
@ -0,0 +1,4 @@
|
|||
~print
|
||||
minetest
|
||||
ItemStack
|
||||
VoxelArea
|
|
@ -0,0 +1,105 @@
|
|||
-- 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
|
|
@ -0,0 +1,83 @@
|
|||
-- LUALOCALS < ---------------------------------------------------------
|
||||
local math, minetest
|
||||
= math, minetest
|
||||
local math_random
|
||||
= math.random
|
||||
-- LUALOCALS > ---------------------------------------------------------
|
||||
|
||||
local modname = minetest.get_current_modname()
|
||||
|
||||
local blackdot = "[combine:1x1^[noalpha"
|
||||
local bdesc = blackdot:gsub("%^", "\\^"):gsub(":", "\\:")
|
||||
local frame = "[combine:16x16:0,0=" .. bdesc .. ":15,0=" .. bdesc
|
||||
.. ":0,15=" .. bdesc .. ":15,15=" .. bdesc
|
||||
|
||||
local function regdemo(num, func)
|
||||
return minetest.register_node(modname .. ":demo" .. num, {
|
||||
drawtype = "allfaces",
|
||||
tiles = {{name = frame, backface_culling = false}},
|
||||
groups = {[modname] = 1},
|
||||
on_punch = function(pos) return minetest.remove_node(pos) end,
|
||||
on_demo = func
|
||||
})
|
||||
end
|
||||
|
||||
minetest.register_abm({
|
||||
nodenames = {"group:" .. modname},
|
||||
interval = 2,
|
||||
chance = 1,
|
||||
action = function(pos, node)
|
||||
local def = minetest.registered_nodes[node.name]
|
||||
if def and def.on_demo then return def.on_demo(pos, node) end
|
||||
end
|
||||
})
|
||||
|
||||
regdemo(1, function(pos)
|
||||
local endpos = {
|
||||
x = pos.x + math_random() * 20 - 10,
|
||||
y = pos.y + math_random() * 20 - 10,
|
||||
z = pos.z + math_random() * 20 - 10,
|
||||
}
|
||||
minetest.add_particlespawner_advanced({
|
||||
amount = 25,
|
||||
time = 0.25,
|
||||
pos = {
|
||||
x = {pos.x, endpos.x - pos.x},
|
||||
y = {pos.y, endpos.y - pos.y},
|
||||
z = {pos.z, endpos.z - pos.z}
|
||||
},
|
||||
velocity = {
|
||||
x = {(endpos.x - pos.x) / 2, -(endpos.x - pos.x) / 2},
|
||||
y = {(endpos.y - pos.y) / 2, -(endpos.y - pos.y) / 2},
|
||||
z = {(endpos.z - pos.z) / 2, -(endpos.z - pos.z) / 2}
|
||||
},
|
||||
expirationtime = {2, -0.25},
|
||||
texture = blackdot,
|
||||
size = {1, 4}
|
||||
})
|
||||
end)
|
||||
|
||||
regdemo(2, function(pos)
|
||||
minetest.add_particlespawner_advanced({
|
||||
amount = 25,
|
||||
time = 0,
|
||||
pos = {
|
||||
x = {pos.x, -10, 20},
|
||||
y = {pos.y, -10, 0, 20},
|
||||
z = {pos.z, -10, 0, 0, 20}
|
||||
},
|
||||
velocity = {
|
||||
x = {0, 20, -40},
|
||||
y = {0, 20, 0, -40},
|
||||
z = {0, 20, 0, 0, -40}
|
||||
},
|
||||
acceleration = {
|
||||
x = {0, -20, 40},
|
||||
y = {0, -20, 0, 40},
|
||||
z = {0, -20, 0, 0, 40}
|
||||
},
|
||||
expirationtime = {1},
|
||||
texture = blackdot,
|
||||
size = {1, 0, 0, 0, 0, 4}
|
||||
})
|
||||
end)
|
|
@ -0,0 +1,10 @@
|
|||
-- LUALOCALS < ---------------------------------------------------------
|
||||
local dofile, minetest
|
||||
= dofile, minetest
|
||||
-- LUALOCALS > ---------------------------------------------------------
|
||||
|
||||
local modname = minetest.get_current_modname()
|
||||
local modpath = minetest.get_modpath(modname)
|
||||
|
||||
dofile(modpath .. "/api.lua")
|
||||
dofile(modpath .. "/demo.lua")
|
Loading…
Reference in New Issue