#define MIN_LEV_FIELDY 3
#define STD_LEV_FIELDX 64
#define STD_LEV_FIELDY 32
-#define MAX_LEV_FIELDX 128
-#define MAX_LEV_FIELDY 128
+#define MAX_LEV_FIELDX MAX_PLAYFIELD_WIDTH
+#define MAX_LEV_FIELDY MAX_PLAYFIELD_HEIGHT
#define SCREENX(a) ((a) - scroll_x)
#define SCREENY(a) ((a) - scroll_y)
#define EP_CAN_EXPLODE_BY_EXPLOSION 78
#define EP_COULD_MOVE_INTO_ACID 79
#define EP_MAYBE_DONT_COLLIDE_WITH 80
+#define EP_CAN_BE_CLONED_BY_ANDROID 81
/* values for internal purpose only (level editor) */
-#define EP_WALK_TO_OBJECT 81
-#define EP_DEADLY 82
-#define EP_EDITOR_CASCADE 83
-#define EP_EDITOR_CASCADE_ACTIVE 84
-#define EP_EDITOR_CASCADE_INACTIVE 85
+#define EP_WALK_TO_OBJECT 82
+#define EP_DEADLY 83
+#define EP_EDITOR_CASCADE 84
+#define EP_EDITOR_CASCADE_ACTIVE 85
+#define EP_EDITOR_CASCADE_INACTIVE 86
/* values for internal purpose only (game engine) */
-#define EP_HAS_ACTION 86
-#define EP_CAN_CHANGE_OR_HAS_ACTION 87
+#define EP_HAS_ACTION 87
+#define EP_CAN_CHANGE_OR_HAS_ACTION 88
-#define NUM_ELEMENT_PROPERTIES 88
+#define NUM_ELEMENT_PROPERTIES 89
#define NUM_EP_BITFIELDS ((NUM_ELEMENT_PROPERTIES + 31) / 32)
#define EP_BITFIELD_BASE 0
#define EP_BITMASK_DEFAULT 0
#define PROPERTY_BIT(p) (1 << ((p) % 32))
+#if 1
+#define PROPERTY_VAR(e,p) (element_info[e].properties[(p) / 32])
+#else
#define PROPERTY_VAR(e,p) (Properties[e][(p) / 32])
+#endif
#define HAS_PROPERTY(e,p) ((PROPERTY_VAR(e, p) & PROPERTY_BIT(p)) != 0)
#define SET_PROPERTY(e,p,v) ((v) ? \
(PROPERTY_VAR(e,p) |= PROPERTY_BIT(p)) : \
#define CA_ARG_ELEMENT_RESET (CA_ARG_ELEMENT + 0)
#define CA_ARG_ELEMENT_TARGET (CA_ARG_ELEMENT + 1)
#define CA_ARG_ELEMENT_TRIGGER (CA_ARG_ELEMENT + 2)
-#define CA_ARG_ELEMENT_HEADLINE (CA_ARG_ELEMENT + 999)
+#define CA_ARG_ELEMENT_HEADLINE (CA_ARG_ELEMENT + 998)
+#define CA_ARG_ELEMENT_CV_TARGET (CA_ARG_ELEMENT_TARGET)
+#define CA_ARG_ELEMENT_CV_TRIGGER (CA_ARG_ELEMENT_TRIGGER)
+#define CA_ARG_ELEMENT_CV_HEADLINE (CA_ARG_ELEMENT_HEADLINE)
+#define CA_ARG_ELEMENT_NR_TARGET (CA_ARG_ELEMENT + 3)
+#define CA_ARG_ELEMENT_NR_TRIGGER (CA_ARG_ELEMENT + 4)
+#define CA_ARG_ELEMENT_NR_HEADLINE (CA_ARG_ELEMENT + 999)
#define CA_ARG_SPEED 13000
#define CA_ARG_SPEED_NOT_MOVING (CA_ARG_SPEED + STEPSIZE_NOT_MOVING)
#define CA_ARG_SPEED_VERY_SLOW (CA_ARG_SPEED + STEPSIZE_VERY_SLOW)
HAS_PROPERTY(e, EP_CAN_EXPLODE_BY_EXPLOSION)
#define COULD_MOVE_INTO_ACID(e) HAS_PROPERTY(e, EP_COULD_MOVE_INTO_ACID)
#define MAYBE_DONT_COLLIDE_WITH(e) HAS_PROPERTY(e, EP_MAYBE_DONT_COLLIDE_WITH)
+#define CAN_BE_CLONED_BY_ANDROID(e) \
+ HAS_PROPERTY(e, EP_CAN_BE_CLONED_BY_ANDROID)
#define IS_EDITOR_CASCADE(e) HAS_PROPERTY(e, EP_EDITOR_CASCADE)
#define IS_EDITOR_CASCADE_ACTIVE(e) \
#define GFX_ELEMENT(e) (element_info[e].use_gfx_element ? \
element_info[e].gfx_element : e)
+#if 1
+#define TILE_GFX_ELEMENT(x, y) \
+ (GfxElement[x][y] != EL_UNDEFINED && \
+ Feld[x][y] != EL_EXPLOSION ? \
+ GfxElement[x][y] : Feld[x][y])
+#else
+#define TILE_GFX_ELEMENT(x, y) \
+ GFX_ELEMENT(GfxElement[x][y] != EL_UNDEFINED && \
+ Feld[x][y] != EL_EXPLOSION ? \
+ GfxElement[x][y] : Feld[x][y])
+#endif
+
/* !!! "use sound" deactivated due to problems with level "bug machine" !!! */
/* (solution: add separate "use sound of element" to level file and editor) */
#if 0
#define SND_ELEMENT(e) (e)
#endif
+#if 1
+#define GROUP_NR(e) ((e) - EL_GROUP_START)
+#define IS_IN_GROUP(e, nr) (element_info[e].in_group[nr] == TRUE)
+#define IS_IN_GROUP_EL(e, ge) (IS_IN_GROUP(e, (ge) - EL_GROUP_START))
+
+#define IS_EQUAL_OR_IN_GROUP(e, ge) \
+ (IS_GROUP_ELEMENT(ge) ? IS_IN_GROUP(e, GROUP_NR(ge)) : (e) == (ge))
+#endif
+
#define IS_PLAYER(x, y) (ELEM_IS_PLAYER(StorePlayer[x][y]))
#define IS_FREE(x, y) (Feld[x][y] == EL_EMPTY && !IS_PLAYER(x, y))
#define IS_FALLING(x,y) (MovPos[x][y] != 0 && MovDir[x][y] == MV_DOWN)
#define IS_BLOCKED(x,y) (Feld[x][y] == EL_BLOCKED)
+#define IS_MV_DIAGONAL(x) ((x) & MV_HORIZONTAL && (x) & MV_VERTICAL)
+
#define EL_CHANGED(e) ((e) == EL_ROCK ? EL_EMERALD : \
(e) == EL_BD_ROCK ? EL_BD_DIAMOND : \
(e) == EL_EMERALD ? EL_DIAMOND : \
#define EL_CASCADE_TOGGLE(e) (IS_EDITOR_CASCADE_INACTIVE(e) ? (e) + 1 : \
IS_EDITOR_CASCADE_ACTIVE(e) ? (e) - 1 : (e))
-#define EL_NAME(e) (element_info[e].token_name)
+#define EL_NAME(e) ((e) >= 0 ? element_info[e].token_name : "(?)")
/* fundamental game speed values */
#define ONE_SECOND_DELAY 1000 /* delay value for one second */
#define EL_EM_GATE_3_GRAY 252
#define EL_EM_GATE_4_GRAY 253
-#define EL_UNUSED_254 254
-#define EL_UNUSED_255 255
+#define EL_EM_DYNAMITE 254
+#define EL_EM_DYNAMITE_ACTIVE 255
#define EL_PEARL 256
#define EL_CRYSTAL 257
#define EL_TRIGGER_ELEMENT 657
#define EL_TRIGGER_PLAYER 658
+/* SP style elements */
#define EL_SP_GRAVITY_ON_PORT_RIGHT 659
#define EL_SP_GRAVITY_ON_PORT_DOWN 660
#define EL_SP_GRAVITY_ON_PORT_LEFT 661
#define EL_SP_GRAVITY_OFF_PORT_LEFT 665
#define EL_SP_GRAVITY_OFF_PORT_UP 666
-
-/* the following EMC style elements are currently not implemented in R'n'D */
+/* EMC style elements */
#define EL_BALLOON_SWITCH_NONE 667
#define EL_EMC_GATE_5 668
#define EL_EMC_GATE_6 669
#define EL_EMC_FAKE_ACID 703
#define EL_EMC_DRIPPER 704
-#define NUM_FILE_ELEMENTS 705
+#define EL_TRIGGER_CE_VALUE 705
+
+#define EL_YAMYAM_LEFT 706
+#define EL_YAMYAM_RIGHT 707
+#define EL_YAMYAM_UP 708
+#define EL_YAMYAM_DOWN 709
+
+#define NUM_FILE_ELEMENTS 710
/* "real" (and therefore drawable) runtime elements */
#define EL_EMC_GATE_7_GRAY_ACTIVE (EL_FIRST_RUNTIME_REAL + 56)
#define EL_EMC_GATE_8_GRAY_ACTIVE (EL_FIRST_RUNTIME_REAL + 57)
#define EL_EMC_DRIPPER_ACTIVE (EL_FIRST_RUNTIME_REAL + 58)
+#define EL_EMC_SPRING_BUMPER_ACTIVE (EL_FIRST_RUNTIME_REAL + 59)
/* "unreal" (and therefore not drawable) runtime elements */
-#define EL_FIRST_RUNTIME_UNREAL (EL_FIRST_RUNTIME_REAL + 59)
+#define EL_FIRST_RUNTIME_UNREAL (EL_FIRST_RUNTIME_REAL + 60)
#define EL_BLOCKED (EL_FIRST_RUNTIME_UNREAL + 0)
#define EL_EXPLOSION (EL_FIRST_RUNTIME_UNREAL + 1)
#define EL_MAGIC_WALL_FILLING (EL_FIRST_RUNTIME_UNREAL + 16)
#define EL_BD_MAGIC_WALL_FILLING (EL_FIRST_RUNTIME_UNREAL + 17)
#define EL_ELEMENT_SNAPPING (EL_FIRST_RUNTIME_UNREAL + 18)
+#define EL_DIAGONAL_SHRINKING (EL_FIRST_RUNTIME_UNREAL + 19)
+#define EL_DIAGONAL_GROWING (EL_FIRST_RUNTIME_UNREAL + 20)
+
+#define NUM_RUNTIME_ELEMENTS (EL_FIRST_RUNTIME_UNREAL + 21)
/* dummy elements (never used as game elements, only used as graphics) */
-#define EL_FIRST_DUMMY (EL_FIRST_RUNTIME_UNREAL + 19)
+#define EL_FIRST_DUMMY NUM_RUNTIME_ELEMENTS
#define EL_STEELWALL_TOPLEFT (EL_FIRST_DUMMY + 0)
#define EL_STEELWALL_TOPRIGHT (EL_FIRST_DUMMY + 1)
#define ACTION_TURNING_FROM_DOWN 46
#define ACTION_SMASHED_BY_ROCK 47
#define ACTION_SMASHED_BY_SPRING 48
-#define ACTION_SLURPED_BY_SPRING 49
+#define ACTION_EATING 49
#define ACTION_TWINKLING 50
#define ACTION_SPLASHING 51
#define ACTION_PAGE_1 52
#define PROGRAM_TITLE_STRING "Rocks'n'Diamonds"
#define PROGRAM_AUTHOR_STRING "Holger Schemel"
-#define PROGRAM_COPYRIGHT_STRING "Copyright ©1995-2005 by Holger Schemel"
+#define PROGRAM_COPYRIGHT_STRING "Copyright ©1995-2006 by Holger Schemel"
#define ICON_TITLE_STRING PROGRAM_TITLE_STRING
#define COOKIE_PREFIX "ROCKSNDIAMONDS"
struct DoorInfo
{
+ int width;
+ int height;
int step_offset;
int step_delay;
int anim_mode;
boolean is_pushing;
boolean is_switching;
boolean is_dropping;
+ boolean is_dropping_pressed;
boolean is_bored;
boolean is_sleeping;
int anim_delay_counter;
int post_delay_counter;
+ int dir_waiting;
int action_waiting, last_action_waiting;
int special_action_bored;
int special_action_sleeping;
unsigned long actual_frame_counter;
int drop_delay;
+ int drop_pressed_delay;
int step_counter;
boolean can_pass_to_walkable; /* player can pass to empty or walkable tile */
boolean grow_into_diggable; /* amoeba can grow into anything diggable */
+ boolean continuous_snapping; /* repeated snapping without releasing key */
boolean block_snap_field; /* snapping blocks field to show animation */
boolean block_last_field; /* player blocks previous field while moving */
boolean sp_block_last_field; /* player blocks previous field while moving */
/* values for special game initialization control */
boolean restart_level;
+
+ /* values for special game control */
+ int centered_player_nr;
+ int centered_player_nr_next;
+ boolean set_centered_player;
};
struct GlobalInfo
/* ---------- graphic and sound definitions ---------- */
int graphic[NUM_ACTIONS]; /* default graphics for several actions */
- int direction_graphic[NUM_ACTIONS][NUM_DIRECTIONS];
+ int direction_graphic[NUM_ACTIONS][NUM_DIRECTIONS_FULL];
/* special graphics for left/right/up/down */
int crumbled[NUM_ACTIONS]; /* crumbled graphics for several actions */
- int direction_crumbled[NUM_ACTIONS][NUM_DIRECTIONS];
+ int direction_crumbled[NUM_ACTIONS][NUM_DIRECTIONS_FULL];
/* crumbled graphics for left/right/up/down */
int special_graphic[NUM_SPECIAL_GFX_ARGS];
/* ---------- special element property values ---------- */
+ unsigned long properties[NUM_EP_BITFIELDS]; /* element base properties */
+
boolean use_gfx_element; /* use custom graphic element */
int gfx_element; /* optional custom graphic element */
extern int RunnerVisit[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
extern int PlayerVisit[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
+#if 0
extern unsigned long Properties[MAX_NUM_ELEMENTS][NUM_EP_BITFIELDS];
+#endif
extern int GfxFrame[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
extern int GfxRandom[MAX_LEV_FIELDX][MAX_LEV_FIELDY];