Bug 100: Flip slopes properly.
[supertux.git] / src / supertux / sector.cpp
index 76ebf06..e0ebde1 100644 (file)
@@ -902,19 +902,19 @@ void check_collisions(collision::Constraints* constraints,
 
   if(fabsf(movement.y) > fabsf(movement.x)) {
     if(ileft < SHIFT_DELTA) {
-      constraints->right = std::min(constraints->right, r2.get_left());
+      constraints->min_right(r2.get_left());
       return;
     } else if(iright < SHIFT_DELTA) {
-      constraints->left = std::max(constraints->left, r2.get_right());
+      constraints->max_left(r2.get_right());
       return;
     }
   } else {
     // shiftout bottom/top
     if(itop < SHIFT_DELTA) {
-      constraints->bottom = std::min(constraints->bottom, r2.get_top());
+      constraints->min_bottom(r2.get_top());
       return;
     } else if(ibottom < SHIFT_DELTA) {
-      constraints->top = std::max(constraints->top, r2.get_bottom());
+      constraints->max_top(r2.get_bottom());
       return;
     }
   }
@@ -935,18 +935,18 @@ void check_collisions(collision::Constraints* constraints,
   float horiz_penetration = std::min(ileft, iright);
   if(vert_penetration < horiz_penetration) {
     if(itop < ibottom) {
-      constraints->bottom = std::min(constraints->bottom, r2.get_top());
+      constraints->min_bottom(r2.get_top());
       constraints->hit.bottom = true;
     } else {
-      constraints->top = std::max(constraints->top, r2.get_bottom());
+      constraints->max_top(r2.get_bottom());
       constraints->hit.top = true;
     }
   } else {
     if(ileft < iright) {
-      constraints->right = std::min(constraints->right, r2.get_left());
+      constraints->min_right(r2.get_left());
       constraints->hit.right = true;
     } else {
-      constraints->left = std::max(constraints->left, r2.get_right());
+      constraints->max_left(r2.get_right());
       constraints->hit.left = true;
     }
   }
@@ -990,7 +990,10 @@ Sector::collision_tilemap(collision::Constraints* constraints,
           AATriangle triangle;
           Vector p1(x*32 + solids->get_x_offset(), y*32 + solids->get_y_offset());
           Vector p2((x+1)*32 + solids->get_x_offset(), (y+1)*32 + solids->get_y_offset());
-          triangle = AATriangle(p1, p2, tile->getData());
+          int slope_data = tile->getData();
+          if (solids->get_drawing_effect() == VERTICAL_FLIP)
+            slope_data = AATriangle::vertical_flip(slope_data);
+          triangle = AATriangle(p1, p2, slope_data);
 
           collision::rectangle_aatriangle(constraints, dest, triangle, solids->get_movement());
         } else { // normal rectangular tile
@@ -1008,7 +1011,7 @@ Sector::collision_tile_attributes(const Rectf& dest) const
   float x1 = dest.p1.x;
   float y1 = dest.p1.y;
   float x2 = dest.p2.x;
-  float y2 = dest.p2.y + SHIFT_DELTA;
+  float y2 = dest.p2.y;
 
   uint32_t result = 0;
   for(std::list<TileMap*>::const_iterator i = solid_tilemaps.begin(); i != solid_tilemaps.end(); i++) {
@@ -1019,14 +1022,22 @@ Sector::collision_tile_attributes(const Rectf& dest) const
     int starttiley = int(y1 - solids->get_y_offset()) / 32;
     int max_x = int(x2 - solids->get_x_offset());
     int max_y = int(y2+1 - solids->get_y_offset());
+    int max_y_ice = int(max_y + SHIFT_DELTA);
 
     for(int x = starttilex; x*32 < max_x; ++x) {
-      for(int y = starttiley; y*32 < max_y; ++y) {
+      int y;
+      for(y = starttiley; y*32 < max_y; ++y) {
         const Tile* tile = solids->get_tile(x, y);
         if(!tile)
           continue;
         result |= tile->getAttributes();
       }
+      for(; y*32 < max_y_ice; ++y) {
+        const Tile* tile = solids->get_tile(x, y);
+        if(!tile)
+          continue;
+        result |= (tile->getAttributes() & Tile::ICE);
+      }
     }
   }
 
@@ -1176,8 +1187,8 @@ Sector::collision_static_constrains(MovingObject& object)
       break;
 
     // apply calculated vertical constraints
-    if(constraints.right < infinity) {
-      float width = constraints.right - constraints.left;
+    float width = constraints.right - constraints.left;
+    if(width < infinity) {
       if(width + SHIFT_DELTA < owidth) {
 #if 0
         printf("Object %p crushed horizontally... L:%f R:%f\n", &object,
@@ -1189,9 +1200,13 @@ Sector::collision_static_constrains(MovingObject& object)
         h.crush = true;
         object.collision_solid(h);
       } else {
-        dest.p2.x = constraints.right - DELTA;
-        dest.p1.x = dest.p2.x - owidth;
+        float xmid = (constraints.left + constraints.right) / 2;
+        dest.p1.x = xmid - owidth/2;
+        dest.p2.x = xmid + owidth/2;
       }
+    } else if(constraints.right < infinity) {
+      dest.p2.x = constraints.right - DELTA;
+      dest.p1.x = dest.p2.x - owidth;
     } else if(constraints.left > -infinity) {
       dest.p1.x = constraints.left + DELTA;
       dest.p2.x = dest.p1.x + owidth;
@@ -1272,7 +1287,7 @@ Sector::handle_collisions()
       continue;
 
     uint32_t tile_attributes = collision_tile_attributes(moving_object->dest);
-    if(tile_attributes > Tile::FIRST_INTERESTING_FLAG) {
+    if(tile_attributes >= Tile::FIRST_INTERESTING_FLAG) {
       moving_object->collision_tile(tile_attributes);
     }
   }