#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();
+ get_level_target_time(*level);
+ if(level->statistics.completed(level->statistics, level->target_time)) {
+ level->perfect = true;
+ if(level->sprite->has_action("perfect"))
+ level->sprite->set_action("perfect");
+ }
save_state();
}
// handle input
+ Controller *controller = g_jk_controller->get_main_controller();
bool enter_level = false;
- if(g_main_controller->pressed(Controller::ACTION)
- || g_main_controller->pressed(Controller::JUMP)
- || g_main_controller->pressed(Controller::MENU_SELECT)) {
+ if(controller->pressed(Controller::ACTION)
+ || controller->pressed(Controller::JUMP)
+ || controller->pressed(Controller::MENU_SELECT)) {
/* some people define UP and JUMP on the same key... */
- if(!g_main_controller->pressed(Controller::UP))
+ if(!controller->pressed(Controller::UP))
enter_level = true;
}
- if(g_main_controller->pressed(Controller::PAUSE_MENU))
+ if(controller->pressed(Controller::PAUSE_MENU))
on_escape_press();
// check for teleporters
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
sq_newtable(vm);
store_bool(vm, "solved", level->solved);
+ store_bool(vm, "perfect", level->perfect);
level->statistics.serialize_to_squirrel(vm);
sq_createslot(vm, -3);
sq_pushstring(vm, level->get_name().c_str(), -1);
if(SQ_SUCCEEDED(sq_get(vm, -2))) {
level->solved = read_bool(vm, "solved");
- level->sprite->set_action(level->solved ? "solved" : "default");
+ level->perfect = read_bool(vm, "perfect");
+ if(!level->solved)
+ level->sprite->set_action("default");
+ else
+ level->sprite->set_action((level->sprite->has_action("perfect") && level->perfect) ? "perfect" : "solved");
level->statistics.unserialize_from_squirrel(vm);
sq_pop(vm, 1);
}