]> git.lizzy.rs Git - dragonfireclient.git/blobdiff - src/tile.cpp
Make shift the default descent control on ladders and when flying
[dragonfireclient.git] / src / tile.cpp
index d2a61b931e5aa90eb01893e04c28b14d0b17115b..f7f1779ca51f619d9d987de00b3fab200d085c22 100644 (file)
@@ -21,7 +21,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "debug.h"
 #include "main.h" // for g_settings
 #include "filesys.h"
-#include "utility.h"
 #include "settings.h"
 #include "mesh.h"
 #include <ICameraSceneNode.h>
@@ -29,7 +28,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "mapnode.h" // For texture atlas making
 #include "nodedef.h" // For texture atlas making
 #include "gamedef.h"
-#include "utility_string.h"
+#include "util/string.h"
+#include "util/container.h"
+#include "util/thread.h"
+#include "util/numeric.h"
 
 /*
        A cache from texture name to texture path
@@ -502,6 +504,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
@@ -858,7 +865,7 @@ void TextureSource::buildMainAtlas(class IGameDef *gamedef)
                const ContentFeatures &f = ndef->get(j);
                for(u32 i=0; i<6; i++)
                {
-                       std::string name = f.tname_tiles[i];
+                       std::string name = f.tiledef[i].name;
                        sourcelist[name] = true;
                }
        }
@@ -988,7 +995,7 @@ void TextureSource::buildMainAtlas(class IGameDef *gamedef)
                                src_x = pos_in_atlas.X;
                        }
                        s32 y = y0 + pos_in_atlas.Y;
-                       s32 src_y = MYMAX(pos_in_atlas.Y, MYMIN(pos_in_atlas.Y + dim.Height - 1, y));
+                       s32 src_y = MYMAX((int)pos_in_atlas.Y, MYMIN((int)pos_in_atlas.Y + (int)dim.Height - 1, y));
                        s32 dst_y = y;
                        video::SColor c = atlas_img->getPixel(src_x, src_y);
                        atlas_img->setPixel(dst_x,dst_y,c);
@@ -1193,10 +1200,11 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg,
                        // Position to copy the blitted from in the blitted image
                        core::position2d<s32> pos_from(0,0);
                        // Blit
-                       image->copyToWithAlpha(baseimg, pos_to,
+                       /*image->copyToWithAlpha(baseimg, pos_to,
                                        core::rect<s32>(pos_from, dim),
                                        video::SColor(255,255,255,255),
-                                       NULL);
+                                       NULL);*/
+                       blit_with_alpha(image, baseimg, pos_from, pos_to, dim);
                        // Drop image
                        image->drop();
                }
@@ -1266,7 +1274,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 +1314,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);
                                        }
                                }
 
@@ -1334,7 +1345,11 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg,
                        u32 h0 = stoi(sf.next(":"));
                        infostream<<"combined w="<<w0<<" h="<<h0<<std::endl;
                        core::dimension2d<u32> dim(w0,h0);
-                       baseimg = driver->createImage(video::ECF_A8R8G8B8, dim);
+                       if(baseimg == NULL)
+                       {
+                               baseimg = driver->createImage(video::ECF_A8R8G8B8, dim);
+                               baseimg->fill(video::SColor(0,0,0,0));
+                       }
                        while(sf.atend() == false)
                        {
                                u32 x = stoi(sf.next(","));
@@ -1354,10 +1369,11 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg,
                                                        driver->createImage(video::ECF_A8R8G8B8, dim);
                                        img->copyTo(img2);
                                        img->drop();
-                                       img2->copyToWithAlpha(baseimg, pos_base,
+                                       /*img2->copyToWithAlpha(baseimg, pos_base,
                                                        core::rect<s32>(v2s32(0,0), dim),
                                                        video::SColor(255,255,255,255),
-                                                       NULL);
+                                                       NULL);*/
+                                       blit_with_alpha(img2, baseimg, v2s32(0,0), pos_base, dim);
                                        img2->drop();
                                }
                                else
@@ -1638,6 +1654,51 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg,
                                img2->drop();
                        }
                }
+               /*
+                       [verticalframe:N:I
+                       Crops a frame of a vertical animation.
+                       N = frame count, I = frame index
+               */
+               else if(part_of_name.substr(0,15) == "[verticalframe:")
+               {
+                       Strfnd sf(part_of_name);
+                       sf.next(":");
+                       u32 frame_count = stoi(sf.next(":"));
+                       u32 frame_index = stoi(sf.next(":"));
+
+                       if(baseimg == NULL){
+                               errorstream<<"generate_image(): baseimg!=NULL "
+                                               <<"for part_of_name=\""<<part_of_name
+                                               <<"\", cancelling."<<std::endl;
+                               return false;
+                       }
+                       
+                       v2u32 frame_size = baseimg->getDimension();
+                       frame_size.Y /= frame_count;
+
+                       video::IImage *img = driver->createImage(video::ECF_A8R8G8B8,
+                                       frame_size);
+                       if(!img){
+                               errorstream<<"generate_image(): Could not create image "
+                                               <<"for part_of_name=\""<<part_of_name
+                                               <<"\", cancelling."<<std::endl;
+                               return false;
+                       }
+
+                       // Fill target image with transparency
+                       img->fill(video::SColor(0,0,0,0));
+
+                       core::dimension2d<u32> dim = frame_size;
+                       core::position2d<s32> pos_dst(0, 0);
+                       core::position2d<s32> pos_src(0, frame_index * frame_size.Y);
+                       baseimg->copyToWithAlpha(img, pos_dst,
+                                       core::rect<s32>(pos_src, dim),
+                                       video::SColor(255,255,255,255),
+                                       NULL);
+                       // Replace baseimg
+                       baseimg->drop();
+                       baseimg = img;
+               }
                else
                {
                        errorstream<<"generate_image(): Invalid "
@@ -1679,6 +1740,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)