X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Fgame.c;h=d0afc792ca8270df465b41cefcac6177eab172d9;hb=1ca582ff344bd825e03229636cee6d006e19251f;hp=843956362443cfc5e95da1e4f338e71620ef54cd;hpb=80a9825ee7983ea810b89f4e827efc85e01b69bc;p=rocksndiamonds.git diff --git a/src/game.c b/src/game.c index 84395636..d0afc792 100644 --- a/src/game.c +++ b/src/game.c @@ -245,7 +245,9 @@ #define PENGUIN_CAN_ENTER_FIELD(e, x, y) \ ELEMENT_CAN_ENTER_FIELD_BASE_2(e, x, y, (Feld[x][y] == EL_EXIT_OPEN || \ + Feld[x][y] == EL_EM_EXIT_OPEN || \ Feld[x][y] == EL_STEEL_EXIT_OPEN || \ + Feld[x][y] == EL_EM_STEEL_EXIT_OPEN || \ IS_FOOD_PENGUIN(Feld[x][y]))) #define DRAGON_CAN_ENTER_FIELD(e, x, y) \ ELEMENT_CAN_ENTER_FIELD_BASE_2(e, x, y, 0) @@ -381,8 +383,8 @@ static int getInvisibleFromInvisibleActiveElement(int); static struct GadgetInfo *game_gadget[NUM_GAME_BUTTONS]; /* for detection of endless loops, caused by custom element programming */ -/* (using "MAX_PLAYFIELD_WIDTH" here is just a rough approximation...) */ -#define MAX_ELEMENT_CHANGE_RECURSION_DEPTH (MAX_PLAYFIELD_WIDTH) +/* (using maximal playfield width x 10 is just a rough approximation) */ +#define MAX_ELEMENT_CHANGE_RECURSION_DEPTH (MAX_PLAYFIELD_WIDTH * 10) #define RECURSION_LOOP_DETECTION_START(e, rc) \ { \ @@ -491,6 +493,46 @@ static struct ChangingElementInfo change_delay_list[] = NULL, NULL }, + { + EL_EM_EXIT_OPENING, + EL_EM_EXIT_OPEN, + 29, + NULL, + NULL, + NULL + }, + { + EL_EM_EXIT_CLOSING, +#if 1 + EL_EMPTY, +#else + EL_EM_EXIT_CLOSED, +#endif + 29, + NULL, + NULL, + NULL + }, + { + EL_EM_STEEL_EXIT_OPENING, + EL_EM_STEEL_EXIT_OPEN, + 29, + NULL, + NULL, + NULL + }, + { + EL_EM_STEEL_EXIT_CLOSING, +#if 1 + EL_STEELWALL, +#else + EL_EM_STEEL_EXIT_CLOSED, +#endif + 29, + NULL, + NULL, + NULL + }, { EL_SP_EXIT_OPENING, EL_SP_EXIT_OPEN, @@ -2802,18 +2844,33 @@ void GameWon() if (ExitX >= 0 && ExitY >= 0) /* local player has left the level */ { /* close exit door after last player */ - if (AllPlayersGone && - (Feld[ExitX][ExitY] == EL_EXIT_OPEN || - Feld[ExitX][ExitY] == EL_SP_EXIT_OPEN || - Feld[ExitX][ExitY] == EL_STEEL_EXIT_OPEN)) + if ((AllPlayersGone && + (Feld[ExitX][ExitY] == EL_EXIT_OPEN || + Feld[ExitX][ExitY] == EL_SP_EXIT_OPEN || + Feld[ExitX][ExitY] == EL_STEEL_EXIT_OPEN)) || + Feld[ExitX][ExitY] == EL_EM_EXIT_OPEN || + Feld[ExitX][ExitY] == EL_EM_STEEL_EXIT_OPEN) { int element = Feld[ExitX][ExitY]; - Feld[ExitX][ExitY] = (element == EL_EXIT_OPEN ? EL_EXIT_CLOSING : - element == EL_SP_EXIT_OPEN ? EL_SP_EXIT_CLOSING: - EL_STEEL_EXIT_CLOSING); - - PlayLevelSoundElementAction(ExitX, ExitY, element, ACTION_CLOSING); +#if 0 + if (element == EL_EM_EXIT_OPEN || + element == EL_EM_STEEL_EXIT_OPEN) + { + Bang(ExitX, ExitY); + } + else +#endif + { + Feld[ExitX][ExitY] = + (element == EL_EXIT_OPEN ? EL_EXIT_CLOSING : + element == EL_EM_EXIT_OPEN ? EL_EM_EXIT_CLOSING : + element == EL_SP_EXIT_OPEN ? EL_SP_EXIT_CLOSING: + element == EL_STEEL_EXIT_OPEN ? EL_STEEL_EXIT_CLOSING: + EL_EM_STEEL_EXIT_CLOSING); + + PlayLevelSoundElementAction(ExitX, ExitY, element, ACTION_CLOSING); + } } /* player disappears */ @@ -4044,6 +4101,10 @@ void Bang(int x, int y) break; case EL_DC_LANDMINE: +#if 0 + case EL_EM_EXIT_OPEN: + case EL_EM_STEEL_EXIT_OPEN: +#endif explosion_type = EX_TYPE_CENTER; break; @@ -5114,7 +5175,9 @@ inline static void TurnRoundExt(int x, int y) int ey = y + xy[i][1]; if (IN_LEV_FIELD(ex, ey) && (Feld[ex][ey] == EL_EXIT_OPEN || - Feld[ex][ey] == EL_STEEL_EXIT_OPEN)) + Feld[ex][ey] == EL_EM_EXIT_OPEN || + Feld[ex][ey] == EL_STEEL_EXIT_OPEN || + Feld[ex][ey] == EL_EM_STEEL_EXIT_OPEN)) { attr_x = ex; attr_y = ey; @@ -6112,7 +6175,9 @@ void StartMoving(int x, int y) else if (element == EL_PENGUIN && IN_LEV_FIELD(newx, newy)) { if (Feld[newx][newy] == EL_EXIT_OPEN || - Feld[newx][newy] == EL_STEEL_EXIT_OPEN) + Feld[newx][newy] == EL_EM_EXIT_OPEN || + Feld[newx][newy] == EL_STEEL_EXIT_OPEN || + Feld[newx][newy] == EL_EM_STEEL_EXIT_OPEN) { RemoveField(x, y); DrawLevelField(x, y); @@ -7373,6 +7438,29 @@ void CheckExit(int x, int y) PlayLevelSoundNearest(x, y, SND_CLASS_EXIT_OPENING); } +void CheckExitEM(int x, int y) +{ + if (local_player->gems_still_needed > 0 || + local_player->sokobanfields_still_needed > 0 || + local_player->lights_still_needed > 0) + { + int element = Feld[x][y]; + int graphic = el2img(element); + + if (IS_ANIMATED(graphic)) + DrawLevelGraphicAnimationIfNeeded(x, y, graphic); + + return; + } + + if (AllPlayersGone) /* do not re-open exit door closed after last player */ + return; + + Feld[x][y] = EL_EM_EXIT_OPENING; + + PlayLevelSoundNearest(x, y, SND_CLASS_EM_EXIT_OPENING); +} + void CheckExitSteel(int x, int y) { if (local_player->gems_still_needed > 0 || @@ -7396,6 +7484,29 @@ void CheckExitSteel(int x, int y) PlayLevelSoundNearest(x, y, SND_CLASS_STEEL_EXIT_OPENING); } +void CheckExitSteelEM(int x, int y) +{ + if (local_player->gems_still_needed > 0 || + local_player->sokobanfields_still_needed > 0 || + local_player->lights_still_needed > 0) + { + int element = Feld[x][y]; + int graphic = el2img(element); + + if (IS_ANIMATED(graphic)) + DrawLevelGraphicAnimationIfNeeded(x, y, graphic); + + return; + } + + if (AllPlayersGone) /* do not re-open exit door closed after last player */ + return; + + Feld[x][y] = EL_EM_STEEL_EXIT_OPENING; + + PlayLevelSoundNearest(x, y, SND_CLASS_EM_STEEL_EXIT_OPENING); +} + void CheckExitSP(int x, int y) { if (local_player->gems_still_needed > 0) @@ -9820,8 +9931,10 @@ void GameActions_RND() } else if ((element == EL_ACID || element == EL_EXIT_OPEN || + element == EL_EM_EXIT_OPEN || element == EL_SP_EXIT_OPEN || element == EL_STEEL_EXIT_OPEN || + element == EL_EM_STEEL_EXIT_OPEN || element == EL_SP_TERMINAL || element == EL_SP_TERMINAL_ACTIVE || element == EL_EXTRA_TIME || @@ -9847,8 +9960,12 @@ void GameActions_RND() Life(x, y); else if (element == EL_EXIT_CLOSED) CheckExit(x, y); + else if (element == EL_EM_EXIT_CLOSED) + CheckExitEM(x, y); else if (element == EL_STEEL_EXIT_CLOSED) CheckExitSteel(x, y); + else if (element == EL_EM_STEEL_EXIT_CLOSED) + CheckExitSteelEM(x, y); else if (element == EL_SP_EXIT_CLOSED) CheckExitSP(x, y); else if (element == EL_EXPANDABLE_WALL_GROWING || @@ -10676,7 +10793,9 @@ void ScrollPlayer(struct PlayerInfo *player, int mode) player->last_jy = jy; if (Feld[jx][jy] == EL_EXIT_OPEN || + Feld[jx][jy] == EL_EM_EXIT_OPEN || Feld[jx][jy] == EL_STEEL_EXIT_OPEN || + Feld[jx][jy] == EL_EM_STEEL_EXIT_OPEN || Feld[jx][jy] == EL_SP_EXIT_OPEN || Feld[jx][jy] == EL_SP_EXIT_OPENING) /* <-- special case */ { @@ -11645,7 +11764,9 @@ int DigField(struct PlayerInfo *player, return MP_NO_ACTION; } else if (element == EL_EXIT_OPEN || + element == EL_EM_EXIT_OPEN || element == EL_STEEL_EXIT_OPEN || + element == EL_EM_STEEL_EXIT_OPEN || element == EL_SP_EXIT_OPEN || element == EL_SP_EXIT_OPENING) {