From 146b4af7aef9c9177151d3383c937f05caac0177 Mon Sep 17 00:00:00 2001 From: Aaron Suen Date: Mon, 30 Dec 2019 10:19:46 -0500 Subject: [PATCH] Initial commit with working proof-of-concept. --- .luacheckrc | 3 ++ .lualocals | 4 ++ api.lua | 105 ++++++++++++++++++++++++++++++++++++++++++++++++++++ demo.lua | 83 +++++++++++++++++++++++++++++++++++++++++ init.lua | 10 +++++ 5 files changed, 205 insertions(+) create mode 100644 .luacheckrc create mode 100644 .lualocals create mode 100644 api.lua create mode 100644 demo.lua create mode 100644 init.lua diff --git a/.luacheckrc b/.luacheckrc new file mode 100644 index 0000000..ba6434e --- /dev/null +++ b/.luacheckrc @@ -0,0 +1,3 @@ +globals = {"minetest", "ItemStack", "VoxelArea", "vector", "nodecore", "include", "SecureRandom"} +color = false +quiet = 1 diff --git a/.lualocals b/.lualocals new file mode 100644 index 0000000..19c8d07 --- /dev/null +++ b/.lualocals @@ -0,0 +1,4 @@ +~print +minetest +ItemStack +VoxelArea diff --git a/api.lua b/api.lua new file mode 100644 index 0000000..531b119 --- /dev/null +++ b/api.lua @@ -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 diff --git a/demo.lua b/demo.lua new file mode 100644 index 0000000..913e88f --- /dev/null +++ b/demo.lua @@ -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) diff --git a/init.lua b/init.lua new file mode 100644 index 0000000..00dafb8 --- /dev/null +++ b/init.lua @@ -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")