X-Git-Url: https://git.artsoft.org/?p=rocksndiamonds.git;a=blobdiff_plain;f=src%2Fgame.c;h=2fb1b686c7ae07a5482a68cc21e459993164d4b1;hp=479fa0aefda2d2279e9e5e08790a0f1eba85d36a;hb=10406b9d6cad2b0ec7c30c71520abe2c702bccbc;hpb=ae55cab94c43d759ef6d9772e32322df930a760d diff --git a/src/game.c b/src/game.c index 479fa0ae..2fb1b686 100644 --- a/src/game.c +++ b/src/game.c @@ -1683,6 +1683,30 @@ int GetElementFromGroupElement(int element) return element; } +static void IncrementPlayerSokobanFieldsNeeded(struct PlayerInfo *player) +{ + if (level.sb_fields_needed) + player->sokoban_fields_still_needed++; +} + +static void IncrementPlayerSokobanObjectsNeeded(struct PlayerInfo *player) +{ + if (level.sb_objects_needed) + player->sokoban_objects_still_needed++; +} + +static void DecrementPlayerSokobanFieldsNeeded(struct PlayerInfo *player) +{ + if (player->sokoban_fields_still_needed > 0) + player->sokoban_fields_still_needed--; +} + +static void DecrementPlayerSokobanObjectsNeeded(struct PlayerInfo *player) +{ + if (player->sokoban_objects_still_needed > 0) + player->sokoban_objects_still_needed--; +} + static void InitPlayerField(int x, int y, int element, boolean init_game) { if (element == EL_SP_MURPHY) @@ -1792,7 +1816,11 @@ static void InitField(int x, int y, boolean init_game) break; case EL_SOKOBAN_FIELD_EMPTY: - local_player->sokobanfields_still_needed++; + IncrementPlayerSokobanFieldsNeeded(local_player); + break; + + case EL_SOKOBAN_OBJECT: + IncrementPlayerSokobanObjectsNeeded(local_player); break; case EL_STONEBLOCK: @@ -2212,7 +2240,8 @@ static void UpdateGameControlValues(void) game_mm.kettles_still_needed > 0 || game_mm.lights_still_needed > 0 : local_player->gems_still_needed > 0 || - local_player->sokobanfields_still_needed > 0 || + local_player->sokoban_fields_still_needed > 0 || + local_player->sokoban_objects_still_needed > 0 || local_player->lights_still_needed > 0); int health = (local_player->LevelSolved ? local_player->LevelSolved_CountingHealth : @@ -2381,9 +2410,9 @@ static void UpdateGameControlValues(void) local_player->friends_still_needed; game_panel_controls[GAME_PANEL_SOKOBAN_OBJECTS].value = - local_player->sokobanfields_still_needed; + local_player->sokoban_objects_still_needed; game_panel_controls[GAME_PANEL_SOKOBAN_FIELDS].value = - local_player->sokobanfields_still_needed; + local_player->sokoban_fields_still_needed; game_panel_controls[GAME_PANEL_ROBOT_WHEEL].value = (game.robot_wheel_active ? EL_ROBOT_WHEEL_ACTIVE : EL_ROBOT_WHEEL); @@ -3389,7 +3418,8 @@ void InitGame(void) player->health_final = MAX_HEALTH; player->gems_still_needed = level.gems_needed; - player->sokobanfields_still_needed = 0; + player->sokoban_fields_still_needed = 0; + player->sokoban_objects_still_needed = 0; player->lights_still_needed = 0; player->players_still_needed = 0; player->friends_still_needed = 0; @@ -9053,7 +9083,8 @@ static void ActivateMagicBall(int bx, int by) static void CheckExit(int x, int y) { if (local_player->gems_still_needed > 0 || - local_player->sokobanfields_still_needed > 0 || + local_player->sokoban_fields_still_needed > 0 || + local_player->sokoban_objects_still_needed > 0 || local_player->lights_still_needed > 0) { int element = Feld[x][y]; @@ -9076,7 +9107,8 @@ static void CheckExit(int x, int y) static void CheckExitEM(int x, int y) { if (local_player->gems_still_needed > 0 || - local_player->sokobanfields_still_needed > 0 || + local_player->sokoban_fields_still_needed > 0 || + local_player->sokoban_objects_still_needed > 0 || local_player->lights_still_needed > 0) { int element = Feld[x][y]; @@ -9099,7 +9131,8 @@ static void CheckExitEM(int x, int y) static void CheckExitSteel(int x, int y) { if (local_player->gems_still_needed > 0 || - local_player->sokobanfields_still_needed > 0 || + local_player->sokoban_fields_still_needed > 0 || + local_player->sokoban_objects_still_needed > 0 || local_player->lights_still_needed > 0) { int element = Feld[x][y]; @@ -9122,7 +9155,8 @@ static void CheckExitSteel(int x, int y) static void CheckExitSteelEM(int x, int y) { if (local_player->gems_still_needed > 0 || - local_player->sokobanfields_still_needed > 0 || + local_player->sokoban_fields_still_needed > 0 || + local_player->sokoban_objects_still_needed > 0 || local_player->lights_still_needed > 0) { int element = Feld[x][y]; @@ -13933,16 +13967,26 @@ static int DigField(struct PlayerInfo *player, if (IS_SB_ELEMENT(element)) { + boolean sokoban_task_solved = FALSE; + if (element == EL_SOKOBAN_FIELD_FULL) { Back[x][y] = EL_SOKOBAN_FIELD_EMPTY; - local_player->sokobanfields_still_needed++; + + IncrementPlayerSokobanFieldsNeeded(local_player); + IncrementPlayerSokobanObjectsNeeded(local_player); } if (Feld[nextx][nexty] == EL_SOKOBAN_FIELD_EMPTY) { Back[nextx][nexty] = EL_SOKOBAN_FIELD_EMPTY; - local_player->sokobanfields_still_needed--; + + DecrementPlayerSokobanFieldsNeeded(local_player); + DecrementPlayerSokobanObjectsNeeded(local_player); + + // sokoban object was pushed from empty field to sokoban field + if (Back[x][y] == EL_EMPTY) + sokoban_task_solved = TRUE; } Feld[x][y] = EL_SOKOBAN_OBJECT; @@ -13956,7 +14000,9 @@ static int DigField(struct PlayerInfo *player, PlayLevelSoundElementAction(nextx, nexty, EL_SOKOBAN_FIELD_EMPTY, ACTION_FILLING); - if (local_player->sokobanfields_still_needed == 0 && + if (sokoban_task_solved && + local_player->sokoban_fields_still_needed == 0 && + local_player->sokoban_objects_still_needed == 0 && (game.emulation == EMU_SOKOBAN || level.auto_exit_sokoban)) { local_player->players_still_needed = 0;