#define USE_NEW_AMOEBA_CODE FALSE
/* EXPERIMENTAL STUFF */
-#define USE_NEW_STUFF ( * 1)
+#define USE_NEW_STUFF ( 1)
#define USE_NEW_SP_SLIPPERY (USE_NEW_STUFF * 1)
#define USE_NEW_COLLECT_COUNT (USE_NEW_STUFF * 1)
#define USE_NEW_PLAYER_ANIM (USE_NEW_STUFF * 1)
#define USE_NEW_ALL_SLIPPERY (USE_NEW_STUFF * 1)
#define USE_NEW_PLAYER_SPEED (USE_NEW_STUFF * 1)
-
+#define USE_NEW_DELAYED_ACTION (USE_NEW_STUFF * 1)
/* for DigField() */
#define DF_NO_PUSH 0
ei->change->change_function = ch_delay->change_function;
ei->change->post_change_function = ch_delay->post_change_function;
+ ei->change->can_change = TRUE;
+ ei->change->can_change_or_has_action = TRUE;
+
ei->has_change_event[CE_DELAY] = TRUE;
SET_PROPERTY(ch_delay->element, EP_CAN_CHANGE, TRUE);
player->move_delay = game.initial_move_delay;
player->move_delay_value = game.initial_move_delay_value;
+ player->move_delay_value_next = -1;
+
player->move_delay_reset_counter = 0;
player->push_delay = -1; /* initialized when pushing starts */
for (yy = 0; yy < 3; yy++) for (xx = 0; xx < 3; xx++)
{
- content = element_info[element].content[xx][yy];
+ content = element_info[element].content.e[xx][yy];
is_player = ELEM_IS_PLAYER(content);
if (is_player && (found_rating < 2 || element < found_element))
for (i = 0; i < element_info[element].num_change_pages; i++)
{
- content= element_info[element].change_page[i].target_content[xx][yy];
+ content =
+ element_info[element].change_page[i].target_content.e[xx][yy];
+
is_player = ELEM_IS_PLAYER(content);
if (is_player && (found_rating < 1 || element < found_element))
else if (center_element == EL_AMOEBA_TO_DIAMOND)
Store[x][y] = level.amoeba_content;
else if (center_element == EL_YAMYAM)
- Store[x][y] = level.yamyam_content[game.yamyam_content_nr][xx][yy];
+ Store[x][y] = level.yamyam_content[game.yamyam_content_nr].e[xx][yy];
else if (IS_CUSTOM_ELEMENT(center_element) &&
- element_info[center_element].content[xx][yy] != EL_EMPTY)
- Store[x][y] = element_info[center_element].content[xx][yy];
+ element_info[center_element].content.e[xx][yy] != EL_EMPTY)
+ Store[x][y] = element_info[center_element].content.e[xx][yy];
else if (element == EL_WALL_EMERALD)
Store[x][y] = EL_EMERALD;
else if (element == EL_WALL_DIAMOND)
else if (element == EL_WALL_CRYSTAL)
Store[x][y] = EL_CRYSTAL;
else if (IS_CUSTOM_ELEMENT(element) && !CAN_EXPLODE(element))
- Store[x][y] = element_info[element].content[1][1];
+ Store[x][y] = element_info[element].content.e[1][1];
else
Store[x][y] = EL_EMPTY;
/* make sure that value is power of 2 */
move_stepsize = (1 << log_2(move_stepsize));
- stored_player[i].move_delay_value = TILEX / move_stepsize;
+ /* do no immediately change -- the player might just be moving */
+ stored_player[i].move_delay_value_next = TILEX / move_stepsize;
#if 0
printf("::: move_delay_value == %d [%d]\n",
- stored_player[i].move_delay_value, action_arg_number);
+ stored_player[i].move_delay_value_next, action_arg_number);
#endif
}
}
boolean is_destructible;
int ex = x + xx - 1;
int ey = y + yy - 1;
- int content_element = change->target_content[xx][yy];
+ int content_element = change->target_content.e[xx][yy];
int e;
can_replace[xx][yy] = TRUE;
ChangeEvent[ex][ey] = ChangeEvent[x][y];
- content_element = change->target_content[xx][yy];
+ content_element = change->target_content.e[xx][yy];
target_element = GET_TARGET_ELEMENT(content_element, change);
ChangeElementNowExt(change, ex, ey, target_element);
}
if (something_has_changed)
+ {
PlayLevelSoundElementAction(x, y, element, ACTION_CHANGING);
+ PlayLevelSoundElementAction(x, y, element, ACTION_PAGE_1 + page);
+ }
}
}
else
ChangeElementNowExt(change, x, y, target_element);
PlayLevelSoundElementAction(x, y, element, ACTION_CHANGING);
+ PlayLevelSoundElementAction(x, y, element, ACTION_PAGE_1 + page);
}
/* this uses direct change before indirect change */
return TRUE;
}
+#if USE_NEW_DELAYED_ACTION
+
+static void ChangeElement(int x, int y, int page)
+{
+ int element = MovingOrBlocked2Element(x, y);
+ struct ElementInfo *ei = &element_info[element];
+ struct ElementChangeInfo *change = &ei->change_page[page];
+
+#ifdef DEBUG
+ if (!CAN_CHANGE_OR_HAS_ACTION(element) &&
+ !CAN_CHANGE_OR_HAS_ACTION(Back[x][y]))
+ {
+ printf("\n\n");
+ printf("ChangeElement(): %d,%d: element = %d ('%s')\n",
+ x, y, element, element_info[element].token_name);
+ printf("ChangeElement(): This should never happen!\n");
+ printf("\n\n");
+ }
+#endif
+
+ /* this can happen with classic bombs on walkable, changing elements */
+ if (!CAN_CHANGE_OR_HAS_ACTION(element))
+ {
+#if 0
+ if (!CAN_CHANGE(Back[x][y])) /* prevent permanent repetition */
+ ChangeDelay[x][y] = 0;
+#endif
+
+ return;
+ }
+
+ if (ChangeDelay[x][y] == 0) /* initialize element change */
+ {
+ ChangeDelay[x][y] = GET_CHANGE_DELAY(change) + 1;
+
+ if (change->can_change)
+ {
+ ResetGfxAnimation(x, y);
+ ResetRandomAnimationValue(x, y);
+
+ if (change->pre_change_function)
+ change->pre_change_function(x, y);
+ }
+ }
+
+ ChangeDelay[x][y]--;
+
+ if (ChangeDelay[x][y] != 0) /* continue element change */
+ {
+ if (change->can_change)
+ {
+ int graphic = el_act_dir2img(element, GfxAction[x][y], GfxDir[x][y]);
+
+ if (IS_ANIMATED(graphic))
+ DrawLevelGraphicAnimationIfNeeded(x, y, graphic);
+
+ if (change->change_function)
+ change->change_function(x, y);
+ }
+ }
+ else /* finish element change */
+ {
+ if (ChangePage[x][y] != -1) /* remember page from delayed change */
+ {
+ page = ChangePage[x][y];
+ ChangePage[x][y] = -1;
+
+ change = &ei->change_page[page];
+ }
+
+ if (IS_MOVING(x, y)) /* never change a running system ;-) */
+ {
+ ChangeDelay[x][y] = 1; /* try change after next move step */
+ ChangePage[x][y] = page; /* remember page to use for change */
+
+ return;
+ }
+
+ if (change->can_change)
+ {
+ if (ChangeElementNow(x, y, element, page))
+ {
+ if (change->post_change_function)
+ change->post_change_function(x, y);
+ }
+ }
+
+ if (change->has_action)
+ ExecuteCustomElementAction(x, y, element, page);
+ }
+}
+
+#else
+
static void ChangeElement(int x, int y, int page)
{
int element = MovingOrBlocked2Element(x, y);
}
}
+#endif
+
static boolean CheckTriggeredElementChangeExt(int trigger_element,
int trigger_event,
int trigger_player,
ChangeEvent[x][y] = trigger_event;
ChangeElement(x, y, p);
}
-
+#if USE_NEW_DELAYED_ACTION
+ else if (change->has_action)
+ {
+ ExecuteCustomElementAction(x, y, element, p);
+ PlayLevelSoundElementAction(x, y, element, ACTION_PAGE_1 + p);
+ }
+#else
if (change->has_action)
+ {
ExecuteCustomElementAction(x, y, element, p);
+ PlayLevelSoundElementAction(x, y, element, ACTION_PAGE_1 + p);
+ }
+#endif
}
}
change_done = TRUE;
}
-
+#if USE_NEW_DELAYED_ACTION
+ else if (change->has_action)
+ {
+ ExecuteCustomElementAction(x, y, element, p);
+ PlayLevelSoundElementAction(x, y, element, ACTION_PAGE_1 + p);
+ }
+#else
if (change->has_action)
+ {
ExecuteCustomElementAction(x, y, element, p);
+ PlayLevelSoundElementAction(x, y, element, ACTION_PAGE_1 + p);
+ }
+#endif
}
}
printf("::: ChangeDelay == %d\n", ChangeDelay[x][y]);
#endif
+#if 1
+ ChangeElement(x, y, page);
+#else
if (CAN_CHANGE(element))
ChangeElement(x, y, page);
- if (HAS_ACTION(element) && ChangeDelay[x][y] == 0)
+ if (HAS_ACTION(element))
ExecuteCustomElementAction(x, y, element, page);
+#endif
+
#endif
element = Feld[x][y];
player->jy = new_jy;
StorePlayer[new_jx][new_jy] = player->element_nr;
+ if (player->move_delay_value_next != -1)
+ {
+ player->move_delay_value = player->move_delay_value_next;
+ player->move_delay_value_next = -1;
+ }
+
player->MovPos =
(dx > 0 || dy > 0 ? -1 : 1) * (TILEX - TILEX / player->move_delay_value);
return;
#if 0
- printf("::: player->MovPos: %d -> %d\n",
- player->MovPos,
- player->MovPos + (player->MovPos > 0 ? -1 : 1) * move_stepsize);
+ printf("::: player->MovPos: %d -> %d\n",
+ player->MovPos,
+ player->MovPos + (player->MovPos > 0 ? -1 : 1) * move_stepsize);
#endif
#if USE_NEW_PLAYER_SPEED
- if (player->MovPos != 0)
- {
- player->MovPos += (player->MovPos > 0 ? -1 : 1) * move_stepsize;
- player->GfxPos = move_stepsize * (player->MovPos / move_stepsize);
+ if (player->MovPos != 0)
+ {
+ player->MovPos += (player->MovPos > 0 ? -1 : 1) * move_stepsize;
+ player->GfxPos = move_stepsize * (player->MovPos / move_stepsize);
- /* before DrawPlayer() to draw correct player graphic for this case */
- if (player->MovPos == 0)
- CheckGravityMovement(player);
- }
+ /* before DrawPlayer() to draw correct player graphic for this case */
+ if (player->MovPos == 0)
+ CheckGravityMovement(player);
+ }
#else
player->MovPos += (player->MovPos > 0 ? -1 : 1) * move_stepsize;
player->GfxPos = move_stepsize * (player->MovPos / move_stepsize);