fixed bug with not recognizing ".mode_loop: false" for music
[rocksndiamonds.git] / src / game.c
index c51b7ece8e596108139c1ebc94670c66497faa6a..4c9c56e8f81825e57bebbd3e92dd0f3bb6c3adaa 100644 (file)
@@ -1112,7 +1112,7 @@ void TestIfGoodThingGetsHitByBadThing(int, int, int);
 void KillPlayer(struct PlayerInfo *);
 void BuryPlayer(struct PlayerInfo *);
 void RemovePlayer(struct PlayerInfo *);
-void RemovePlayerWithCleanup(struct PlayerInfo *);
+void ExitPlayer(struct PlayerInfo *);
 
 static int getInvisibleActiveFromInvisibleElement(int);
 static int getInvisibleFromInvisibleActiveElement(int);
@@ -2224,7 +2224,8 @@ void UpdateGameControlValues()
 
   /* update game panel control values */
 
-  game_panel_controls[GAME_PANEL_LEVEL_NUMBER].value = level_nr;
+  /* used instead of "level_nr" (for network games) */
+  game_panel_controls[GAME_PANEL_LEVEL_NUMBER].value = levelset.level_nr;
   game_panel_controls[GAME_PANEL_GEMS].value = gems;
 
   game_panel_controls[GAME_PANEL_INVENTORY_COUNT].value = 0;
@@ -3336,8 +3337,7 @@ void InitGame()
 
   ExpireSoundLoops(TRUE);
 
-  if (!level_editor_test_game)
-    FadeOut(fade_mask);
+  FadeOut(fade_mask);
 
   /* needed if different viewport properties defined for playing */
   ChangeViewportPropertiesIfNeeded();
@@ -3392,6 +3392,7 @@ void InitGame()
     player->gems_still_needed = level.gems_needed;
     player->sokobanfields_still_needed = 0;
     player->lights_still_needed = 0;
+    player->players_still_needed = 0;
     player->friends_still_needed = 0;
 
     for (j = 0; j < MAX_NUM_KEYS; j++)
@@ -3949,6 +3950,10 @@ void InitGame()
     }
   }
 
+  for (i = 0; i < MAX_PLAYERS; i++)
+    if (stored_player[i].active)
+      local_player->players_still_needed++;
+
   /* when recording the game, store which players take part in the game */
   if (tape.recording)
   {
@@ -4417,6 +4422,10 @@ void InitAmoebaNr(int x, int y)
 
 static void PlayerWins(struct PlayerInfo *player)
 {
+  if (level.game_engine_type == GAME_ENGINE_TYPE_RND &&
+      local_player->players_still_needed > 0)
+    return;
+
   player->LevelSolved = TRUE;
   player->GameOver = TRUE;
 
@@ -4651,7 +4660,6 @@ void GameWon()
 void GameEnd()
 {
   int hi_pos;
-  int last_level_nr = level_nr;
 
   local_player->LevelSolved_GameEnd = TRUE;
 
@@ -4693,7 +4701,8 @@ void GameEnd()
   }
 
   if (setup.increment_levels &&
-      level_nr < leveldir_current->last_level)
+      level_nr < leveldir_current->last_level &&
+      !network_playing)
   {
     level_nr++;                /* advance to next level */
     TapeErase();       /* start with empty tape */
@@ -4706,23 +4715,25 @@ void GameEnd()
     }
   }
 
-  hi_pos = NewHiScore(last_level_nr);
+  /* used instead of last "level_nr" (for network games) */
+  hi_pos = NewHiScore(levelset.level_nr);
 
   if (hi_pos >= 0 && !setup.skip_scores_after_game)
   {
     SetGameStatus(GAME_MODE_SCORES);
 
-    DrawHallOfFame(last_level_nr, hi_pos);
+    DrawHallOfFame(levelset.level_nr, hi_pos);
   }
-  else if (!setup.auto_play_next_level || !setup.increment_levels)
+  else if (setup.auto_play_next_level && setup.increment_levels &&
+          !network_playing)
   {
-    SetGameStatus(GAME_MODE_MAIN);
-
-    DrawMainMenu();
+    StartGameActions(network.enabled, setup.autorecord, level.random_seed);
   }
   else
   {
-    StartGameActions(network.enabled, setup.autorecord, level.random_seed);
+    SetGameStatus(GAME_MODE_MAIN);
+
+    DrawMainMenu();
   }
 }
 
@@ -9776,7 +9787,7 @@ static void ExecuteCustomElementAction(int x, int y, int element, int page)
     {
       for (i = 0; i < MAX_PLAYERS; i++)
        if (action_arg_player_bits & (1 << i))
-         RemovePlayerWithCleanup(&stored_player[i]);
+         ExitPlayer(&stored_player[i]);
 
       if (AllPlayersGone)
        PlayerWins(local_player);
@@ -11218,6 +11229,7 @@ void StartGameActions(boolean init_network_game, boolean record_tape,
 
   if (init_network_game)
   {
+    SendToServer_LevelFile();
     SendToServer_StartPlaying();
 
     return;
@@ -12645,7 +12657,7 @@ void ScrollPlayer(struct PlayerInfo *player, int mode)
        Feld[jx][jy] == EL_SP_EXIT_OPEN ||
        Feld[jx][jy] == EL_SP_EXIT_OPENING)     /* <-- special case */
     {
-      RemovePlayerWithCleanup(player);
+      ExitPlayer(player);
 
       if ((local_player->friends_still_needed == 0 ||
           IS_SP_ELEMENT(Feld[jx][jy])) &&
@@ -13406,10 +13418,12 @@ void RemovePlayer(struct PlayerInfo *player)
   ExitY = ZY = jy;
 }
 
-void RemovePlayerWithCleanup(struct PlayerInfo *player)
+void ExitPlayer(struct PlayerInfo *player)
 {
   DrawPlayer(player);  /* needed here only to cleanup last field */
   RemovePlayer(player);
+
+  local_player->players_still_needed--;
 }
 
 static void setFieldForSnapping(int x, int y, int element, int direction)
@@ -13957,6 +13971,8 @@ static int DigField(struct PlayerInfo *player,
       if (local_player->sokobanfields_still_needed == 0 &&
          (game.emulation == EMU_SOKOBAN || level.auto_exit_sokoban))
       {
+       local_player->players_still_needed = 0;
+
        PlayerWins(player);
 
        PlayLevelSound(x, y, SND_GAME_SOKOBAN_SOLVING);
@@ -14578,7 +14594,7 @@ static void PlayLevelMusic()
   char *next_music = getMusicInfoEntryFilename(music_nr);
 
   if (!strEqual(curr_music, next_music))
-    PlayMusic(music_nr);
+    PlayMusicLoop(music_nr);
 }
 
 void PlayLevelSound_EM(int xx, int yy, int element_em, int sample)