#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"
{
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",
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[] =
(level.em_slippery_gems &&
game.engine_version > VERSION_IDENT(2,0,1)));
}
+#endif
/* initialize changing elements information */
for (i=0; i<MAX_NUM_ELEMENTS; i++)
RemoveMovingField(x, y);
}
+#if 1
+ if (IS_EXPLOSION_PROOF(element))
+ continue;
+#else
if ((IS_INDESTRUCTIBLE(element) &&
(game.engine_version < VERSION_IDENT(2,2,0) ||
(!IS_WALKABLE_OVER(element) && !IS_WALKABLE_UNDER(element)))) ||
element == EL_FLAMES)
continue;
+#endif
if (IS_PLAYER(x, y) && SHIELD_ON(PLAYERINFO(x, y)))
{
int sx = SCREENX(xx), sy = SCREENY(yy);
int flame_graphic = graphic + (i - 1);
+#if 1
+ if (!IN_LEV_FIELD(xx, yy) || IS_DRAGONFIRE_PROOF(Feld[xx][yy]))
+ break;
+#else
if (!IN_LEV_FIELD(xx, yy) ||
IS_HISTORIC_SOLID(Feld[xx][yy]) || Feld[xx][yy] == EL_EXPLOSION)
break;
+#endif
if (MovDelay[x][y])
{
static boolean checkDiagonalPushing(struct PlayerInfo *player,
int x, int y, int real_dx, int real_dy)
{
- int jx = player->jx, jy = player->jy;
- int dx = x - jx, dy = y - jy;
+#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);
{
int element = Feld[xx][yy];
-#if 0
- if (IS_HISTORIC_SOLID(element) !=
- (!(IS_WALKABLE(element) ||
- IS_DIGGABLE(element) ||
- IS_COLLECTIBLE(element))))
- printf("::: %d ['%s'] [%d, %d]\n",
- element,
- element_info[element].token_name,
- game.engine_version, tape.engine_version);
-#endif
-
if (game.engine_version < VERSION_IDENT(2,2,0))
return IS_HISTORIC_SOLID(element);
else
}
return TRUE; /* no diagonal direction input => push object */
+#endif
}
/*
/* currently nothing to do */
}
-void InitElementProperties()
+void InitElementPropertiesStatic()
{
- int i, j;
-
static int ep_amoebalive[] =
{
EL_AMOEBA_WET,
{ NULL, -1 }
};
+ int i, j;
+
+ /* always start with reliable default values (element has no properties) */
+ for (i=0; i < MAX_NUM_ELEMENTS; i++)
+ for (j=0; j < NUM_ELEMENT_PROPERTIES; j++)
+ SET_PROPERTY(i, j, FALSE);
+
+ /* set all base element properties from above array definitions */
+ for (i=0; element_properties[i].elements != NULL; i++)
+ for (j=0; (element_properties[i].elements)[j] != -1; j++)
+ SET_PROPERTY((element_properties[i].elements)[j],
+ element_properties[i].property, TRUE);
+}
+
+void InitElementPropertiesEngine(int engine_version)
+{
#if 0
static int active_properties[] =
{
-1
};
- /* always start with reliable default values (no properties) */
- for (i=0; i<MAX_NUM_ELEMENTS; i++)
- for (j=0; j<NUM_EP_BITFIELDS; j++)
- Properties[i][j] = EP_BITMASK_DEFAULT;
-
- /* set all predefined element properties from above arrays */
- for (i=0; element_properties[i].elements != NULL; i++)
- for (j=0; (element_properties[i].elements)[j] != -1; j++)
- SET_PROPERTY((element_properties[i].elements)[j],
- element_properties[i].property, TRUE);
-
- /* set properties of character elements */
- for (i=EL_CHAR_START; i<=EL_CHAR_END; i++)
- SET_PROPERTY(i, EP_INACTIVE, TRUE);
+ int i, j;
- /* set properties derived from other properties */
- for (i=0; i<MAX_NUM_ELEMENTS; i++)
+ /* set all special, combined or engine dependant element properties */
+ for (i=0; i < MAX_NUM_ELEMENTS; i++)
{
+ /* ---------- INACTIVE ------------------------------------------------- */
+ if (i >= EL_CHAR_START && i <= EL_CHAR_END)
+ SET_PROPERTY(i, EP_INACTIVE, TRUE);
+
+ /* ---------- WALKABLE, PASSABLE, ACCESSIBLE --------------------------- */
if (IS_WALKABLE_OVER(i) || IS_WALKABLE_INSIDE(i) || IS_WALKABLE_UNDER(i))
SET_PROPERTY(i, EP_WALKABLE, TRUE);
if (IS_WALKABLE(i) || IS_PASSABLE(i))
SET_PROPERTY(i, EP_ACCESSIBLE, TRUE);
- }
- /* dynamically determine wall-like elements */
- for (i=0; i < MAX_NUM_ELEMENTS; i++)
- {
- /* default: element is wall-like */
- SET_PROPERTY(i, EP_WALL, TRUE);
+ /* ---------- WALL ----------------------------------------------------- */
+ SET_PROPERTY(i, EP_WALL, TRUE); /* default: element is wall */
for (j=0; no_wall_properties[j] != -1; j++)
if (HAS_PROPERTY(i, no_wall_properties[j]) ||
if (IS_HISTORIC_WALL(i))
SET_PROPERTY(i, EP_WALL, TRUE);
-#if 0
- printf("::: %d: %s '%s'\n",
- i,
- (IS_WALL(i) ? "IS A WALL: " : "IS NOT A WALL:"),
- element_info[i].token_name);
-#endif
+ /* ---------- SOLID ---------------------------------------------------- */
+ if (engine_version < VERSION_IDENT(2,2,0))
+ SET_PROPERTY(i, EP_SOLID, IS_HISTORIC_SOLID(i));
+ else
+ SET_PROPERTY(i, EP_SOLID, (!IS_WALKABLE(i) &&
+ !IS_DIGGABLE(i) &&
+ !IS_COLLECTIBLE(i)));
+
+ /* ---------- DRAGONFIRE_PROOF ----------------------------------------- */
+ if (IS_HISTORIC_SOLID(i) || i == EL_EXPLOSION)
+ SET_PROPERTY(i, EP_DRAGONFIRE_PROOF, TRUE);
+
+ /* ---------- EXPLOSION_PROOF ------------------------------------------ */
+ if (i == EL_FLAMES)
+ SET_PROPERTY(i, EP_EXPLOSION_PROOF, TRUE);
+ else if (engine_version < VERSION_IDENT(2,2,0))
+ SET_PROPERTY(i, EP_EXPLOSION_PROOF, IS_INDESTRUCTIBLE(i));
+ else
+ SET_PROPERTY(i, EP_EXPLOSION_PROOF, (IS_INDESTRUCTIBLE(i) &&
+ !IS_WALKABLE_OVER(i) &&
+ !IS_WALKABLE_UNDER(i)));
}
#if 0
#endif
}
#endif
+
+ /* dynamically adjust element properties according to game engine version */
+ {
+ static int ep_em_slippery_wall[] =
+ {
+ EL_STEELWALL,
+ EL_WALL,
+ EL_EXPANDABLE_WALL,
+ EL_EXPANDABLE_WALL_HORIZONTAL,
+ EL_EXPANDABLE_WALL_VERTICAL,
+ EL_EXPANDABLE_WALL_ANY,
+ -1
+ };
+
+ /* special EM style gems behaviour */
+ for (i=0; ep_em_slippery_wall[i] != -1; i++)
+ SET_PROPERTY(ep_em_slippery_wall[i], EP_EM_SLIPPERY_WALL,
+ level.em_slippery_gems);
+
+ /* "EL_EXPANDABLE_WALL_GROWING" wasn't slippery for EM gems in 2.0.1 */
+ SET_PROPERTY(EL_EXPANDABLE_WALL_GROWING, EP_EM_SLIPPERY_WALL,
+ (level.em_slippery_gems &&
+ engine_version > VERSION_IDENT(2,0,1)));
+ }
}
static void InitGlobal()
InitEventFilter(FilterMouseMotionEvents);
- InitElementProperties();
+ InitElementPropertiesStatic();
InitGfx();