rnd-20070414-1-src
[rocksndiamonds.git] / src / game.c
index 3f6ec77b97628b366a671484bc2c9f203ebc4886..f600e0462613cf1b878924af1dfccfc25802e06e 100644 (file)
 #define GAME_PANEL_ELEMENT_6                   74
 #define GAME_PANEL_ELEMENT_7                   75
 #define GAME_PANEL_ELEMENT_8                   76
-#define GAME_PANEL_CE_SCORE_1                  77
-#define GAME_PANEL_CE_SCORE_2                  78
-#define GAME_PANEL_CE_SCORE_3                  79
-#define GAME_PANEL_CE_SCORE_4                  80
-#define GAME_PANEL_CE_SCORE_5                  81
-#define GAME_PANEL_CE_SCORE_6                  82
-#define GAME_PANEL_CE_SCORE_7                  83
-#define GAME_PANEL_CE_SCORE_8                  84
-#define GAME_PANEL_CE_SCORE_1_ELEMENT          85
-#define GAME_PANEL_CE_SCORE_2_ELEMENT          86
-#define GAME_PANEL_CE_SCORE_3_ELEMENT          87
-#define GAME_PANEL_CE_SCORE_4_ELEMENT          88
-#define GAME_PANEL_CE_SCORE_5_ELEMENT          89
-#define GAME_PANEL_CE_SCORE_6_ELEMENT          90
-#define GAME_PANEL_CE_SCORE_7_ELEMENT          91
-#define GAME_PANEL_CE_SCORE_8_ELEMENT          92
-#define GAME_PANEL_PLAYER_NAME                 93
-#define GAME_PANEL_LEVEL_NAME                  94
-#define GAME_PANEL_LEVEL_AUTHOR                        95
-
-#define NUM_GAME_PANEL_CONTROLS                        96
+#define GAME_PANEL_ELEMENT_COUNT_1             77
+#define GAME_PANEL_ELEMENT_COUNT_2             78
+#define GAME_PANEL_ELEMENT_COUNT_3             79
+#define GAME_PANEL_ELEMENT_COUNT_4             80
+#define GAME_PANEL_ELEMENT_COUNT_5             81
+#define GAME_PANEL_ELEMENT_COUNT_6             82
+#define GAME_PANEL_ELEMENT_COUNT_7             83
+#define GAME_PANEL_ELEMENT_COUNT_8             84
+#define GAME_PANEL_CE_SCORE_1                  85
+#define GAME_PANEL_CE_SCORE_2                  86
+#define GAME_PANEL_CE_SCORE_3                  87
+#define GAME_PANEL_CE_SCORE_4                  88
+#define GAME_PANEL_CE_SCORE_5                  89
+#define GAME_PANEL_CE_SCORE_6                  90
+#define GAME_PANEL_CE_SCORE_7                  91
+#define GAME_PANEL_CE_SCORE_8                  92
+#define GAME_PANEL_CE_SCORE_1_ELEMENT          93
+#define GAME_PANEL_CE_SCORE_2_ELEMENT          94
+#define GAME_PANEL_CE_SCORE_3_ELEMENT          95
+#define GAME_PANEL_CE_SCORE_4_ELEMENT          96
+#define GAME_PANEL_CE_SCORE_5_ELEMENT          97
+#define GAME_PANEL_CE_SCORE_6_ELEMENT          98
+#define GAME_PANEL_CE_SCORE_7_ELEMENT          99
+#define GAME_PANEL_CE_SCORE_8_ELEMENT          100
+#define GAME_PANEL_PLAYER_NAME                 101
+#define GAME_PANEL_LEVEL_NAME                  102
+#define GAME_PANEL_LEVEL_AUTHOR                        103
+
+#define NUM_GAME_PANEL_CONTROLS                        104
 
 struct GamePanelOrderInfo
 {
@@ -638,6 +646,46 @@ static struct GamePanelControlInfo game_panel_controls[] =
     &game.panel.element[7],
     TYPE_ELEMENT,
   },
+  {
+    GAME_PANEL_ELEMENT_COUNT_1,
+    &game.panel.element_count[0],
+    TYPE_INTEGER,
+  },
+  {
+    GAME_PANEL_ELEMENT_COUNT_2,
+    &game.panel.element_count[1],
+    TYPE_INTEGER,
+  },
+  {
+    GAME_PANEL_ELEMENT_COUNT_3,
+    &game.panel.element_count[2],
+    TYPE_INTEGER,
+  },
+  {
+    GAME_PANEL_ELEMENT_COUNT_4,
+    &game.panel.element_count[3],
+    TYPE_INTEGER,
+  },
+  {
+    GAME_PANEL_ELEMENT_COUNT_5,
+    &game.panel.element_count[4],
+    TYPE_INTEGER,
+  },
+  {
+    GAME_PANEL_ELEMENT_COUNT_6,
+    &game.panel.element_count[5],
+    TYPE_INTEGER,
+  },
+  {
+    GAME_PANEL_ELEMENT_COUNT_7,
+    &game.panel.element_count[6],
+    TYPE_INTEGER,
+  },
+  {
+    GAME_PANEL_ELEMENT_COUNT_8,
+    &game.panel.element_count[7],
+    TYPE_INTEGER,
+  },
   {
     GAME_PANEL_CE_SCORE_1,
     &game.panel.ce_score[0],
@@ -2010,19 +2058,53 @@ void InitGameControlValues()
        sizeof(struct GamePanelOrderInfo), compareGamePanelOrderInfo);
 }
 
+void UpdatePlayfieldElementCount()
+{
+  int i, j, x, y;
+
+  for (i = 0; i < MAX_NUM_ELEMENTS; i++)
+    element_info[i].element_count = 0;
+
+  SCAN_PLAYFIELD(x, y)
+  {
+    element_info[Feld[x][y]].element_count++;
+  }
+
+  for (i = 0; i < NUM_GROUP_ELEMENTS; i++)
+    for (j = 0; j < MAX_NUM_ELEMENTS; j++)
+      if (IS_IN_GROUP(j, i))
+       element_info[EL_GROUP_START + i].element_count +=
+         element_info[j].element_count;
+}
+
 void UpdateGameControlValues()
 {
   int i, k;
-  int time = (level.time == 0 ? TimePlayed : TimeLeft);
-  int score = (local_player->LevelSolved ? local_player->score_final :
+  int time = (local_player->LevelSolved ?
+             local_player->LevelSolved_CountingTime :
+             level.game_engine_type == GAME_ENGINE_TYPE_EM ?
+             level.native_em_level->lev->time :
+             level.time == 0 ? TimePlayed : TimeLeft);
+  int score = (local_player->LevelSolved ?
+              local_player->LevelSolved_CountingScore :
+              level.game_engine_type == GAME_ENGINE_TYPE_EM ?
+              level.native_em_level->lev->score :
               local_player->score);
-  int exit_closed = (local_player->gems_still_needed > 0 ||
+  int gems = (level.game_engine_type == GAME_ENGINE_TYPE_EM ?
+             level.native_em_level->lev->required :
+             local_player->gems_still_needed);
+  int exit_closed = (level.game_engine_type == GAME_ENGINE_TYPE_EM ?
+                    level.native_em_level->lev->required > 0 :
+                    local_player->gems_still_needed > 0 ||
                     local_player->sokobanfields_still_needed > 0 ||
                     local_player->lights_still_needed > 0);
 
+  UpdatePlayfieldElementCount();
+
+  /* update game panel control values */
+
   game_panel_controls[GAME_PANEL_LEVEL_NUMBER].value = level_nr;
-  game_panel_controls[GAME_PANEL_GEMS].value =
-    local_player->gems_still_needed;
+  game_panel_controls[GAME_PANEL_GEMS].value = gems;
 
   game_panel_controls[GAME_PANEL_INVENTORY_COUNT].value = 0;
   for (i = 0; i < MAX_NUM_KEYS; i++)
@@ -2035,12 +2117,24 @@ void UpdateGameControlValues()
     for (i = 0; i < MAX_PLAYERS; i++)
     {
       for (k = 0; k < MAX_NUM_KEYS; k++)
-       if (stored_player[i].key[k])
+      {
+       if (level.game_engine_type == GAME_ENGINE_TYPE_EM)
+       {
+         if (level.native_em_level->ply[i]->keys & (1 << k))
+           game_panel_controls[GAME_PANEL_KEY_1 + k].value =
+             get_key_element_from_nr(k);
+       }
+       else if (stored_player[i].key[k])
          game_panel_controls[GAME_PANEL_KEY_1 + k].value =
            get_key_element_from_nr(k);
+      }
 
-      game_panel_controls[GAME_PANEL_INVENTORY_COUNT].value +=
-       stored_player[i].inventory_size;
+      if (level.game_engine_type == GAME_ENGINE_TYPE_EM)
+       game_panel_controls[GAME_PANEL_INVENTORY_COUNT].value +=
+         level.native_em_level->ply[i]->dynamite;
+      else
+       game_panel_controls[GAME_PANEL_INVENTORY_COUNT].value +=
+         stored_player[i].inventory_size;
 
       if (stored_player[i].num_white_keys > 0)
        game_panel_controls[GAME_PANEL_KEY_WHITE].value =
@@ -2055,12 +2149,24 @@ void UpdateGameControlValues()
     int player_nr = game.centered_player_nr;
 
     for (k = 0; k < MAX_NUM_KEYS; k++)
-      if (stored_player[player_nr].key[k])
+    {
+      if (level.game_engine_type == GAME_ENGINE_TYPE_EM)
+      {
+       if (level.native_em_level->ply[player_nr]->keys & (1 << k))
+         game_panel_controls[GAME_PANEL_KEY_1 + k].value =
+           get_key_element_from_nr(k);
+      }
+      else if (stored_player[player_nr].key[k])
        game_panel_controls[GAME_PANEL_KEY_1 + k].value =
          get_key_element_from_nr(k);
+    }
 
-    game_panel_controls[GAME_PANEL_INVENTORY_COUNT].value +=
-      stored_player[player_nr].inventory_size;
+    if (level.game_engine_type == GAME_ENGINE_TYPE_EM)
+      game_panel_controls[GAME_PANEL_INVENTORY_COUNT].value +=
+       level.native_em_level->ply[player_nr]->dynamite;
+    else
+      game_panel_controls[GAME_PANEL_INVENTORY_COUNT].value +=
+       stored_player[player_nr].inventory_size;
 
     if (stored_player[player_nr].num_white_keys > 0)
       game_panel_controls[GAME_PANEL_KEY_WHITE].value = EL_DC_KEY_WHITE;
@@ -2179,6 +2285,12 @@ void UpdateGameControlValues()
       (IS_DRAWABLE_ELEMENT(game.panel.element[i].id) ?
        game.panel.element[i].id : EL_UNDEFINED);
 
+  for (i = 0; i < NUM_PANEL_ELEMENTS; i++)
+    game_panel_controls[GAME_PANEL_ELEMENT_COUNT_1 + i].value =
+      (IS_VALID_ELEMENT(game.panel.element_count[i].id) ?
+       element_info[game.panel.element_count[i].id].element_count :
+       EL_UNDEFINED);
+
   for (i = 0; i < NUM_PANEL_CE_SCORE; i++)
     game_panel_controls[GAME_PANEL_CE_SCORE_1 + i].value =
       (IS_CUSTOM_ELEMENT(game.panel.ce_score[i].id) ?
@@ -2194,6 +2306,8 @@ void UpdateGameControlValues()
   game_panel_controls[GAME_PANEL_LEVEL_NAME].value = 0;
   game_panel_controls[GAME_PANEL_LEVEL_AUTHOR].value = 0;
 
+  /* update game panel control frames */
+
   for (i = 0; game_panel_controls[i].nr != -1; i++)
   {
     struct GamePanelControlInfo *gpc = &game_panel_controls[i];
@@ -3526,6 +3640,8 @@ void InitGame()
     player->LevelSolved_PanelOff = FALSE;
     player->LevelSolved_SaveTape = FALSE;
     player->LevelSolved_SaveScore = FALSE;
+    player->LevelSolved_CountingTime = 0;
+    player->LevelSolved_CountingScore = 0;
   }
 
   network_player_action_received = FALSE;
@@ -4281,6 +4397,9 @@ static void PlayerWins(struct PlayerInfo *player)
 
   player->score_final = (level.game_engine_type == GAME_ENGINE_TYPE_EM ?
                         level.native_em_level->lev->score : player->score);
+
+  player->LevelSolved_CountingTime = (level.time == 0 ? TimePlayed : TimeLeft);
+  player->LevelSolved_CountingScore = player->score_final;
 }
 
 void GameWon()
@@ -4336,6 +4455,9 @@ void GameWon()
       score = score_final;
 
 #if 1
+      local_player->LevelSolved_CountingTime = time;
+      local_player->LevelSolved_CountingScore = score;
+
       game_panel_controls[GAME_PANEL_TIME].value = time;
       game_panel_controls[GAME_PANEL_SCORE].value = score;
 
@@ -4418,6 +4540,9 @@ void GameWon()
     score += time_count_steps * level.score[SC_TIME_BONUS];
 
 #if 1
+    local_player->LevelSolved_CountingTime = time;
+    local_player->LevelSolved_CountingScore = score;
+
     game_panel_controls[GAME_PANEL_TIME].value = time;
     game_panel_controls[GAME_PANEL_SCORE].value = score;