rnd-20030902-1-src
[rocksndiamonds.git] / src / main.h
index 255a6475adc66f2f3aa4786be75c8835394c871c..68ad89ca303d0a240c3c656f0e3d25204e26c355 100644 (file)
@@ -63,7 +63,7 @@
 
 /* values for configurable properties (custom elem's only, else pre-defined) */
 #define EP_DIGGABLE            0
-#define EP_COLLECTIBLE         1
+#define EP_COLLECTIBLE_ONLY    1
 #define EP_DONT_RUN_INTO       2
 #define EP_DONT_COLLIDE_WITH   3
 #define EP_DONT_TOUCH          4
@@ -84,8 +84,8 @@
 #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_DROPPABLE           22
+#define EP_CAN_EXPLODE_1X1     23
 #define EP_PUSHABLE            24
 
 /* values for special configurable properties (depending on level settings) */
 #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
+#define EP_COLLECTIBLE         63
+#define EP_SNAPPABLE           64
+#define EP_WALL                        65
+#define EP_SOLID_FOR_PUSHING   66
+#define EP_DRAGONFIRE_PROOF    67
+#define EP_EXPLOSION_PROOF     68
+#define EP_CAN_SMASH           69
+#define EP_CAN_EXPLODE         70
+#define EP_CAN_EXPLODE_3X3     71
 
 /* values for internal purpose only (level editor) */
-#define EP_EXPLODE_RESULT      70
-#define EP_WALK_TO_OBJECT      71
-#define EP_DEADLY              72
+#define EP_EXPLODE_RESULT      72
+#define EP_WALK_TO_OBJECT      73
+#define EP_DEADLY              74
 
-#define NUM_ELEMENT_PROPERTIES 73
+#define NUM_ELEMENT_PROPERTIES 75
 
 #define NUM_EP_BITFIELDS       ((NUM_ELEMENT_PROPERTIES + 31) / 32)
 #define EP_BITFIELD_BASE       0
                                 (PROPERTY_VAR(e,p) &= ~PROPERTY_BIT(p)))
 
 
-/* values for change events for custom elements */
+/* values for change events for custom elements (stored in level file) */
 #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_DROPPED_BY_PLAYER   4
+#define CE_COLLISION           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
+
+/* values for activating change events (also stored in level file!) */
+#define CE_BY_PLAYER           16
+#define CE_BY_COLLISION                17
+#define CE_BY_OTHER            18
+
+#define NUM_CHANGE_EVENTS      19
 
 #define CE_BITMASK_DEFAULT     0
 
 #define CH_EVENT_BIT(c)                (1 << (c))
-#define CH_EVENT_VAR(e)                (element_info[e].change.events)
+#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)) : \
 #define CP_HALF_DESTRUCTIVE    1
 #define CP_FULL_DESTRUCTIVE    2
 
+/* values for special move patterns (bits 0-3: basic move directions) */
+#define MV_BIT_TOWARDS_PLAYER  4
+#define MV_BIT_AWAY_FROM_PLAYER        5
+#define MV_BIT_ALONG_LEFT_SIDE 6
+#define MV_BIT_ALONG_RIGHT_SIDE        7
+#define MV_BIT_TURNING_LEFT    8
+#define MV_BIT_TURNING_RIGHT   9
+
+/* values for special move patterns for custom elements */
+#define MV_HORIZONTAL          (MV_LEFT | MV_RIGHT)
+#define MV_VERTICAL            (MV_UP | MV_DOWN)
+#define MV_ALL_DIRECTIONS      (MV_HORIZONTAL | MV_VERTICAL)
+#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 MV_ALONG_RIGHT_SIDE    (1 << MV_BIT_ALONG_RIGHT_SIDE)
+#define MV_TURNING_LEFT                (1 << MV_BIT_TURNING_LEFT)
+#define MV_TURNING_RIGHT       (1 << MV_BIT_TURNING_RIGHT)
+
+/* values for slippery property for custom elements */
+#define SLIPPERY_ANY_RANDOM    0
+#define SLIPPERY_ANY_LEFT_RIGHT        1
+#define SLIPPERY_ANY_RIGHT_LEFT        2
+#define SLIPPERY_ONLY_LEFT     3
+#define SLIPPERY_ONLY_RIGHT    4
 
 /* macros for configurable properties */
 #define IS_DIGGABLE(e)         HAS_PROPERTY(e, EP_DIGGABLE)
-#define IS_COLLECTIBLE(e)      HAS_PROPERTY(e, EP_COLLECTIBLE)
+#define IS_COLLECTIBLE_ONLY(e) HAS_PROPERTY(e, EP_COLLECTIBLE_ONLY)
 #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_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_DROPPABLE(e)                HAS_PROPERTY(e, EP_DROPPABLE)
+#define CAN_EXPLODE_1X1(e)     HAS_PROPERTY(e, EP_CAN_EXPLODE_1X1)
 #define IS_PUSHABLE(e)         HAS_PROPERTY(e, EP_PUSHABLE)
 
 /* macros for special configurable 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_COLLECTIBLE(e)      HAS_PROPERTY(e, EP_COLLECTIBLE)
+#define IS_SNAPPABLE(e)                HAS_PROPERTY(e, EP_SNAPPABLE)
 #define IS_WALL(e)             HAS_PROPERTY(e, EP_WALL)
 #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 CAN_EXPLODE_3X3(e)     HAS_PROPERTY(e, EP_CAN_EXPLODE_3X3)
 
 /* special macros used in game engine */
 #define IS_CUSTOM_ELEMENT(e)   ((e) >= EL_CUSTOM_START &&              \
 #define IS_LOOP_SOUND(s)       (sound_info[s].loop)
 
 
+/* fundamental game speed values */
+#define GAME_FRAME_DELAY       20      /* frame delay in milliseconds */
+#define FFWD_FRAME_DELAY       10      /* 200% speed for fast forward */
+#define FRAMES_PER_SECOND      (1000 / GAME_FRAME_DELAY)
+#define MICROLEVEL_SCROLL_DELAY        50      /* delay for scrolling micro level */
+#define MICROLEVEL_LABEL_DELAY 250     /* delay for micro level label */
+
 /* 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_ELEMENT_NAME_LEN   32
+#define MAX_TAPELEN            (1000 * FRAMES_PER_SECOND) /* max.time x fps */
 #define MAX_SCORE_ENTRIES      100
 #define MAX_NUM_AMOEBA         100
+#define MAX_INVENTORY_SIZE     1000
+#define MIN_ENVELOPE_XSIZE     1
+#define MIN_ENVELOPE_YSIZE     1
+#define MAX_ENVELOPE_XSIZE     30
+#define MAX_ENVELOPE_YSIZE     20
+#define MAX_ENVELOPE_TEXT_LEN  (MAX_ENVELOPE_XSIZE * MAX_ENVELOPE_YSIZE)
+#define MIN_CHANGE_PAGES       1
+#define MAX_CHANGE_PAGES       10
 
 /* values for elements with content */
 #define MIN_ELEMENT_CONTENTS   1
 
 #define LEVEL_SCORE_ELEMENTS   16      /* level elements with score */
 
-/* fundamental game speed values */
-#define GAME_FRAME_DELAY       20      /* frame delay in milliseconds */
-#define FFWD_FRAME_DELAY       10      /* 200% speed for fast forward */
-#define FRAMES_PER_SECOND      (1000 / GAME_FRAME_DELAY)
-#define MICROLEVEL_SCROLL_DELAY        50      /* delay for scrolling micro level */
-#define MICROLEVEL_LABEL_DELAY 250     /* delay for micro level label */
-
 /* often used screen positions */
 #define SX                     8
 #define SY                     8
 #define EL_EMPTY                       EL_EMPTY_SPACE
 #define EL_SAND                                1
 #define EL_WALL                                2
-#define EL_WALL_CRUMBLED               3
+#define EL_WALL_SLIPPERY               3
 #define EL_ROCK                                4
 #define EL_KEY_OBSOLETE                        5 /* obsolete; mapped to EL_KEY_1 */
 #define EL_EMERALD                     6
 #define EL_MOLE_RIGHT                  312
 #define EL_MOLE_UP                     313
 #define EL_MOLE_DOWN                   314
-#define EL_STEELWALL_SLANTED           315
+#define EL_STEELWALL_SLIPPERY          315
 #define EL_INVISIBLE_SAND              316
 #define EL_DX_UNKNOWN_15               317
 #define EL_DX_UNKNOWN_42               318
 
 #include "conf_cus.h"  /* include auto-generated data structure definitions */
 
-#define EL_CUSTOM_END                  (EL_CUSTOM_START + 127)
+#define NUM_CUSTOM_ELEMENTS            256
 
-#define NUM_CUSTOM_ELEMENTS            128
-#define NUM_FILE_ELEMENTS              488
+#define EL_CUSTOM_END          (EL_CUSTOM_START + NUM_CUSTOM_ELEMENTS - 1)
+#define NUM_FILE_ELEMENTS      (EL_CUSTOM_START + NUM_CUSTOM_ELEMENTS)
 
 
 /* "real" (and therefore drawable) runtime elements */
 #define EL_INVISIBLE_STEELWALL_BOTTOMRIGHT     (EL_FIRST_DUMMY + 9)
 #define EL_INVISIBLE_STEELWALL_HORIZONTAL      (EL_FIRST_DUMMY + 10)
 #define EL_INVISIBLE_STEELWALL_VERTICAL                (EL_FIRST_DUMMY + 11)
-#define EL_SAND_CRUMBLED                       (EL_FIRST_DUMMY + 12)
+#define EL_DYNABOMB                            (EL_FIRST_DUMMY + 12)
 #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 EL_DYNABOMB_PLAYER_1                   (EL_FIRST_DUMMY + 14)
+#define EL_DYNABOMB_PLAYER_2                   (EL_FIRST_DUMMY + 15)
+#define EL_DYNABOMB_PLAYER_3                   (EL_FIRST_DUMMY + 16)
+#define EL_DYNABOMB_PLAYER_4                   (EL_FIRST_DUMMY + 17)
+#define EL_SHIELD_NORMAL_ACTIVE                        (EL_FIRST_DUMMY + 18)
+#define EL_SHIELD_DEADLY_ACTIVE                        (EL_FIRST_DUMMY + 19)
+#define EL_DEFAULT                             (EL_FIRST_DUMMY + 20)
+#define EL_BD_DEFAULT                          (EL_FIRST_DUMMY + 21)
+#define EL_SP_DEFAULT                          (EL_FIRST_DUMMY + 22)
+#define EL_SB_DEFAULT                          (EL_FIRST_DUMMY + 23)
 
-#define MAX_NUM_ELEMENTS                       (EL_FIRST_DUMMY + 20)
+#define MAX_NUM_ELEMENTS                       (EL_FIRST_DUMMY + 24)
 
 
 /* values for graphics/sounds action types */
 #define GFX_SPECIAL_ARG_EDITOR                 3
 #define GFX_SPECIAL_ARG_INFO                   4
 #define GFX_SPECIAL_ARG_SETUP                  5
-#define GFX_SPECIAL_ARG_DOOR                   6
-#define GFX_SPECIAL_ARG_PREVIEW                        7
+#define GFX_SPECIAL_ARG_PLAYING                        6
+#define GFX_SPECIAL_ARG_DOOR                   7
+#define GFX_SPECIAL_ARG_PREVIEW                        8
+#define GFX_SPECIAL_ARG_CRUMBLED               9
 
-#define NUM_SPECIAL_GFX_ARGS                   8
+#define NUM_SPECIAL_GFX_ARGS                   10
 
 
 /* values for image configuration suffixes */
 #define GFX_ARG_DELAY                          13
 #define GFX_ARG_ANIM_MODE                      14
 #define GFX_ARG_GLOBAL_SYNC                    15
-#define GFX_ARG_STEP_OFFSET                    16
-#define GFX_ARG_STEP_DELAY                     17
-#define GFX_ARG_DIRECTION                      18
-#define GFX_ARG_POSITION                       19
-#define GFX_ARG_DRAW_XOFFSET                   20
-#define GFX_ARG_DRAW_YOFFSET                   21
-#define GFX_ARG_NAME                           22
+#define GFX_ARG_CRUMBLED_LIKE                  16
+#define GFX_ARG_DIGGABLE_LIKE                  17
+#define GFX_ARG_STEP_OFFSET                    18
+#define GFX_ARG_STEP_DELAY                     19
+#define GFX_ARG_DIRECTION                      20
+#define GFX_ARG_POSITION                       21
+#define GFX_ARG_DRAW_XOFFSET                   22
+#define GFX_ARG_DRAW_YOFFSET                   23
+#define GFX_ARG_NAME                           24
 
-#define NUM_GFX_ARGS                           23
+#define NUM_GFX_ARGS                           25
 
 
 /* values for sound configuration suffixes */
 #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
+#define GAME_MODE_PLAYING                      6
+#define GAME_MODE_PSEUDO_DOOR                  7
+#define GAME_MODE_PSEUDO_PREVIEW               8
+#define GAME_MODE_PSEUDO_CRUMBLED              9
 
 /* 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 GAME_MODE_PSEUDO_TYPENAME              10
+#define GAME_MODE_QUIT                         11
 
-#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_VERSION_MAJOR  3
+#define PROGRAM_VERSION_MINOR  0
+#define PROGRAM_VERSION_PATCH  3
+#define PROGRAM_VERSION_RELEASE        0
+#define PROGRAM_VERSION_STRING "3.0.3"
 
 #define PROGRAM_TITLE_STRING   "Rocks'n'Diamonds"
 #define PROGRAM_AUTHOR_STRING  "Holger Schemel"
@@ -1051,10 +1106,12 @@ struct PlayerInfo
   int lights_still_needed;
   int friends_still_needed;
   int key[4];
-  int dynamite;
   int dynabomb_count, dynabomb_size, dynabombs_left, dynabomb_xl;
   int shield_normal_time_left;
   int shield_deadly_time_left;
+
+  int inventory_element[MAX_INVENTORY_SIZE];
+  int inventory_size;
 };
 
 struct LevelInfo
@@ -1066,12 +1123,13 @@ struct LevelInfo
   boolean encoding_16bit_yamyam;       /* yamyam contains 16-bit elements */
   boolean encoding_16bit_amoeba;       /* amoeba contains 16-bit elements */
 
-  int fieldx;
-  int fieldy;
+  int fieldx, fieldy;
   int time;
   int gems_needed;
   char name[MAX_LEVEL_NAME_LEN + 1];
   char author[MAX_LEVEL_AUTHOR_LEN + 1];
+  char envelope[MAX_ENVELOPE_TEXT_LEN + 1];
+  int envelope_xsize, envelope_ysize;
   int score[LEVEL_SCORE_ELEMENTS];
   int yamyam_content[MAX_ELEMENT_CONTENTS][3][3];
   int num_yamyam_contents;
@@ -1085,9 +1143,11 @@ struct LevelInfo
   boolean gravity;
   boolean em_slippery_gems;    /* EM style "gems slip from wall" behaviour */
 
+  short field[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
+
   boolean use_custom_template; /* use custom properties from template file */
 
-  boolean no_level_file;
+  boolean no_level_file;       /* set for currently undefined levels */
 };
 
 struct TapeInfo
@@ -1163,6 +1223,8 @@ struct MenuInfo
   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];
 };
@@ -1175,6 +1237,8 @@ struct DoorInfo
 
 struct ElementChangeInfo
 {
+  boolean can_change;          /* use or ignore this change info */
+
   unsigned long events;                /* bitfield for change events */
 
   short target_element;                /* target element after change */
@@ -1199,6 +1263,12 @@ struct ElementChangeInfo
   void (*pre_change_function)(int x, int y);
   void (*change_function)(int x, int y);
   void (*post_change_function)(int x, int y);
+
+  /* ---------- internal values used in level editor ---------- */
+
+  int player_action;           /* touched/pressed/pushed by player */
+  int collide_action;          /* collision/impact/smashed */
+  int other_action;            /* various change actions */
 };
 
 struct ElementInfo
@@ -1207,14 +1277,20 @@ struct ElementInfo
 
   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 */
+  char *editor_description;    /* pre-defined description for level editor */
+  char *custom_description;    /* alternative description from config file */
+  char description[MAX_ELEMENT_NAME_LEN + 1];  /* for custom elements */
 
   /* ---------- 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 */
+
+  int crumbled[NUM_ACTIONS];   /* crumbled graphics for several actions */
+  int direction_crumbled[NUM_ACTIONS][NUM_DIRECTIONS];
+                               /* crumbled graphics for left/right/up/down */
+
   int special_graphic[NUM_SPECIAL_GFX_ARGS];
                                /* special graphics for certain screens */
 
@@ -1222,11 +1298,11 @@ struct ElementInfo
 
   /* ---------- special element property values ---------- */
 
-  boolean use_gfx_element;
+  boolean use_gfx_element;     /* use custom graphic element */
   short gfx_element;           /* optional custom graphic element */
 
-  int score;                   /* score value for collecting */
-  int gem_count;               /* gem count value for collecting */
+  int collect_score;           /* score value for collecting */
+  int collect_count;           /* count value for collecting */
 
   int push_delay_fixed;                /* constant frame delay for pushing */
   int push_delay_random;       /* additional random frame delay for pushing */
@@ -1237,9 +1313,22 @@ struct ElementInfo
   int move_direction_initial;  /* initial direction element moves to */
   int move_stepsize;           /* step size element moves with */
 
+  int slippery_type;           /* how/where other elements slip away */
+
   int content[3][3];           /* new elements after explosion */
 
-  struct ElementChangeInfo change;
+  struct ElementChangeInfo *change_page; /* actual list of change pages */
+  struct ElementChangeInfo *change;     /* pointer to current change page */
+
+  int num_change_pages;                /* actual number of change pages */
+  int current_change_page;     /* currently edited change page */
+
+  /* ---------- internal values used at runtime when playing ---------- */
+
+  unsigned long change_events; /* bitfield for combined change events */
+
+  int event_page_num[NUM_CHANGE_EVENTS]; /* page number for each event */
+  struct ElementChangeInfo *event_page[NUM_CHANGE_EVENTS]; /* page for event */
 
   /* ---------- internal values used in level editor ---------- */
 
@@ -1249,13 +1338,12 @@ struct ElementInfo
   int smash_targets;           /* can smash player/enemies/everything */
   int deadliness;              /* deadly when running/colliding/touching */
   int consistency;             /* indestructible/can explode */
-  int change_player_action;    /* touched/pressed/pushed by player */
-  int change_collide_action;   /* collision/impact/smashed */
-  int change_other_action;     /* various change actions */
 
   boolean can_explode_by_fire; /* element explodes by fire */
   boolean can_explode_smashed; /* element explodes when smashed */
   boolean can_explode_impact;  /* element explodes on impact */
+
+  boolean modified_settings;   /* set for all modified custom elements */
 };
 
 struct FontInfo
@@ -1281,6 +1369,8 @@ struct GraphicInfo
   int anim_delay;              /* important: delay of 1 means "no delay"! */
   int anim_mode;
   boolean anim_global_sync;
+  int crumbled_like;           /* element for cloning crumble graphics */
+  int diggable_like;           /* element for cloning digging graphics */
 
   int step_offset;             /* optional step offset of toon animations */
   int step_delay;              /* optional step delay of toon animations */
@@ -1337,7 +1427,6 @@ extern boolean                    redraw[MAX_BUF_XSIZE][MAX_BUF_YSIZE];
 extern int                     redraw_x1, redraw_y1;
 
 extern short                   Feld[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
-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];
@@ -1348,6 +1437,7 @@ 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 boolean                 Changing[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];
@@ -1387,7 +1477,7 @@ extern boolean                    network_player_action_received;
 
 extern int                     graphics_action_mapping[];
 
-extern struct LevelInfo                level;
+extern struct LevelInfo                level, level_template;
 extern struct PlayerInfo       stored_player[], *local_player;
 extern struct HiScore          highscore[];
 extern struct TapeInfo         tape;