#define GET_NEW_PUSH_DELAY(e) ( (element_info[e].push_delay_fixed) + \
RND(element_info[e].push_delay_random))
+#define GET_NEW_DROP_DELAY(e) ( (element_info[e].drop_delay_fixed) + \
+ RND(element_info[e].drop_delay_random))
#define GET_NEW_MOVE_DELAY(e) ( (element_info[e].move_delay_fixed) + \
RND(element_info[e].move_delay_random))
#define GET_MAX_MOVE_DELAY(e) ( (element_info[e].move_delay_fixed) + \
((e) == EL_TRIGGER_ELEMENT ? (ch)->actual_trigger_element : \
(e) == EL_TRIGGER_PLAYER ? (ch)->actual_trigger_player : (e))
+#define CAN_GROW_INTO(e) \
+ (e == EL_SAND || (IS_DIGGABLE(e) && level.grow_into_diggable))
+
#define ELEMENT_CAN_ENTER_FIELD_BASE_X(x, y, condition) \
(IN_LEV_FIELD(x, y) && (IS_FREE(x, y) || \
(condition)))
#define IN_LEV_FIELD_AND_IS_FREE(x, y) (IN_LEV_FIELD(x, y) && IS_FREE(x, y))
#define IN_LEV_FIELD_AND_NOT_FREE(x, y) (IN_LEV_FIELD(x, y) && !IS_FREE(x, y))
+#define ACCESS_FROM(e, d) (element_info[e].access_direction &(d))
+#define IS_WALKABLE_FROM(e, d) (IS_WALKABLE(e) && ACCESS_FROM(e, d))
+#define IS_PASSABLE_FROM(e, d) (IS_PASSABLE(e) && ACCESS_FROM(e, d))
+#define IS_ACCESSIBLE_FROM(e, d) (IS_ACCESSIBLE(e) && ACCESS_FROM(e, d))
+
/* game button identifiers */
#define GAME_CTRL_ID_STOP 0
#define GAME_CTRL_ID_PAUSE 1
#define CheckTriggeredElementChange(x, y, e, ev) \
CheckTriggeredElementChangeExt(x, y, e, ev, CH_PLAYER_ANY, \
CH_SIDE_ANY, -1)
-#define CheckTriggeredElementChangePlayer(x, y, e, ev, p, s) \
+#define CheckTriggeredElementChangeByPlayer(x, y, e, ev, p, s) \
CheckTriggeredElementChangeExt(x, y, e, ev, p, s, -1)
-#define CheckTriggeredElementChangeSide(x, y, e, ev, s) \
+#define CheckTriggeredElementChangeBySide(x, y, e, ev, s) \
CheckTriggeredElementChangeExt(x, y, e, ev, CH_PLAYER_ANY, s, -1)
-#define CheckTriggeredElementChangePage(x, y, e, ev, p) \
+#define CheckTriggeredElementChangeByPage(x, y, e, ev, p) \
CheckTriggeredElementChangeExt(x, y, e, ev, CH_PLAYER_ANY, \
CH_SIDE_ANY, p)
static boolean CheckElementChangeExt(int, int, int, int, int, int, int, int);
#define CheckElementChange(x, y, e, te, ev) \
CheckElementChangeExt(x, y, e, te, ev, CH_PLAYER_ANY, CH_SIDE_ANY, -1)
-#define CheckElementChangePlayer(x, y, e, ev, p, s) \
+#define CheckElementChangeByPlayer(x, y, e, ev, p, s) \
CheckElementChangeExt(x, y, e, EL_EMPTY, ev, p, s, CH_PAGE_ANY)
-#define CheckElementChangeSide(x, y, e, te, ev, s) \
+#define CheckElementChangeBySide(x, y, e, te, ev, s) \
CheckElementChangeExt(x, y, e, te, ev, CH_PLAYER_ANY, s, CH_PAGE_ANY)
-#define CheckElementChangePage(x, y, e, te, ev, p) \
+#define CheckElementChangeByPage(x, y, e, te, ev, p) \
CheckElementChangeExt(x, y, e, te, ev, CH_PLAYER_ANY, CH_SIDE_ANY, p)
static void PlayLevelSound(int, int, int);
int element;
int direction;
}
-tube_access[] =
+access_direction_list[] =
{
{ EL_TUBE_ANY, MV_LEFT | MV_RIGHT | MV_UP | MV_DOWN },
{ EL_TUBE_VERTICAL, MV_UP | MV_DOWN },
{ EL_TUBE_RIGHT_UP, MV_RIGHT | MV_UP },
{ EL_TUBE_RIGHT_DOWN, MV_RIGHT | MV_DOWN },
- { EL_UNDEFINED, 0 }
+ { EL_SP_PORT_LEFT, MV_RIGHT },
+ { EL_SP_PORT_RIGHT, MV_LEFT },
+ { EL_SP_PORT_UP, MV_DOWN },
+ { EL_SP_PORT_DOWN, MV_UP },
+ { EL_SP_PORT_HORIZONTAL, MV_LEFT | MV_RIGHT },
+ { EL_SP_PORT_VERTICAL, MV_UP | MV_DOWN },
+ { EL_SP_PORT_ANY, MV_LEFT | MV_RIGHT | MV_UP | MV_DOWN },
+ { EL_SP_GRAVITY_PORT_LEFT, MV_RIGHT },
+ { EL_SP_GRAVITY_PORT_RIGHT, MV_LEFT },
+ { EL_SP_GRAVITY_PORT_UP, MV_DOWN },
+ { EL_SP_GRAVITY_PORT_DOWN, MV_UP },
+
+ { EL_UNDEFINED, MV_NO_MOVING }
};
static unsigned long trigger_events[MAX_NUM_ELEMENTS];
/* this case is in fact a combination of not less than three bugs:
first, it calls InitMovDir() for elements that can move, although this is
already done by InitField(); then, it checks the element that was at this
- field _before_ the call to InitField() (which can change it)
-
- */
+ field _before_ the call to InitField() (which can change it); lastly, it
+ was not called for "mole with direction" elements, which were treated as
+ "cannot move" due to (fixed) wrong element initialization in "src/init.c"
+ */
}
inline void DrawGameValue_Emeralds(int value)
element_info[e].move_stepsize = move_stepsize_list[i].move_stepsize;
}
+#if 0
/* ---------- initialize move dig/leave ---------------------------------- */
for (i = 0; i < MAX_NUM_ELEMENTS; i++)
element_info[i].can_leave_element = FALSE;
element_info[i].can_leave_element_last = FALSE;
}
+#endif
/* ---------- initialize gem count --------------------------------------- */
/* ---------- initialize access direction -------------------------------- */
- /* initialize access direction values to default */
+ /* initialize access direction values to default (access from every side) */
for (i = 0; i < MAX_NUM_ELEMENTS; i++)
if (!IS_CUSTOM_ELEMENT(i))
element_info[i].access_direction = MV_ALL_DIRECTIONS;
/* set access direction value for certain elements from pre-defined list */
- for (i = 0; tube_access[i].element != EL_UNDEFINED; i++)
- element_info[tube_access[i].element].access_direction =
- tube_access[i].direction;
+ for (i = 0; access_direction_list[i].element != EL_UNDEFINED; i++)
+ element_info[access_direction_list[i].element].access_direction =
+ access_direction_list[i].direction;
}
player->is_waiting = FALSE;
player->is_moving = FALSE;
+ player->is_auto_moving = FALSE;
player->is_digging = FALSE;
player->is_snapping = FALSE;
player->is_collecting = FALSE;
else if (move_pattern == MV_ALONG_LEFT_SIDE ||
move_pattern == MV_ALONG_RIGHT_SIDE)
{
+#if 1
+ /* use random direction as default start direction */
+ if (game.engine_version >= VERSION_IDENT(3,1,0,2))
+ MovDir[x][y] = 1 << RND(4);
+#endif
+
for (i = 0; i < NUM_DIRECTIONS; i++)
{
int x1 = x + xy[i][0];
int element = (element_raw == EL_SP_MURPHY ? EL_PLAYER_1 : element_raw);
struct PlayerInfo *player = &stored_player[element - EL_PLAYER_1];
boolean ffwd_delay = (tape.playing && tape.fast_forward);
- boolean no_delay = (tape.index_search);
+ boolean no_delay = (tape.warp_forward);
int frame_delay_value = (ffwd_delay ? FfwdFrameDelay : GameFrameDelay);
int wait_delay_value = (no_delay ? 0 : frame_delay_value);
int old_jx, old_jy;
Explode(x, y, EX_PHASE_START, EX_TYPE_BORDER);
+#if 1
+ if (element != EL_EMPTY && element != EL_EXPLOSION &&
+ !CAN_GROW_INTO(element) && !dynabomb_xl)
+ break;
+#else
/* !!! extend EL_SAND to anything diggable (but maybe not SP_BASE) !!! */
- if (element != EL_EMPTY &&
- element != EL_SAND &&
- element != EL_EXPLOSION &&
- !dynabomb_xl)
+ if (element != EL_EMPTY && element != EL_EXPLOSION &&
+ element != EL_SAND && !dynabomb_xl)
break;
+#endif
}
}
}
CheckElementChange(x, y + 1, smashed, element, CE_SMASHED);
- CheckTriggeredElementChangeSide(x, y + 1, smashed,
- CE_OTHER_IS_SWITCHING, CH_SIDE_TOP);
- CheckElementChangeSide(x, y + 1, smashed, element,
- CE_SWITCHED, CH_SIDE_TOP);
+#if 1
+ /* !!! TEST ONLY !!! */
+ CheckElementChangeBySide(x, y + 1, smashed, element,
+ CE_SWITCHED, CH_SIDE_TOP);
+ CheckTriggeredElementChangeBySide(x, y + 1, smashed,
+ CE_OTHER_IS_SWITCHING,CH_SIDE_TOP);
+#else
+ CheckTriggeredElementChangeBySide(x, y + 1, smashed,
+ CE_OTHER_IS_SWITCHING,CH_SIDE_TOP);
+ CheckElementChangeBySide(x, y + 1, smashed, element,
+ CE_SWITCHED, CH_SIDE_TOP);
+#endif
}
}
else
}
}
+#if 1
+ if (element == EL_ROBOT && ZX >= 0 && ZY >= 0 &&
+ (Feld[ZX][ZY] == EL_ROBOT_WHEEL_ACTIVE ||
+ game.engine_version < VERSION_IDENT(3,1,0,0)))
+#else
if (element == EL_ROBOT && ZX >= 0 && ZY >= 0)
+#endif
{
attr_x = ZX;
attr_y = ZY;
{
int flamed = MovingOrBlocked2Element(xx, yy);
+ /* !!! */
+#if 0
+ if (IS_CLASSIC_ENEMY(flamed) || CAN_EXPLODE_BY_DRAGONFIRE(flamed))
+ Bang(xx, yy);
+ else if (IS_MOVING(xx, yy) || IS_BLOCKED(xx, yy))
+ RemoveMovingField(xx, yy);
+ else
+ RemoveField(xx, yy);
+#else
if (IS_CLASSIC_ENEMY(flamed) || CAN_EXPLODE_BY_DRAGONFIRE(flamed))
Bang(xx, yy);
else
RemoveMovingField(xx, yy);
+#endif
+#if 0
+ if (ChangeDelay[xx][yy])
+ printf("::: !!! [%d]\n", (IS_MOVING(xx, yy) ||
+ Feld[xx][yy] == EL_BLOCKED));
+#endif
+
+#if 1
+ ChangeDelay[xx][yy] = 0;
+#endif
Feld[xx][yy] = EL_FLAMES;
if (IN_SCR_FIELD(sx, sy))
{
PlayLevelSoundAction(x, y, action);
}
+#if 1
+#if 1
+ Store[newx][newy] = EL_EMPTY;
+ if (IS_EQUAL_OR_IN_GROUP(new_element, MOVE_ENTER_EL(element)))
+ Store[newx][newy] = element_info[element].move_leave_element;
+#else
+ Store[newx][newy] = EL_EMPTY;
+ if (IS_EQUAL_OR_IN_GROUP(new_element, MOVE_ENTER_EL(element)) ||
+ element_info[element].move_leave_type == LEAVE_TYPE_UNLIMITED)
+ Store[newx][newy] = element_info[element].move_leave_element;
+#endif
+#else
if (IS_EQUAL_OR_IN_GROUP(new_element, MOVE_ENTER_EL(element)))
element_info[element].can_leave_element = TRUE;
+#endif
if (move_pattern & MV_MAZE_RUNNER_STYLE)
{
MovDelay[x][y] = 50;
+ /* !!! */
+#if 0
+ RemoveField(newx, newy);
+#endif
Feld[newx][newy] = EL_FLAMES;
if (IN_LEV_FIELD(newx1, newy1) && Feld[newx1][newy1] == EL_EMPTY)
+ {
+#if 0
+ RemoveField(newx1, newy1);
+#endif
Feld[newx1][newy1] = EL_FLAMES;
+ }
if (IN_LEV_FIELD(newx2, newy2) && Feld[newx2][newy2] == EL_EMPTY)
+ {
+#if 0
+ RemoveField(newx2, newy2);
+#endif
Feld[newx2][newy2] = EL_FLAMES;
+ }
return;
}
void ContinueMoving(int x, int y)
{
int element = Feld[x][y];
+ int stored = Store[x][y];
struct ElementInfo *ei = &element_info[element];
int direction = MovDir[x][y];
int dx = (direction == MV_LEFT ? -1 : direction == MV_RIGHT ? +1 : 0);
{
element = Feld[newx][newy] = EL_ACID;
}
+#if 0
+ else if (IS_CUSTOM_ELEMENT(element) && !IS_PLAYER(x, y) &&
+ ei->move_leave_element != EL_EMPTY &&
+ (ei->move_leave_type == LEAVE_TYPE_UNLIMITED ||
+ Store[x][y] != EL_EMPTY))
+ {
+ /* some elements can leave other elements behind after moving */
+
+ Feld[x][y] = ei->move_leave_element;
+ InitField(x, y, FALSE);
+
+ if (GFX_CRUMBLED(Feld[x][y]))
+ DrawLevelFieldCrumbledSandNeighbours(x, y);
+ }
+#endif
- Store[x][y] = 0;
+ Store[x][y] = EL_EMPTY;
MovPos[x][y] = MovDir[x][y] = MovDelay[x][y] = 0;
MovDelay[newx][newy] = 0;
ResetGfxAnimation(x, y); /* reset animation values for old field */
#if 1
+ if (IS_CUSTOM_ELEMENT(element) && !IS_PLAYER(x, y) &&
+ ei->move_leave_element != EL_EMPTY &&
+ (ei->move_leave_type == LEAVE_TYPE_UNLIMITED ||
+ stored != EL_EMPTY))
+ {
+ /* some elements can leave other elements behind after moving */
+
+ Feld[x][y] = ei->move_leave_element;
+ InitField(x, y, FALSE);
+
+ if (GFX_CRUMBLED(Feld[x][y]))
+ DrawLevelFieldCrumbledSandNeighbours(x, y);
+ }
+#endif
+
+#if 0
/* some elements can leave other elements behind after moving */
if (IS_CUSTOM_ELEMENT(element) && !IS_PLAYER(x, y) &&
ei->move_leave_element != EL_EMPTY &&
MovDir[newx][newy] = 0;
*/
+#if 0
if (!CAN_MOVE(element) ||
(CAN_FALL(element) && direction == MV_DOWN))
GfxDir[x][y] = MovDir[newx][newy] = 0;
+#else
+ if (!CAN_MOVE(element) ||
+ (CAN_FALL(element) && direction == MV_DOWN &&
+ (element == EL_SPRING ||
+ element_info[element].move_pattern == MV_WHEN_PUSHED ||
+ element_info[element].move_pattern == MV_WHEN_DROPPED)))
+ GfxDir[x][y] = MovDir[newx][newy] = 0;
+#endif
#endif
#endif
(newy == lev_fieldy - 1 || !IS_FREE(x, newy + 1)))
Impact(x, newy);
+#if 1
+ if (pushed_by_player)
+ {
+ static int trigger_sides[4] =
+ {
+ CH_SIDE_RIGHT, /* moving left */
+ CH_SIDE_LEFT, /* moving right */
+ CH_SIDE_BOTTOM, /* moving up */
+ CH_SIDE_TOP, /* moving down */
+ };
+ int dig_side = trigger_sides[MV_DIR_BIT(direction)];
+ struct PlayerInfo *player = PLAYERINFO(x, y);
+
+ CheckElementChangeByPlayer(newx, newy, element, CE_PUSHED_BY_PLAYER,
+ player->index_bit, dig_side);
+ CheckTriggeredElementChangeByPlayer(newx,newy,element,CE_OTHER_GETS_PUSHED,
+ player->index_bit, dig_side);
+ }
+#endif
+
#if 1
TestIfElementTouchesCustomElement(x, y); /* empty or new element */
#endif
int hitting_element = Feld[newx][newy];
/* !!! fix side (direction) orientation here and elsewhere !!! */
- CheckElementChangeSide(newx, newy, hitting_element, CE_HITTING_SOMETHING,
- direction);
+ CheckElementChangeBySide(newx, newy, hitting_element, CE_HITTING_SOMETHING,
+ direction);
#if 0
if (IN_LEV_FIELD(nextx, nexty))
{
int i;
- CheckElementChangeSide(nextx, nexty, touched_element,
- CE_HIT_BY_SOMETHING, opposite_direction);
+ CheckElementChangeBySide(nextx, nexty, touched_element,
+ CE_HIT_BY_SOMETHING, opposite_direction);
if (IS_CUSTOM_ELEMENT(hitting_element) &&
HAS_ANY_CHANGE_EVENT(hitting_element, CE_OTHER_IS_HITTING))
change->trigger_side & touched_side &&
change->trigger_element == touched_element)
{
- CheckElementChangePage(newx, newy, hitting_element,
- touched_element, CE_OTHER_IS_HITTING, i);
+ CheckElementChangeByPage(newx, newy, hitting_element,
+ touched_element, CE_OTHER_IS_HITTING,i);
break;
}
}
change->trigger_side & hitting_side &&
change->trigger_element == hitting_element)
{
- CheckElementChangePage(nextx, nexty, touched_element,
- hitting_element, CE_OTHER_GETS_HIT, i);
+ CheckElementChangeByPage(nextx, nexty, touched_element,
+ hitting_element, CE_OTHER_GETS_HIT, i);
break;
}
}
if (!IN_LEV_FIELD(x, y))
return;
+#if 1
+ if (IS_FREE(x, y) ||
+ CAN_GROW_INTO(Feld[x][y]) ||
+ Feld[x][y] == EL_QUICKSAND_EMPTY)
+ {
+ newax = x;
+ neway = y;
+ }
+#else
/* !!! extend EL_SAND to anything diggable (but maybe not SP_BASE) !!! */
if (IS_FREE(x, y) ||
Feld[x][y] == EL_SAND || Feld[x][y] == EL_QUICKSAND_EMPTY)
newax = x;
neway = y;
}
+#endif
if (newax == ax && neway == ay)
return;
if (!IN_LEV_FIELD(x, y))
continue;
+#if 1
+ if (IS_FREE(x, y) ||
+ CAN_GROW_INTO(Feld[x][y]) ||
+ Feld[x][y] == EL_QUICKSAND_EMPTY)
+ {
+ newax = x;
+ neway = y;
+ break;
+ }
+#else
/* !!! extend EL_SAND to anything diggable (but maybe not SP_BASE) !!! */
if (IS_FREE(x, y) ||
Feld[x][y] == EL_SAND || Feld[x][y] == EL_QUICKSAND_EMPTY)
neway = y;
break;
}
+#endif
else if (IS_PLAYER(x, y))
waiting_for_player = TRUE;
}
if (newax == ax && neway == ay) /* amoeba cannot grow */
{
+#if 1
+ if (i == 4 && (!waiting_for_player || element == EL_BD_AMOEBA))
+#else
if (i == 4 && (!waiting_for_player || game.emulation == EMU_BOULDERDASH))
+#endif
{
Feld[ax][ay] = EL_AMOEBA_DEAD;
DrawLevelField(ax, ay);
changed = TRUE;
}
}
+#if 1
+ else if (IS_FREE(xx, yy) || CAN_GROW_INTO(Feld[xx][yy]))
+ { /* free border field */
+ if (nachbarn >= life[2] && nachbarn <= life[3])
+ {
+ Feld[xx][yy] = element;
+ MovDelay[xx][yy] = (element == EL_GAME_OF_LIFE ? 0 : life_time-1);
+ if (!Stop[xx][yy])
+ DrawLevelField(xx, yy);
+ Stop[xx][yy] = TRUE;
+ changed = TRUE;
+ }
+ }
+#else
/* !!! extend EL_SAND to anything diggable (but maybe not SP_BASE) !!! */
else if (IS_FREE(xx, yy) || Feld[xx][yy] == EL_SAND)
{ /* free border field */
changed = TRUE;
}
}
+#endif
}
if (changed)
static void InitTimegateWheel(int x, int y)
{
+#if 1
+ ChangeDelay[x][y] = level.time_timegate * FRAMES_PER_SECOND;
+#else
+ /* another brainless, "type style" bug ... :-( */
ChangeDelay[x][y] = level.time_wheel * FRAMES_PER_SECOND;
+#endif
}
static void RunTimegateWheel(int x, int y)
Changed[x][y] |= ChangeEvent[x][y]; /* ignore same changes in this frame */
- CheckTriggeredElementChangePage(x,y, Feld[x][y], CE_OTHER_IS_CHANGING, page);
+ CheckTriggeredElementChangeByPage(x,y,Feld[x][y], CE_OTHER_IS_CHANGING,page);
if (change->explode)
{
e = MovingOrBlocked2Element(ex, ey);
#if 1
+
+#if 1
+ is_empty = (IS_FREE(ex, ey) || (IS_FREE_OR_PLAYER(ex, ey) &&
+ IS_WALKABLE(content_element)));
+#else
is_empty = (IS_FREE(ex, ey) || (IS_PLAYER(ex, ey) &&
IS_WALKABLE(content_element)));
+#endif
is_diggable = (is_empty || IS_DIGGABLE(e));
is_destructible = (is_empty || !IS_INDESTRUCTIBLE(e));
action_delay_value =
(tape.playing && tape.fast_forward ? FfwdFrameDelay : GameFrameDelay);
- if (tape.playing && tape.index_search && !tape.pausing)
+ if (tape.playing && tape.warp_forward && !tape.pausing)
action_delay_value = 0;
/* ---------- main game synchronization point ---------- */
#endif
element = Feld[x][y];
+#if 1
+ if (!IS_PLAYER(x,y) &&
+ (element == EL_EMPTY ||
+ CAN_GROW_INTO(element) ||
+ element == EL_QUICKSAND_EMPTY ||
+ element == EL_ACID_SPLASH_LEFT ||
+ element == EL_ACID_SPLASH_RIGHT))
+ {
+ if ((IN_LEV_FIELD(x, y-1) && Feld[x][y-1] == EL_AMOEBA_WET) ||
+ (IN_LEV_FIELD(x-1, y) && Feld[x-1][y] == EL_AMOEBA_WET) ||
+ (IN_LEV_FIELD(x+1, y) && Feld[x+1][y] == EL_AMOEBA_WET) ||
+ (IN_LEV_FIELD(x, y+1) && Feld[x][y+1] == EL_AMOEBA_WET))
+ Feld[x][y] = EL_AMOEBA_DROP;
+ }
+#else
/* !!! extend EL_SAND to anything diggable (but maybe not SP_BASE) !!! */
if (!IS_PLAYER(x,y) &&
(element == EL_EMPTY ||
(IN_LEV_FIELD(x, y+1) && Feld[x][y+1] == EL_AMOEBA_WET))
Feld[x][y] = EL_AMOEBA_DROP;
}
+#endif
random = random * 129 + 1;
}
redraw_mask |= REDRAW_FIELD;
}
+#if 0
static boolean canEnterSupaplexPort(int x, int y, int dx, int dy)
{
int nextx = x + dx, nexty = y + dy;
return TRUE;
}
+#endif
+
+static boolean canFallDown(struct PlayerInfo *player)
+{
+ int jx = player->jx, jy = player->jy;
+
+ return (IN_LEV_FIELD(jx, jy + 1) &&
+ (IS_FREE(jx, jy + 1) ||
+ (Feld[jx][jy + 1] == EL_ACID && player->can_fall_into_acid)) &&
+ IS_WALKABLE_FROM(Feld[jx][jy], MV_DOWN) &&
+ !IS_WALKABLE_INSIDE(Feld[jx][jy]));
+}
+
+static boolean canPassField(int x, int y, int move_dir)
+{
+ int opposite_dir = MV_DIR_OPPOSITE(move_dir);
+ int dx = (move_dir & MV_LEFT ? -1 : move_dir & MV_RIGHT ? +1 : 0);
+ int dy = (move_dir & MV_UP ? -1 : move_dir & MV_DOWN ? +1 : 0);
+ int nextx = x + dx;
+ int nexty = y + dy;
+ int element = Feld[x][y];
+
+ return (IS_PASSABLE_FROM(element, opposite_dir) &&
+ !CAN_MOVE(element) &&
+ IN_LEV_FIELD(nextx, nexty) && !IS_PLAYER(nextx, nexty) &&
+ IS_WALKABLE_FROM(Feld[nextx][nexty], move_dir) &&
+ (level.can_pass_to_walkable || IS_FREE(nextx, nexty)));
+}
+
+static boolean canMoveToValidFieldWithGravity(int x, int y, int move_dir)
+{
+ int opposite_dir = MV_DIR_OPPOSITE(move_dir);
+ int dx = (move_dir & MV_LEFT ? -1 : move_dir & MV_RIGHT ? +1 : 0);
+ int dy = (move_dir & MV_UP ? -1 : move_dir & MV_DOWN ? +1 : 0);
+ int newx = x + dx;
+ int newy = y + dy;
+#if 0
+ int nextx = newx + dx;
+ int nexty = newy + dy;
+#endif
+
+#if 1
+ return (IN_LEV_FIELD(newx, newy) && !IS_FREE_OR_PLAYER(newx, newy) &&
+ (IS_DIGGABLE(Feld[newx][newy]) ||
+ IS_WALKABLE_FROM(Feld[newx][newy], opposite_dir) ||
+ canPassField(newx, newy, move_dir)));
+#else
+ return (IN_LEV_FIELD(newx, newy) && !IS_FREE_OR_PLAYER(newx, newy) &&
+ (IS_DIGGABLE(Feld[newx][newy]) ||
+ IS_WALKABLE_FROM(Feld[newx][newy], opposite_dir) ||
+ (IS_PASSABLE_FROM(Feld[newx][newy], opposite_dir) &&
+ !CAN_MOVE(Feld[newx][newy]) &&
+ IN_LEV_FIELD(nextx, nexty) && !IS_PLAYER(nextx, nexty) &&
+ IS_WALKABLE_FROM(Feld[nextx][nexty], move_dir) &&
+ (level.can_pass_to_walkable || IS_FREE(nextx, nexty)))));
+#endif
+}
static void CheckGravityMovement(struct PlayerInfo *player)
{
int move_dir_horizontal = player->action & MV_HORIZONTAL;
int move_dir_vertical = player->action & MV_VERTICAL;
#endif
+
+#if 1
+ boolean player_is_snapping = player->effective_action & JOY_BUTTON_1;
+#else
+ boolean player_is_snapping = player->action & JOY_BUTTON_1;
+#endif
+
+ int jx = player->jx, jy = player->jy;
+
+ boolean player_is_moving_to_valid_field =
+ (!player_is_snapping &&
+ (canMoveToValidFieldWithGravity(jx, jy, move_dir_horizontal) ||
+ canMoveToValidFieldWithGravity(jx, jy, move_dir_vertical)));
+
+#if 0
int move_dir =
(player->last_move_dir & MV_HORIZONTAL ?
(move_dir_vertical ? move_dir_vertical : move_dir_horizontal) :
(move_dir_horizontal ? move_dir_horizontal : move_dir_vertical));
- int jx = player->jx, jy = player->jy;
+#endif
+
+#if 0
+ int opposite_dir = MV_DIR_OPPOSITE(move_dir);
int dx = (move_dir & MV_LEFT ? -1 : move_dir & MV_RIGHT ? +1 : 0);
int dy = (move_dir & MV_UP ? -1 : move_dir & MV_DOWN ? +1 : 0);
int new_jx = jx + dx, new_jy = jy + dy;
-#if 1
- boolean player_is_snapping = player->effective_action & JOY_BUTTON_1;
-#else
- boolean player_is_snapping = player->action & JOY_BUTTON_1;
+ int nextx = new_jx + dx, nexty = new_jy + dy;
#endif
+
+#if 1
+
#if 1
+ boolean player_can_fall_down = canFallDown(player);
+#else
boolean player_can_fall_down =
(IN_LEV_FIELD(jx, jy + 1) &&
(IS_FREE(jx, jy + 1) ||
(Feld[jx][jy + 1] == EL_ACID && player->can_fall_into_acid)));
+#endif
+
#else
boolean player_can_fall_down =
(IN_LEV_FIELD(jx, jy + 1) &&
(IS_FREE(jx, jy + 1)));
#endif
+
+#if 0
boolean player_is_moving_to_valid_field =
(
#if 1
!player_is_snapping &&
#endif
+
+#if 1
+ IN_LEV_FIELD(new_jx, new_jy) &&
+ (IS_DIGGABLE(Feld[new_jx][new_jy]) ||
+ (IS_SP_PORT(Feld[new_jx][new_jy]) &&
+ element_info[Feld[new_jx][new_jy]].access_direction & opposite_dir &&
+ IN_LEV_FIELD(nextx, nexty) &&
+ element_info[Feld[nextx][nexty]].access_direction & move_dir))
+#else
IN_LEV_FIELD(new_jx, new_jy) &&
(Feld[new_jx][new_jy] == EL_SP_BASE ||
Feld[new_jx][new_jy] == EL_SAND ||
(IS_SP_PORT(Feld[new_jx][new_jy]) &&
- canEnterSupaplexPort(new_jx, new_jy, dx, dy))));
+ canEnterSupaplexPort(new_jx, new_jy, dx, dy)))
/* !!! extend EL_SAND to anything diggable !!! */
+#endif
+ );
+#endif
+#if 0
boolean player_is_standing_on_valid_field =
(IS_WALKABLE_INSIDE(Feld[jx][jy]) ||
- (IS_WALKABLE(Feld[jx][jy]) &&
- !(element_info[Feld[jx][jy]].access_direction & MV_DOWN)));
+ (IS_WALKABLE(Feld[jx][jy]) && !ACCESS_FROM(Feld[jx][jy], MV_DOWN)));
+#endif
#if 0
printf("::: checking gravity NOW [%d, %d, %d] [%d] [%d / %d] ...\n",
#endif
if (player_can_fall_down &&
+#if 0
!player_is_standing_on_valid_field &&
+#endif
!player_is_moving_to_valid_field)
{
#if 0
player->step_counter++;
+#if 0
player->drop_delay = 0;
+#endif
PlayerVisit[jx][jy] = FrameCounter;
#if 0
if (IS_CUSTOM_ELEMENT(Feld[jx][jy]))
{
- CheckTriggeredElementChangeSide(jx, jy, Feld[jx][jy], CE_OTHER_GETS_LEFT,
- leave_side);
- CheckElementChangeSide(jx, jy, Feld[jx][jy], CE_LEFT_BY_PLAYER,leave_side);
+ CheckTriggeredElementChangeBySide(jx, jy, Feld[jx][jy], CE_OTHER_GETS_LEFT,
+ leave_side);
+ CheckElementChangeBySide(jx,jy, Feld[jx][jy],CE_LEFT_BY_PLAYER,leave_side);
}
if (IS_CUSTOM_ELEMENT(Feld[new_jx][new_jy]))
{
- CheckTriggeredElementChangeSide(new_jx, new_jy, Feld[new_jx][new_jy],
- CE_OTHER_GETS_ENTERED, enter_side);
- CheckElementChangeSide(new_jx, new_jy, Feld[new_jx][new_jy],
- CE_ENTERED_BY_PLAYER, enter_side);
+ CheckTriggeredElementChangeBySide(new_jx, new_jy, Feld[new_jx][new_jy],
+ CE_OTHER_GETS_ENTERED, enter_side);
+ CheckElementChangeBySide(new_jx, new_jy, Feld[new_jx][new_jy],
+ CE_ENTERED_BY_PLAYER, enter_side);
}
#endif
#endif
+ /* store if player is automatically moved to next field */
+ player->is_auto_moving = (player->programmed_action != MV_NO_MOVING);
+
/* remove the last programmed player action */
player->programmed_action = 0;
#if 0
/* !!! ENABLE THIS FOR OLD VERSIONS !!! */
+
+#if 1
+ if (game.engine_version < VERSION_IDENT(3,1,0,0))
+#endif
{
static int trigger_sides[4][2] =
{
int leave_side = trigger_sides[MV_DIR_BIT(move_direction)][1];
#if 1
- CheckTriggeredElementChangePlayer(old_jx, old_jy, Feld[old_jx][old_jy],
- CE_OTHER_GETS_LEFT,
- player->index_bit, leave_side);
-
+ /* !!! TEST ONLY !!! */
if (IS_CUSTOM_ELEMENT(Feld[old_jx][old_jy]))
- CheckElementChangePlayer(old_jx, old_jy, Feld[old_jx][old_jy],
- CE_LEFT_BY_PLAYER,
- player->index_bit, leave_side);
+ CheckElementChangeByPlayer(old_jx, old_jy, Feld[old_jx][old_jy],
+ CE_LEFT_BY_PLAYER,
+ player->index_bit, leave_side);
- CheckTriggeredElementChangePlayer(jx, jy, Feld[jx][jy],
- CE_OTHER_GETS_ENTERED,
- player->index_bit, enter_side);
+ CheckTriggeredElementChangeByPlayer(old_jx, old_jy, Feld[old_jx][old_jy],
+ CE_OTHER_GETS_LEFT,
+ player->index_bit, leave_side);
if (IS_CUSTOM_ELEMENT(Feld[jx][jy]))
- CheckElementChangePlayer(jx, jy, Feld[jx][jy], CE_ENTERED_BY_PLAYER,
- player->index_bit, enter_side);
+ CheckElementChangeByPlayer(jx, jy, Feld[jx][jy], CE_ENTERED_BY_PLAYER,
+ player->index_bit, enter_side);
+
+ CheckTriggeredElementChangeByPlayer(jx, jy, Feld[jx][jy],
+ CE_OTHER_GETS_ENTERED,
+ player->index_bit, enter_side);
#endif
}
#if 1
/* !!! ENABLE THIS FOR NEW VERSIONS !!! */
/* this breaks one level: "machine", level 000 */
+#if 0
+ if (game.engine_version >= VERSION_IDENT(3,1,0,0))
+#endif
{
static int trigger_sides[4][2] =
{
int old_jy = last_jy;
#if 1
- CheckTriggeredElementChangePlayer(old_jx, old_jy, Feld[old_jx][old_jy],
- CE_OTHER_GETS_LEFT,
- player->index_bit, leave_side);
-
+ /* !!! TEST ONLY !!! */
if (IS_CUSTOM_ELEMENT(Feld[old_jx][old_jy]))
- CheckElementChangePlayer(old_jx, old_jy, Feld[old_jx][old_jy],
- CE_LEFT_BY_PLAYER,
- player->index_bit, leave_side);
+ CheckElementChangeByPlayer(old_jx, old_jy, Feld[old_jx][old_jy],
+ CE_LEFT_BY_PLAYER,
+ player->index_bit, leave_side);
- CheckTriggeredElementChangePlayer(jx, jy, Feld[jx][jy],
- CE_OTHER_GETS_ENTERED,
- player->index_bit, enter_side);
+ CheckTriggeredElementChangeByPlayer(old_jx, old_jy, Feld[old_jx][old_jy],
+ CE_OTHER_GETS_LEFT,
+ player->index_bit, leave_side);
if (IS_CUSTOM_ELEMENT(Feld[jx][jy]))
- CheckElementChangePlayer(jx, jy, Feld[jx][jy], CE_ENTERED_BY_PLAYER,
- player->index_bit, enter_side);
+ CheckElementChangeByPlayer(jx, jy, Feld[jx][jy], CE_ENTERED_BY_PLAYER,
+ player->index_bit, enter_side);
+
+ CheckTriggeredElementChangeByPlayer(jx, jy, Feld[jx][jy],
+ CE_OTHER_GETS_ENTERED,
+ player->index_bit, enter_side);
#endif
}
else
continue; /* center and border element do not touch */
- CheckTriggeredElementChangePlayer(xx, yy, border_element,
- CE_OTHER_GETS_TOUCHED,
- player->index_bit, border_side);
- CheckElementChangePlayer(xx, yy, border_element, CE_TOUCHED_BY_PLAYER,
- player->index_bit, border_side);
+#if 1
+ /* !!! TEST ONLY !!! */
+ CheckElementChangeByPlayer(xx, yy, border_element, CE_TOUCHED_BY_PLAYER,
+ player->index_bit, border_side);
+ CheckTriggeredElementChangeByPlayer(xx, yy, border_element,
+ CE_OTHER_GETS_TOUCHED,
+ player->index_bit, border_side);
+#else
+ CheckTriggeredElementChangeByPlayer(xx, yy, border_element,
+ CE_OTHER_GETS_TOUCHED,
+ player->index_bit, border_side);
+ CheckElementChangeByPlayer(xx, yy, border_element, CE_TOUCHED_BY_PLAYER,
+ player->index_bit, border_side);
+#endif
}
else if (IS_PLAYER(xx, yy))
{
continue; /* center and border element do not touch */
}
- CheckTriggeredElementChangePlayer(x, y, center_element,
- CE_OTHER_GETS_TOUCHED,
- player->index_bit, center_side);
- CheckElementChangePlayer(x, y, center_element, CE_TOUCHED_BY_PLAYER,
- player->index_bit, center_side);
+#if 1
+ /* !!! TEST ONLY !!! */
+ CheckElementChangeByPlayer(x, y, center_element, CE_TOUCHED_BY_PLAYER,
+ player->index_bit, center_side);
+ CheckTriggeredElementChangeByPlayer(x, y, center_element,
+ CE_OTHER_GETS_TOUCHED,
+ player->index_bit, center_side);
+#else
+ CheckTriggeredElementChangeByPlayer(x, y, center_element,
+ CE_OTHER_GETS_TOUCHED,
+ player->index_bit, center_side);
+ CheckElementChangeByPlayer(x, y, center_element, CE_TOUCHED_BY_PLAYER,
+ player->index_bit, center_side);
+#endif
break;
}
printf("::: border_element %d, %d\n", x, y);
#endif
- CheckElementChangePage(xx, yy, border_element, center_element,
- CE_OTHER_IS_TOUCHING, j);
+ CheckElementChangeByPage(xx, yy, border_element, center_element,
+ CE_OTHER_IS_TOUCHING, j);
break;
}
}
printf("::: center_element %d, %d\n", x, y);
#endif
- CheckElementChangePage(x, y, center_element, border_trigger_element,
- CE_OTHER_IS_TOUCHING, center_element_change_page);
+ CheckElementChangeByPage(x, y, center_element, border_trigger_element,
+ CE_OTHER_IS_TOUCHING, center_element_change_page);
}
}
touched_element = (IN_LEV_FIELD(hitx, hity) ?
MovingOrBlocked2Element(hitx, hity) : EL_STEELWALL);
- CheckElementChangeSide(x, y, hitting_element, touched_element,
- CE_HITTING_SOMETHING, direction);
+ CheckElementChangeBySide(x, y, hitting_element, touched_element,
+ CE_HITTING_SOMETHING, direction);
if (IN_LEV_FIELD(hitx, hity))
{
{
int i;
- CheckElementChangeSide(hitx, hity, touched_element, hitting_element,
- CE_HIT_BY_SOMETHING, opposite_direction);
+ CheckElementChangeBySide(hitx, hity, touched_element, hitting_element,
+ CE_HIT_BY_SOMETHING, opposite_direction);
if (IS_CUSTOM_ELEMENT(hitting_element) &&
HAS_ANY_CHANGE_EVENT(hitting_element, CE_OTHER_IS_HITTING))
#endif
)
{
- CheckElementChangePage(x, y, hitting_element, touched_element,
- CE_OTHER_IS_HITTING, i);
+ CheckElementChangeByPage(x, y, hitting_element, touched_element,
+ CE_OTHER_IS_HITTING, i);
break;
}
}
#endif
)
{
- CheckElementChangePage(hitx, hity, touched_element,
- hitting_element, CE_OTHER_GETS_HIT, i);
+ CheckElementChangeByPage(hitx, hity, touched_element,
+ hitting_element, CE_OTHER_GETS_HIT, i);
break;
}
}
touched_element = (IN_LEV_FIELD(hitx, hity) ?
MovingOrBlocked2Element(hitx, hity) : EL_STEELWALL);
- CheckElementChangeSide(x, y, hitting_element, touched_element,
- EP_CAN_SMASH_EVERYTHING, direction);
+ CheckElementChangeBySide(x, y, hitting_element, touched_element,
+ EP_CAN_SMASH_EVERYTHING, direction);
if (IN_LEV_FIELD(hitx, hity))
{
{
int i;
- CheckElementChangeSide(hitx, hity, touched_element, hitting_element,
- CE_SMASHED_BY_SOMETHING, opposite_direction);
+ CheckElementChangeBySide(hitx, hity, touched_element, hitting_element,
+ CE_SMASHED_BY_SOMETHING, opposite_direction);
if (IS_CUSTOM_ELEMENT(hitting_element) &&
HAS_ANY_CHANGE_EVENT(hitting_element, CE_OTHER_IS_SMASHING))
#endif
)
{
- CheckElementChangePage(x, y, hitting_element, touched_element,
- CE_OTHER_IS_SMASHING, i);
+ CheckElementChangeByPage(x, y, hitting_element, touched_element,
+ CE_OTHER_IS_SMASHING, i);
break;
}
}
#endif
)
{
- CheckElementChangePage(hitx, hity, touched_element,
- hitting_element, CE_OTHER_GETS_SMASHED, i);
+ CheckElementChangeByPage(hitx, hity, touched_element,
+ hitting_element, CE_OTHER_GETS_SMASHED,i);
break;
}
}
void TestIfGoodThingHitsBadThing(int good_x, int good_y, int good_move_dir)
{
int i, kill_x = -1, kill_y = -1;
+ int bad_element = -1;
static int test_xy[4][2] =
{
{ 0, -1 },
test_x = good_x + test_xy[i][0];
test_y = good_y + test_xy[i][1];
+
if (!IN_LEV_FIELD(test_x, test_y))
continue;
{
kill_x = test_x;
kill_y = test_y;
+ bad_element = test_element;
+
break;
}
}
{
struct PlayerInfo *player = PLAYERINFO(good_x, good_y);
+#if 1
+ if (player->shield_deadly_time_left > 0 &&
+ !IS_INDESTRUCTIBLE(bad_element))
+ Bang(kill_x, kill_y);
+ else if (!PLAYER_ENEMY_PROTECTED(good_x, good_y))
+ KillHero(player);
+#else
if (player->shield_deadly_time_left > 0)
Bang(kill_x, kill_y);
else if (!PLAYER_ENEMY_PROTECTED(good_x, good_y))
KillHero(player);
+#endif
}
else
Bang(good_x, good_y);
{
struct PlayerInfo *player = PLAYERINFO(kill_x, kill_y);
+#if 1
+ if (player->shield_deadly_time_left > 0 &&
+ !IS_INDESTRUCTIBLE(bad_element))
+ Bang(bad_x, bad_y);
+ else if (!PLAYER_ENEMY_PROTECTED(kill_x, kill_y))
+ KillHero(player);
+#else
if (player->shield_deadly_time_left > 0)
Bang(bad_x, bad_y);
else if (!PLAYER_ENEMY_PROTECTED(kill_x, kill_y))
KillHero(player);
+#endif
}
else
Bang(kill_x, kill_y);
#endif
- if (IS_WALKABLE(old_element) &&
- !(element_info[old_element].access_direction & move_direction))
+ if (IS_WALKABLE(old_element) && !ACCESS_FROM(old_element, move_direction))
+ return MF_NO_ACTION; /* field has no opening in this direction */
+
+ if (IS_PASSABLE(old_element) && !ACCESS_FROM(old_element,opposite_direction))
return MF_NO_ACTION; /* field has no opening in this direction */
element = Feld[x][y];
switch (element)
{
+#if 0
case EL_SP_PORT_LEFT:
case EL_SP_PORT_RIGHT:
case EL_SP_PORT_UP:
PlayLevelSound(x, y, SND_CLASS_SP_PORT_PASSING);
break;
+#endif
#if 0
case EL_TUBE_ANY:
{
int sound_action = ACTION_WALKING;
- if (!(element_info[element].access_direction & opposite_direction))
+ if (!ACCESS_FROM(element, opposite_direction))
return MF_NO_ACTION; /* field not accessible from this direction */
- if (element >= EL_GATE_1 && element <= EL_GATE_4)
+#if 1
+ if (element == EL_EMPTY_SPACE &&
+ game.gravity && !player->is_auto_moving &&
+ canFallDown(player) && move_direction != MV_DOWN)
+ return MF_NO_ACTION; /* player cannot walk here due to gravity */
+#endif
+
+ if (IS_GATE(element))
{
if (!player->key[element - EL_GATE_1])
return MF_NO_ACTION;
}
- else if (element >= EL_GATE_1_GRAY && element <= EL_GATE_4_GRAY)
+ else if (IS_GATE_GRAY(element))
{
if (!player->key[element - EL_GATE_1_GRAY])
return MF_NO_ACTION;
}
else if (IS_PASSABLE(element))
{
+#if 1
+ if (!canPassField(x, y, move_direction))
+ return MF_NO_ACTION;
+#else
+
+#if 1
+ if (!IN_LEV_FIELD(nextx, nexty) || IS_PLAYER(nextx, nexty) ||
+ !IS_WALKABLE_FROM(Feld[nextx][nexty], move_direction) ||
+ (!level.can_pass_to_walkable && !IS_FREE(nextx, nexty)))
+ return MF_NO_ACTION;
+#else
if (!IN_LEV_FIELD(nextx, nexty) || !IS_FREE(nextx, nexty))
return MF_NO_ACTION;
+#endif
+#if 1
+ if (!ACCESS_FROM(element, opposite_direction))
+ return MF_NO_ACTION; /* field not accessible from this direction */
+#else
if (IS_CUSTOM_ELEMENT(element) &&
- !(element_info[element].access_direction & opposite_direction))
+ !ACCESS_FROM(element, opposite_direction))
return MF_NO_ACTION; /* field not accessible from this direction */
+#endif
#if 1
if (CAN_MOVE(element)) /* only fixed elements can be passed! */
return MF_NO_ACTION;
#endif
- if (element >= EL_EM_GATE_1 && element <= EL_EM_GATE_4)
+#endif
+
+ if (IS_EM_GATE(element))
{
if (!player->key[element - EL_EM_GATE_1])
return MF_NO_ACTION;
}
- else if (element >= EL_EM_GATE_1_GRAY && element <= EL_EM_GATE_4_GRAY)
+ else if (IS_EM_GATE_GRAY(element))
{
if (!player->key[element - EL_EM_GATE_1_GRAY])
return MF_NO_ACTION;
}
+ else if (IS_SP_PORT(element))
+ {
+ if (element == EL_SP_GRAVITY_PORT_LEFT ||
+ element == EL_SP_GRAVITY_PORT_RIGHT ||
+ element == EL_SP_GRAVITY_PORT_UP ||
+ element == EL_SP_GRAVITY_PORT_DOWN)
+ game.gravity = !game.gravity;
+ }
/* automatically move to the next field with double speed */
player->programmed_action = move_direction;
PlayLevelSoundElementAction(x, y, element, ACTION_DIGGING);
- CheckTriggeredElementChangePlayer(x, y, element, CE_OTHER_GETS_DIGGED,
- player->index_bit, dig_side);
+ CheckTriggeredElementChangeByPlayer(x, y, element,CE_OTHER_GETS_DIGGED,
+ player->index_bit, dig_side);
#if 1
if (mode == DF_SNAP)
RaiseScoreElement(element);
PlayLevelSoundElementAction(x, y, element, ACTION_COLLECTING);
- CheckTriggeredElementChangePlayer(x, y, element,
- CE_OTHER_GETS_COLLECTED,
- player->index_bit, dig_side);
+ CheckTriggeredElementChangeByPlayer(x, y, element,
+ CE_OTHER_GETS_COLLECTED,
+ player->index_bit, dig_side);
#if 1
if (mode == DF_SNAP)
else
player->push_delay_value = -1; /* get new value later */
- CheckTriggeredElementChangePlayer(x, y, element, CE_OTHER_GETS_PUSHED,
- player->index_bit, dig_side);
- CheckElementChangePlayer(x, y, element, CE_PUSHED_BY_PLAYER,
- player->index_bit, dig_side);
+#if 1
+ /* check for element change _after_ element has been pushed! */
+#else
+
+#if 1
+ /* !!! TEST ONLY !!! */
+ CheckElementChangeByPlayer(x, y, element, CE_PUSHED_BY_PLAYER,
+ player->index_bit, dig_side);
+ CheckTriggeredElementChangeByPlayer(x, y, element,CE_OTHER_GETS_PUSHED,
+ player->index_bit, dig_side);
+#else
+ CheckTriggeredElementChangeByPlayer(x, y, element,CE_OTHER_GETS_PUSHED,
+ player->index_bit, dig_side);
+ CheckElementChangeByPlayer(x, y, element, CE_PUSHED_BY_PLAYER,
+ player->index_bit, dig_side);
+#endif
+#endif
break;
}
player->switch_x = x;
player->switch_y = y;
- CheckTriggeredElementChangePlayer(x, y, element,
- CE_OTHER_IS_SWITCHING,
- player->index_bit, dig_side);
- CheckElementChangePlayer(x, y, element, CE_SWITCHED,
- player->index_bit, dig_side);
+#if 1
+ /* !!! TEST ONLY !!! */
+ CheckElementChangeByPlayer(x, y, element, CE_SWITCHED,
+ player->index_bit, dig_side);
+ CheckTriggeredElementChangeByPlayer(x, y, element,
+ CE_OTHER_IS_SWITCHING,
+ player->index_bit, dig_side);
+#else
+ CheckTriggeredElementChangeByPlayer(x, y, element,
+ CE_OTHER_IS_SWITCHING,
+ player->index_bit, dig_side);
+ CheckElementChangeByPlayer(x, y, element, CE_SWITCHED,
+ player->index_bit, dig_side);
+#endif
}
- CheckTriggeredElementChangePlayer(x, y, element, CE_OTHER_GETS_PRESSED,
- player->index_bit, dig_side);
- CheckElementChangePlayer(x, y, element, CE_PRESSED_BY_PLAYER,
- player->index_bit, dig_side);
+#if 1
+ /* !!! TEST ONLY !!! (this breaks "machine", level 000) */
+ CheckElementChangeByPlayer(x, y, element, CE_PRESSED_BY_PLAYER,
+ player->index_bit, dig_side);
+ CheckTriggeredElementChangeByPlayer(x,y, element,CE_OTHER_GETS_PRESSED,
+ player->index_bit, dig_side);
+#else
+ CheckTriggeredElementChangeByPlayer(x,y, element,CE_OTHER_GETS_PRESSED,
+ player->index_bit, dig_side);
+ CheckElementChangeByPlayer(x, y, element, CE_PRESSED_BY_PLAYER,
+ player->index_bit, dig_side);
+#endif
}
return MF_NO_ACTION;
int drop_direction = player->MovDir;
int drop_side = trigger_sides[MV_DIR_BIT(drop_direction)];
int old_element = Feld[jx][jy];
- int new_element = (player->inventory_size > 0 ?
- player->inventory_element[player->inventory_size - 1] :
- player->inventory_infinite_element != EL_UNDEFINED ?
- player->inventory_infinite_element :
- player->dynabombs_left > 0 ?
- EL_DYNABOMB_PLAYER_1_ACTIVE + player->index_nr :
- EL_UNDEFINED);
+ int drop_element = (player->inventory_size > 0 ?
+ player->inventory_element[player->inventory_size - 1] :
+ player->inventory_infinite_element != EL_UNDEFINED ?
+ player->inventory_infinite_element :
+ player->dynabombs_left > 0 ?
+ EL_DYNABOMB_PLAYER_1_ACTIVE + player->index_nr :
+ EL_UNDEFINED);
+ int new_element = drop_element; /* default: element does not change */
/* check if player is active, not moving and ready to drop */
if (!player->active || player->MovPos || player->drop_delay > 0)
Changed[jx][jy] = 0; /* allow another change */
#endif
- CheckTriggeredElementChangePlayer(jx, jy, new_element,
- CE_OTHER_GETS_DROPPED,
- player->index_bit, drop_side);
- CheckElementChangePlayer(jx, jy, new_element, CE_DROPPED_BY_PLAYER,
- player->index_bit, drop_side);
+#if 1
+ /* !!! TEST ONLY !!! */
+ CheckElementChangeByPlayer(jx, jy, new_element, CE_DROPPED_BY_PLAYER,
+ player->index_bit, drop_side);
+ CheckTriggeredElementChangeByPlayer(jx, jy, new_element,
+ CE_OTHER_GETS_DROPPED,
+ player->index_bit, drop_side);
+#else
+ CheckTriggeredElementChangeByPlayer(jx, jy, new_element,
+ CE_OTHER_GETS_DROPPED,
+ player->index_bit, drop_side);
+ CheckElementChangeByPlayer(jx, jy, new_element, CE_DROPPED_BY_PLAYER,
+ player->index_bit, drop_side);
+#endif
TestIfElementTouchesCustomElement(jx, jy);
}
#endif
}
- new_element = Feld[jx][jy];
+ new_element = Feld[jx][jy]; /* element might have changed */
if (IS_CUSTOM_ELEMENT(new_element) && CAN_MOVE(new_element) &&
element_info[new_element].move_pattern == MV_WHEN_DROPPED)
{
+#if 0
int move_stepsize = element_info[new_element].move_stepsize;
+#endif
int direction, dx, dy, nextx, nexty;
if (element_info[new_element].move_direction_initial == MV_START_AUTOMATIC)
#if 1
TestIfElementHitsCustomElement(jx, jy, direction);
#else
- CheckElementChangeSide(jx, jy, new_element, touched_element,
- CE_HITTING_SOMETHING, direction);
+ CheckElementChangeBySide(jx, jy, new_element, touched_element,
+ CE_HITTING_SOMETHING, direction);
#endif
}
+#if 0
player->drop_delay = 2 * TILEX / move_stepsize + 1;
+#endif
}
#if 0
player->drop_delay = 8 + 8 + 8;
#endif
+#if 1
+ player->drop_delay = GET_NEW_DROP_DELAY(drop_element);
+#endif
+
#endif
player->is_dropping = TRUE;
{
#if 1
- if (tape.playing && tape.index_search)
- {
- SetDrawDeactivationMask(REDRAW_NONE);
- audio.sound_deactivated = FALSE;
- }
+ if (tape.playing && tape.deactivate_display)
+ TapeDeactivateDisplayOff(TRUE);
#endif
OpenDoor(DOOR_OPEN_1 | DOOR_COPY_BACK);
#if 1
- if (tape.playing && tape.index_search)
- {
- SetDrawDeactivationMask(REDRAW_FIELD);
- audio.sound_deactivated = TRUE;
- }
+ if (tape.playing && tape.deactivate_display)
+ TapeDeactivateDisplayOn();
#endif
}