rnd-20051208-1-src
[rocksndiamonds.git] / src / main.h
index 4b22fe907624a0ab574530503fe3d54322b7db36..e80c5c49ae185299f3b5de3207c9573094f3166f 100644 (file)
 #define EP_WALK_TO_OBJECT      81
 #define EP_DEADLY              82
 
-#define NUM_ELEMENT_PROPERTIES 83
+/* values for internal purpose only (game engine) */
+#define EP_HAS_ACTION          83
+#define EP_CAN_CHANGE_OR_HAS_ACTION    84
+
+#define NUM_ELEMENT_PROPERTIES 85
 
 #define NUM_EP_BITFIELDS       ((NUM_ELEMENT_PROPERTIES + 31) / 32)
 #define EP_BITFIELD_BASE       0
 #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_BY_PLAYER_OBSOLETE  16      /* obsolete; now CE_BY_DIRECT_ACTION */
-#define CE_BY_COLLISION_OBSOLETE 17    /* obsolete; now CE_BY_DIRECT_ACTION */
+#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
+#define CE_COUNT_AT_ZERO       16
+#define CE_COUNT_AT_ZERO_OF_X  17
 #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
 
-#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)
-
-#define HAS_CHANGE_EVENT(e,c)  (IS_CUSTOM_ELEMENT(e) &&                  \
-                                (CH_EVENT_VAR(e) & CH_EVENT_BIT(c)) != 0)
-#define HAS_ANY_CHANGE_EVENT(e,c) (IS_CUSTOM_ELEMENT(e) &&               \
-                                (CH_ANY_EVENT_VAR(e) & CH_EVENT_BIT(c)) != 0)
-#define SET_CHANGE_EVENT(e,c,v)        (IS_CUSTOM_ELEMENT(e) ?                   \
-                                ((v) ?                                   \
-                                 (CH_EVENT_VAR(e) |=  CH_EVENT_BIT(c)) : \
-                                 (CH_EVENT_VAR(e) &= ~CH_EVENT_BIT(c))) : 0)
+#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)
+
+/* 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_SET            1
+#define CA_MODE_ADD            2
+#define CA_MODE_SUBTRACT       3
+#define CA_MODE_MULTIPLY       4
+#define CA_MODE_DIVIDE         5
+#define CA_MODE_MODULO         6
+
+/* 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)
                                HAS_PROPERTY(e, EP_CAN_EXPLODE_BY_EXPLOSION)
 #define COULD_MOVE_INTO_ACID(e)        HAS_PROPERTY(e, EP_COULD_MOVE_INTO_ACID)
 #define MAYBE_DONT_COLLIDE_WITH(e) HAS_PROPERTY(e, EP_MAYBE_DONT_COLLIDE_WITH)
+#define HAS_ACTION(e)          HAS_PROPERTY(e, EP_HAS_ACTION)
+#define CAN_CHANGE_OR_HAS_ACTION(e)    \
+                               HAS_PROPERTY(e, EP_CAN_CHANGE_OR_HAS_ACTION)
 
 /* special macros used in game engine */
 #define IS_CUSTOM_ELEMENT(e)   ((e) >= EL_CUSTOM_START &&              \
 #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 PLAYERINFO(x,y)                (&stored_player[StorePlayer[x][y]-EL_PLAYER_1])
 #define SHIELD_ON(p)           ((p)->shield_normal_time_left > 0)
 
-#if 1
-
 #define ENEMY_PROTECTED_FIELD(x,y)     (IS_PROTECTED(Feld[x][y]) ||       \
                                         IS_PROTECTED(Back[x][y]))
 #define EXPLOSION_PROTECTED_FIELD(x,y)  (IS_EXPLOSION_PROOF(Feld[x][y]))
 #define PLAYER_EXPLOSION_PROTECTED(x,y) (SHIELD_ON(PLAYERINFO(x, y)) ||           \
                                         EXPLOSION_PROTECTED_FIELD(x, y))
 
-#else
-
-#define PROTECTED_FIELD(x,y)   (IS_ACCESSIBLE_INSIDE(Feld[x][y]) &&    \
-                                IS_INDESTRUCTIBLE(Feld[x][y]))
-#define PLAYER_ENEMY_PROTECTED(x,y)    (SHIELD_ON(PLAYERINFO(x, y)) || \
-                                PROTECTED_FIELD(x, y))
-#define PLAYER_EXPLOSION_PROTECTED(x,y)        (SHIELD_ON(PLAYERINFO(x, y)) || \
-                                PROTECTED_FIELD(x, y))
-#endif
-
 #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];
@@ -1456,7 +1578,7 @@ struct PlayerInfo
   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;
 
@@ -1491,26 +1613,16 @@ struct PlayerInfo
   int num_special_action_sleeping;
 
   int switch_x, switch_y;
+  int drop_x, drop_y;
 
   int show_envelope;
 
-#if 1  /* USE_NEW_MOVE_DELAY */
   int move_delay;
   int move_delay_value;
-#else
-  unsigned long move_delay;
-  int move_delay_value;
-#endif
-
   int move_delay_reset_counter;
 
-#if 1  /* USE_NEW_PUSH_DELAY */
   int push_delay;
   int push_delay_value;
-#else
-  unsigned long push_delay;
-  unsigned long push_delay_value;
-#endif
 
   unsigned long actual_frame_counter;
 
@@ -1523,7 +1635,7 @@ struct PlayerInfo
   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;
@@ -1615,8 +1727,6 @@ struct LevelInfo
 
   boolean block_last_field;    /* player blocks previous field while moving */
   boolean sp_block_last_field; /* player blocks previous field while moving */
-  int block_delay;             /* delay for blocking previous field */
-  int sp_block_delay;          /* delay for blocking previous field */
 
   /* ('int' instead of 'boolean' because used as selectbox value in editor) */
   int use_step_counter;                /* count steps instead of seconds for level */
@@ -1661,7 +1771,7 @@ struct TapeInfo
   {
     byte action[MAX_PLAYERS];
     byte delay;
-  } pos[MAX_TAPELEN];
+  } pos[MAX_TAPE_LEN];
 
   boolean no_valid_file;       /* set when tape file missing or invalid */
 };
@@ -1681,7 +1791,8 @@ struct GameInfo
 
   /* 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;
@@ -1702,12 +1813,16 @@ struct GameInfo
   int player_boring_delay_random;
   int player_sleeping_delay_fixed;
   int player_sleeping_delay_random;
+
+  /* values for special game initialization control */
+  boolean restart_level;
 };
 
 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;
@@ -1723,7 +1838,7 @@ struct ElementChangeInfo
 {
   boolean can_change;          /* use or ignore this change info */
 
-  unsigned long events;                /* change events */
+  boolean has_event[NUM_CHANGE_EVENTS];                /* change events */
 
   int trigger_player;          /* player triggering change */
   int trigger_side;            /* side triggering change */
@@ -1746,6 +1861,11 @@ struct ElementChangeInfo
 
   boolean explode;             /* explode instead of change */
 
+  boolean has_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
@@ -1757,6 +1877,8 @@ struct ElementChangeInfo
   short actual_trigger_element;        /* element that actually triggered change */
   int actual_trigger_player;   /* player which actually triggered change */
 
+  boolean can_change_or_has_action;    /* can_change | has_action */
+
   /* ---------- internal values used in level editor ---------- */
 
   int direct_action;           /* change triggered by actions on element */
@@ -1821,8 +1943,8 @@ struct ElementInfo
 
   int access_direction;                /* accessible from which direction */
 
-  int collect_score;           /* score value for collecting */
-  int collect_count;           /* count value for collecting */
+  int collect_score_initial;   /* initial score value for collecting */
+  int collect_count_initial;   /* initial count value for collecting */
 
   int push_delay_fixed;                /* constant delay before pushing */
   int push_delay_random;       /* additional random delay before pushing */
@@ -1857,17 +1979,14 @@ struct ElementInfo
 
   /* ---------- internal values used at runtime when playing ---------- */
 
-  unsigned long change_events; /* bitfield for combined change events */
+  boolean has_change_event[NUM_CHANGE_EVENTS];
 
   int event_page_nr[NUM_CHANGE_EVENTS]; /* page number for each event */
   struct ElementChangeInfo *event_page[NUM_CHANGE_EVENTS]; /* page for event */
 
   boolean in_group[NUM_GROUP_ELEMENTS];
 
-#if 0
-  boolean can_leave_element;   /* element can leave other element behind */
-  boolean can_leave_element_last;
-#endif
+  int collect_score;           /* runtime score value for collecting */
 
   /* ---------- internal values used in level editor ---------- */
 
@@ -1904,6 +2023,7 @@ struct GraphicInfo
   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;
@@ -2001,10 +2121,6 @@ struct HelpAnimInfo
 };
 
 
-#if 0
-extern GC                      tile_clip_gc;
-extern Bitmap                 *pix[];
-#endif
 extern Bitmap                 *bitmap_db_field, *bitmap_db_door;
 extern Pixmap                  tile_clipmask[];
 extern DrawBuffer            *fieldbuffer;
@@ -2030,14 +2146,15 @@ extern short                    MovDir[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
 extern short                   MovDelay[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
 extern short                   ChangeDelay[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
 extern short                   ChangePage[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
+extern short                   Count[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
 extern short                   Store[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
 extern short                   Store2[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
 extern short                   StorePlayer[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
 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];