+ break;
+ }
+
+ case CA_ADD_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)] = TRUE;
+
+ DrawGameValue_Keys(stored_player[i].key);
+
+ redraw_mask |= REDRAW_DOOR_1;
+ }
+ }
+ }
+
+ break;
+ }
+
+ case CA_REMOVE_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;
+ }
+
+#if 1
+ case CA_SET_PLAYER_SPEED:
+ {
+ for (i = 0; i < MAX_PLAYERS; i++)
+ {
+ if (trigger_player_bits & (1 << i))
+ {
+ int move_stepsize = TILEX / stored_player[i].move_delay_value;
+
+ if (action_arg == CA_ARG_SPEED_SLOWER ||
+ action_arg == CA_ARG_SPEED_FASTER)
+ {
+ action_arg_number = 2;
+ action_mode = (action_arg == CA_ARG_SPEED_SLOWER ? CA_MODE_DIVIDE :
+ CA_MODE_MULTIPLY);
+ }
+
+ move_stepsize =
+ getModifiedActionNumber(move_stepsize,
+ action_mode,
+ action_arg_number,
+ action_arg_number_min,
+ action_arg_number_max);
+
+ /* make sure that value is power of 2 */
+ move_stepsize = (1 << log_2(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_next, action_arg_number);
+#endif
+ }
+ }
+
+ break;
+ }
+#else
+ case CA_SET_PLAYER_SPEED:
+ {
+ for (i = 0; i < MAX_PLAYERS; i++)
+ {
+ if (trigger_player_bits & (1 << i))
+ {
+ int move_stepsize = TILEX / stored_player[i].move_delay_value;
+
+ if (action_mode == CA_MODE_ADD || action_mode == CA_MODE_SUBTRACT)
+ {
+ /* translate "+" and "-" to "*" and "/" with powers of two */
+ action_arg_number = 1 << action_arg_number;
+ action_mode = (action_mode == CA_MODE_ADD ? CA_MODE_MULTIPLY :
+ CA_MODE_DIVIDE);
+ }
+
+ move_stepsize =
+ getModifiedActionNumber(move_stepsize,
+ action_mode,
+ action_arg_number,
+ action_arg_number_min,
+ action_arg_number_max);
+
+ /* make sure that value is power of 2 */
+ move_stepsize = (1 << log_2(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_next, action_arg_number);
+#endif
+ }
+ }
+
+ break;
+ }
+#endif
+
+ case CA_SET_PLAYER_GRAVITY:
+ {
+ game.gravity = (action_arg == CA_ARG_GRAVITY_OFF ? FALSE :
+ action_arg == CA_ARG_GRAVITY_ON ? TRUE :
+ action_arg == CA_ARG_GRAVITY_TOGGLE ? !game.gravity :
+ game.gravity);
+ break;
+ }
+
+ case CA_SET_WIND_DIRECTION:
+ {
+ game.wind_direction = (action_arg >= CA_ARG_DIRECTION_NONE &&
+ action_arg <= CA_ARG_DIRECTION_DOWN ?
+ action_arg - CA_ARG_DIRECTION :
+ action_arg == CA_ARG_DIRECTION_TRIGGER ?
+ MV_DIR_OPPOSITE(change->actual_trigger_side) :
+ game.wind_direction);
+
+ break;
+ }
+
+ case CA_SET_LEVEL_GEMS:
+ {
+ local_player->gems_still_needed = action_arg_number_new;
+
+ DrawGameValue_Emeralds(local_player->gems_still_needed);
+
+ break;
+ }
+
+ case CA_SET_LEVEL_TIME:
+ {
+ if (level.time > 0) /* only modify limited time value */
+ {
+ TimeLeft = action_arg_number_new;
+
+ DrawGameValue_Time(TimeLeft);
+
+ if (!TimeLeft && setup.time_limit)
+ for (i = 0; i < MAX_PLAYERS; i++)
+ KillPlayer(&stored_player[i]);
+ }
+
+ break;
+ }
+
+ case CA_SET_LEVEL_SCORE:
+ {
+ local_player->score = action_arg_number_new;
+
+ DrawGameValue_Score(local_player->score);
+
+ break;
+ }
+
+ case CA_SET_CE_SCORE:
+ {
+ ei->collect_score = action_arg_number_new;
+
+ break;
+ }
+
+ case CA_SET_CE_VALUE:
+ {
+#if USE_NEW_CUSTOM_VALUE
+ int last_custom_value = CustomValue[x][y];
+
+ CustomValue[x][y] = action_arg_number_new;
+
+#if 0
+ printf("::: Count == %d\n", CustomValue[x][y]);
+#endif
+
+ if (CustomValue[x][y] == 0 && last_custom_value > 0)
+ {
+#if 0
+ printf("::: CE_VALUE_GETS_ZERO\n");
+#endif
+
+ CheckElementChange(x, y, element, EL_UNDEFINED, CE_VALUE_GETS_ZERO);
+ CheckTriggeredElementChange(x, y, element, CE_VALUE_GETS_ZERO_OF_X);
+ }
+#endif
+
+ break;
+ }
+
+#if 0
+ 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;
+ }
+#endif
+
+ default:
+ break;
+ }
+}
+
+static void ChangeElementNowExt(struct ElementChangeInfo *change,
+ int x, int y, int target_element)
+{
+ int previous_move_direction = MovDir[x][y];
+#if USE_NEW_CUSTOM_VALUE
+ int last_ce_value = CustomValue[x][y];
+#endif
+ 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;
+
+#if USE_NEW_CUSTOM_VALUE
+ if (element_info[Feld[x][y]].use_last_ce_value)
+ CustomValue[x][y] = last_ce_value;
+#endif
+
+ 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))