diff --git a/doc/lua_api.txt b/doc/lua_api.txt index 648a29303..6166826af 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -3702,7 +3702,26 @@ Definition tables * `image` (name) ### Tile animation definition -* `{type="vertical_frames", aspect_w=16, aspect_h=16, length=3.0}` + + { + type = "vertical_frames", + aspect_w = 16, + -- ^ specify width of a frame in pixels + aspect_h = 16, + -- ^ specify height of a frame in pixels + length = 3.0, + -- ^ specify full loop length + } + + { + type = "sheet_2d", + frames_w = 5, + -- ^ specify width in number of frames + frames_h = 3, + -- ^ specify height in number of frames + frame_length = 0.5, + -- ^ specify length of a single frame + } ### Node definition (`register_node`) diff --git a/games/minimal/mods/default/init.lua b/games/minimal/mods/default/init.lua index f532e7193..2f73b53ef 100644 --- a/games/minimal/mods/default/init.lua +++ b/games/minimal/mods/default/init.lua @@ -1044,8 +1044,11 @@ minetest.register_node("default:lava_source", { inventory_image = minetest.inventorycube("default_lava.png"), drawtype = "liquid", --tiles ={"default_lava.png"}, - tiles ={ - {name="default_lava_source_animated.png", animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=3.0}} + tiles = { + { + name = "default_lava_source_animated.png", + animation = {type="sheet_2d", frames_w=3, frames_h=2, frame_length=0.5} + } }, special_tiles = { -- New-style lava source material (mostly unused) diff --git a/games/minimal/mods/default/textures/default_lava_source_animated.png b/games/minimal/mods/default/textures/default_lava_source_animated.png index aa9d57cf1..54f4c0ddd 100644 Binary files a/games/minimal/mods/default/textures/default_lava_source_animated.png and b/games/minimal/mods/default/textures/default_lava_source_animated.png differ diff --git a/src/nodedef.cpp b/src/nodedef.cpp index 21bceb94d..92cdf738e 100644 --- a/src/nodedef.cpp +++ b/src/nodedef.cpp @@ -528,7 +528,7 @@ void ContentFeatures::fillTileAttribs(ITextureSource *tsrc, TileSpec *tile, tile->material_flags = 0; if (backface_culling) tile->material_flags |= MATERIAL_FLAG_BACKFACE_CULLING; - if (tiledef->animation.type == TAT_VERTICAL_FRAMES) + if (tiledef->animation.type != TAT_NONE) tile->material_flags |= MATERIAL_FLAG_ANIMATION; if (tiledef->tileable_horizontal) tile->material_flags |= MATERIAL_FLAG_TILEABLE_HORIZONTAL; diff --git a/src/particles.cpp b/src/particles.cpp index e9ddba986..97f42e2c4 100644 --- a/src/particles.cpp +++ b/src/particles.cpp @@ -570,7 +570,7 @@ void ParticleManager::addNodeParticle(IGameDef* gamedef, scene::ISceneManager* s video::ITexture *texture; // Only use first frame of animated texture - if(tiles[texid].material_flags & MATERIAL_FLAG_ANIMATION) + if (tiles[texid].material_flags & MATERIAL_FLAG_ANIMATION) texture = tiles[texid].frames[0].texture; else texture = tiles[texid].texture; diff --git a/src/script/common/c_content.cpp b/src/script/common/c_content.cpp index 6cd1d040b..b9bcfef69 100644 --- a/src/script/common/c_content.cpp +++ b/src/script/common/c_content.cpp @@ -39,6 +39,7 @@ struct EnumString es_TileAnimationType[] = { {TAT_NONE, "none"}, {TAT_VERTICAL_FRAMES, "vertical_frames"}, + {TAT_SHEET_2D, "sheet_2d"}, {0, NULL}, }; @@ -334,16 +335,26 @@ TileDef read_tiledef(lua_State *L, int index, u8 drawtype) // animation = {} 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.vertical_frames.aspect_w = - getintfield_default(L, -1, "aspect_w", 16); - tiledef.animation.vertical_frames.aspect_h = - getintfield_default(L, -1, "aspect_h", 16); - tiledef.animation.vertical_frames.length = - getfloatfield_default(L, -1, "length", 1.0); + if (tiledef.animation.type == TAT_VERTICAL_FRAMES) { + // {type="vertical_frames", aspect_w=16, aspect_h=16, length=2.0} + tiledef.animation.vertical_frames.aspect_w = + getintfield_default(L, -1, "aspect_w", 16); + tiledef.animation.vertical_frames.aspect_h = + getintfield_default(L, -1, "aspect_h", 16); + tiledef.animation.vertical_frames.length = + getfloatfield_default(L, -1, "length", 1.0); + } else if (tiledef.animation.type == TAT_SHEET_2D) { + // {type="sheet_2d", frames_w=5, frames_h=3, frame_length=0.5} + getintfield(L, -1, "frames_w", + tiledef.animation.sheet_2d.frames_w); + getintfield(L, -1, "frames_h", + tiledef.animation.sheet_2d.frames_h); + getfloatfield(L, -1, "frame_length", + tiledef.animation.sheet_2d.frame_length); + } } lua_pop(L, 1); } diff --git a/src/tileanimation.cpp b/src/tileanimation.cpp index 891478c9f..a23eecc2e 100644 --- a/src/tileanimation.cpp +++ b/src/tileanimation.cpp @@ -21,7 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc., void TileAnimationParams::serialize(std::ostream &os, u16 protocol_version) const { - if(protocol_version < 29 /* TODO bump */) { + if (protocol_version < 29) { if (type == TAT_VERTICAL_FRAMES) { writeU8(os, type); writeU16(os, vertical_frames.aspect_w); @@ -41,47 +41,69 @@ void TileAnimationParams::serialize(std::ostream &os, u16 protocol_version) cons writeU16(os, vertical_frames.aspect_w); writeU16(os, vertical_frames.aspect_h); writeF1000(os, vertical_frames.length); + } else if (type == TAT_SHEET_2D) { + writeU8(os, sheet_2d.frames_w); + writeU8(os, sheet_2d.frames_h); + writeF1000(os, sheet_2d.frame_length); } } void TileAnimationParams::deSerialize(std::istream &is, u16 protocol_version) { type = (TileAnimationType) readU8(is); - if(protocol_version < 29 /* TODO bump */) { + if (protocol_version < 29) { vertical_frames.aspect_w = readU16(is); vertical_frames.aspect_h = readU16(is); vertical_frames.length = readF1000(is); return; } - if(type == TAT_VERTICAL_FRAMES) { + if (type == TAT_VERTICAL_FRAMES) { vertical_frames.aspect_w = readU16(is); vertical_frames.aspect_h = readU16(is); vertical_frames.length = readF1000(is); + } else if (type == TAT_SHEET_2D) { + sheet_2d.frames_w = readU8(is); + sheet_2d.frames_h = readU8(is); + sheet_2d.frame_length = readF1000(is); } } void TileAnimationParams::determineParams(v2u32 texture_size, int *frame_count, int *frame_length_ms) const { - if (type == TAT_NONE) { + if (type == TAT_VERTICAL_FRAMES) { + int frame_height = (float)texture_size.X / + (float)vertical_frames.aspect_w * + (float)vertical_frames.aspect_h; + int _frame_count = texture_size.Y / frame_height; + if (frame_count) + *frame_count = _frame_count; + if (frame_length_ms) + *frame_length_ms = 1000.0 * vertical_frames.length / _frame_count; + } else if (type == TAT_SHEET_2D) { + if (frame_count) + *frame_count = sheet_2d.frames_w * sheet_2d.frames_h; + if (frame_length_ms) + *frame_length_ms = 1000 * sheet_2d.frame_length; + } else { // TAT_NONE *frame_count = 1; *frame_length_ms = 1000; - return; } - int frame_height = (float)texture_size.X / - (float)vertical_frames.aspect_w * - (float)vertical_frames.aspect_h; - if (frame_count) - *frame_count = texture_size.Y / frame_height; - if (frame_length_ms) - *frame_length_ms = 1000.0 * vertical_frames.length / (texture_size.Y / frame_height); } void TileAnimationParams::getTextureModifer(std::ostream &os, v2u32 texture_size, int frame) const { if (type == TAT_NONE) return; - int frame_count; - determineParams(texture_size, &frame_count, NULL); - os << "^[verticalframe:" << frame_count << ":" << frame; + if (type == TAT_VERTICAL_FRAMES) { + int frame_count; + determineParams(texture_size, &frame_count, NULL); + os << "^[verticalframe:" << frame_count << ":" << frame; + } else if (type == TAT_SHEET_2D) { + int q, r; + q = frame / sheet_2d.frames_w; + r = frame % sheet_2d.frames_w; + os << "^[sheet:" << sheet_2d.frames_w << "x" << sheet_2d.frames_h + << ":" << r << "," << q; + } } diff --git a/src/tileanimation.h b/src/tileanimation.h index d5172ed50..289ce515b 100644 --- a/src/tileanimation.h +++ b/src/tileanimation.h @@ -26,6 +26,7 @@ with this program; if not, write to the Free Software Foundation, Inc., enum TileAnimationType { TAT_NONE = 0, TAT_VERTICAL_FRAMES = 1, + TAT_SHEET_2D = 2, }; struct TileAnimationParams { @@ -38,6 +39,11 @@ struct TileAnimationParams { int aspect_h; // height for aspect ratio float length; // seconds } vertical_frames; + struct { + int frames_w; // number of frames left-to-right + int frames_h; // number of frames top-to-bottom + float frame_length; // seconds + } sheet_2d; }; void serialize(std::ostream &os, u16 protocol_version) const;