rnd-20040323-1-src
[rocksndiamonds.git] / src / init.c
index 40b6417a04d32f6218f0c8efb5862833196ddeb6..6917ee0b1aabc04799fb382eff7feb95d0b7cdeb 100644 (file)
@@ -1569,79 +1569,143 @@ static void ReinitializeMusic()
   InitGameModeMusicInfo();     /* game mode music mapping */
 }
 
-static int get_special_property_bit(int element, int base_property_bit)
+static int get_special_property_bit(int element, int property_bit_nr)
 {
-  static struct
+  struct PropertyBitInfo
   {
     int element;
     int bit_nr;
-  } pb_can_move_into_acid[] =
-  {
-    { EL_BUG,                  0 },
-    { EL_BUG_LEFT,             0 },
-    { EL_BUG_RIGHT,            0 },
-    { EL_BUG_UP,               0 },
-    { EL_BUG_DOWN,             0 },
-    { EL_SPACESHIP,            0 },
-    { EL_SPACESHIP_LEFT,       0 },
-    { EL_SPACESHIP_RIGHT,      0 },
-    { EL_SPACESHIP_UP,         0 },
-    { EL_SPACESHIP_DOWN,       0 },
-    { EL_BD_BUTTERFLY,         1 },
-    { EL_BD_BUTTERFLY_LEFT,    1 },
-    { EL_BD_BUTTERFLY_RIGHT,   1 },
-    { EL_BD_BUTTERFLY_UP,      1 },
-    { EL_BD_BUTTERFLY_DOWN,    1 },
-    { EL_BD_FIREFLY,           1 },
-    { EL_BD_FIREFLY_LEFT,      1 },
-    { EL_BD_FIREFLY_RIGHT,     1 },
-    { EL_BD_FIREFLY_UP,                1 },
-    { EL_BD_FIREFLY_DOWN,      1 },
-    { EL_YAMYAM,               2 },
-    { EL_DARK_YAMYAM,          2 },
-    { EL_ROBOT,                        3 },
-    { EL_PACMAN,               4 },
-    { EL_PACMAN_LEFT,          4 },
-    { EL_PACMAN_RIGHT,         4 },
-    { EL_PACMAN_UP,            4 },
-    { EL_PACMAN_DOWN,          4 },
-    { EL_MOLE,                 4 },
-    { EL_MOLE_LEFT,            4 },
-    { EL_MOLE_RIGHT,           4 },
-    { EL_MOLE_UP,              4 },
-    { EL_MOLE_DOWN,            4 },
-    { EL_PENGUIN,              5 },
-    { EL_PIG,                  6 },
-    { EL_DRAGON,               6 },
-    { EL_SATELLITE,            7 },
-    { EL_SP_SNIKSNAK,          8 },
-    { EL_SP_ELECTRON,          8 },
-    { EL_BALLOON,              9 },
-
-    { -1,                      0 },
   };
+
+  static struct PropertyBitInfo pb_can_move_into_acid[] =
+  {
+    /* the player may be able fall into acid when gravity is activated */
+    { EL_PLAYER_1,             0       },
+    { EL_PLAYER_2,             0       },
+    { EL_PLAYER_3,             0       },
+    { EL_PLAYER_4,             0       },
+    { EL_SP_MURPHY,            0       },
+
+    /* all element that can move may be able to also move into acid */
+    { EL_BUG,                  1       },
+    { EL_BUG_LEFT,             1       },
+    { EL_BUG_RIGHT,            1       },
+    { EL_BUG_UP,               1       },
+    { EL_BUG_DOWN,             1       },
+    { EL_SPACESHIP,            2       },
+    { EL_SPACESHIP_LEFT,       2       },
+    { EL_SPACESHIP_RIGHT,      2       },
+    { EL_SPACESHIP_UP,         2       },
+    { EL_SPACESHIP_DOWN,       2       },
+    { EL_BD_BUTTERFLY,         3       },
+    { EL_BD_BUTTERFLY_LEFT,    3       },
+    { EL_BD_BUTTERFLY_RIGHT,   3       },
+    { EL_BD_BUTTERFLY_UP,      3       },
+    { EL_BD_BUTTERFLY_DOWN,    3       },
+    { EL_BD_FIREFLY,           4       },
+    { EL_BD_FIREFLY_LEFT,      4       },
+    { EL_BD_FIREFLY_RIGHT,     4       },
+    { EL_BD_FIREFLY_UP,                4       },
+    { EL_BD_FIREFLY_DOWN,      4       },
+    { EL_YAMYAM,               5       },
+    { EL_DARK_YAMYAM,          6       },
+    { EL_ROBOT,                        7       },
+    { EL_PACMAN,               8       },
+    { EL_PACMAN_LEFT,          8       },
+    { EL_PACMAN_RIGHT,         8       },
+    { EL_PACMAN_UP,            8       },
+    { EL_PACMAN_DOWN,          8       },
+    { EL_MOLE,                 9       },
+    { EL_MOLE_LEFT,            9       },
+    { EL_MOLE_RIGHT,           9       },
+    { EL_MOLE_UP,              9       },
+    { EL_MOLE_DOWN,            9       },
+    { EL_PENGUIN,              10      },
+    { EL_PIG,                  11      },
+    { EL_DRAGON,               12      },
+    { EL_SATELLITE,            13      },
+    { EL_SP_SNIKSNAK,          14      },
+    { EL_SP_ELECTRON,          15      },
+    { EL_BALLOON,              16      },
+    { EL_SPRING,               17      },
+
+    { -1,                      -1      },
+  };
+
+  static struct PropertyBitInfo pb_dont_collide_with[] =
+  {
+    { EL_SP_SNIKSNAK,          0       },
+    { EL_SP_ELECTRON,          1       },
+
+    { -1,                      -1      },
+  };
+
+  static struct
+  {
+    int bit_nr;
+    struct PropertyBitInfo *pb_info;
+  } pb_definition[] =
+  {
+    { EP_CAN_MOVE_INTO_ACID,   pb_can_move_into_acid   },
+    { EP_DONT_COLLIDE_WITH,    pb_dont_collide_with    },
+
+    { -1,                      NULL                    },
+  };
+
+  struct PropertyBitInfo *pb_info = NULL;
   int i;
 
-  if (base_property_bit != EP_CAN_MOVE_INTO_ACID)
+  for (i = 0; pb_definition[i].bit_nr != -1; i++)
+    if (pb_definition[i].bit_nr == property_bit_nr)
+      pb_info = pb_definition[i].pb_info;
+
+  if (pb_info == NULL)
     return -1;
 
-  for (i = 0; pb_can_move_into_acid[i].element != -1; i++)
-    if (pb_can_move_into_acid[i].element == element)
-      return pb_can_move_into_acid[i].bit_nr;
+  for (i = 0; pb_info[i].element != -1; i++)
+    if (pb_info[i].element == element)
+      return pb_info[i].bit_nr;
 
   return -1;
 }
 
+#if 1
+void setBitfieldProperty(int *bitfield, int property_bit_nr, int element,
+                        boolean property_value)
+{
+  int bit_nr = get_special_property_bit(element, property_bit_nr);
+
+  if (bit_nr > -1)
+  {
+    if (property_value)
+      *bitfield |=  (1 << bit_nr);
+    else
+      *bitfield &= ~(1 << bit_nr);
+  }
+}
+
+boolean getBitfieldProperty(int *bitfield, int property_bit_nr, int element)
+{
+  int bit_nr = get_special_property_bit(element, property_bit_nr);
+
+  if (bit_nr > -1)
+    return ((*bitfield & (1 << bit_nr)) != 0);
+
+  return FALSE;
+}
+
+#else
+
 void setMoveIntoAcidProperty(struct LevelInfo *level, int element, boolean set)
 {
   int bit_nr = get_special_property_bit(element, EP_CAN_MOVE_INTO_ACID);
 
   if (bit_nr > -1)
   {
-    level->can_move_into_acid &= ~(1 << bit_nr);
+    level->can_move_into_acid_bits &= ~(1 << bit_nr);
 
     if (set)
-      level->can_move_into_acid |= (1 << bit_nr);
+      level->can_move_into_acid_bits |= (1 << bit_nr);
   }
 }
 
@@ -1650,10 +1714,11 @@ boolean getMoveIntoAcidProperty(struct LevelInfo *level, int element)
   int bit_nr = get_special_property_bit(element, EP_CAN_MOVE_INTO_ACID);
 
   if (bit_nr > -1)
-    return ((level->can_move_into_acid & (1 << bit_nr)) != 0);
+    return ((level->can_move_into_acid_bits & (1 << bit_nr)) != 0);
 
   return FALSE;
 }
+#endif
 
 void InitElementPropertiesStatic()
 {
@@ -1912,6 +1977,7 @@ void InitElementPropertiesStatic()
 
   static int ep_can_move[] =
   {
+    /* same elements as in 'pb_can_move_into_acid' */
     EL_BUG,
     EL_SPACESHIP,
     EL_BD_BUTTERFLY,
@@ -2168,7 +2234,7 @@ void InitElementPropertiesStatic()
     -1
   };
 
-  static int ep_can_explode_dyna[] =
+  static int ep_can_explode_cross[] =
   {
     -1
   };
@@ -2764,6 +2830,12 @@ void InitElementPropertiesStatic()
     -1
   };
 
+  static int ep_can_turn_each_move[] =
+  {
+    /* !!! do something !!! */
+    -1
+  };
+
   static int ep_active_bomb[] =
   {
     EL_DYNAMITE_ACTIVE,
@@ -2960,7 +3032,7 @@ void InitElementPropertiesStatic()
     { ep_droppable,            EP_DROPPABLE            },
     { ep_can_explode_1x1,      EP_CAN_EXPLODE_1X1      },
     { ep_pushable,             EP_PUSHABLE             },
-    { ep_can_explode_dyna,     EP_CAN_EXPLODE_DYNA     },
+    { ep_can_explode_cross,    EP_CAN_EXPLODE_CROSS    },
     { ep_protected,            EP_PROTECTED            },
 
     { ep_player,               EP_PLAYER               },
@@ -2984,6 +3056,7 @@ void InitElementPropertiesStatic()
     { ep_amoeboid,             EP_AMOEBOID             },
     { ep_amoebalive,           EP_AMOEBALIVE           },
     { ep_has_content,          EP_HAS_CONTENT          },
+    { ep_can_turn_each_move,   EP_CAN_TURN_EACH_MOVE   },
     { ep_active_bomb,          EP_ACTIVE_BOMB          },
     { ep_inactive,             EP_INACTIVE             },
 
@@ -3254,7 +3327,7 @@ void InitElementPropertiesEngine(int engine_version)
     /* ---------- CAN_EXPLODE_3X3 ------------------------------------------ */
     SET_PROPERTY(i, EP_CAN_EXPLODE_3X3, (CAN_EXPLODE(i) &&
                                         !CAN_EXPLODE_1X1(i) &&
-                                        !CAN_EXPLODE_DYNA(i)));
+                                        !CAN_EXPLODE_CROSS(i)));
 
     /* ---------- CAN_EXPLODE_BY_DRAGONFIRE -------------------------------- */
     SET_PROPERTY(i, EP_CAN_EXPLODE_BY_DRAGONFIRE, CAN_EXPLODE_BY_FIRE(i));
@@ -3264,12 +3337,23 @@ void InitElementPropertiesEngine(int engine_version)
                                                  i == EL_BLACK_ORB));
 
     /* ---------- COULD_MOVE_INTO_ACID ------------------------------------- */
-    SET_PROPERTY(i, EP_COULD_MOVE_INTO_ACID, ((CAN_MOVE(i) && i != EL_SPRING)||
+    SET_PROPERTY(i, EP_COULD_MOVE_INTO_ACID, (ELEM_IS_PLAYER(i) ||
+                                             CAN_MOVE(i) ||
                                              IS_CUSTOM_ELEMENT(i)));
 
+    /* ---------- MAYBE_DONT_COLLIDE_WITH ---------------------------------- */
+    SET_PROPERTY(i, EP_MAYBE_DONT_COLLIDE_WITH, (i == EL_SP_SNIKSNAK ||
+                                                i == EL_SP_ELECTRON));
+
     /* ---------- CAN_MOVE_INTO_ACID --------------------------------------- */
-    if (!IS_CUSTOM_ELEMENT(i))
-      SET_PROPERTY(i, EP_CAN_MOVE_INTO_ACID,getMoveIntoAcidProperty(&level,i));
+    if (COULD_MOVE_INTO_ACID(i) && !IS_CUSTOM_ELEMENT(i))
+      SET_PROPERTY(i, EP_CAN_MOVE_INTO_ACID,
+                  getMoveIntoAcidProperty(&level, i));
+
+    /* ---------- DONT_COLLIDE_WITH ---------------------------------------- */
+    if (MAYBE_DONT_COLLIDE_WITH(i))
+      SET_PROPERTY(i, EP_DONT_COLLIDE_WITH,
+                  getDontCollideWithProperty(&level, i));
 
     /* ---------- SP_PORT -------------------------------------------------- */
     SET_PROPERTY(i, EP_SP_PORT, (IS_SP_ELEMENT(i) &&
@@ -3280,7 +3364,7 @@ void InitElementPropertiesEngine(int engine_version)
       printf("::: %d, %d, %d -> %d\n",
             CAN_EXPLODE_1X1(i),
             CAN_EXPLODE_3X3(i),
-            CAN_EXPLODE_DYNA(i),
+            CAN_EXPLODE_CROSS(i),
             CAN_EXPLODE(i));
 #endif
 
@@ -3363,7 +3447,7 @@ void InitElementPropertiesEngine(int engine_version)
   }
 
   /* set some other uninitialized values of custom elements in older levels */
-  if (engine_version < VERSION_IDENT(3,0,9,0))
+  if (engine_version < VERSION_IDENT(3,1,0,0))
   {
     for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++)
     {
@@ -3371,10 +3455,20 @@ void InitElementPropertiesEngine(int engine_version)
 
       element_info[element].access_direction = MV_ALL_DIRECTIONS;
 
-      element_info[element].explosion_delay = 18;
+      element_info[element].explosion_delay = 17;
       element_info[element].ignition_delay = 8;
     }
   }
+
+#if 0
+  /* set element properties that were handled incorrectly in older levels */
+  if (engine_version < VERSION_IDENT(3,1,0,0))
+  {
+    SET_PROPERTY(EL_SP_SNIKSNAK, EP_DONT_COLLIDE_WITH, FALSE);
+    SET_PROPERTY(EL_SP_ELECTRON, EP_DONT_COLLIDE_WITH, FALSE);
+  }
+#endif
+
 #endif
 
   /* this is needed because some graphics depend on element properties */