rnd-20040228-1-src
[rocksndiamonds.git] / src / main.h
index 062c7a603bb9b8b38003f3635262f89968cdaef8..370d28910103f66e59f26e633d23cff59ed1bd4b 100644 (file)
@@ -87,6 +87,8 @@
 #define EP_CAN_EXPLODE_1X1     23
 #define EP_PUSHABLE            24
 #define EP_CAN_EXPLODE_DYNA    25
+#define EP_PROTECTED           26
+#define EP_CAN_MOVE_INTO_ACID  27
 
 /* 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
+#define EP_CAN_EXPLODE_BY_DRAGONFIRE 73
+#define EP_CAN_EXPLODE_BY_EXPLOSION  74
+#define EP_COULD_MOVE_INTO_ACID        75
 
 /* 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      76
+#define EP_WALK_TO_OBJECT      77
+#define EP_DEADLY              78
 
-#define NUM_ELEMENT_PROPERTIES 75
+#define NUM_ELEMENT_PROPERTIES 79
 
 #define NUM_EP_BITFIELDS       ((NUM_ELEMENT_PROPERTIES + 31) / 32)
 #define EP_BITFIELD_BASE       0
                                  (CH_EVENT_VAR(e) |=  CH_EVENT_BIT(c)) : \
                                  (CH_EVENT_VAR(e) &= ~CH_EVENT_BIT(c))) : 0)
 
-/* values for change sides for custom elements */
+/* values for change side for custom elements */
 #define CH_SIDE_NONE           MV_NO_MOVING
 #define CH_SIDE_LEFT           MV_LEFT
 #define CH_SIDE_RIGHT          MV_RIGHT
 #define CH_SIDE_TOP_BOTTOM     MV_VERTICAL
 #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)
+
+/* values for change page for custom elements */
+#define CH_PAGE_ANY_FILE       (0xff)
+#define CH_PAGE_ANY            (0xffffffff)
+
 /* values for change power for custom elements */
 #define CP_NON_DESTRUCTIVE     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_LEFT_RIGHT 14
 #define MV_BIT_TURNING_RIGHT_LEFT 15
 #define MV_BIT_TURNING_RANDOM  16
-#define MV_BIT_PREVIOUS                17
 
-/* 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_ANY_DIRECTION       (MV_ALL_DIRECTIONS)
-#define MV_RANDOM              (MV_ALL_DIRECTIONS)
-#define MV_AUTOMATIC           (MV_NO_MOVING)
 #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_TURNING_LEFT_RIGHT  (1 << MV_BIT_TURNING_LEFT_RIGHT)
 #define MV_TURNING_RIGHT_LEFT  (1 << MV_BIT_TURNING_RIGHT_LEFT)
 #define MV_TURNING_RANDOM      (1 << MV_BIT_TURNING_RANDOM)
-#define MV_PREVIOUS            (1 << MV_BIT_PREVIOUS)
+
+/* 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 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)
+#define CAN_MOVE_INTO_ACID(e)  HAS_PROPERTY(e, EP_CAN_MOVE_INTO_ACID)
 
 /* 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)
+#define CAN_EXPLODE_BY_DRAGONFIRE(e)   \
+                               HAS_PROPERTY(e, EP_CAN_EXPLODE_BY_DRAGONFIRE)
+#define CAN_EXPLODE_BY_EXPLOSION(e)    \
+                               HAS_PROPERTY(e, EP_CAN_EXPLODE_BY_EXPLOSION)
+#define COULD_MOVE_INTO_ACID(e)        HAS_PROPERTY(e, EP_COULD_MOVE_INTO_ACID)
 
 /* 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)) ||         \
+#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))
 
 
 /* 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_SCORE_ENTRIES      100
 #define MAX_NUM_AMOEBA         100
 #define MAX_INVENTORY_SIZE     1000
+#define MAX_KEYS               4
+#define NUM_BELTS              4
+#define NUM_BELT_PARTS         3
 #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       16
+#define MAX_CHANGE_PAGES       32
 #define MIN_ELEMENTS_IN_GROUP  1
 #define MAX_ELEMENTS_IN_GROUP  16
 
 #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 */
@@ -1235,7 +1292,10 @@ struct PlayerInfo
   boolean connected;           /* player connected (locally or via network) */
   boolean active;              /* player present and connected */
 
-  int index_nr, client_nr, element_nr;
+  int index_nr;                        /* player number (0 to 3) */
+  int index_bit;               /* player number bit (1 << 0 to 1 << 3) */
+  int element_nr;              /* element (EL_PLAYER_1 to EL_PLAYER_4) */
+  int client_nr;               /* network client identifier */
 
   byte action;                 /* action from local input device */
   byte effective_action;       /* action acknowledged from network server
@@ -1252,6 +1312,8 @@ struct PlayerInfo
 
   boolean use_murphy_graphic;
 
+  boolean block_last_field;
+
   boolean LevelSolved, GameOver;
 
   int last_move_dir;
@@ -1337,24 +1399,37 @@ struct LevelInfo
   boolean encoding_16bit_amoeba;       /* amoeba contains 16-bit elements */
 
   int fieldx, fieldy;
+
   int time;
   int gems_needed;
+
   char name[MAX_LEVEL_NAME_LEN + 1];
   char author[MAX_LEVEL_AUTHOR_LEN + 1];
+
   char envelope_text[4][MAX_ENVELOPE_TEXT_LEN + 1];
   int envelope_xsize[4], envelope_ysize[4];
+
   int score[LEVEL_SCORE_ELEMENTS];
+
   int yamyam_content[MAX_ELEMENT_CONTENTS][3][3];
   int num_yamyam_contents;
+
   int amoeba_speed;
   int amoeba_content;
+
   int time_magic_wall;
   int time_wheel;
   int time_light;
   int time_timegate;
+
+  int can_move_into_acid;      /* bits indicate property for element groups */
+
   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 */
+  boolean use_spring_bug;      /* for compatibility with old levels */
 
   short field[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
 
@@ -1447,7 +1522,10 @@ struct ElementChangeInfo
   boolean can_change;          /* use or ignore this change info */
 
   unsigned long events;                /* change events */
-  int sides;                   /* change sides */
+
+  int trigger_player;          /* player triggering change */
+  int trigger_side;            /* side triggering change */
+  int trigger_page;            /* page triggering change */
 
   short target_element;                /* target element after change */
 
@@ -1483,12 +1561,16 @@ 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
@@ -1521,6 +1603,8 @@ struct ElementInfo
   boolean use_gfx_element;     /* use custom graphic element */
   short gfx_element;           /* optional custom graphic element */
 
+  int access_direction;                /* accessible from which direction */
+
   int collect_score;           /* score value for collecting */
   int collect_count;           /* count value for collecting */
 
@@ -1540,6 +1624,9 @@ struct ElementInfo
 
   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 */
 
@@ -1564,6 +1651,7 @@ struct ElementInfo
 
   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 */
@@ -1724,8 +1812,9 @@ extern short                      WasJustFalling[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
 extern short                   AmoebaNr[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
 extern short                   AmoebaCnt[MAX_NUM_AMOEBA];
 extern short                   AmoebaCnt2[MAX_NUM_AMOEBA];
-extern short                   ExplodePhase[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
 extern short                   ExplodeField[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
+extern short                   ExplodePhase[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
+extern short                   ExplodeDelay[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
 extern int                     RunnerVisit[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
 extern int                     PlayerVisit[MAX_LEV_FIELDX][MAX_LEV_FIELDY];