Fixed time/badguy errors in statistics, still needs some testing
authorChristoph Sommer <mail@christoph-sommer.de>
Tue, 18 Apr 2006 02:38:49 +0000 (02:38 +0000)
committerChristoph Sommer <mail@christoph-sommer.de>
Tue, 18 Apr 2006 02:38:49 +0000 (02:38 +0000)
SVN-Revision: 3357

src/badguy/badguy.cpp
src/game_session.cpp
src/game_session.hpp
src/object/coin.cpp
src/statistics.cpp
src/statistics.hpp

index b9ae233..1f1d597 100644 (file)
@@ -214,7 +214,7 @@ BadGuy::kill_squished(Player& player)
   physic.set_velocity_y(0);
   set_state(STATE_SQUISHED);
   set_group(COLGROUP_MOVING_ONLY_STATIC);
-  Sector::current()->get_level()->stats.add_points(BADGUYS_KILLED_STAT, 1);
+  if (countMe) Sector::current()->get_level()->stats.badguys++;
   player.bounce(*this);
 }
 
@@ -222,7 +222,7 @@ void
 BadGuy::kill_fall()
 {
   sound_manager->play("sounds/fall.wav", get_pos());
-  Sector::current()->get_level()->stats.add_points(BADGUYS_KILLED_STAT, 1);
+  if (countMe) Sector::current()->get_level()->stats.badguys++;
   physic.set_velocity_y(0);
   physic.enable_gravity(true);
   set_state(STATE_FALLING);
index edac2d9..b650253 100644 (file)
@@ -83,7 +83,8 @@ GameSession::GameSession(const std::string& levelfile_, Statistics* statistics)
   : level(0), currentsector(0),
     end_sequence(NO_ENDSEQUENCE), end_sequence_controller(0),
     levelfile(levelfile_), best_level_statistics(statistics),
-    capture_demo_stream(0), playback_demo_stream(0), demo_controller(0)
+    capture_demo_stream(0), playback_demo_stream(0), demo_controller(0),
+    play_time(0)
 {
   current_ = this;
   currentsector = NULL;
@@ -115,28 +116,9 @@ GameSession::restart_level(bool fromBeginning)
 
   level.reset(new Level);
   level->load(levelfile);
-
+  level->stats.total_coins = level->get_total_coins();
+  level->stats.total_badguys = level->get_total_badguys();
   level->stats.reset();
-  level->stats.set_total_points(COINS_COLLECTED_STAT, level->get_total_coins());
-  level->stats.set_total_points(BADGUYS_KILLED_STAT, level->get_total_badguys());
-  
-  // get time
-  int time = 0;
-  for(std::vector<Sector*>::iterator i = level->sectors.begin(); i != level->sectors.end(); ++i)
-  {
-    Sector* sec = *i;
-
-    for(std::vector<GameObject*>::iterator j = sec->gameobjects.begin();
-        j != sec->gameobjects.end(); ++j)
-    {
-      GameObject* obj = *j;
-      
-      LevelTime* lt = dynamic_cast<LevelTime*> (obj);
-      if(lt)
-        time += int(lt->get_level_time());
-    }
-  }
-  level->stats.set_total_points(TIME_NEEDED_STAT, (time == 0) ? -1 : time);
 
   if (fromBeginning) reset_sector="";
   if(reset_sector != "") {
@@ -235,12 +217,10 @@ GameSession::levelintro()
       CENTER_ALLIGN, LAYER_FOREGROUND1);
 
   if((level->get_author().size()) && (level->get_author() != "SuperTux Team"))
-    //TODO make author check case/blank-insensitive
     context.draw_text(white_small_text,
       std::string(_("contributed by ")) + level->get_author(), 
       Vector(SCREEN_WIDTH/2, 350), CENTER_ALLIGN, LAYER_FOREGROUND1);
 
-
   if(best_level_statistics != NULL)
     best_level_statistics->draw_message_info(context, _("Best Level Statistics"));
 
@@ -425,8 +405,11 @@ GameSession::update(float elapsed_time)
     if (end_sequence == ENDSEQUENCE_RUNNING) {
       currentsector->update(elapsed_time/2);
     } else if(end_sequence == NO_ENDSEQUENCE) {
-      if(!currentsector->player->growing_timer.started())
+      if(!currentsector->player->growing_timer.started()) {
+       play_time += elapsed_time; //TODO: make sure we don't count cutscene time
+        level->stats.time = play_time;
         currentsector->update(elapsed_time);
+      }
     } 
   }
 
@@ -543,27 +526,6 @@ GameSession::start_sequence(const std::string& sequencename)
         lt->stop();
     }
 
-    // add time spent to statistics
-    int tottime = 0, remtime = 0;
-    for(std::vector<Sector*>::iterator i = level->sectors.begin(); i != level->sectors.end(); ++i)
-    {
-      Sector* sec = *i;
-
-      for(std::vector<GameObject*>::iterator j = sec->gameobjects.begin();
-          j != sec->gameobjects.end(); ++j)
-      {
-        GameObject* obj = *j;
-
-        LevelTime* lt = dynamic_cast<LevelTime*> (obj);
-        if(lt)
-        {
-          tottime += int(lt->get_level_time());
-          remtime += int(lt->get_remaining_time());
-        }
-      }
-    }
-    level->stats.set_points(TIME_NEEDED_STAT, (tottime == 0 ? -1 : (tottime-remtime)));
-
     if(sequencename == "fireworks") {
       currentsector->add_object(new Fireworks());
     }
index 3a216fd..b9e1ff1 100644 (file)
@@ -133,6 +133,8 @@ private:
   CodeController* demo_controller;
 
   std::auto_ptr<Menu> game_menu;
+
+  float play_time; /**< total time in seconds that this session ran interactively */
 };
 
 #endif /*SUPERTUX_GAMELOOP_H*/
index 7fbebc7..c7cf940 100644 (file)
@@ -68,7 +68,7 @@ Coin::collect()
 {
   Sector::current()->player->get_status()->add_coins(1);
   Sector::current()->add_object(new BouncyCoin(get_pos()));
-  Sector::current()->get_level()->stats.add_points(COINS_COLLECTED_STAT, 1);
+  Sector::current()->get_level()->stats.coins++;
   remove_me();
 }
 
index 4e32a1b..1642312 100644 (file)
@@ -3,6 +3,7 @@
 //  SuperTux (Statistics module)
 //  Copyright (C) 2004 Ricardo Cruz <rick2@aeiou.pt>
 //  Copyright (C) 2006 Ondrej Hosek <ondra.hosek@gmail.com>
+//  Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
 //
 //  This program is free software; you can redistribute it and/or
 //  modify it under the terms of the GNU General Public License
 #include <config.h>
 
 #include <assert.h>
+#include <math.h>
 #include "video/drawing_context.hpp"
 #include "gettext.hpp"
 #include "lisp/lisp.hpp"
 #include "resources.hpp"
 #include "main.hpp"
 #include "statistics.hpp"
+#include "log.hpp"
 
-std::string
-stat_name_to_string(int stat_enum)
-{
-  switch(stat_enum)
-    {
-//    case SCORE_STAT:
-//      return "score";
-    case COINS_COLLECTED_STAT:
-      return "coins-collected";
-    case BADGUYS_KILLED_STAT:
-      return "badguys-killed";
-    case TIME_NEEDED_STAT:
-      return "time-needed";;
-    }
-  return "";
+namespace {
+  const int nv_coins = std::numeric_limits<int>::min();
+  const int nv_badguys = std::numeric_limits<int>::min();
+  const float nv_time = std::numeric_limits<float>::max();
 }
 
-int
-my_min(int a, int b)
+Statistics::Statistics() : coins(nv_coins), total_coins(nv_coins), badguys(nv_badguys), total_badguys(nv_badguys), time(nv_time), display_stat(0)
 {
-if(a == -1)
-  return b;
-if(b == -1)
-  return a;
-return std::min(a, b);
-}
-
-Statistics::Statistics()
-{
-  display_stat = 1;
-
-  for(int i = 0; i < NUM_STATS; i++)
-    for(int j = 0; j < 2; j++)
-      stats[i][j] = -1;
 }
 
 Statistics::~Statistics()
@@ -70,19 +47,21 @@ Statistics::~Statistics()
 void
 Statistics::parse(const lisp::Lisp& reader)
 {
-  for(int i = 0; i < NUM_STATS; i++) {
-    reader.get(stat_name_to_string(i).c_str(), stats[i][SPLAYER]);
-    reader.get((stat_name_to_string(i) + "-total").c_str(), stats[i][STOTAL]);
-  }
+  reader.get("coins-collected", coins);
+  reader.get("coins-collected-total", total_coins);
+  reader.get("badguys-killed", badguys);
+  reader.get("badguys-killed-total", total_badguys);
+  reader.get("time-needed", time);
 }
 
 void
 Statistics::write(lisp::Writer& writer)
 {
-  for(int i = 0; i < NUM_STATS; i++) {
-    writer.write_int(stat_name_to_string(i), stats[i][SPLAYER]);
-    writer.write_int(stat_name_to_string(i) + "-total", stats[i][STOTAL]);
-  }
+  writer.write_int("coins-collected", coins);
+  writer.write_int("coins-collected-total", total_coins);
+  writer.write_int("badguys-killed", badguys);
+  writer.write_int("badguys-killed-total", total_badguys);
+  writer.write_float("time-needed", time);
 }
 
 //define TOTAL_DISPLAY_TIME  3400
@@ -97,37 +76,10 @@ Statistics::write(lisp::Writer& writer)
 void
 Statistics::draw_worldmap_info(DrawingContext& context)
 {
-  if(stats[COINS_COLLECTED_STAT][SPLAYER] == -1)  // not initialized yet
-    return;
-
-//  if(timer.check())
-  if (!timer.started())
-  {
-    timer.start(TOTAL_DISPLAY_TIME);
-    display_stat++;
-    if(display_stat >= NUM_STATS)
-      display_stat = 0;
-
-    if((display_stat == TIME_NEEDED_STAT) && (stats[TIME_NEEDED_STAT][STOTAL] == -1))
-    { // no timer in level
-      display_stat++;
-      if(display_stat >= NUM_STATS)
-        display_stat = 0;
-    }
-  }
+  // skip draw if level was never played
+  if (coins == nv_coins) return;
 
-  char str[128];
-
-  context.draw_text(white_small_text, _("- Best Level Statistics -"),
-                    Vector((WMAP_INFO_LEFT_X + WMAP_INFO_RIGHT_X) / 2, 470),
-                    CENTER_ALLIGN, LAYER_GUI);
-
-  // Score has been removed
-  //sprintf(str, _("Max score:"));
-  //context.draw_text(white_small_text, str, Vector(WMAP_INFO_LEFT_X, 490), LEFT_ALLIGN, LAYER_GUI);
-
-  //sprintf(str, "%d", stats[SCORE_STAT][SPLAYER]);
-  //context.draw_text(white_small_text, str, Vector(WMAP_INFO_RIGHT_X, 490), RIGHT_ALLIGN, LAYER_GUI);
+  context.draw_text(white_small_text, _("- Best Level Statistics -"), Vector((WMAP_INFO_LEFT_X + WMAP_INFO_RIGHT_X) / 2, 470), CENTER_ALLIGN, LAYER_GUI);
 
   float alpha;
   if(timer.get_timegone() < FADING_TIME)
@@ -140,76 +92,81 @@ Statistics::draw_worldmap_info(DrawingContext& context)
   context.push_transform();
   context.set_alpha(alpha);
 
-  if(display_stat == COINS_COLLECTED_STAT)
-    sprintf(str, _("Max coins collected:"));
-  else if(display_stat == BADGUYS_KILLED_STAT)
-    sprintf(str, _("Max fragging:"));
-  else// if(display_stat == TIME_NEEDED_STAT)
-    sprintf(str, _("Min time needed:"));
-
-  // y == 508 before score was removed
-  context.draw_text(white_small_text, str, Vector(WMAP_INFO_LEFT_X, 490), LEFT_ALLIGN, LAYER_GUI);
-
-  if(display_stat == COINS_COLLECTED_STAT)
-    sprintf(str, "%d/%d", stats[COINS_COLLECTED_STAT][SPLAYER],
-                          stats[COINS_COLLECTED_STAT][STOTAL]);
-  else if(display_stat == BADGUYS_KILLED_STAT)
-    sprintf(str, "%d/%d", stats[BADGUYS_KILLED_STAT][SPLAYER],
-                          stats[BADGUYS_KILLED_STAT][STOTAL]);
-  else// if(display_stat == TIME_NEEDED_STAT)
-    sprintf(str, "%d/%d", stats[TIME_NEEDED_STAT][SPLAYER],
-                          stats[TIME_NEEDED_STAT][STOTAL]);
+  char caption_buf[128];
+  char stat_buf[128];
+  switch (display_stat) 
+  {
+    case 0:
+      sprintf(caption_buf, _("Max coins collected:"));
+      sprintf(stat_buf, "%d/%d", coins, total_coins);
+      break;
+    case 1:
+      sprintf(caption_buf, _("Max fragging:"));
+      sprintf(stat_buf, "%d/%d", badguys, total_badguys);
+      break;
+    case 2:
+      sprintf(caption_buf, _("Min time needed:"));
+      {
+       int csecs = (int)(time * 100);
+       int mins = (int)(csecs / 6000);
+       int secs = (csecs % 6000) / 100;
+       sprintf(stat_buf, "%02d:%02d", mins,secs); 
+      }
+      break;
+    default:
+      log_debug << "Invalid stat requested to be drawn" << std::endl;
+      break;
+  }
 
-  context.draw_text(white_small_text, str, Vector(WMAP_INFO_RIGHT_X, 490), RIGHT_ALLIGN, LAYER_GUI);
+  if (!timer.started())
+  {
+    timer.start(TOTAL_DISPLAY_TIME);
+    display_stat++;
+    if (display_stat > 2) display_stat = 0;
+  }
 
+  context.draw_text(white_small_text, caption_buf, Vector(WMAP_INFO_LEFT_X, 490), LEFT_ALLIGN, LAYER_GUI);
+  context.draw_text(white_small_text, stat_buf, Vector(WMAP_INFO_RIGHT_X, 490), RIGHT_ALLIGN, LAYER_GUI);
   context.pop_transform();
 }
 
 void
 Statistics::draw_message_info(DrawingContext& context, std::string title)
 {
-  if(stats[COINS_COLLECTED_STAT][SPLAYER] == -1)  // not initialized yet
-    return;
+  // skip draw if level was never played
+  // TODO: do we need this?
+  if (coins == nv_coins) return;
 
   context.draw_text(gold_text, title, Vector(SCREEN_WIDTH/2, 410), CENTER_ALLIGN, LAYER_GUI);
 
   char str[128];
+  int py = 450 + 18;
 
-  //sprintf(str, _(    "Max score:             %d"), stats[SCORE_STAT][SPLAYER]);
-  //context.draw_text(white_text, str, Vector(SCREEN_WIDTH/2, 450), CENTER_ALLIGN, LAYER_GUI);
-
-  for(int i = 0; i < NUM_STATS; i++)
-    {
-    if(i == COINS_COLLECTED_STAT)
-      sprintf(str, _("Max coins collected:   %d / %d"),
-              stats[COINS_COLLECTED_STAT][SPLAYER],
-              stats[COINS_COLLECTED_STAT][STOTAL]);
-    else if(i == BADGUYS_KILLED_STAT)
-      sprintf(str, _("Max fragging:          %d / %d"),
-              stats[BADGUYS_KILLED_STAT][SPLAYER],
-              stats[BADGUYS_KILLED_STAT][STOTAL]);
-    else if((i == TIME_NEEDED_STAT) && (stats[TIME_NEEDED_STAT][STOTAL] != -1))
-      sprintf(str, _("Min time needed:       %d / %d"),
-              stats[TIME_NEEDED_STAT][SPLAYER],
-              stats[TIME_NEEDED_STAT][STOTAL]);
-    else
-      continue;
-
-
-    // y == (462 + i*18) before score removal
-    context.draw_text(white_small_text, str, Vector(SCREEN_WIDTH/2, 450 + (i+1)*18), CENTER_ALLIGN, LAYER_GUI);
-    }
+  sprintf(str, _("Max coins collected:   %d / %d"), coins, total_coins);
+  context.draw_text(white_small_text, str, Vector(SCREEN_WIDTH/2, py), CENTER_ALLIGN, LAYER_GUI); 
+  py+=18;
+
+  sprintf(str, _("Max fragging:          %d / %d"), badguys, total_badguys);
+  context.draw_text(white_small_text, str, Vector(SCREEN_WIDTH/2, py), CENTER_ALLIGN, LAYER_GUI); 
+  py+=18;
+
+  int csecs = (int)(time * 100);
+  int mins = (int)(csecs / 6000);
+  int secs = (csecs % 6000) / 100;
+  sprintf(str, _("Min time needed:       %02d:%02d"), mins,secs);
+  context.draw_text(white_small_text, str, Vector(SCREEN_WIDTH/2, py), CENTER_ALLIGN, LAYER_GUI); 
 }
 
 void 
 Statistics::draw_endseq_panel(DrawingContext& context, Statistics* best_stats, Surface* backdrop)
 {
-  // abort if statistics are not yet initialized
-  if(stats[COINS_COLLECTED_STAT][SPLAYER] == -1) return;
+  // skip draw if level was never played
+  // TODO: do we need this?
+  if (coins == nv_coins) return;
 
   // abort if we have no backdrop
   if (!backdrop) return;
-  
+
   int box_w = 130+130+130;
   int box_h = 30+20+20+20;
   int box_x = (int)((SCREEN_WIDTH - box_w) / 2);
@@ -236,86 +193,60 @@ Statistics::draw_endseq_panel(DrawingContext& context, Statistics* best_stats, S
   context.draw_text(white_text, "Best", Vector(col3_x, row1_y), LEFT_ALLIGN, LAYER_GUI);
 
   context.draw_text(white_text, "Coins", Vector(col1_x, row2_y), LEFT_ALLIGN, LAYER_GUI);
-  snprintf(buf, 128, "%d/%d", stats[COINS_COLLECTED_STAT][SPLAYER], stats[COINS_COLLECTED_STAT][STOTAL]);
+  snprintf(buf, 128, "%d/%d", coins, total_coins);
   context.draw_text(gold_text, buf, Vector(col2_x, row2_y), LEFT_ALLIGN, LAYER_GUI);
-  if (best_stats && (best_stats->stats[COINS_COLLECTED_STAT][SPLAYER] > stats[COINS_COLLECTED_STAT][SPLAYER])) {
-    snprintf(buf, 128, "%d/%d", best_stats->stats[COINS_COLLECTED_STAT][SPLAYER], best_stats->stats[COINS_COLLECTED_STAT][STOTAL]);
+  if (best_stats && (best_stats->coins > coins)) {
+    snprintf(buf, 128, "%d/%d", best_stats->coins, best_stats->total_coins);
   }
   context.draw_text(gold_text, buf, Vector(col3_x, row2_y), LEFT_ALLIGN, LAYER_GUI);
 
-  context.draw_text(white_text, "Time", Vector(col1_x, row3_y), LEFT_ALLIGN, LAYER_GUI);
-  snprintf(buf, 128, "%d:%02d", stats[TIME_NEEDED_STAT][SPLAYER] / 60, stats[TIME_NEEDED_STAT][SPLAYER] % 60);
-  context.draw_text(gold_text, buf, Vector(col2_x, row3_y), LEFT_ALLIGN, LAYER_GUI);
-  if (best_stats && (best_stats->stats[TIME_NEEDED_STAT][SPLAYER] < stats[TIME_NEEDED_STAT][SPLAYER])) {
-    snprintf(buf, 128, "%d:%02d", best_stats->stats[TIME_NEEDED_STAT][SPLAYER] / 60, best_stats->stats[TIME_NEEDED_STAT][SPLAYER] % 60);
-  }
-  context.draw_text(gold_text, buf, Vector(col3_x, row3_y), LEFT_ALLIGN, LAYER_GUI);
-  
   context.draw_text(white_text, "Badguys", Vector(col1_x, row4_y), LEFT_ALLIGN, LAYER_GUI);
-  snprintf(buf, 128, "%d/%d", stats[BADGUYS_KILLED_STAT][SPLAYER], stats[BADGUYS_KILLED_STAT][STOTAL]);
+  snprintf(buf, 128, "%d/%d", badguys, total_badguys);
   context.draw_text(gold_text, buf, Vector(col2_x, row4_y), LEFT_ALLIGN, LAYER_GUI);
-  if (best_stats && (best_stats->stats[BADGUYS_KILLED_STAT][SPLAYER] > stats[BADGUYS_KILLED_STAT][SPLAYER])) {
-    snprintf(buf, 128, "%d/%d", best_stats->stats[BADGUYS_KILLED_STAT][SPLAYER], best_stats->stats[BADGUYS_KILLED_STAT][STOTAL]);
+  if (best_stats && (best_stats->badguys > badguys)) {
+    snprintf(buf, 128, "%d/%d", best_stats->badguys, best_stats->total_badguys);
   }
   context.draw_text(gold_text, buf, Vector(col3_x, row4_y), LEFT_ALLIGN, LAYER_GUI);
 
-}
-
-void
-Statistics::add_points(int stat, int points)
-{
-  stats[stat][SPLAYER] += points;
-}
-
-int
-Statistics::get_points(int stat)
-{
-  return stats[stat][SPLAYER];
-}
-
-void
-Statistics::set_points(int stat, int points)
-{
-  stats[stat][SPLAYER] = points;
-}
-
-void
-Statistics::set_total_points(int stat, int points)
-{
-  stats[stat][STOTAL] = points;
+  context.draw_text(white_text, "Time", Vector(col1_x, row3_y), LEFT_ALLIGN, LAYER_GUI);
+  int csecs = (int)(time * 100);
+  int mins = (int)(csecs / 6000);
+  int secs = (csecs % 6000) / 100;
+  snprintf(buf, 128, "%02d:%02d", mins,secs);
+  context.draw_text(gold_text, buf, Vector(col2_x, row3_y), LEFT_ALLIGN, LAYER_GUI);
+  if (best_stats && (best_stats->time < time)) {
+    int csecs = (int)(best_stats->time * 100);
+    int mins = (int)(csecs / 6000);
+    int secs = (csecs % 6000) / 100;
+    snprintf(buf, 128, "%02d:%02d", mins,secs);
+  }
+  context.draw_text(gold_text, buf, Vector(col3_x, row3_y), LEFT_ALLIGN, LAYER_GUI);
 }
 
 void
 Statistics::reset()
 {
-  for(int i = 0; i < NUM_STATS; i++)
-    stats[i][SPLAYER] = 0;
+  coins = 0; 
+  badguys = 0; 
+  time = 0; 
 }
 
 void
-Statistics::merge(Statistics& stats_)
+Statistics::merge(Statistics& s2)
 {
-//  stats[SCORE_STAT][SPLAYER] = std::max(stats[SCORE_STAT][SPLAYER], stats_.stats[SCORE_STAT][SPLAYER]);
-  stats[COINS_COLLECTED_STAT][SPLAYER] = std::max(stats[COINS_COLLECTED_STAT][SPLAYER], stats_.stats[COINS_COLLECTED_STAT][SPLAYER]);
-  stats[BADGUYS_KILLED_STAT][SPLAYER] =
-    std::max(stats[BADGUYS_KILLED_STAT][SPLAYER], stats_.stats[BADGUYS_KILLED_STAT][SPLAYER]);
-  stats[TIME_NEEDED_STAT][SPLAYER] =
-    my_min(stats[TIME_NEEDED_STAT][SPLAYER], stats_.stats[TIME_NEEDED_STAT][SPLAYER]);
-
-  stats[COINS_COLLECTED_STAT][STOTAL] = stats_.stats[COINS_COLLECTED_STAT][STOTAL];
-  stats[BADGUYS_KILLED_STAT][STOTAL] = stats_.stats[BADGUYS_KILLED_STAT][STOTAL];
-  stats[TIME_NEEDED_STAT][STOTAL] = stats_.stats[TIME_NEEDED_STAT][STOTAL];
+  coins = std::max(coins, s2.coins);
+  total_coins = s2.total_coins;
+  badguys = std::max(badguys, s2.badguys);
+  total_badguys = s2.total_badguys;
+  time = std::min(time, s2.time);
 }
 
 void
-Statistics::operator+=(const Statistics& stats_)
+Statistics::operator+=(const Statistics& s2)
 {
-  for(int i = 0; i < NUM_STATS; i++)
-    {
-    if(stats_.stats[i][SPLAYER] == -1)
-      continue;
-    stats[i][SPLAYER] += stats_.stats[i][SPLAYER];
-    if(stats_.stats[i][STOTAL] != -1)
-      stats[i][STOTAL] += stats_.stats[i][STOTAL];
-    }
+  if (s2.coins != nv_coins) coins += s2.coins;
+  if (s2.total_coins != nv_coins) total_coins += s2.total_coins;
+  if (s2.badguys != nv_badguys) badguys += s2.badguys;
+  if (s2.total_badguys != nv_badguys) total_badguys += s2.total_badguys;
+  if (s2.time != nv_time) time += s2.time;
 }
index 47c9e6c..d2655eb 100644 (file)
@@ -3,6 +3,7 @@
 //  SuperTux (Statistics module)
 //  Copyright (C) 2004 Ricardo Cruz <rick2@aeiou.pt>
 //  Copyright (C) 2006 Ondrej Hosek <ondra.hosek@gmail.com>
+//  Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
 //
 //  This program is free software; you can redistribute it and/or
 //  modify it under the terms of the GNU General Public License
 #include "video/surface.hpp"
 #include "video/drawing_context.hpp"
 
-#define SPLAYER 0
-#define STOTAL  1
-
-enum {
-//  SCORE_STAT,
-  COINS_COLLECTED_STAT,
-  BADGUYS_KILLED_STAT,
-  TIME_NEEDED_STAT,
-  NUM_STATS
-};
-
 /** This class is a layer between level and worldmap to keep
  *  track of stuff like scores, and minor, but funny things, like
  *  number of jumps and stuff */
-
 class Statistics
-{
+{ 
+public:
+  int coins; /**< coins collected */
+  int total_coins; /**< coins in level */
+  int badguys; /**< badguys actively killed */
+  int total_badguys; /**< (vincible) badguys in level */
+  float time; /**< seconds needed */
+
 public:
-  // don't forget to call reset() to init stat
-  Statistics();
+  Statistics(); /**< Creates new statistics, call reset() before counting */
   ~Statistics();
 
   /// read statistics from lisp file
@@ -54,33 +49,17 @@ public:
   /// write statistics to lisp file
   void write(lisp::Writer& writer);
 
-  /* Draw to the worldmap or a game message */
-  // TODO: make this functions working
-  void draw_worldmap_info(DrawingContext& context);
-  void draw_message_info(DrawingContext& context, std::string title);
+  void draw_worldmap_info(DrawingContext& context); /**< draw worldmap stat HUD */
+  void draw_message_info(DrawingContext& context, std::string title); /**< draw stats at level start */
   void draw_endseq_panel(DrawingContext& context, Statistics* best_stats, Surface* backdrop); /**< draw panel shown during level's end sequence */
 
-  /* Add / Set / Get points to/from one of the stats this can keep track of */
-  void add_points(int stat, int points);
-  void set_points(int stat, int points);
-  int get_points(int stat);
-
-  void set_total_points(int stat, int points);
-
-  /* Reset statistics */
-  void reset();
-
-  /* Give another Statistics object, find the best of each one */
-  void merge(Statistics& stats);
-
-  /* Add two statistic objects */
-  void operator+=(const Statistics& o);
+  void reset(); /**< Set stats (but not totals) to zero */
+  void merge(Statistics& stats); /**< Given another Statistics object finds the best of each one */
+  void operator+=(const Statistics& o); /**< Add two Statistics objects */
 
 private:
-  int stats[NUM_STATS][2];
-
-  Timer timer;
-  int display_stat;
+  Timer timer; /**< for draw_worldmap_info: time until switching to next stat */
+  int display_stat; /**< for draw_worldmap_info: which stat is currently displayed */
 };
 
 #endif /*SUPERTUX_STATISTICS_H*/