X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Fgame.c;h=a46368e1a87874e31529b510d780db0d2b0848a9;hb=39af00f43cf5c4cea174d0e90633877df08a2f7c;hp=7bc96654856096d699bfba3a8cf5cb4a1335d959;hpb=2a8b100c02ff1e102b30cb5f0e9345ba531e06c2;p=rocksndiamonds.git diff --git a/src/game.c b/src/game.c index 7bc96654..a46368e1 100644 --- a/src/game.c +++ b/src/game.c @@ -800,13 +800,19 @@ static void InitGameEngine() /* dynamically adjust player properties according to game engine version */ game.initial_move_delay = - (game.engine_version <= VERSION_IDENT(2,0,1) ? INITIAL_MOVE_DELAY_ON : + (game.engine_version <= VERSION_IDENT(2,0,1,0) ? INITIAL_MOVE_DELAY_ON : INITIAL_MOVE_DELAY_OFF); /* dynamically adjust player properties according to level information */ game.initial_move_delay_value = (level.double_speed ? MOVE_DELAY_HIGH_SPEED : MOVE_DELAY_NORMAL_SPEED); + /* ---------- initialize player's initial push delay --------------------- */ + + /* dynamically adjust player properties according to game engine version */ + game.initial_push_delay_value = + (game.engine_version < VERSION_IDENT(3,0,7,1) ? 5 : -1); + /* ---------- initialize changing elements ------------------------------- */ /* initialize changing elements information */ @@ -927,8 +933,8 @@ static void InitGameEngine() { if (!IS_CUSTOM_ELEMENT(i)) { - element_info[i].push_delay_fixed = 2; - element_info[i].push_delay_random = 8; + element_info[i].push_delay_fixed = game.default_push_delay_fixed; + element_info[i].push_delay_random = game.default_push_delay_random; } } @@ -1059,7 +1065,7 @@ void InitGame() player->move_delay_value = game.initial_move_delay_value; player->push_delay = 0; - player->push_delay_value = 5; + player->push_delay_value = game.initial_push_delay_value; player->last_jx = player->last_jy = 0; player->jx = player->jy = 0; @@ -2149,7 +2155,7 @@ void Explode(int ex, int ey, int phase, int mode) #if 0 /* --- This is only really needed (and now handled) in "Impact()". --- */ /* do not explode moving elements that left the explode field in time */ - if (game.engine_version >= RELEASE_IDENT(2,2,0,7) && + if (game.engine_version >= VERSION_IDENT(2,2,0,7) && center_element == EL_EMPTY && (mode == EX_NORMAL || mode == EX_CENTER)) return; #endif @@ -2204,7 +2210,7 @@ void Explode(int ex, int ey, int phase, int mode) #else if ((IS_INDESTRUCTIBLE(element) && - (game.engine_version < VERSION_IDENT(2,2,0) || + (game.engine_version < VERSION_IDENT(2,2,0,0) || (!IS_WALKABLE_OVER(element) && !IS_WALKABLE_UNDER(element)))) || element == EL_FLAMES) continue; @@ -2965,7 +2971,7 @@ void Impact(int x, int y) MovPos[x][y + 1] <= TILEY / 2)); /* do not smash moving elements that left the smashed field in time */ - if (game.engine_version >= RELEASE_IDENT(2,2,0,7) && IS_MOVING(x, y + 1) && + if (game.engine_version >= VERSION_IDENT(2,2,0,7) && IS_MOVING(x, y + 1) && ABS(MovPos[x][y + 1] + getElementMoveStepsize(x, y + 1)) >= TILEX) object_hit = FALSE; @@ -3735,7 +3741,7 @@ static boolean JustBeingPushed(int x, int y) void StartMoving(int x, int y) { - boolean use_spring_bug = (game.engine_version < VERSION_IDENT(2,2,0)); + boolean use_spring_bug = (game.engine_version < VERSION_IDENT(2,2,0,0)); boolean started_moving = FALSE; /* some elements can fall _and_ move */ int element = Feld[x][y]; @@ -3891,16 +3897,16 @@ void StartMoving(int x, int y) #endif } #if 1 - else if ((game.engine_version < RELEASE_IDENT(2,2,0,7) && + else if ((game.engine_version < VERSION_IDENT(2,2,0,7) && CAN_SMASH(element) && WasJustMoving[x][y] && !Pushed[x][y + 1] && (Feld[x][y + 1] == EL_BLOCKED)) || - (game.engine_version >= VERSION_IDENT(3,0,7) && + (game.engine_version >= VERSION_IDENT(3,0,7,0) && CAN_SMASH(element) && WasJustFalling[x][y] && (Feld[x][y + 1] == EL_BLOCKED || IS_PLAYER(x, y + 1)))) #else #if 1 - else if (game.engine_version < RELEASE_IDENT(2,2,0,7) && + else if (game.engine_version < VERSION_IDENT(2,2,0,7) && CAN_SMASH(element) && Feld[x][y + 1] == EL_BLOCKED && WasJustMoving[x][y] && !Pushed[x][y + 1]) #else @@ -4117,12 +4123,27 @@ void StartMoving(int x, int y) dir == MV_RIGHT ? IMG_FLAMES_1_RIGHT : dir == MV_UP ? IMG_FLAMES_1_UP : dir == MV_DOWN ? IMG_FLAMES_1_DOWN : IMG_EMPTY); - int frame = getGraphicAnimationFrame(graphic, -1); + int frame = getGraphicAnimationFrame(graphic, GfxFrame[x][y]); + +#if 0 + printf("::: %d, %d\n", GfxAction[x][y], GfxFrame[x][y]); +#endif + + GfxAction[x][y] = ACTION_ATTACKING; + + if (IS_PLAYER(x, y)) + DrawPlayerField(x, y); + else + DrawLevelField(x, y); + + PlaySoundLevelActionIfLoop(x, y, ACTION_ATTACKING); - for (i=1; i<=3; i++) + for (i=1; i <= 3; i++) { - int xx = x + i*dx, yy = y + i*dy; - int sx = SCREENX(xx), sy = SCREENY(yy); + int xx = x + i * dx; + int yy = y + i * dy; + int sx = SCREENX(xx); + int sy = SCREENY(yy); int flame_graphic = graphic + (i - 1); if (!IN_LEV_FIELD(xx, yy) || IS_DRAGONFIRE_PROOF(Feld[xx][yy])) @@ -4139,7 +4160,10 @@ void StartMoving(int x, int y) Feld[xx][yy] = EL_FLAMES; if (IN_SCR_FIELD(sx, sy)) + { + DrawLevelFieldCrumbledSand(xx, yy); DrawGraphic(sx, sy, flame_graphic, frame); + } } else { @@ -4260,14 +4284,15 @@ void StartMoving(int x, int y) DrawPlayerField(x, y); else DrawLevelField(x, y); + return; } else { boolean wanna_flame = !RND(10); int dx = newx - x, dy = newy - y; - int newx1 = newx+1*dx, newy1 = newy+1*dy; - int newx2 = newx+2*dx, newy2 = newy+2*dy; + int newx1 = newx + 1 * dx, newy1 = newy + 1 * dy; + int newx2 = newx + 2 * dx, newy2 = newy + 2 * dy; int element1 = (IN_LEV_FIELD(newx1, newy1) ? MovingOrBlocked2Element(newx1, newy1) : EL_STEELWALL); int element2 = (IN_LEV_FIELD(newx2, newy2) ? @@ -4292,6 +4317,7 @@ void StartMoving(int x, int y) PlaySoundLevel(x, y, SND_DRAGON_ATTACKING); MovDelay[x][y] = 50; + Feld[newx][newy] = EL_FLAMES; if (IN_LEV_FIELD(newx1, newy1) && Feld[newx1][newy1] == EL_EMPTY) Feld[newx1][newy1] = EL_FLAMES; @@ -5749,9 +5775,18 @@ static boolean CheckTriggeredElementSideChange(int lx, int ly, struct ElementChangeInfo *change = &element_info[element].change_page[j]; if (change->can_change && +#if 1 + change->events & CH_EVENT_BIT(trigger_event) && +#endif change->sides & trigger_side && change->trigger_element == trigger_element) { +#if 0 + if (!(change->events & CH_EVENT_BIT(trigger_event))) + printf("::: !!! %d triggers %d: using wrong page %d [event %d]\n", + trigger_element-EL_CUSTOM_START+1, i+1, j, trigger_event); +#endif + change_element = TRUE; page = j; @@ -5980,7 +6015,7 @@ void GameActions() #endif #if 1 - if (game.engine_version < RELEASE_IDENT(2,2,0,7)) + if (game.engine_version < VERSION_IDENT(2,2,0,7)) { for (i=0; iis_moving = FALSE; } - if (game.engine_version < VERSION_IDENT(3,0,7)) + if (game.engine_version < VERSION_IDENT(3,0,7,0)) { TestIfHeroTouchesBadThing(jx, jy); TestIfPlayerTouchesCustomElement(jx, jy); @@ -6943,10 +6978,13 @@ void ScrollPlayer(struct PlayerInfo *player, int mode) player->LevelSolved = player->GameOver = TRUE; } - if (game.engine_version >= VERSION_IDENT(3,0,7)) + if (game.engine_version >= VERSION_IDENT(3,0,7,0)) { TestIfHeroTouchesBadThing(jx, jy); TestIfPlayerTouchesCustomElement(jx, jy); +#if 1 + TestIfElementTouchesCustomElement(jx, jy); /* for empty space */ +#endif if (!player->active) RemoveHero(player); @@ -7026,7 +7064,7 @@ void TestIfPlayerTouchesCustomElement(int x, int y) if (IS_PLAYER(x, y)) { - if (game.engine_version < VERSION_IDENT(3,0,7)) + if (game.engine_version < VERSION_IDENT(3,0,7,0)) border_element = Feld[xx][yy]; /* may be moving! */ else if (!IS_MOVING(xx, yy) && !IS_BLOCKED(xx, yy)) border_element = Feld[xx][yy]; @@ -7042,7 +7080,7 @@ void TestIfPlayerTouchesCustomElement(int x, int y) } else if (IS_PLAYER(xx, yy)) { - if (game.engine_version >= VERSION_IDENT(3,0,7)) + if (game.engine_version >= VERSION_IDENT(3,0,7,0)) { struct PlayerInfo *player = PLAYERINFO(xx, yy); @@ -7100,7 +7138,7 @@ void TestIfElementTouchesCustomElement(int x, int y) if (!IN_LEV_FIELD(xx, yy)) continue; - if (game.engine_version < VERSION_IDENT(3,0,7)) + if (game.engine_version < VERSION_IDENT(3,0,7,0)) border_element = Feld[xx][yy]; /* may be moving! */ else if (!IS_MOVING(xx, yy) && !IS_BLOCKED(xx, yy)) border_element = Feld[xx][yy]; @@ -7280,7 +7318,7 @@ void TestIfBadThingHitsGoodThing(int bad_x, int bad_y, int bad_move_dir) if (bad_element == EL_ROBOT && player->is_moving) continue; /* robot does not kill player if he is moving */ - if (game.engine_version >= VERSION_IDENT(3,0,7)) + if (game.engine_version >= VERSION_IDENT(3,0,7,0)) { if (player->MovPos != 0 && !(player->MovDir & touch_dir[i])) continue; /* center and border element do not touch */ @@ -7490,7 +7528,7 @@ int DigField(struct PlayerInfo *player, CH_SIDE_BOTTOM, /* moving up */ CH_SIDE_TOP, /* moving down */ }; - boolean use_spring_bug = (game.engine_version < VERSION_IDENT(2,2,0)); + boolean use_spring_bug = (game.engine_version < VERSION_IDENT(2,2,0,0)); int jx = player->jx, jy = player->jy; int dx = x - jx, dy = y - jy; int nextx = x + dx, nexty = y + dy; @@ -7525,7 +7563,7 @@ int DigField(struct PlayerInfo *player, if (IS_TUBE(Feld[jx][jy]) || IS_TUBE(Back[jx][jy])) #else if (IS_TUBE(Feld[jx][jy]) || - (IS_TUBE(Back[jx][jy]) && game.engine_version >= VERSION_IDENT(2,2,0))) + (IS_TUBE(Back[jx][jy]) && game.engine_version >= VERSION_IDENT(2,2,0,0))) #endif { int i = 0; @@ -7560,7 +7598,7 @@ int DigField(struct PlayerInfo *player, element = Feld[x][y]; if (mode == DF_SNAP && !IS_SNAPPABLE(element) && - game.engine_version >= VERSION_IDENT(2,2,0)) + game.engine_version >= VERSION_IDENT(2,2,0,0)) return MF_NO_ACTION; switch (element) @@ -7739,7 +7777,10 @@ int DigField(struct PlayerInfo *player, CheckTriggeredElementChange(x, y, element, CE_OTHER_GETS_DIGGED); - TestIfElementTouchesCustomElement(x, y); /* for empty space */ +#if 1 + if (mode == DF_SNAP) + TestIfElementTouchesCustomElement(x, y); /* for empty space */ +#endif break; } @@ -7834,7 +7875,10 @@ int DigField(struct PlayerInfo *player, CheckTriggeredElementChange(x, y, element, CE_OTHER_GETS_COLLECTED); - TestIfElementTouchesCustomElement(x, y); /* for empty space */ +#if 1 + if (mode == DF_SNAP) + TestIfElementTouchesCustomElement(x, y); /* for empty space */ +#endif break; } @@ -7859,9 +7903,36 @@ int DigField(struct PlayerInfo *player, if (element == EL_SPRING && MovDir[x][y] != MV_NO_MOVING) return MF_NO_ACTION; #endif + +#if 1 + if (game.engine_version >= VERSION_IDENT(3,0,7,1)) + { + if (player->push_delay_value == -1) + player->push_delay_value = GET_NEW_PUSH_DELAY(element); + } + else if (game.engine_version >= VERSION_IDENT(2,2,0,7)) + { + if (!player->is_pushing) + player->push_delay_value = GET_NEW_PUSH_DELAY(element); + } + + /* + if (game.engine_version >= VERSION_IDENT(2,2,0,7) && + (game.engine_version < VERSION_IDENT(3,0,7,1) || + !player_is_pushing)) + player->push_delay_value = GET_NEW_PUSH_DELAY(element); + */ +#else if (!player->is_pushing && - game.engine_version >= RELEASE_IDENT(2,2,0,7)) + game.engine_version >= VERSION_IDENT(2,2,0,7)) player->push_delay_value = GET_NEW_PUSH_DELAY(element); +#endif + +#if 0 + printf("::: push delay: %ld [%d, %d] [%d]\n", + player->push_delay_value, FrameCounter, game.engine_version, + player->is_pushing); +#endif player->is_pushing = TRUE; @@ -7880,7 +7951,17 @@ int DigField(struct PlayerInfo *player, if (!FrameReached(&player->push_delay, player->push_delay_value) && !(tape.playing && tape.file_version < FILE_VERSION_2_0) && element != EL_SPRING && element != EL_BALLOON) + { + /* make sure that there is no move delay before next try to push */ + if (game.engine_version >= VERSION_IDENT(3,0,7,1)) + player->move_delay = INITIAL_MOVE_DELAY_OFF; + return MF_NO_ACTION; + } + +#if 0 + printf("::: NOW PUSHING... [%d]\n", FrameCounter); +#endif if (IS_SB_ELEMENT(element)) { @@ -7928,8 +8009,10 @@ int DigField(struct PlayerInfo *player, Pushed[x][y] = TRUE; Pushed[nextx][nexty] = TRUE; - if (game.engine_version < RELEASE_IDENT(2,2,0,7)) + if (game.engine_version < VERSION_IDENT(2,2,0,7)) player->push_delay_value = GET_NEW_PUSH_DELAY(element); + else + player->push_delay_value = -1; /* get new value later */ CheckTriggeredElementSideChange(x, y, element, dig_side, CE_OTHER_GETS_PUSHED); @@ -8069,7 +8152,7 @@ boolean SnapField(struct PlayerInfo *player, int dx, int dy) dy == -1 ? MV_UP : dy == +1 ? MV_DOWN : MV_NO_MOVING); - if (player->MovPos && game.engine_version >= VERSION_IDENT(2,2,0)) + if (player->MovPos && game.engine_version >= VERSION_IDENT(2,2,0,0)) return FALSE; if (!player->active || !IN_LEV_FIELD(x, y))