Initial commit with working proof-of-concept.

master
Aaron Suen 2019-12-30 10:19:46 -05:00
commit 146b4af7ae
5 changed files with 205 additions and 0 deletions

3
.luacheckrc Normal file
View File

@ -0,0 +1,3 @@
globals = {"minetest", "ItemStack", "VoxelArea", "vector", "nodecore", "include", "SecureRandom"}
color = false
quiet = 1

4
.lualocals Normal file
View File

@ -0,0 +1,4 @@
~print
minetest
ItemStack
VoxelArea

105
api.lua Normal file
View File

@ -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

83
demo.lua Normal file
View File

@ -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)

10
init.lua Normal file
View File

@ -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")