diff options
Diffstat (limited to 'src/script/lua_api/l_particles.cpp')
-rw-r--r-- | src/script/lua_api/l_particles.cpp | 214 |
1 files changed, 131 insertions, 83 deletions
diff --git a/src/script/lua_api/l_particles.cpp b/src/script/lua_api/l_particles.cpp index a51c4fe20..586c7dc73 100644 --- a/src/script/lua_api/l_particles.cpp +++ b/src/script/lua_api/l_particles.cpp @@ -20,30 +20,50 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "lua_api/l_particles.h" #include "lua_api/l_object.h" #include "lua_api/l_internal.h" +#include "lua_api/l_particleparams.h" #include "common/c_converter.h" #include "common/c_content.h" #include "server.h" #include "particles.h" -// add_particle({pos=, velocity=, acceleration=, expirationtime=, -// size=, collisiondetection=, collision_removal=, object_collision=, -// vertical=, texture=, player=}) -// pos/velocity/acceleration = {x=num, y=num, z=num} -// expirationtime = num (seconds) -// size = num -// collisiondetection = bool -// collision_removal = bool -// object_collision = bool -// vertical = bool -// texture = e.g."default_wood.png" -// animation = TileAnimation definition -// glow = num +void LuaParticleParams::readTexValue(lua_State* L, ServerParticleTexture& tex) +{ + StackUnroller unroll(L); + + tex.animated = false; + if (lua_isstring(L, -1)) { + tex.string = lua_tostring(L, -1); + return; + } + + luaL_checktype(L, -1, LUA_TTABLE); + lua_getfield(L, -1, "name"); + tex.string = luaL_checkstring(L, -1); + lua_pop(L, 1); + + lua_getfield(L, -1, "animation"); + if (! lua_isnil(L, -1)) { + tex.animated = true; + tex.animation = read_animation_definition(L, -1); + } + lua_pop(L, 1); + + lua_getfield(L, -1, "blend"); + LuaParticleParams::readLuaValue(L, tex.blendmode); + lua_pop(L, 1); + + LuaParticleParams::readTweenTable(L, "alpha", tex.alpha); + LuaParticleParams::readTweenTable(L, "scale", tex.scale); + +} + +// add_particle({...}) int ModApiParticles::l_add_particle(lua_State *L) { NO_MAP_LOCK_REQUIRED; // Get parameters - struct ParticleParameters p; + ParticleParameters p; std::string playername; if (lua_gettop(L) > 1) // deprecated @@ -56,7 +76,7 @@ int ModApiParticles::l_add_particle(lua_State *L) p.expirationtime = luaL_checknumber(L, 4); p.size = luaL_checknumber(L, 5); p.collisiondetection = readParam<bool>(L, 6); - p.texture = luaL_checkstring(L, 7); + p.texture.string = luaL_checkstring(L, 7); if (lua_gettop(L) == 8) // only spawn for a single player playername = luaL_checkstring(L, 8); } @@ -108,7 +128,12 @@ int ModApiParticles::l_add_particle(lua_State *L) p.animation = read_animation_definition(L, -1); lua_pop(L, 1); - p.texture = getstringfield_default(L, 1, "texture", p.texture); + lua_getfield(L, 1, "texture"); + if (!lua_isnil(L, -1)) { + LuaParticleParams::readTexValue(L, p.texture); + } + lua_pop(L, 1); + p.glow = getintfield_default(L, 1, "glow", p.glow); lua_getfield(L, 1, "node"); @@ -119,34 +144,26 @@ int ModApiParticles::l_add_particle(lua_State *L) p.node_tile = getintfield_default(L, 1, "node_tile", p.node_tile); playername = getstringfield_default(L, 1, "playername", ""); + + lua_getfield(L, 1, "drag"); + if (lua_istable(L, -1)) + p.drag = check_v3f(L, -1); + lua_pop(L, 1); + + lua_getfield(L, 1, "jitter"); + LuaParticleParams::readLuaValue(L, p.jitter); + lua_pop(L, 1); + + lua_getfield(L, 1, "bounce"); + LuaParticleParams::readLuaValue(L, p.bounce); + lua_pop(L, 1); } getServer(L)->spawnParticle(playername, p); return 1; } -// add_particlespawner({amount=, time=, -// minpos=, maxpos=, -// minvel=, maxvel=, -// minacc=, maxacc=, -// minexptime=, maxexptime=, -// minsize=, maxsize=, -// collisiondetection=, -// collision_removal=, -// object_collision=, -// vertical=, -// texture=, -// player=}) -// minpos/maxpos/minvel/maxvel/minacc/maxacc = {x=num, y=num, z=num} -// minexptime/maxexptime = num (seconds) -// minsize/maxsize = num -// collisiondetection = bool -// collision_removal = bool -// object_collision = bool -// vertical = bool -// texture = e.g."default_wood.png" -// animation = TileAnimation definition -// glow = num +// add_particlespawner({...}) int ModApiParticles::l_add_particlespawner(lua_State *L) { NO_MAP_LOCK_REQUIRED; @@ -156,24 +173,31 @@ int ModApiParticles::l_add_particlespawner(lua_State *L) ServerActiveObject *attached = NULL; std::string playername; + using namespace ParticleParamTypes; if (lua_gettop(L) > 1) //deprecated { log_deprecated(L, "Deprecated add_particlespawner call with " "individual parameters instead of definition"); p.amount = luaL_checknumber(L, 1); p.time = luaL_checknumber(L, 2); - p.minpos = check_v3f(L, 3); - p.maxpos = check_v3f(L, 4); - p.minvel = check_v3f(L, 5); - p.maxvel = check_v3f(L, 6); - p.minacc = check_v3f(L, 7); - p.maxacc = check_v3f(L, 8); - p.minexptime = luaL_checknumber(L, 9); - p.maxexptime = luaL_checknumber(L, 10); - p.minsize = luaL_checknumber(L, 11); - p.maxsize = luaL_checknumber(L, 12); + auto minpos = check_v3f(L, 3); + auto maxpos = check_v3f(L, 4); + auto minvel = check_v3f(L, 5); + auto maxvel = check_v3f(L, 6); + auto minacc = check_v3f(L, 7); + auto maxacc = check_v3f(L, 8); + auto minexptime = luaL_checknumber(L, 9); + auto maxexptime = luaL_checknumber(L, 10); + auto minsize = luaL_checknumber(L, 11); + auto maxsize = luaL_checknumber(L, 12); + p.pos = v3fRange(minpos, maxpos); + p.vel = v3fRange(minvel, maxvel); + p.acc = v3fRange(minacc, maxacc); + p.exptime = f32Range(minexptime, maxexptime); + p.size = f32Range(minsize, maxsize); + p.collisiondetection = readParam<bool>(L, 13); - p.texture = luaL_checkstring(L, 14); + p.texture.string = luaL_checkstring(L, 14); if (lua_gettop(L) == 15) // only spawn for a single player playername = luaL_checkstring(L, 15); } @@ -182,40 +206,46 @@ int ModApiParticles::l_add_particlespawner(lua_State *L) p.amount = getintfield_default(L, 1, "amount", p.amount); p.time = getfloatfield_default(L, 1, "time", p.time); - lua_getfield(L, 1, "minpos"); - if (lua_istable(L, -1)) - p.minpos = check_v3f(L, -1); - lua_pop(L, 1); - - lua_getfield(L, 1, "maxpos"); - if (lua_istable(L, -1)) - p.maxpos = check_v3f(L, -1); - lua_pop(L, 1); - - lua_getfield(L, 1, "minvel"); - if (lua_istable(L, -1)) - p.minvel = check_v3f(L, -1); - lua_pop(L, 1); - - lua_getfield(L, 1, "maxvel"); - if (lua_istable(L, -1)) - p.maxvel = check_v3f(L, -1); - lua_pop(L, 1); - - lua_getfield(L, 1, "minacc"); - if (lua_istable(L, -1)) - p.minacc = check_v3f(L, -1); - lua_pop(L, 1); - - lua_getfield(L, 1, "maxacc"); - if (lua_istable(L, -1)) - p.maxacc = check_v3f(L, -1); - lua_pop(L, 1); + // set default values + p.exptime = 1; + p.size = 1; + + // read spawner parameters from the table + LuaParticleParams::readTweenTable(L, "pos", p.pos); + LuaParticleParams::readTweenTable(L, "vel", p.vel); + LuaParticleParams::readTweenTable(L, "acc", p.acc); + LuaParticleParams::readTweenTable(L, "size", p.size); + LuaParticleParams::readTweenTable(L, "exptime", p.exptime); + LuaParticleParams::readTweenTable(L, "drag", p.drag); + LuaParticleParams::readTweenTable(L, "jitter", p.jitter); + LuaParticleParams::readTweenTable(L, "bounce", p.bounce); + lua_getfield(L, 1, "attract"); + if (!lua_isnil(L, -1)) { + luaL_checktype(L, -1, LUA_TTABLE); + lua_getfield(L, -1, "kind"); + LuaParticleParams::readLuaValue(L, p.attractor_kind); + lua_pop(L,1); + + lua_getfield(L, -1, "die_on_contact"); + if (!lua_isnil(L, -1)) + p.attractor_kill = readParam<bool>(L, -1); + lua_pop(L,1); + + if (p.attractor_kind != AttractorKind::none) { + LuaParticleParams::readTweenTable(L, "strength", p.attract); + LuaParticleParams::readTweenTable(L, "origin", p.attractor_origin); + p.attractor_attachment = LuaParticleParams::readAttachmentID(L, "origin_attached"); + if (p.attractor_kind != AttractorKind::point) { + LuaParticleParams::readTweenTable(L, "direction", p.attractor_direction); + p.attractor_direction_attachment = LuaParticleParams::readAttachmentID(L, "direction_attached"); + } + } + } else { + p.attractor_kind = AttractorKind::none; + } + lua_pop(L,1); + LuaParticleParams::readTweenTable(L, "radius", p.radius); - p.minexptime = getfloatfield_default(L, 1, "minexptime", p.minexptime); - p.maxexptime = getfloatfield_default(L, 1, "maxexptime", p.maxexptime); - p.minsize = getfloatfield_default(L, 1, "minsize", p.minsize); - p.maxsize = getfloatfield_default(L, 1, "maxsize", p.maxsize); p.collisiondetection = getboolfield_default(L, 1, "collisiondetection", p.collisiondetection); p.collision_removal = getboolfield_default(L, 1, @@ -234,11 +264,29 @@ int ModApiParticles::l_add_particlespawner(lua_State *L) attached = ObjectRef::getobject(ref); } + lua_getfield(L, 1, "texture"); + if (!lua_isnil(L, -1)) { + LuaParticleParams::readTexValue(L, p.texture); + } + lua_pop(L, 1); + p.vertical = getboolfield_default(L, 1, "vertical", p.vertical); - p.texture = getstringfield_default(L, 1, "texture", p.texture); playername = getstringfield_default(L, 1, "playername", ""); p.glow = getintfield_default(L, 1, "glow", p.glow); + lua_getfield(L, 1, "texpool"); + if (lua_istable(L, -1)) { + size_t tl = lua_objlen(L, -1); + p.texpool.reserve(tl); + for (size_t i = 0; i < tl; ++i) { + lua_pushinteger(L, i+1), lua_gettable(L, -2); + p.texpool.emplace_back(); + LuaParticleParams::readTexValue(L, p.texpool.back()); + lua_pop(L,1); + } + } + lua_pop(L, 1); + lua_getfield(L, 1, "node"); if (lua_istable(L, -1)) p.node = readnode(L, -1, getGameDef(L)->ndef()); |