X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Fgame.c;h=750c70a91e01a7ddfaeb6f63bf296c168b6bc7e9;hb=9a1ccc76e3542f3974103e505b27fc1879f0f777;hp=0f2aff310c07a1e89555c6d5fa9be3a317eb6a66;hpb=10b9382e55f3a8cd0a15644cf1ed6e1451654a76;p=rocksndiamonds.git diff --git a/src/game.c b/src/game.c index 0f2aff31..750c70a9 100644 --- a/src/game.c +++ b/src/game.c @@ -753,11 +753,11 @@ static void InitGameEngine() InitElementPropertiesEngine(game.engine_version); #if 0 - printf("level %d: level version == %06d\n", level_nr, level.game_version); - printf(" tape version == %06d [%s] [file: %06d]\n", - tape.engine_version, (tape.playing ? "PLAYING" : "RECORDING"), - tape.file_version); - printf(" => game.engine_version == %06d\n", game.engine_version); + printf("level %d: level version == %06d\n", level_nr, level.game_version); + printf(" tape version == %06d [%s] [file: %06d]\n", + tape.engine_version, (tape.playing ? "PLAYING" : "RECORDING"), + tape.file_version); + printf(" => game.engine_version == %06d\n", game.engine_version); #endif /* ---------- initialize player's initial move delay --------------------- */ @@ -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; @@ -1581,8 +1581,13 @@ void GameWon() if (local_player->MovPos) return; +#if 1 + if (tape.auto_play) /* tape might already be stopped here */ + tape.auto_play_level_solved = TRUE; +#else if (tape.playing && tape.auto_play) tape.auto_play_level_solved = TRUE; +#endif local_player->LevelSolved = FALSE; @@ -2280,6 +2285,22 @@ void Explode(int ex, int ey, int phase, int mode) ExplodePhase[x][y] = (phase < last_phase ? phase + 1 : 0); +#ifdef DEBUG + + /* activate this even in non-DEBUG version until cause for crash in + getGraphicAnimationFrame() (see below) is found and eliminated */ +#endif +#if 1 + + if (GfxElement[x][y] == EL_UNDEFINED) + { + printf("Explode(): x = %d, y = %d: GfxElement == EL_UNDEFINED\n", x, y); + printf("Explode(): This should never happen!\n"); + + GfxElement[x][y] = EL_EMPTY; + } +#endif + if (phase == first_phase_after_start) { int element = Store2[x][y]; @@ -5337,6 +5358,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); @@ -5357,16 +5380,22 @@ static void ChangeElementNowExt(int x, int y, int target_element) RelocatePlayer(x, y, target_element); } -static void ChangeElementNow(int x, int y, int element, int page) +static boolean ChangeElementNow(int x, int y, int element, int page) { struct ElementChangeInfo *change = &element_info[element].change_page[page]; + if (Changed[x][y]) /* do not change already changed elements */ + return FALSE; + + Changed[x][y] = TRUE; /* no more changes in this frame */ + CheckTriggeredElementChange(x, y, Feld[x][y], CE_OTHER_IS_CHANGING); if (change->explode) { Bang(x, y); - return; + + return TRUE; } if (change->use_content) @@ -5424,7 +5453,7 @@ static void ChangeElementNow(int x, int y, int element, int page) if (change->only_complete && change->use_random_change && RND(100) < change->random) - return; + return FALSE; for (yy = 0; yy < 3; yy++) for(xx = 0; xx < 3 ; xx++) { @@ -5441,9 +5470,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 */ } } @@ -5457,6 +5486,8 @@ static void ChangeElementNow(int x, int y, int element, int page) PlaySoundLevelElementAction(x, y, element, ACTION_CHANGING); } + + return TRUE; } static void ChangeElement(int x, int y, int page) @@ -5497,10 +5528,11 @@ static void ChangeElement(int x, int y, int page) return; } - ChangeElementNow(x, y, element, page); - - if (change->post_change_function) - change->post_change_function(x, y); + if (ChangeElementNow(x, y, element, page)) + { + if (change->post_change_function) + change->post_change_function(x, y); + } } } @@ -5512,9 +5544,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,22 +5589,28 @@ 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 0 + if (Changed[x][y]) /* do not change already changed elements */ continue; +#endif if (Feld[x][y] == 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 +5834,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 +6690,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 +6702,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 +6731,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 +6753,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 +6773,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 +6781,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 +6794,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 +6815,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 +7505,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 +7569,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 +7600,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 +7840,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 */ {