X-Git-Url: https://git.artsoft.org/?p=rocksndiamonds.git;a=blobdiff_plain;f=src%2Fgame.c;h=4c9c56e8f81825e57bebbd3e92dd0f3bb6c3adaa;hp=ca13127d2e7a5866aef72e02591ed0b87daa459a;hb=39fb4fecfb8d4647d3563bdb18ce0065f6129522;hpb=e2260726590fbcffca87320d7443153f0cdbdfe9 diff --git a/src/game.c b/src/game.c index ca13127d..4c9c56e8 100644 --- a/src/game.c +++ b/src/game.c @@ -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); @@ -2223,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; @@ -3335,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(); @@ -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,6 @@ void GameWon() void GameEnd() { int hi_pos; - boolean raise_level = FALSE; local_player->LevelSolved_GameEnd = TRUE; @@ -4692,31 +4701,38 @@ void GameEnd() } if (setup.increment_levels && - level_nr < leveldir_current->last_level) - raise_level = TRUE; /* advance to next level */ - - if ((hi_pos = NewHiScore(level_nr)) >= 0) + level_nr < leveldir_current->last_level && + !network_playing) { - SetGameStatus(GAME_MODE_SCORES); - - DrawHallOfFame(level_nr, 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(); } } + + /* 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(levelset.level_nr, hi_pos); + } + else if (setup.auto_play_next_level && setup.increment_levels && + !network_playing) + { + StartGameActions(network.enabled, setup.autorecord, level.random_seed); + } else { SetGameStatus(GAME_MODE_MAIN); - if (raise_level) - { - level_nr++; - TapeErase(); - } - DrawMainMenu(); } } @@ -9771,7 +9787,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; } @@ -11210,6 +11229,7 @@ void StartGameActions(boolean init_network_game, boolean record_tape, if (init_network_game) { + SendToServer_LevelFile(); SendToServer_StartPlaying(); return; @@ -12637,12 +12657,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 +13418,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 +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); @@ -14564,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)