X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Fgame.c;h=bb6e6ede2b2d259978b05380fef26368630f6027;hb=dff0e0c8702770fe23992f07964ebe9ed54e9f7c;hp=d0afc792ca8270df465b41cefcac6177eab172d9;hpb=1ca582ff344bd825e03229636cee6d006e19251f;p=rocksndiamonds.git diff --git a/src/game.c b/src/game.c index d0afc792..bb6e6ede 100644 --- a/src/game.c +++ b/src/game.c @@ -85,27 +85,38 @@ #define EX_TYPE_DYNA (1 << 4) #define EX_TYPE_SINGLE_TILE (EX_TYPE_CENTER | EX_TYPE_BORDER) +#if 1 +#define PANEL_DEACTIVATED(p) ((p)->x < 0 || (p)->y < 0) +#define PANEL_XPOS(p) (DX + ALIGNED_MENU_XPOS(p)) +#define PANEL_YPOS(p) (DY + ALIGNED_MENU_YPOS(p)) +#else #define PANEL_DEACTIVATED(p) ((p).x < 0 || (p).y < 0) +#define PANEL_XPOS(p) (ALIGNED_XPOS((p).x, (p).width, (p).align)) +#define PANEL_YPOS(p) ((p).y) +#endif /* special positions in the game control window (relative to control window) */ -#define XX_LEVEL1 (game.panel.level.x) -#define XX_LEVEL2 (game.panel.level.x - 1) -#define YY_LEVEL (game.panel.level.y) -#define XX_EMERALDS (game.panel.gems.x) -#define YY_EMERALDS (game.panel.gems.y) -#define XX_DYNAMITE (game.panel.inventory.x) -#define YY_DYNAMITE (game.panel.inventory.y) -#define XX_KEYS (game.panel.keys.x) -#define YY_KEYS (game.panel.keys.y) -#define XX_SCORE (game.panel.score.x) -#define YY_SCORE (game.panel.score.y) -#define XX_TIME1 (game.panel.time.x) -#define XX_TIME2 (game.panel.time.x + 1) -#define YY_TIME (game.panel.time.y) +#define XX_LEVEL1 (PANEL_XPOS(game.panel.level)) +#define XX_LEVEL2 (PANEL_XPOS(game.panel.level) - 1) +#define XX_LEVEL (PANEL_XPOS(game.panel.level)) +#define YY_LEVEL (PANEL_YPOS(game.panel.level)) +#define XX_EMERALDS (PANEL_XPOS(game.panel.gems)) +#define YY_EMERALDS (PANEL_YPOS(game.panel.gems)) +#define XX_DYNAMITE (PANEL_XPOS(game.panel.inventory)) +#define YY_DYNAMITE (PANEL_YPOS(game.panel.inventory)) +#define XX_KEYS (PANEL_XPOS(game.panel.keys)) +#define YY_KEYS (PANEL_YPOS(game.panel.keys)) +#define XX_SCORE (PANEL_XPOS(game.panel.score)) +#define YY_SCORE (PANEL_YPOS(game.panel.score)) +#define XX_TIME1 (PANEL_XPOS(game.panel.time)) +#define XX_TIME2 (PANEL_XPOS(game.panel.time) + 1) +#define XX_TIME (PANEL_XPOS(game.panel.time)) +#define YY_TIME (PANEL_YPOS(game.panel.time)) /* special positions in the game control window (relative to main window) */ #define DX_LEVEL1 (DX + XX_LEVEL1) #define DX_LEVEL2 (DX + XX_LEVEL2) +#define DX_LEVEL (DX + XX_LEVEL) #define DY_LEVEL (DY + YY_LEVEL) #define DX_EMERALDS (DX + XX_EMERALDS) #define DY_EMERALDS (DY + YY_EMERALDS) @@ -117,6 +128,7 @@ #define DY_SCORE (DY + YY_SCORE) #define DX_TIME1 (DX + XX_TIME1) #define DX_TIME2 (DX + XX_TIME2) +#define DX_TIME (DX + XX_TIME) #define DY_TIME (DY + YY_TIME) /* values for delayed check of falling and moving elements and for collision */ @@ -734,10 +746,14 @@ move_stepsize_list[] = { EL_AMOEBA_DROPPING, 2 }, { EL_QUICKSAND_FILLING, 1 }, { EL_QUICKSAND_EMPTYING, 1 }, + { EL_QUICKSAND_FAST_FILLING, 2 }, + { EL_QUICKSAND_FAST_EMPTYING, 2 }, { EL_MAGIC_WALL_FILLING, 2 }, - { EL_BD_MAGIC_WALL_FILLING, 2 }, { EL_MAGIC_WALL_EMPTYING, 2 }, + { EL_BD_MAGIC_WALL_FILLING, 2 }, { EL_BD_MAGIC_WALL_EMPTYING, 2 }, + { EL_DC_MAGIC_WALL_FILLING, 2 }, + { EL_DC_MAGIC_WALL_EMPTYING, 2 }, { EL_UNDEFINED, 0 }, }; @@ -1313,65 +1329,195 @@ static inline void InitField_WithBug2(int x, int y, boolean init_game) */ } -inline void DrawGameValue_Emeralds(int value) +#if 1 + +void DrawGameValue_Emeralds(int value) { - int xpos = (3 * 14 - 3 * getFontWidth(FONT_TEXT_2)) / 2; + struct TextPosInfo *pos = &game.panel.gems; + int font_nr = FONT_TEXT_2; + int font_width = getFontWidth(font_nr); + int digits = pos->chars; - if (PANEL_DEACTIVATED(game.panel.gems)) + if (PANEL_DEACTIVATED(pos)) return; - DrawText(DX_EMERALDS + xpos, DY_EMERALDS, int2str(value, 3), FONT_TEXT_2); + pos->width = digits * font_width; + + DrawText(PANEL_XPOS(pos), PANEL_YPOS(pos), int2str(value, digits), font_nr); } -inline void DrawGameValue_Dynamite(int value) +void DrawGameValue_Dynamite(int value) { - int xpos = (3 * 14 - 3 * getFontWidth(FONT_TEXT_2)) / 2; + struct TextPosInfo *pos = &game.panel.inventory; + int font_nr = FONT_TEXT_2; + int font_width = getFontWidth(font_nr); + int digits = pos->chars; - if (PANEL_DEACTIVATED(game.panel.inventory)) + if (PANEL_DEACTIVATED(pos)) + return; + + pos->width = digits * font_width; + + DrawText(PANEL_XPOS(pos), PANEL_YPOS(pos), int2str(value, digits), font_nr); +} + +void DrawGameValue_Score(int value) +{ + struct TextPosInfo *pos = &game.panel.score; + int font_nr = FONT_TEXT_2; + int font_width = getFontWidth(font_nr); + int digits = pos->chars; + + if (PANEL_DEACTIVATED(pos)) + return; + + pos->width = digits * font_width; + + DrawText(PANEL_XPOS(pos), PANEL_YPOS(pos), int2str(value, digits), font_nr); +} + +void DrawGameValue_Time(int value) +{ + struct TextPosInfo *pos = &game.panel.time; + static int last_value = -1; + int digits1 = 3; + int digits2 = 4; + int digits = pos->chars; + int font1_nr = FONT_TEXT_2; + int font2_nr = FONT_TEXT_1; + int font_nr = font1_nr; + boolean use_dynamic_digits = (digits == -1 ? TRUE : FALSE); + + if (PANEL_DEACTIVATED(pos)) + return; + + if (use_dynamic_digits) /* use dynamic number of digits */ + { + digits = (value < 1000 ? digits1 : digits2); + font_nr = (value < 1000 ? font1_nr : font2_nr); + } + + /* clear background if value just changed its size (dynamic digits only) */ + if (use_dynamic_digits && (last_value < 1000) != (value < 1000)) + { + int width1 = digits1 * getFontWidth(font1_nr); + int width2 = digits2 * getFontWidth(font2_nr); + int max_width = MAX(width1, width2); + int max_height = MAX(getFontHeight(font1_nr), getFontHeight(font2_nr)); + + pos->width = max_width; + + ClearRectangleOnBackground(drawto, PANEL_XPOS(pos), PANEL_YPOS(pos), + max_width, max_height); + } + + pos->width = digits * getFontWidth(font_nr); + + DrawText(PANEL_XPOS(pos), PANEL_YPOS(pos), int2str(value, digits), font_nr); + + last_value = value; +} + +void DrawGameValue_Level(int value) +{ + struct TextPosInfo *pos = &game.panel.level; + int digits1 = 2; + int digits2 = 3; + int digits = pos->chars; + int font1_nr = FONT_TEXT_2; + int font2_nr = FONT_TEXT_1; + int font_nr = font1_nr; + boolean use_dynamic_digits = (digits == -1 ? TRUE : FALSE); + + if (PANEL_DEACTIVATED(pos)) return; - DrawText(DX_DYNAMITE + xpos, DY_DYNAMITE, int2str(value, 3), FONT_TEXT_2); + if (use_dynamic_digits) /* use dynamic number of digits */ + { + digits = (level_nr < 100 ? digits1 : digits2); + font_nr = (level_nr < 100 ? font1_nr : font2_nr); + } + + pos->width = digits * getFontWidth(font_nr); + + DrawText(PANEL_XPOS(pos), PANEL_YPOS(pos), int2str(value, digits), font_nr); } -inline void DrawGameValue_Keys(int key[MAX_NUM_KEYS]) +void DrawGameValue_Keys(int key[MAX_NUM_KEYS]) { + struct TextPosInfo *pos = &game.panel.keys; int base_key_graphic = EL_KEY_1; int i; - if (PANEL_DEACTIVATED(game.panel.keys)) + if (PANEL_DEACTIVATED(pos)) return; if (level.game_engine_type == GAME_ENGINE_TYPE_EM) base_key_graphic = EL_EM_KEY_1; + pos->width = 4 * MINI_TILEX; + /* currently only 4 of 8 possible keys are displayed */ for (i = 0; i < STD_NUM_KEYS; i++) { - int x = XX_KEYS + i * MINI_TILEX; - int y = YY_KEYS; + int src_x = DOOR_GFX_PAGEX5 + 18; + int src_y = DOOR_GFX_PAGEY1 + 123; + int dst_x = PANEL_XPOS(pos) + i * MINI_TILEX; + int dst_y = PANEL_YPOS(pos); if (key[i]) - DrawMiniGraphicExt(drawto, DX + x,DY + y, el2edimg(base_key_graphic + i)); + DrawMiniGraphicExt(drawto, dst_x, dst_y, el2edimg(base_key_graphic + i)); else - BlitBitmap(graphic_info[IMG_GLOBAL_DOOR].bitmap, drawto, - DOOR_GFX_PAGEX5 + x, y, MINI_TILEX, MINI_TILEY, DX + x,DY + y); + BlitBitmap(graphic_info[IMG_GLOBAL_DOOR].bitmap, drawto, src_x, src_y, + MINI_TILEX, MINI_TILEY, dst_x, dst_y); } } -inline void DrawGameValue_Score(int value) +#else + +void DrawGameValue_Emeralds(int value) +{ + int font_nr = FONT_TEXT_2; + int xpos = (3 * 14 - 3 * getFontWidth(font_nr)) / 2; + + if (PANEL_DEACTIVATED(game.panel.gems)) + return; + + DrawText(DX_EMERALDS + xpos, DY_EMERALDS, int2str(value, 3), font_nr); +} + +void DrawGameValue_Dynamite(int value) +{ + int font_nr = FONT_TEXT_2; + int xpos = (3 * 14 - 3 * getFontWidth(font_nr)) / 2; + + if (PANEL_DEACTIVATED(game.panel.inventory)) + return; + + DrawText(DX_DYNAMITE + xpos, DY_DYNAMITE, int2str(value, 3), font_nr); +} + +void DrawGameValue_Score(int value) { - int xpos = (5 * 14 - 5 * getFontWidth(FONT_TEXT_2)) / 2; + int font_nr = FONT_TEXT_2; + int xpos = (5 * 14 - 5 * getFontWidth(font_nr)) / 2; if (PANEL_DEACTIVATED(game.panel.score)) return; - DrawText(DX_SCORE + xpos, DY_SCORE, int2str(value, 5), FONT_TEXT_2); + DrawText(DX_SCORE + xpos, DY_SCORE, int2str(value, 5), font_nr); } -inline void DrawGameValue_Time(int value) +void DrawGameValue_Time(int value) { - int xpos3 = (3 * 14 - 3 * getFontWidth(FONT_TEXT_2)) / 2; - int xpos4 = (4 * 10 - 4 * getFontWidth(FONT_LEVEL_NUMBER)) / 2; + int font1_nr = FONT_TEXT_2; +#if 1 + int font2_nr = FONT_TEXT_1; +#else + int font2_nr = FONT_LEVEL_NUMBER; +#endif + int xpos3 = (3 * 14 - 3 * getFontWidth(font1_nr)) / 2; + int xpos4 = (4 * 10 - 4 * getFontWidth(font2_nr)) / 2; if (PANEL_DEACTIVATED(game.panel.time)) return; @@ -1381,22 +1527,56 @@ inline void DrawGameValue_Time(int value) ClearRectangleOnBackground(drawto, DX_TIME1, DY_TIME, 14 * 3, 14); if (value < 1000) - DrawText(DX_TIME1 + xpos3, DY_TIME, int2str(value, 3), FONT_TEXT_2); + DrawText(DX_TIME1 + xpos3, DY_TIME, int2str(value, 3), font1_nr); else - DrawText(DX_TIME2 + xpos4, DY_TIME, int2str(value, 4), FONT_LEVEL_NUMBER); + DrawText(DX_TIME2 + xpos4, DY_TIME, int2str(value, 4), font2_nr); } -inline void DrawGameValue_Level(int value) +void DrawGameValue_Level(int value) { + int font1_nr = FONT_TEXT_2; +#if 1 + int font2_nr = FONT_TEXT_1; +#else + int font2_nr = FONT_LEVEL_NUMBER; +#endif + if (PANEL_DEACTIVATED(game.panel.level)) return; if (level_nr < 100) - DrawText(DX_LEVEL1, DY_LEVEL, int2str(value, 2), FONT_TEXT_2); + DrawText(DX_LEVEL1, DY_LEVEL, int2str(value, 2), font1_nr); else - DrawText(DX_LEVEL2, DY_LEVEL, int2str(value, 3), FONT_LEVEL_NUMBER); + DrawText(DX_LEVEL2, DY_LEVEL, int2str(value, 3), font2_nr); +} + +void DrawGameValue_Keys(int key[MAX_NUM_KEYS]) +{ + int base_key_graphic = EL_KEY_1; + int i; + + if (PANEL_DEACTIVATED(game.panel.keys)) + return; + + if (level.game_engine_type == GAME_ENGINE_TYPE_EM) + base_key_graphic = EL_EM_KEY_1; + + /* currently only 4 of 8 possible keys are displayed */ + for (i = 0; i < STD_NUM_KEYS; i++) + { + int x = XX_KEYS + i * MINI_TILEX; + int y = YY_KEYS; + + if (key[i]) + DrawMiniGraphicExt(drawto, DX + x,DY + y, el2edimg(base_key_graphic + i)); + else + BlitBitmap(graphic_info[IMG_GLOBAL_DOOR].bitmap, drawto, + DOOR_GFX_PAGEX5 + x, y, MINI_TILEX, MINI_TILEY, DX + x,DY + y); + } } +#endif + void DrawAllGameValues(int emeralds, int dynamite, int score, int time, int key_bits) { @@ -1966,6 +2146,8 @@ void InitGame() for (j = 0; j < MAX_NUM_KEYS; j++) player->key[j] = FALSE; + player->num_white_keys = 0; + player->dynabomb_count = 0; player->dynabomb_size = 1; player->dynabombs_left = 0; @@ -3337,8 +3519,10 @@ void RemoveMovingField(int x, int y) if (element == EL_BLOCKED && (Feld[oldx][oldy] == EL_QUICKSAND_EMPTYING || + Feld[oldx][oldy] == EL_QUICKSAND_FAST_EMPTYING || Feld[oldx][oldy] == EL_MAGIC_WALL_EMPTYING || Feld[oldx][oldy] == EL_BD_MAGIC_WALL_EMPTYING || + Feld[oldx][oldy] == EL_DC_MAGIC_WALL_EMPTYING || Feld[oldx][oldy] == EL_AMOEBA_DROPPING)) next_element = get_next_element(Feld[oldx][oldy]); @@ -4617,6 +4801,16 @@ void Impact(int x, int y) object_hit = TRUE; } + + if (Feld[x][y + 1] == EL_QUICKSAND_FAST_EMPTYING && object_hit == FALSE) + { + RemoveMovingField(x, y + 1); + Feld[x][y + 1] = EL_QUICKSAND_FAST_EMPTY; + Feld[x][y + 2] = EL_ROCK; + DrawLevelField(x, y + 2); + + object_hit = TRUE; + } #endif if (object_hit) @@ -4645,7 +4839,8 @@ void Impact(int x, int y) Bang(x, y); return; } - else if (impact && element == EL_PEARL) + else if (impact && element == EL_PEARL && + smashed != EL_DC_MAGIC_WALL && smashed != EL_DC_MAGIC_WALL_ACTIVE) { ResetGfxAnimation(x, y); @@ -4678,26 +4873,33 @@ void Impact(int x, int y) if (object_hit) /* check which object was hit */ { - if (CAN_PASS_MAGIC_WALL(element) && - (smashed == EL_MAGIC_WALL || - smashed == EL_BD_MAGIC_WALL)) + if ((CAN_PASS_MAGIC_WALL(element) && + (smashed == EL_MAGIC_WALL || + smashed == EL_BD_MAGIC_WALL)) || + (CAN_PASS_DC_MAGIC_WALL(element) && + smashed == EL_DC_MAGIC_WALL)) { int xx, yy; int activated_magic_wall = (smashed == EL_MAGIC_WALL ? EL_MAGIC_WALL_ACTIVE : - EL_BD_MAGIC_WALL_ACTIVE); + smashed == EL_BD_MAGIC_WALL ? EL_BD_MAGIC_WALL_ACTIVE : + EL_DC_MAGIC_WALL_ACTIVE); /* activate magic wall / mill */ SCAN_PLAYFIELD(xx, yy) + { if (Feld[xx][yy] == smashed) Feld[xx][yy] = activated_magic_wall; + } game.magic_wall_time_left = level.time_magic_wall * FRAMES_PER_SECOND; game.magic_wall_active = TRUE; PlayLevelSound(x, y, (smashed == EL_MAGIC_WALL ? SND_MAGIC_WALL_ACTIVATING : - SND_BD_MAGIC_WALL_ACTIVATING)); + smashed == EL_BD_MAGIC_WALL ? + SND_BD_MAGIC_WALL_ACTIVATING : + SND_DC_MAGIC_WALL_ACTIVATING)); } if (IS_PLAYER(x, y + 1)) @@ -4812,12 +5014,15 @@ void Impact(int x, int y) /* play sound of magic wall / mill */ if (!last_line && (Feld[x][y + 1] == EL_MAGIC_WALL_ACTIVE || - Feld[x][y + 1] == EL_BD_MAGIC_WALL_ACTIVE)) + Feld[x][y + 1] == EL_BD_MAGIC_WALL_ACTIVE || + Feld[x][y + 1] == EL_DC_MAGIC_WALL_ACTIVE)) { if (Feld[x][y + 1] == EL_MAGIC_WALL_ACTIVE) PlayLevelSound(x, y, SND_MAGIC_WALL_FILLING); else if (Feld[x][y + 1] == EL_BD_MAGIC_WALL_ACTIVE) PlayLevelSound(x, y, SND_BD_MAGIC_WALL_FILLING); + else if (Feld[x][y + 1] == EL_DC_MAGIC_WALL_ACTIVE) + PlayLevelSound(x, y, SND_DC_MAGIC_WALL_FILLING); return; } @@ -5734,6 +5939,43 @@ void StartMoving(int x, int y) PlayLevelSoundAction(x, y, ACTION_FILLING); } } + else if (element == EL_QUICKSAND_FAST_FULL) + { + if (IS_FREE(x, y + 1)) + { + InitMovingField(x, y, MV_DOWN); + started_moving = TRUE; + + Feld[x][y] = EL_QUICKSAND_FAST_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); + } + else if (Feld[x][y + 1] == EL_QUICKSAND_FAST_EMPTY) + { + if (!MovDelay[x][y]) + MovDelay[x][y] = TILEY + 1; + + if (MovDelay[x][y]) + { + MovDelay[x][y]--; + if (MovDelay[x][y]) + return; + } + + Feld[x][y] = EL_QUICKSAND_FAST_EMPTY; + Feld[x][y + 1] = EL_QUICKSAND_FAST_FULL; + Store[x][y + 1] = Store[x][y]; + Store[x][y] = 0; + + PlayLevelSoundAction(x, y, ACTION_FILLING); + } + } else if ((element == EL_ROCK || element == EL_BD_ROCK) && Feld[x][y + 1] == EL_QUICKSAND_EMPTY) { @@ -5745,6 +5987,17 @@ void StartMoving(int x, int y) PlayLevelSoundAction(x, y, ACTION_FILLING); } + else if ((element == EL_ROCK || element == EL_BD_ROCK) && + Feld[x][y + 1] == EL_QUICKSAND_FAST_EMPTY) + { + InitMovingField(x, y, MV_DOWN); + started_moving = TRUE; + + Feld[x][y] = EL_QUICKSAND_FAST_FILLING; + Store[x][y] = element; + + PlayLevelSoundAction(x, y, ACTION_FILLING); + } else if (element == EL_MAGIC_WALL_FULL) { if (IS_FREE(x, y + 1)) @@ -5781,7 +6034,7 @@ void StartMoving(int x, int y) started_moving = TRUE; Feld[x][y] = EL_BD_MAGIC_WALL_EMPTYING; - Store[x][y] = EL_CHANGED2(Store[x][y]); + Store[x][y] = EL_CHANGED_BD(Store[x][y]); } else if (Feld[x][y + 1] == EL_BD_MAGIC_WALL_ACTIVE) { @@ -5797,20 +6050,52 @@ void StartMoving(int x, int y) Feld[x][y] = EL_BD_MAGIC_WALL_ACTIVE; Feld[x][y + 1] = EL_BD_MAGIC_WALL_FULL; - Store[x][y + 1] = EL_CHANGED2(Store[x][y]); + Store[x][y + 1] = EL_CHANGED_BD(Store[x][y]); + Store[x][y] = 0; + } + } + else if (element == EL_DC_MAGIC_WALL_FULL) + { + if (IS_FREE(x, y + 1)) + { + InitMovingField(x, y, MV_DOWN); + started_moving = TRUE; + + Feld[x][y] = EL_DC_MAGIC_WALL_EMPTYING; + Store[x][y] = EL_CHANGED_DC(Store[x][y]); + } + else if (Feld[x][y + 1] == EL_DC_MAGIC_WALL_ACTIVE) + { + if (!MovDelay[x][y]) + MovDelay[x][y] = TILEY/4 + 1; + + if (MovDelay[x][y]) + { + MovDelay[x][y]--; + if (MovDelay[x][y]) + return; + } + + Feld[x][y] = EL_DC_MAGIC_WALL_ACTIVE; + Feld[x][y + 1] = EL_DC_MAGIC_WALL_FULL; + Store[x][y + 1] = EL_CHANGED_DC(Store[x][y]); Store[x][y] = 0; } } - else if (CAN_PASS_MAGIC_WALL(element) && - (Feld[x][y + 1] == EL_MAGIC_WALL_ACTIVE || - Feld[x][y + 1] == EL_BD_MAGIC_WALL_ACTIVE)) + else if ((CAN_PASS_MAGIC_WALL(element) && + (Feld[x][y + 1] == EL_MAGIC_WALL_ACTIVE || + Feld[x][y + 1] == EL_BD_MAGIC_WALL_ACTIVE)) || + (CAN_PASS_DC_MAGIC_WALL(element) && + (Feld[x][y + 1] == EL_DC_MAGIC_WALL_ACTIVE))) + { InitMovingField(x, y, MV_DOWN); started_moving = TRUE; Feld[x][y] = (Feld[x][y + 1] == EL_MAGIC_WALL_ACTIVE ? EL_MAGIC_WALL_FILLING : - EL_BD_MAGIC_WALL_FILLING); + Feld[x][y + 1] == EL_BD_MAGIC_WALL_ACTIVE ? EL_BD_MAGIC_WALL_FILLING : + EL_DC_MAGIC_WALL_FILLING); Store[x][y] = element; } else if (CAN_FALL(element) && Feld[x][y + 1] == EL_ACID) @@ -6626,6 +6911,16 @@ void ContinueMoving(int x, int y) Feld[x][y] = get_next_element(element); element = Feld[newx][newy] = Store[x][y]; } + else if (element == EL_QUICKSAND_FAST_FILLING) + { + element = Feld[newx][newy] = get_next_element(element); + Store[newx][newy] = Store[x][y]; + } + else if (element == EL_QUICKSAND_FAST_EMPTYING) + { + Feld[x][y] = get_next_element(element); + element = Feld[newx][newy] = Store[x][y]; + } else if (element == EL_MAGIC_WALL_FILLING) { element = Feld[newx][newy] = get_next_element(element); @@ -6658,6 +6953,24 @@ void ContinueMoving(int x, int y) Feld[x][y] = EL_BD_MAGIC_WALL_DEAD; element = Feld[newx][newy] = Store[x][y]; +#if USE_NEW_CUSTOM_VALUE + InitField(newx, newy, FALSE); +#endif + } + else if (element == EL_DC_MAGIC_WALL_FILLING) + { + element = Feld[newx][newy] = get_next_element(element); + if (!game.magic_wall_active) + element = Feld[newx][newy] = EL_DC_MAGIC_WALL_DEAD; + Store[newx][newy] = Store[x][y]; + } + else if (element == EL_DC_MAGIC_WALL_EMPTYING) + { + Feld[x][y] = get_next_element(element); + if (!game.magic_wall_active) + Feld[x][y] = EL_DC_MAGIC_WALL_DEAD; + element = Feld[newx][newy] = Store[x][y]; + #if USE_NEW_CUSTOM_VALUE InitField(newx, newy, FALSE); #endif @@ -7161,7 +7474,8 @@ void AmoebeAbleger(int ax, int ay) if (IS_FREE(x, y) || CAN_GROW_INTO(Feld[x][y]) || - Feld[x][y] == EL_QUICKSAND_EMPTY) + Feld[x][y] == EL_QUICKSAND_EMPTY || + Feld[x][y] == EL_QUICKSAND_FAST_EMPTY) { newax = x; neway = y; @@ -7186,7 +7500,8 @@ void AmoebeAbleger(int ax, int ay) if (IS_FREE(x, y) || CAN_GROW_INTO(Feld[x][y]) || - Feld[x][y] == EL_QUICKSAND_EMPTY) + Feld[x][y] == EL_QUICKSAND_EMPTY || + Feld[x][y] == EL_QUICKSAND_FAST_EMPTY) { newax = x; neway = y; @@ -10009,7 +10324,10 @@ void GameActions_RND() element == EL_MAGIC_WALL_EMPTYING || element == EL_BD_MAGIC_WALL_FULL || element == EL_BD_MAGIC_WALL_ACTIVE || - element == EL_BD_MAGIC_WALL_EMPTYING) && + element == EL_BD_MAGIC_WALL_EMPTYING || + element == EL_DC_MAGIC_WALL_FULL || + element == EL_DC_MAGIC_WALL_ACTIVE || + element == EL_DC_MAGIC_WALL_EMPTYING) && ABS(x-jx) + ABS(y-jy) < ABS(magic_wall_x-jx) + ABS(magic_wall_y-jy)) { magic_wall_x = x; @@ -10034,6 +10352,7 @@ void GameActions_RND() (element == EL_EMPTY || CAN_GROW_INTO(element) || element == EL_QUICKSAND_EMPTY || + element == EL_QUICKSAND_FAST_EMPTY || element == EL_ACID_SPLASH_LEFT || element == EL_ACID_SPLASH_RIGHT)) { @@ -10080,6 +10399,10 @@ void GameActions_RND() element == EL_BD_MAGIC_WALL_ACTIVE || element == EL_BD_MAGIC_WALL_EMPTYING) PlayLevelSound(magic_wall_x, magic_wall_y, SND_BD_MAGIC_WALL_ACTIVE); + else if (element == EL_DC_MAGIC_WALL_FULL || + element == EL_DC_MAGIC_WALL_ACTIVE || + element == EL_DC_MAGIC_WALL_EMPTYING) + PlayLevelSound(magic_wall_x, magic_wall_y, SND_DC_MAGIC_WALL_ACTIVE); else PlayLevelSound(magic_wall_x, magic_wall_y, SND_MAGIC_WALL_ACTIVE); } @@ -10105,6 +10428,12 @@ void GameActions_RND() Feld[x][y] = EL_BD_MAGIC_WALL_DEAD; DrawLevelField(x, y); } + else if (element == EL_DC_MAGIC_WALL_ACTIVE || + element == EL_DC_MAGIC_WALL_FULL) + { + Feld[x][y] = EL_DC_MAGIC_WALL_DEAD; + DrawLevelField(x, y); + } } game.magic_wall_active = FALSE; @@ -10239,13 +10568,30 @@ void ScrollLevel(int dx, int dy) int softscroll_offset = (setup.soft_scrolling ? TILEX : 0); int x, y; +#if 1 + BlitBitmap(drawto_field, bitmap_db_field2, + FX + TILEX * (dx == -1) - softscroll_offset, + FY + TILEY * (dy == -1) - softscroll_offset, + SXSIZE - TILEX * (dx != 0) + 2 * softscroll_offset, + SYSIZE - TILEY * (dy != 0) + 2 * softscroll_offset, + FX + TILEX * (dx == 1) - softscroll_offset, + FY + TILEY * (dy == 1) - softscroll_offset); + BlitBitmap(bitmap_db_field2, drawto_field, + FX + TILEX * (dx == 1) - softscroll_offset, + FY + TILEY * (dy == 1) - softscroll_offset, + SXSIZE - TILEX * (dx != 0) + 2 * softscroll_offset, + SYSIZE - TILEY * (dy != 0) + 2 * softscroll_offset, + FX + TILEX * (dx == 1) - softscroll_offset, + FY + TILEY * (dy == 1) - softscroll_offset); +#else BlitBitmap(drawto_field, drawto_field, FX + TILEX * (dx == -1) - softscroll_offset, FY + TILEY * (dy == -1) - softscroll_offset, - SXSIZE - TILEX * (dx!=0) + 2 * softscroll_offset, - SYSIZE - TILEY * (dy!=0) + 2 * softscroll_offset, + SXSIZE - TILEX * (dx != 0) + 2 * softscroll_offset, + SYSIZE - TILEY * (dy != 0) + 2 * softscroll_offset, FX + TILEX * (dx == 1) - softscroll_offset, FY + TILEY * (dy == 1) - softscroll_offset); +#endif if (dx) { @@ -11822,6 +12168,15 @@ int DigField(struct PlayerInfo *player, if (!player->key[EMC_GATE_GRAY_ACTIVE_NR(element)]) return MP_NO_ACTION; } + else if (element == EL_DC_GATE_WHITE || + element == EL_DC_GATE_WHITE_GRAY || + element == EL_DC_GATE_WHITE_GRAY_ACTIVE) + { + if (player->num_white_keys == 0) + return MP_NO_ACTION; + + player->num_white_keys--; + } else if (IS_SP_PORT(element)) { if (element == EL_SP_GRAVITY_PORT_LEFT || @@ -11948,6 +12303,13 @@ int DigField(struct PlayerInfo *player, DrawGameDoorValues(); } + else if (element == EL_DC_KEY_WHITE) + { + player->num_white_keys++; + + /* display white keys? */ + /* DrawGameDoorValues(); */ + } else if (IS_ENVELOPE(element)) { player->show_envelope = element; @@ -12924,6 +13286,7 @@ void RaiseScoreElement(int element) case EL_EMC_KEY_6: case EL_EMC_KEY_7: case EL_EMC_KEY_8: + case EL_DC_KEY_WHITE: RaiseScore(level.score[SC_KEY]); break; default: