#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_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 75
-#define EP_WALK_TO_OBJECT 76
-#define EP_DEADLY 77
+#define EP_EXPLODE_RESULT 76
+#define EP_WALK_TO_OBJECT 77
+#define EP_DEADLY 78
-#define NUM_ELEMENT_PROPERTIES 78
+#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
/* 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_VERTICAL (MV_UP | MV_DOWN)
+#define MV_ALL_DIRECTIONS (MV_LEFT | MV_RIGHT | MV_UP | MV_DOWN)
#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 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)
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 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 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
int shield_deadly_time_left;
int inventory_element[MAX_INVENTORY_SIZE];
+ int inventory_infinite_element;
int inventory_size;
};
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; /* 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 */
+
+ int use_step_counter; /* count steps instead of seconds for level */
short field[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
boolean use_custom_template; /* use custom properties from template file */
- boolean no_level_file; /* set for currently undefined levels */
+ boolean no_valid_file; /* set when level file missing or invalid */
};
struct TapeInfo
byte action[MAX_PLAYERS];
byte delay;
} pos[MAX_TAPELEN];
+
+ boolean no_valid_file; /* set when tape file missing or invalid */
};
struct GameInfo
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 */
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 */
extern int ExitX, ExitY;
extern int AllPlayersGone;
-extern int TimeFrames, TimePlayed, TimeLeft;
+extern int TimeFrames, TimePlayed, TimeLeft, TapeTime;
extern boolean SiebAktiv;
extern int SiebCount;