]> git.lizzy.rs Git - dragonfireclient.git/blobdiff - src/content_mapblock.cpp
Make shift the default descent control on ladders and when flying
[dragonfireclient.git] / src / content_mapblock.cpp
index 2fc179fabd4f6048f644cb98776c812e44ac9685..ad819e7939e9669853f44db449a339a06e40e4c3 100644 (file)
@@ -25,6 +25,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "nodedef.h"
 #include "tile.h"
 #include "gamedef.h"
+#include "util/numeric.h"
+#include "util/serialize.h"
+#include "util/directiontables.h"
 
 // Create a cuboid.
 //  collector - the MeshCollector for the resulting polygons
@@ -471,7 +474,9 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
                                                        pa_liquid.x0(), pa_liquid.y0()),
                                };
                                
-                               // This fixes a strange bug
+                               // To get backface culling right, the vertices need to go
+                               // clockwise around the front of the face. And we happened to
+                               // calculate corner levels in exact reverse order.
                                s32 corner_resolve[4] = {3,2,1,0};
 
                                for(s32 i=0; i<4; i++)
@@ -482,6 +487,52 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
                                        vertices[i].Pos.Y += corner_levels[j];
                                        vertices[i].Pos += intToFloat(p, BS);
                                }
+                               
+                               // Default downwards-flowing texture animation goes from 
+                               // -Z towards +Z, thus the direction is +Z.
+                               // Rotate texture to make animation go in flow direction
+                               // Positive if liquid moves towards +Z
+                               int dz = (corner_levels[side_corners[2][0]] +
+                                               corner_levels[side_corners[2][1]] <
+                                               corner_levels[side_corners[3][0]] +
+                                               corner_levels[side_corners[3][1]]);
+                               // Positive if liquid moves towards +X
+                               int dx = (corner_levels[side_corners[0][0]] +
+                                               corner_levels[side_corners[0][1]] <
+                                               corner_levels[side_corners[1][0]] +
+                                               corner_levels[side_corners[1][1]]);
+                               // -X
+                               if(-dx >= abs(dz))
+                               {
+                                       v2f t = vertices[0].TCoords;
+                                       vertices[0].TCoords = vertices[1].TCoords;
+                                       vertices[1].TCoords = vertices[2].TCoords;
+                                       vertices[2].TCoords = vertices[3].TCoords;
+                                       vertices[3].TCoords = t;
+                               }
+                               // +X
+                               if(dx >= abs(dz))
+                               {
+                                       v2f t = vertices[0].TCoords;
+                                       vertices[0].TCoords = vertices[3].TCoords;
+                                       vertices[3].TCoords = vertices[2].TCoords;
+                                       vertices[2].TCoords = vertices[1].TCoords;
+                                       vertices[1].TCoords = t;
+                               }
+                               // -Z
+                               if(-dz >= abs(dx))
+                               {
+                                       v2f t = vertices[0].TCoords;
+                                       vertices[0].TCoords = vertices[3].TCoords;
+                                       vertices[3].TCoords = vertices[2].TCoords;
+                                       vertices[2].TCoords = vertices[1].TCoords;
+                                       vertices[1].TCoords = t;
+                                       t = vertices[0].TCoords;
+                                       vertices[0].TCoords = vertices[3].TCoords;
+                                       vertices[3].TCoords = vertices[2].TCoords;
+                                       vertices[2].TCoords = vertices[1].TCoords;
+                                       vertices[1].TCoords = t;
+                               }
 
                                u16 indices[] = {0,1,2,2,3,0};
                                // Add to mesh collector
@@ -868,7 +919,6 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
                        if(n_plus_z_plus_y.getContent() == thiscontent)
                                is_rail_z_plus_y[1] = true;
 
-
                        bool is_rail_x_all[] = {false, false};
                        bool is_rail_z_all[] = {false, false};
                        is_rail_x_all[0]=is_rail_x[0] || is_rail_x_minus_y[0] || is_rail_x_plus_y[0];
@@ -876,30 +926,69 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
                        is_rail_z_all[0]=is_rail_z[0] || is_rail_z_minus_y[0] || is_rail_z_plus_y[0];
                        is_rail_z_all[1]=is_rail_z[1] || is_rail_z_minus_y[1] || is_rail_z_plus_y[1];
 
-                       bool is_straight = (is_rail_x_all[0] && is_rail_x_all[1]) || (is_rail_z_all[0] && is_rail_z_all[1]);//is really straight, rails on both sides
-                       int adjacencies = is_rail_x_all[0] + is_rail_x_all[1] + is_rail_z_all[0] + is_rail_z_all[1];
+                       // reasonable default, flat straight unrotated rail
+                       bool is_straight = true;
+                       int adjacencies = 0;
+                       int angle = 0;
+                       u8 tileindex = 0;
 
-                       if (is_rail_x_plus_y[0] || is_rail_x_plus_y[1] || is_rail_z_plus_y[0] || is_rail_z_plus_y[1]) //is straight because sloped
+                       // check for sloped rail
+                       if (is_rail_x_plus_y[0] || is_rail_x_plus_y[1] || is_rail_z_plus_y[0] || is_rail_z_plus_y[1])
                        {
                                adjacencies = 5; //5 means sloped
-                               is_straight = true;
+                               is_straight = true; // sloped is always straight
                        }
-
-                       // Assign textures
-                       u8 tileindex = 0; // straight
-                       if(adjacencies < 2)
-                               tileindex = 0; // straight
-                       else if(adjacencies == 2)
+                       else
                        {
-                               if(is_straight)
-                                       tileindex = 0; // straight
-                               else
-                                       tileindex = 1; // curved
+                               // is really straight, rails on both sides
+                               is_straight = (is_rail_x_all[0] && is_rail_x_all[1]) || (is_rail_z_all[0] && is_rail_z_all[1]);
+                               adjacencies = is_rail_x_all[0] + is_rail_x_all[1] + is_rail_z_all[0] + is_rail_z_all[1];
                        }
-                       else if(adjacencies == 3)
+
+                       switch (adjacencies) {
+                       case 1:
+                               if(is_rail_x_all[0] || is_rail_x_all[1])
+                                       angle = 90;
+                               break;
+                       case 2:
+                               if(!is_straight)
+                                       tileindex = 1; // curved
+                               if(is_rail_x_all[0] && is_rail_x_all[1])
+                                       angle = 90;
+                               if(is_rail_z_all[0] && is_rail_z_all[1]){
+                                       if (n_minus_z_plus_y.getContent() == thiscontent) angle = 180;
+                               }
+                               else if(is_rail_x_all[0] && is_rail_z_all[0])
+                                       angle = 270;
+                               else if(is_rail_x_all[0] && is_rail_z_all[1])
+                                       angle = 180;
+                               else if(is_rail_x_all[1] && is_rail_z_all[1])
+                                       angle = 90;
+                               break;
+                       case 3:
+                               // here is where the potential to 'switch' a junction is, but not implemented at present
                                tileindex = 2; // t-junction
-                       else if(adjacencies == 4)
+                               if(!is_rail_x_all[1])
+                                       angle=180;
+                               if(!is_rail_z_all[0])
+                                       angle=90;
+                               if(!is_rail_z_all[1])
+                                       angle=270;
+                               break;
+                       case 4:
                                tileindex = 3; // crossing
+                               break;
+                       case 5: //sloped
+                               if(is_rail_z_plus_y[0])
+                                       angle = 180;
+                               if(is_rail_x_plus_y[0])
+                                       angle = 90;
+                               if(is_rail_x_plus_y[1])
+                                       angle = -90;
+                               break;
+                       default:
+                               break;
+                       }
 
                        TileSpec tile = getNodeTileN(n, p, tileindex, data);
                        tile.material_flags &= ~MATERIAL_FLAG_BACKFACE_CULLING;
@@ -928,66 +1017,72 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
                                                        ap.x0(), ap.y0()),
                        };
 
-
-                       // Rotate textures
-                       int angle = 0;
-
-                       if(adjacencies == 1)
-                       {
-                               if(is_rail_x_all[0] || is_rail_x_all[1])
-                                       angle = 90;
-                       }
-                       if(adjacencies == 2)
-                       {
-                               if(is_rail_x_all[0] && is_rail_x_all[1])
-                               {
-                                       angle = 90;
-                               }
-                               if(is_rail_z_all[0] && is_rail_z_all[1])
-                               {
-                                       if (n_minus_z_plus_y.getContent() == thiscontent) angle = 180;
-                               }
-                               else if(is_rail_x_all[0] && is_rail_z_all[0])
-                                       angle = 270;
-                               else if(is_rail_x_all[0] && is_rail_z_all[1])
-                                       angle = 180;
-                               else if(is_rail_x_all[1] && is_rail_z_all[1])
-                                       angle = 90;
-                       }
-                       if(adjacencies == 3)
+                       for(s32 i=0; i<4; i++)
                        {
-                               if(!is_rail_x_all[0])
-                                       angle=0;
-                               if(!is_rail_x_all[1])
-                                       angle=180;
-                               if(!is_rail_z_all[0])
-                                       angle=90;
-                               if(!is_rail_z_all[1])
-                                       angle=270;
+                               if(angle != 0)
+                                       vertices[i].Pos.rotateXZBy(angle);
+                               vertices[i].Pos += intToFloat(p, BS);
                        }
-                       //adjacencies 4: Crossing
-                       if(adjacencies == 5) //sloped
+
+                       u16 indices[] = {0,1,2,2,3,0};
+                       collector.append(tile, vertices, 4, indices, 6);
+               break;}
+               case NDT_NODEBOX:
+               {
+                       static const v3s16 tile_dirs[6] = {
+                               v3s16(0, 1, 0),
+                               v3s16(0, -1, 0),
+                               v3s16(1, 0, 0),
+                               v3s16(-1, 0, 0),
+                               v3s16(0, 0, 1),
+                               v3s16(0, 0, -1)
+                       };
+
+                       TileSpec tiles[6];
+                       for(int i = 0; i < 6; i++)
                        {
-                               if(is_rail_z_plus_y[0])
-                                       angle = 180;
-                               if(is_rail_x_plus_y[0])
-                                       angle = 90;
-                               if(is_rail_x_plus_y[1])
-                                       angle = -90;
+                               // Handles facedir rotation for textures
+                               tiles[i] = getNodeTile(n, p, tile_dirs[i], data);
                        }
 
-                       if(angle != 0) {
-                               for(u16 i=0; i<4; i++)
-                                       vertices[i].Pos.rotateXZBy(angle);
-                       }
+                       u16 l = getInteriorLight(n, 0, data);
+                       video::SColor c = MapBlock_LightColor(255, l);
 
-                       for(s32 i=0; i<4; i++)
+                       v3f pos = intToFloat(p, BS);
+
+                       std::vector<aabb3f> boxes = n.getNodeBoxes(nodedef);
+                       for(std::vector<aabb3f>::iterator
+                                       i = boxes.begin();
+                                       i != boxes.end(); i++)
                        {
-                               vertices[i].Pos += intToFloat(p, BS);
-                       }
+                               aabb3f box = *i;
+                               box.MinEdge += pos;
+                               box.MaxEdge += pos;
+
+                               // Compute texture coords
+                               f32 tx1 = (i->MinEdge.X/BS)+0.5;
+                               f32 ty1 = (i->MinEdge.Y/BS)+0.5;
+                               f32 tz1 = (i->MinEdge.Z/BS)+0.5;
+                               f32 tx2 = (i->MaxEdge.X/BS)+0.5;
+                               f32 ty2 = (i->MaxEdge.Y/BS)+0.5;
+                               f32 tz2 = (i->MaxEdge.Z/BS)+0.5;
+                               f32 txc[24] = {
+                                       // up
+                                       tx1, 1-tz2, tx2, 1-tz1,
+                                       // down
+                                       tx1, tz1, tx2, tz2,
+                                       // right
+                                       tz1, 1-ty2, tz2, 1-ty1,
+                                       // left
+                                       1-tz2, 1-ty2, 1-tz1, 1-ty1,
+                                       // back
+                                       1-tx2, 1-ty2, 1-tx1, 1-ty1,
+                                       // front
+                                       tx1, 1-ty2, tx2, 1-ty1,
+                               };
 
-                       u16 indices[] = {0,1,2,2,3,0};
-                       collector.append(tile, vertices, 4, indices, 6);
+                               makeCuboid(&collector, box, tiles, 6, c, txc);
+                       }
                break;}
                }
        }