diff options
author | Foghrye4 <foghrye4@gmail.com> | 2016-11-14 18:09:59 +0400 |
---|---|---|
committer | Zeno- <kde.psych@gmail.com> | 2016-11-15 00:09:59 +1000 |
commit | 93e3555eae2deaeca69ee252cfa9cc9c3e0e49ef (patch) | |
tree | 9b9b665b97c01f0b281652a85088b336cc4cefde /src/script | |
parent | 649448a2a91fbf3e944b2f2e739f4e2292af1df0 (diff) | |
download | minetest-93e3555eae2deaeca69ee252cfa9cc9c3e0e49ef.tar.gz minetest-93e3555eae2deaeca69ee252cfa9cc9c3e0e49ef.tar.bz2 minetest-93e3555eae2deaeca69ee252cfa9cc9c3e0e49ef.zip |
Adding particle blend, glow and animation (#4705)
Diffstat (limited to 'src/script')
-rw-r--r-- | src/script/common/c_content.cpp | 13 | ||||
-rw-r--r-- | src/script/common/c_content.h | 2 | ||||
-rw-r--r-- | src/script/common/c_converter.cpp | 22 | ||||
-rw-r--r-- | src/script/common/c_converter.h | 2 | ||||
-rw-r--r-- | src/script/lua_api/l_particles.cpp | 166 |
5 files changed, 193 insertions, 12 deletions
diff --git a/src/script/common/c_content.cpp b/src/script/common/c_content.cpp index f20a65903..d4a25b68b 100644 --- a/src/script/common/c_content.cpp +++ b/src/script/common/c_content.cpp @@ -35,10 +35,11 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "noise.h" #include <json/json.h> -struct EnumString es_TileAnimationType[] = +struct EnumString es_AnimationType[] = { - {TAT_NONE, "none"}, - {TAT_VERTICAL_FRAMES, "vertical_frames"}, + {AT_NONE, "none"}, + {AT_VERTICAL_FRAMES, "vertical_frames"}, + {AT_2D_ANIMATION_SHEET, "2d_animation_sheet"}, {0, NULL}, }; @@ -335,9 +336,9 @@ TileDef read_tiledef(lua_State *L, int index, u8 drawtype) lua_getfield(L, index, "animation"); if(lua_istable(L, -1)){ // {type="vertical_frames", aspect_w=16, aspect_h=16, length=2.0} - tiledef.animation.type = (TileAnimationType) - getenumfield(L, -1, "type", es_TileAnimationType, - TAT_NONE); + tiledef.animation.type = (AnimationType) + getenumfield(L, -1, "type", es_AnimationType, + AT_NONE); tiledef.animation.aspect_w = getintfield_default(L, -1, "aspect_w", 16); tiledef.animation.aspect_h = diff --git a/src/script/common/c_content.h b/src/script/common/c_content.h index 2a2228b6d..32fdb4f04 100644 --- a/src/script/common/c_content.h +++ b/src/script/common/c_content.h @@ -159,6 +159,6 @@ bool push_json_value (lua_State *L, void read_json_value (lua_State *L, Json::Value &root, int index, u8 recursion = 0); -extern struct EnumString es_TileAnimationType[]; +extern struct EnumString es_AnimationType[]; #endif /* C_CONTENT_H_ */ diff --git a/src/script/common/c_converter.cpp b/src/script/common/c_converter.cpp index f36298915..cfb5e26db 100644 --- a/src/script/common/c_converter.cpp +++ b/src/script/common/c_converter.cpp @@ -513,6 +513,28 @@ int getintfield_default(lua_State *L, int table, return result; } +int check_material_type_param(lua_State *L, int table, + const char *fieldname, int default_) +{ + int material_type_param = + getintfield_default(L, table, fieldname, default_); + u32 alphaSource = (material_type_param & 0x0000F000) >> 12; + u32 modulo = (material_type_param & 0x00000F00) >> 8; + u32 srcFact = (material_type_param & 0x000000F0) >> 4; + u32 dstFact = material_type_param & 0x0000000F; + if (alphaSource <= 3 && modulo <= 4 && srcFact <= 10 && dstFact <= 10) { + return material_type_param; + } else { + std::ostringstream error_text; + error_text << "Incorrect material_type_param value "; + error_text << "for particle or particle spawner."; + error_text << std::endl; + throw LuaError(error_text.str()); + return 0; + } +} + + float getfloatfield_default(lua_State *L, int table, const char *fieldname, float default_) { diff --git a/src/script/common/c_converter.h b/src/script/common/c_converter.h index a5fbee765..71ac735c1 100644 --- a/src/script/common/c_converter.h +++ b/src/script/common/c_converter.h @@ -45,6 +45,8 @@ float getfloatfield_default(lua_State *L, int table, const char *fieldname, float default_); int getintfield_default (lua_State *L, int table, const char *fieldname, int default_); +int check_material_type_param(lua_State *L, int table, + const char *fieldname, int default_); bool getstringfield(lua_State *L, int table, const char *fieldname, std::string &result); diff --git a/src/script/lua_api/l_particles.cpp b/src/script/lua_api/l_particles.cpp index 667ac7272..b0a57ce6d 100644 --- a/src/script/lua_api/l_particles.cpp +++ b/src/script/lua_api/l_particles.cpp @@ -21,6 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "lua_api/l_object.h" #include "lua_api/l_internal.h" #include "common/c_converter.h" +#include "common/c_content.h" #include "server.h" #include "particles.h" @@ -34,6 +35,9 @@ with this program; if not, write to the Free Software Foundation, Inc., // collision_removal = bool // vertical = bool // texture = e.g."default_wood.png" +// material_type_param = num +// animation = animation definition +// glow = indexed color or color string int ModApiParticles::l_add_particle(lua_State *L) { MAP_LOCK_REQUIRED; @@ -44,13 +48,24 @@ int ModApiParticles::l_add_particle(lua_State *L) float expirationtime, size; expirationtime = size = 1; + float frame_or_loop_length = -1; + + AnimationType animation_type = AT_NONE; + + u16 vertical_frame_num_or_aspect = 1; + u16 horizontal_frame_num_or_aspect = 1; + u16 first_frame = 0; bool collisiondetection, vertical, collision_removal; collisiondetection = vertical = collision_removal = false; + bool loop_animation = true; std::string texture = ""; std::string playername = ""; + u32 material_type_param = 0; + u8 glow = 0; + if (lua_gettop(L) > 1) // deprecated { log_deprecated(L, "Deprecated add_particle call with individual parameters instead of definition"); @@ -94,8 +109,61 @@ int ModApiParticles::l_add_particle(lua_State *L) acc = lua_istable(L, -1) ? check_v3f(L, -1) : acc; lua_pop(L, 1); - expirationtime = getfloatfield_default(L, 1, "expirationtime", 1); + expirationtime = getfloatfield_default(L, 1, "expirationtime", 1); size = getfloatfield_default(L, 1, "size", 1); + + lua_getfield(L, 1, "animation"); + if (lua_istable(L, -1)) { + animation_type = (AnimationType) + getenumfield(L, -1, "type", es_AnimationType, + AT_NONE); + } + switch (animation_type) { + case AT_NONE: + break; + case AT_2D_ANIMATION_SHEET: + frame_or_loop_length = + getfloatfield_default(L, -1, "frame_length", -1); + vertical_frame_num_or_aspect = + getintfield_default(L, -1, "vertical_frame_num", 1); + horizontal_frame_num_or_aspect = + getintfield_default(L, -1, "horizontal_frame_num", 1); + first_frame = + getintfield_default(L, -1, "first_frame", 0); + loop_animation = + getboolfield_default(L, -1, "loop_animation", true); + break; + case AT_VERTICAL_FRAMES: + frame_or_loop_length = + getfloatfield_default(L, -1, "length", -1); + vertical_frame_num_or_aspect = + getintfield_default(L, -1, "aspect_w", 1); + horizontal_frame_num_or_aspect = + getintfield_default(L, -1, "aspect_h", 1); + first_frame = + getintfield_default(L, -1, "first_frame", 0); + loop_animation = + getboolfield_default(L, -1, "loop_animation", true); + break; + default: + break; + } + lua_pop(L, 1); + + if (animation_type == AT_2D_ANIMATION_SHEET && + first_frame >= vertical_frame_num_or_aspect * + horizontal_frame_num_or_aspect) { + std::ostringstream error_text; + error_text << "first_frame should be lower, than " + << "vertical_frame_num * horizontal_frame_num. " + << "Got first_frame=" << first_frame + << ", vertical_frame_num=" + << vertical_frame_num_or_aspect + << " and horizontal_frame_num=" + << horizontal_frame_num_or_aspect << std::endl; + throw LuaError(error_text.str()); + } + collisiondetection = getboolfield_default(L, 1, "collisiondetection", collisiondetection); collision_removal = getboolfield_default(L, 1, @@ -103,9 +171,16 @@ int ModApiParticles::l_add_particle(lua_State *L) vertical = getboolfield_default(L, 1, "vertical", vertical); texture = getstringfield_default(L, 1, "texture", ""); playername = getstringfield_default(L, 1, "playername", ""); + material_type_param = check_material_type_param(L, 1, "material_type_param", 0); + glow = getintfield_default (L, 1, "glow", 0); } - getServer(L)->spawnParticle(playername, pos, vel, acc, expirationtime, size, - collisiondetection, collision_removal, vertical, texture); + getServer(L)->spawnParticle(playername, pos, vel, acc, expirationtime, + size, collisiondetection, collision_removal, vertical, + texture, material_type_param, + animation_type, + vertical_frame_num_or_aspect, + horizontal_frame_num_or_aspect, + first_frame, frame_or_loop_length, loop_animation, glow); return 1; } @@ -127,21 +202,33 @@ int ModApiParticles::l_add_particle(lua_State *L) // collision_removal = bool // vertical = bool // texture = e.g."default_wood.png" +// material_type_param = num +// animation = animation definition +// glow = indexed color or color string int ModApiParticles::l_add_particlespawner(lua_State *L) { MAP_LOCK_REQUIRED; // Get parameters u16 amount = 1; + u16 vertical_frame_num_or_aspect = 1; + u16 horizontal_frame_num_or_aspect = 1; + u16 min_first_frame = 0; + u16 max_first_frame = 0; v3f minpos, maxpos, minvel, maxvel, minacc, maxacc; minpos= maxpos= minvel= maxvel= minacc= maxacc= v3f(0, 0, 0); float time, minexptime, maxexptime, minsize, maxsize; time= minexptime= maxexptime= minsize= maxsize= 1; + AnimationType animation_type = AT_NONE; + float frame_or_loop_length = -1; bool collisiondetection, vertical, collision_removal; collisiondetection = vertical = collision_removal = false; + bool loop_animation = true; ServerActiveObject *attached = NULL; std::string texture = ""; std::string playername = ""; + u32 material_type_param = 0; + u8 glow = 0; if (lua_gettop(L) > 1) //deprecated { @@ -196,6 +283,65 @@ int ModApiParticles::l_add_particlespawner(lua_State *L) maxexptime = getfloatfield_default(L, 1, "maxexptime", maxexptime); minsize = getfloatfield_default(L, 1, "minsize", minsize); maxsize = getfloatfield_default(L, 1, "maxsize", maxsize); + + + lua_getfield(L, 1, "animation"); + if (lua_istable(L, -1)) { + animation_type = (AnimationType) + getenumfield(L, -1, "type", es_AnimationType, + AT_NONE); + } + switch (animation_type) { + case AT_NONE: + break; + case AT_2D_ANIMATION_SHEET: + frame_or_loop_length = + getfloatfield_default(L, -1, "frame_length", -1); + vertical_frame_num_or_aspect = + getintfield_default(L, -1, "vertical_frame_num", 1); + horizontal_frame_num_or_aspect = + getintfield_default(L, -1, "horizontal_frame_num", 1); + min_first_frame = + getintfield_default(L, -1, "min_first_frame", 0); + max_first_frame = + getintfield_default(L, -1, "max_first_frame", 0); + loop_animation = + getboolfield_default(L, -1, "loop_animation", true); + break; + case AT_VERTICAL_FRAMES: + frame_or_loop_length = + getfloatfield_default(L, -1, "length", -1); + vertical_frame_num_or_aspect = + getintfield_default(L, -1, "aspect_w", 1); + horizontal_frame_num_or_aspect = + getintfield_default(L, -1, "aspect_h", 1); + min_first_frame = + getintfield_default(L, -1, "min_first_frame", 0); + max_first_frame = + getintfield_default(L, -1, "max_first_frame", 0); + loop_animation = + getboolfield_default(L, -1, "loop_animation", true); + break; + default: + break; + } + lua_pop(L, 1); + + if (animation_type == AT_2D_ANIMATION_SHEET && + max_first_frame >= vertical_frame_num_or_aspect * + horizontal_frame_num_or_aspect) { + std::ostringstream error_text; + error_text << "max_first_frame should be lower, than " + << "vertical_frame_num * horizontal_frame_num. " + << "Got max_first_frame=" + << max_first_frame + << ", vertical_frame_num=" + << vertical_frame_num_or_aspect + << " and horizontal_frame_num=" + << horizontal_frame_num_or_aspect << std::endl; + throw LuaError(error_text.str()); + } + collisiondetection = getboolfield_default(L, 1, "collisiondetection", collisiondetection); collision_removal = getboolfield_default(L, 1, @@ -211,6 +357,8 @@ int ModApiParticles::l_add_particlespawner(lua_State *L) vertical = getboolfield_default(L, 1, "vertical", vertical); texture = getstringfield_default(L, 1, "texture", ""); playername = getstringfield_default(L, 1, "playername", ""); + material_type_param = check_material_type_param(L, 1, "material_type_param", 0); + glow = getintfield_default(L, 1, "glow", 0); } u32 id = getServer(L)->addParticleSpawner(amount, time, @@ -223,9 +371,17 @@ int ModApiParticles::l_add_particlespawner(lua_State *L) collision_removal, attached, vertical, - texture, playername); + texture, + playername, + material_type_param, + animation_type, + vertical_frame_num_or_aspect, + horizontal_frame_num_or_aspect, + min_first_frame, max_first_frame, + frame_or_loop_length, + loop_animation, + glow); lua_pushnumber(L, id); - return 1; } |