X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Fgame.c;h=c1e87624b867bf3a92a53e976a1cbbd0bee2cd48;hb=ac4c028b525860750de315d626730ac493f56944;hp=bf1000db0c1b794f93bc6a1d3ac744f519bbbddd;hpb=72e44014938c9042261b67213a6cd37b7a17488f;p=rocksndiamonds.git diff --git a/src/game.c b/src/game.c index bf1000db..c1e87624 100644 --- a/src/game.c +++ b/src/game.c @@ -723,7 +723,7 @@ void InitGame() { Feld[x][y] = Ur[x][y]; MovPos[x][y] = MovDir[x][y] = MovDelay[x][y] = 0; - Store[x][y] = Store2[x][y] = StorePlayer[x][y] = 0; + Store[x][y] = Store2[x][y] = StorePlayer[x][y] = Back[x][y] = 0; AmoebaNr[x][y] = 0; JustStopped[x][y] = 0; Stop[x][y] = FALSE; @@ -1433,13 +1433,18 @@ void DrawDynamite(int x, int y) if (!IN_SCR_FIELD(sx, sy) || IS_PLAYER(x, y)) return; - if (Store[x][y]) + if (IS_WALKABLE_INSIDE(Back[x][y])) + return; + + if (Back[x][y]) + DrawGraphic(sx, sy, el2img(Back[x][y]), 0); + else if (Store[x][y]) DrawGraphic(sx, sy, el2img(Store[x][y]), 0); frame = getGraphicAnimationFrame(graphic, GfxFrame[x][y]); #if 1 - if (Store[x][y]) + if (Back[x][y] || Store[x][y]) DrawGraphicThruMask(sx, sy, graphic, frame); else DrawGraphic(sx, sy, graphic, frame); @@ -1500,6 +1505,10 @@ void Explode(int ex, int ey, int phase, int mode) { int center_element = Feld[ex][ey]; + /* remove things displayed in background while burning dynamite */ + if (!IS_INDESTRUCTIBLE(Back[ex][ey])) + Back[ex][ey] = 0; + if (IS_MOVING(ex, ey) || IS_BLOCKED(ex, ey)) { /* put moving element to center field (and let it explode there) */ @@ -1525,7 +1534,9 @@ void Explode(int ex, int ey, int phase, int mode) RemoveMovingField(x, y); } - if ((IS_INDESTRUCTIBLE(element) && !IS_ACCESSIBLE(element)) || + if ((IS_INDESTRUCTIBLE(element) && + (game.engine_version < VERSION_IDENT(2,2,0) || + (!IS_WALKABLE_OVER(element) && !IS_WALKABLE_UNDER(element)))) || element == EL_FLAMES) continue; @@ -1541,14 +1552,14 @@ void Explode(int ex, int ey, int phase, int mode) continue; } + /* save walkable background elements while explosion on same tile */ + if (IS_INDESTRUCTIBLE(element)) + Back[x][y] = element; + + /* ignite explodable elements reached by other explosion */ if (element == EL_EXPLOSION) element = Store2[x][y]; -#if 1 - if (IS_INDESTRUCTIBLE(Store[x][y])) /* hard element under bomb */ - element = Store[x][y]; -#endif - if (IS_PLAYER(ex, ey) && !PLAYER_PROTECTED(ex, ey)) { switch(StorePlayer[ex][ey]) @@ -1601,15 +1612,8 @@ void Explode(int ex, int ey, int phase, int mode) Store[x][y] = EL_PEARL; else if (element == EL_WALL_CRYSTAL) Store[x][y] = EL_CRYSTAL; -#if 1 - else if (IS_INDESTRUCTIBLE(element)) - Store[x][y] = element; else Store[x][y] = EL_EMPTY; -#else - else if (!IS_PFORTE(Store[x][y])) - Store[x][y] = EL_EMPTY; -#endif if (x != ex || y != ey || center_element == EL_AMOEBA_TO_DIAMOND || mode == EX_BORDER) @@ -1679,6 +1683,11 @@ void Explode(int ex, int ey, int phase, int mode) element = Feld[x][y] = Store[x][y]; Store[x][y] = Store2[x][y] = 0; + + if (Back[x][y] && IS_INDESTRUCTIBLE(Back[x][y])) + element = Feld[x][y] = Back[x][y]; + Back[x][y] = 0; + MovDir[x][y] = MovPos[x][y] = MovDelay[x][y] = 0; InitField(x, y, FALSE); if (CAN_MOVE(element) || COULD_MOVE(element)) @@ -1699,28 +1708,18 @@ void Explode(int ex, int ey, int phase, int mode) if (phase == delay) DrawLevelFieldCrumbledSand(x, y); -#if 1 - if (IS_ACCESSIBLE_OVER(Store[x][y])) + if (IS_WALKABLE_OVER(Back[x][y])) { - DrawLevelElement(x, y, Store[x][y]); + DrawLevelElement(x, y, Back[x][y]); DrawGraphicThruMask(SCREENX(x), SCREENY(y), graphic, frame); } - else if (IS_ACCESSIBLE_UNDER(Store[x][y])) + else if (IS_WALKABLE_UNDER(Back[x][y])) { DrawGraphic(SCREENX(x), SCREENY(y), graphic, frame); - DrawLevelElementThruMask(x, y, Store[x][y]); - } - else if (!IS_ACCESSIBLE_INSIDE(Store[x][y])) - DrawGraphic(SCREENX(x), SCREENY(y), graphic, frame); -#else - if (IS_PFORTE(Store[x][y])) - { - DrawLevelElement(x, y, Store[x][y]); - DrawGraphicThruMask(SCREENX(x), SCREENY(y), graphic, frame); + DrawLevelElementThruMask(x, y, Back[x][y]); } - else + else if (!IS_WALKABLE_INSIDE(Back[x][y])) DrawGraphic(SCREENX(x), SCREENY(y), graphic, frame); -#endif } } @@ -1848,6 +1847,26 @@ void SplashAcid(int x, int y) } } +static int ChangeElementOnPlayfield(int element_old, int element_new) +{ + int x, y; + int num_changes = 0; + + for(y=0; yactive) return; -#if 1 -#else - if (IS_PFORTE(Feld[jx][jy])) - Feld[jx][jy] = EL_EMPTY; -#endif + /* remove accessible field at the player's position */ + Feld[jx][jy] = EL_EMPTY; /* deactivate shield (else Bang()/Explode() would not work right) */ player->shield_normal_time_left = 0; @@ -5892,6 +5912,8 @@ int DigField(struct PlayerInfo *player, { int key_nr = element - EL_KEY_1; int graphic = el2edimg(element); + int element_old, element_new; + int num_changes; RemoveField(x, y); player->key[key_nr] = TRUE; @@ -5901,6 +5923,34 @@ int DigField(struct PlayerInfo *player, DrawMiniGraphicExt(window, DX_KEYS + key_nr * MINI_TILEX, DY_KEYS, graphic); PlaySoundLevel(x, y, SND_CLASS_KEY_COLLECTING); + + element_old = EL_GATE_1_CLOSED + key_nr; + element_new = EL_GATE_1_OPEN + key_nr; + num_changes = ChangeElementOnPlayfield(element_old, element_new); + if (num_changes > 0) + PlaySoundLevelElementAction(x, y, element_old, ACTION_OPENING); + + element_old = EL_GATE_1_GRAY_CLOSED + key_nr; + element_new = EL_GATE_1_GRAY_OPEN + key_nr; + num_changes = ChangeElementOnPlayfield(element_old, element_new); + if (num_changes > 0) + PlaySoundLevelElementAction(x, y, element_old, ACTION_OPENING); + + if (game.engine_version < VERSION_IDENT(2,2,0)) + { + element_old = EL_EM_GATE_1_CLOSED + key_nr; + element_new = EL_EM_GATE_1_OPEN + key_nr; + num_changes = ChangeElementOnPlayfield(element_old, element_new); + if (num_changes > 0) + PlaySoundLevelElementAction(x, y, element_old, ACTION_OPENING); + + element_old = EL_EM_GATE_1_GRAY_CLOSED + key_nr; + element_new = EL_EM_GATE_1_GRAY_OPEN + key_nr; + num_changes = ChangeElementOnPlayfield(element_old, element_new); + if (num_changes > 0) + PlaySoundLevelElementAction(x, y, element_old, ACTION_OPENING); + } + break; } @@ -5911,6 +5961,8 @@ int DigField(struct PlayerInfo *player, { int key_nr = element - EL_EM_KEY_1; int graphic = el2edimg(EL_KEY_1 + key_nr); + int element_old, element_new; + int num_changes; RemoveField(x, y); player->key[key_nr] = TRUE; @@ -5920,6 +5972,34 @@ int DigField(struct PlayerInfo *player, DrawMiniGraphicExt(window, DX_KEYS + key_nr * MINI_TILEX, DY_KEYS, graphic); PlaySoundLevel(x, y, SND_CLASS_KEY_COLLECTING); + + element_old = EL_EM_GATE_1_CLOSED + key_nr; + element_new = EL_EM_GATE_1_OPEN + key_nr; + num_changes = ChangeElementOnPlayfield(element_old, element_new); + if (num_changes > 0) + PlaySoundLevelElementAction(x, y, element_old, ACTION_OPENING); + + element_old = EL_EM_GATE_1_GRAY_CLOSED + key_nr; + element_new = EL_EM_GATE_1_GRAY_OPEN + key_nr; + num_changes = ChangeElementOnPlayfield(element_old, element_new); + if (num_changes > 0) + PlaySoundLevelElementAction(x, y, element_old, ACTION_OPENING); + + if (game.engine_version < VERSION_IDENT(2,2,0)) + { + element_old = EL_GATE_1_CLOSED + key_nr; + element_new = EL_GATE_1_OPEN + key_nr; + num_changes = ChangeElementOnPlayfield(element_old, element_new); + if (num_changes > 0) + PlaySoundLevelElementAction(x, y, element_old, ACTION_OPENING); + + element_old = EL_GATE_1_GRAY_CLOSED + key_nr; + element_new = EL_GATE_1_GRAY_OPEN + key_nr; + num_changes = ChangeElementOnPlayfield(element_old, element_new); + if (num_changes > 0) + PlaySoundLevelElementAction(x, y, element_old, ACTION_OPENING); + } + break; } @@ -6090,28 +6170,34 @@ int DigField(struct PlayerInfo *player, PlaySoundLevelElementAction(x, y, element, ACTION_PUSHING); break; - case EL_GATE_1: - case EL_GATE_2: - case EL_GATE_3: - case EL_GATE_4: + case EL_GATE_1_OPEN: + case EL_GATE_2_OPEN: + case EL_GATE_3_OPEN: + case EL_GATE_4_OPEN: +#if 0 if (!player->key[element - EL_GATE_1]) return MF_NO_ACTION; +#endif break; - case EL_GATE_1_GRAY: - case EL_GATE_2_GRAY: - case EL_GATE_3_GRAY: - case EL_GATE_4_GRAY: + case EL_GATE_1_GRAY_OPEN: + case EL_GATE_2_GRAY_OPEN: + case EL_GATE_3_GRAY_OPEN: + case EL_GATE_4_GRAY_OPEN: +#if 0 if (!player->key[element - EL_GATE_1_GRAY]) return MF_NO_ACTION; +#endif break; - case EL_EM_GATE_1: - case EL_EM_GATE_2: - case EL_EM_GATE_3: - case EL_EM_GATE_4: + case EL_EM_GATE_1_OPEN: + case EL_EM_GATE_2_OPEN: + case EL_EM_GATE_3_OPEN: + case EL_EM_GATE_4_OPEN: +#if 0 if (!player->key[element - EL_EM_GATE_1]) return MF_NO_ACTION; +#endif if (!IN_LEV_FIELD(x + dx, y + dy) || !IS_FREE(x + dx, y + dy)) return MF_NO_ACTION; @@ -6119,15 +6205,21 @@ int DigField(struct PlayerInfo *player, player->programmed_action = move_direction; DOUBLE_PLAYER_SPEED(player); +#if 1 + PlaySoundLevelAction(x, y, ACTION_PASSING); +#else PlaySoundLevel(x, y, SND_CLASS_GATE_PASSING); +#endif break; - case EL_EM_GATE_1_GRAY: - case EL_EM_GATE_2_GRAY: - case EL_EM_GATE_3_GRAY: - case EL_EM_GATE_4_GRAY: + case EL_EM_GATE_1_GRAY_OPEN: + case EL_EM_GATE_2_GRAY_OPEN: + case EL_EM_GATE_3_GRAY_OPEN: + case EL_EM_GATE_4_GRAY_OPEN: +#if 0 if (!player->key[element - EL_EM_GATE_1_GRAY]) return MF_NO_ACTION; +#endif if (!IN_LEV_FIELD(x + dx, y + dy) || !IS_FREE(x + dx, y + dy)) return MF_NO_ACTION; @@ -6505,7 +6597,13 @@ boolean PlaceBomb(struct PlayerInfo *player) return FALSE; if (element != EL_EMPTY) + { +#if 0 Store[jx][jy] = element; +#else + Back[jx][jy] = element; +#endif + } MovDelay[jx][jy] = 96;