#include <limits>
#include "scripting/squirrel_util.hpp"
-#include "supertux/main.hpp"
+#include "supertux/globals.hpp"
#include "supertux/resources.hpp"
#include "util/gettext.hpp"
#include "video/drawing_context.hpp"
float WMAP_INFO_TOP_Y1;
float WMAP_INFO_TOP_Y2;
-Statistics::Statistics() :
- coins(nv_coins),
- total_coins(nv_coins),
- badguys(nv_badguys),
- total_badguys(nv_badguys),
- time(nv_time),
- secrets(nv_secrets),
- total_secrets(nv_secrets),
- valid(true)
+Statistics::Statistics() :
+ coins(nv_coins),
+ total_coins(nv_coins),
+ badguys(nv_badguys),
+ total_badguys(nv_badguys),
+ time(nv_time),
+ secrets(nv_secrets),
+ total_secrets(nv_secrets),
+ valid(true)
{
- WMAP_INFO_LEFT_X = (SCREEN_WIDTH/2 + 80) + 32;
- WMAP_INFO_RIGHT_X = SCREEN_WIDTH/2 + 368;
- WMAP_INFO_TOP_Y1 = SCREEN_HEIGHT/2 + 172 - 16;
- WMAP_INFO_TOP_Y2 = SCREEN_HEIGHT/2 + 172;
+ WMAP_INFO_LEFT_X = SCREEN_WIDTH - 32 - 256;
+ WMAP_INFO_RIGHT_X = WMAP_INFO_LEFT_X + 256;
+ WMAP_INFO_TOP_Y1 = SCREEN_HEIGHT - 100;
+ WMAP_INFO_TOP_Y2 = WMAP_INFO_TOP_Y1 + 16;
}
Statistics::~Statistics()
{
}
-/*
- void
- Statistics::parse(const Reader& reader)
- {
- 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);
- reader.get("secrets-found", secrets);
- reader.get("secrets-found-total", total_secrets);
- }
-
- void
- Statistics::write(lisp::Writer& writer)
- {
- writer.write("coins-collected", coins);
- writer.write("coins-collected-total", total_coins);
- writer.write("badguys-killed", badguys);
- writer.write("badguys-killed-total", total_badguys);
- writer.write("time-needed", time);
- writer.write("secrets-found", secrets);
- writer.write("secrets-found-total", total_secrets);
- }
-*/
-
void
Statistics::serialize_to_squirrel(HSQUIRRELVM vm)
{
sq_pushstring(vm, "statistics", -1);
sq_newtable(vm);
- if (coins != nv_coins) Scripting::store_int(vm, "coins-collected", coins);
- if (total_coins != nv_coins) Scripting::store_int(vm, "coins-collected-total", total_coins);
- if (badguys != nv_badguys) Scripting::store_int(vm, "badguys-killed", badguys);
- if (total_badguys != nv_badguys) Scripting::store_int(vm, "badguys-killed-total", total_badguys);
- if (time != nv_time) Scripting::store_float(vm, "time-needed", time);
- if (secrets != nv_secrets) Scripting::store_int(vm, "secrets-found", secrets);
- if (total_secrets != nv_secrets) Scripting::store_int(vm, "secrets-found-total", total_secrets);
- sq_createslot(vm, -3);
+ if (coins != nv_coins) scripting::store_int(vm, "coins-collected", coins);
+ if (total_coins != nv_coins) scripting::store_int(vm, "coins-collected-total", total_coins);
+ if (badguys != nv_badguys) scripting::store_int(vm, "badguys-killed", badguys);
+ if (total_badguys != nv_badguys) scripting::store_int(vm, "badguys-killed-total", total_badguys);
+ if (time != nv_time) scripting::store_float(vm, "time-needed", time);
+ if (secrets != nv_secrets) scripting::store_int(vm, "secrets-found", secrets);
+ if (total_secrets != nv_secrets) scripting::store_int(vm, "secrets-found-total", total_secrets);
+ if(SQ_FAILED(sq_createslot(vm, -3)))
+ throw scripting::SquirrelError(vm, "Couldn't create statistics table");
}
void
if(SQ_FAILED(sq_get(vm, -2))) {
return;
}
- Scripting::get_int(vm, "coins-collected", coins);
- Scripting::get_int(vm, "coins-collected-total", total_coins);
- Scripting::get_int(vm, "badguys-killed", badguys);
- Scripting::get_int(vm, "badguys-killed-total", total_badguys);
- Scripting::get_float(vm, "time-needed", time);
- Scripting::get_int(vm, "secrets-found", secrets);
- Scripting::get_int(vm, "secrets-found-total", total_secrets);
+ scripting::get_int(vm, "coins-collected", coins);
+ scripting::get_int(vm, "coins-collected-total", total_coins);
+ scripting::get_int(vm, "badguys-killed", badguys);
+ scripting::get_int(vm, "badguys-killed-total", total_badguys);
+ scripting::get_float(vm, "time-needed", time);
+ scripting::get_int(vm, "secrets-found", secrets);
+ scripting::get_int(vm, "secrets-found-total", total_secrets);
sq_pop(vm, 1);
}
void
-Statistics::draw_worldmap_info(DrawingContext& context)
+Statistics::draw_worldmap_info(DrawingContext& context, float target_time)
{
// skip draw if level was never played
if (coins == nv_coins) return;
// skip draw if stats were declared invalid
if (!valid) return;
- context.draw_text(small_font, std::string("- ") + _("Best Level Statistics") + " -", Vector((WMAP_INFO_LEFT_X + WMAP_INFO_RIGHT_X) / 2, WMAP_INFO_TOP_Y1), ALIGN_CENTER, LAYER_GUI,Statistics::header_color);
+ // no sense drawing stats if there are none
+ if (total_coins + total_badguys + total_secrets == 0) return;
+
+ // check to see if screen size has been changed
+ if (!(WMAP_INFO_TOP_Y1 == SCREEN_HEIGHT - 100)) {
+ WMAP_INFO_LEFT_X = SCREEN_WIDTH - 32 - 256;
+ WMAP_INFO_RIGHT_X = WMAP_INFO_LEFT_X + 256;
+ WMAP_INFO_TOP_Y1 = SCREEN_HEIGHT - 100;
+ WMAP_INFO_TOP_Y2 = WMAP_INFO_TOP_Y1 + 16;
+ }
+
+ context.draw_text(Resources::small_font, std::string("- ") + _("Best Level Statistics") + " -",
+ Vector((WMAP_INFO_LEFT_X + WMAP_INFO_RIGHT_X) / 2, WMAP_INFO_TOP_Y1),
+ ALIGN_CENTER, LAYER_HUD,Statistics::header_color);
std::string caption_buf;
std::string stat_buf;
float posy = WMAP_INFO_TOP_Y2;
- for (int stat_no = 0; stat_no < 4; stat_no++) {
+ for (int stat_no = 0; stat_no < 5; stat_no++) {
switch (stat_no)
{
case 0:
stat_buf = frags_to_string(badguys, total_badguys);
break;
case 2:
- caption_buf = _("Min time needed:");
- stat_buf = time_to_string(time);
- break;
- case 3:
caption_buf = _("Max secrets found:");
stat_buf = secrets_to_string(secrets, total_secrets);
break;
+ case 3:
+ caption_buf = _("Best time completed:");
+ stat_buf = time_to_string(time);
+ break;
+ case 4:
+ if(target_time){ // display target time only if defined for level
+ caption_buf = _("Level target time:");
+ stat_buf = time_to_string(target_time);
+ } else {
+ caption_buf = "";
+ stat_buf = "";
+ }
+ break;
default:
log_debug << "Invalid stat requested to be drawn" << std::endl;
break;
}
- context.draw_text(small_font, caption_buf, Vector(WMAP_INFO_LEFT_X, posy), ALIGN_LEFT, LAYER_GUI, Statistics::header_color);
- context.draw_text(small_font, stat_buf, Vector(WMAP_INFO_RIGHT_X, posy), ALIGN_RIGHT, LAYER_GUI, Statistics::header_color);
- posy += small_font->get_height() + 2;
+ context.draw_text(Resources::small_font, caption_buf, Vector(WMAP_INFO_LEFT_X, posy), ALIGN_LEFT, LAYER_HUD, Statistics::header_color);
+ context.draw_text(Resources::small_font, stat_buf, Vector(WMAP_INFO_RIGHT_X, posy), ALIGN_RIGHT, LAYER_HUD, Statistics::header_color);
+ posy += Resources::small_font->get_height() + 2;
}
}
void
-Statistics::draw_endseq_panel(DrawingContext& context, Statistics* best_stats, Surface* backdrop)
+Statistics::draw_endseq_panel(DrawingContext& context, Statistics* best_stats, SurfacePtr backdrop)
{
- // skip draw if level was never played
- // TODO: do we need this?
- if (coins == nv_coins) return;
-
// skip draw if stats were declared invalid
if (!valid) return;
// abort if we have no backdrop
if (!backdrop) return;
+ // no sense drawing stats if there are none
+ if (total_coins + total_badguys + total_secrets == 0) return;
+
int box_w = 220+110+110;
int box_h = 30+20+20+20;
int box_x = (int)((SCREEN_WIDTH - box_w) / 2);
int row2_y = row1_y+30;
int row3_y = row2_y+20;
int row4_y = row3_y+20;
+ int row5_y = row4_y+20;
context.push_transform();
context.set_alpha(0.5);
- context.draw_surface(backdrop, Vector(bd_x, bd_y), LAYER_GUI);
+ context.draw_surface(backdrop, Vector(bd_x, bd_y), LAYER_HUD);
context.pop_transform();
- context.draw_text(normal_font, _("You"), Vector(col2_x, row1_y), ALIGN_LEFT, LAYER_GUI, Statistics::header_color);
- context.draw_text(normal_font, _("Best"), Vector(col3_x, row1_y), ALIGN_LEFT, LAYER_GUI, Statistics::header_color);
-
- context.draw_text(normal_font, _("Coins"), Vector(col2_x-16, row3_y), ALIGN_RIGHT, LAYER_GUI, Statistics::header_color);
- int coins_best = (best_stats && (best_stats->coins > coins)) ? best_stats->coins : coins;
- int total_coins_best = (best_stats && (best_stats->total_coins > total_coins)) ? best_stats->total_coins : total_coins;
- context.draw_text(normal_font, coins_to_string(coins, total_coins), Vector(col2_x, row3_y), ALIGN_LEFT, LAYER_GUI, Statistics::text_color);
- context.draw_text(normal_font, coins_to_string(coins_best, total_coins_best), Vector(col3_x, row3_y), ALIGN_LEFT, LAYER_GUI, Statistics::text_color);
-
- context.draw_text(normal_font, _("Secrets"), Vector(col2_x-16, row4_y), ALIGN_RIGHT, LAYER_GUI, Statistics::header_color);
- int secrets_best = (best_stats && (best_stats->secrets > secrets)) ? best_stats->secrets : secrets;
- int total_secrets_best = (best_stats && (best_stats->total_secrets > total_secrets)) ? best_stats->total_secrets : total_secrets;
- context.draw_text(normal_font, secrets_to_string(secrets, total_secrets), Vector(col2_x, row4_y), ALIGN_LEFT, LAYER_GUI, Statistics::text_color);
- context.draw_text(normal_font, secrets_to_string(secrets_best, total_secrets_best), Vector(col3_x, row4_y), ALIGN_LEFT, LAYER_GUI, Statistics::text_color);
-
- context.draw_text(normal_font, _("Time"), Vector(col2_x-16, row2_y), ALIGN_RIGHT, LAYER_GUI, Statistics::header_color);
- float time_best = (best_stats && (best_stats->time < time)) ? best_stats->time : time;
- context.draw_text(normal_font, time_to_string(time), Vector(col2_x, row2_y), ALIGN_LEFT, LAYER_GUI, Statistics::text_color);
- context.draw_text(normal_font, time_to_string(time_best), Vector(col3_x, row2_y), ALIGN_LEFT, LAYER_GUI, Statistics::text_color);
+ context.draw_text(Resources::normal_font, _("You"), Vector(col2_x, row1_y), ALIGN_LEFT, LAYER_HUD, Statistics::header_color);
+ if (best_stats)
+ context.draw_text(Resources::normal_font, _("Best"), Vector(col3_x, row1_y), ALIGN_LEFT, LAYER_HUD, Statistics::header_color);
+
+ context.draw_text(Resources::normal_font, _("Coins"), Vector(col2_x-16, row3_y), ALIGN_RIGHT, LAYER_HUD, Statistics::header_color);
+ context.draw_text(Resources::normal_font, coins_to_string(coins, total_coins), Vector(col2_x, row3_y), ALIGN_LEFT, LAYER_HUD, Statistics::text_color);
+ if (best_stats) {
+ int coins_best = (best_stats->coins > coins) ? best_stats->coins : coins;
+ int total_coins_best = (best_stats->total_coins > total_coins) ? best_stats->total_coins : total_coins;
+ 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);
+ }
+
+ context.draw_text(Resources::normal_font, _("Badguys"), Vector(col2_x-16, row4_y), ALIGN_RIGHT, LAYER_HUD, Statistics::header_color);
+ context.draw_text(Resources::normal_font, frags_to_string(badguys, total_badguys), Vector(col2_x, row4_y), ALIGN_LEFT, LAYER_HUD, Statistics::text_color);
+ if (best_stats) {
+ int badguys_best = (best_stats->badguys > badguys) ? best_stats->badguys : badguys;
+ int total_badguys_best = (best_stats->total_badguys > total_badguys) ? best_stats->total_badguys : total_badguys;
+ context.draw_text(Resources::normal_font, frags_to_string(badguys_best, total_badguys_best), Vector(col3_x, row4_y), ALIGN_LEFT, LAYER_HUD, Statistics::text_color);
+ }
+
+ context.draw_text(Resources::normal_font, _("Secrets"), Vector(col2_x-16, row5_y), ALIGN_RIGHT, LAYER_HUD, Statistics::header_color);
+ context.draw_text(Resources::normal_font, secrets_to_string(secrets, total_secrets), Vector(col2_x, row5_y), ALIGN_LEFT, LAYER_HUD, Statistics::text_color);
+ if (best_stats) {
+ int secrets_best = (best_stats->secrets > secrets) ? best_stats->secrets : secrets;
+ int total_secrets_best = (best_stats->total_secrets > total_secrets) ? best_stats->total_secrets : total_secrets;
+ context.draw_text(Resources::normal_font, secrets_to_string(secrets_best, total_secrets_best), Vector(col3_x, row5_y), ALIGN_LEFT, LAYER_HUD, Statistics::text_color);
+ }
+
+ context.draw_text(Resources::normal_font, _("Time"), Vector(col2_x-16, row2_y), ALIGN_RIGHT, LAYER_HUD, Statistics::header_color);
+ context.draw_text(Resources::normal_font, time_to_string(time), Vector(col2_x, row2_y), ALIGN_LEFT, LAYER_HUD, Statistics::text_color);
+ if (best_stats) {
+ float time_best = (best_stats->time < time) ? best_stats->time : time;
+ context.draw_text(Resources::normal_font, time_to_string(time_best), Vector(col3_x, row2_y), ALIGN_LEFT, LAYER_HUD, Statistics::text_color);
+ }
}
void
if (!s2.valid) return;
coins = std::max(coins, s2.coins);
total_coins = s2.total_coins;
+ coins = std::min(coins, total_coins);
badguys = std::max(badguys, s2.badguys);
total_badguys = s2.total_badguys;
+ badguys = std::min(badguys, total_badguys);
time = std::min(time, s2.time);
secrets = std::max(secrets, s2.secrets);
total_secrets = s2.total_secrets;
+ secrets = std::min(secrets, total_secrets);
}
void
if (s2.total_secrets != nv_secrets) total_secrets += s2.total_secrets;
}
+bool
+Statistics::completed(const Statistics& stats, const float target_time)
+{
+ return (stats.coins == stats.total_coins &&
+ stats.badguys == stats.total_badguys &&
+ stats.secrets == stats.total_secrets &&
+ ((!target_time) || (stats.time <= target_time)));
+}
+
void
Statistics::declare_invalid()
{
return os.str();
}
-std::string
+std::string
Statistics::time_to_string(float time) {
int time_csecs = std::min(static_cast<int>(time * 100), 99 * 6000 + 9999);
int mins = (time_csecs / 6000);