-#define COMPILE_DATE_STRING "[2005-12-17 04:14]"
+#define COMPILE_DATE_STRING "[2005-12-21 01:06]"
{ CA_NO_ACTION, "no action" },
{ CA_EXIT_PLAYER, "exit player" },
{ CA_KILL_PLAYER, "kill player" },
+ { CA_MOVE_PLAYER, "move player" },
{ CA_RESTART_LEVEL, "restart level" },
{ CA_SHOW_ENVELOPE, "show envelope" },
- { CA_ADD_KEY, "add key" },
- { CA_REMOVE_KEY, "remove key" },
- { CA_SET_PLAYER_SPEED, "set player speed" },
- { CA_SET_PLAYER_GRAVITY, "set gravity" },
- { CA_SET_WIND_DIRECTION, "set wind dir." },
- { CA_SET_LEVEL_GEMS, "set needed gems" },
- { CA_SET_LEVEL_TIME, "set level time" },
- { CA_SET_LEVEL_SCORE, "set level score" },
+ { CA_SET_TIME, "set level time" },
+ { CA_SET_GEMS, "set needed gems" },
+ { CA_SET_SCORE, "set level score" },
+ { CA_SET_KEYS, "set player keys" },
+ { CA_SET_SPEED, "set player speed" },
+ { CA_SET_GRAVITY, "set gravity" },
+ { CA_SET_WIND, "set wind dir." },
{ CA_SET_CE_SCORE, "set CE score" },
{ CA_SET_CE_VALUE, "set CE value" },
#if 0
{ -1, NULL }
};
-static struct ValueTextInfo options_action_mode_set[] =
+static struct ValueTextInfo options_action_mode_assign[] =
{
{ CA_MODE_SET, "=" },
{ -1, NULL }
};
-static struct ValueTextInfo options_action_mode_calc[] =
+static struct ValueTextInfo options_action_mode_add_remove[] =
+{
+ { CA_MODE_ADD, "+" },
+ { CA_MODE_SUBTRACT, "-" },
+
+ { -1, NULL }
+};
+
+static struct ValueTextInfo options_action_mode_calculate[] =
{
{ CA_MODE_SET, "=" },
{ CA_MODE_ADD, "+" },
static struct ValueTextInfo options_action_arg_speed[] =
{
{ CA_ARG_SPEED_HEADLINE, "[speed]" },
+ { CA_ARG_SPEED_NOT_MOVING, "frozen" },
{ CA_ARG_SPEED_VERY_SLOW, "very slow" },
{ CA_ARG_SPEED_SLOW, "slow" },
{ CA_ARG_SPEED_NORMAL, "normal" },
{ CA_ARG_DIRECTION_UP, "up" },
{ CA_ARG_DIRECTION_DOWN, "down" },
{ CA_ARG_DIRECTION_TRIGGER, "trigger" },
+ { CA_ARG_DIRECTION_TRIGGER_BACK, "-trigger" },
{ -1, NULL }
};
static struct ValueTextInfo *action_arg_modes[] =
{
options_action_mode_none,
- options_action_mode_set,
- options_action_mode_calc,
+ options_action_mode_assign,
+ options_action_mode_add_remove,
+ options_action_mode_calculate,
};
static struct
{ CA_NO_ACTION, 0, options_action_arg_none, },
{ CA_EXIT_PLAYER, 0, options_action_arg_player, },
{ CA_KILL_PLAYER, 0, options_action_arg_player, },
+ { CA_MOVE_PLAYER, 0, options_action_arg_direction, },
{ CA_RESTART_LEVEL, 0, options_action_arg_none, },
{ CA_SHOW_ENVELOPE, 0, options_action_arg_envelope, },
- { CA_ADD_KEY, 0, options_action_arg_key, },
- { CA_REMOVE_KEY, 0, options_action_arg_key, },
- { CA_SET_PLAYER_SPEED, 1, options_action_arg_speed, },
- { CA_SET_LEVEL_GEMS, 2, options_action_arg_number, },
- { CA_SET_LEVEL_TIME, 2, options_action_arg_number, },
- { CA_SET_LEVEL_SCORE, 2, options_action_arg_number, },
- { CA_SET_CE_SCORE, 2, options_action_arg_number, },
- { CA_SET_CE_VALUE, 2, options_action_arg_number, },
- { CA_SET_PLAYER_GRAVITY, 1, options_action_arg_gravity, },
- { CA_SET_WIND_DIRECTION, 1, options_action_arg_direction, },
+ { CA_SET_TIME, 3, options_action_arg_number, },
+ { CA_SET_GEMS, 3, options_action_arg_number, },
+ { CA_SET_SCORE, 3, options_action_arg_number, },
+ { CA_SET_KEYS, 2, options_action_arg_key, },
+ { CA_SET_SPEED, 1, options_action_arg_speed, },
+ { CA_SET_GRAVITY, 1, options_action_arg_gravity, },
+ { CA_SET_WIND, 1, options_action_arg_direction, },
+ { CA_SET_CE_SCORE, 3, options_action_arg_number, },
+ { CA_SET_CE_VALUE, 3, options_action_arg_number, },
{ -1, FALSE, NULL }
};
-1,
options_change_trigger_side,
&custom_element_change.trigger_side,
- "at", "side", "element side that causes change"
+ "at", "side", "element side triggering change"
},
{
ED_ELEMENT_SETTINGS_XPOS(2), ED_ELEMENT_SETTINGS_YPOS(7),
else if (id == GADGET_ID_CUSTOM_MOVE_LEAVE)
strcpy(infotext, "Element that will be left behind");
else if (id == GADGET_ID_CUSTOM_CHANGE_TARGET)
- strcpy(infotext, "New element after change");
+ strcpy(infotext, "New target element after change");
else if (id == GADGET_ID_CUSTOM_CHANGE_CONTENT)
strcpy(infotext, "New extended elements after change");
else if (id == GADGET_ID_CUSTOM_CHANGE_TRIGGER)
if (level->game_version < VERSION_IDENT(2,2,0,0))
level->use_spring_bug = TRUE;
- /* time orb caused limited time in endless time levels before 3.1.2 */
- if (level->game_version < VERSION_IDENT(3,1,2,0))
+ /* time orb caused limited time in endless time levels before 3.2.0-5 */
+ if (level->game_version < VERSION_IDENT(3,2,0,5))
level->use_time_orb_bug = TRUE;
- /* default behaviour for snapping was "no snap delay" before 3.1.2 */
- if (level->game_version < VERSION_IDENT(3,1,2,0))
+ /* default behaviour for snapping was "no snap delay" before 3.2.0-5 */
+ if (level->game_version < VERSION_IDENT(3,2,0,5))
level->block_snap_field = FALSE;
/* only few elements were able to actively move into acid before 3.1.0 */
player->is_bored = FALSE;
player->is_sleeping = FALSE;
+ player->cannot_move = FALSE;
+
player->frame_counter_bored = -1;
player->frame_counter_sleeping = -1;
action_arg == CA_ARG_ELEMENT_TARGET ? change->target_element :
EL_EMPTY);
+ int action_arg_direction =
+ (action_arg >= CA_ARG_DIRECTION_LEFT &&
+ action_arg <= CA_ARG_DIRECTION_DOWN ? action_arg - CA_ARG_DIRECTION :
+ action_arg == CA_ARG_DIRECTION_TRIGGER ?
+ change->actual_trigger_side :
+ action_arg == CA_ARG_DIRECTION_TRIGGER_BACK ?
+ MV_DIR_OPPOSITE(change->actual_trigger_side) :
+ MV_NONE);
+
int action_arg_number_min =
- (action_type == CA_SET_PLAYER_SPEED ? MOVE_STEPSIZE_MIN :
+ (action_type == CA_SET_SPEED ? MOVE_STEPSIZE_MIN :
CA_ARG_MIN);
int action_arg_number_max =
- (action_type == CA_SET_PLAYER_SPEED ? MOVE_STEPSIZE_MAX :
- action_type == CA_SET_LEVEL_GEMS ? 999 :
- action_type == CA_SET_LEVEL_TIME ? 9999 :
- action_type == CA_SET_LEVEL_SCORE ? 99999 :
+ (action_type == CA_SET_SPEED ? MOVE_STEPSIZE_MAX :
+ action_type == CA_SET_GEMS ? 999 :
+ action_type == CA_SET_TIME ? 9999 :
+ action_type == CA_SET_SCORE ? 99999 :
action_type == CA_SET_CE_SCORE ? 9999 :
action_type == CA_SET_CE_VALUE ? 9999 :
CA_ARG_MAX);
int action_arg_number_reset =
- (action_type == CA_SET_PLAYER_SPEED ? TILEX/game.initial_move_delay_value :
- action_type == CA_SET_LEVEL_GEMS ? level.gems_needed :
- action_type == CA_SET_LEVEL_TIME ? level.time :
- action_type == CA_SET_LEVEL_SCORE ? 0 :
+ (action_type == CA_SET_SPEED ? TILEX / game.initial_move_delay_value :
+ action_type == CA_SET_GEMS ? level.gems_needed :
+ action_type == CA_SET_TIME ? level.time :
+ action_type == CA_SET_SCORE ? 0 :
action_type == CA_SET_CE_SCORE ? 0 :
#if 1
action_type == CA_SET_CE_VALUE ? GET_NEW_CUSTOM_VALUE(element) :
int action_arg_number =
(action_arg <= CA_ARG_MAX ? action_arg :
- action_arg >= CA_ARG_SPEED_VERY_SLOW &&
+ action_arg >= CA_ARG_SPEED_NOT_MOVING &&
action_arg <= CA_ARG_SPEED_EVEN_FASTER ? (action_arg - CA_ARG_SPEED) :
action_arg == CA_ARG_SPEED_RESET ? action_arg_number_reset :
action_arg == CA_ARG_NUMBER_MIN ? action_arg_number_min :
-1);
int action_arg_number_old =
- (action_type == CA_SET_LEVEL_GEMS ? local_player->gems_still_needed :
- action_type == CA_SET_LEVEL_TIME ? TimeLeft :
- action_type == CA_SET_LEVEL_SCORE ? local_player->score :
+ (action_type == CA_SET_GEMS ? local_player->gems_still_needed :
+ action_type == CA_SET_TIME ? TimeLeft :
+ action_type == CA_SET_SCORE ? local_player->score :
action_type == CA_SET_CE_SCORE ? ei->collect_score :
action_type == CA_SET_CE_VALUE ? CustomValue[x][y] :
0);
action_mode, action_arg_number,
action_arg_number_min, action_arg_number_max);
- int action_arg_player_bits =
- (action_arg == CA_ARG_PLAYER_ANY ? PLAYER_BITS_ANY :
- action_arg >= CA_ARG_PLAYER_1 &&
- action_arg <= CA_ARG_PLAYER_4 ? action_arg - CA_ARG_PLAYER :
- action_arg >= CA_ARG_1 &&
- action_arg <= CA_ARG_PLAYER_4 ? (1 << (action_arg - CA_ARG_1)) :
- action_arg_element >= EL_PLAYER_1 &&
- action_arg_element <= EL_PLAYER_4 ?
- (1 << (action_arg_element - EL_PLAYER_1)) :
- PLAYER_BITS_ANY);
-
int trigger_player_bits =
(change->actual_trigger_player >= EL_PLAYER_1 &&
change->actual_trigger_player <= EL_PLAYER_4 ?
(1 << (change->actual_trigger_player - EL_PLAYER_1)) :
PLAYER_BITS_ANY);
+ int action_arg_player_bits =
+ (action_arg >= CA_ARG_PLAYER_1 &&
+ action_arg <= CA_ARG_PLAYER_4 ? action_arg - CA_ARG_PLAYER :
+ action_arg == CA_ARG_PLAYER_TRIGGER ? trigger_player_bits :
+ PLAYER_BITS_ANY);
+
/* ---------- execute action ---------- */
switch(action_type)
break;
}
+ case CA_MOVE_PLAYER:
+ {
+ /* automatically move to the next field in specified direction */
+ for (i = 0; i < MAX_PLAYERS; i++)
+ if (trigger_player_bits & (1 << i))
+ stored_player[i].programmed_action = action_arg_direction;
+
+ break;
+ }
+
case CA_RESTART_LEVEL:
{
game.restart_level = TRUE;
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:
+ case CA_SET_KEYS:
{
+ int key_state = (action_mode == CA_MODE_ADD ? TRUE : FALSE);
int element = getSpecialActionElement(action_arg_element,
action_arg_number, EL_KEY_1);
{
if (trigger_player_bits & (1 << i))
{
- stored_player[i].key[KEY_NR(element)] = FALSE;
+ stored_player[i].key[KEY_NR(element)] = key_state;
DrawGameValue_Keys(stored_player[i].key);
break;
}
-#if 1
- case CA_SET_PLAYER_SPEED:
+ case CA_SET_SPEED:
{
for (i = 0; i < MAX_PLAYERS; i++)
{
/* 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;
+ stored_player[i].cannot_move =
+ (action_arg == CA_ARG_SPEED_NOT_MOVING ? TRUE : FALSE);
#if 0
printf("::: move_delay_value == %d [%d]\n",
break;
}
-#endif
- case CA_SET_PLAYER_GRAVITY:
+ case CA_SET_GRAVITY:
{
game.gravity = (action_arg == CA_ARG_GRAVITY_OFF ? FALSE :
action_arg == CA_ARG_GRAVITY_ON ? TRUE :
break;
}
- case CA_SET_WIND_DIRECTION:
+ case CA_SET_WIND:
{
- 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);
+ game.wind_direction = action_arg_direction;
break;
}
- case CA_SET_LEVEL_GEMS:
+ case CA_SET_GEMS:
{
local_player->gems_still_needed = action_arg_number_new;
break;
}
- case CA_SET_LEVEL_TIME:
+ case CA_SET_TIME:
{
if (level.time > 0) /* only modify limited time value */
{
break;
}
- case CA_SET_LEVEL_SCORE:
+ case CA_SET_SCORE:
{
local_player->score = action_arg_number_new;
if (!IN_LEV_FIELD(new_jx, new_jy))
return MF_NO_ACTION;
+ if (player->cannot_move)
+ {
+ DigField(player, 0, 0, 0, 0, 0, 0, DF_NO_PUSH);
+ SnapField(player, 0, 0);
+
+ return MF_NO_ACTION;
+ }
+
if (!options.network && !AllPlayersInSight(player, new_jx, new_jy))
return MF_NO_ACTION;
PLAYER_BITS_4)
#define PLAYER_BITS_TRIGGER (1 << 4)
+/* values for move directions (bits 0 - 3: basic move directions) */
+#define MV_BIT_PREVIOUS 4
+#define MV_BIT_TRIGGER 5
+#define MV_BIT_TRIGGER_BACK 6
+
+#define MV_PREVIOUS (1 << MV_BIT_PREVIOUS)
+#define MV_TRIGGER (1 << MV_BIT_TRIGGER)
+#define MV_TRIGGER_BACK (1 << MV_BIT_TRIGGER_BACK)
+
/* values for change side for custom elements */
#define CH_SIDE_NONE MV_NONE
#define CH_SIDE_LEFT MV_LEFT
#define CA_KILL_PLAYER 2
#define CA_RESTART_LEVEL 3
#define CA_SHOW_ENVELOPE 4
-#define CA_ADD_KEY 5
-#define CA_REMOVE_KEY 6
-#define CA_SET_PLAYER_SPEED 7
-#define CA_SET_PLAYER_GRAVITY 8
-#define CA_SET_WIND_DIRECTION 9
-#define CA_SET_LEVEL_GEMS 10
-#define CA_SET_LEVEL_TIME 11
-#define CA_SET_LEVEL_SCORE 12
-#define CA_SET_CE_SCORE 13
-#define CA_SET_CE_VALUE 14
+#define CA_SET_TIME 5
+#define CA_SET_GEMS 6
+#define CA_SET_SCORE 7
+#define CA_SET_WIND 8
+#define CA_SET_KEYS 9
+#define CA_SET_SPEED 10
+#define CA_SET_GRAVITY 11
+#define CA_SET_CE_SCORE 12
+#define CA_SET_CE_VALUE 13
+#define CA_MOVE_PLAYER 14
#if 0
#define CA_SET_DYNABOMB_NUMBER 15
#define CA_SET_DYNABOMB_SIZE 16
#define CA_ARG_ELEMENT_TRIGGER (CA_ARG_ELEMENT + 1)
#define CA_ARG_ELEMENT_HEADLINE (CA_ARG_ELEMENT + 999)
#define CA_ARG_SPEED 13000
+#define CA_ARG_SPEED_NOT_MOVING (CA_ARG_SPEED + 0)
#define CA_ARG_SPEED_VERY_SLOW (CA_ARG_SPEED + 1)
#define CA_ARG_SPEED_SLOW (CA_ARG_SPEED + 2)
#define CA_ARG_SPEED_NORMAL (CA_ARG_SPEED + 4)
#define CA_ARG_SPEED_EVEN_FASTER (CA_ARG_SPEED + 32)
#define CA_ARG_SPEED_SLOWER (CA_ARG_SPEED + 50)
#define CA_ARG_SPEED_FASTER (CA_ARG_SPEED + 200)
-#define CA_ARG_SPEED_RESET (CA_ARG_SPEED + 0)
+#define CA_ARG_SPEED_RESET (CA_ARG_SPEED + 100)
#define CA_ARG_SPEED_HEADLINE (CA_ARG_SPEED + 999)
#define CA_ARG_GRAVITY 14000
#define CA_ARG_GRAVITY_OFF (CA_ARG_GRAVITY + 0)
#define CA_ARG_DIRECTION_RIGHT (CA_ARG_DIRECTION + MV_RIGHT)
#define CA_ARG_DIRECTION_UP (CA_ARG_DIRECTION + MV_UP)
#define CA_ARG_DIRECTION_DOWN (CA_ARG_DIRECTION + MV_DOWN)
-#define CA_ARG_DIRECTION_TRIGGER (CA_ARG_DIRECTION + MV_ANY_DIRECTION)
+#define CA_ARG_DIRECTION_TRIGGER (CA_ARG_DIRECTION + MV_TRIGGER)
+#define CA_ARG_DIRECTION_TRIGGER_BACK (CA_ARG_DIRECTION + MV_TRIGGER_BACK)
#define CA_ARG_DIRECTION_HEADLINE (CA_ARG_DIRECTION + 999)
#define CA_ARG_UNDEFINED 19999
#define MV_TURNING_RANDOM (1 << MV_BIT_TURNING_RANDOM)
#define MV_WIND_DIRECTION (1 << MV_BIT_WIND_DIRECTION)
-/* values for initial move direction (bits 0 - 3: basic move directions) */
-#define MV_START_BIT_PREVIOUS 4
-
/* values for initial move direction */
#define MV_START_NONE (MV_NONE)
#define MV_START_AUTOMATIC (MV_NONE)
#define MV_START_UP (MV_UP)
#define MV_START_DOWN (MV_DOWN)
#define MV_START_RANDOM (MV_ALL_DIRECTIONS)
-#define MV_START_PREVIOUS (1 << MV_START_BIT_PREVIOUS)
+#define MV_START_PREVIOUS (MV_PREVIOUS)
/* values for elements left behind by custom elements */
#define LEAVE_TYPE_UNLIMITED 0
boolean is_bored;
boolean is_sleeping;
+ boolean cannot_move;
+
int frame_counter_bored;
int frame_counter_sleeping;