rnd-20030703-1-src
[rocksndiamonds.git] / src / main.h
index c5a79500ed547e960ab515958be62c0ebd18070a..7e70d87fc4a15a1d79fcb368a03d85b7a2027ebc 100644 (file)
@@ -33,6 +33,7 @@
 #define IMG_UNDEFINED          (-1)
 #define IMG_EMPTY              IMG_EMPTY_SPACE
 #define IMG_SP_EMPTY           IMG_SP_EMPTY_SPACE
+#define IMG_EXPLOSION          IMG_DEFAULT_EXPLODING
 #define IMG_CHAR_START         IMG_CHAR_SPACE
 #define IMG_CUSTOM_START       IMG_CUSTOM_1
 
 #define IN_SCR_FIELD(x,y) ((x)>=BX1 && (x)<=BX2 && (y)>=BY1 &&(y)<=BY2)
 #define IN_LEV_FIELD(x,y) ((x)>=0 && (x)<lev_fieldx && (y)>=0 &&(y)<lev_fieldy)
 
-/* values for base properties (storable) */
-#define EP_AMOEBALIVE          0
-#define EP_AMOEBOID            1
-#define EP_CAN_BE_CRUMBLED     2
-#define EP_KEYGATE             3
-#define EP_HISTORIC_SOLID      4
+/* values for configurable properties (custom elem's only, else pre-defined) */
+#define EP_DIGGABLE            0
+#define EP_COLLECTIBLE         1
+#define EP_DONT_RUN_INTO       2
+#define EP_DONT_COLLIDE_WITH   3
+#define EP_DONT_TOUCH          4
 #define EP_INDESTRUCTIBLE      5
 #define EP_SLIPPERY            6
-#define EP_ENEMY               7
-#define EP_HISTORIC_WALL       8
+#define EP_CAN_CHANGE          7
+#define EP_CAN_MOVE            8
 #define EP_CAN_FALL            9
-#define EP_CAN_SMASH           10
-#define EP_CAN_CHANGE          11
-#define EP_CAN_MOVE            12
-#define EP_COULD_MOVE          13
-#define EP_DONT_TOUCH          14
-#define EP_DONT_GO_TO          15
-#define EP_FOOD_DARK_YAMYAM    16
-#define EP_EM_SLIPPERY_WALL    17
-#define EP_BD_ELEMENT          18
-#define EP_SB_ELEMENT          19
-#define EP_GEM                 20
-#define EP_INACTIVE            21
-#define EP_EXPLOSIVE           22
-#define EP_FOOD_PENGUIN                23
+#define EP_CAN_SMASH_PLAYER    10
+#define EP_CAN_SMASH_ENEMIES   11
+#define EP_CAN_SMASH_EVERYTHING        12
+#define EP_CAN_EXPLODE_BY_FIRE 13
+#define EP_CAN_EXPLODE_SMASHED 14
+#define EP_CAN_EXPLODE_IMPACT  15
+#define EP_WALKABLE_OVER       16
+#define EP_WALKABLE_INSIDE     17
+#define EP_WALKABLE_UNDER      18
+#define EP_PASSABLE_OVER       19
+#define EP_PASSABLE_INSIDE     20
+#define EP_PASSABLE_UNDER      21
+#define EP_UNUSED_22           22
+#define EP_UNUSED_23           23
 #define EP_PUSHABLE            24
-#define EP_PLAYER              25
-#define EP_WALKABLE_OVER       26
-#define EP_WALKABLE_INSIDE     27
-#define EP_WALKABLE_UNDER      28
-#define EP_PASSABLE_OVER       29
-#define EP_PASSABLE_INSIDE     30
-#define EP_PASSABLE_UNDER      31
-
-/* values for runtime properties (non-storable) */
-#define EP_ACCESSIBLE_OVER     32
-#define EP_ACCESSIBLE_INSIDE   33
-#define EP_ACCESSIBLE_UNDER    34
-#define EP_WALKABLE            35
-#define EP_PASSABLE            36
-#define EP_ACCESSIBLE          37
-#define EP_DIGGABLE            38
-#define EP_COLLECTIBLE         39
-#define EP_ACTIVE_BOMB         40
-#define EP_BELT                        41
-#define EP_BELT_ACTIVE         42
-#define EP_BELT_SWITCH         43
-#define EP_SP_ELEMENT          44
-#define EP_HAS_CONTENT         45
-#define EP_TUBE                        46
-#define EP_WALL                        47
-#define EP_SOLID               48
-#define EP_DRAGONFIRE_PROOF    49
-#define EP_EXPLOSION_PROOF     50
-
-#define NUM_ELEMENT_PROPERTIES 51
+
+/* values for special configurable properties (depending on level settings) */
+#define EP_EM_SLIPPERY_WALL    32
+
+/* values for special graphics properties (no effect on game engine) */
+#define EP_CAN_BE_CRUMBLED     33
+
+/* values for pre-defined properties */
+#define EP_PLAYER              34
+#define EP_CAN_PASS_MAGIC_WALL 35
+#define EP_SWITCHABLE          36
+#define EP_BD_ELEMENT          37
+#define EP_SP_ELEMENT          38
+#define EP_SB_ELEMENT          39
+#define EP_GEM                 40
+#define EP_FOOD_DARK_YAMYAM    41
+#define EP_FOOD_PENGUIN                42
+#define EP_FOOD_PIG            43
+#define EP_HISTORIC_WALL       44
+#define EP_HISTORIC_SOLID      45
+#define EP_CLASSIC_ENEMY       46
+#define EP_BELT                        47
+#define EP_BELT_ACTIVE         48
+#define EP_BELT_SWITCH         49
+#define EP_TUBE                        50
+#define EP_KEYGATE             51
+#define EP_AMOEBOID            52
+#define EP_AMOEBALIVE          53
+#define EP_HAS_CONTENT         54
+#define EP_ACTIVE_BOMB         55
+#define EP_INACTIVE            56
+
+/* values for derived properties (determined from properties above) */
+#define EP_ACCESSIBLE_OVER     57
+#define EP_ACCESSIBLE_INSIDE   58
+#define EP_ACCESSIBLE_UNDER    59
+#define EP_WALKABLE            60
+#define EP_PASSABLE            61
+#define EP_ACCESSIBLE          62
+#define EP_SNAPPABLE           63
+#define EP_WALL                        64
+#define EP_SOLID_FOR_PUSHING   65
+#define EP_DRAGONFIRE_PROOF    66
+#define EP_EXPLOSION_PROOF     67
+#define EP_CAN_SMASH           68
+#define EP_CAN_EXPLODE         69
+
+/* values for internal purpose only (level editor) */
+#define EP_EXPLODE_RESULT      70
+#define EP_WALK_TO_OBJECT      71
+#define EP_DEADLY              72
+
+#define NUM_ELEMENT_PROPERTIES 73
 
 #define NUM_EP_BITFIELDS       ((NUM_ELEMENT_PROPERTIES + 31) / 32)
 #define EP_BITFIELD_BASE       0
 #define EP_BITMASK_DEFAULT     0
 
 #define PROPERTY_BIT(p)                (1 << ((p) % 32))
-#define PROPERTY_VAR(e, p)     (Properties[e][(p) / 32])
-#define HAS_PROPERTY(e, p)     ((PROPERTY_VAR(e, p) & PROPERTY_BIT(p)) != 0)
-#define SET_PROPERTY(e, p, v)  ((v) ?                                     \
+#define PROPERTY_VAR(e,p)      (Properties[e][(p) / 32])
+#define HAS_PROPERTY(e,p)      ((PROPERTY_VAR(e, p) & PROPERTY_BIT(p)) != 0)
+#define SET_PROPERTY(e,p,v)    ((v) ?                                     \
                                 (PROPERTY_VAR(e,p) |=  PROPERTY_BIT(p)) : \
                                 (PROPERTY_VAR(e,p) &= ~PROPERTY_BIT(p)))
 
-/* macros for base properties */
-#define IS_AMOEBALIVE(e)       HAS_PROPERTY(e, EP_AMOEBALIVE)
-#define IS_AMOEBOID(e)         HAS_PROPERTY(e, EP_AMOEBOID)
-#define CAN_BE_CRUMBLED(e)     HAS_PROPERTY(e, EP_CAN_BE_CRUMBLED)
-#define IS_KEYGATE(e)          HAS_PROPERTY(e, EP_KEYGATE)
-#define IS_HISTORIC_SOLID(e)   HAS_PROPERTY(e, EP_HISTORIC_SOLID)
+
+/* values for change events for custom elements */
+#define CE_DELAY               0
+#define CE_TOUCHED_BY_PLAYER   1
+#define CE_PRESSED_BY_PLAYER   2
+#define CE_PUSHED_BY_PLAYER    3
+#define CE_COLLISION           4
+#define CE_IMPACT              5
+#define CE_SMASHED             6
+#define CE_OTHER_IS_TOUCHING   7
+#define CE_OTHER_IS_CHANGING   8
+#define CE_OTHER_IS_EXPLODING  9
+#define CE_OTHER_GETS_TOUCHED  10
+#define CE_OTHER_GETS_PRESSED  11
+#define CE_OTHER_GETS_PUSHED   12
+#define CE_OTHER_GETS_COLLECTED        13
+
+/* values for internal purpose only (level editor) */
+#define CE_BY_PLAYER           14
+#define CE_BY_COLLISION                15
+#define CE_BY_OTHER            16
+
+#define NUM_CHANGE_EVENTS      17
+
+#define CE_BITMASK_DEFAULT     0
+
+#define CH_EVENT_BIT(c)                (1 << (c))
+#define CH_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 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)
+
+/* values for change power for custom elements */
+#define CP_NON_DESTRUCTIVE     0
+#define CP_HALF_DESTRUCTIVE    1
+#define CP_FULL_DESTRUCTIVE    2
+
+
+/* macros for configurable properties */
+#define IS_DIGGABLE(e)         HAS_PROPERTY(e, EP_DIGGABLE)
+#define IS_COLLECTIBLE(e)      HAS_PROPERTY(e, EP_COLLECTIBLE)
+#define DONT_RUN_INTO(e)       HAS_PROPERTY(e, EP_DONT_RUN_INTO)
+#define DONT_COLLIDE_WITH(e)   HAS_PROPERTY(e, EP_DONT_COLLIDE_WITH)
+#define DONT_TOUCH(e)          HAS_PROPERTY(e, EP_DONT_TOUCH)
 #define IS_INDESTRUCTIBLE(e)   HAS_PROPERTY(e, EP_INDESTRUCTIBLE)
 #define IS_SLIPPERY(e)         HAS_PROPERTY(e, EP_SLIPPERY)
-#define IS_ENEMY(e)            HAS_PROPERTY(e, EP_ENEMY)
-#define IS_HISTORIC_WALL(e)    HAS_PROPERTY(e, EP_HISTORIC_WALL)
-#define CAN_FALL(e)            HAS_PROPERTY(e, EP_CAN_FALL)
-#define CAN_SMASH(e)           HAS_PROPERTY(e, EP_CAN_SMASH)
 #define CAN_CHANGE(e)          HAS_PROPERTY(e, EP_CAN_CHANGE)
 #define CAN_MOVE(e)            HAS_PROPERTY(e, EP_CAN_MOVE)
-#define COULD_MOVE(e)          HAS_PROPERTY(e, EP_COULD_MOVE)
-#define DONT_TOUCH(e)          HAS_PROPERTY(e, EP_DONT_TOUCH)
-#define DONT_GO_TO(e)          HAS_PROPERTY(e, EP_DONT_GO_TO)
-#define IS_FOOD_DARK_YAMYAM(e) HAS_PROPERTY(e, EP_FOOD_DARK_YAMYAM)
-#define IS_EM_SLIPPERY_WALL(e) HAS_PROPERTY(e, EP_EM_SLIPPERY_WALL)
-#define IS_BD_ELEMENT(e)       HAS_PROPERTY(e, EP_BD_ELEMENT)
-#define IS_SB_ELEMENT(e)       HAS_PROPERTY(e, EP_SB_ELEMENT)
-#define IS_GEM(e)              HAS_PROPERTY(e, EP_GEM)
-#define IS_INACTIVE(e)         HAS_PROPERTY(e, EP_INACTIVE)
-#define IS_EXPLOSIVE(e)                HAS_PROPERTY(e, EP_EXPLOSIVE)
-#define IS_FOOD_PENGUIN(e)     HAS_PROPERTY(e, EP_FOOD_PENGUIN)
-#define IS_PUSHABLE(e)         HAS_PROPERTY(e, EP_PUSHABLE)
-#define ELEM_IS_PLAYER(e)      HAS_PROPERTY(e, EP_PLAYER)
+#define CAN_FALL(e)            HAS_PROPERTY(e, EP_CAN_FALL)
+#define CAN_SMASH_PLAYER(e)    HAS_PROPERTY(e, EP_CAN_SMASH_PLAYER)
+#define CAN_SMASH_ENEMIES(e)   HAS_PROPERTY(e, EP_CAN_SMASH_ENEMIES)
+#define CAN_SMASH_EVERYTHING(e)        HAS_PROPERTY(e, EP_CAN_SMASH_EVERYTHING)
+#define CAN_EXPLODE_BY_FIRE(e) HAS_PROPERTY(e, EP_CAN_EXPLODE_BY_FIRE)
+#define CAN_EXPLODE_SMASHED(e) HAS_PROPERTY(e, EP_CAN_EXPLODE_SMASHED)
+#define CAN_EXPLODE_IMPACT(e)  HAS_PROPERTY(e, EP_CAN_EXPLODE_IMPACT)
 #define IS_WALKABLE_OVER(e)    HAS_PROPERTY(e, EP_WALKABLE_OVER)
 #define IS_WALKABLE_INSIDE(e)  HAS_PROPERTY(e, EP_WALKABLE_INSIDE)
 #define IS_WALKABLE_UNDER(e)   HAS_PROPERTY(e, EP_WALKABLE_UNDER)
 #define IS_PASSABLE_OVER(e)    HAS_PROPERTY(e, EP_PASSABLE_OVER)
 #define IS_PASSABLE_INSIDE(e)  HAS_PROPERTY(e, EP_PASSABLE_INSIDE)
 #define IS_PASSABLE_UNDER(e)   HAS_PROPERTY(e, EP_PASSABLE_UNDER)
+#define IS_PUSHABLE(e)         HAS_PROPERTY(e, EP_PUSHABLE)
 
-/* macros for runtime properties */
+/* macros for special configurable properties */
+#define IS_EM_SLIPPERY_WALL(e) HAS_PROPERTY(e, EP_EM_SLIPPERY_WALL)
+
+/* macros for special graphics properties */
+#define CAN_BE_CRUMBLED(e)     HAS_PROPERTY(GFX_ELEMENT(e),EP_CAN_BE_CRUMBLED)
+
+/* macros for pre-defined properties */
+#define ELEM_IS_PLAYER(e)      HAS_PROPERTY(e, EP_PLAYER)
+#define CAN_PASS_MAGIC_WALL(e) HAS_PROPERTY(e, EP_CAN_PASS_MAGIC_WALL)
+#define IS_SWITCHABLE(e)       HAS_PROPERTY(e, EP_SWITCHABLE)
+#define IS_BD_ELEMENT(e)       HAS_PROPERTY(e, EP_BD_ELEMENT)
+#define IS_SP_ELEMENT(e)       HAS_PROPERTY(e, EP_SP_ELEMENT)
+#define IS_SB_ELEMENT(e)       HAS_PROPERTY(e, EP_SB_ELEMENT)
+#define IS_GEM(e)              HAS_PROPERTY(e, EP_GEM)
+#define IS_FOOD_DARK_YAMYAM(e) HAS_PROPERTY(e, EP_FOOD_DARK_YAMYAM)
+#define IS_FOOD_PENGUIN(e)     HAS_PROPERTY(e, EP_FOOD_PENGUIN)
+#define IS_FOOD_PIG(e)         HAS_PROPERTY(e, EP_FOOD_PIG)
+#define IS_HISTORIC_WALL(e)    HAS_PROPERTY(e, EP_HISTORIC_WALL)
+#define IS_HISTORIC_SOLID(e)   HAS_PROPERTY(e, EP_HISTORIC_SOLID)
+#define IS_CLASSIC_ENEMY(e)    HAS_PROPERTY(e, EP_CLASSIC_ENEMY)
+#define IS_BELT(e)             HAS_PROPERTY(e, EP_BELT)
+#define IS_BELT_ACTIVE(e)      HAS_PROPERTY(e, EP_BELT_ACTIVE)
+#define IS_BELT_SWITCH(e)      HAS_PROPERTY(e, EP_BELT_SWITCH)
+#define IS_TUBE(e)             HAS_PROPERTY(e, EP_TUBE)
+#define IS_KEYGATE(e)          HAS_PROPERTY(e, EP_KEYGATE)
+#define IS_AMOEBOID(e)         HAS_PROPERTY(e, EP_AMOEBOID)
+#define IS_AMOEBALIVE(e)       HAS_PROPERTY(e, EP_AMOEBALIVE)
+#define HAS_CONTENT(e)         HAS_PROPERTY(e, EP_HAS_CONTENT)
+#define IS_ACTIVE_BOMB(e)      HAS_PROPERTY(e, EP_ACTIVE_BOMB)
+#define IS_INACTIVE(e)         HAS_PROPERTY(e, EP_INACTIVE)
+
+/* macros for derived properties */
 #define IS_ACCESSIBLE_OVER(e)  HAS_PROPERTY(e, EP_ACCESSIBLE_OVER)
 #define IS_ACCESSIBLE_INSIDE(e)        HAS_PROPERTY(e, EP_ACCESSIBLE_INSIDE)
 #define IS_ACCESSIBLE_UNDER(e) HAS_PROPERTY(e, EP_ACCESSIBLE_UNDER)
+#define IS_SNAPPABLE(e)                HAS_PROPERTY(e, EP_SNAPPABLE)
 #define IS_WALKABLE(e)         HAS_PROPERTY(e, EP_WALKABLE)
 #define IS_PASSABLE(e)         HAS_PROPERTY(e, EP_PASSABLE)
 #define IS_ACCESSIBLE(e)       HAS_PROPERTY(e, EP_ACCESSIBLE)
-#define IS_DIGGABLE(e)         HAS_PROPERTY(e, EP_DIGGABLE)
-#define IS_COLLECTIBLE(e)      HAS_PROPERTY(e, EP_COLLECTIBLE)
-#define IS_ACTIVE_BOMB(e)      HAS_PROPERTY(e, EP_ACTIVE_BOMB)
-#define IS_BELT(e)             HAS_PROPERTY(e, EP_BELT)
-#define IS_BELT_ACTIVE(e)      HAS_PROPERTY(e, EP_BELT_ACTIVE)
-#define IS_BELT_SWITCH(e)      HAS_PROPERTY(e, EP_BELT_SWITCH)
-#define IS_SP_ELEMENT(e)       HAS_PROPERTY(e, EP_SP_ELEMENT)
-#define HAS_CONTENT(e)         HAS_PROPERTY(e, EP_HAS_CONTENT)
-#define IS_TUBE(e)             HAS_PROPERTY(e, EP_TUBE)
 #define IS_WALL(e)             HAS_PROPERTY(e, EP_WALL)
-#define IS_SOLID(e)            HAS_PROPERTY(e, EP_SOLID)
+#define IS_SOLID_FOR_PUSHING(e)        HAS_PROPERTY(e, EP_SOLID_FOR_PUSHING)
 #define IS_DRAGONFIRE_PROOF(e) HAS_PROPERTY(e, EP_DRAGONFIRE_PROOF)
 #define IS_EXPLOSION_PROOF(e)  HAS_PROPERTY(e, EP_EXPLOSION_PROOF)
+#define CAN_SMASH(e)           HAS_PROPERTY(e, EP_CAN_SMASH)
+#define CAN_EXPLODE(e)         HAS_PROPERTY(e, EP_CAN_EXPLODE)
 
-#define IS_CUSTOM_ELEMENT(e)   ((e) >= EL_CUSTOM_START &&      \
+/* special macros used in game engine */
+#define IS_CUSTOM_ELEMENT(e)   ((e) >= EL_CUSTOM_START &&              \
                                 (e) <= EL_CUSTOM_END)
 
+#define GFX_ELEMENT(e)         (element_info[e].use_gfx_element ?      \
+                                element_info[e].gfx_element : e)
+
 #define IS_PLAYER(x,y)         (ELEM_IS_PLAYER(StorePlayer[x][y]))
 
 #define IS_FREE(x,y)           (Feld[x][y] == EL_EMPTY && !IS_PLAYER(x,y))
 #define IS_LOOP_SOUND(s)       (sound_info[s].loop)
 
 
-#if 0
-
-/* Bitmaps with graphic file */
-#define PIX_BACK               0
-#define PIX_DOOR               1
-#define PIX_TOONS              2
-#define PIX_FONT_BIG           3
-#define PIX_FONT_SMALL         4
-#define PIX_FONT_MEDIUM                5
-#define PIX_FONT_EM            6
-/* Bitmaps without graphic file */
-#define PIX_DB_DOOR            7
-#define PIX_DB_FIELD           8
-
-#define NUM_PICTURES           7
-#define NUM_BITMAPS            9
-
-#else
-
-/* Bitmaps with graphic file */
-#define PIX_BACK               0
-#define PIX_ELEMENTS           1
-#define PIX_DOOR               2
-#define PIX_HEROES             3
-#define PIX_TOONS              4
-#define PIX_SP                 5
-#define PIX_DC                 6
-#define PIX_MORE               7
-#define PIX_FONT_BIG           8
-#define PIX_FONT_SMALL         9
-#define PIX_FONT_MEDIUM                10
-#define PIX_FONT_EM            11
-/* Bitmaps without graphic file */
-#define PIX_DB_DOOR            12
-#define PIX_DB_FIELD           13
-
-#define NUM_PICTURES           12
-#define NUM_BITMAPS            14
-
-#endif
-
 /* boundaries of arrays etc. */
 #define MAX_LEVEL_NAME_LEN     32
 #define MAX_LEVEL_AUTHOR_LEN   32
 #define MAX_TAPELEN            (1000 * 50)     /* max. time * framerate */
 #define MAX_SCORE_ENTRIES      100
-#if 0
-#define MAX_ELEMENTS           700             /* 500 static + 200 runtime */
-#define MAX_GRAPHICS           1536            /* see below: NUM_TILES */
-#endif
 #define MAX_NUM_AMOEBA         100
 
 /* values for elements with content */
 #define EL_BLOCKED                     (EL_FIRST_RUNTIME_UNREAL + 0)
 #define EL_EXPLOSION                   (EL_FIRST_RUNTIME_UNREAL + 1)
 #define EL_NUT_BREAKING                        (EL_FIRST_RUNTIME_UNREAL + 2)
-#define EL_ACID_SPLASH_LEFT            (EL_FIRST_RUNTIME_UNREAL + 3)
-#define EL_ACID_SPLASH_RIGHT           (EL_FIRST_RUNTIME_UNREAL + 4)
-#define EL_AMOEBA_GROWING              (EL_FIRST_RUNTIME_UNREAL + 5)
-#define EL_AMOEBA_SHRINKING            (EL_FIRST_RUNTIME_UNREAL + 6)
-#define EL_EXPANDABLE_WALL_GROWING     (EL_FIRST_RUNTIME_UNREAL + 7)
-#define EL_FLAMES                      (EL_FIRST_RUNTIME_UNREAL + 8)
-#define EL_PLAYER_IS_LEAVING           (EL_FIRST_RUNTIME_UNREAL + 9)
-#define EL_QUICKSAND_FILLING           (EL_FIRST_RUNTIME_UNREAL + 10)
-#define EL_MAGIC_WALL_FILLING          (EL_FIRST_RUNTIME_UNREAL + 11)
-#define EL_BD_MAGIC_WALL_FILLING       (EL_FIRST_RUNTIME_UNREAL + 12)
+#define EL_DIAMOND_BREAKING            (EL_FIRST_RUNTIME_UNREAL + 3)
+#define EL_ACID_SPLASH_LEFT            (EL_FIRST_RUNTIME_UNREAL + 4)
+#define EL_ACID_SPLASH_RIGHT           (EL_FIRST_RUNTIME_UNREAL + 5)
+#define EL_AMOEBA_GROWING              (EL_FIRST_RUNTIME_UNREAL + 6)
+#define EL_AMOEBA_SHRINKING            (EL_FIRST_RUNTIME_UNREAL + 7)
+#define EL_EXPANDABLE_WALL_GROWING     (EL_FIRST_RUNTIME_UNREAL + 8)
+#define EL_FLAMES                      (EL_FIRST_RUNTIME_UNREAL + 9)
+#define EL_PLAYER_IS_LEAVING           (EL_FIRST_RUNTIME_UNREAL + 10)
+#define EL_QUICKSAND_FILLING           (EL_FIRST_RUNTIME_UNREAL + 11)
+#define EL_MAGIC_WALL_FILLING          (EL_FIRST_RUNTIME_UNREAL + 12)
+#define EL_BD_MAGIC_WALL_FILLING       (EL_FIRST_RUNTIME_UNREAL + 13)
 
 /* dummy elements (never used as game elements, only used as graphics) */
-#define EL_FIRST_DUMMY                 (EL_FIRST_RUNTIME_UNREAL + 13)
+#define EL_FIRST_DUMMY                 (EL_FIRST_RUNTIME_UNREAL + 14)
 
 #define EL_STEELWALL_TOPLEFT                   (EL_FIRST_DUMMY + 0)
 #define EL_STEELWALL_TOPRIGHT                  (EL_FIRST_DUMMY + 1)
 #define EL_DYNABOMB_ACTIVE                     (EL_FIRST_DUMMY + 13)
 #define EL_SHIELD_NORMAL_ACTIVE                        (EL_FIRST_DUMMY + 14)
 #define EL_SHIELD_DEADLY_ACTIVE                        (EL_FIRST_DUMMY + 15)
+#define EL_DEFAULT                             (EL_FIRST_DUMMY + 16)
+#define EL_BD_DEFAULT                          (EL_FIRST_DUMMY + 17)
+#define EL_SP_DEFAULT                          (EL_FIRST_DUMMY + 18)
+#define EL_SB_DEFAULT                          (EL_FIRST_DUMMY + 19)
 
-#define MAX_NUM_ELEMENTS                       (EL_FIRST_DUMMY + 16)
+#define MAX_NUM_ELEMENTS                       (EL_FIRST_DUMMY + 20)
 
 
 /* values for graphics/sounds action types */
 #define ACTION_COLLECTING                      6
 #define ACTION_DROPPING                                7
 #define ACTION_PUSHING                         8
-#define ACTION_PASSING                         9
-#define ACTION_IMPACT                          10
-#define ACTION_BREAKING                                11
-#define ACTION_ACTIVATING                      12
-#define ACTION_DEACTIVATING                    13
-#define ACTION_OPENING                         14
-#define ACTION_CLOSING                         15
-#define ACTION_ATTACKING                       16
-#define ACTION_GROWING                         17
-#define ACTION_SHRINKING                       18
-#define ACTION_ACTIVE                          19
-#define ACTION_FILLING                         20
-#define ACTION_EMPTYING                                21
-#define ACTION_CHANGING                                22
-#define ACTION_EXPLODING                       23
-#define ACTION_DYING                           24
-#define ACTION_OTHER                           25
-
-#define NUM_ACTIONS                            26
-
-/* values for special image configuration suffixes */
+#define ACTION_WALKING                         9
+#define ACTION_PASSING                         10
+#define ACTION_IMPACT                          11
+#define ACTION_BREAKING                                12
+#define ACTION_ACTIVATING                      13
+#define ACTION_DEACTIVATING                    14
+#define ACTION_OPENING                         15
+#define ACTION_CLOSING                         16
+#define ACTION_ATTACKING                       17
+#define ACTION_GROWING                         18
+#define ACTION_SHRINKING                       19
+#define ACTION_ACTIVE                          20
+#define ACTION_FILLING                         21
+#define ACTION_EMPTYING                                22
+#define ACTION_CHANGING                                23
+#define ACTION_EXPLODING                       24
+#define ACTION_DYING                           25
+#define ACTION_OTHER                           26
+
+#define NUM_ACTIONS                            27
+
+/* values for special image configuration suffixes (must match game mode) */
 #define GFX_SPECIAL_ARG_MAIN                   0
 #define GFX_SPECIAL_ARG_LEVELS                 1
 #define GFX_SPECIAL_ARG_SCORES                 2
 #define FONT_TITLE_2                           5
 #define FONT_MENU_1                            6
 #define FONT_MENU_2                            7
-#define FONT_TEXT_1                            8
-#define FONT_TEXT_2                            9
-#define FONT_TEXT_3                            10
-#define FONT_TEXT_4                            11
-#define FONT_INPUT_1_ACTIVE                    12
-#define FONT_INPUT_1                           13
-#define FONT_INPUT_2_ACTIVE                    14
-#define FONT_INPUT_2                           15
-#define FONT_OPTION_OFF                                16
-#define FONT_OPTION_ON                         17
-#define FONT_VALUE_1                           18
-#define FONT_VALUE_2                           19
-#define FONT_VALUE_OLD                         20
-#define FONT_LEVEL_NUMBER                      21
-#define FONT_TAPE_RECORDER                     22
-#define FONT_GAME_INFO                         23
-
-#define NUM_FONTS                              24
+#define FONT_TEXT_1_ACTIVE                     8
+#define FONT_TEXT_2_ACTIVE                     9
+#define FONT_TEXT_3_ACTIVE                     10
+#define FONT_TEXT_4_ACTIVE                     11
+#define FONT_TEXT_1                            12
+#define FONT_TEXT_2                            13
+#define FONT_TEXT_3                            14
+#define FONT_TEXT_4                            15
+#define FONT_INPUT_1_ACTIVE                    16
+#define FONT_INPUT_2_ACTIVE                    17
+#define FONT_INPUT_1                           18
+#define FONT_INPUT_2                           19
+#define FONT_OPTION_OFF                                20
+#define FONT_OPTION_ON                         21
+#define FONT_VALUE_1                           22
+#define FONT_VALUE_2                           23
+#define FONT_VALUE_OLD                         24
+#define FONT_LEVEL_NUMBER                      25
+#define FONT_TAPE_RECORDER                     26
+#define FONT_GAME_INFO                         27
+
+#define NUM_FONTS                              28
 #define NUM_INITIAL_FONTS                      4
 
-/* values for game_status */
-#define EXITGAME               0
-#define MAINMENU               1
-#define PLAYING                        2
-#define LEVELED                        3
-#define HELPSCREEN             4
-#define CHOOSELEVEL            5
-#define TYPENAME               6
-#define HALLOFFAME             7
-#define SETUP                  8
-#define PSEUDO_PREVIEW         9
-#define PSEUDO_DOOR            10
+/* values for game_status (must match special image configuration suffixes) */
+#define GAME_MODE_MAIN                         0
+#define GAME_MODE_LEVELS                       1
+#define GAME_MODE_SCORES                       2
+#define GAME_MODE_EDITOR                       3
+#define GAME_MODE_INFO                         4
+#define GAME_MODE_SETUP                                5
+#define GAME_MODE_PSEUDO_DOOR                  6
+#define GAME_MODE_PSEUDO_PREVIEW               7
+
+/* there are no special config file suffixes for these modes */
+#define GAME_MODE_PLAYING                      8
+#define GAME_MODE_PSEUDO_TYPENAME              9
+#define GAME_MODE_QUIT                         10
 
 #define PROGRAM_VERSION_MAJOR  2
 #define PROGRAM_VERSION_MINOR  2
 #define PROGRAM_VERSION_PATCH  0
+#define PROGRAM_VERSION_RELEASE        7
 #define PROGRAM_VERSION_STRING "2.2.0rc7"
 
 #define PROGRAM_TITLE_STRING   "Rocks'n'Diamonds"
 #define GAME_VERSION_1_4       FILE_VERSION_1_4
 #define GAME_VERSION_2_0       FILE_VERSION_2_0
 
-#define GAME_VERSION_ACTUAL    VERSION_IDENT(PROGRAM_VERSION_MAJOR, \
+#define GAME_VERSION_ACTUAL    RELEASE_IDENT(PROGRAM_VERSION_MAJOR, \
                                              PROGRAM_VERSION_MINOR, \
-                                             PROGRAM_VERSION_PATCH)
+                                             PROGRAM_VERSION_PATCH, \
+                                             PROGRAM_VERSION_RELEASE)
 
 /* values for game_emulation */
 #define EMU_NONE               0
@@ -1018,8 +1073,8 @@ struct LevelInfo
   char name[MAX_LEVEL_NAME_LEN + 1];
   char author[MAX_LEVEL_AUTHOR_LEN + 1];
   int score[LEVEL_SCORE_ELEMENTS];
-  int yam_content[MAX_ELEMENT_CONTENTS][3][3];
-  int num_yam_contents;
+  int yamyam_content[MAX_ELEMENT_CONTENTS][3][3];
+  int num_yamyam_contents;
   int amoeba_speed;
   int amoeba_content;
   int time_magic_wall;
@@ -1030,7 +1085,7 @@ struct LevelInfo
   boolean gravity;
   boolean em_slippery_gems;    /* EM style "gems slip from wall" behaviour */
 
-  short custom_element_successor[NUM_CUSTOM_ELEMENTS];
+  boolean use_custom_template; /* use custom properties from template file */
 
   boolean no_level_file;
 };
@@ -1077,7 +1132,7 @@ struct GameInfo
   int initial_move_delay_value;
 
   /* variable within running game */
-  int yam_content_nr;
+  int yamyam_content_nr;
   boolean magic_wall_active;
   int magic_wall_time_left;
   int light_time_left;
@@ -1096,26 +1151,67 @@ struct GlobalInfo
 
   int num_toons;
 
-  int menu_draw_xoffset;
-  int menu_draw_yoffset;
-  int menu_draw_xoffset_MAIN;
-  int menu_draw_yoffset_MAIN;
-
-  int door_step_offset;
-  int door_step_delay;
-
   float frames_per_second;
   boolean fps_slowdown;
   int fps_slowdown_factor;
 };
 
+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 list_size_default;
+  int list_size[NUM_SPECIAL_GFX_ARGS];
+};
+
+struct DoorInfo
+{
+  int step_offset;
+  int step_delay;
+};
+
+struct ElementChangeInfo
+{
+  unsigned long events;                /* bitfield for change events */
+
+  short target_element;                /* target element after change */
+
+  int delay_fixed;             /* added frame delay before changed (fixed) */
+  int delay_random;            /* added frame delay before changed (random) */
+  int delay_frames;            /* either 1 (frames) or 50 (seconds; 50 fps) */
+
+  short trigger_element;       /* custom element triggering change */
+
+  int content[3][3];           /* new elements after extended change */
+  boolean use_content;         /* use extended change content */
+  boolean only_complete;       /* only use complete content */
+  boolean use_random_change;   /* use random value for setting content */
+  int random;                  /* random value for setting content */
+  int power;                   /* power of extended change */
+
+  boolean explode;             /* explode instead of change */
+
+  /* functions that are called before, while and after the change of an
+     element -- currently only used for non-custom elements */
+  void (*pre_change_function)(int x, int y);
+  void (*change_function)(int x, int y);
+  void (*post_change_function)(int x, int y);
+};
+
 struct ElementInfo
 {
+  /* ---------- token and description strings ---------- */
+
   char *token_name;            /* element token used in config files */
   char *class_name;            /* element class used in config files */
   char *editor_description;    /* short description for level editor */
   char *custom_description;    /* custom description for level editor */
 
+  /* ---------- graphic and sound definitions ---------- */
+
   int graphic[NUM_ACTIONS];    /* default graphics for several actions */
   int direction_graphic[NUM_ACTIONS][NUM_DIRECTIONS];
                                /* special graphics for left/right/up/down */
@@ -1123,6 +1219,27 @@ struct ElementInfo
                                /* special graphics for certain screens */
 
   int sound[NUM_ACTIONS];      /* default sounds for several actions */
+
+  /* ---------- special element property values ---------- */
+
+  boolean use_gfx_element;
+  short gfx_element;           /* optional custom graphic element */
+
+  int score;                   /* score value for collecting */
+  int gem_count;               /* gem count value for collecting */
+
+  int push_delay_fixed;                /* constant frame delay for pushing */
+  int push_delay_random;       /* additional random frame delay for pushing */
+  int move_delay_fixed;                /* constant frame delay for moving */
+  int move_delay_random;       /* additional random frame delay for moving */
+
+  int move_pattern;            /* direction movable element moves to */
+  int move_direction_initial;  /* initial direction element moves to */
+  int move_stepsize;           /* step size element moves with */
+
+  int content[3][3];           /* new elements after explosion */
+
+  struct ElementChangeInfo change;
 };
 
 struct FontInfo
@@ -1208,11 +1325,13 @@ extern short                    Ur[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
 extern short                   MovPos[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
 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                   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 short                   JustStopped[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
 extern short                   AmoebaNr[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
 extern short                   AmoebaCnt[MAX_NUM_AMOEBA];
@@ -1258,10 +1377,13 @@ extern struct HiScore           highscore[];
 extern struct TapeInfo         tape;
 extern struct GameInfo         game;
 extern struct GlobalInfo       global;
+extern struct MenuInfo         menu;
+extern struct DoorInfo         door;
 extern struct ElementInfo      element_info[];
 extern struct ElementActionInfo        element_action_info[];
 extern struct ElementDirectionInfo element_direction_info[];
 extern struct SpecialSuffixInfo special_suffix_info[];
+extern struct TokenIntPtrInfo  image_config_vars[];
 extern struct FontInfo         font_info[];
 extern struct GraphicInfo      *graphic_info;
 extern struct SoundInfo               *sound_info;