X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Fgame.c;h=54ae41a2fe154713af63ac92fde530b6895d8a62;hb=24101bdeee0ac963cfd48b5220f6d9b0188a6f69;hp=ac37d91eb997b8f8f9097c144c23d8a00fdc817b;hpb=64d0700c316f0c9dee9730c93ad2b13785b3dad4;p=rocksndiamonds.git diff --git a/src/game.c b/src/game.c index ac37d91e..54ae41a2 100644 --- a/src/game.c +++ b/src/game.c @@ -44,6 +44,8 @@ #define USE_GFX_RESET_GFX_ANIMATION (USE_NEW_STUFF * 1) #define USE_BOTH_SWITCHGATE_SWITCHES (USE_NEW_STUFF * 1) #define USE_PLAYER_GRAVITY (USE_NEW_STUFF * 1) +#define USE_FIXED_BORDER_RUNNING_GFX (USE_NEW_STUFF * 1) +#define USE_QUICKSAND_BD_ROCK_BUGFIX (USE_NEW_STUFF * 0) #define USE_QUICKSAND_IMPACT_BUGFIX (USE_NEW_STUFF * 0) @@ -1993,6 +1995,8 @@ void InitGame() player->last_move_dir = MV_NONE; + player->is_active = FALSE; + player->is_waiting = FALSE; player->is_moving = FALSE; player->is_auto_moving = FALSE; @@ -5858,7 +5862,12 @@ void StartMoving(int x, int y) started_moving = TRUE; Feld[x][y] = EL_QUICKSAND_EMPTYING; +#if USE_QUICKSAND_BD_ROCK_BUGFIX + if (Store[x][y] != EL_ROCK && Store[x][y] != EL_BD_ROCK) + Store[x][y] = EL_ROCK; +#else Store[x][y] = EL_ROCK; +#endif PlayLevelSoundAction(x, y, ACTION_EMPTYING); } @@ -7801,7 +7810,8 @@ void MauerAbleger(int ax, int ay) if (element == EL_EXPANDABLE_WALL_HORIZONTAL || element == EL_EXPANDABLE_WALL_ANY || - element == EL_EXPANDABLE_WALL) + element == EL_EXPANDABLE_WALL || + element == EL_BD_EXPANDABLE_WALL) { if (links_frei) { @@ -8410,6 +8420,8 @@ static void ExecuteCustomElementAction(int x, int y, int element, int page) if (ei->collect_score == 0) { + int xx, yy; + #if 0 printf("::: CE_SCORE_GETS_ZERO\n"); #endif @@ -8420,6 +8432,26 @@ static void ExecuteCustomElementAction(int x, int y, int element, int page) #if 0 printf("::: RESULT: %d, %d\n", Feld[x][y], ChangePage[x][y]); #endif + +#if 1 + /* + This is a very special case that seems to be a mixture between + CheckElementChange() and CheckTriggeredElementChange(): while + the first one only affects single elements that are triggered + directly, the second one affects multiple elements in the playfield + that are triggered indirectly by another element. This is a third + case: Changing the CE score always affects multiple identical CEs, + so every affected CE must be checked, not only the single CE for + which the CE score was changed in the first place (as every instance + of that CE shares the same CE score, and therefore also can change)! + */ + SCAN_PLAYFIELD(xx, yy) + { + if (Feld[xx][yy] == element) + CheckElementChange(xx, yy, element, EL_UNDEFINED, + CE_SCORE_GETS_ZERO); + } +#endif } } @@ -9641,6 +9673,10 @@ void GameActions_EM_Main() for (i = 0; i < MAX_PLAYERS; i++) effective_action[i] = stored_player[i].effective_action; +#if 0 + printf("::: %04d: %08x\n", FrameCounter, effective_action[0]); +#endif + GameActions_EM(effective_action, warp_mode); CheckLevelTime(); @@ -10011,7 +10047,8 @@ void GameActions_RND() else if (element == EL_EXPANDABLE_WALL || element == EL_EXPANDABLE_WALL_HORIZONTAL || element == EL_EXPANDABLE_WALL_VERTICAL || - element == EL_EXPANDABLE_WALL_ANY) + element == EL_EXPANDABLE_WALL_ANY || + element == EL_BD_EXPANDABLE_WALL) MauerAbleger(x, y); else if (element == EL_FLAMES) CheckForDragon(x, y); @@ -10364,7 +10401,7 @@ static void CheckGravityMovement(struct PlayerInfo *player) { int move_dir_horizontal = player->effective_action & MV_HORIZONTAL; int move_dir_vertical = player->effective_action & MV_VERTICAL; - boolean player_is_snapping = player->effective_action & JOY_BUTTON_1; + boolean player_is_snapping = (player->effective_action & JOY_BUTTON_1); int jx = player->jx, jy = player->jy; boolean player_is_moving_to_valid_field = (!player_is_snapping && @@ -10587,6 +10624,8 @@ boolean MovePlayer(struct PlayerInfo *player, int dx, int dy) player->move_delay_value = original_move_delay_value; } + player->is_active = FALSE; + if (player->last_move_dir & MV_HORIZONTAL) { if (!(moved |= MovePlayerOneStep(player, 0, dy, dx, dy))) @@ -10598,6 +10637,17 @@ boolean MovePlayer(struct PlayerInfo *player, int dx, int dy) moved |= MovePlayerOneStep(player, 0, dy, dx, dy); } +#if USE_FIXED_BORDER_RUNNING_GFX + if (!moved && !player->is_active) + { + player->is_moving = FALSE; + player->is_digging = FALSE; + player->is_collecting = FALSE; + player->is_snapping = FALSE; + player->is_pushing = FALSE; + } +#endif + jx = player->jx; jy = player->jy; @@ -12182,6 +12232,7 @@ int DigField(struct PlayerInfo *player, } player->is_pushing = TRUE; + player->is_active = TRUE; if (!(IN_LEV_FIELD(nextx, nexty) && (IS_FREE(nextx, nexty) || @@ -12434,7 +12485,10 @@ int DigField(struct PlayerInfo *player, if (is_player) /* function can also be called by EL_PENGUIN */ { if (Feld[x][y] != element) /* really digged/collected something */ + { player->is_collecting = !player->is_digging; + player->is_active = TRUE; + } } return MP_MOVING; @@ -12503,6 +12557,7 @@ boolean SnapField(struct PlayerInfo *player, int dx, int dy) return FALSE; player->is_snapping = TRUE; + player->is_active = TRUE; if (player->MovPos == 0) {