X-Git-Url: https://git.verplant.org/?a=blobdiff_plain;f=src%2Flevel.cpp;h=33c7c2523a5584084c3e15de0f9a74159af6a114;hb=13c84268f16872f9b442251c4175a3a1a7a7899a;hp=ae81a34c3db8326dec2d410da6ae8082352cd4ed;hpb=c0093d25093395cb62fc2526ab42be65a9f015b8;p=supertux.git diff --git a/src/level.cpp b/src/level.cpp index ae81a34c3..33c7c2523 100644 --- a/src/level.cpp +++ b/src/level.cpp @@ -1,7 +1,7 @@ // $Id$ -// +// // SuperTux -// Copyright (C) 2004 SuperTux Development Team, see AUTHORS for details +// Copyright (C) 2006 Matthias Braun // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License @@ -12,56 +12,59 @@ // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. -// +// // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA // 02111-1307, USA. #include +#include "level.hpp" + #include -#include -#include -#include +#include +#include +#include #include #include #include #include #include -#include "app/globals.h" -#include "app/setup.h" -#include "video/screen.h" -#include "lisp/parser.h" -#include "lisp/lisp.h" -#include "lisp/list_iterator.h" -#include "lisp/writer.h" -#include "level.h" -#include "math/physic.h" -#include "sector.h" -#include "tile.h" -#include "resources.h" -#include "object/gameobjs.h" -#include "object/camera.h" -#include "object/tilemap.h" -#include "object/coin.h" - -// test -#include "flip_level_transformer.h" +#include "log.hpp" +#include "lisp/parser.hpp" +#include "lisp/lisp.hpp" +#include "lisp/list_iterator.hpp" +#include "lisp/writer.hpp" +#include "sector.hpp" +#include "tile_set.hpp" +#include "tile_manager.hpp" +#include "object/coin.hpp" +#include "object/block.hpp" +#include "trigger/secretarea_trigger.hpp" using namespace std; Level::Level() - : name("noname"), author("Mr. X"), timelimit(500) + : 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,46 +73,74 @@ 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); - -#if 0 - // test for now - FlipLevelTransformer* transformer = new FlipLevelTransformer(); - transformer->transform(this); -#endif - 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(); if(token == "version") { iter.value()->get(version); if(version > 2) { - std::cerr << "Warning: level format newer than application.\n"; + 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 == "time") { - iter.value()->get(timelimit); + } 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; + Sector* sector = new Sector(this); sector->parse(*(iter.lisp())); add_sector(sector); } else { - std::cerr << "Unknown token '" << token << "' in level file.\n"; - continue; + log_warning << "Unknown token '" << token << "' in level file" << std::endl; } } - + + 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 @@ -117,9 +148,8 @@ Level::load_old_format(const lisp::Lisp& reader) { reader.get("name", name); reader.get("author", author); - reader.get("time", timelimit); - Sector* sector = new Sector; + Sector* sector = new Sector(this); sector->parse_old_format(reader); add_sector(sector); } @@ -127,12 +157,7 @@ Level::load_old_format(const lisp::Lisp& reader) void Level::save(const std::string& filename) { - std::string filepath = "levels/" + filename; - int last_slash = filepath.find_last_of('/'); - FileSystem::fcreatedir(filepath.substr(0,last_slash).c_str()); - filepath = user_dir + "/" + filepath; - ofstream file(filepath.c_str(), ios::out); - lisp::Writer* writer = new lisp::Writer(file); + lisp::Writer* writer = new lisp::Writer(filename); writer->write_comment("Level made using SuperTux's built-in Level Editor"); @@ -143,7 +168,8 @@ Level::save(const std::string& filename) writer->write_string("name", name, true); writer->write_string("author", author); - writer->write_int("time", timelimit); + 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; @@ -155,13 +181,6 @@ Level::save(const std::string& filename) writer->end_list("supertux-level"); delete writer; - file.close(); -} - -Level::~Level() -{ - for(Sectors::iterator i = sectors.begin(); i != sectors.end(); ++i) - delete *i; } void @@ -199,18 +218,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; @@ -218,9 +227,46 @@ 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; +} + +int +Level::get_total_secrets() +{ + int total_secrets = 0; + for(Sectors::iterator i = sectors.begin(); i != sectors.end(); ++i) + total_secrets += (*i)->get_total_count(); + return total_secrets; +}