#define CE_HITTING_SOMETHING 5
#define CE_IMPACT 6
#define CE_SMASHED 7
-#define CE_OTHER_IS_TOUCHING 8
-#define CE_OTHER_IS_CHANGING 9
-#define CE_OTHER_IS_EXPLODING 10
-#define CE_OTHER_GETS_TOUCHED 11
-#define CE_OTHER_GETS_PRESSED 12
-#define CE_OTHER_GETS_PUSHED 13
-#define CE_OTHER_GETS_COLLECTED 14
-#define CE_OTHER_GETS_DROPPED 15
+#define CE_TOUCHING_X 8
+#define CE_CHANGE_OF_X 9
+#define CE_EXPLOSION_OF_X 10
+#define CE_PLAYER_TOUCHES_X 11
+#define CE_PLAYER_PRESSES_X 12
+#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_OTHER_GETS_DIGGED 20
+#define CE_PLAYER_DIGS_X 20
#define CE_ENTERED_BY_PLAYER 21
#define CE_LEFT_BY_PLAYER 22
-#define CE_OTHER_GETS_ENTERED 23
-#define CE_OTHER_GETS_LEFT 24
+#define CE_PLAYER_ENTERS_X 23
+#define CE_PLAYER_LEAVES_X 24
#define CE_SWITCHED 25
-#define CE_OTHER_IS_SWITCHING 26
+#define CE_SWITCH_OF_X 26
#define CE_HIT_BY_SOMETHING 27
-#define CE_OTHER_IS_HITTING 28
-#define CE_OTHER_GETS_HIT 29
+#define CE_HITTING_X 28
+#define CE_HIT_BY_X 29
#define CE_BLOCKED 30
#define NUM_CHANGE_EVENTS 31
#define CE_BITMASK_DEFAULT 0
+#if 1
+
+#define CH_EVENT_VAR(e,c) (element_info[e].change->has_event[c])
+#define CH_ANY_EVENT_VAR(e,c) (element_info[e].has_change_event[c])
+
+#define PAGE_HAS_CHANGE_EVENT(p,c) ((p)->has_event[c])
+#define HAS_CHANGE_EVENT(e,c) (IS_CUSTOM_ELEMENT(e) && \
+ CH_EVENT_VAR(e,c))
+#define HAS_ANY_CHANGE_EVENT(e,c) (IS_CUSTOM_ELEMENT(e) && \
+ CH_ANY_EVENT_VAR(e,c))
+
+#define SET_CHANGE_EVENT(e,c,v) (IS_CUSTOM_ELEMENT(e) ? \
+ CH_EVENT_VAR(e,c) = (v) : 0)
+#define SET_ANY_CHANGE_EVENT(e,c,v) (IS_CUSTOM_ELEMENT(e) ? \
+ CH_ANY_EVENT_VAR(e,c) = (v) : 0)
+
+#else
+
#define CH_EVENT_BIT(c) (1 << (c))
#define CH_EVENT_VAR(e) (element_info[e].change->events)
#define CH_ANY_EVENT_VAR(e) (element_info[e].change_events)
((v) ? \
(CH_EVENT_VAR(e) |= CH_EVENT_BIT(c)) : \
(CH_EVENT_VAR(e) &= ~CH_EVENT_BIT(c))) : 0)
+#define SET_ANY_CHANGE_EVENT(e,c,v) (IS_CUSTOM_ELEMENT(e) ? \
+ ((v) ? \
+ (CH_ANY_EVENT_VAR(e) |= CH_EVENT_BIT(c)) : \
+ (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_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_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 CP_WHEN_REMOVABLE 4
#define CP_WHEN_WALKABLE 5
+/* values for change actions for custom elements */
+#define CA_NO_ACTION 0
+#define CA_EXIT_PLAYER 1
+#define CA_KILL_PLAYER 2
+#define CA_RESTART_LEVEL 3
+#define CA_SHOW_ENVELOPE 4
+#define CA_ADD_KEY 5
+#define CA_DEL_KEY 6
+#define CA_SET_PLAYER_SPEED 7
+#define CA_SET_GEMS 8
+#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_ADD 1
+#define CA_MODE_SUBTRACT 2
+#define CA_MODE_MULTIPLY 3
+#define CA_MODE_DIVIDE 4
+#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_10 10
+#define CA_ARG_100 100
+#define CA_ARG_1000 1000
+#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 + 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_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) */
#define MV_BIT_TOWARDS_PLAYER 4
#define MV_BIT_AWAY_FROM_PLAYER 5
#define MV_BIT_TURNING_RANDOM 16
/* values for custom move patterns */
-#define MV_HORIZONTAL (MV_LEFT | MV_RIGHT)
-#define MV_VERTICAL (MV_UP | MV_DOWN)
-#define MV_ALL_DIRECTIONS (MV_LEFT | MV_RIGHT | MV_UP | MV_DOWN)
-#define MV_ANY_DIRECTION (MV_ALL_DIRECTIONS)
#define MV_TOWARDS_PLAYER (1 << MV_BIT_TOWARDS_PLAYER)
#define MV_AWAY_FROM_PLAYER (1 << MV_BIT_AWAY_FROM_PLAYER)
#define MV_ALONG_LEFT_SIDE (1 << MV_BIT_ALONG_LEFT_SIDE)
#define IS_ENVELOPE(e) ((e) >= EL_ENVELOPE_1 && \
(e) <= EL_ENVELOPE_4)
-#define IS_GATE(e) ((e) >= EL_GATE_1 && \
+#define IS_RND_KEY(e) ((e) >= EL_KEY_1 && \
+ (e) <= EL_KEY_4)
+#define IS_EM_KEY(e) ((e) >= EL_EM_KEY_1 && \
+ (e) <= EL_EM_KEY_4)
+#define IS_EMC_KEY(e) ((e) >= EL_EMC_KEY_5 && \
+ (e) <= EL_EMC_KEY_8)
+#define IS_KEY(e) (IS_RND_KEY(e) || \
+ IS_EM_KEY(e) || \
+ IS_EMC_KEY(e))
+#define RND_KEY_NR(e) ((e) - EL_KEY_1)
+#define EM_KEY_NR(e) ((e) - EL_EM_KEY_1)
+#define EMC_KEY_NR(e) ((e) - EL_EMC_KEY_5 + 4)
+#define KEY_NR(e) (IS_RND_KEY(e) ? RND_KEY_NR(e) : \
+ IS_EM_KEY(e) ? EM_KEY_NR(e) : \
+ IS_EMC_KEY(e) ? EMC_KEY_NR(e) : 0)
+
+#define IS_RND_GATE(e) ((e) >= EL_GATE_1 && \
(e) <= EL_GATE_4)
-
-#define IS_GATE_GRAY(e) ((e) >= EL_GATE_1_GRAY && \
- (e) <= EL_GATE_4_GRAY)
-
#define IS_EM_GATE(e) ((e) >= EL_EM_GATE_1 && \
(e) <= EL_EM_GATE_4)
-
+#define IS_EMC_GATE(e) ((e) >= EL_EMC_GATE_5 && \
+ (e) <= EL_EMC_GATE_8)
+#define IS_GATE(e) (IS_RND_GATE(e) || \
+ IS_EM_GATE(e) || \
+ IS_EMC_GATE(e))
+#define RND_GATE_NR(e) ((e) - EL_GATE_1)
+#define EM_GATE_NR(e) ((e) - EL_EM_GATE_1)
+#define EMC_GATE_NR(e) ((e) - EL_EMC_GATE_5 + 4)
+#define GATE_NR(e) (IS_RND_GATE(e) ? RND_GATE_NR(e) : \
+ IS_EM_GATE(e) ? EM_GATE_NR(e) : \
+ IS_EMC_GATE(e) ? EMC_GATE_NR(e) : 0)
+
+#define IS_RND_GATE_GRAY(e) ((e) >= EL_GATE_1_GRAY && \
+ (e) <= EL_GATE_4_GRAY)
#define IS_EM_GATE_GRAY(e) ((e) >= EL_EM_GATE_1_GRAY && \
(e) <= EL_EM_GATE_4_GRAY)
+#define IS_EMC_GATE_GRAY(e) ((e) >= EL_EMC_GATE_5_GRAY && \
+ (e) <= EL_EMC_GATE_8_GRAY)
+#define IS_GATE_GRAY(e) (IS_RND_GATE_GRAY(e) || \
+ IS_EM_GATE_GRAY(e) || \
+ IS_EMC_GATE_GRAY(e))
+#define RND_GATE_GRAY_NR(e) ((e) - EL_GATE_1_GRAY)
+#define EM_GATE_GRAY_NR(e) ((e) - EL_EM_GATE_1_GRAY)
+#define EMC_GATE_GRAY_NR(e) ((e) - EL_EMC_GATE_5_GRAY + 4)
+#define GATE_GRAY_NR(e) (IS_RND_GATE_GRAY(e) ? RND_GATE_GRAY_NR(e) : \
+ IS_EM_GATE_GRAY(e) ? EM_GATE_GRAY_NR(e) : \
+ IS_EMC_GATE_GRAY(e) ? EMC_GATE_GRAY_NR(e) : 0)
#define GFX_ELEMENT(e) (element_info[e].use_gfx_element ? \
element_info[e].gfx_element : e)
#define PLAYER_SWITCHING(p,x,y) ((p)->is_switching && \
(p)->switch_x == (x) && (p)->switch_y == (y))
+#define PLAYER_DROPPING(p,x,y) ((p)->is_dropping && \
+ (p)->drop_x == (x) && (p)->drop_y == (y))
+
#define PLAYER_NR_GFX(g,i) ((g) + i * (IMG_PLAYER_2 - IMG_PLAYER_1))
#define ANIM_FRAMES(g) (graphic_info[g].anim_frames)
#define MAX_LEVEL_NAME_LEN 32
#define MAX_LEVEL_AUTHOR_LEN 32
#define MAX_ELEMENT_NAME_LEN 32
-#define MAX_TAPELEN (1000 * FRAMES_PER_SECOND) /* max.time x fps */
+#define MAX_TAPE_LEN (1000 * FRAMES_PER_SECOND) /* max.time x fps */
+#define MAX_TAPES_PER_SET 1024
#define MAX_SCORE_ENTRIES 100
#define MAX_NUM_AMOEBA 100
#define MAX_INVENTORY_SIZE 1000
-#define MAX_KEYS 4
+#define STD_NUM_KEYS 4
+#define MAX_NUM_KEYS 8
#define NUM_BELTS 4
#define NUM_BELT_PARTS 3
#define MIN_ENVELOPE_XSIZE 1
#define EYSIZE (VYSIZE + 44)
#define FULL_SXSIZE (2 + SXSIZE + 2)
#define FULL_SYSIZE (2 + SYSIZE + 2)
-#define MICROLEV_XSIZE ((STD_LEV_FIELDX + 2) * MICRO_TILEX)
-#define MICROLEV_YSIZE ((STD_LEV_FIELDY + 2) * MICRO_TILEY)
-#define MICROLEV_XPOS (SX + (SXSIZE - MICROLEV_XSIZE) / 2)
-#define MICROLEV_YPOS (SX + 12 * TILEY - MICRO_TILEY)
-#define MICROLABEL_YPOS (MICROLEV_YPOS + MICROLEV_YSIZE + 7)
+#define MICROLEVEL_XSIZE ((STD_LEV_FIELDX + 2) * MICRO_TILEX)
+#define MICROLEVEL_YSIZE ((STD_LEV_FIELDY + 2) * MICRO_TILEY)
+#define MICROLEVEL_XPOS (SX + (SXSIZE - MICROLEVEL_XSIZE) / 2)
+#define MICROLEVEL_YPOS (SX + 12 * TILEY - MICRO_TILEY)
+#define MICROLABEL1_YPOS (MICROLEVEL_YPOS - 36)
+#define MICROLABEL2_YPOS (MICROLEVEL_YPOS + MICROLEVEL_YSIZE + 7)
/* score for elements */
/* the following EMC style elements are currently not implemented in R'n'D */
#define EL_BALLOON_SWITCH_NONE 667
-#define EL_EM_GATE_5 668
-#define EL_EM_GATE_6 669
-#define EL_EM_GATE_7 670
-#define EL_EM_GATE_8 671
-#define EL_EM_GATE_5_GRAY 672
-#define EL_EM_GATE_6_GRAY 673
-#define EL_EM_GATE_7_GRAY 674
-#define EL_EM_GATE_8_GRAY 675
-#define EL_EM_KEY_5 676
-#define EL_EM_KEY_6 677
-#define EL_EM_KEY_7 678
-#define EL_EM_KEY_8 679
+#define EL_EMC_GATE_5 668
+#define EL_EMC_GATE_6 669
+#define EL_EMC_GATE_7 670
+#define EL_EMC_GATE_8 671
+#define EL_EMC_GATE_5_GRAY 672
+#define EL_EMC_GATE_6_GRAY 673
+#define EL_EMC_GATE_7_GRAY 674
+#define EL_EMC_GATE_8_GRAY 675
+#define EL_EMC_KEY_5 676
+#define EL_EMC_KEY_6 677
+#define EL_EMC_KEY_7 678
+#define EL_EMC_KEY_8 679
#define EL_EMC_ANDROID 680
#define EL_EMC_GRASS 681
#define EL_EMC_MAGIC_BALL 682
-#define EL_EMC_MAGIC_BALL_SWITCH 683
-#define EL_EMC_SPRING_BUMPER 684
-#define EL_EMC_PLANT 685
-#define EL_EMC_LENSES 686
-#define EL_EMC_MAGNIFIER 687
-#define EL_EMC_WALL_9 688
-#define EL_EMC_WALL_10 689
-#define EL_EMC_WALL_11 690
-#define EL_EMC_WALL_12 691
-#define EL_EMC_WALL_13 692
-#define EL_EMC_WALL_14 693
-#define EL_EMC_WALL_15 694
-#define EL_EMC_WALL_16 695
-#define EL_EMC_WALL_SLIPPERY_1 696
-#define EL_EMC_WALL_SLIPPERY_2 697
-#define EL_EMC_WALL_SLIPPERY_3 698
-#define EL_EMC_WALL_SLIPPERY_4 699
-#define EL_EMC_FAKE_GRASS 700
-#define EL_EMC_DRIPPER 701
-
-#define NUM_FILE_ELEMENTS 702
+#define EL_EMC_MAGIC_BALL_ACTIVE 683
+#define EL_EMC_MAGIC_BALL_SWITCH 684
+#define EL_EMC_MAGIC_BALL_SWITCH_ACTIVE 685
+#define EL_EMC_SPRING_BUMPER 686
+#define EL_EMC_PLANT 687
+#define EL_EMC_LENSES 688
+#define EL_EMC_MAGNIFIER 689
+#define EL_EMC_WALL_9 690
+#define EL_EMC_WALL_10 691
+#define EL_EMC_WALL_11 692
+#define EL_EMC_WALL_12 693
+#define EL_EMC_WALL_13 694
+#define EL_EMC_WALL_14 695
+#define EL_EMC_WALL_15 696
+#define EL_EMC_WALL_16 697
+#define EL_EMC_WALL_SLIPPERY_1 698
+#define EL_EMC_WALL_SLIPPERY_2 699
+#define EL_EMC_WALL_SLIPPERY_3 700
+#define EL_EMC_WALL_SLIPPERY_4 701
+#define EL_EMC_FAKE_GRASS 702
+#define EL_EMC_FAKE_ACID 703
+#define EL_EMC_DRIPPER 704
+
+#define NUM_FILE_ELEMENTS 705
/* "real" (and therefore drawable) runtime elements */
#define ACTION_SMASHED_BY_SPRING 48
#define ACTION_SLURPED_BY_SPRING 49
#define ACTION_TWINKLING 50
-#define ACTION_OTHER 51
+#define ACTION_SPLASHING 51
+#define ACTION_OTHER 52
-#define NUM_ACTIONS 52
+#define NUM_ACTIONS 53
#define ACTION_BORING_LAST ACTION_BORING_10
#define ACTION_SLEEPING_LAST ACTION_SLEEPING_3
#define GFX_ARG_2ND_OFFSET 12
#define GFX_ARG_2ND_XOFFSET 13
#define GFX_ARG_2ND_YOFFSET 14
-#define GFX_ARG_FRAMES 15
-#define GFX_ARG_FRAMES_PER_LINE 16
-#define GFX_ARG_START_FRAME 17
-#define GFX_ARG_DELAY 18
-#define GFX_ARG_ANIM_MODE 19
-#define GFX_ARG_GLOBAL_SYNC 20
-#define GFX_ARG_CRUMBLED_LIKE 21
-#define GFX_ARG_DIGGABLE_LIKE 22
-#define GFX_ARG_BORDER_SIZE 23
-#define GFX_ARG_STEP_OFFSET 24
-#define GFX_ARG_STEP_DELAY 25
-#define GFX_ARG_DIRECTION 26
-#define GFX_ARG_POSITION 27
-#define GFX_ARG_DRAW_XOFFSET 28
-#define GFX_ARG_DRAW_YOFFSET 29
-#define GFX_ARG_DRAW_MASKED 30
-#define GFX_ARG_ANIM_DELAY_FIXED 31
-#define GFX_ARG_ANIM_DELAY_RANDOM 32
-#define GFX_ARG_POST_DELAY_FIXED 33
-#define GFX_ARG_POST_DELAY_RANDOM 34
-#define GFX_ARG_NAME 35
-#define GFX_ARG_SCALE_UP_FACTOR 36
-
-#define NUM_GFX_ARGS 37
+#define GFX_ARG_2ND_SWAP_TILES 15
+#define GFX_ARG_FRAMES 16
+#define GFX_ARG_FRAMES_PER_LINE 17
+#define GFX_ARG_START_FRAME 18
+#define GFX_ARG_DELAY 19
+#define GFX_ARG_ANIM_MODE 20
+#define GFX_ARG_GLOBAL_SYNC 21
+#define GFX_ARG_CRUMBLED_LIKE 22
+#define GFX_ARG_DIGGABLE_LIKE 23
+#define GFX_ARG_BORDER_SIZE 24
+#define GFX_ARG_STEP_OFFSET 25
+#define GFX_ARG_STEP_DELAY 26
+#define GFX_ARG_DIRECTION 27
+#define GFX_ARG_POSITION 28
+#define GFX_ARG_DRAW_XOFFSET 29
+#define GFX_ARG_DRAW_YOFFSET 30
+#define GFX_ARG_DRAW_MASKED 31
+#define GFX_ARG_ANIM_DELAY_FIXED 32
+#define GFX_ARG_ANIM_DELAY_RANDOM 33
+#define GFX_ARG_POST_DELAY_FIXED 34
+#define GFX_ARG_POST_DELAY_RANDOM 35
+#define GFX_ARG_NAME 36
+#define GFX_ARG_SCALE_UP_FACTOR 37
+
+#define NUM_GFX_ARGS 38
/* values for sound configuration suffixes */
/* program information and versioning definitions */
+#define RELEASE_311 FALSE
+
+#if RELEASE_311
#define PROGRAM_VERSION_MAJOR 3
#define PROGRAM_VERSION_MINOR 1
-#define PROGRAM_VERSION_PATCH 1
+#define PROGRAM_VERSION_PATCH 2
#define PROGRAM_VERSION_BUILD 0
+#else
+/* !!! make sure that packaging script can find unique version number !!! */
+#define PROGRAM_VERSION_MAJOR 3
+#define PROGRAM_VERSION_MINOR 2
+#define PROGRAM_VERSION_PATCH 0
+#define PROGRAM_VERSION_BUILD 3
+#endif
#define PROGRAM_TITLE_STRING "Rocks'n'Diamonds"
#define PROGRAM_AUTHOR_STRING "Holger Schemel"
-#define PROGRAM_COPYRIGHT_STRING "Copyright ©1995-2004 by Holger Schemel"
+#define PROGRAM_COPYRIGHT_STRING "Copyright ©1995-2005 by Holger Schemel"
#define ICON_TITLE_STRING PROGRAM_TITLE_STRING
#define COOKIE_PREFIX "ROCKSNDIAMONDS"
struct MenuInfo
{
- int draw_xoffset_default;
- int draw_yoffset_default;
int draw_xoffset[NUM_SPECIAL_GFX_ARGS];
int draw_yoffset[NUM_SPECIAL_GFX_ARGS];
int scrollbar_xoffset;
- int list_size_default;
int list_size[NUM_SPECIAL_GFX_ARGS];
int sound[NUM_SPECIAL_GFX_ARGS];
boolean use_murphy_graphic;
boolean block_last_field;
- int block_delay;
+ int block_delay_adjustment; /* needed for different engine versions */
boolean can_fall_into_acid;
int num_special_action_sleeping;
int switch_x, switch_y;
+ int drop_x, drop_y;
int show_envelope;
int sokobanfields_still_needed;
int lights_still_needed;
int friends_still_needed;
- int key[4];
+ int key[MAX_NUM_KEYS];
int dynabomb_count, dynabomb_size, dynabombs_left, dynabomb_xl;
int shield_normal_time_left;
int shield_deadly_time_left;
boolean block_last_field; /* player blocks previous field while moving */
boolean sp_block_last_field; /* player blocks previous field while moving */
+
+#if 0 /* !!! THIS IS NOT A LEVEL SETTING => LOGIC MOVED TO "game.c" !!! */
int block_delay; /* delay for blocking previous field */
int sp_block_delay; /* delay for blocking previous field */
+#endif
/* ('int' instead of 'boolean' because used as selectbox value in editor) */
int use_step_counter; /* count steps instead of seconds for level */
{
byte action[MAX_PLAYERS];
byte delay;
- } pos[MAX_TAPELEN];
+ } pos[MAX_TAPE_LEN];
boolean no_valid_file; /* set when tape file missing or invalid */
};
/* flags to handle bugs in and changes between different engine versions */
/* (for the latest engine version, these flags should always be "FALSE") */
- boolean use_bug_change_when_pushing;
+ boolean use_change_when_pushing_bug;
+ boolean use_block_last_field_bug;
/* variable within running game */
int yamyam_content_nr;
struct GlobalInfo
{
char *autoplay_leveldir;
- int autoplay_level_nr;
+ int autoplay_level[MAX_TAPES_PER_SET];
+ boolean autoplay_all;
char *convert_leveldir;
int convert_level_nr;
{
boolean can_change; /* use or ignore this change info */
+#if 1
+ boolean has_event[NUM_CHANGE_EVENTS]; /* change events */
+#else
unsigned long events; /* change events */
+#endif
int trigger_player; /* player triggering change */
int trigger_side; /* side triggering change */
boolean explode; /* explode instead of 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 ---------- */
/* functions that are called before, while and after the change of an
int explosion_delay; /* duration of explosion of this element */
int ignition_delay; /* delay for explosion by other explosion */
+ int counter_initial; /* initial value of generic CE counter */
+
struct ElementChangeInfo *change_page; /* actual list of change pages */
struct ElementChangeInfo *change; /* pointer to current change page */
/* ---------- internal values used at runtime when playing ---------- */
+#if 1
+ boolean has_change_event[NUM_CHANGE_EVENTS];
+#else
unsigned long change_events; /* bitfield for combined change events */
+#endif
int event_page_nr[NUM_CHANGE_EVENTS]; /* page number for each event */
struct ElementChangeInfo *event_page[NUM_CHANGE_EVENTS]; /* page for event */
boolean can_leave_element_last;
#endif
+ int counter; /* current value of generic CE counter */
+
/* ---------- internal values used in level editor ---------- */
int access_type; /* walkable or passable */
int offset_x, offset_y; /* x/y offset to next animation frame */
int offset2_x, offset2_y; /* x/y offset to second movement tile */
boolean double_movement; /* animation has second movement tile */
+ int swap_double_tiles; /* explicitely force or forbid tile swapping */
int anim_frames;
int anim_frames_per_line;
int anim_start_frame;
extern short Back[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
extern boolean Stop[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
extern boolean Pushed[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
-extern unsigned long Changed[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
-extern unsigned long ChangeEvent[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
+extern boolean Changed[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
+extern short ChangeEvent[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
extern short WasJustMoving[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
extern short WasJustFalling[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
extern short CheckCollision[MAX_LEV_FIELDX][MAX_LEV_FIELDY];