#define IN_SCR_FIELD(x,y) ((x)>=BX1 && (x)<=BX2 && (y)>=BY1 &&(y)<=BY2)
#define IN_LEV_FIELD(x,y) ((x)>=0 && (x)<lev_fieldx && (y)>=0 &&(y)<lev_fieldy)
-/* values for 'Properties1' */
-#define EP_BIT_AMOEBALIVE (1 << 0)
-#define EP_BIT_AMOEBOID (1 << 1)
-#define EP_BIT_SCHLUESSEL (1 << 2)
-#define EP_BIT_PFORTE (1 << 3)
-#define EP_BIT_SOLID (1 << 4)
-#define EP_BIT_INDESTRUCTIBLE (1 << 5)
-#define EP_BIT_SLIPPERY (1 << 6)
-#define EP_BIT_ENEMY (1 << 7)
-#define EP_BIT_MAUER (1 << 8)
-#define EP_BIT_CAN_FALL (1 << 9)
-#define EP_BIT_CAN_SMASH (1 << 10)
-#define EP_BIT_CAN_CHANGE (1 << 11)
-#define EP_BIT_CAN_MOVE (1 << 12)
-#define EP_BIT_COULD_MOVE (1 << 13)
-#define EP_BIT_DONT_TOUCH (1 << 14)
-#define EP_BIT_DONT_GO_TO (1 << 15)
-#define EP_BIT_MAMPF2 (1 << 16)
-#define EP_BIT_CHAR (1 << 17)
-#define EP_BIT_BD_ELEMENT (1 << 18)
-#define EP_BIT_SB_ELEMENT (1 << 19)
-#define EP_BIT_GEM (1 << 20)
-#define EP_BIT_INACTIVE (1 << 21)
-#define EP_BIT_EXPLOSIVE (1 << 22)
-#define EP_BIT_MAMPF3 (1 << 23)
-#define EP_BIT_PUSHABLE (1 << 24)
-#define EP_BIT_PLAYER (1 << 25)
-#define EP_BIT_HAS_CONTENT (1 << 26)
-#define EP_BIT_EATABLE (1 << 27)
-#define EP_BIT_SP_ELEMENT (1 << 28)
-#define EP_BIT_QUICK_GATE (1 << 29)
-#define EP_BIT_OVER_PLAYER (1 << 30)
-#define EP_BIT_ACTIVE_BOMB (1 << 31)
-
-/* values for 'Properties2' */
-#define EP_BIT_BELT (1 << 0)
-#define EP_BIT_BELT_ACTIVE (1 << 1)
-#define EP_BIT_BELT_SWITCH (1 << 2)
-#define EP_BIT_TUBE (1 << 3)
-#define EP_BIT_EM_SLIPPERY_WALL (1 << 4)
-#define EP_BIT_CAN_BE_CRUMBLED (1 << 5)
+/* values for base properties (storable) */
+#define EP_AMOEBALIVE 0
+#define EP_AMOEBOID 1
+#define EP_CAN_BE_CRUMBLED 2
+#define EP_PFORTE 3
+#define EP_SOLID 4
+#define EP_INDESTRUCTIBLE 5
+#define EP_SLIPPERY 6
+#define EP_ENEMY 7
+#define EP_MAUER 8
+#define EP_CAN_FALL 9
+#define EP_CAN_SMASH 10
+#define EP_CAN_CHANGE 11
+#define EP_CAN_MOVE 12
+#define EP_COULD_MOVE 13
+#define EP_DONT_TOUCH 14
+#define EP_DONT_GO_TO 15
+#define EP_FOOD_DARK_YAMYAM 16
+#define EP_EM_SLIPPERY_WALL 17
+#define EP_BD_ELEMENT 18
+#define EP_SB_ELEMENT 19
+#define EP_GEM 20
+#define EP_INACTIVE 21
+#define EP_EXPLOSIVE 22
+#define EP_FOOD_PENGUIN 23
+#define EP_PUSHABLE 24
+#define EP_PLAYER 25
+#define EP_WALKABLE_OVER 26
+#define EP_WALKABLE_INSIDE 27
+#define EP_WALKABLE_UNDER 28
+#define EP_PASSABLE_OVER 29
+#define EP_PASSABLE_INSIDE 30
+#define EP_PASSABLE_UNDER 31
+
+/* values for runtime properties (non-storable) */
+#define EP_ACCESSIBLE_OVER 32
+#define EP_ACCESSIBLE_INSIDE 33
+#define EP_ACCESSIBLE_UNDER 34
+#define EP_WALKABLE 35
+#define EP_PASSABLE 36
+#define EP_ACCESSIBLE 37
+#define EP_DIGGABLE 38
+#define EP_COLLECTIBLE 39
+#define EP_ACTIVE_BOMB 40
+#define EP_BELT 41
+#define EP_BELT_ACTIVE 42
+#define EP_BELT_SWITCH 43
+#define EP_SP_ELEMENT 44
+#define EP_HAS_CONTENT 45
+#define EP_TUBE 46
+
+#define NUM_ELEMENT_PROPERTIES 47
+
+#define NUM_EP_BITFIELDS ((NUM_ELEMENT_PROPERTIES + 31) / 32)
+#define EP_BITFIELD_BASE 0
#define EP_BITMASK_DEFAULT 0
-#define IS_AMOEBALIVE(e) (Properties1[e] & EP_BIT_AMOEBALIVE)
-#define IS_AMOEBOID(e) (Properties1[e] & EP_BIT_AMOEBOID)
-#define IS_SCHLUESSEL(e) (Properties1[e] & EP_BIT_SCHLUESSEL)
-#define IS_PFORTE(e) (Properties1[e] & EP_BIT_PFORTE)
-#define IS_SOLID(e) (Properties1[e] & EP_BIT_SOLID)
-#define IS_INDESTRUCTIBLE(e) (Properties1[e] & EP_BIT_INDESTRUCTIBLE)
-#define IS_SLIPPERY(e) (Properties1[e] & EP_BIT_SLIPPERY)
-#define IS_ENEMY(e) (Properties1[e] & EP_BIT_ENEMY)
-#define IS_MAUER(e) (Properties1[e] & EP_BIT_MAUER)
-#define CAN_FALL(e) (Properties1[e] & EP_BIT_CAN_FALL)
-#define CAN_SMASH(e) (Properties1[e] & EP_BIT_CAN_SMASH)
-#define CAN_CHANGE(e) (Properties1[e] & EP_BIT_CAN_CHANGE)
-#define CAN_MOVE(e) (Properties1[e] & EP_BIT_CAN_MOVE)
-#define COULD_MOVE(e) (Properties1[e] & EP_BIT_COULD_MOVE)
-#define DONT_TOUCH(e) (Properties1[e] & EP_BIT_DONT_TOUCH)
-#define DONT_GO_TO(e) (Properties1[e] & EP_BIT_DONT_GO_TO)
-#define IS_MAMPF2(e) (Properties1[e] & EP_BIT_MAMPF2)
-#define IS_CHAR(e) (Properties1[e] & EP_BIT_CHAR)
-#define IS_BD_ELEMENT(e) (Properties1[e] & EP_BIT_BD_ELEMENT)
-#define IS_SB_ELEMENT(e) (Properties1[e] & EP_BIT_SB_ELEMENT)
-#define IS_GEM(e) (Properties1[e] & EP_BIT_GEM)
-#define IS_INACTIVE(e) (Properties1[e] & EP_BIT_INACTIVE)
-#define IS_EXPLOSIVE(e) (Properties1[e] & EP_BIT_EXPLOSIVE)
-#define IS_MAMPF3(e) (Properties1[e] & EP_BIT_MAMPF3)
-#define IS_PUSHABLE(e) (Properties1[e] & EP_BIT_PUSHABLE)
-#define ELEM_IS_PLAYER(e) (Properties1[e] & EP_BIT_PLAYER)
-#define HAS_CONTENT(e) (Properties1[e] & EP_BIT_HAS_CONTENT)
-#define IS_EATABLE(e) (Properties1[e] & EP_BIT_EATABLE)
-#define IS_SP_ELEMENT(e) (Properties1[e] & EP_BIT_SP_ELEMENT)
-#define IS_QUICK_GATE(e) (Properties1[e] & EP_BIT_QUICK_GATE)
-#define IS_OVER_PLAYER(e) (Properties1[e] & EP_BIT_OVER_PLAYER)
-#define IS_ACTIVE_BOMB(e) (Properties1[e] & EP_BIT_ACTIVE_BOMB)
-
-#define IS_BELT(e) (Properties2[e] & EP_BIT_BELT)
-#define IS_BELT_ACTIVE(e) (Properties2[e] & EP_BIT_BELT_ACTIVE)
-#define IS_BELT_SWITCH(e) (Properties2[e] & EP_BIT_BELT_SWITCH)
-#define IS_TUBE(e) (Properties2[e] & EP_BIT_TUBE)
-#define IS_EM_SLIPPERY_WALL(e) (Properties2[e] & EP_BIT_EM_SLIPPERY_WALL)
-#define CAN_BE_CRUMBLED(e) (Properties2[e] & EP_BIT_CAN_BE_CRUMBLED)
+#define PROPERTY_BIT(p) (1 << ((p) % 32))
+#define PROPERTY_VAR(e, p) (Properties[e][(p) / 32])
+#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)) : \
+ (PROPERTY_VAR(e,p) &= ~PROPERTY_BIT(p)))
+
+/* macros for base properties */
+#define IS_AMOEBALIVE(e) HAS_PROPERTY(e, EP_AMOEBALIVE)
+#define IS_AMOEBOID(e) HAS_PROPERTY(e, EP_AMOEBOID)
+#define CAN_BE_CRUMBLED(e) HAS_PROPERTY(e, EP_CAN_BE_CRUMBLED)
+#define IS_PFORTE(e) HAS_PROPERTY(e, EP_PFORTE)
+#define IS_SOLID(e) HAS_PROPERTY(e, EP_SOLID)
+#define IS_INDESTRUCTIBLE(e) HAS_PROPERTY(e, EP_INDESTRUCTIBLE)
+#define IS_SLIPPERY(e) HAS_PROPERTY(e, EP_SLIPPERY)
+#define IS_ENEMY(e) HAS_PROPERTY(e, EP_ENEMY)
+#define IS_MAUER(e) HAS_PROPERTY(e, EP_MAUER)
+#define CAN_FALL(e) HAS_PROPERTY(e, EP_CAN_FALL)
+#define CAN_SMASH(e) HAS_PROPERTY(e, EP_CAN_SMASH)
+#define CAN_CHANGE(e) HAS_PROPERTY(e, EP_CAN_CHANGE)
+#define CAN_MOVE(e) HAS_PROPERTY(e, EP_CAN_MOVE)
+#define COULD_MOVE(e) HAS_PROPERTY(e, EP_COULD_MOVE)
+#define DONT_TOUCH(e) HAS_PROPERTY(e, EP_DONT_TOUCH)
+#define DONT_GO_TO(e) HAS_PROPERTY(e, EP_DONT_GO_TO)
+#define IS_FOOD_DARK_YAMYAM(e) HAS_PROPERTY(e, EP_FOOD_DARK_YAMYAM)
+#define IS_EM_SLIPPERY_WALL(e) HAS_PROPERTY(e, EP_EM_SLIPPERY_WALL)
+#define IS_BD_ELEMENT(e) HAS_PROPERTY(e, EP_BD_ELEMENT)
+#define IS_SB_ELEMENT(e) HAS_PROPERTY(e, EP_SB_ELEMENT)
+#define IS_GEM(e) HAS_PROPERTY(e, EP_GEM)
+#define IS_INACTIVE(e) HAS_PROPERTY(e, EP_INACTIVE)
+#define IS_EXPLOSIVE(e) HAS_PROPERTY(e, EP_EXPLOSIVE)
+#define IS_FOOD_PENGUIN(e) HAS_PROPERTY(e, EP_FOOD_PENGUIN)
+#define IS_PUSHABLE(e) HAS_PROPERTY(e, EP_PUSHABLE)
+#define ELEM_IS_PLAYER(e) HAS_PROPERTY(e, EP_PLAYER)
+#define IS_WALKABLE_OVER(e) HAS_PROPERTY(e, EP_WALKABLE_OVER)
+#define IS_WALKABLE_INSIDE(e) HAS_PROPERTY(e, EP_WALKABLE_INSIDE)
+#define IS_WALKABLE_UNDER(e) HAS_PROPERTY(e, EP_WALKABLE_UNDER)
+#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)
+
+/* macros for runtime 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_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_DIGGABLE(e) HAS_PROPERTY(e, EP_DIGGABLE)
+#define IS_COLLECTIBLE(e) HAS_PROPERTY(e, EP_COLLECTIBLE)
+#define IS_ACTIVE_BOMB(e) HAS_PROPERTY(e, EP_ACTIVE_BOMB)
+#define IS_BELT(e) HAS_PROPERTY(e, EP_BELT)
+#define IS_BELT_ACTIVE(e) HAS_PROPERTY(e, EP_BELT_ACTIVE)
+#define IS_BELT_SWITCH(e) HAS_PROPERTY(e, EP_BELT_SWITCH)
+#define IS_SP_ELEMENT(e) HAS_PROPERTY(e, EP_SP_ELEMENT)
+#define HAS_CONTENT(e) HAS_PROPERTY(e, EP_HAS_CONTENT)
+#define IS_TUBE(e) HAS_PROPERTY(e, EP_TUBE)
#define IS_CUSTOM_ELEMENT(e) ((e) >= EL_CUSTOM_START && \
(e) <= EL_CUSTOM_END)
#define PLAYERINFO(x,y) (&stored_player[StorePlayer[x][y]-EL_PLAYER_1])
#define SHIELD_ON(p) ((p)->shield_normal_time_left > 0)
-#define PROTECTED_FIELD(x,y) (IS_TUBE(Feld[x][y]))
+#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)) || \
PROTECTED_FIELD(x, y))
#define EL_CHAR(c) (EL_CHAR_ASCII0 + MAP_FONT_ASCII(c))
-#if 0
-#define EL_CHAR(x) ((x) == 'Ä' ? EL_CHAR_AE : \
- (x) == 'Ö' ? EL_CHAR_OE : \
- (x) == 'Ü' ? EL_CHAR_UE : \
- (x) == 'ä' ? EL_CHAR_AE : \
- (x) == 'ö' ? EL_CHAR_OE : \
- (x) == 'ü' ? EL_CHAR_UE : \
- (x) == '©' ? EL_CHAR_COPYRIGHT : \
- (x) == '_' ? EL_CHAR_UNDERSCORE : \
- (x) == '°' ? EL_CHAR_DEGREE : \
- (x) == '´' ? EL_CHAR_TM : \
- (x) == '|' ? EL_CHAR_CURSOR : \
- EL_CHAR_A + (x) - 'A')
-#endif
-
#define EL_EXPANDABLE_WALL_HORIZONTAL 200
#define EL_EXPANDABLE_WALL_VERTICAL 201
#define EL_EXPANDABLE_WALL_ANY 202
#define FONT_TEXT_2 9
#define FONT_TEXT_3 10
#define FONT_TEXT_4 11
-#define FONT_INPUT 12
-#define FONT_INPUT_ACTIVE 13
-#define FONT_OPTION_OFF 14
-#define FONT_OPTION_ON 15
-#define FONT_VALUE_1 16
-#define FONT_VALUE_2 17
-#define FONT_VALUE_OLD 18
-#define FONT_TAPE_RECORDER 19
-#define FONT_LEVEL_NUMBER 20
-
-#define NUM_FONTS 21
+#define FONT_INPUT_1 12
+#define FONT_INPUT_1_ACTIVE 13
+#define FONT_INPUT_2 14
+#define FONT_INPUT_2_ACTIVE 15
+#define FONT_OPTION_OFF 16
+#define FONT_OPTION_ON 17
+#define FONT_VALUE_1 18
+#define FONT_VALUE_2 19
+#define FONT_VALUE_OLD 20
+#define FONT_LEVEL_NUMBER 21
+#define FONT_TAPE_RECORDER 22
+#define FONT_GAME_INFO 23
+
+#define NUM_FONTS 24
#define NUM_INITIAL_FONTS 4
/* values for game_status */
boolean gravity;
boolean em_slippery_gems; /* EM style "gems slip from wall" behaviour */
+ short custom_element_successor[NUM_CUSTOM_ELEMENTS];
+
boolean no_level_file;
};
extern short Store[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
extern short Store2[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
extern short StorePlayer[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
+extern short Back[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
extern boolean Stop[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 ExplodePhase[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
extern short ExplodeField[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
-extern unsigned long Properties1[MAX_NUM_ELEMENTS];
-extern unsigned long Properties2[MAX_NUM_ELEMENTS];
+extern unsigned long Properties[MAX_NUM_ELEMENTS][NUM_EP_BITFIELDS];
extern int GfxFrame[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
extern int GfxAction[MAX_LEV_FIELDX][MAX_LEV_FIELDY];