X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;ds=sidebyside;f=src%2Fgame.c;h=25e138060311fa14b1ebca089bd154b2c7dc68db;hb=0eaa7d33772143903b8a93abac8f1dce5422fa66;hp=ce66ee8711fecdaeaee3a670fc7c5924ce5a23e3;hpb=b98c54e042b8dd87b4a42f0a038a600bdd23ffd4;p=rocksndiamonds.git diff --git a/src/game.c b/src/game.c index ce66ee87..25e13806 100644 --- a/src/game.c +++ b/src/game.c @@ -14,9 +14,9 @@ #include "libgame/libgame.h" #include "game.h" +#include "init.h" #include "tools.h" #include "screens.h" -#include "init.h" #include "files.h" #include "tape.h" #include "network.h" @@ -500,9 +500,13 @@ static void InitGameEngine() { int i; + /* set game engine from tape file when re-playing, else from level file */ game.engine_version = (tape.playing ? tape.engine_version : level.game_version); + /* dynamically adjust element properties according to game engine version */ + 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", @@ -520,6 +524,7 @@ static void InitGameEngine() game.initial_move_delay_value = (level.double_speed ? MOVE_DELAY_HIGH_SPEED : MOVE_DELAY_NORMAL_SPEED); +#if 0 /* dynamically adjust element properties according to game engine version */ { static int ep_em_slippery_wall[] = @@ -543,6 +548,7 @@ static void InitGameEngine() (level.em_slippery_gems && game.engine_version > VERSION_IDENT(2,0,1))); } +#endif /* initialize changing elements information */ for (i=0; iprogrammed_action = MV_DOWN; } } @@ -5316,7 +5360,7 @@ void ScrollFigure(struct PlayerInfo *player, int mode) if (player->MovPos == 0) { - if (IS_WALKABLE_THROUGH(Feld[last_jx][last_jy])) + if (IS_PASSABLE(Feld[last_jx][last_jy])) { /* continue with normal speed after quickly moving through gate */ HALVE_PLAYER_SPEED(player); @@ -5604,8 +5648,8 @@ void KillHero(struct PlayerInfo *player) if (!player->active) return; - if (IS_PFORTE(Feld[jx][jy])) - Feld[jx][jy] = EL_EMPTY; + /* remove accessible field at the player's position */ + Feld[jx][jy] = EL_EMPTY; /* deactivate shield (else Bang()/Explode() would not work right) */ player->shield_normal_time_left = 0; @@ -5657,17 +5701,57 @@ void RemoveHero(struct PlayerInfo *player) ExitY = ZY = jy; } -#if 0 /* checkDiagonalPushing() ----------------------------------------------------------------------------- check if diagonal input device direction results in pushing of object + (by checking if the alternative direction is walkable, diggable, ...) */ -static boolean checkDiagonalPushing(int x, int y, int real_dx, int real_dy) +static boolean checkDiagonalPushing(struct PlayerInfo *player, + int x, int y, int real_dx, int real_dy) { -} +#if 1 + int jx, jy, dx, dy, xx, yy; + + if (real_dx == 0 || real_dy == 0) /* no diagonal direction => push */ + return TRUE; + + /* diagonal direction: check alternative direction */ + jx = player->jx; + jy = player->jy; + dx = x - jx; + dy = y - jy; + xx = jx + (dx == 0 ? real_dx : 0); + yy = jy + (dy == 0 ? real_dy : 0); + + return (!IN_LEV_FIELD(xx, yy) || IS_SOLID(Feld[xx][yy])); +#else + + if (real_dx && real_dy) /* diagonal direction input => do check */ + { + /* diagonal direction: check alternative direction */ + int jx = player->jx, jy = player->jy; + int dx = x - jx, dy = y - jy; + int xx = jx + (dx == 0 ? real_dx : 0); + int yy = jy + (dy == 0 ? real_dy : 0); + + if (IN_LEV_FIELD(xx, yy)) + { + int element = Feld[xx][yy]; + + if (game.engine_version < VERSION_IDENT(2,2,0)) + return IS_HISTORIC_SOLID(element); + else + return !(IS_WALKABLE(element) || + IS_DIGGABLE(element) || + IS_COLLECTIBLE(element)); + } + } + + return TRUE; /* no diagonal direction input => push object */ #endif +} /* DigField() @@ -5706,9 +5790,15 @@ int DigField(struct PlayerInfo *player, if (IS_MOVING(x, y) || IS_PLAYER(x, y)) return MF_NO_ACTION; - if (IS_WALKABLE_THROUGH(Feld[jx][jy])) +#if 0 + 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))) +#endif { int i = 0; + int tube_element = (IS_TUBE(Feld[jx][jy]) ? Feld[jx][jy] : Back[jx][jy]); int tube_leave_directions[][2] = { { EL_TUBE_ANY, MV_LEFT | MV_RIGHT | MV_UP | MV_DOWN }, @@ -5725,7 +5815,7 @@ int DigField(struct PlayerInfo *player, { -1, MV_LEFT | MV_RIGHT | MV_UP | MV_DOWN } }; - while (tube_leave_directions[i][0] != Feld[jx][jy]) + while (tube_leave_directions[i][0] != tube_element) { i++; if (tube_leave_directions[i][0] == -1) /* should not happen */ @@ -6016,11 +6106,17 @@ int DigField(struct PlayerInfo *player, if (!IN_LEV_FIELD(x+dx, y+dy) || !IS_FREE(x+dx, y+dy)) return MF_NO_ACTION; +#if 1 + if (!checkDiagonalPushing(player, x, y, real_dx, real_dy)) + return MF_NO_ACTION; +#else if (real_dy) { - if (IN_LEV_FIELD(jx, jy+real_dy) && !IS_SOLID(Feld[jx][jy+real_dy])) + if (IN_LEV_FIELD(jx, jy+real_dy) && + !IS_HISTORIC_SOLID(Feld[jx][jy+real_dy])) return MF_NO_ACTION; } +#endif if (player->push_delay == 0) player->push_delay = FrameCounter; @@ -6262,16 +6358,23 @@ int DigField(struct PlayerInfo *player, || !IS_SB_ELEMENT(element)))) return MF_NO_ACTION; +#if 1 + if (!checkDiagonalPushing(player, x, y, real_dx, real_dy)) + return MF_NO_ACTION; +#else if (dx && real_dy) { - if (IN_LEV_FIELD(jx, jy+real_dy) && !IS_SOLID(Feld[jx][jy+real_dy])) + if (IN_LEV_FIELD(jx, jy+real_dy) && + !IS_HISTORIC_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])) + if (IN_LEV_FIELD(jx+real_dx, jy) && + !IS_HISTORIC_SOLID(Feld[jx+real_dx][jy])) return MF_NO_ACTION; } +#endif if (player->push_delay == 0) player->push_delay = FrameCounter; @@ -6371,16 +6474,23 @@ int DigField(struct PlayerInfo *player, if (!IN_LEV_FIELD(x+dx, y+dy) || !IS_FREE(x+dx, y+dy)) return MF_NO_ACTION; +#if 1 + if (!checkDiagonalPushing(player, x, y, real_dx, real_dy)) + return MF_NO_ACTION; +#else if (dx && real_dy) { - if (IN_LEV_FIELD(jx, jy+real_dy) && !IS_SOLID(Feld[jx][jy+real_dy])) + if (IN_LEV_FIELD(jx, jy+real_dy) && + !IS_HISTORIC_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])) + if (IN_LEV_FIELD(jx+real_dx, jy) && + !IS_HISTORIC_SOLID(Feld[jx+real_dx][jy])) return MF_NO_ACTION; } +#endif if (player->push_delay == 0) player->push_delay = FrameCounter; @@ -6473,8 +6583,19 @@ boolean PlaceBomb(struct PlayerInfo *player) IS_ACTIVE_BOMB(element) || element == EL_EXPLOSION) return FALSE; +#if 0 + if (element != EL_EMPTY) + return FALSE; +#endif + if (element != EL_EMPTY) + { +#if 0 Store[jx][jy] = element; +#else + Back[jx][jy] = element; +#endif + } MovDelay[jx][jy] = 96;