+ DrawGameValue_Keys(stored_player[i].key);
+
+ redraw_mask |= REDRAW_DOOR_1;
+ }
+ }
+ }
+
+ break;
+ }
+
+ case CA_DEL_KEY:
+ {
+ int element = getSpecialActionElement(action_arg_element,
+ action_arg_number, EL_KEY_1);
+
+ if (IS_KEY(element))
+ {
+ for (i = 0; i < MAX_PLAYERS; i++)
+ {
+ if (trigger_player_bits & (1 << i))
+ {
+ stored_player[i].key[KEY_NR(element)] = FALSE;
+
+ DrawGameValue_Keys(stored_player[i].key);
+
+ redraw_mask |= REDRAW_DOOR_1;
+ }
+ }
+ }
+
+ break;
+ }
+
+ case CA_SET_PLAYER_SPEED:
+ {
+ for (i = 0; i < MAX_PLAYERS; i++)
+ {
+ if (trigger_player_bits & (1 << i))
+ {
+ if (action_arg == CA_ARG_NUMBER_RESET)
+ stored_player[i].move_delay_value = game.initial_move_delay_value;
+ else if (action_arg == CA_ARG_NUMBER_NORMAL)
+ stored_player[i].move_delay_value = MOVE_DELAY_NORMAL_SPEED;
+ else if (action_arg == CA_ARG_NUMBER_MIN)
+ stored_player[i].move_delay_value = 16;
+ else if (action_arg == CA_ARG_NUMBER_MAX)
+ stored_player[i].move_delay_value = MOVE_DELAY_HIGH_SPEED;
+ else
+ {
+#if 0
+ if (action_mode == CA_MODE_ADD)
+ {
+ action_mode = CA_MODE_DIVIDE;
+ action_arg_number = (1 << action_arg_number);
+ }
+ else if (action_mode == CA_MODE_SUBTRACT)
+ {
+ action_mode = CA_MODE_MULTIPLY;
+ action_arg_number = (1 << action_arg_number);
+ }
+
+ int mode = (action_mode == CA_MODE_MULTIPLY ? CA_MODE_DIVIDE :
+ action_mode == CA_MODE_DIVIDE ? CA_MODE_MULTIPLY :
+ action_mode);
+
+ stored_player[i].move_delay_value =
+ getModifiedActionNumber(stored_player[i].move_delay_value,
+ 1, 16,
+ action_mode, action_arg_number);
+#endif
+ }
+ }
+ }
+
+ break;
+ }
+
+ case CA_SET_GEMS:
+ {
+ local_player->gems_still_needed =
+ getModifiedActionNumber(local_player->gems_still_needed, 0, 999,
+ action_mode, action_arg_number);
+
+ DrawGameValue_Emeralds(local_player->gems_still_needed);
+
+ break;
+ }
+
+ case CA_SET_TIME:
+ {
+ if (level.time > 0) /* only modify limited time value */
+ {
+ TimeLeft = getModifiedActionNumber(TimeLeft, 0, 9999,
+ action_mode, action_arg_number);
+
+ DrawGameValue_Time(TimeLeft);
+ }
+
+ break;
+ }
+
+ case CA_SET_SCORE:
+ {
+ local_player->score =
+ getModifiedActionNumber(local_player->score, 0, 99999,
+ action_mode, action_arg_number);
+
+ DrawGameValue_Score(local_player->score);
+
+ break;
+ }
+
+ case CA_SET_CE_SCORE:
+ {
+ printf("::: CA_SET_CE_SCORE -- not yet implemented\n");
+
+ break;
+ }
+
+ case CA_SET_CE_COUNT:
+ {
+ printf("::: CA_SET_CE_COUNT -- not yet implemented\n");
+
+ break;
+ }
+
+ case CA_SET_DYNABOMB_NUMBER:
+ {
+ printf("::: CA_SET_DYNABOMB_NUMBER -- not yet implemented\n");
+
+ break;
+ }
+
+ case CA_SET_DYNABOMB_SIZE:
+ {
+ printf("::: CA_SET_DYNABOMB_SIZE -- not yet implemented\n");
+
+ break;
+ }
+
+ case CA_SET_DYNABOMB_POWER:
+ {
+ printf("::: CA_SET_DYNABOMB_POWER -- not yet implemented\n");
+
+ break;
+ }
+
+ case CA_TOGGLE_PLAYER_GRAVITY:
+ {
+ game.gravity = !game.gravity;
+
+ break;
+ }
+
+ case CA_ENABLE_PLAYER_GRAVITY:
+ {
+ game.gravity = TRUE;
+
+ break;
+ }
+
+ case CA_DISABLE_PLAYER_GRAVITY:
+ {
+ game.gravity = FALSE;
+
+ break;
+ }
+
+ default:
+ break;
+ }
+}
+
+static void ChangeElementNowExt(struct ElementChangeInfo *change,
+ int x, int y, int target_element)
+{
+ int previous_move_direction = MovDir[x][y];
+ boolean add_player = (ELEM_IS_PLAYER(target_element) &&
+ IS_WALKABLE(Feld[x][y]));
+
+ /* check if element under player changes from accessible to unaccessible
+ (needed for special case of dropping element which then changes) */
+ if (IS_PLAYER(x, y) && !PLAYER_EXPLOSION_PROTECTED(x, y) &&
+ IS_ACCESSIBLE(Feld[x][y]) && !IS_ACCESSIBLE(target_element))
+ {
+ Bang(x, y);
+ return;
+ }
+
+ if (!add_player)
+ {
+ if (IS_MOVING(x, y) || IS_BLOCKED(x, y))
+ RemoveMovingField(x, y);
+ else
+ RemoveField(x, y);
+
+ Feld[x][y] = target_element;
+
+ ResetGfxAnimation(x, y);
+ ResetRandomAnimationValue(x, y);
+
+ if (element_info[Feld[x][y]].move_direction_initial == MV_START_PREVIOUS)
+ MovDir[x][y] = previous_move_direction;
+
+ InitField_WithBug1(x, y, FALSE);
+
+ DrawLevelField(x, y);
+
+ if (GFX_CRUMBLED(Feld[x][y]))
+ DrawLevelFieldCrumbledSandNeighbours(x, y);
+ }
+
+ /* "Changed[][]" not set yet to allow "entered by player" change one time */
+ if (ELEM_IS_PLAYER(target_element))
+ RelocatePlayer(x, y, target_element);
+
+#if 1
+ Changed[x][y] = TRUE; /* ignore all further changes in this frame */
+#else
+ Changed[x][y] |= ChangeEvent[x][y]; /* ignore same changes in this frame */
+#endif
+
+ TestIfBadThingTouchesHero(x, y);
+ TestIfPlayerTouchesCustomElement(x, y);
+ TestIfElementTouchesCustomElement(x, y);
+}
+
+static boolean ChangeElementNow(int x, int y, int element, int page)
+{
+ struct ElementChangeInfo *change = &element_info[element].change_page[page];
+ int target_element;
+ int old_element = Feld[x][y];
+
+ /* always use default change event to prevent running into a loop */
+ if (ChangeEvent[x][y] == -1)
+ ChangeEvent[x][y] = CE_DELAY;
+
+ if (ChangeEvent[x][y] == CE_DELAY)
+ {
+ /* reset actual trigger element, trigger player and action element */
+ change->actual_trigger_element = EL_EMPTY;
+ change->actual_trigger_player = EL_PLAYER_1;
+ }
+
+#if 1
+ /* do not change any elements that have already changed in this frame */
+ if (Changed[x][y])
+ return FALSE;
+#else
+ /* do not change already changed elements with same change event */
+ if (Changed[x][y] & ChangeEvent[x][y])
+ return FALSE;
+#endif
+
+#if 1
+ Changed[x][y] = TRUE; /* ignore all further changes in this frame */
+#else
+ Changed[x][y] |= ChangeEvent[x][y]; /* ignore same changes in this frame */
+#endif