Allow node cracking animations of any length
authorPerttu Ahola <celeron55@gmail.com>
Sat, 16 Jun 2012 15:02:56 +0000 (18:02 +0300)
committerPerttu Ahola <celeron55@gmail.com>
Sat, 16 Jun 2012 15:02:56 +0000 (18:02 +0300)
games/minimal/mods/default/textures/crack.png [deleted file]
games/minimal/mods/default/textures/crack_anylength.png [new file with mode: 0644]
src/game.cpp
src/tile.cpp

diff --git a/games/minimal/mods/default/textures/crack.png b/games/minimal/mods/default/textures/crack.png
deleted file mode 100644 (file)
index 4997839..0000000
Binary files a/games/minimal/mods/default/textures/crack.png and /dev/null differ
diff --git a/games/minimal/mods/default/textures/crack_anylength.png b/games/minimal/mods/default/textures/crack_anylength.png
new file mode 100644 (file)
index 0000000..031888a
Binary files /dev/null and b/games/minimal/mods/default/textures/crack_anylength.png differ
index ac6d13af106677b4601cfc5bc6793cfb6ba426e5..83e853b93fb87e848d03d27f128b35ec9d1f98ac 100644 (file)
@@ -1225,6 +1225,16 @@ void the_game(
        */
        Inventory local_inventory(itemdef);
 
+       /*
+               Find out size of crack animation
+       */
+       int crack_animation_length = 5;
+       {
+               video::ITexture *t = tsrc->getTextureRaw("crack_anylength.png");
+               v2u32 size = t->getOriginalSize();
+               crack_animation_length = size.Y / size.X;
+       }
+
        /*
                Add some gui stuff
        */
@@ -2271,20 +2281,20 @@ void the_game(
 
                                if(dig_time_complete >= 0.001)
                                {
-                                       dig_index = (u16)((float)CRACK_ANIMATION_LENGTH
+                                       dig_index = (u16)((float)crack_animation_length
                                                        * dig_time/dig_time_complete);
                                }
                                // This is for torches
                                else
                                {
-                                       dig_index = CRACK_ANIMATION_LENGTH;
+                                       dig_index = crack_animation_length;
                                }
                                
                                // Don't show cracks if not diggable
                                if(dig_time_complete >= 100000.0)
                                {
                                }
-                               else if(dig_index < CRACK_ANIMATION_LENGTH)
+                               else if(dig_index < crack_animation_length)
                                {
                                        //TimeTaker timer("client.setTempMod");
                                        //infostream<<"dig_index="<<dig_index<<std::endl;
@@ -2302,7 +2312,7 @@ void the_game(
                                        digging = false;
 
                                        nodig_delay_timer = dig_time_complete
-                                                       / (float)CRACK_ANIMATION_LENGTH;
+                                                       / (float)crack_animation_length;
 
                                        // We don't want a corresponding delay to
                                        // very time consuming nodes
index 92c56c2772d2098f1bdebecf6ec8027c065b17b3..f0b905c4a67ebee3720dd5fe9370132b8b99932f 100644 (file)
@@ -502,6 +502,11 @@ u32 TextureSource::getTextureId(const std::string &name)
 // Overlay image on top of another image (used for cracks)
 void overlay(video::IImage *image, video::IImage *overlay);
 
+// Draw an image on top of an another one, using the alpha channel of the
+// source image
+static void blit_with_alpha(video::IImage *src, video::IImage *dst,
+               v2s32 src_pos, v2s32 dst_pos, v2u32 size);
+
 // Brighten image
 void brighten(video::IImage *image);
 // Parse a transform name
@@ -1266,7 +1271,8 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg,
                                It is an image with a number of cracking stages
                                horizontally tiled.
                        */
-                       video::IImage *img_crack = sourcecache->getOrLoad("crack.png", device);
+                       video::IImage *img_crack = sourcecache->getOrLoad(
+                                       "crack_anylength.png", device);
                
                        if(img_crack && progression >= 0)
                        {
@@ -1305,11 +1311,13 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg,
                                        }
                                        else
                                        {
-                                               img_crack_scaled->copyToWithAlpha(
+                                               /*img_crack_scaled->copyToWithAlpha(
                                                                baseimg,
                                                                v2s32(0,0),
                                                                core::rect<s32>(v2s32(0,0), dim_base),
-                                                               video::SColor(255,255,255,255));
+                                                               video::SColor(255,255,255,255));*/
+                                               blit_with_alpha(img_crack_scaled, baseimg,
+                                                               v2s32(0,0), v2s32(0,0), dim_base);
                                        }
                                }
 
@@ -1721,6 +1729,30 @@ void overlay(video::IImage *image, video::IImage *overlay)
        }
 }
 
+/*
+       Draw an image on top of an another one, using the alpha channel of the
+       source image
+
+       This exists because IImage::copyToWithAlpha() doesn't seem to always
+       work.
+*/
+static void blit_with_alpha(video::IImage *src, video::IImage *dst,
+               v2s32 src_pos, v2s32 dst_pos, v2u32 size)
+{
+       for(u32 y0=0; y0<size.Y; y0++)
+       for(u32 x0=0; x0<size.X; x0++)
+       {
+               s32 src_x = src_pos.X + x0;
+               s32 src_y = src_pos.Y + y0;
+               s32 dst_x = dst_pos.X + x0;
+               s32 dst_y = dst_pos.Y + y0;
+               video::SColor src_c = src->getPixel(src_x, src_y);
+               video::SColor dst_c = dst->getPixel(dst_x, dst_y);
+               dst_c = src_c.getInterpolated(dst_c, (float)src_c.getAlpha()/255.0f);
+               dst->setPixel(dst_x, dst_y, dst_c);
+       }
+}
+
 void brighten(video::IImage *image)
 {
        if(image == NULL)