X-Git-Url: https://git.artsoft.org/?p=rocksndiamonds.git;a=blobdiff_plain;f=src%2Fgame.c;h=e1522b58bb844136786b4113ee247df34506cfdb;hp=c6d3a862b4a10a46de412b3059e5a3cb4e848b5f;hb=6999c82df7c989eb8b2a7cc98f0f1e108df34910;hpb=389d6f45817495cee6f667742756ddf96df1ba2d diff --git a/src/game.c b/src/game.c index c6d3a862..e1522b58 100644 --- a/src/game.c +++ b/src/game.c @@ -1096,7 +1096,7 @@ void ContinueMoving(int, int); void Bang(int, int); void InitMovDir(int, int); void InitAmoebaNr(int, int); -int NewHiScore(void); +int NewHiScore(int); void TestIfGoodThingHitsBadThing(int, int, int); void TestIfBadThingHitsGoodThing(int, int, int); @@ -1112,6 +1112,7 @@ void TestIfGoodThingGetsHitByBadThing(int, int, int); void KillPlayer(struct PlayerInfo *); void BuryPlayer(struct PlayerInfo *); void RemovePlayer(struct PlayerInfo *); +void ExitPlayer(struct PlayerInfo *); static int getInvisibleActiveFromInvisibleElement(int); static int getInvisibleFromInvisibleActiveElement(int); @@ -3391,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++) @@ -3948,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) { @@ -4416,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; @@ -4650,7 +4660,7 @@ void GameWon() void GameEnd() { int hi_pos; - boolean raise_level = FALSE; + int last_level_nr = level_nr; local_player->LevelSolved_GameEnd = TRUE; @@ -4693,35 +4703,39 @@ void GameEnd() if (setup.increment_levels && level_nr < leveldir_current->last_level) - raise_level = TRUE; /* advance to next level */ - - if ((hi_pos = NewHiScore()) >= 0) { - SetGameStatus(GAME_MODE_SCORES); - - DrawHallOfFame(hi_pos); + level_nr++; /* advance to next level */ + TapeErase(); /* start with empty tape */ - if (raise_level) + if (setup.auto_play_next_level) { - level_nr++; - TapeErase(); + LoadLevel(level_nr); + + SaveLevelSetup_SeriesInfo(); } } - else + + hi_pos = NewHiScore(last_level_nr); + + if (hi_pos >= 0 && !setup.skip_scores_after_game) { - SetGameStatus(GAME_MODE_MAIN); + SetGameStatus(GAME_MODE_SCORES); - if (raise_level) - { - level_nr++; - TapeErase(); - } + DrawHallOfFame(last_level_nr, hi_pos); + } + else if (!setup.auto_play_next_level || !setup.increment_levels) + { + SetGameStatus(GAME_MODE_MAIN); DrawMainMenu(); } + else + { + StartGameActions(network.enabled, setup.autorecord, level.random_seed); + } } -int NewHiScore() +int NewHiScore(int level_nr) { int k, l; int position = -1; @@ -9771,7 +9785,10 @@ 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)) - PlayerWins(&stored_player[i]); + ExitPlayer(&stored_player[i]); + + if (AllPlayersGone) + PlayerWins(local_player); break; } @@ -12637,12 +12654,12 @@ void ScrollPlayer(struct PlayerInfo *player, int mode) Feld[jx][jy] == EL_SP_EXIT_OPEN || Feld[jx][jy] == EL_SP_EXIT_OPENING) /* <-- special case */ { - DrawPlayer(player); /* needed here only to cleanup last field */ - RemovePlayer(player); + ExitPlayer(player); - if (local_player->friends_still_needed == 0 || - IS_SP_ELEMENT(Feld[jx][jy])) - PlayerWins(player); + if ((local_player->friends_still_needed == 0 || + IS_SP_ELEMENT(Feld[jx][jy])) && + AllPlayersGone) + PlayerWins(local_player); } /* this breaks one level: "machine", level 000 */ @@ -13398,6 +13415,14 @@ void RemovePlayer(struct PlayerInfo *player) ExitY = ZY = jy; } +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) { struct ElementInfo *ei = &element_info[element]; @@ -13943,6 +13968,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);