rnd-20040206-B-src
[rocksndiamonds.git] / src / main.h
index f3f625dc5906dafa5225298b46ff748d8d748833..d09b3278e5eea8ba321998d87e74035acee18c83 100644 (file)
@@ -87,6 +87,7 @@
 #define EP_CAN_EXPLODE_1X1     23
 #define EP_PUSHABLE            24
 #define EP_CAN_EXPLODE_DYNA    25
+#define EP_PROTECTED           26
 
 /* values for pre-defined properties */
 #define EP_PLAYER              32
 #define EP_CAN_SMASH           69
 #define EP_CAN_EXPLODE         70
 #define EP_CAN_EXPLODE_3X3     71
+#define EP_SP_PORT             72
 
 /* values for internal purpose only (level editor) */
-#define EP_EXPLODE_RESULT      72
-#define EP_WALK_TO_OBJECT      73
-#define EP_DEADLY              74
+#define EP_EXPLODE_RESULT      73
+#define EP_WALK_TO_OBJECT      74
+#define EP_DEADLY              75
 
-#define NUM_ELEMENT_PROPERTIES 75
+#define NUM_ELEMENT_PROPERTIES 76
 
 #define NUM_EP_BITFIELDS       ((NUM_ELEMENT_PROPERTIES + 31) / 32)
 #define EP_BITFIELD_BASE       0
 #define CP_HALF_DESTRUCTIVE    1
 #define CP_FULL_DESTRUCTIVE    2
 
-/* values for special move patterns (bits 0-3: basic move directions) */
+/* 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_ALONG_LEFT_SIDE 6
 #define MV_BIT_TURNING_RIGHT_LEFT 15
 #define MV_BIT_TURNING_RANDOM  16
 
-/* values for special move patterns for custom elements */
+/* values for custom move patterns */
 #define MV_HORIZONTAL          (MV_LEFT | MV_RIGHT)
 #define MV_VERTICAL            (MV_UP | MV_DOWN)
 #define MV_ALL_DIRECTIONS      (MV_HORIZONTAL | MV_VERTICAL)
 #define MV_TURNING_RIGHT_LEFT  (1 << MV_BIT_TURNING_RIGHT_LEFT)
 #define MV_TURNING_RANDOM      (1 << MV_BIT_TURNING_RANDOM)
 
+/* values for initial move direction (bits 0 - 3: basic move directions) */
+#define MV_START_BIT_PREVIOUS  4
+
+/* values for initial move direction */
+#define MV_START_AUTOMATIC     (MV_NO_MOVING)
+#define MV_START_LEFT          (MV_LEFT)
+#define MV_START_RIGHT         (MV_RIGHT)
+#define MV_START_UP            (MV_UP)
+#define MV_START_DOWN          (MV_DOWN)
+#define MV_START_RANDOM                (MV_ALL_DIRECTIONS)
+#define MV_START_PREVIOUS      (1 << MV_START_BIT_PREVIOUS)
+
+/* values for elements left behind by custom elements */
+#define LEAVE_TYPE_UNLIMITED   0
+#define LEAVE_TYPE_LIMITED     1
+
 /* values for slippery property for custom elements */
 #define SLIPPERY_ANY_RANDOM    0
 #define SLIPPERY_ANY_LEFT_RIGHT        1
 #define CAN_EXPLODE_1X1(e)     HAS_PROPERTY(e, EP_CAN_EXPLODE_1X1)
 #define IS_PUSHABLE(e)         HAS_PROPERTY(e, EP_PUSHABLE)
 #define CAN_EXPLODE_DYNA(e)    HAS_PROPERTY(e, EP_CAN_EXPLODE_DYNA)
+#define IS_PROTECTED(e)                HAS_PROPERTY(e, EP_PROTECTED)
 
 /* macros for special configurable properties */
 #define IS_EM_SLIPPERY_WALL(e) HAS_PROPERTY(e, EP_EM_SLIPPERY_WALL)
 #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)
+#define IS_SP_PORT(e)          HAS_PROPERTY(e, EP_SP_PORT)
 
 /* special macros used in game engine */
 #define IS_CUSTOM_ELEMENT(e)   ((e) >= EL_CUSTOM_START &&              \
 
 #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_ENEMY_PROTECTED(x,y)     (SHIELD_ON(PLAYERINFO(x, y)) ||           \
+                                        ENEMY_PROTECTED_FIELD(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_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))
 
 
 /* fundamental game speed values */
+#define ONE_SECOND_DELAY       1000    /* delay value for one second */
 #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 FRAMES_PER_SECOND      (ONE_SECOND_DELAY / GAME_FRAME_DELAY)
 #define MICROLEVEL_SCROLL_DELAY        50      /* delay for scrolling micro level */
 #define MICROLEVEL_LABEL_DELAY 250     /* delay for micro level label */
 
 #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       16
+#define MAX_CHANGE_PAGES       32
 #define MIN_ELEMENTS_IN_GROUP  1
 #define MAX_ELEMENTS_IN_GROUP  16
 
 #define EL_DARK_YAMYAM                 60
 #define EL_BD_MAGIC_WALL               61
 #define EL_INVISIBLE_STEELWALL         62
-
-#define EL_MAZE_RUNNER                 63
-
+#define EL_SOKOBAN_FIELD_PLAYER                63
 #define EL_DYNABOMB_INCREASE_NUMBER    64
 #define EL_DYNABOMB_INCREASE_SIZE      65
 #define EL_DYNABOMB_INCREASE_POWER     66
 #define EL_GROUP_END                   655
 /* ---------- end of custom elements section ------------------------------- */
 
-#define NUM_FILE_ELEMENTS              656
+#define EL_UNKNOWN                     656
+
+#define NUM_FILE_ELEMENTS              657
 
 
 /* "real" (and therefore drawable) runtime elements */
 #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)
+#define EL_PLAYER_IS_EXPLODING_1       (EL_FIRST_RUNTIME_UNREAL + 11)
+#define EL_PLAYER_IS_EXPLODING_2       (EL_FIRST_RUNTIME_UNREAL + 12)
+#define EL_PLAYER_IS_EXPLODING_3       (EL_FIRST_RUNTIME_UNREAL + 13)
+#define EL_PLAYER_IS_EXPLODING_4       (EL_FIRST_RUNTIME_UNREAL + 14)
+#define EL_QUICKSAND_FILLING           (EL_FIRST_RUNTIME_UNREAL + 15)
+#define EL_MAGIC_WALL_FILLING          (EL_FIRST_RUNTIME_UNREAL + 16)
+#define EL_BD_MAGIC_WALL_FILLING       (EL_FIRST_RUNTIME_UNREAL + 17)
 
 /* dummy elements (never used as game elements, only used as graphics) */
-#define EL_FIRST_DUMMY                 (EL_FIRST_RUNTIME_UNREAL + 14)
+#define EL_FIRST_DUMMY                 (EL_FIRST_RUNTIME_UNREAL + 18)
 
 #define EL_STEELWALL_TOPLEFT                   (EL_FIRST_DUMMY + 0)
 #define EL_STEELWALL_TOPRIGHT                  (EL_FIRST_DUMMY + 1)
 #define EL_BD_DEFAULT                          (EL_FIRST_DUMMY + 22)
 #define EL_SP_DEFAULT                          (EL_FIRST_DUMMY + 23)
 #define EL_SB_DEFAULT                          (EL_FIRST_DUMMY + 24)
-#define EL_DUMMY                               (EL_FIRST_DUMMY + 25)
 
-#define MAX_NUM_ELEMENTS                       (EL_FIRST_DUMMY + 26)
+/* internal elements (only used for internal purposes like copying) */
+#define EL_FIRST_INTERNAL                      (EL_FIRST_DUMMY + 25)
+
+#define EL_INTERNAL_EDITOR                     (EL_FIRST_INTERNAL + 0)
+#define EL_INTERNAL_DUMMY                      (EL_FIRST_INTERNAL + 1)
+
+#define MAX_NUM_ELEMENTS                       (EL_FIRST_INTERNAL + 2)
 
 
 /* values for graphics/sounds action types */
@@ -1237,6 +1278,8 @@ struct PlayerInfo
 
   boolean use_murphy_graphic;
 
+  boolean block_last_field;
+
   boolean LevelSolved, GameOver;
 
   int last_move_dir;
@@ -1307,6 +1350,8 @@ struct LevelFileInfo
 {
   int nr;
   int type;
+  boolean packed;
+  char *basename;
   char *filename;
 };
 
@@ -1338,6 +1383,8 @@ struct LevelInfo
   boolean double_speed;
   boolean initial_gravity;
   boolean em_slippery_gems;    /* EM style "gems slip from wall" behaviour */
+  boolean block_last_field;    /* player blocks previous field while moving */
+  boolean sp_block_last_field; /* player blocks previous field while moving */
 
   short field[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
 
@@ -1464,8 +1511,18 @@ struct ElementChangeInfo
 struct ElementGroupInfo
 {
   int num_elements;                    /* number of elements in this group */
-
   short element[MAX_ELEMENTS_IN_GROUP];        /* list of elements in this group */
+
+  int choice_mode;             /* how to choose element from group */
+
+  /* ---------- internal values used at runtime when playing ---------- */
+
+  /* the following is the same as above, but with recursively resolved group
+     elements (group elements may also contain further group elements!) */
+  int num_elements_resolved;
+  short element_resolved[NUM_FILE_ELEMENTS];
+
+  int choice_pos;              /* current element choice position */
 };
 
 struct ElementInfo
@@ -1509,11 +1566,17 @@ struct ElementInfo
   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 move_enter_element;      /* element that can be entered (and removed) */
+  int move_leave_element;      /* element that can be left behind */
+  int move_leave_type;         /* change (limited) or leave (unlimited) */
 
   int slippery_type;           /* how/where other elements slip away */
 
   int content[3][3];           /* new elements after explosion */
 
+  int explosion_delay;         /* duration of explosion of this element */
+  int ignition_delay;          /* delay for explosion by other explosion */
+
   struct ElementChangeInfo *change_page; /* actual list of change pages */
   struct ElementChangeInfo *change;     /* pointer to current change page */
 
@@ -1529,10 +1592,16 @@ struct ElementInfo
   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];
+
+  boolean can_leave_element;   /* element can leave other element behind */
+  boolean can_leave_element_last;
+
   /* ---------- internal values used in level editor ---------- */
 
   int access_type;             /* walkable or passable */
   int access_layer;            /* accessible over/inside/under */
+  int access_protected;                /* protection against deadly elements */
   int walk_to_action;          /* diggable/collectible/pushable */
   int smash_targets;           /* can smash player/enemies/everything */
   int deadliness;              /* deadly when running/colliding/touching */