moved setting auto-exit for Sokoban-style levels from runtime to level
[rocksndiamonds.git] / src / game.c
index be192e4fecda551a84af7b27346773c0571ae37c..0dc37771206428ec53ab7a72d6bccf0ea9cee016 100644 (file)
@@ -3542,7 +3542,6 @@ void InitGame(void)
   int fade_mask = REDRAW_FIELD;
 
   boolean emulate_bd = TRUE;   // unless non-BOULDERDASH elements found
-  boolean emulate_sb = TRUE;   // unless non-SOKOBAN     elements found
   boolean emulate_sp = TRUE;   // unless non-SUPAPLEX    elements found
   int initial_move_dir = MV_DOWN;
   int i, j, x, y;
@@ -3886,8 +3885,6 @@ void InitGame(void)
   {
     if (emulate_bd && !IS_BD_ELEMENT(Tile[x][y]))
       emulate_bd = FALSE;
-    if (emulate_sb && !IS_SB_ELEMENT(Tile[x][y]))
-      emulate_sb = FALSE;
     if (emulate_sp && !IS_SP_ELEMENT(Tile[x][y]))
       emulate_sp = FALSE;
 
@@ -3912,7 +3909,6 @@ void InitGame(void)
   }
 
   game.emulation = (emulate_bd ? EMU_BOULDERDASH :
-                   emulate_sb ? EMU_SOKOBAN :
                    emulate_sp ? EMU_SUPAPLEX : EMU_NONE);
 
   // initialize type of slippery elements
@@ -4310,7 +4306,7 @@ void InitGame(void)
        {
          // check for player created from custom element as single target
          content = element_info[element].change_page[i].target_element;
-         is_player = ELEM_IS_PLAYER(content);
+         is_player = IS_PLAYER_ELEMENT(content);
 
          if (is_player && (found_rating < 3 ||
                            (found_rating == 3 && element < found_element)))
@@ -4328,7 +4324,7 @@ void InitGame(void)
       {
        // check for player created from custom element as explosion content
        content = element_info[element].content.e[xx][yy];
-       is_player = ELEM_IS_PLAYER(content);
+       is_player = IS_PLAYER_ELEMENT(content);
 
        if (is_player && (found_rating < 2 ||
                          (found_rating == 2 && element < found_element)))
@@ -4349,7 +4345,7 @@ void InitGame(void)
          content =
            element_info[element].change_page[i].target_content.e[xx][yy];
 
-         is_player = ELEM_IS_PLAYER(content);
+         is_player = IS_PLAYER_ELEMENT(content);
 
          if (is_player && (found_rating < 1 ||
                            (found_rating == 1 && element < found_element)))
@@ -5688,7 +5684,7 @@ static void RelocatePlayer(int jx, int jy, int el_player_raw)
      possible that the relocation target field did not contain a player element,
      but a walkable element, to which the new player was relocated -- in this
      case, restore that (already initialized!) element on the player field */
-  if (!ELEM_IS_PLAYER(element))        // player may be set on walkable element
+  if (!IS_PLAYER_ELEMENT(element))     // player may be set on walkable element
   {
     Tile[jx][jy] = element;    // restore previously existing element
   }
@@ -5858,7 +5854,7 @@ static void Explode(int ex, int ey, int phase, int mode)
 
       // !!! check this case -- currently needed for rnd_rado_negundo_v,
       // !!! levels 015 018 019 020 021 022 023 026 027 028 !!!
-      else if (ELEM_IS_PLAYER(center_element))
+      else if (IS_PLAYER_ELEMENT(center_element))
        Store[x][y] = EL_EMPTY;
       else if (center_element == EL_YAMYAM)
        Store[x][y] = level.yamyam_content[game.yamyam_content_nr].e[xx][yy];
@@ -5998,7 +5994,7 @@ static void Explode(int ex, int ey, int phase, int mode)
     if (IS_PLAYER(x, y) && !PLAYERINFO(x, y)->present)
       StorePlayer[x][y] = 0;
 
-    if (ELEM_IS_PLAYER(element))
+    if (IS_PLAYER_ELEMENT(element))
       RelocatePlayer(x, y, element);
   }
   else if (IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
@@ -8784,7 +8780,7 @@ void ContinueMoving(int x, int y)
     if (GFX_CRUMBLED(Tile[x][y]))
       TEST_DrawLevelFieldCrumbledNeighbours(x, y);
 
-    if (ELEM_IS_PLAYER(move_leave_element))
+    if (IS_PLAYER_ELEMENT(move_leave_element))
       RelocatePlayer(x, y, move_leave_element);
   }
 
@@ -10594,7 +10590,7 @@ static void CreateFieldExt(int x, int y, int element, boolean is_change)
   int previous_move_direction = MovDir[x][y];
   int last_ce_value = CustomValue[x][y];
   boolean player_explosion_protected = PLAYER_EXPLOSION_PROTECTED(x, y);
-  boolean new_element_is_player = ELEM_IS_PLAYER(new_element);
+  boolean new_element_is_player = IS_PLAYER_ELEMENT(new_element);
   boolean add_player_onto_element = (new_element_is_player &&
                                     new_element != EL_SOKOBAN_FIELD_PLAYER &&
                                     IS_WALKABLE(old_element));
@@ -10770,7 +10766,7 @@ static boolean ChangeElement(int x, int y, int element, int page)
          (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)));
+        !(IS_PLAYER(ex, ey) && IS_PLAYER_ELEMENT(content_element)));
 
       if (!can_replace[xx][yy])
        complete_replace = FALSE;
@@ -10832,6 +10828,10 @@ static boolean ChangeElement(int x, int y, int element, int page)
       Store[x][y] = EL_EMPTY;
     }
 
+    // special case: element changes to player (and may be kept if walkable)
+    if (IS_PLAYER_ELEMENT(target_element) && !level.keep_walkable_ce)
+      CreateElementFromChange(x, y, EL_EMPTY);
+
     CreateElementFromChange(x, y, target_element);
 
     PlayLevelSoundElementAction(x, y, element, ACTION_CHANGING);
@@ -14523,7 +14523,7 @@ static int DigField(struct PlayerInfo *player,
       if (sokoban_task_solved &&
          game.sokoban_fields_still_needed == 0 &&
          game.sokoban_objects_still_needed == 0 &&
-         (game.emulation == EMU_SOKOBAN || level.auto_exit_sokoban))
+         level.auto_exit_sokoban)
       {
        game.players_still_needed = 0;