#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 */
/* 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
}
}
}
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);