/* 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
#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
+#define CE_BY_PLAYER 16 /* obsolete; map'd to CE_BY_DIRECT_ACTION */
+#define CE_BY_COLLISION 17 /* obsolete; map'd to CE_BY_DIRECT_ACTION */
+#define CE_BY_OTHER_ACTION 18 /* activates other element events */
+#define CE_BY_DIRECT_ACTION 19 /* activates direct element events */
+#define CE_OTHER_GETS_DIGGED 20
+
+#define NUM_CHANGE_EVENTS 21
#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)) : \
/* 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_ELEMENT_NAME_LEN 32
-#define MAX_TAPELEN (1000 * 50) /* max. time * framerate */
+#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_BORDER_SIZE 18
+#define GFX_ARG_STEP_OFFSET 19
+#define GFX_ARG_STEP_DELAY 20
+#define GFX_ARG_DIRECTION 21
+#define GFX_ARG_POSITION 22
+#define GFX_ARG_DRAW_XOFFSET 23
+#define GFX_ARG_DRAW_YOFFSET 24
+#define GFX_ARG_DRAW_MASKED 25
+#define GFX_ARG_NAME 26
-#define NUM_GFX_ARGS 23
+#define NUM_GFX_ARGS 27
/* 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"
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
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;
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
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];
};
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 */
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 direct_action; /* change triggered by actions on element */
+ int other_action; /* change triggered by other element actions */
};
struct ElementInfo
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 */
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 */
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 ---------- */
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
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 border_size; /* border size for "crumbled" graphics */
int step_offset; /* optional step offset of toon animations */
int step_delay; /* optional step delay of toon animations */
int draw_x, draw_y; /* optional offset for drawing fonts chars */
+ int draw_masked; /* optional setting for drawing envelope gfx */
+
#if defined(TARGET_X11_NATIVE_PERFORMANCE_WORKAROUND)
Pixmap clip_mask; /* single-graphic-only clip mask for X11 */
GC clip_gc; /* single-graphic-only clip gc for X11 */
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 Changed[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];