X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Fgame.c;h=5f3f9689f3cdbd505d7c56a5e3533afdb358337e;hb=29fc833ae1b5e46a429a9fa82098e8ad94f6f400;hp=7f239043076b8a3eaceabd78469b603bd4e92a37;hpb=3378979a81f39e4a4082d208bf288492d87f5cd1;p=rocksndiamonds.git diff --git a/src/game.c b/src/game.c index 7f239043..5f3f9689 100644 --- a/src/game.c +++ b/src/game.c @@ -102,7 +102,9 @@ #define NUM_GAME_BUTTONS 6 /* forward declaration for internal use */ +#if 0 static void ResetGfxAnimation(int, int); +#endif static void InitBeltMovement(void); static void CloseAllOpenTimegates(void); @@ -1254,21 +1256,31 @@ int NewHiScore() static void ResetRandomAnimationValue(int x, int y) { + GfxRandom[x][y] = INIT_GFX_RANDOM(); +} + +static void ResetGfxAnimation(int x, int y) +{ +#if 0 +#if 1 int element = Feld[x][y]; int graphic = el2img(element); - /* reset random value not until one full delay cycle has reached */ + /* reset random value not until one full delay cycle was reached */ if (ANIM_MODE(graphic) == ANIM_RANDOM && GfxFrame[x][y] > ANIM_DELAY(graphic)) - GfxRandom[x][y] = INIT_GFX_RANDOM(); -} - -static void ResetGfxAnimation(int x, int y) -{ - ResetRandomAnimationValue(x, y); +#endif + ResetRandomAnimationValue(x, y); +#endif GfxFrame[x][y] = 0; GfxAction[x][y] = ACTION_DEFAULT; + +#if 0 + if (Feld[x][y] == EL_ROCK) + printf("ResetGfxAnimation: EL_ROCK [%d, %d]\n", + JustStopped[x][y], MovDir[x][y]); +#endif } void InitMovingField(int x, int y, int direction) @@ -1280,8 +1292,7 @@ void InitMovingField(int x, int y, int direction) if (!JustStopped[x][y] || direction != MovDir[x][y]) ResetGfxAnimation(x, y); - MovDir[x][y] = direction; - MovDir[newx][newy] = direction; + MovDir[newx][newy] = MovDir[x][y] = direction; if (Feld[newx][newy] == EL_EMPTY) Feld[newx][newy] = EL_BLOCKED; @@ -1290,6 +1301,10 @@ void InitMovingField(int x, int y, int direction) GfxAction[x][y] = ACTION_FALLING; else GfxAction[x][y] = ACTION_MOVING; + + GfxFrame[newx][newy] = GfxFrame[x][y]; + GfxAction[newx][newy] = GfxAction[x][y]; + GfxRandom[newx][newy] = GfxRandom[x][y]; } void Moving2Blocked(int x, int y, int *goes_to_x, int *goes_to_y) @@ -1430,21 +1445,15 @@ void DrawDynamite(int x, int y) void CheckDynamite(int x, int y) { -#if 0 - int element = Feld[x][y]; -#endif - if (MovDelay[x][y] != 0) /* dynamite is still waiting to explode */ { MovDelay[x][y]--; if (MovDelay[x][y] != 0) { -#if 0 - if (checkDrawLevelGraphicAnimation(x, y, el2img(element))) -#endif - DrawDynamite(x, y); + DrawDynamite(x, y); + /* !!! correct: "PlaySoundLevelActionIfLoop" etc. !!! */ PlaySoundLevelAction(x, y, ACTION_ACTIVE); return; @@ -2138,8 +2147,8 @@ void Impact(int x, int y) return; object_hit = (!IS_FREE(x, y+1) && (!IS_MOVING(x, y+1) || - MovDir[x][y+1]!=MV_DOWN || - MovPos[x][y+1]<=TILEY/2)); + MovDir[x][y+1] != MV_DOWN || + MovPos[x][y+1] <= TILEY / 2)); if (object_hit) smashed = MovingOrBlocked2Element(x, y+1); } @@ -2150,6 +2159,17 @@ void Impact(int x, int y) return; } +#if 1 + if (lastline || object_hit) + { +#if 0 + MovDir[x][y] = 0; +#endif + ResetGfxAnimation(x, y); + DrawLevelField(x, y); + } +#endif + if ((element == EL_BOMB || element == EL_SP_DISK_ORANGE || element == EL_DX_SUPABOMB) && @@ -2175,6 +2195,8 @@ void Impact(int x, int y) { Feld[x][y] = EL_AMOEBA_CREATING; Store[x][y] = EL_AMOEBA_WET; + + ResetRandomAnimationValue(x, y); } return; } @@ -2878,7 +2900,11 @@ void StartMoving(int x, int y) EL_BD_MAGIC_WALL_FILLING); Store[x][y] = element; } +#if 0 else if (CAN_SMASH(element) && Feld[x][y+1] == EL_ACID) +#else + else if (CAN_FALL(element) && Feld[x][y+1] == EL_ACID) +#endif { SplashAcid(x, y); @@ -2902,6 +2928,9 @@ void StartMoving(int x, int y) } else if (IS_FREE(x, y+1)) { + if (JustStopped[x][y]) /* prevent animation from being restarted */ + MovDir[x][y] = MV_DOWN; + InitMovingField(x, y, MV_DOWN); started_moving = TRUE; } @@ -3023,7 +3052,7 @@ void StartMoving(int x, int y) element == EL_DARK_YAMYAM) { #if 1 - ContinueLevelElementAnimation(x, y, element); + DrawLevelElementAnimationIfNeeded(x, y, element); #else if (IN_SCR_FIELD(SCREENX(x), SCREENY(y))) { @@ -3047,7 +3076,7 @@ void StartMoving(int x, int y) #endif } else if (element == EL_SP_ELECTRON) - ContinueLevelElementAnimation(x, y, element); + DrawLevelElementAnimationIfNeeded(x, y, element); else if (element == EL_DRAGON) { int i; @@ -3305,11 +3334,11 @@ void StartMoving(int x, int y) element == EL_SP_SNIKSNAK || element == EL_MOLE) DrawLevelField(x, y); else if (element == EL_BD_BUTTERFLY || element == EL_BD_FIREFLY) - ContinueLevelElementAnimation(x, y, element); + DrawLevelElementAnimationIfNeeded(x, y, element); else if (element == EL_SATELLITE) - ContinueLevelElementAnimation(x, y, element); + DrawLevelElementAnimationIfNeeded(x, y, element); else if (element == EL_SP_ELECTRON) - ContinueLevelElementAnimation(x, y, element); + DrawLevelElementAnimationIfNeeded(x, y, element); if (DONT_TOUCH(element)) TestIfBadThingTouchesHero(x, y); @@ -3444,10 +3473,20 @@ void ContinueMoving(int x, int y) MovPos[x][y] = MovDir[x][y] = MovDelay[x][y] = 0; MovDelay[newx][newy] = 0; +#if 0 + /* all done in "InitMovingField()" */ GfxAction[newx][newy] = GfxAction[x][y]; /* keep action one frame */ GfxRandom[newx][newy] = GfxRandom[x][y]; /* keep same random value */ - GfxAction[x][y] = ACTION_DEFAULT; +#endif + /* copy animation control values to new field */ + GfxFrame[newx][newy] = GfxFrame[x][y]; + GfxAction[newx][newy] = GfxAction[x][y]; + GfxRandom[newx][newy] = GfxRandom[x][y]; + + ResetGfxAnimation(x, y); /* reset animation values for old field */ + +#if 1 #if 0 if (!CAN_MOVE(element)) MovDir[newx][newy] = 0; @@ -3460,6 +3499,7 @@ void ContinueMoving(int x, int y) if (!CAN_MOVE(element) || (element == EL_SPRING && MovDir[newx][newy] == MV_DOWN)) MovDir[newx][newy] = 0; +#endif #endif DrawLevelField(x, y); @@ -3994,13 +4034,6 @@ static void RunTimegateWheel(int x, int y) PlaySoundLevel(x, y, SND_TIMEGATE_SWITCH_ACTIVE); } -void SiebAktivieren(int x, int y, int type) -{ - int graphic = (type == 1 ? IMG_MAGIC_WALL_FULL : IMG_BD_MAGIC_WALL_FULL); - - ContinueLevelGraphicAnimation(x, y, graphic); -} - void CheckExit(int x, int y) { if (local_player->gems_still_needed > 0 || @@ -4345,10 +4378,9 @@ static void ChangeActiveTrap(int x, int y) { int graphic = IMG_TRAP_ACTIVE; - /* if animation frame already drawn, correct crumbled sand border */ - if (IS_ANIMATED(graphic)) - if (checkDrawLevelGraphicAnimation(x, y, graphic)) - DrawCrumbledSand(SCREENX(x), SCREENY(y)); + /* if new animation frame was drawn, correct crumbled sand border */ + if (IS_NEW_FRAME(GfxFrame[x][y], graphic)) + DrawCrumbledSand(SCREENX(x), SCREENY(y)); } static void ChangeElement(int x, int y) @@ -4360,6 +4392,7 @@ static void ChangeElement(int x, int y) MovDelay[x][y] = changing_element[element].change_delay + 1; ResetGfxAnimation(x, y); + ResetRandomAnimationValue(x, y); if (changing_element[element].pre_change_function) changing_element[element].pre_change_function(x, y); @@ -4370,7 +4403,7 @@ static void ChangeElement(int x, int y) if (MovDelay[x][y] != 0) /* continue element change */ { if (IS_ANIMATED(el2img(element))) - ContinueLevelElementAnimation(x, y, element); + DrawLevelElementAnimationIfNeeded(x, y, element); if (changing_element[element].change_function) changing_element[element].change_function(x, y); @@ -4380,6 +4413,7 @@ static void ChangeElement(int x, int y) Feld[x][y] = changing_element[element].next_element; ResetGfxAnimation(x, y); + ResetRandomAnimationValue(x, y); DrawLevelField(x, y); @@ -4533,7 +4567,7 @@ void GameActions() { static unsigned long action_delay = 0; unsigned long action_delay_value; - int sieb_x = 0, sieb_y = 0; + int magic_wall_x = 0, magic_wall_y = 0; int i, x, y, element, graphic; byte *recorded_player_action; byte summarized_player_action = 0; @@ -4671,8 +4705,13 @@ void GameActions() element = Feld[x][y]; graphic = el2img(element); +#if 1 + if (graphic_info[graphic].anim_global_sync) + GfxFrame[x][y] = FrameCounter; +#endif + if (ANIM_MODE(graphic) == ANIM_RANDOM && - IS_NEW_FRAME(GfxFrame[x][y], graphic)) + IS_NEXT_FRAME(GfxFrame[x][y], graphic)) ResetRandomAnimationValue(x, y); SetRandomAnimationValue(x, y); @@ -4682,7 +4721,7 @@ void GameActions() #if 1 if (IS_ANIMATED(graphic)) - ContinueLevelGraphicAnimation(x, y, graphic); + DrawLevelGraphicAnimationIfNeeded(x, y, graphic); #endif continue; @@ -4692,18 +4731,10 @@ void GameActions() { StartMoving(x, y); -#if 1 -#if 0 - if (Feld[x][y] == EL_EMERALD && - IS_ANIMATED(graphic) && - !IS_MOVING(x, y)) - ContinueLevelGraphicAnimation(x, y, graphic); -#else if (IS_ANIMATED(graphic) && - !IS_MOVING(x, y)) - ContinueLevelGraphicAnimation(x, y, graphic); -#endif -#endif + !IS_MOVING(x, y) && + !Stop[x][y]) + DrawLevelGraphicAnimationIfNeeded(x, y, graphic); if (IS_GEM(element) || element == EL_SP_INFOTRON) EdelsteinFunkeln(x, y); @@ -4719,7 +4750,7 @@ void GameActions() element == EL_SHIELD_NORMAL || element == EL_SHIELD_DEADLY) && IS_ANIMATED(graphic)) - ContinueLevelGraphicAnimation(x, y, graphic); + DrawLevelGraphicAnimationIfNeeded(x, y, graphic); #endif else if (IS_MOVING(x, y)) @@ -4803,7 +4834,7 @@ void GameActions() else if (element == EL_EXPLOSION) ; /* drawing of correct explosion animation is handled separately */ else if (IS_ANIMATED(graphic)) - ContinueLevelGraphicAnimation(x, y, graphic); + DrawLevelGraphicAnimationIfNeeded(x, y, graphic); #endif if (IS_BELT_ACTIVE(element)) @@ -4811,29 +4842,19 @@ void GameActions() if (game.magic_wall_active) { - boolean sieb = FALSE; int jx = local_player->jx, jy = local_player->jy; - if (element == EL_MAGIC_WALL_FULL || - element == EL_MAGIC_WALL_ACTIVE || - element == EL_MAGIC_WALL_EMPTYING) - { - SiebAktivieren(x, y, 1); - sieb = TRUE; - } - else if (element == EL_BD_MAGIC_WALL_FULL || - element == EL_BD_MAGIC_WALL_ACTIVE || - element == EL_BD_MAGIC_WALL_EMPTYING) - { - SiebAktivieren(x, y, 2); - sieb = TRUE; - } - /* play the element sound at the position nearest to the player */ - if (sieb && ABS(x-jx)+ABS(y-jy) < ABS(sieb_x-jx)+ABS(sieb_y-jy)) + if ((element == EL_MAGIC_WALL_FULL || + element == EL_MAGIC_WALL_ACTIVE || + element == EL_MAGIC_WALL_EMPTYING || + element == EL_BD_MAGIC_WALL_FULL || + element == EL_BD_MAGIC_WALL_ACTIVE || + element == EL_BD_MAGIC_WALL_EMPTYING) && + ABS(x-jx) + ABS(y-jy) < ABS(magic_wall_x-jx) + ABS(magic_wall_y-jy)) { - sieb_x = x; - sieb_y = y; + magic_wall_x = x; + magic_wall_y = y; } } } @@ -4901,14 +4922,14 @@ void GameActions() { if (!(game.magic_wall_time_left % 4)) { - int element = Feld[sieb_x][sieb_y]; + int element = Feld[magic_wall_x][magic_wall_y]; if (element == EL_BD_MAGIC_WALL_FULL || element == EL_BD_MAGIC_WALL_ACTIVE || element == EL_BD_MAGIC_WALL_EMPTYING) - PlaySoundLevel(sieb_x, sieb_y, SND_BD_MAGIC_WALL_ACTIVE); + PlaySoundLevel(magic_wall_x, magic_wall_y, SND_BD_MAGIC_WALL_ACTIVE); else - PlaySoundLevel(sieb_x, sieb_y, SND_MAGIC_WALL_ACTIVE); + PlaySoundLevel(magic_wall_x, magic_wall_y, SND_MAGIC_WALL_ACTIVE); } if (game.magic_wall_time_left > 0) @@ -6047,7 +6068,9 @@ int DigField(struct PlayerInfo *player, case EL_SPRING: if (mode == DF_SNAP) return MF_NO_ACTION; + /* no "break" -- fall through to next case */ + /* the following elements can be pushed by "snapping" */ case EL_BD_ROCK: if (dy) @@ -6068,7 +6091,8 @@ int DigField(struct PlayerInfo *player, player->push_delay = FrameCounter; #if 0 if (!FrameReached(&player->push_delay, player->push_delay_value) && - !tape.playing && element != EL_SPRING) + !tape.playing && + element != EL_SPRING) return MF_NO_ACTION; #else if (!FrameReached(&player->push_delay, player->push_delay_value) && @@ -6379,6 +6403,48 @@ int DigField(struct PlayerInfo *player, break; default: + if (IS_PUSHABLE(element)) + { + if (mode == DF_SNAP) + return MF_NO_ACTION; + + if (CAN_FALL(element) && dy) + return MF_NO_ACTION; + + player->Pushing = TRUE; + + if (!IN_LEV_FIELD(x+dx, y+dy) || !IS_FREE(x+dx, y+dy)) + return MF_NO_ACTION; + + if (dx && real_dy) + { + if (IN_LEV_FIELD(jx, jy+real_dy) && !IS_SOLID(Feld[jx][jy+real_dy])) + return MF_NO_ACTION; + } + else if (dy && real_dx) + { + if (IN_LEV_FIELD(jx+real_dx, jy) && !IS_SOLID(Feld[jx+real_dx][jy])) + return MF_NO_ACTION; + } + + if (player->push_delay == 0) + player->push_delay = FrameCounter; + + if (!FrameReached(&player->push_delay, player->push_delay_value) && + !(tape.playing && tape.file_version < FILE_VERSION_2_0)) + return MF_NO_ACTION; + + RemoveField(x, y); + Feld[x + dx][y + dy] = element; + + player->push_delay_value = 2 + RND(8); + + DrawLevelField(x + dx, y + dy); + PlaySoundLevelElementAction(x, y, element, ACTION_PUSHING); + + break; + } + return MF_NO_ACTION; } @@ -6445,6 +6511,7 @@ boolean PlaceBomb(struct PlayerInfo *player) MovDelay[jx][jy] = 96; ResetGfxAnimation(jx, jy); + ResetRandomAnimationValue(jx, jy); if (player->dynamite) {