rnd-20040323-1-src
[rocksndiamonds.git] / src / init.c
index a78ee6118bb5241ef391f7eb193ee46af187798c..6917ee0b1aabc04799fb382eff7feb95d0b7cdeb 100644 (file)
@@ -1569,71 +1569,133 @@ 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[] =
-  {
-    /* all element that can move */
-    { 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       },
-    { EL_SPRING,               10      },
+  };
+
+  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);
@@ -1656,6 +1718,7 @@ boolean getMoveIntoAcidProperty(struct LevelInfo *level, int element)
 
   return FALSE;
 }
+#endif
 
 void InitElementPropertiesStatic()
 {
@@ -2171,7 +2234,7 @@ void InitElementPropertiesStatic()
     -1
   };
 
-  static int ep_can_explode_dyna[] =
+  static int ep_can_explode_cross[] =
   {
     -1
   };
@@ -2767,6 +2830,12 @@ void InitElementPropertiesStatic()
     -1
   };
 
+  static int ep_can_turn_each_move[] =
+  {
+    /* !!! do something !!! */
+    -1
+  };
+
   static int ep_active_bomb[] =
   {
     EL_DYNAMITE_ACTIVE,
@@ -2963,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               },
@@ -2987,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             },
 
@@ -3257,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));
@@ -3267,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) ||
+    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) &&
@@ -3283,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
 
@@ -3366,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++)
     {
@@ -3374,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 */