static void TestIfPlayerTouchesCustomElement(int, int);
static void TestIfElementTouchesCustomElement(int, int);
+static boolean CheckTriggeredElementSideChange(int, int, int, int, int);
static boolean CheckTriggeredElementChange(int, int, int, int);
+static boolean CheckElementSideChange(int, int, int, int, int, int);
static boolean CheckElementChange(int, int, int, int);
static void PlaySoundLevel(int, int, int);
MovDir[x][y] = 1 << RND(4);
break;
+#if 0
case EL_SP_EMPTY:
Feld[x][y] = EL_EMPTY;
break;
+#endif
+#if 0
case EL_EM_KEY_1_FILE:
Feld[x][y] = EL_EM_KEY_1;
break;
case EL_EM_KEY_4_FILE:
Feld[x][y] = EL_EM_KEY_4;
break;
+#endif
case EL_CONVEYOR_BELT_1_SWITCH_LEFT:
case EL_CONVEYOR_BELT_1_SWITCH_MIDDLE:
ei->change_events = CE_BITMASK_DEFAULT;
for (j=0; j < NUM_CHANGE_EVENTS; j++)
{
- ei->event_page_num[j] = 0;
+ ei->event_page_nr[j] = 0;
ei->event_page[j] = &ei->change_page[0];
}
}
ei->change_events |= CH_EVENT_BIT(CE_DELAY);
}
- /* set summarized change event CE_TOUCHING_ANY_SIDE_OF */
- for (i=0; i < NUM_CUSTOM_ELEMENTS; i++)
- {
- struct ElementInfo *ei = &element_info[EL_CUSTOM_START + i];
-
- for (j=0; j < ei->num_change_pages; j++)
- {
- if (!ei->change_page[j].can_change)
- continue;
-
- /* check for change event of touching other element on some side */
- if (ei->change_page[j].events & (CH_EVENT_BIT(CE_TOUCHING_ANY_SIDE_OF |
- CE_TOUCHING_LEFT_OF |
- CE_TOUCHING_RIGHT_OF |
- CE_TOUCHING_TOP_OF |
- CE_TOUCHING_BOTTOM_OF)))
- ei->change_page[j].events |= CH_EVENT_BIT(CE_TOUCHING_SOME_SIDE);
-
- /* add change event for each side when event exists for any side */
- if (ei->change_page[j].events & CH_EVENT_BIT(CE_TOUCHING_ANY_SIDE_OF))
- ei->change_page[j].events |= (CH_EVENT_BIT(CE_TOUCHING_LEFT_OF) |
- CH_EVENT_BIT(CE_TOUCHING_RIGHT_OF) |
- CH_EVENT_BIT(CE_TOUCHING_TOP_OF) |
- CH_EVENT_BIT(CE_TOUCHING_BOTTOM_OF));
- }
- }
-
#if 1
/* add change events from custom element configuration */
for (i=0; i < NUM_CUSTOM_ELEMENTS; i++)
!(ei->change_events & CH_EVENT_BIT(k)))
{
ei->change_events |= CH_EVENT_BIT(k);
- ei->event_page_num[k] = j;
+ ei->event_page_nr[k] = j;
ei->event_page[k] = &ei->change_page[j];
}
}
player->is_digging = FALSE;
player->is_collecting = FALSE;
- player->show_envelope = FALSE;
+ player->show_envelope = 0;
player->move_delay = game.initial_move_delay;
player->move_delay_value = game.initial_move_delay_value;
/* copy element change control values to new field */
ChangeDelay[newx][newy] = ChangeDelay[x][y];
+#if 1
Changed[newx][newy] = Changed[x][y];
ChangeEvent[newx][newy] = ChangeEvent[x][y];
ChangeDelay[x][y] = 0;
Changed[x][y] = CE_BITMASK_DEFAULT;
ChangeEvent[x][y] = CE_BITMASK_DEFAULT;
+#endif
/* copy animation control values to new field */
GfxFrame[newx][newy] = GfxFrame[x][y];
int element = MovingOrBlocked2Element(x, y);
struct ElementChangeInfo *change = &element_info[element].change_page[page];
+#ifdef DEBUG
+ if (!CAN_CHANGE(element))
+ {
+ printf("\n\n\n");
+ printf("ChangeElement(): element = %d\n", element);
+ printf("Explode(): This should never happen!\n");
+ printf("\n\n\n");
+ }
+#endif
+
if (ChangeDelay[x][y] == 0) /* initialize element change */
{
ChangeDelay[x][y] = ( change->delay_fixed * change->delay_frames +
}
}
-static boolean CheckTriggeredElementChange(int lx, int ly, int trigger_element,
- int trigger_event)
+static boolean CheckTriggeredElementSideChange(int lx, int ly,
+ int trigger_element,
+ int trigger_side,
+ int trigger_event)
{
int i, j, x, y;
if (!(trigger_events[trigger_element] & CH_EVENT_BIT(trigger_event)))
return FALSE;
-#if 0
- /* prevent this function from running into a loop */
- if (trigger_event == CE_OTHER_IS_CHANGING)
- Changed[lx][ly] = TRUE;
-#endif
-
for (i=0; i < NUM_CUSTOM_ELEMENTS; i++)
{
int element = EL_CUSTOM_START + i;
-#if 1
boolean change_element = FALSE;
int page;
for (j=0; j < element_info[element].num_change_pages; j++)
{
- if (element_info[element].change_page[j].trigger_element ==
- trigger_element)
+ struct ElementChangeInfo *change = &element_info[element].change_page[j];
+
+ if (change->sides & trigger_side &&
+ change->trigger_element == trigger_element)
{
change_element = TRUE;
page = j;
if (!change_element)
continue;
-#else
- if (!CAN_CHANGE(element) ||
- !HAS_ANY_CHANGE_EVENT(element, trigger_event) ||
- element_info[element].change->trigger_element != trigger_element)
- continue;
-#endif
-
for (y=0; y<lev_fieldy; y++) for (x=0; x<lev_fieldx; x++)
{
- if (x == lx && y == ly) /* do not change trigger element itself */
- continue;
-
#if 0
- if (Changed[x][y]) /* do not change already changed elements */
+ if (x == lx && y == ly) /* do not change trigger element itself */
continue;
#endif
ChangeDelay[x][y] = 1;
ChangeEvent[x][y] = CH_EVENT_BIT(trigger_event);
ChangeElement(x, y, page);
-
-#if 0
- Changed[x][y] = TRUE; /* prevent element from being changed again */
-#endif
}
}
}
-#if 0
- /* reset change prevention array */
- for (y=0; y<lev_fieldy; y++) for (x=0; x<lev_fieldx; x++)
- Changed[x][y] = FALSE;
-#endif
-
return TRUE;
}
-static boolean CheckElementChangeExt(int x, int y, int element,
- int trigger_event, int page)
+static boolean CheckTriggeredElementChange(int lx, int ly, int trigger_element,
+ int trigger_event)
+{
+ return CheckTriggeredElementSideChange(lx, ly, trigger_element, CH_SIDE_ANY,
+ trigger_event);
+}
+
+static boolean CheckElementSideChange(int x, int y, int element, int side,
+ int trigger_event, int page)
{
if (!CAN_CHANGE(element) || !HAS_ANY_CHANGE_EVENT(element, trigger_event))
return FALSE;
if (Feld[x][y] == EL_BLOCKED)
+ {
Blocked2Moving(x, y, &x, &y);
+ element = Feld[x][y];
+ }
+
+ if (page < 0)
+ page = element_info[element].event_page_nr[trigger_event];
+
+ if (!(element_info[element].change_page[page].sides & side))
+ return FALSE;
ChangeDelay[x][y] = 1;
ChangeEvent[x][y] = CH_EVENT_BIT(trigger_event);
static boolean CheckElementChange(int x, int y, int element, int trigger_event)
{
- int page = element_info[element].event_page_num[trigger_event];
-
- return CheckElementChangeExt(x, y, element, trigger_event, page);
+ return CheckElementSideChange(x, y, element, CH_SIDE_ANY, trigger_event, -1);
}
static void PlayerActions(struct PlayerInfo *player, byte player_action)
/* this may take place after moving, so 'element' may have changed */
if (IS_CHANGING(x, y))
{
- ChangeElement(x, y, element_info[element].event_page_num[CE_DELAY]);
+ ChangeElement(x, y, element_info[element].event_page_nr[CE_DELAY]);
element = Feld[x][y];
graphic = el_act_dir2img(element, GfxAction[x][y], MovDir[x][y]);
}
#endif
#if 1
- if (local_player->show_envelope && local_player->MovPos == 0)
+ if (local_player->show_envelope != 0 && local_player->MovPos == 0)
{
- ShowEnvelope();
+ ShowEnvelope(local_player->show_envelope - EL_ENVELOPE_1);
- local_player->show_envelope = FALSE;
+ local_player->show_envelope = 0;
}
#endif
}
boolean MoveFigureOneStep(struct PlayerInfo *player,
int dx, int dy, int real_dx, int real_dy)
{
+ static int change_sides[4][2] =
+ {
+ /* enter side leave side */
+ { CH_SIDE_RIGHT, CH_SIDE_LEFT }, /* moving left */
+ { CH_SIDE_LEFT, CH_SIDE_RIGHT }, /* moving right */
+ { CH_SIDE_BOTTOM, CH_SIDE_TOP }, /* moving up */
+ { CH_SIDE_TOP, CH_SIDE_BOTTOM } /* moving down */
+ };
+ int move_direction = (dx == -1 ? MV_LEFT :
+ dx == +1 ? MV_RIGHT :
+ dy == -1 ? MV_UP :
+ dy == +1 ? MV_DOWN : MV_NO_MOVING);
+ int enter_side = change_sides[MV_DIR_BIT(move_direction)][0];
+ int leave_side = change_sides[MV_DIR_BIT(move_direction)][1];
int jx = player->jx, jy = player->jy;
- int new_jx = jx+dx, new_jy = jy+dy;
+ int new_jx = jx + dx, new_jy = jy + dy;
int element;
int can_move;
StorePlayer[jx][jy] = 0;
player->last_jx = jx;
player->last_jy = jy;
- jx = player->jx = new_jx;
- jy = player->jy = new_jy;
- StorePlayer[jx][jy] = player->element_nr;
+ player->jx = new_jx;
+ player->jy = new_jy;
+ StorePlayer[new_jx][new_jy] = player->element_nr;
player->MovPos =
(dx > 0 || dy > 0 ? -1 : 1) * (TILEX - TILEX / player->move_delay_value);
ScrollFigure(player, SCROLL_INIT);
+#if 1
+ if (IS_CUSTOM_ELEMENT(Feld[jx][jy]))
+ {
+ CheckTriggeredElementSideChange(jx, jy, Feld[jx][jy], leave_side,
+ CE_OTHER_GETS_LEFT);
+ CheckElementSideChange(jx, jy, Feld[jx][jy], leave_side,
+ CE_LEFT_BY_PLAYER, -1);
+ }
+
+ if (IS_CUSTOM_ELEMENT(Feld[new_jx][new_jy]))
+ {
+ CheckTriggeredElementSideChange(new_jx, new_jy, Feld[new_jx][new_jy],
+ enter_side, CE_OTHER_GETS_ENTERED);
+ CheckElementSideChange(new_jx, new_jy, Feld[new_jx][new_jy], enter_side,
+ CE_ENTERED_BY_PLAYER, -1);
+ }
+#endif
+
return MF_MOVING;
}
{ +1, 0 },
{ 0, +1 }
};
- static int touching_side[4][2] =
+ static int change_sides[4][2] =
{
- { CE_TOUCHING_TOP_OF, CE_TOUCHING_BOTTOM_OF },
- { CE_TOUCHING_LEFT_OF, CE_TOUCHING_RIGHT_OF },
- { CE_TOUCHING_RIGHT_OF, CE_TOUCHING_LEFT_OF },
- { CE_TOUCHING_BOTTOM_OF, CE_TOUCHING_TOP_OF }
+ /* center side border side */
+ { CH_SIDE_TOP, CH_SIDE_BOTTOM }, /* check top */
+ { CH_SIDE_LEFT, CH_SIDE_RIGHT }, /* check left */
+ { CH_SIDE_RIGHT, CH_SIDE_LEFT }, /* check right */
+ { CH_SIDE_BOTTOM, CH_SIDE_TOP } /* check bottom */
};
boolean change_center_element = FALSE;
int center_element_change_page = 0;
- int center_element_change_event = 0;
int center_element = Feld[x][y];
int i, j;
{
int xx = x + xy[i][0];
int yy = y + xy[i][1];
- int change_event_center = touching_side[i][0];
- int change_event_border = touching_side[i][1];
+ int center_side = change_sides[i][0];
+ int border_side = change_sides[i][1];
int border_element;
if (!IN_LEV_FIELD(xx, yy))
/* check for change of center element (but change it only once) */
if (IS_CUSTOM_ELEMENT(center_element) &&
- HAS_ANY_CHANGE_EVENT(center_element, change_event_border) &&
+ HAS_ANY_CHANGE_EVENT(center_element, CE_OTHER_IS_TOUCHING) &&
!change_center_element)
{
for (j=0; j < element_info[center_element].num_change_pages; j++)
struct ElementChangeInfo *change =
&element_info[center_element].change_page[j];
- if (change->events & CH_EVENT_BIT(change_event_border) &&
+ if (change->events & CH_EVENT_BIT(CE_OTHER_IS_TOUCHING) &&
+ change->sides & border_side &&
change->trigger_element == border_element)
{
change_center_element = TRUE;
center_element_change_page = j;
- center_element_change_event = change_event_border;
break;
}
/* check for change of border element */
if (IS_CUSTOM_ELEMENT(border_element) &&
- HAS_ANY_CHANGE_EVENT(border_element, change_event_center))
+ HAS_ANY_CHANGE_EVENT(border_element, CE_OTHER_IS_TOUCHING))
{
for (j=0; j < element_info[border_element].num_change_pages; j++)
{
struct ElementChangeInfo *change =
&element_info[border_element].change_page[j];
- if (change->events & CH_EVENT_BIT(change_event_center) &&
+ if (change->events & CH_EVENT_BIT(CE_OTHER_IS_TOUCHING) &&
+ change->sides & center_side &&
change->trigger_element == center_element)
{
- CheckElementChangeExt(xx,yy, border_element, change_event_center, j);
+ CheckElementSideChange(xx, yy, border_element, CH_SIDE_ANY,
+ CE_OTHER_IS_TOUCHING, j);
break;
}
}
}
if (change_center_element)
- CheckElementChangeExt(x, y, center_element, center_element_change_event,
- center_element_change_page);
+ CheckElementSideChange(x, y, center_element, CH_SIDE_ANY,
+ CE_OTHER_IS_TOUCHING, center_element_change_page);
#if 0
check_changing = FALSE;
int DigField(struct PlayerInfo *player,
int x, int y, int real_dx, int real_dy, int mode)
{
+#if 0
+ static int change_sides[4][2] =
+ {
+ /* enter side leave side */
+ { CH_SIDE_RIGHT, CH_SIDE_LEFT }, /* moving left */
+ { CH_SIDE_LEFT, CH_SIDE_RIGHT }, /* moving right */
+ { CH_SIDE_BOTTOM, CH_SIDE_TOP }, /* moving up */
+ { CH_SIDE_TOP, CH_SIDE_BOTTOM } /* moving down */
+ };
+#endif
boolean use_spring_bug = (game.engine_version < VERSION_IDENT(2,2,0));
int jx = player->jx, jy = player->jy;
int dx = x - jx, dy = y - jy;
dx == +1 ? MV_RIGHT :
dy == -1 ? MV_UP :
dy == +1 ? MV_DOWN : MV_NO_MOVING);
+#if 0
+ int enter_side = change_sides[MV_DIR_BIT(move_direction)][0];
+ int leave_side = change_sides[MV_DIR_BIT(move_direction)][1];
+#endif
int element;
if (player->MovPos == 0)
el2edimg(EL_KEY_1 + key_nr));
redraw_mask |= REDRAW_DOOR_1;
}
- else if (element == EL_ENVELOPE)
+ else if (IS_ENVELOPE(element))
{
#if 1
- player->show_envelope = TRUE;
+ player->show_envelope = element;
#else
- ShowEnvelope();
+ ShowEnvelope(element - EL_ENVELOPE_1);
#endif
}
else if (IS_DROPPABLE(element)) /* can be collected and dropped */
if (Feld[x][y] != element) /* really digged/collected something */
player->is_collecting = !player->is_digging;
+#if 0
+ if (IS_CUSTOM_ELEMENT(Feld[jx][jy]))
+ {
+ CheckTriggeredElementSideChange(jx, jy, Feld[jx][jy], leave_side,
+ CE_OTHER_GETS_LEFT);
+ CheckElementSideChange(jx, jy, Feld[jx][jy], leave_side,
+ CE_LEFT_BY_PLAYER, -1);
+ }
+
+ if (IS_CUSTOM_ELEMENT(Feld[x][y]))
+ {
+ CheckTriggeredElementSideChange(x, y, Feld[x][y], enter_side,
+ CE_OTHER_GETS_ENTERED);
+ CheckElementSideChange(x, y, Feld[x][y], enter_side,
+ CE_ENTERED_BY_PLAYER, -1);
+ }
+#endif
+
return MF_MOVING;
}