00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "supertux/statistics.hpp"
00020
00021 #include <iomanip>
00022 #include <limits>
00023
00024 #include "scripting/squirrel_util.hpp"
00025 #include "supertux/globals.hpp"
00026 #include "supertux/resources.hpp"
00027 #include "util/gettext.hpp"
00028 #include "video/drawing_context.hpp"
00029
00030 namespace {
00031 const int nv_coins = std::numeric_limits<int>::min();
00032 const int nv_badguys = std::numeric_limits<int>::min();
00033 const float nv_time = std::numeric_limits<float>::max();
00034 const int nv_secrets = std::numeric_limits<int>::min();
00035 }
00036
00037 float WMAP_INFO_LEFT_X;
00038 float WMAP_INFO_RIGHT_X;
00039 float WMAP_INFO_TOP_Y1;
00040 float WMAP_INFO_TOP_Y2;
00041
00042 Statistics::Statistics() :
00043 coins(nv_coins),
00044 total_coins(nv_coins),
00045 badguys(nv_badguys),
00046 total_badguys(nv_badguys),
00047 time(nv_time),
00048 secrets(nv_secrets),
00049 total_secrets(nv_secrets),
00050 valid(true)
00051 {
00052 WMAP_INFO_LEFT_X = (SCREEN_WIDTH/2 + 80) + 32;
00053 WMAP_INFO_RIGHT_X = SCREEN_WIDTH/2 + 368;
00054 WMAP_INFO_TOP_Y1 = SCREEN_HEIGHT/2 + 172 - 16;
00055 WMAP_INFO_TOP_Y2 = SCREEN_HEIGHT/2 + 172;
00056 }
00057
00058 Statistics::~Statistics()
00059 {
00060 }
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088 void
00089 Statistics::serialize_to_squirrel(HSQUIRRELVM vm)
00090 {
00091
00092 if (!((coins != nv_coins) || (total_coins != nv_coins) || (badguys != nv_badguys) || (total_badguys != nv_badguys) || (time != nv_time) || (secrets != nv_secrets) || (total_secrets != nv_secrets))) return;
00093
00094 sq_pushstring(vm, "statistics", -1);
00095 sq_newtable(vm);
00096 if (coins != nv_coins) scripting::store_int(vm, "coins-collected", coins);
00097 if (total_coins != nv_coins) scripting::store_int(vm, "coins-collected-total", total_coins);
00098 if (badguys != nv_badguys) scripting::store_int(vm, "badguys-killed", badguys);
00099 if (total_badguys != nv_badguys) scripting::store_int(vm, "badguys-killed-total", total_badguys);
00100 if (time != nv_time) scripting::store_float(vm, "time-needed", time);
00101 if (secrets != nv_secrets) scripting::store_int(vm, "secrets-found", secrets);
00102 if (total_secrets != nv_secrets) scripting::store_int(vm, "secrets-found-total", total_secrets);
00103 sq_createslot(vm, -3);
00104 }
00105
00106 void
00107 Statistics::unserialize_from_squirrel(HSQUIRRELVM vm)
00108 {
00109 sq_pushstring(vm, "statistics", -1);
00110 if(SQ_FAILED(sq_get(vm, -2))) {
00111 return;
00112 }
00113 scripting::get_int(vm, "coins-collected", coins);
00114 scripting::get_int(vm, "coins-collected-total", total_coins);
00115 scripting::get_int(vm, "badguys-killed", badguys);
00116 scripting::get_int(vm, "badguys-killed-total", total_badguys);
00117 scripting::get_float(vm, "time-needed", time);
00118 scripting::get_int(vm, "secrets-found", secrets);
00119 scripting::get_int(vm, "secrets-found-total", total_secrets);
00120 sq_pop(vm, 1);
00121 }
00122
00123 void
00124 Statistics::draw_worldmap_info(DrawingContext& context)
00125 {
00126
00127 if (coins == nv_coins) return;
00128
00129
00130 if (!valid) return;
00131
00132 context.draw_text(Resources::small_font, std::string("- ") + _("Best Level Statistics") + " -",
00133 Vector((WMAP_INFO_LEFT_X + WMAP_INFO_RIGHT_X) / 2, WMAP_INFO_TOP_Y1),
00134 ALIGN_CENTER, LAYER_HUD,Statistics::header_color);
00135
00136 std::string caption_buf;
00137 std::string stat_buf;
00138 float posy = WMAP_INFO_TOP_Y2;
00139 for (int stat_no = 0; stat_no < 4; stat_no++) {
00140 switch (stat_no)
00141 {
00142 case 0:
00143 caption_buf = _("Max coins collected:");
00144 stat_buf = coins_to_string(coins, total_coins);
00145 break;
00146 case 1:
00147 caption_buf = _("Max fragging:");
00148 stat_buf = frags_to_string(badguys, total_badguys);
00149 break;
00150 case 2:
00151 caption_buf = _("Min time needed:");
00152 stat_buf = time_to_string(time);
00153 break;
00154 case 3:
00155 caption_buf = _("Max secrets found:");
00156 stat_buf = secrets_to_string(secrets, total_secrets);
00157 break;
00158 default:
00159 log_debug << "Invalid stat requested to be drawn" << std::endl;
00160 break;
00161 }
00162
00163 context.draw_text(Resources::small_font, caption_buf, Vector(WMAP_INFO_LEFT_X, posy), ALIGN_LEFT, LAYER_HUD, Statistics::header_color);
00164 context.draw_text(Resources::small_font, stat_buf, Vector(WMAP_INFO_RIGHT_X, posy), ALIGN_RIGHT, LAYER_HUD, Statistics::header_color);
00165 posy += Resources::small_font->get_height() + 2;
00166 }
00167
00168 }
00169
00170 void
00171 Statistics::draw_endseq_panel(DrawingContext& context, Statistics* best_stats, SurfacePtr backdrop)
00172 {
00173
00174
00175 if (coins == nv_coins) return;
00176
00177
00178 if (!valid) return;
00179
00180
00181 if (!backdrop) return;
00182
00183 int box_w = 220+110+110;
00184 int box_h = 30+20+20+20;
00185 int box_x = (int)((SCREEN_WIDTH - box_w) / 2);
00186 int box_y = (int)(SCREEN_HEIGHT / 2) - box_h;
00187
00188 int bd_w = (int)backdrop->get_width();
00189 int bd_h = (int)backdrop->get_height();
00190 int bd_x = (int)((SCREEN_WIDTH - bd_w) / 2);
00191 int bd_y = box_y + (box_h / 2) - (bd_h / 2);
00192
00193 int col1_x = box_x;
00194 int col2_x = col1_x+200;
00195 int col3_x = col2_x+130;
00196
00197 int row1_y = box_y;
00198 int row2_y = row1_y+30;
00199 int row3_y = row2_y+20;
00200 int row4_y = row3_y+20;
00201
00202 context.push_transform();
00203 context.set_alpha(0.5);
00204 context.draw_surface(backdrop, Vector(bd_x, bd_y), LAYER_HUD);
00205 context.pop_transform();
00206
00207 context.draw_text(Resources::normal_font, _("You"), Vector(col2_x, row1_y), ALIGN_LEFT, LAYER_HUD, Statistics::header_color);
00208 if (best_stats)
00209 context.draw_text(Resources::normal_font, _("Best"), Vector(col3_x, row1_y), ALIGN_LEFT, LAYER_HUD, Statistics::header_color);
00210
00211 context.draw_text(Resources::normal_font, _("Coins"), Vector(col2_x-16, row3_y), ALIGN_RIGHT, LAYER_HUD, Statistics::header_color);
00212 context.draw_text(Resources::normal_font, coins_to_string(coins, total_coins), Vector(col2_x, row3_y), ALIGN_LEFT, LAYER_HUD, Statistics::text_color);
00213 if (best_stats) {
00214 int coins_best = (best_stats->coins > coins) ? best_stats->coins : coins;
00215 int total_coins_best = (best_stats->total_coins > total_coins) ? best_stats->total_coins : total_coins;
00216 context.draw_text(Resources::normal_font, coins_to_string(coins_best, total_coins_best), Vector(col3_x, row3_y), ALIGN_LEFT, LAYER_HUD, Statistics::text_color);
00217 }
00218
00219 context.draw_text(Resources::normal_font, _("Secrets"), Vector(col2_x-16, row4_y), ALIGN_RIGHT, LAYER_HUD, Statistics::header_color);
00220 context.draw_text(Resources::normal_font, secrets_to_string(secrets, total_secrets), Vector(col2_x, row4_y), ALIGN_LEFT, LAYER_HUD, Statistics::text_color);
00221 if (best_stats) {
00222 int secrets_best = (best_stats->secrets > secrets) ? best_stats->secrets : secrets;
00223 int total_secrets_best = (best_stats->total_secrets > total_secrets) ? best_stats->total_secrets : total_secrets;
00224 context.draw_text(Resources::normal_font, secrets_to_string(secrets_best, total_secrets_best), Vector(col3_x, row4_y), ALIGN_LEFT, LAYER_HUD, Statistics::text_color);
00225 }
00226
00227 context.draw_text(Resources::normal_font, _("Time"), Vector(col2_x-16, row2_y), ALIGN_RIGHT, LAYER_HUD, Statistics::header_color);
00228 context.draw_text(Resources::normal_font, time_to_string(time), Vector(col2_x, row2_y), ALIGN_LEFT, LAYER_HUD, Statistics::text_color);
00229 if (best_stats) {
00230 float time_best = (best_stats->time < time) ? best_stats->time : time;
00231 context.draw_text(Resources::normal_font, time_to_string(time_best), Vector(col3_x, row2_y), ALIGN_LEFT, LAYER_HUD, Statistics::text_color);
00232 }
00233 }
00234
00235 void
00236 Statistics::zero()
00237 {
00238 reset();
00239 total_coins = 0;
00240 total_badguys = 0;
00241 total_secrets = 0;
00242 }
00243
00244 void
00245 Statistics::reset()
00246 {
00247 coins = 0;
00248 badguys = 0;
00249 time = 0;
00250 secrets = 0;
00251 }
00252
00253 void
00254 Statistics::merge(const Statistics& s2)
00255 {
00256 if (!s2.valid) return;
00257 coins = std::max(coins, s2.coins);
00258 total_coins = s2.total_coins;
00259 badguys = std::max(badguys, s2.badguys);
00260 total_badguys = s2.total_badguys;
00261 time = std::min(time, s2.time);
00262 secrets = std::max(secrets, s2.secrets);
00263 total_secrets = s2.total_secrets;
00264 }
00265
00266 void
00267 Statistics::operator+=(const Statistics& s2)
00268 {
00269 if (!s2.valid) return;
00270 if (s2.coins != nv_coins) coins += s2.coins;
00271 if (s2.total_coins != nv_coins) total_coins += s2.total_coins;
00272 if (s2.badguys != nv_badguys) badguys += s2.badguys;
00273 if (s2.total_badguys != nv_badguys) total_badguys += s2.total_badguys;
00274 if (s2.time != nv_time) time += s2.time;
00275 if (s2.secrets != nv_secrets) secrets += s2.secrets;
00276 if (s2.total_secrets != nv_secrets) total_secrets += s2.total_secrets;
00277 }
00278
00279 void
00280 Statistics::declare_invalid()
00281 {
00282 valid = false;
00283 }
00284
00285 std::string
00286 Statistics::coins_to_string(int coins, int total_coins) {
00287 std::ostringstream os;
00288 os << std::min(coins, 999) << "/" << std::min(total_coins, 999);
00289 return os.str();
00290 }
00291
00292 std::string
00293 Statistics::frags_to_string(int badguys, int total_badguys) {
00294 std::ostringstream os;
00295 os << std::min(badguys, 999) << "/" << std::min(total_badguys, 999);
00296 return os.str();
00297 }
00298
00299 std::string
00300 Statistics::time_to_string(float time) {
00301 int time_csecs = std::min(static_cast<int>(time * 100), 99 * 6000 + 9999);
00302 int mins = (time_csecs / 6000);
00303 int secs = (time_csecs % 6000) / 100;
00304 int cscs = (time_csecs % 6000) % 100;
00305
00306 std::ostringstream os;
00307 os << std::setw(2) << std::setfill('0') << mins << ":" << std::setw(2) << std::setfill('0') << secs << "." << std::setw(2) << std::setfill('0') << cscs;
00308 return os.str();
00309 }
00310
00311 std::string
00312 Statistics::secrets_to_string(int secrets, int total_secrets) {
00313 std::ostringstream os;
00314 os << std::min(secrets, 999) << "/" << std::min(total_secrets, 999);
00315 return os.str();
00316 }
00317
00318