enginetestnew: all
./Scripts/make_enginetest.sh new
+leveltest: all
+ ./Scripts/make_enginetest.sh leveltest
+
backup:
./Scripts/make_backup.sh src
-#define COMPILE_DATE_STRING "[2005-11-20 02:42]"
+#define COMPILE_DATE_STRING "[2005-11-22 02:31]"
#define GADGET_ID_CHANGE_PLAYER (GADGET_ID_SELECTBOX_FIRST + 19)
#define GADGET_ID_CHANGE_PAGE (GADGET_ID_SELECTBOX_FIRST + 20)
#define GADGET_ID_CHANGE_REPLACE_WHEN (GADGET_ID_SELECTBOX_FIRST + 21)
-#define GADGET_ID_CHANGE_ACTION (GADGET_ID_SELECTBOX_FIRST + 22)
-#define GADGET_ID_CHANGE_ACTION_MODE (GADGET_ID_SELECTBOX_FIRST + 23)
-#define GADGET_ID_CHANGE_ACTION_ARG (GADGET_ID_SELECTBOX_FIRST + 24)
+#define GADGET_ID_ACTION_TYPE (GADGET_ID_SELECTBOX_FIRST + 22)
+#define GADGET_ID_ACTION_MODE (GADGET_ID_SELECTBOX_FIRST + 23)
+#define GADGET_ID_ACTION_ARG (GADGET_ID_SELECTBOX_FIRST + 24)
#define GADGET_ID_SELECT_CHANGE_PAGE (GADGET_ID_SELECTBOX_FIRST + 25)
#define GADGET_ID_GROUP_CHOICE_MODE (GADGET_ID_SELECTBOX_FIRST + 26)
#define ED_SELECTBOX_ID_CHANGE_PLAYER 19
#define ED_SELECTBOX_ID_CHANGE_PAGE 20
#define ED_SELECTBOX_ID_CHANGE_REPLACE_WHEN 21
-#define ED_SELECTBOX_ID_CHANGE_ACTION 22
-#define ED_SELECTBOX_ID_CHANGE_ACTION_MODE 23
-#define ED_SELECTBOX_ID_CHANGE_ACTION_ARG 24
+#define ED_SELECTBOX_ID_ACTION_TYPE 22
+#define ED_SELECTBOX_ID_ACTION_MODE 23
+#define ED_SELECTBOX_ID_ACTION_ARG 24
#define ED_SELECTBOX_ID_SELECT_CHANGE_PAGE 25
#define ED_SELECTBOX_ID_GROUP_CHOICE_MODE 26
/* values for elements with count for collecting */
#define MIN_COLLECT_COUNT 0
-#define MAX_COLLECT_COUNT 100
+#define MAX_COLLECT_COUNT 255
/* values for random placement */
#define RANDOM_USE_PERCENTAGE 0
{ CE_IMPACT, "impact (on something)" },
{ CE_SMASHED, "smashed (from above)" },
+ { CE_COUNT_AT_ZERO, "CE count at zero" },
{ -1, NULL }
};
{ CE_SWITCH_OF_X, "switch of" },
{ CE_CHANGE_OF_X, "change by page of" },
{ CE_EXPLOSION_OF_X, "explosion of" },
+ { CE_COUNT_AT_ZERO_OF_X, "CE count at zero of" },
{ -1, NULL }
};
{ -1, NULL }
};
-static struct ValueTextInfo options_change_action[] =
+static struct ValueTextInfo options_action_type[] =
{
{ CA_NO_ACTION, "no action" },
{ CA_EXIT_PLAYER, "exit player" },
{ CA_DEL_KEY, "remove key" },
{ CA_SET_PLAYER_SPEED, "set player speed" },
{ CA_SET_GEMS, "set gems" },
- { CA_SET_SCORE, "set score" },
{ CA_SET_TIME, "set time" },
- { CA_SET_COUNTER, "set counter" },
+ { CA_SET_SCORE, "set score" },
+ { CA_SET_CE_SCORE, "set CE score" },
+ { CA_SET_CE_COUNT, "set CE count" },
{ CA_SET_DYNABOMB_NUMBER, "set bomb number" },
{ CA_SET_DYNABOMB_SIZE, "set bomb size" },
{ CA_SET_DYNABOMB_POWER, "set bomb power" },
{ -1, NULL }
};
-static struct ValueTextInfo options_change_action_mode[] =
+static struct ValueTextInfo options_action_mode[] =
{
{ CA_MODE_UNDEFINED, " " },
{ CA_MODE_ADD, "+" },
{ -1, NULL }
};
-static struct ValueTextInfo options_change_action_arg[] =
+static struct ValueTextInfo options_action_arg[] =
{
- { CA_ARG_PLAYER_HEADLINE, "[players]" },
+ { CA_ARG_PLAYER_HEADLINE, "[player]" },
{ CA_ARG_PLAYER_1, "1" },
{ CA_ARG_PLAYER_2, "2" },
{ CA_ARG_PLAYER_3, "3" },
{ CA_ARG_PLAYER_ANY, "any" },
{ CA_ARG_PLAYER_TRIGGER, "trigger" },
{ CA_ARG_UNDEFINED, " " },
- { CA_ARG_NUMBER_HEADLINE, "[numbers]" },
+ { CA_ARG_NUMBER_HEADLINE, "[number]" },
{ CA_ARG_0, "0" },
{ CA_ARG_1, "1" },
{ CA_ARG_2, "2" },
{ CA_ARG_3, "3" },
{ CA_ARG_4, "4" },
{ CA_ARG_5, "5" },
- { CA_ARG_6, "6" },
- { CA_ARG_7, "7" },
- { CA_ARG_8, "8" },
- { CA_ARG_9, "9" },
{ CA_ARG_10, "10" },
- { CA_ARG_20, "20" },
- { CA_ARG_25, "25" },
- { CA_ARG_50, "50" },
{ CA_ARG_100, "100" },
{ CA_ARG_1000, "1000" },
{ CA_ARG_UNDEFINED, " " },
{ CA_ARG_NUMBER_MAX, "max" },
{ CA_ARG_NUMBER_NORMAL, "normal" },
{ CA_ARG_NUMBER_RESET, "reset" },
- { CA_ARG_NUMBER_COUNT, "counter" },
+ { CA_ARG_NUMBER_CE_SCORE, "CE score" },
+ { CA_ARG_NUMBER_CE_COUNT, "CE count" },
+ { CA_ARG_NUMBER_CE_DELAY, "CE delay" },
+ { CA_ARG_UNDEFINED, " " },
+ { CA_ARG_ELEMENT_HEADLINE, "[element]" },
+ { CA_ARG_ELEMENT_TARGET, "target" },
+ { CA_ARG_ELEMENT_TRIGGER, "trigger" },
{ -1, NULL }
};
},
{
ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(13),
- GADGET_ID_CHANGE_ACTION, GADGET_ID_NONE,
+ GADGET_ID_ACTION_TYPE, GADGET_ID_NONE,
-1,
- options_change_action,
- &custom_element_change.change_action,
+ options_action_type,
+ &custom_element_change.action_type,
NULL, NULL, "action on specified condition"
},
{
-1, ED_ELEMENT_SETTINGS_YPOS(13),
- GADGET_ID_CHANGE_ACTION_MODE, GADGET_ID_CHANGE_ACTION,
+ GADGET_ID_ACTION_MODE, GADGET_ID_ACTION_TYPE,
-1,
- options_change_action_mode,
- &custom_element_change.change_action_mode,
+ options_action_mode,
+ &custom_element_change.action_mode,
NULL, NULL, "action operator"
},
{
-1, ED_ELEMENT_SETTINGS_YPOS(13),
- GADGET_ID_CHANGE_ACTION_ARG, GADGET_ID_CHANGE_ACTION_MODE,
+ GADGET_ID_ACTION_ARG, GADGET_ID_ACTION_MODE,
-1,
- options_change_action_arg,
- &custom_element_change.change_action_arg,
+ options_action_arg,
+ &custom_element_change.action_arg,
NULL, NULL, "action parameter"
},
{
{
ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(13),
GADGET_ID_CHANGE_USE_ACTION, GADGET_ID_NONE,
- &custom_element_change.use_change_action,
+ &custom_element_change.use_action,
NULL, NULL, "execute action on specified condition"
},
};
HAS_CHANGE_EVENT(element, CE_BLOCKED) ? CE_BLOCKED :
HAS_CHANGE_EVENT(element, CE_IMPACT) ? CE_IMPACT :
HAS_CHANGE_EVENT(element, CE_SMASHED) ? CE_SMASHED :
+ HAS_CHANGE_EVENT(element, CE_COUNT_AT_ZERO) ? CE_COUNT_AT_ZERO :
custom_element_change.direct_action);
/* set "change by other element action" selectbox help value */
HAS_CHANGE_EVENT(element, CE_SWITCH_OF_X) ? CE_SWITCH_OF_X :
HAS_CHANGE_EVENT(element, CE_CHANGE_OF_X) ? CE_CHANGE_OF_X :
HAS_CHANGE_EVENT(element, CE_EXPLOSION_OF_X) ? CE_EXPLOSION_OF_X :
+ HAS_CHANGE_EVENT(element, CE_COUNT_AT_ZERO_OF_X) ? CE_COUNT_AT_ZERO_OF_X :
custom_element_change.other_action);
}
custom_element_change_events[CE_BLOCKED] = FALSE;
custom_element_change_events[CE_IMPACT] = FALSE;
custom_element_change_events[CE_SMASHED] = FALSE;
+ custom_element_change_events[CE_COUNT_AT_ZERO] = FALSE;
custom_element_change_events[custom_element_change.direct_action] =
custom_element_change_events[CE_BY_DIRECT_ACTION];
custom_element_change_events[CE_SWITCH_OF_X] = FALSE;
custom_element_change_events[CE_CHANGE_OF_X] = FALSE;
custom_element_change_events[CE_EXPLOSION_OF_X] = FALSE;
+ custom_element_change_events[CE_COUNT_AT_ZERO_OF_X] = FALSE;
custom_element_change_events[custom_element_change.other_action] =
custom_element_change_events[CE_BY_OTHER_ACTION];
change->random_percentage = 100;
change->replace_when = CP_WHEN_EMPTY;
- change->use_change_action = FALSE;
- change->change_action = CA_NO_ACTION;
- change->change_action_mode = CA_MODE_UNDEFINED;
- change->change_action_arg = CA_ARG_UNDEFINED;
+ change->use_action = FALSE;
+ change->action_type = CA_NO_ACTION;
+ change->action_mode = CA_MODE_UNDEFINED;
+ change->action_arg = CA_ARG_UNDEFINED;
for (x = 0; x < 3; x++)
for (y = 0; y < 3; y++)
change->trigger_page = (change->trigger_page == CH_PAGE_ANY_FILE ?
CH_PAGE_ANY : (1 << change->trigger_page));
+#if 1
+ change->use_action = getFile8Bit(file);
+ change->action_type = getFile8Bit(file);
+ change->action_mode = getFile8Bit(file);
+ change->action_arg = getFile16BitBE(file);
+
+ /* some free bytes for future change property values and padding */
+ ReadUnusedBytesFromFile(file, 1);
+#else
/* some free bytes for future change property values and padding */
ReadUnusedBytesFromFile(file, 6);
+#endif
#else
int i, j, x, y;
/* map custom element change events that have changed in newer versions
- (these following values were accidentally changed in version 3.0.1) */
+ (these following values were accidentally changed in version 3.0.1)
+ (this seems to be needed only for 'ab_levelset3' and 'ab_levelset4') */
if (level->game_version <= VERSION_IDENT(3,0,0,0))
{
for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++)
int element = EL_CUSTOM_START + i;
/* order of checking and copying events to be mapped is important */
- for (j = CE_BY_OTHER_ACTION; j >= CE_BY_PLAYER_OBSOLETE; j--)
+ for (j = CE_BY_OTHER_ACTION; j >= CE_COUNT_AT_ZERO; j--)
{
if (HAS_CHANGE_EVENT(element, j - 2))
{
}
}
+#if 0
+ /* !!! TESTS SHOWED THAT THIS CODE SEGMENT IS NOT NEEDED FOR ANY LEVEL !!! */
+
/* some custom element change events get mapped since version 3.0.3 */
- for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++)
+#if 1
+ if (level->game_version >= VERSION_IDENT(3,0,3,0) &&
+ level->game_version <= VERSION_IDENT(3,2,0,3))
+#endif
{
- int element = EL_CUSTOM_START + i;
-
- if (HAS_CHANGE_EVENT(element, CE_BY_PLAYER_OBSOLETE) ||
- HAS_CHANGE_EVENT(element, CE_BY_COLLISION_OBSOLETE))
+ for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++)
{
- SET_CHANGE_EVENT(element, CE_BY_PLAYER_OBSOLETE, FALSE);
- SET_CHANGE_EVENT(element, CE_BY_COLLISION_OBSOLETE, FALSE);
+ int element = EL_CUSTOM_START + i;
+
+ if (HAS_CHANGE_EVENT(element, CE_BY_PLAYER_OBSOLETE) ||
+ HAS_CHANGE_EVENT(element, CE_BY_COLLISION_OBSOLETE))
+ {
+ SET_CHANGE_EVENT(element, CE_BY_PLAYER_OBSOLETE, FALSE);
+ SET_CHANGE_EVENT(element, CE_BY_COLLISION_OBSOLETE, FALSE);
- SET_CHANGE_EVENT(element, CE_BY_DIRECT_ACTION, TRUE);
+ SET_CHANGE_EVENT(element, CE_BY_DIRECT_ACTION, TRUE);
+ }
}
}
+#endif
/* initialize "can_change" field for old levels with only one change page */
if (level->game_version <= VERSION_IDENT(3,0,2,0))
putFile8Bit(file, (change->trigger_page == CH_PAGE_ANY ? CH_PAGE_ANY_FILE :
log_2(change->trigger_page)));
+#if 1
+
+ putFile8Bit(file, change->use_action);
+ putFile8Bit(file, change->action_type);
+ putFile8Bit(file, change->action_mode);
+ putFile16BitBE(file, change->action_arg);
+
+ /* some free bytes for future change property values and padding */
+ WriteUnusedBytesToFile(file, 1);
+#else
/* some free bytes for future change property values and padding */
WriteUnusedBytesToFile(file, 6);
+#endif
#else
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_CHANGE_DELAY(c) ( ((c)->delay_fixed * (c)->delay_frames) + \
+ RND((c)->delay_random * (c)->delay_frames))
#define GET_TARGET_ELEMENT(e, ch) \
((e) == EL_TRIGGER_ELEMENT ? (ch)->actual_trigger_element : \
/* currently only 4 of 8 possible keys are displayed */
for (i = 0; i < STD_NUM_KEYS; i++)
+ {
if (key[i])
DrawMiniGraphicExt(drawto, DX_KEYS + i * MINI_TILEX, DY_KEYS,
el2edimg(EL_KEY_1 + i));
+ else
+ BlitBitmap(graphic_info[IMG_GLOBAL_DOOR].bitmap, drawto,
+ DOOR_GFX_PAGEX5 + XX_KEYS + i * MINI_TILEX, YY_KEYS,
+ MINI_TILEX, MINI_TILEY, DX_KEYS + i * MINI_TILEX, DY_KEYS);
+ }
}
inline void DrawGameValue_Score(int value)
DrawLevelFieldCrumbledSand(x, y);
}
-static void HandleChangeAction(int change_action)
+static int getSpecialActionElement(int element, int number, int base_element)
{
- if (change_action == CA_EXIT_PLAYER)
- {
- printf("::: CA_EXIT_GAME\n");
+ return (element != EL_EMPTY ? element :
+ number != -1 ? base_element + number - 1 :
+ EL_EMPTY);
+}
- /* !!! local_player <-> 4 players !!! (EXTEND THIS) !!! */
- local_player->LevelSolved = local_player->GameOver = TRUE;
- }
- else if (change_action == CA_KILL_PLAYER)
- {
- printf("::: CA_KILL_PLAYER\n");
+static int getModifiedActionNumber(int value_old, int value_min, int value_max,
+ int operator, int operand)
+{
+ int value_new = (operator == CA_MODE_ADD ? value_old + operand :
+ operator == CA_MODE_SUBTRACT ? value_old - operand :
+ operator == CA_MODE_MULTIPLY ? value_old * operand :
+ operator == CA_MODE_DIVIDE ? value_old / MAX(1, operand) :
+ operator == CA_MODE_SET ? operand :
+ value_old);
+
+ return (value_new < value_min ? value_min :
+ value_new > value_max ? value_max :
+ value_new);
+}
+
+static void ExecuteCustomElementAction(int x, int y, int element, int page)
+{
+ struct ElementInfo *ei = &element_info[element];
+ struct ElementChangeInfo *change = &ei->change_page[page];
+ int action_type = change->action_type;
+ int action_mode = change->action_mode;
+ int action_arg = change->action_arg;
+ int i;
+
+ /* ---------- determine action paramater values ---------- */
+
+ int action_arg_element =
+ (action_arg == CA_ARG_PLAYER_TRIGGER ? change->actual_trigger_player :
+ action_arg == CA_ARG_ELEMENT_TRIGGER ? change->actual_trigger_element :
+ action_arg == CA_ARG_ELEMENT_TARGET ? change->target_element :
+ EL_EMPTY);
+
+ int action_arg_number =
+ (action_arg <= CA_ARG_MAX ? action_arg :
+ action_arg == CA_ARG_NUMBER_MIN ? CA_ARG_MIN :
+ action_arg == CA_ARG_NUMBER_MAX ? CA_ARG_MAX :
+ action_arg == CA_ARG_NUMBER_CE_SCORE ? ei->collect_score :
+ action_arg == CA_ARG_NUMBER_CE_COUNT ? ei->collect_count :
+ action_arg == CA_ARG_NUMBER_CE_DELAY ? GET_CHANGE_DELAY(change) :
+ -1);
+
+ /* (for explicit player choice, set invalid value to "no player") */
+ int action_arg_player_bits =
+ (action_arg == CA_ARG_PLAYER_ANY ? action_arg - CA_ARG_PLAYER :
+ 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 - 1)) :
+ action_arg_element >= EL_PLAYER_1 &&
+ action_arg_element <= EL_PLAYER_4 ?
+ (1 << (action_arg_element - EL_PLAYER_1)) :
+ 0);
+
+ /* (for implicit player choice, set invalid value to "all players") */
+ 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);
+
+ /* ---------- execute action ---------- */
+
+ switch(action_type)
+ {
+ case CA_NO_ACTION:
+ {
+ return;
+ }
+
+ case CA_EXIT_PLAYER:
+ {
+ for (i = 0; i < MAX_PLAYERS; i++)
+ if (action_arg_player_bits & (1 << i))
+ stored_player[i].LevelSolved = stored_player[i].GameOver = TRUE;
+
+ break;
+ }
+
+ case CA_KILL_PLAYER:
+ {
+ for (i = 0; i < MAX_PLAYERS; i++)
+ if (action_arg_player_bits & (1 << i))
+ KillHero(&stored_player[i]);
+
+ break;
+ }
+
+ case CA_RESTART_LEVEL:
+ {
+ printf("::: CA_RESTART_LEVEL -- not yet implemented\n");
+
+ break;
+ }
+
+ case CA_SHOW_ENVELOPE:
+ {
+ int element = getSpecialActionElement(action_arg_element,
+ action_arg_number, EL_ENVELOPE_1);
+
+ if (IS_ENVELOPE(element))
+ local_player->show_envelope = element;
+
+ 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_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);
+ }
- /* !!! local_player <-> 4 players !!! (EXTEND THIS) !!! */
- KillHero(local_player);
+ 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;
}
}
TestIfElementTouchesCustomElement(x, y);
#endif
- if (change->use_change_action)
- HandleChangeAction(change->change_action);
+#if 0
+ if (change->use_action)
+ ExecuteCustomElementAction(...);
+#endif
}
static boolean ChangeElementNow(int x, int y, int element, int page)
if (ChangeEvent[x][y] == CE_DELAY)
{
- /* reset actual trigger element and player */
+ /* reset actual trigger element, trigger player and action element */
change->actual_trigger_element = EL_EMPTY;
change->actual_trigger_player = EL_PLAYER_1;
}
if (ChangeDelay[x][y] == 0) /* initialize element change */
{
+#if 1
+ ChangeDelay[x][y] = GET_CHANGE_DELAY(change) + 1;
+#else
ChangeDelay[x][y] = ( change->delay_fixed * change->delay_frames +
RND(change->delay_random * change->delay_frames)) + 1;
+#endif
ResetGfxAnimation(x, y);
ResetRandomAnimationValue(x, y);
return;
}
+#if 1
+ if (change->use_action)
+ ExecuteCustomElementAction(x, y, element, page);
+#endif
+
if (ChangeElementNow(x, y, element, page))
{
if (change->post_change_function)
}
if (element == EL_SPEED_PILL)
+ {
player->move_delay_value = MOVE_DELAY_HIGH_SPEED;
+ }
else if (element == EL_EXTRA_TIME && level.time > 0)
{
TimeLeft += 10;
#define CE_PLAYER_PUSHES_X 13
#define CE_PLAYER_COLLECTS_X 14
#define CE_PLAYER_DROPS_X 15
+
+#if 1
+#define CE_COUNT_AT_ZERO 16
+#define CE_COUNT_AT_ZERO_OF_X 17
+#else
#define CE_BY_PLAYER_OBSOLETE 16 /* obsolete; now CE_BY_DIRECT_ACTION */
#define CE_BY_COLLISION_OBSOLETE 17 /* obsolete; now CE_BY_DIRECT_ACTION */
+#endif
+
#define CE_BY_OTHER_ACTION 18 /* activates other element events */
#define CE_BY_DIRECT_ACTION 19 /* activates direct element events */
#define CE_PLAYER_DIGS_X 20
(CH_ANY_EVENT_VAR(e) &= ~CH_EVENT_BIT(c))) : 0)
#endif
+/* values for player bitmasks */
+#define PLAYER_BITS_NONE 0
+#define PLAYER_BITS_1 (1 << 0)
+#define PLAYER_BITS_2 (1 << 1)
+#define PLAYER_BITS_3 (1 << 2)
+#define PLAYER_BITS_4 (1 << 3)
+#define PLAYER_BITS_ANY (PLAYER_BITS_1 | \
+ PLAYER_BITS_2 | \
+ PLAYER_BITS_3 | \
+ PLAYER_BITS_4)
+#define PLAYER_BITS_TRIGGER (1 << 4)
+
/* values for change side for custom elements */
#define CH_SIDE_NONE MV_NO_MOVING
#define CH_SIDE_LEFT MV_LEFT
#define CH_SIDE_ANY MV_ANY_DIRECTION
/* values for change player for custom elements */
-#define CH_PLAYER_NONE 0
-#define CH_PLAYER_1 (1 << 0)
-#define CH_PLAYER_2 (1 << 1)
-#define CH_PLAYER_3 (1 << 2)
-#define CH_PLAYER_4 (1 << 3)
-#define CH_PLAYER_ANY (CH_PLAYER_1 | \
- CH_PLAYER_2 | \
- CH_PLAYER_3 | \
- CH_PLAYER_4)
-#define CH_PLAYER_TRIGGER (1 << 4)
+#define CH_PLAYER_NONE PLAYER_BITS_NONE
+#define CH_PLAYER_1 PLAYER_BITS_1
+#define CH_PLAYER_2 PLAYER_BITS_2
+#define CH_PLAYER_3 PLAYER_BITS_3
+#define CH_PLAYER_4 PLAYER_BITS_4
+#define CH_PLAYER_ANY PLAYER_BITS_ANY
/* values for change page for custom elements */
#define CH_PAGE_ANY_FILE (0xff)
#define CA_DEL_KEY 6
#define CA_SET_PLAYER_SPEED 7
#define CA_SET_GEMS 8
-#define CA_SET_SCORE 9
-#define CA_SET_TIME 10
-#define CA_SET_COUNTER 11
-#define CA_SET_DYNABOMB_NUMBER 12
-#define CA_SET_DYNABOMB_SIZE 13
-#define CA_SET_DYNABOMB_POWER 14
-#define CA_TOGGLE_PLAYER_GRAVITY 15
-#define CA_ENABLE_PLAYER_GRAVITY 16
-#define CA_DISABLE_PLAYER_GRAVITY 17
+#define CA_SET_TIME 9
+#define CA_SET_SCORE 10
+#define CA_SET_CE_SCORE 11
+#define CA_SET_CE_COUNT 12
+#define CA_SET_DYNABOMB_NUMBER 13
+#define CA_SET_DYNABOMB_SIZE 14
+#define CA_SET_DYNABOMB_POWER 15
+#define CA_TOGGLE_PLAYER_GRAVITY 16
+#define CA_ENABLE_PLAYER_GRAVITY 17
+#define CA_DISABLE_PLAYER_GRAVITY 18
/* values for change action mode for custom elements */
#define CA_MODE_UNDEFINED 0
#define CA_MODE_SET 5
/* values for change action parameters for custom elements */
+#define CA_ARG_MIN 0
#define CA_ARG_0 0
#define CA_ARG_1 1
#define CA_ARG_2 2
#define CA_ARG_3 3
#define CA_ARG_4 4
#define CA_ARG_5 5
-#define CA_ARG_6 6
-#define CA_ARG_7 7
-#define CA_ARG_8 8
-#define CA_ARG_9 9
#define CA_ARG_10 10
-#define CA_ARG_20 20
-#define CA_ARG_25 25
-#define CA_ARG_50 50
#define CA_ARG_100 100
#define CA_ARG_1000 1000
-#define CA_ARG_PLAYER 20000
+#define CA_ARG_MAX 9999
+#define CA_ARG_PLAYER 10000
#define CA_ARG_PLAYER_HEADLINE (CA_ARG_PLAYER + 0)
-#define CA_ARG_PLAYER_1 (CA_ARG_PLAYER + CH_PLAYER_1)
-#define CA_ARG_PLAYER_2 (CA_ARG_PLAYER + CH_PLAYER_2)
-#define CA_ARG_PLAYER_3 (CA_ARG_PLAYER + CH_PLAYER_3)
-#define CA_ARG_PLAYER_4 (CA_ARG_PLAYER + CH_PLAYER_4)
-#define CA_ARG_PLAYER_ANY (CA_ARG_PLAYER + CH_PLAYER_ANY)
-#define CA_ARG_PLAYER_TRIGGER (CA_ARG_PLAYER + CH_PLAYER_TRIGGER)
-#define CA_ARG_NUMBER 30000
+#define CA_ARG_PLAYER_1 (CA_ARG_PLAYER + PLAYER_BITS_1)
+#define CA_ARG_PLAYER_2 (CA_ARG_PLAYER + PLAYER_BITS_2)
+#define CA_ARG_PLAYER_3 (CA_ARG_PLAYER + PLAYER_BITS_3)
+#define CA_ARG_PLAYER_4 (CA_ARG_PLAYER + PLAYER_BITS_4)
+#define CA_ARG_PLAYER_ANY (CA_ARG_PLAYER + PLAYER_BITS_ANY)
+#define CA_ARG_PLAYER_TRIGGER (CA_ARG_PLAYER + PLAYER_BITS_TRIGGER)
+#define CA_ARG_NUMBER 20000
#define CA_ARG_NUMBER_HEADLINE (CA_ARG_NUMBER + 0)
#define CA_ARG_NUMBER_MIN (CA_ARG_NUMBER + 1)
#define CA_ARG_NUMBER_MAX (CA_ARG_NUMBER + 2)
#define CA_ARG_NUMBER_NORMAL (CA_ARG_NUMBER + 3)
#define CA_ARG_NUMBER_RESET (CA_ARG_NUMBER + 4)
-#define CA_ARG_NUMBER_COUNT (CA_ARG_NUMBER + 5)
+#define CA_ARG_NUMBER_CE_SCORE (CA_ARG_NUMBER + 5)
+#define CA_ARG_NUMBER_CE_COUNT (CA_ARG_NUMBER + 6)
+#define CA_ARG_NUMBER_CE_DELAY (CA_ARG_NUMBER + 7)
+#define CA_ARG_ELEMENT 30000
+#define CA_ARG_ELEMENT_HEADLINE (CA_ARG_ELEMENT + 0)
+#define CA_ARG_ELEMENT_TARGET (CA_ARG_ELEMENT + 1)
+#define CA_ARG_ELEMENT_TRIGGER (CA_ARG_ELEMENT + 2)
#define CA_ARG_UNDEFINED 30999
/* values for custom move patterns (bits 0 - 3: basic move directions) */
boolean explode; /* explode instead of change */
- boolean use_change_action; /* execute change action after change */
- int change_action; /* type of change action after change */
- int change_action_mode; /* mode of change action after change */
- int change_action_arg; /* parameter of change action after change */
+ boolean use_action; /* execute action on specified condition */
+ int action_type; /* type of action */
+ int action_mode; /* mode of action */
+ int action_arg; /* parameter of action */
/* ---------- internal values used at runtime when playing ---------- */
continue;
}
+#if 0
+ /* ACTIVATE THIS FOR LOADING/TESTING OF LEVELS ONLY */
+ printf("(only testing level)\n");
+ continue;
+#endif
+
LoadSolutionTape(level_nr);
#if 1
if (tape.no_valid_file)