rnd-20060606-1-src
[rocksndiamonds.git] / src / game.c
index 769cde25f8c20ec18ca56e289678368d32994b4d..ac37d91eb997b8f8f9097c144c23d8a00fdc817b 100644 (file)
@@ -780,6 +780,7 @@ static int get_move_delay_from_stepsize(int move_stepsize)
 static void SetPlayerMoveSpeed(struct PlayerInfo *player, int move_stepsize,
                               boolean init_game)
 {
+  int player_nr = player->index_nr;
   int move_delay = get_move_delay_from_stepsize(move_stepsize);
   boolean cannot_move = (move_stepsize == STEPSIZE_NOT_MOVING ? TRUE : FALSE);
 
@@ -791,8 +792,8 @@ static void SetPlayerMoveSpeed(struct PlayerInfo *player, int move_stepsize,
 
   if (init_game)
   {
-    player->move_delay       = game.initial_move_delay;
-    player->move_delay_value = game.initial_move_delay_value;
+    player->move_delay       = game.initial_move_delay[player_nr];
+    player->move_delay_value = game.initial_move_delay_value[player_nr];
 
     player->move_delay_value_next = -1;
 
@@ -1594,8 +1595,9 @@ static void InitGameEngine()
 
 #if 1
   /* dynamically adjust player properties according to level information */
-  game.initial_move_delay_value =
-    get_move_delay_from_stepsize(level.initial_player_stepsize);
+  for (i = 0; i < MAX_PLAYERS; i++)
+    game.initial_move_delay_value[i] =
+      get_move_delay_from_stepsize(level.initial_player_stepsize[i]);
 #else
   /* dynamically adjust player properties according to level information */
   game.initial_move_delay_value =
@@ -1603,8 +1605,10 @@ static void InitGameEngine()
 #endif
 
   /* dynamically adjust player properties according to game engine version */
-  game.initial_move_delay = (game.engine_version <= VERSION_IDENT(2,0,1,0) ?
-                            game.initial_move_delay_value : 0);
+  for (i = 0; i < MAX_PLAYERS; i++)
+    game.initial_move_delay[i] =
+      (game.engine_version <= VERSION_IDENT(2,0,1,0) ?
+       game.initial_move_delay_value[i] : 0);
 
   /* ---------- initialize player's initial push delay --------------------- */
 
@@ -1763,8 +1767,22 @@ static void InitGameEngine()
   {
     if (!IS_CUSTOM_ELEMENT(i))
     {
+#if 1
+      /* set default push delay values (corrected since version 3.0.7-1) */
+      if (game.engine_version < VERSION_IDENT(3,0,7,1))
+      {
+       element_info[i].push_delay_fixed = 2;
+       element_info[i].push_delay_random = 8;
+      }
+      else
+      {
+       element_info[i].push_delay_fixed = 8;
+       element_info[i].push_delay_random = 8;
+      }
+#else
       element_info[i].push_delay_fixed  = game.default_push_delay_fixed;
       element_info[i].push_delay_random = game.default_push_delay_random;
+#endif
     }
   }
 
@@ -2022,7 +2040,7 @@ void InitGame()
     player->show_envelope = 0;
 
 #if 1
-    SetPlayerMoveSpeed(player, level.initial_player_stepsize, TRUE);
+    SetPlayerMoveSpeed(player, level.initial_player_stepsize[i], TRUE);
 #else
     player->move_delay       = game.initial_move_delay;
     player->move_delay_value = game.initial_move_delay_value;
@@ -2088,8 +2106,15 @@ void InitGame()
   game.timegate_time_left = 0;
   game.switchgate_pos = 0;
   game.wind_direction = level.wind_direction_initial;
+
+#if !USE_PLAYER_GRAVITY
+#if 1
+  game.gravity = FALSE;
+#else
   game.gravity = level.initial_gravity;
+#endif
   game.explosions_delayed = TRUE;
+#endif
 
   game.lenses_time_left = 0;
   game.magnify_time_left = 0;
@@ -8002,7 +8027,7 @@ static void ExecuteCustomElementAction(int x, int y, int element, int page)
      CA_ARG_MAX);
 
   int action_arg_number_reset =
-    (action_type == CA_SET_PLAYER_SPEED ? level.initial_player_stepsize :
+    (action_type == CA_SET_PLAYER_SPEED ? level.initial_player_stepsize[0] :
      action_type == CA_SET_LEVEL_GEMS ? level.gems_needed :
      action_type == CA_SET_LEVEL_TIME ? level.time :
      action_type == CA_SET_LEVEL_SCORE ? 0 :
@@ -8224,6 +8249,10 @@ static void ExecuteCustomElementAction(int x, int y, int element, int page)
            action_mode = (action_arg == CA_ARG_SPEED_SLOWER ? CA_MODE_DIVIDE :
                           CA_MODE_MULTIPLY);
          }
+         else if (action_arg == CA_ARG_NUMBER_RESET)
+         {
+           action_arg_number = level.initial_player_stepsize[i];
+         }
 
          move_stepsize =
            getModifiedActionNumber(move_stepsize,
@@ -8421,8 +8450,10 @@ static void CreateFieldExt(int x, int y, int element, boolean is_change)
 #if USE_NEW_CUSTOM_VALUE
   int last_ce_value = CustomValue[x][y];
 #endif
-  boolean add_player = (ELEM_IS_PLAYER(new_element) &&
-                       IS_WALKABLE(old_element));
+  boolean new_element_is_player = ELEM_IS_PLAYER(new_element);
+  boolean add_player_onto_element = (new_element_is_player &&
+                                    new_element != EL_SOKOBAN_FIELD_PLAYER &&
+                                    IS_WALKABLE(old_element));
 
 #if 0
   /* check if element under the player changes from accessible to unaccessible
@@ -8436,7 +8467,7 @@ static void CreateFieldExt(int x, int y, int element, boolean is_change)
   }
 #endif
 
-  if (!add_player)
+  if (!add_player_onto_element)
   {
     if (IS_MOVING(x, y) || IS_BLOCKED(x, y))
       RemoveMovingField(x, y);
@@ -8487,7 +8518,7 @@ static void CreateFieldExt(int x, int y, int element, boolean is_change)
 #endif
 
   /* "ChangeCount" not set yet to allow "entered by player" change one time */
-  if (ELEM_IS_PLAYER(new_element))
+  if (new_element_is_player)
     RelocatePlayer(x, y, new_element);
 
   if (is_change)
@@ -11666,6 +11697,8 @@ int DigField(struct PlayerInfo *player,
           game.engine_version >= VERSION_IDENT(2,2,0,0))
     old_element = Back[jx][jy];
 
+  /* checking here causes player to move into acid even if the current field
+     cannot be left to that direction */
 #if 0
 #if USE_FIXED_DONT_RUN_INTO
   if (player_can_move && DONT_RUN_INTO(element))
@@ -11687,6 +11720,43 @@ int DigField(struct PlayerInfo *player,
 #endif
 #endif
 
+#if 1  /* ------------------------------ NEW ------------------------------ */
+
+  if (IS_WALKABLE(old_element) && !ACCESS_FROM(old_element, move_direction))
+    return MP_NO_ACTION;       /* field has no opening in this direction */
+
+  if (IS_PASSABLE(old_element) && !ACCESS_FROM(old_element,opposite_direction))
+    return MP_NO_ACTION;       /* field has no opening in this direction */
+
+#if USE_FIXED_DONT_RUN_INTO
+  if (player_can_move && element == EL_ACID && move_direction == MV_DOWN)
+  {
+    SplashAcid(x, y);
+#if 1
+    Feld[jx][jy] = player->artwork_element;
+#else
+    Feld[jx][jy] = EL_PLAYER_1;
+#endif
+    InitMovingField(jx, jy, MV_DOWN);
+    Store[jx][jy] = EL_ACID;
+    ContinueMoving(jx, jy);
+    BuryPlayer(player);
+
+    return MP_DONT_RUN_INTO;
+  }
+#endif
+
+#if USE_FIXED_DONT_RUN_INTO
+  if (player_can_move && DONT_RUN_INTO(element))
+  {
+    TestIfPlayerRunsIntoBadThing(jx, jy, player->MovDir);
+
+    return MP_DONT_RUN_INTO;
+  }
+#endif
+
+#else  /* ------------------------------ OLD ------------------------------ */
+
 #if 1
 #if USE_FIXED_DONT_RUN_INTO
   if (player_can_move && DONT_RUN_INTO(element))
@@ -11704,6 +11774,7 @@ int DigField(struct PlayerInfo *player,
   if (IS_PASSABLE(old_element) && !ACCESS_FROM(old_element,opposite_direction))
     return MP_NO_ACTION;       /* field has no opening in this direction */
 
+  /* checking here causes player to explode when moving into acid */
 #if 1
 #if USE_FIXED_DONT_RUN_INTO
   if (player_can_move && element == EL_ACID && move_direction == MV_DOWN)
@@ -11720,6 +11791,8 @@ int DigField(struct PlayerInfo *player,
 #endif
 #endif
 
+#endif /* ------------------------------ END ------------------------------ */
+
 #if 0
 #if USE_FIXED_DONT_RUN_INTO
   if (player_can_move && DONT_RUN_INTO(element))
@@ -11846,6 +11919,21 @@ int DigField(struct PlayerInfo *player,
       if (!player->key[EM_GATE_GRAY_ACTIVE_NR(element)])
        return MP_NO_ACTION;
     }
+    else if (IS_EMC_GATE(element))
+    {
+      if (!player->key[EMC_GATE_NR(element)])
+       return MP_NO_ACTION;
+    }
+    else if (IS_EMC_GATE_GRAY(element))
+    {
+      if (!player->key[EMC_GATE_GRAY_NR(element)])
+       return MP_NO_ACTION;
+    }
+    else if (IS_EMC_GATE_GRAY_ACTIVE(element))
+    {
+      if (!player->key[EMC_GATE_GRAY_ACTIVE_NR(element)])
+       return MP_NO_ACTION;
+    }
     else if (IS_SP_PORT(element))
     {
       if (element == EL_SP_GRAVITY_PORT_LEFT ||