#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_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 73
-#define EP_WALK_TO_OBJECT 74
-#define EP_DEADLY 75
+#define EP_EXPLODE_RESULT 76
+#define EP_WALK_TO_OBJECT 77
+#define EP_DEADLY 78
-#define NUM_ELEMENT_PROPERTIES 76
+#define NUM_ELEMENT_PROPERTIES 79
#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_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 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_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))
#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
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];
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 */
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 */
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];