#include "object/background.hpp"
#include "object/decal.hpp"
#include "object/tilemap.hpp"
-#include "physfs/ifile_stream.hpp"
+#include "physfs/ifile_streambuf.hpp"
#include "scripting/squirrel_error.hpp"
#include "scripting/squirrel_util.hpp"
#include "sprite/sprite.hpp"
WorldMap::WorldMap(const std::string& filename, PlayerStatus* player_status, const std::string& force_spawnpoint) :
tux(0),
player_status(player_status),
- tileset(NULL),
+ tileset(NULL),
free_tileset(false),
worldmap_menu(),
camera_offset(),
total_stats(),
worldmap_table(),
scripts(),
- ambient_light( 1.0f, 1.0f, 1.0f, 1.0f ),
+ ambient_light( 1.0f, 1.0f, 1.0f, 1.0f ),
force_spawnpoint(force_spawnpoint),
- in_level(false),
+ in_level(false),
pan_pos(),
panning(false)
{
sq_pop(global_vm, 1);
sound_manager->preload("sounds/warp.wav");
-
+
// load worldmap objects
load(filename);
}
}
}
+void
+WorldMap::get_level_target_time(LevelTile& level)
+{
+ if(last_position == tux->get_tile_pos()) {
+ level.target_time = last_target_time;
+ return;
+ }
+
+ try {
+ lisp::Parser parser;
+ const lisp::Lisp* root = parser.parse(levels_path + level.get_name());
+
+ const lisp::Lisp* level_lisp = root->get_lisp("supertux-level");
+ if(!level_lisp)
+ return;
+
+ level_lisp->get("target-time", level.target_time);
+
+ last_position = level.pos;
+ last_target_time = level.target_time;
+ } catch(std::exception& e) {
+ log_warning << "Problem when reading level target time: " << e.what() << std::endl;
+ return;
+ }
+}
+
void WorldMap::calculate_total_stats()
{
total_stats.zero();
// deal with statistics
level->statistics.merge(gamelevel->stats);
calculate_total_stats();
- if(level->statistics.completed(level->statistics)) {
+ get_level_target_time(*level);
+ if(level->statistics.completed(level->statistics, level->target_time)) {
level->perfect = true;
- level->sprite->set_action("perfect");
+ if(level->sprite->has_action("perfect"))
+ level->sprite->set_action("perfect");
}
save_state();
LevelTile* level = at_level();
if (level && (level->auto_play) && (!level->solved) && (!tux->is_moving())) {
enter_level = true;
+ // automatically mark these levels as solved in case player aborts
+ level->solved = true;
}
if (enter_level && !tux->is_moving())
/*
// FIXME: make this a runtime switch similar to draw_collrects/show_collrects?
// draw visual indication of possible walk directions
- static int flipme = 0;
+ static int flipme = 0;
if (flipme++ & 0x04)
for (int x = 0; x < get_width(); x++) {
for (int y = 0; y < get_height(); y++) {
context.draw_text(Resources::normal_font, level->title,
Vector(SCREEN_WIDTH/2,
- SCREEN_HEIGHT - Resources::normal_font->get_height() - 30),
- ALIGN_CENTER, LAYER_FOREGROUND1, WorldMap::level_title_color);
+ SCREEN_HEIGHT - Resources::normal_font->get_height() - 10),
+ ALIGN_CENTER, LAYER_HUD, WorldMap::level_title_color);
// if level is solved, draw level picture behind stats
/*
}
*/
- level->statistics.draw_worldmap_info(context);
+ get_level_target_time(*level);
+ level->statistics.draw_worldmap_info(context, level->target_time);
break;
}
}
//Run default.nut just before init script
try {
- IFileStream in(levels_path + "/default.nut");
+ IFileStreambuf ins(levels_path + "default.nut");
+ std::istream in(&ins);
run_script(in, "WorldMap::default.nut");
} catch(std::exception& ) {
// doesn't exist or erroneous; do nothing