Implemented a new special-tile field that should replaced the depricated level field...
authorRicardo Cruz <rick2@aeiou.pt>
Fri, 16 Jul 2004 19:22:26 +0000 (19:22 +0000)
committerRicardo Cruz <rick2@aeiou.pt>
Fri, 16 Jul 2004 19:22:26 +0000 (19:22 +0000)
Also extended display_text_file().

special-tile can have the following flags:
 [integer] x / y - necessary to say where the tile is located
 [string] extro-filename - read the given file *
 [integer] swap-x / swap-y - say coordinates for swapping *
 [string] map-message - show a message in the world map viewer
 [string] goto-world - change the world to the given one *
 [boolean] flip-level - flip vertically the level (of course, only works when there is a level)
 [boolean] exit-game - quit game *
 [string] level - feed a level to this tile

* - if there is a level, open it only if the level is successful

SVN-Revision: 1581

src/screen/font.cpp
src/worldmap.cpp
src/worldmap.h

index 0555530..2ee8338 100644 (file)
@@ -27,6 +27,8 @@
 #include "font.h"
 #include "drawing_context.h"
 #include "../lispreader.h"
+#include "../musicref.h"
+#include "../resources.h"
 
 Font::Font(const std::string& file, FontType ntype, int nw, int nh,
         int nshadowsize)
@@ -146,8 +148,18 @@ void display_text_file(const std::string& file, float scroll_speed)
   reader->read_string("text", text, true);
   std::string background_file;
   reader->read_string("background", background_file, true);
+  std::string music_file;
+  reader->read_string("music", music_file, true);
+  std::string show_after_text;
+  reader->read_string("show-after", show_after_text, true);
   delete reader;
 
+  if(!music_file.empty())
+    {
+    MusicRef theme = sound_manager->load_music(datadir + "/music/" + music_file);
+    sound_manager->play_music(theme);
+    }
+
   // Split text string lines into a vector
   names.clear();
   unsigned int i, l;
@@ -264,5 +276,10 @@ void display_text_file(const std::string& file, float scroll_speed)
 
   SDL_EnableKeyRepeat(0, 0);    // disables key repeating
   delete background;
+
+  if(!show_after_text.empty())
+    {
+    display_text_file(show_after_text, scroll_speed);
+    }
 }
 
index e8b711d..c402150 100644 (file)
@@ -415,8 +415,37 @@ WorldMap::load_map()
               while(!lisp_nil_p(cur))
                 {
                   lisp_object_t* element = lisp_car(cur);
-                  
-                  if (strcmp(lisp_symbol(lisp_car(element)), "level") == 0)
+
+                  if (strcmp(lisp_symbol(lisp_car(element)), "special-tile") == 0)
+                    {
+                      Level level;
+                      LispReader reader(lisp_cdr(element));
+                      level.solved = false;
+                      
+                      level.north = true;
+                      level.east  = true;
+                      level.south = true;
+                      level.west  = true;
+
+                      reader.read_string("extro-filename", level.extro_filename);
+                      reader.read_string("map-message", level.display_map_message);
+                      reader.read_string("goto-world", level.goto_worldmap);
+                      reader.read_string("level", level.name, true);
+                      reader.read_int("x", level.x);
+                      reader.read_int("y", level.y);
+                      level.swap_x = level.swap_y = -1;
+                      reader.read_int("swap-x", level.swap_x);
+                      reader.read_int("swap-y", level.swap_y);
+                      level.vertical_flip = false;
+                      reader.read_bool("flip-level", level.vertical_flip);
+                      level.quit_worldmap = false;
+                      reader.read_bool("exit-game", level.quit_worldmap);
+
+                      levels.push_back(level);
+                    }
+
+                  /* Kept for backward compability */
+                  else if (strcmp(lisp_symbol(lisp_car(element)), "level") == 0)
                     {
                       Level level;
                       LispReader reader(lisp_cdr(element));
@@ -428,11 +457,13 @@ WorldMap::load_map()
                       level.west  = true;
 
                       reader.read_string("extro-filename", level.extro_filename);
+                      if(!level.extro_filename.empty())
+                        level.quit_worldmap = true;
                       reader.read_string("name", level.name, true);
                       reader.read_int("x", level.x);
                       reader.read_int("y", level.y);
                       level.vertical_flip = false;
-                      reader.read_bool("flip", level.vertical_flip);
+                      level.swap_x = level.swap_y = -1;
 
                       levels.push_back(level);
                     }
@@ -639,8 +670,17 @@ WorldMap::update(float delta)
 {
   if (enter_level && !tux->is_moving())
     {
+      bool level_finished = true;
       Level* level = at_level();
-      if (level)
+      if (!level)
+        {
+        std::cout << "Nothing to enter at: "
+          << tux->get_tile_pos().x << ", " << tux->get_tile_pos().y << std::endl;
+        return;
+        }
+
+
+      if(!level->name.empty())
         {
           if (level->x == tux->get_tile_pos().x && 
               level->y == tux->get_tile_pos().y)
@@ -658,6 +698,7 @@ WorldMap::update(float delta)
                 {
                 case GameSession::ES_LEVEL_FINISHED:
                   {
+                    level_finished = true;
                     bool old_level_state = level->solved;
                     level->solved = true;
 
@@ -693,30 +734,22 @@ WorldMap::update(float delta)
 
                         std::cout << "Walk to dir: " << dir << std::endl;
                       }
-
-                    if (!level->extro_filename.empty())
-                      { 
-                        MusicRef theme =
-                          sound_manager->load_music(datadir + "/music/theme.mod");
-                        sound_manager->play_music(theme);
-                        // Display final credits and go back to the main menu
-                        display_text_file(level->extro_filename, SCROLL_SPEED_MESSAGE);
-                        display_text_file("CREDITS", SCROLL_SPEED_CREDITS);
-                        quit = true;
-                      }
                   }
 
                   break;
                 case GameSession::ES_LEVEL_ABORT:
+                  level_finished = false;
                   /* In case the player's abort the level, keep it using the old
                       status. But the minimum lives and no bonus. */
                   player_status.score = old_player_status.score;
                   player_status.distros = old_player_status.distros;
                   player_status.lives = std::min(old_player_status.lives, player_status.lives);
                   player_status.bonus = player_status.NO_BONUS;
+
                   break;
                 case GameSession::ES_GAME_OVER:
-                {
+                  {
+                  level_finished = false;
                   /* draw an end screen */
                   /* in the future, this should make a dialog a la SuperMario, asking
                   if the player wants to restart the world map with no score and from
@@ -724,7 +757,7 @@ WorldMap::update(float delta)
                   char str[80];
 
                   DrawingContext context;
-                  context.draw_gradient(Color (0, 255, 0), Color (255, 0, 255),
+                  context.draw_gradient(Color (200,240,220), Color(200,200,220),
                       LAYER_BACKGROUND0);
 
                   context.draw_text_center(blue_text, _("GAMEOVER"), 
@@ -732,7 +765,7 @@ WorldMap::update(float delta)
 
                   sprintf(str, _("SCORE: %d"), player_status.score);
                   context.draw_text_center(gold_text, str,
-                      Vector(0, 224), LAYER_FOREGROUND1);
+                      Vector(0, 230), LAYER_FOREGROUND1);
 
                   sprintf(str, _("COINS: %d"), player_status.distros);
                   context.draw_text_center(gold_text, str,
@@ -746,7 +779,7 @@ WorldMap::update(float delta)
                   quit = true;
                   player_status.reset();
                   break;
-                }
+                  }
                 case GameSession::ES_NONE:
                   assert(false);
                   // Should never be reached 
@@ -757,13 +790,29 @@ WorldMap::update(float delta)
               Menu::set_current(0);
               if (!savegame_file.empty())
                 savegame(savegame_file);
-              return;
             }
         }
-      else
+      /* The porpose of the next checking is that if the player lost
+         the level (in case there is one), don't show anything */
+      if(level_finished)
         {
-          std::cout << "Nothing to enter at: "
-                    << tux->get_tile_pos().x << ", " << tux->get_tile_pos().y << std::endl;
+        if (!level->extro_filename.empty())
+          {
+          // Display a text file
+          display_text_file(level->extro_filename, SCROLL_SPEED_MESSAGE);
+          }
+        if (level->swap_x != -1 && level->swap_y != -1)
+          {
+          // TODO: add an effect, like a camera scrolling, or at least, a fading
+          tux->set_tile_pos(Vector(level->swap_x, level->swap_y));
+          }
+        if (!level->goto_worldmap.empty())
+          {
+          // Load given worldmap
+          loadmap(level->goto_worldmap);
+          }
+        if (level->quit_worldmap)
+          quit = true;
         }
     }
   else
@@ -835,6 +884,9 @@ WorldMap::draw(DrawingContext& context, const Vector& offset)
   
   for(Levels::iterator i = levels.begin(); i != levels.end(); ++i)
     {
+      if(i->name.empty())
+        continue;
+
       if (i->solved)
         context.draw_surface(leveldot_green,
             Vector(i->x*32 + offset.x, i->y*32 + offset.y), LAYER_TILES+1);
@@ -889,13 +941,21 @@ WorldMap::draw_status(DrawingContext& context)
           if (i->x == tux->get_tile_pos().x && 
               i->y == tux->get_tile_pos().y)
             {
-              if(i->title == "")
-                get_level_title(*i);
+              if(!i->name.empty())
+                {
+                if(i->title == "")
+                  get_level_title(*i);
+
+                context.draw_text_center(white_text, i->title, 
+                    Vector(0, screen->h - white_text->get_height() - 30),
+                    LAYER_FOREGROUND1);
+                }
 
-              context.draw_text(white_text, i->title, 
-                  Vector(screen->w/2 - white_text->get_text_width(i->title)/2,
-                         screen->h - white_text->get_height() - 30),
-                  LAYER_FOREGROUND1);
+              /* Display a message in the map, if any as been selected */
+              if(!i->display_map_message.empty())
+                context.draw_text_center(gold_text, i->display_map_message, 
+                    Vector(0, screen->h - white_text->get_height() - 60),
+                    LAYER_FOREGROUND1);
               break;
             }
         }
index f4e1ecc..5113c74 100644 (file)
@@ -139,6 +139,8 @@ public:
     std::string title;
     bool solved;
 
+    /** Optional flags: */
+
     /** Check if this level should be vertically flipped */
     bool vertical_flip;
 
@@ -146,6 +148,18 @@ public:
         successfully completed */
     std::string extro_filename;
 
+    /** Position to swap player */
+    int swap_x, swap_y;
+
+    /** Message to show in the Map */
+    std::string display_map_message;
+
+    /** Go to this world */
+    std::string goto_worldmap;
+
+    /** Quit the worldmap */
+    bool quit_worldmap;
+
     // Directions which are walkable from this level
     bool north;
     bool east;