X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Fgame.c;h=ff6d5568c52d451c6eb176296b52bd45851815db;hb=8e5671db64b55432158b1d43d7fd2e684544ebeb;hp=0f2aff310c07a1e89555c6d5fa9be3a317eb6a66;hpb=7a821f79cb735d048869b503279c402800afa44a;p=rocksndiamonds.git diff --git a/src/game.c b/src/game.c index 0f2aff31..ff6d5568 100644 --- a/src/game.c +++ b/src/game.c @@ -868,7 +868,7 @@ static void InitGameEngine() if (!ei->change_page->can_change) continue; - if (ei->change_page[j].events & CH_EVENT_BIT(CE_BY_OTHER)) + if (ei->change_page[j].events & CH_EVENT_BIT(CE_BY_OTHER_ACTION)) { int trigger_element = ei->change_page[j].trigger_element; @@ -879,7 +879,7 @@ static void InitGameEngine() #else /* add trigger events from element change event properties */ for (i=0; itrigger_element] |= element_info[i].change->events; #endif @@ -1090,7 +1090,7 @@ void InitGame() JustStopped[x][y] = 0; Stop[x][y] = FALSE; Pushed[x][y] = FALSE; - Changing[x][y] = FALSE; + Changed[x][y] = FALSE; ExplodePhase[x][y] = 0; ExplodeField[x][y] = EX_NO_EXPLOSION; @@ -1989,6 +1989,165 @@ void CheckDynamite(int x, int y) Bang(x, y); } +void ShowEnvelope() +{ + int graphic = IMG_GAME_ENVELOPE_BACKGROUND; + boolean draw_masked = graphic_info[graphic].draw_masked; + int mask_mode = (draw_masked ? BLIT_MASKED : BLIT_ON_BACKGROUND); + int font_nr = FONT_TEXT_1; + int font_width = getFontWidth(font_nr); + int font_height = getFontHeight(font_nr); + int i, x, y; + + /* open envelope window horizontally */ + for (i = 2; i <= level.envelope_xsize + 2; i += 2) + { + int startx = (SXSIZE / font_width - i) / 2; + int starty = (SYSIZE / font_height) / 2 - 1; + + SetDrawtoField(DRAW_BUFFERED); + + BlitBitmap(fieldbuffer, backbuffer, FX, FY, SXSIZE, SYSIZE, SX, SY); + + SetDrawtoField(DRAW_BACKBUFFER); + + for (y=0; y < 2; y++) for (x=0; x < i; x++) + { + int sx = SX + (startx + x) * font_width; + int sy = SY + (starty + y) * font_height; + int ex = (x == 0 ? -1 : x == i - 1 ? +1 : 0); + int ey = (y == 0 ? -1 : y == 1 ? +1 : 0); + + DrawEnvelopeBackground(sx, sy, ex, ey, font_nr); + } + + redraw_mask |= REDRAW_FIELD | REDRAW_FROM_BACKBUFFER; + BackToFront(); + + Delay(GAME_FRAME_DELAY); + + /* special case: envelope has odd width */ + if (level.envelope_xsize % 2 && i == 2) + i--; + } + + /* open envelope window vertically */ + for (i = 2; i <= level.envelope_ysize + 2; i += 2) + { + int xsize = level.envelope_xsize + 2; + int startx = (SXSIZE / font_width - (xsize - 1)) / 2; + int starty = (SYSIZE / font_height - i) / 2; + + SetDrawtoField(DRAW_BUFFERED); + + BlitBitmap(fieldbuffer, backbuffer, FX, FY, SXSIZE, SYSIZE, SX, SY); + + SetDrawtoField(DRAW_BACKBUFFER); + + for (y=0; y < i; y++) for (x=0; x < xsize; x++) + { + int sx = SX + (startx + x) * font_width; + int sy = SY + (starty + y) * font_height; + int ex = (x == 0 ? -1 : x == xsize - 1 ? +1 : 0); + int ey = (y == 0 ? -1 : y == i - 1 ? +1 : 0); + + DrawEnvelopeBackground(sx, sy, ex, ey, font_nr); + } + + DrawTextToTextArea(SX + (startx + 1) * font_width, + SY + (starty + 1) * font_height, level.envelope, + FONT_TEXT_1, level.envelope_xsize, i - 2, mask_mode); + + redraw_mask |= REDRAW_FIELD | REDRAW_FROM_BACKBUFFER; + BackToFront(); + + Delay(GAME_FRAME_DELAY); + + /* special case: envelope has odd height */ + if (level.envelope_ysize % 2 && i == 2) + i--; + } + + if (tape.playing) + Delay(1000); + else + WaitForEventToContinue(); + + /* close envelope window vertically */ + for (i = level.envelope_ysize + 2; i >= 2; i -= 2) + { + int xsize = level.envelope_xsize + 2; + int startx = (SXSIZE / font_width - (xsize - 1)) / 2; + int starty = (SYSIZE / font_height - i) / 2; + + SetDrawtoField(DRAW_BUFFERED); + + BlitBitmap(fieldbuffer, backbuffer, FX, FY, SXSIZE, SYSIZE, SX, SY); + + SetDrawtoField(DRAW_BACKBUFFER); + + for (y=0; y < i; y++) for (x=0; x < xsize; x++) + { + int sx = SX + (startx + x) * font_width; + int sy = SY + (starty + y) * font_height; + int ex = (x == 0 ? -1 : x == xsize - 1 ? +1 : 0); + int ey = (y == 0 ? -1 : y == i - 1 ? +1 : 0); + + DrawEnvelopeBackground(sx, sy, ex, ey, font_nr); + } + + DrawTextToTextArea(SX + (startx + 1) * font_width, + SY + (starty + 1) * font_height, level.envelope, + FONT_TEXT_1, level.envelope_xsize, i - 2, mask_mode); + + redraw_mask |= REDRAW_FIELD | REDRAW_FROM_BACKBUFFER; + BackToFront(); + + Delay(GAME_FRAME_DELAY); + + /* special case: envelope has odd height */ + if (level.envelope_ysize % 2 && i == level.envelope_ysize + 2) + i++; + } + + /* close envelope window horizontally */ + for (i = level.envelope_xsize + 2; i >= 2; i -= 2) + { + int startx = (SXSIZE / font_width - i) / 2; + int starty = (SYSIZE / font_height) / 2 - 1; + + SetDrawtoField(DRAW_BUFFERED); + + BlitBitmap(fieldbuffer, backbuffer, FX, FY, SXSIZE, SYSIZE, SX, SY); + + SetDrawtoField(DRAW_BACKBUFFER); + + for (y=0; y < 2; y++) for (x=0; x < i; x++) + { + int sx = SX + (startx + x) * font_width; + int sy = SY + (starty + y) * font_height; + int ex = (x == 0 ? -1 : x == i - 1 ? +1 : 0); + int ey = (y == 0 ? -1 : y == 1 ? +1 : 0); + + DrawEnvelopeBackground(sx, sy, ex, ey, font_nr); + } + + redraw_mask |= REDRAW_FIELD | REDRAW_FROM_BACKBUFFER; + BackToFront(); + + Delay(GAME_FRAME_DELAY); + + /* special case: envelope has odd width */ + if (level.envelope_xsize % 2 && i == level.envelope_xsize + 2) + i++; + } + + SetDrawtoField(DRAW_BUFFERED); + + redraw_mask |= REDRAW_FIELD; + BackToFront(); +} + void RelocatePlayer(int x, int y, int element) { struct PlayerInfo *player = &stored_player[element - EL_PLAYER_1]; @@ -5337,6 +5496,8 @@ static void ChangeElementNowExt(int x, int y, int target_element) RemoveField(x, y); Feld[x][y] = target_element; + Changed[x][y] = TRUE; /* no more changes in this frame */ + ResetGfxAnimation(x, y); ResetRandomAnimationValue(x, y); @@ -5361,6 +5522,8 @@ static void ChangeElementNow(int x, int y, int element, int page) { struct ElementChangeInfo *change = &element_info[element].change_page[page]; + Changed[x][y] = TRUE; /* no more changes in this frame */ + CheckTriggeredElementChange(x, y, Feld[x][y], CE_OTHER_IS_CHANGING); if (change->explode) @@ -5441,9 +5604,9 @@ static void ChangeElementNow(int x, int y, int element, int page) something_has_changed = TRUE; - /* for symmetry reasons, stop newly created border elements */ + /* for symmetry reasons, freeze newly created border elements */ if (ex != x || ey != y) - Stop[ex][ey] = TRUE; + Stop[ex][ey] = TRUE; /* no more moving in this frame */ } } @@ -5512,9 +5675,11 @@ static boolean CheckTriggeredElementChange(int lx, int ly, int trigger_element, if (!(trigger_events[trigger_element] & CH_EVENT_BIT(trigger_event))) return FALSE; +#if 0 /* prevent this function from running into a loop */ if (trigger_event == CE_OTHER_IS_CHANGING) - Changing[lx][ly] = TRUE; + Changed[lx][ly] = TRUE; +#endif for (i=0; i < NUM_CUSTOM_ELEMENTS; i++) { @@ -5555,7 +5720,7 @@ static boolean CheckTriggeredElementChange(int lx, int ly, int trigger_element, if (x == lx && y == ly) /* do not change trigger element itself */ continue; - if (Changing[x][y]) /* do not change just changing elements */ + if (Changed[x][y]) /* do not change already changed elements */ continue; if (Feld[x][y] == element) @@ -5563,14 +5728,18 @@ static boolean CheckTriggeredElementChange(int lx, int ly, int trigger_element, ChangeDelay[x][y] = 1; ChangeElement(x, y, page); - Changing[x][y] = TRUE; /* do not change just changed elements */ +#if 0 + Changed[x][y] = TRUE; /* prevent element from being changed again */ +#endif } } } +#if 0 /* reset change prevention array */ for (y=0; y 0) JustStopped[x][y]--; @@ -5792,7 +5963,7 @@ void GameActions() #if 1 /* reset finished pushing action (not done in ContinueMoving() to allow - continous pushing animation for elements without push delay) */ + continous pushing animation for elements with zero push delay) */ if (GfxAction[x][y] == ACTION_PUSHING && !IS_MOVING(x, y)) { ResetGfxAnimation(x, y); @@ -6648,7 +6819,9 @@ void ScrollScreen(struct PlayerInfo *player, int mode) void TestIfPlayerTouchesCustomElement(int x, int y) { +#if 0 static boolean check_changing = FALSE; +#endif static int xy[4][2] = { { 0, -1 }, @@ -6658,10 +6831,12 @@ void TestIfPlayerTouchesCustomElement(int x, int y) }; int i; +#if 0 if (check_changing) /* prevent this function from running into a loop */ return; check_changing = TRUE; +#endif for (i=0; i<4; i++) { @@ -6685,12 +6860,16 @@ void TestIfPlayerTouchesCustomElement(int x, int y) } } +#if 0 check_changing = FALSE; +#endif } void TestIfElementTouchesCustomElement(int x, int y) { +#if 0 static boolean check_changing = FALSE; +#endif static int xy[4][2] = { { 0, -1 }, @@ -6703,10 +6882,12 @@ void TestIfElementTouchesCustomElement(int x, int y) int center_element = Feld[x][y]; int i, j; +#if 0 if (check_changing) /* prevent this function from running into a loop */ return; check_changing = TRUE; +#endif for (i=0; i<4; i++) { @@ -6721,7 +6902,7 @@ void TestIfElementTouchesCustomElement(int x, int y) /* check for change of center element (but change it only once) */ if (IS_CUSTOM_ELEMENT(center_element) && - element_info[center_element].change_events & CE_OTHER_IS_TOUCHING && + HAS_ANY_CHANGE_EVENT(center_element, CE_OTHER_IS_TOUCHING) && !change_center_element) { for (j=0; j < element_info[center_element].num_change_pages; j++) @@ -6729,7 +6910,7 @@ void TestIfElementTouchesCustomElement(int x, int y) struct ElementChangeInfo *change = &element_info[center_element].change_page[j]; - if (change->events & CE_OTHER_IS_TOUCHING && + if (change->events & CH_EVENT_BIT(CE_OTHER_IS_TOUCHING) && change->trigger_element == border_element) { change_center_element = TRUE; @@ -6742,14 +6923,14 @@ void TestIfElementTouchesCustomElement(int x, int y) /* check for change of border element */ if (IS_CUSTOM_ELEMENT(border_element) && - element_info[border_element].change_events & CE_OTHER_IS_TOUCHING) + HAS_ANY_CHANGE_EVENT(border_element, CE_OTHER_IS_TOUCHING)) { for (j=0; j < element_info[border_element].num_change_pages; j++) { struct ElementChangeInfo *change = &element_info[border_element].change_page[j]; - if (change->events & CE_OTHER_IS_TOUCHING && + if (change->events & CH_EVENT_BIT(CE_OTHER_IS_TOUCHING) && change->trigger_element == center_element) { CheckElementChangeExt(xx,yy, border_element,CE_OTHER_IS_TOUCHING, j); @@ -6763,7 +6944,9 @@ void TestIfElementTouchesCustomElement(int x, int y) CheckElementChangeExt(x, y, center_element, CE_OTHER_IS_TOUCHING, center_element_change_page); +#if 0 check_changing = FALSE; +#endif } void TestIfGoodThingHitsBadThing(int good_x, int good_y, int good_move_dir) @@ -7451,6 +7634,10 @@ int DigField(struct PlayerInfo *player, PlaySoundLevelElementAction(x, y, element, ACTION_DIGGING); + CheckTriggeredElementChange(x, y, element, CE_OTHER_GETS_DIGGED); + + TestIfElementTouchesCustomElement(x, y); + break; } else if (IS_COLLECTIBLE(element)) @@ -7511,6 +7698,10 @@ int DigField(struct PlayerInfo *player, el2edimg(EL_KEY_1 + key_nr)); redraw_mask |= REDRAW_DOOR_1; } + else if (element == EL_ENVELOPE) + { + ShowEnvelope(); + } else if (IS_DROPPABLE(element)) /* can be collected and dropped */ { int i; @@ -7538,6 +7729,8 @@ int DigField(struct PlayerInfo *player, CheckTriggeredElementChange(x, y, element, CE_OTHER_GETS_COLLECTED); + TestIfElementTouchesCustomElement(x, y); + break; } else if (IS_PUSHABLE(element)) @@ -7776,6 +7969,8 @@ boolean DropElement(struct PlayerInfo *player) CheckTriggeredElementChange(jx, jy, new_element, CE_OTHER_GETS_DROPPED); CheckElementChange(jx, jy, new_element, CE_DROPPED_BY_PLAYER); + + TestIfElementTouchesCustomElement(jx, jy); } else /* player is dropping a dyna bomb */ {