#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_CUSTOM_VALUE (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)
RND(element_info[e].move_delay_random))
#define GET_MAX_MOVE_DELAY(e) ( (element_info[e].move_delay_fixed) + \
(element_info[e].move_delay_random))
+#define GET_NEW_CUSTOM_VALUE(e) ( (element_info[e].ce_value_fixed_initial) +\
+ RND(element_info[e].ce_value_random_initial))
#define GET_CHANGE_DELAY(c) ( ((c)->delay_fixed * (c)->delay_frames) + \
RND((c)->delay_random * (c)->delay_frames))
static void ChangeElement(int, int, int);
-static boolean CheckTriggeredElementChangeExt(int, int, int,int,int);
-#define CheckTriggeredElementChange(e, ev) \
- CheckTriggeredElementChangeExt(e, ev, CH_PLAYER_ANY, CH_SIDE_ANY, -1)
-#define CheckTriggeredElementChangeByPlayer(e, ev, p, s) \
- CheckTriggeredElementChangeExt(e, ev, p, s, -1)
-#define CheckTriggeredElementChangeBySide(e, ev, s) \
- CheckTriggeredElementChangeExt(e, ev, CH_PLAYER_ANY, s, -1)
-#define CheckTriggeredElementChangeByPage(e, ev, p) \
- CheckTriggeredElementChangeExt(e, ev, CH_PLAYER_ANY, CH_SIDE_ANY, p)
+static boolean CheckTriggeredElementChangeExt(int, int, int, int, int,int,int);
+#define CheckTriggeredElementChange(x, y, e, ev) \
+ CheckTriggeredElementChangeExt(x,y,e,ev, CH_PLAYER_ANY,CH_SIDE_ANY, -1)
+#define CheckTriggeredElementChangeByPlayer(x, y, e, ev, p, s) \
+ CheckTriggeredElementChangeExt(x, y, e, ev, p, s, -1)
+#define CheckTriggeredElementChangeBySide(x, y, e, ev, s) \
+ CheckTriggeredElementChangeExt(x, y, e, ev, CH_PLAYER_ANY, s, -1)
+#define CheckTriggeredElementChangeByPage(x, y, e, ev, p) \
+ CheckTriggeredElementChangeExt(x,y,e,ev, CH_PLAYER_ANY, CH_SIDE_ANY, p)
static boolean CheckElementChangeExt(int, int, int, int, int, int, int);
#define CheckElementChange(x, y, e, te, ev) \
break;
}
-#if USE_NEW_COLLECT_COUNT
- Count[x][y] = element_info[Feld[x][y]].collect_count_initial;
+#if USE_NEW_CUSTOM_VALUE
+
+#if 1
+ CustomValue[x][y] = GET_NEW_CUSTOM_VALUE(Feld[x][y]);
+#else
+ CustomValue[x][y] = element_info[Feld[x][y]].custom_value_initial;
+#endif
+
#endif
}
{
ei->change_page[j].actual_trigger_element = EL_EMPTY;
ei->change_page[j].actual_trigger_player = EL_PLAYER_1;
+ ei->change_page[j].actual_trigger_side = CH_SIDE_NONE;
+ ei->change_page[j].actual_trigger_ce_value = 0;
}
}
MovPos[x][y] = MovDir[x][y] = MovDelay[x][y] = 0;
ChangeDelay[x][y] = 0;
ChangePage[x][y] = -1;
-#if USE_NEW_COLLECT_COUNT
- Count[x][y] = 0; /* initialized in InitField() */
+#if USE_NEW_CUSTOM_VALUE
+ CustomValue[x][y] = 0; /* initialized in InitField() */
#endif
Store[x][y] = Store2[x][y] = StorePlayer[x][y] = Back[x][y] = 0;
AmoebaNr[x][y] = 0;
MovDir[newx][newy] = MovDir[x][y];
-#if USE_NEW_COLLECT_COUNT
- Count[newx][newy] = Count[x][y];
+#if USE_NEW_CUSTOM_VALUE
+ CustomValue[newx][newy] = CustomValue[x][y];
#endif
GfxFrame[newx][newy] = GfxFrame[x][y];
MovDir[x][y] = 0;
MovDelay[x][y] = 0;
-#if USE_NEW_COLLECT_COUNT
- Count[x][y] = 0;
+#if USE_NEW_CUSTOM_VALUE
+ CustomValue[x][y] = 0;
#endif
AmoebaNr[x][y] = 0;
CE_LEFT_BY_PLAYER,
player->index_bit, leave_side);
- CheckTriggeredElementChangeByPlayer(old_element, CE_PLAYER_LEAVES_X,
+ CheckTriggeredElementChangeByPlayer(old_jx, old_jy, old_element,
+ CE_PLAYER_LEAVES_X,
player->index_bit, leave_side);
Feld[jx][jy] = el_player;
CheckElementChangeByPlayer(jx, jy, element, CE_ENTERED_BY_PLAYER,
player->index_bit, enter_side);
- CheckTriggeredElementChangeByPlayer(element, CE_PLAYER_ENTERS_X,
+ CheckTriggeredElementChangeByPlayer(jx, jy, element, CE_PLAYER_ENTERS_X,
player->index_bit, enter_side);
}
ChangeDelay[x][y] = 0;
ChangePage[x][y] = -1;
-#if USE_NEW_COLLECT_COUNT
- Count[x][y] = 0;
+#if USE_NEW_CUSTOM_VALUE
+ CustomValue[x][y] = 0;
#endif
InitField_WithBug2(x, y, FALSE);
break;
}
- CheckTriggeredElementChange(element, CE_EXPLOSION_OF_X);
+ CheckTriggeredElementChange(x, y, element, CE_EXPLOSION_OF_X);
}
void SplashAcid(int x, int y)
CheckElementChangeBySide(x, y + 1, smashed, element,
CE_SWITCHED, CH_SIDE_TOP);
- CheckTriggeredElementChangeBySide(smashed, CE_SWITCH_OF_X,
+ CheckTriggeredElementChangeBySide(x, y + 1, smashed, CE_SWITCH_OF_X,
CH_SIDE_TOP);
}
}
Feld[x][y] = EL_MAGIC_WALL_DEAD;
element = Feld[newx][newy] = Store[x][y];
-#if USE_NEW_COLLECT_COUNT
+#if USE_NEW_CUSTOM_VALUE
InitField(newx, newy, FALSE);
#endif
}
Feld[x][y] = EL_BD_MAGIC_WALL_DEAD;
element = Feld[newx][newy] = Store[x][y];
-#if USE_NEW_COLLECT_COUNT
+#if USE_NEW_CUSTOM_VALUE
InitField(newx, newy, FALSE);
#endif
}
Changed[newx][newy] = Changed[x][y];
ChangeEvent[newx][newy] = ChangeEvent[x][y];
-#if USE_NEW_COLLECT_COUNT
- Count[newx][newy] = Count[x][y];
+#if USE_NEW_CUSTOM_VALUE
+ CustomValue[newx][newy] = CustomValue[x][y];
#endif
}
Changed[x][y] = FALSE;
ChangeEvent[x][y] = -1;
-#if USE_NEW_COLLECT_COUNT
- Count[x][y] = 0;
+#if USE_NEW_CUSTOM_VALUE
+ CustomValue[x][y] = 0;
#endif
/* copy animation control values to new field */
CheckElementChangeByPlayer(newx, newy, element, CE_PUSHED_BY_PLAYER,
player->index_bit, dig_side);
- CheckTriggeredElementChangeByPlayer(element, CE_PLAYER_PUSHES_X,
+ CheckTriggeredElementChangeByPlayer(newx,newy, element, CE_PLAYER_PUSHES_X,
player->index_bit, dig_side);
}
int action_arg_number_max =
(action_type == CA_SET_PLAYER_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_LEVEL_GEMS ? 999 :
+ action_type == CA_SET_LEVEL_TIME ? 9999 :
+ action_type == CA_SET_LEVEL_SCORE ? 99999 :
action_type == CA_SET_CE_SCORE ? 9999 :
- action_type == CA_SET_CE_COUNT ? 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_GEMS ? level.gems_needed :
- action_type == CA_SET_TIME ? level.time :
- action_type == CA_SET_SCORE ? 0 :
+ 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_CE_SCORE ? 0 :
- action_type == CA_SET_CE_COUNT ? ei->collect_count_initial :
+#if 1
+ action_type == CA_SET_CE_VALUE ? GET_NEW_CUSTOM_VALUE(element) :
+#else
+ action_type == CA_SET_CE_VALUE ? ei->custom_value_initial :
+#endif
0);
- int action_arg_number_normal =
- (action_type == CA_SET_PLAYER_SPEED ? MOVE_STEPSIZE_NORMAL :
- action_arg_number_reset);
-
int action_arg_number =
(action_arg <= CA_ARG_MAX ? action_arg :
+ action_arg >= CA_ARG_SPEED_VERY_SLOW &&
+ 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 :
action_arg == CA_ARG_NUMBER_MAX ? action_arg_number_max :
action_arg == CA_ARG_NUMBER_RESET ? action_arg_number_reset :
- action_arg == CA_ARG_NUMBER_NORMAL ? action_arg_number_normal :
action_arg == CA_ARG_NUMBER_CE_SCORE ? ei->collect_score :
-#if USE_NEW_COLLECT_COUNT
- action_arg == CA_ARG_NUMBER_CE_COUNT ? Count[x][y] :
+#if USE_NEW_CUSTOM_VALUE
+ action_arg == CA_ARG_NUMBER_CE_VALUE ? CustomValue[x][y] :
#else
- action_arg == CA_ARG_NUMBER_CE_COUNT ? ei->collect_count_initial :
+ action_arg == CA_ARG_NUMBER_CE_VALUE ? ei->custom_value_initial :
#endif
action_arg == CA_ARG_NUMBER_CE_DELAY ? GET_CHANGE_DELAY(change) :
+ action_arg == CA_ARG_ELEMENT_TARGET ? GET_NEW_CUSTOM_VALUE(change->target_element) :
+ action_arg == CA_ARG_ELEMENT_TRIGGER ? change->actual_trigger_ce_value :
-1);
int action_arg_number_old =
- (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_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_CE_SCORE ? ei->collect_score :
- action_type == CA_SET_CE_COUNT ? Count[x][y] :
+ action_type == CA_SET_CE_VALUE ? CustomValue[x][y] :
0);
int action_arg_number_new =
break;
}
- case CA_DEL_KEY:
+ case CA_REMOVE_KEY:
{
int element = getSpecialActionElement(action_arg_element,
action_arg_number, EL_KEY_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++)
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_GEMS:
+ 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;
break;
}
- case CA_SET_TIME:
+ case CA_SET_LEVEL_TIME:
{
if (level.time > 0) /* only modify limited time value */
{
break;
}
- case CA_SET_SCORE:
+ case CA_SET_LEVEL_SCORE:
{
local_player->score = action_arg_number_new;
break;
}
- case CA_SET_CE_COUNT:
+ case CA_SET_CE_VALUE:
{
-#if USE_NEW_COLLECT_COUNT
- int count_last = Count[x][y];
+#if USE_NEW_CUSTOM_VALUE
+ int last_custom_value = CustomValue[x][y];
- Count[x][y] = action_arg_number_new;
+ CustomValue[x][y] = action_arg_number_new;
#if 0
- printf("::: Count == %d\n", Count[x][y]);
+ printf("::: Count == %d\n", CustomValue[x][y]);
#endif
- if (Count[x][y] == 0 && count_last > 0)
+ if (CustomValue[x][y] == 0 && last_custom_value > 0)
{
#if 0
- printf("::: CE_COUNT_AT_ZERO\n");
+ printf("::: CE_VALUE_GETS_ZERO\n");
#endif
- CheckElementChange(x, y, element, EL_UNDEFINED, CE_COUNT_AT_ZERO);
- CheckTriggeredElementChange(element, CE_COUNT_AT_ZERO_OF_X);
+ 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_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;
- }
+#endif
default:
break;
/* reset actual trigger element, trigger player and action element */
change->actual_trigger_element = EL_EMPTY;
change->actual_trigger_player = EL_PLAYER_1;
+ change->actual_trigger_side = CH_SIDE_NONE;
+ change->actual_trigger_ce_value = 0;
}
#if 1
}
/* this uses direct change before indirect change */
- CheckTriggeredElementChangeByPage(old_element, CE_CHANGE_OF_X, page);
+ CheckTriggeredElementChangeByPage(x, y, old_element, CE_CHANGE_OF_X, page);
return TRUE;
}
#endif
-static boolean CheckTriggeredElementChangeExt(int trigger_element,
+static boolean CheckTriggeredElementChangeExt(int x, int y,
+ int trigger_element,
int trigger_event,
int trigger_player,
int trigger_side,
{
change->actual_trigger_element = trigger_element;
change->actual_trigger_player = EL_PLAYER_1 + log_2(trigger_player);
+ change->actual_trigger_side = trigger_side;
+ change->actual_trigger_ce_value = CustomValue[x][y];
if ((change->can_change && !change_done) || change->has_action)
{
{
change->actual_trigger_element = trigger_element;
change->actual_trigger_player = EL_PLAYER_1 + log_2(trigger_player);
+ change->actual_trigger_side = trigger_side;
+ change->actual_trigger_ce_value = CustomValue[x][y];
if (change->can_change && !change_done)
{
CE_LEFT_BY_PLAYER,
player->index_bit, leave_side);
- CheckTriggeredElementChangeByPlayer(old_element, CE_PLAYER_LEAVES_X,
+ CheckTriggeredElementChangeByPlayer(old_jx, old_jy, old_element,
+ CE_PLAYER_LEAVES_X,
player->index_bit, leave_side);
if (IS_CUSTOM_ELEMENT(new_element))
CheckElementChangeByPlayer(jx, jy, new_element, CE_ENTERED_BY_PLAYER,
player->index_bit, enter_side);
- CheckTriggeredElementChangeByPlayer(new_element, CE_PLAYER_ENTERS_X,
+ CheckTriggeredElementChangeByPlayer(jx, jy, new_element,
+ CE_PLAYER_ENTERS_X,
player->index_bit, enter_side);
}
CheckElementChangeByPlayer(xx, yy, border_element, CE_TOUCHED_BY_PLAYER,
player->index_bit, border_side);
- CheckTriggeredElementChangeByPlayer(border_element, CE_PLAYER_TOUCHES_X,
+ CheckTriggeredElementChangeByPlayer(xx, yy, border_element,
+ CE_PLAYER_TOUCHES_X,
player->index_bit, border_side);
}
else if (IS_PLAYER(xx, yy))
CheckElementChangeByPlayer(x, y, center_element, CE_TOUCHED_BY_PLAYER,
player->index_bit, center_side);
- CheckTriggeredElementChangeByPlayer(center_element, CE_PLAYER_TOUCHES_X,
+ CheckTriggeredElementChangeByPlayer(x, y, center_element,
+ CE_PLAYER_TOUCHES_X,
player->index_bit, center_side);
break;
}
return MF_NO_ACTION; /* field has no opening in this direction */
element = Feld[x][y];
-#if USE_NEW_COLLECT_COUNT
- collect_count = Count[x][y];
+#if USE_NEW_CUSTOM_VALUE
+
+#if 1
+ collect_count = element_info[element].collect_count_initial;
+#else
+ collect_count = CustomValue[x][y];
+#endif
+
#else
collect_count = element_info[element].collect_count_initial;
#endif
#if 0
if (element != EL_BLOCKED &&
- Count[x][y] != element_info[element].collect_count_initial)
+ CustomValue[x][y] != element_info[element].collect_count_initial)
printf("::: %d: %d != %d\n",
element,
- Count[x][y],
+ CustomValue[x][y],
element_info[element].collect_count_initial);
#endif
PlayLevelSoundElementAction(x, y, element, ACTION_DIGGING);
- CheckTriggeredElementChangeByPlayer(element, CE_PLAYER_DIGS_X,
+ CheckTriggeredElementChangeByPlayer(x, y, element, CE_PLAYER_DIGS_X,
player->index_bit, dig_side);
if (mode == DF_SNAP)
PlayLevelSoundElementAction(x, y, element, ACTION_COLLECTING);
if (is_player)
- CheckTriggeredElementChangeByPlayer(element, CE_PLAYER_COLLECTS_X,
+ CheckTriggeredElementChangeByPlayer(x, y, element, CE_PLAYER_COLLECTS_X,
player->index_bit, dig_side);
if (mode == DF_SNAP)
{
CheckElementChangeByPlayer(x, y, element, CE_PUSHED_BY_PLAYER,
player->index_bit, dig_side);
- CheckTriggeredElementChangeByPlayer(element, CE_PLAYER_PUSHES_X,
+ CheckTriggeredElementChangeByPlayer(x, y, element, CE_PLAYER_PUSHES_X,
player->index_bit, dig_side);
}
}
{
if (PLAYER_SWITCHING(player, x, y))
{
- CheckTriggeredElementChangeByPlayer(element, CE_PLAYER_PRESSES_X,
+ CheckTriggeredElementChangeByPlayer(x, y, element, CE_PLAYER_PRESSES_X,
player->index_bit, dig_side);
return MF_ACTION;
DrawLevelField(x, y);
}
- CheckTriggeredElementChangeByPlayer(element, CE_SWITCH_OF_X,
+ CheckTriggeredElementChangeByPlayer(x, y, element, CE_SWITCH_OF_X,
player->index_bit, dig_side);
- CheckTriggeredElementChangeByPlayer(element, CE_PLAYER_PRESSES_X,
+ CheckTriggeredElementChangeByPlayer(x, y, element, CE_PLAYER_PRESSES_X,
player->index_bit, dig_side);
return MF_ACTION;
CheckElementChangeByPlayer(x, y, element, CE_SWITCHED,
player->index_bit, dig_side);
- CheckTriggeredElementChangeByPlayer(element, CE_SWITCH_OF_X,
+ CheckTriggeredElementChangeByPlayer(x, y, element, CE_SWITCH_OF_X,
player->index_bit, dig_side);
}
CheckElementChangeByPlayer(x, y, element, CE_PRESSED_BY_PLAYER,
player->index_bit, dig_side);
- CheckTriggeredElementChangeByPlayer(element, CE_PLAYER_PRESSES_X,
+ CheckTriggeredElementChangeByPlayer(x, y, element, CE_PLAYER_PRESSES_X,
player->index_bit, dig_side);
return MF_NO_ACTION;
CheckElementChangeByPlayer(dropx, dropy, new_element, CE_DROPPED_BY_PLAYER,
player->index_bit, drop_side);
- CheckTriggeredElementChangeByPlayer(new_element, CE_PLAYER_DROPS_X,
+ CheckTriggeredElementChangeByPlayer(dropx, dropy, new_element,
+ CE_PLAYER_DROPS_X,
player->index_bit, drop_side);
TestIfElementTouchesCustomElement(dropx, dropy);