X-Git-Url: https://git.verplant.org/?a=blobdiff_plain;f=src%2Flevel.cpp;h=78d4a1a6cdcfea375c0c646b473b3af7935b5318;hb=5ee161985d711c1cbe18b51b6db0076e34ddf613;hp=0517c6a6b655d8a5f8ba20fb77b8fa3ee24b02ca;hpb=52de79ad8301a395a5a2999ecbdf31731c0b65f8;p=supertux.git diff --git a/src/level.cpp b/src/level.cpp index 0517c6a6b..78d4a1a6c 100644 --- a/src/level.cpp +++ b/src/level.cpp @@ -20,16 +20,15 @@ #include #include -#include -#include -#include +#include +#include +#include #include #include #include #include #include -#include "video/screen.hpp" #include "log.hpp" #include "lisp/parser.hpp" #include "lisp/lisp.hpp" @@ -39,29 +38,38 @@ #include "physic.hpp" #include "sector.hpp" #include "tile.hpp" +#include "tile_set.hpp" +#include "tile_manager.hpp" #include "resources.hpp" #include "file_system.hpp" #include "object/gameobjs.hpp" #include "object/camera.hpp" #include "object/tilemap.hpp" #include "object/coin.hpp" - -// test -#include "flip_level_transformer.hpp" +#include "object/block.hpp" using namespace std; Level::Level() - : name("noname"), author("Mr. X") + : name("noname"), author("Mr. X"), tileset(NULL), free_tileset(false) +{ +} + +Level::~Level() { + for(Sectors::iterator i = sectors.begin(); i != sectors.end(); ++i) + delete *i; + if(free_tileset) + delete tileset; } void Level::load(const std::string& filepath) { try { + filename = filepath; lisp::Parser parser; - std::auto_ptr root (parser.parse(filepath)); + const lisp::Lisp* root = parser.parse(filepath); const lisp::Lisp* level = root->get_lisp("supertux-level"); if(!level) @@ -70,10 +78,34 @@ Level::load(const std::string& filepath) int version = 1; level->get("version", version); if(version == 1) { + log_info << "level uses old format: version 1" << std::endl; + tileset = tile_manager->get_tileset("images/tiles.strf"); load_old_format(*level); return; } + const lisp::Lisp* tilesets_lisp = level->get_lisp("tilesets"); + if(tilesets_lisp != NULL) { + tileset = tile_manager->parse_tileset_definition(*tilesets_lisp); + free_tileset = true; + } + std::string tileset_name; + if(level->get("tileset", tileset_name)) { + if(tileset != NULL) { + log_warning << "multiple tilesets specified in level" << std::endl; + } else { + tileset = tile_manager->get_tileset(tileset_name); + } + } + /* load default tileset */ + if(tileset == NULL) { + tileset = tile_manager->get_tileset("images/tiles.strf"); + } + current_tileset = tileset; + + contact = ""; + license = ""; + lisp::ListIterator iter(level); while(iter.next()) { const std::string& token = iter.item(); @@ -82,25 +114,38 @@ Level::load(const std::string& filepath) if(version > 2) { log_warning << "level format newer than application" << std::endl; } + } else if(token == "tileset" || token == "tilesets") { + continue; } else if(token == "name") { iter.value()->get(name); } else if(token == "author") { iter.value()->get(author); + } else if(token == "contact") { + iter.value()->get(contact); + } else if(token == "license") { + iter.value()->get(license); + } else if(token == "on-menukey-script") { + iter.value()->get(on_menukey_script); } else if(token == "sector") { Sector* sector = new Sector(this); sector->parse(*(iter.lisp())); add_sector(sector); } else { log_warning << "Unknown token '" << token << "' in level file" << std::endl; - continue; } } - + + if (license == "") { + log_warning << "The level author did not specify a license for this level. You might not be allowed to share it." << std::endl; + + } } catch(std::exception& e) { std::stringstream msg; msg << "Problem when reading level '" << filepath << "': " << e.what(); throw std::runtime_error(msg.str()); } + + current_tileset = NULL; } void @@ -128,6 +173,8 @@ Level::save(const std::string& filename) writer->write_string("name", name, true); writer->write_string("author", author); + if(on_menukey_script != "") + writer->write_string("on-menukey-script", on_menukey_script); for(Sectors::iterator i = sectors.begin(); i != sectors.end(); ++i) { Sector* sector = *i; @@ -141,12 +188,6 @@ Level::save(const std::string& filename) delete writer; } -Level::~Level() -{ - for(Sectors::iterator i = sectors.begin(); i != sectors.end(); ++i) - delete *i; -} - void Level::add_sector(Sector* sector) { @@ -182,18 +223,8 @@ Level::get_sector(size_t num) } int -Level::get_total_badguys() -{ - int total_badguys = 0; - for(Sectors::iterator i = sectors.begin(); i != sectors.end(); ++i) - total_badguys += (*i)->get_total_badguys(); - return total_badguys; -} - -int Level::get_total_coins() { - // FIXME not really correct as coins can also be inside blocks... int total_coins = 0; for(Sectors::iterator i = sectors.begin(); i != sectors.end(); ++i) { Sector* sector = *i; @@ -201,9 +232,37 @@ Level::get_total_coins() o != sector->gameobjects.end(); ++o) { Coin* coin = dynamic_cast (*o); if(coin) + { total_coins++; + continue; + } + BonusBlock *block = dynamic_cast (*o); + if(block) + { + if (block->contents == BonusBlock::CONTENT_COIN) + { + total_coins++; + continue; + } +#if 0 + // FIXME: do we want this? q.v. src/object/oneup.cpp + else if (block->contents == BonusBlock::CONTENT_1UP) + { + total_coins += 100; + continue; + } +#endif + } } } return total_coins; } +int +Level::get_total_badguys() +{ + int total_badguys = 0; + for(Sectors::iterator i = sectors.begin(); i != sectors.end(); ++i) + total_badguys += (*i)->get_total_badguys(); + return total_badguys; +}