X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Fgame.c;h=61d5d6b2f313b7586c73527b7bafd7a19da749dd;hb=81649ac54979cfd96571d7295b12fcccf58b0fd9;hp=f078ff7c5ae5915d0279c07a7c5cc92a0475c014;hpb=36d0e6ff3c76c763be2392f1492eb37c4f062d30;p=rocksndiamonds.git diff --git a/src/game.c b/src/game.c index f078ff7c..61d5d6b2 100644 --- a/src/game.c +++ b/src/game.c @@ -57,6 +57,7 @@ #define USE_GFX_RESET_PLAYER_ARTWORK (USE_NEW_STUFF * 1) #define USE_FIX_KILLED_BY_NON_WALKABLE (USE_NEW_STUFF * 1) +#define USE_FIX_IMPACT_COLLISION (USE_NEW_STUFF * 1) /* for DigField() */ @@ -120,8 +121,9 @@ /* values for delayed check of falling and moving elements and for collision */ #define CHECK_DELAY_MOVING 3 -#define CHECK_DELAY_FALLING 3 +#define CHECK_DELAY_FALLING CHECK_DELAY_MOVING #define CHECK_DELAY_COLLISION 2 +#define CHECK_DELAY_IMPACT CHECK_DELAY_COLLISION /* values for initial player move delay (initial delay counter value) */ #define INITIAL_MOVE_DELAY_OFF -1 @@ -2037,6 +2039,7 @@ void InitGame() WasJustMoving[x][y] = 0; WasJustFalling[x][y] = 0; CheckCollision[x][y] = 0; + CheckImpact[x][y] = 0; Stop[x][y] = FALSE; Pushed[x][y] = FALSE; @@ -2731,35 +2734,38 @@ void GameWon() DrawGameValue_Score(score); } - if (ExitX >= 0 && ExitY >= 0) /* local player has left the level */ + if (level.game_engine_type == GAME_ENGINE_TYPE_RND) { - /* close exit door after last player */ - if (AllPlayersGone && - (Feld[ExitX][ExitY] == EL_EXIT_OPEN || - Feld[ExitX][ExitY] == EL_SP_EXIT_OPEN)) + if (ExitX >= 0 && ExitY >= 0) /* local player has left the level */ { - int element = Feld[ExitX][ExitY]; - - Feld[ExitX][ExitY] = (element == EL_EXIT_OPEN ? EL_EXIT_CLOSING : - EL_SP_EXIT_CLOSING); + /* close exit door after last player */ + if (AllPlayersGone && + (Feld[ExitX][ExitY] == EL_EXIT_OPEN || + Feld[ExitX][ExitY] == EL_SP_EXIT_OPEN)) + { + int element = Feld[ExitX][ExitY]; - PlayLevelSoundElementAction(ExitX, ExitY, element, ACTION_CLOSING); - } + Feld[ExitX][ExitY] = (element == EL_EXIT_OPEN ? EL_EXIT_CLOSING : + EL_SP_EXIT_CLOSING); - /* player disappears */ - DrawLevelField(ExitX, ExitY); - } + PlayLevelSoundElementAction(ExitX, ExitY, element, ACTION_CLOSING); + } - for (i = 0; i < MAX_PLAYERS; i++) - { - struct PlayerInfo *player = &stored_player[i]; + /* player disappears */ + DrawLevelField(ExitX, ExitY); + } - if (player->present) + for (i = 0; i < MAX_PLAYERS; i++) { - RemovePlayer(player); + struct PlayerInfo *player = &stored_player[i]; - /* player disappears */ - DrawLevelField(player->jx, player->jy); + if (player->present) + { + RemovePlayer(player); + + /* player disappears */ + DrawLevelField(player->jx, player->jy); + } } } @@ -5634,9 +5640,14 @@ void StartMoving(int x, int y) Store[x][y] = EL_ACID; } - else if ((game.engine_version >= VERSION_IDENT(3,1,0,0) && + else if ( +#if USE_FIX_IMPACT_COLLISION + (game.engine_version >= VERSION_IDENT(3,1,0,0) && + CheckImpact[x][y] && !IS_FREE(x, y + 1)) || +#else + (game.engine_version >= VERSION_IDENT(3,1,0,0) && CheckCollision[x][y] && !IS_FREE(x, y + 1)) || - +#endif (game.engine_version >= VERSION_IDENT(3,0,7,0) && CAN_FALL(element) && WasJustFalling[x][y] && (Feld[x][y + 1] == EL_BLOCKED || IS_PLAYER(x, y + 1))) || @@ -5656,6 +5667,7 @@ void StartMoving(int x, int y) simply not covered here... :-/ ) */ CheckCollision[x][y] = 0; + CheckImpact[x][y] = 0; Impact(x, y); } @@ -6600,6 +6612,11 @@ void ContinueMoving(int x, int y) if ((!CAN_FALL(element) || direction == MV_DOWN) && check_collision_again) CheckCollision[newx][newy] = CHECK_DELAY_COLLISION; + +#if USE_FIX_IMPACT_COLLISION + if (CAN_FALL(element) && direction == MV_DOWN && check_collision_again) + CheckImpact[newx][newy] = CHECK_DELAY_IMPACT; +#endif } if (DONT_TOUCH(element)) /* object may be nasty to player or others */ @@ -6667,7 +6684,7 @@ void ContinueMoving(int x, int y) if (IS_CUSTOM_ELEMENT(element) && ei->move_enter_element != EL_EMPTY && IS_EQUAL_OR_IN_GROUP(stored_new, ei->move_enter_element)) CheckElementChangeBySide(newx, newy, element, stored_new, CE_DIGGING_X, - MV_DIR_OPPOSITE(direction)); + MV_DIR_OPPOSITE(direction)); } int AmoebeNachbarNr(int ax, int ay) @@ -8644,10 +8661,18 @@ static boolean CheckElementChangeExt(int x, int y, { struct ElementChangeInfo *change = &element_info[element].change_page[p]; + /* check trigger element for all events where the element that is checked + for changing interacts with a directly adjacent element -- this is + different to element changes that affect other elements to change on the + whole playfield (which is handeld by CheckTriggeredElementChangeExt()) */ boolean check_trigger_element = (trigger_event == CE_TOUCHING_X || trigger_event == CE_HITTING_X || - trigger_event == CE_HIT_BY_X); + trigger_event == CE_HIT_BY_X || +#if 1 + /* this one was forgotten until 3.2.3 */ + trigger_event == CE_DIGGING_X); +#endif if (change->can_change_or_has_action && change->has_event[trigger_event] && @@ -9421,6 +9446,8 @@ void GameActions_RND() WasJustFalling[x][y]--; if (CheckCollision[x][y] > 0) CheckCollision[x][y]--; + if (CheckImpact[x][y] > 0) + CheckImpact[x][y]--; GfxFrame[x][y]++; @@ -12057,7 +12084,13 @@ boolean DropElement(struct PlayerInfo *player) nexty = dropy + GET_DY_FROM_DIR(move_direction); ChangeCount[dropx][dropy] = 0; /* allow at least one more change */ + +#if USE_FIX_IMPACT_COLLISION + /* do not cause impact style collision by dropping elements that can fall */ CheckCollision[dropx][dropy] = CHECK_DELAY_COLLISION; +#else + CheckCollision[dropx][dropy] = CHECK_DELAY_COLLISION; +#endif } player->drop_delay = GET_NEW_DROP_DELAY(drop_element); @@ -12739,6 +12772,7 @@ void SaveEngineSnapshot() SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(WasJustMoving)); SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(WasJustFalling)); SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(CheckCollision)); + SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(CheckImpact)); SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(Stop)); SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(Pushed));