rocksndiamonds-3.1.0
[rocksndiamonds.git] / src / game.c
index 13089ad43e1b2f21a018cef525fae6b8c47d893b..762035dc5656bc5479fc3158d263620b0675cb1c 100644 (file)
@@ -612,31 +612,39 @@ struct
 }
 access_direction_list[] =
 {
-  { EL_TUBE_ANY,               MV_LEFT | MV_RIGHT | MV_UP | MV_DOWN },
-  { EL_TUBE_VERTICAL,                               MV_UP | MV_DOWN },
-  { EL_TUBE_HORIZONTAL,                MV_LEFT | MV_RIGHT                   },
-  { EL_TUBE_VERTICAL_LEFT,     MV_LEFT |            MV_UP | MV_DOWN },
-  { EL_TUBE_VERTICAL_RIGHT,              MV_RIGHT | MV_UP | MV_DOWN },
-  { EL_TUBE_HORIZONTAL_UP,     MV_LEFT | MV_RIGHT | MV_UP           },
-  { EL_TUBE_HORIZONTAL_DOWN,   MV_LEFT | MV_RIGHT |         MV_DOWN },
-  { EL_TUBE_LEFT_UP,           MV_LEFT |            MV_UP           },
-  { EL_TUBE_LEFT_DOWN,         MV_LEFT |                    MV_DOWN },
-  { EL_TUBE_RIGHT_UP,                    MV_RIGHT | MV_UP           },
-  { EL_TUBE_RIGHT_DOWN,                          MV_RIGHT |         MV_DOWN },
-
-  { EL_SP_PORT_LEFT,                     MV_RIGHT                   },
-  { EL_SP_PORT_RIGHT,          MV_LEFT                              },
-  { EL_SP_PORT_UP,                                          MV_DOWN },
-  { EL_SP_PORT_DOWN,                                MV_UP           },
-  { EL_SP_PORT_HORIZONTAL,     MV_LEFT | MV_RIGHT                   },
-  { EL_SP_PORT_VERTICAL,                            MV_UP | MV_DOWN },
-  { EL_SP_PORT_ANY,            MV_LEFT | MV_RIGHT | MV_UP | MV_DOWN },
-  { EL_SP_GRAVITY_PORT_LEFT,             MV_RIGHT                   },
-  { EL_SP_GRAVITY_PORT_RIGHT,  MV_LEFT                              },
-  { EL_SP_GRAVITY_PORT_UP,                                  MV_DOWN },
-  { EL_SP_GRAVITY_PORT_DOWN,                        MV_UP           },
-
-  { EL_UNDEFINED,              MV_NO_MOVING                         }
+  { EL_TUBE_ANY,                       MV_LEFT | MV_RIGHT | MV_UP | MV_DOWN },
+  { EL_TUBE_VERTICAL,                                       MV_UP | MV_DOWN },
+  { EL_TUBE_HORIZONTAL,                        MV_LEFT | MV_RIGHT                   },
+  { EL_TUBE_VERTICAL_LEFT,             MV_LEFT |            MV_UP | MV_DOWN },
+  { EL_TUBE_VERTICAL_RIGHT,                      MV_RIGHT | MV_UP | MV_DOWN },
+  { EL_TUBE_HORIZONTAL_UP,             MV_LEFT | MV_RIGHT | MV_UP           },
+  { EL_TUBE_HORIZONTAL_DOWN,           MV_LEFT | MV_RIGHT |         MV_DOWN },
+  { EL_TUBE_LEFT_UP,                   MV_LEFT |            MV_UP           },
+  { EL_TUBE_LEFT_DOWN,                 MV_LEFT |                    MV_DOWN },
+  { EL_TUBE_RIGHT_UP,                            MV_RIGHT | MV_UP           },
+  { EL_TUBE_RIGHT_DOWN,                                  MV_RIGHT |         MV_DOWN },
+
+  { EL_SP_PORT_LEFT,                             MV_RIGHT                   },
+  { EL_SP_PORT_RIGHT,                  MV_LEFT                              },
+  { EL_SP_PORT_UP,                                                  MV_DOWN },
+  { EL_SP_PORT_DOWN,                                        MV_UP           },
+  { EL_SP_PORT_HORIZONTAL,             MV_LEFT | MV_RIGHT                   },
+  { EL_SP_PORT_VERTICAL,                                    MV_UP | MV_DOWN },
+  { EL_SP_PORT_ANY,                    MV_LEFT | MV_RIGHT | MV_UP | MV_DOWN },
+  { EL_SP_GRAVITY_PORT_LEFT,                     MV_RIGHT                   },
+  { EL_SP_GRAVITY_PORT_RIGHT,          MV_LEFT                              },
+  { EL_SP_GRAVITY_PORT_UP,                                          MV_DOWN },
+  { EL_SP_GRAVITY_PORT_DOWN,                                MV_UP           },
+  { EL_SP_GRAVITY_ON_PORT_LEFT,                          MV_RIGHT                   },
+  { EL_SP_GRAVITY_ON_PORT_RIGHT,       MV_LEFT                              },
+  { EL_SP_GRAVITY_ON_PORT_UP,                                       MV_DOWN },
+  { EL_SP_GRAVITY_ON_PORT_DOWN,                                     MV_UP           },
+  { EL_SP_GRAVITY_OFF_PORT_LEFT,                 MV_RIGHT                   },
+  { EL_SP_GRAVITY_OFF_PORT_RIGHT,      MV_LEFT                              },
+  { EL_SP_GRAVITY_OFF_PORT_UP,                                      MV_DOWN },
+  { EL_SP_GRAVITY_OFF_PORT_DOWN,                            MV_UP           },
+
+  { EL_UNDEFINED,                      MV_NO_MOVING                         }
 };
 
 static unsigned long trigger_events[MAX_NUM_ELEMENTS];
@@ -7433,6 +7441,11 @@ static void ChangeElementNowExt(int x, int y, int target_element)
   if (IS_PLAYER(x, y) && !PLAYER_EXPLOSION_PROTECTED(x, y) &&
       IS_ACCESSIBLE(Feld[x][y]) && !IS_ACCESSIBLE(target_element))
   {
+#if 0
+    printf("::: BOOOM! [%d, '%s']\n", target_element,
+          element_info[target_element].token_name);
+#endif
+
     Bang(x, y);
     return;
   }
@@ -7610,6 +7623,7 @@ static boolean ChangeElementNow(int x, int y, int element, int page)
 #endif
 
 #endif
+
       is_walkable     = (is_empty || IS_WALKABLE(e));
       is_diggable     = (is_empty || IS_DIGGABLE(e));
       is_collectible  = (is_empty || IS_COLLECTIBLE(e));
@@ -7617,12 +7631,13 @@ static boolean ChangeElementNow(int x, int y, int element, int page)
       is_removable    = (is_diggable || is_collectible);
 
       can_replace[xx][yy] =
-       ((change->replace_when == CP_WHEN_EMPTY        && is_empty) ||
-        (change->replace_when == CP_WHEN_WALKABLE     && is_walkable) ||
-        (change->replace_when == CP_WHEN_DIGGABLE     && is_diggable) ||
-        (change->replace_when == CP_WHEN_COLLECTIBLE  && is_collectible) ||
-        (change->replace_when == CP_WHEN_REMOVABLE    && is_removable) ||
-        (change->replace_when == CP_WHEN_DESTRUCTIBLE && is_destructible));
+       (((change->replace_when == CP_WHEN_EMPTY        && is_empty) ||
+         (change->replace_when == CP_WHEN_WALKABLE     && is_walkable) ||
+         (change->replace_when == CP_WHEN_DIGGABLE     && is_diggable) ||
+         (change->replace_when == CP_WHEN_COLLECTIBLE  && is_collectible) ||
+         (change->replace_when == CP_WHEN_REMOVABLE    && is_removable) ||
+         (change->replace_when == CP_WHEN_DESTRUCTIBLE && is_destructible)) &&
+        !(IS_PLAYER(ex, ey) && ELEM_IS_PLAYER(content_element)));
 
       if (!can_replace[xx][yy])
        complete_replace = FALSE;
@@ -10036,7 +10051,7 @@ void TestIfElementTouchesCustomElement(int x, int y)
   boolean change_center_element = FALSE;
   int center_element_change_page = 0;
   int center_element = Feld[x][y];     /* should always be non-moving! */
-  int border_trigger_element;
+  int border_trigger_element = EL_UNDEFINED;
   int i, j;
 
   for (i = 0; i < NUM_DIRECTIONS; i++)
@@ -11045,6 +11060,16 @@ int DigField(struct PlayerInfo *player,
              element == EL_SP_GRAVITY_PORT_UP ||
              element == EL_SP_GRAVITY_PORT_DOWN)
            game.gravity = !game.gravity;
+         else if (element == EL_SP_GRAVITY_ON_PORT_LEFT ||
+                  element == EL_SP_GRAVITY_ON_PORT_RIGHT ||
+                  element == EL_SP_GRAVITY_ON_PORT_UP ||
+                  element == EL_SP_GRAVITY_ON_PORT_DOWN)
+           game.gravity = TRUE;
+         else if (element == EL_SP_GRAVITY_OFF_PORT_LEFT ||
+                  element == EL_SP_GRAVITY_OFF_PORT_RIGHT ||
+                  element == EL_SP_GRAVITY_OFF_PORT_UP ||
+                  element == EL_SP_GRAVITY_OFF_PORT_DOWN)
+           game.gravity = FALSE;
        }
 
        /* automatically move to the next field with double speed */