- updated TODO
[supertux.git] / src / sector.cpp
index 401e6b6..3d75b77 100644 (file)
@@ -1,3 +1,21 @@
+//  $Id$
+//
+//  SuperTux -  A Jump'n Run
+//  Copyright (C) 2004 Matthias Braun <matze@braunis.de
+//
+//  This program is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU General Public License
+//  as published by the Free Software Foundation; either version 2
+//  of the License, or (at your option) any later version.
+//
+//  This program is distributed in the hope that it will be useful,
+//  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 "sector.h"
 
 #include <memory>
 #include "particlesystem.h"
 #include "tile.h"
 #include "tilemap.h"
-#include "music_manager.h"
+#include "sound_manager.h"
 #include "gameloop.h"
 #include "resources.h"
+#include "interactive_object.h"
+#include "door.h"
 
 Sector* Sector::_current = 0;
 
@@ -78,6 +98,7 @@ Sector::parse(LispReader& lispreader)
       reader.read_string("name", sp->name);
       reader.read_float("x", sp->pos.x);
       reader.read_float("y", sp->pos.y);
+      spawnpoints.push_back(sp);
     } else if(token == "tilemap") {
       TileMap* tilemap = new TileMap(reader);
       add_object(tilemap);
@@ -103,12 +124,17 @@ Sector::parse(LispReader& lispreader)
       CloudParticleSystem* partsys = new CloudParticleSystem();
       partsys->parse(reader);
       add_object(partsys);
+    } else if(token == "door") {
+      add_object(new Door(reader));
+    } else {
+      std::cerr << "Unknown object type '" << token << "'.\n";
     }
   }
 
   if(!camera) {
-    std::cerr << "sector does not contain a camera.\n";
+    std::cerr << "sector '" << name << "' does not contain a camera.\n";
     camera = new Camera(this);
+    add_object(camera);
   }
   if(!solids)
     throw std::runtime_error("sector does not contain a solid tile layer.");
@@ -264,9 +290,10 @@ Sector::add_object(GameObject* object)
   FlyingPlatform* flying_platform = dynamic_cast<FlyingPlatform*> (object);
   if(flying_platform)
     flying_platforms.push_back(flying_platform);
-  Background* background = dynamic_cast<Background*> (object);
-  if(background)
-    this->background = background;
+  InteractiveObject* interactive_object 
+      = dynamic_cast<InteractiveObject*> (object);
+  if(interactive_object)
+    interactive_objects.push_back(interactive_object);
 
   gameobjects.push_back(object);
 }
@@ -338,6 +365,13 @@ Sector::action(float elapsed_time)
             std::remove(bullets.begin(), bullets.end(), bullet),
             bullets.end());
       }
+      InteractiveObject* interactive_object =
+          dynamic_cast<InteractiveObject*> (*i);
+      if(interactive_object) {
+        interactive_objects.erase(
+            std::remove(interactive_objects.begin(), interactive_objects.end(),
+                interactive_object), interactive_objects.end());
+      }
       Upgrade* upgrade = dynamic_cast<Upgrade*> (*i);
       if(upgrade) {
         upgrades.erase(
@@ -574,7 +608,7 @@ Sector::add_bullet(const Vector& pos, float xm, Direction dir)
     throw std::runtime_error("wrong bullet type.");
   add_object(new_bullet);
                                                                                 
-  play_sound(sounds[SND_SHOOT], SOUND_CENTER_SPEAKER);
+  sound_manager->play_sound(sounds[SND_SHOOT]);
                                                                                 
   return true;
 }
@@ -584,6 +618,13 @@ bool
 Sector::trybreakbrick(const Vector& pos, bool small)
 {
   Tile* tile = solids->get_tile_at(pos);
+  if (!tile)
+  {
+    char errmsg[64];
+    sprintf(errmsg, "Invalid tile at %i,%i", (int)((pos.x+1)/32*32), (int)((pos.y+1)/32*32));
+    throw SuperTuxException(errmsg, __FILE__, __LINE__);
+  }
+
   if (tile->attributes & Tile::BRICK)
     {
       if (tile->data > 0)
@@ -609,7 +650,7 @@ Sector::trybreakbrick(const Vector& pos, bool small)
               solids->change_at(pos, tile->next_tile);
             }
                                                                                 
-          play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER);
+          sound_manager->play_sound(sounds[SND_DISTRO]);
           player_status.score = player_status.score + SCORE_DISTRO;
           player_status.distros++;
           return true;
@@ -625,7 +666,7 @@ Sector::trybreakbrick(const Vector& pos, bool small)
                                  (int)(pos.y / 32) * 32), tile);
                                                                                 
           /* Get some score: */
-          play_sound(sounds[SND_BRICK], SOUND_CENTER_SPEAKER);
+          sound_manager->play_sound(sounds[SND_BRICK]);
           player_status.score = player_status.score + SCORE_BRICK;
                                                                                 
           return true;
@@ -640,6 +681,14 @@ void
 Sector::tryemptybox(const Vector& pos, Direction col_side)
 {
   Tile* tile = solids->get_tile_at(pos);
+  if (!tile)
+  {
+    char errmsg[64];
+    sprintf(errmsg, "Invalid tile at %i,%i", (int)((pos.x+1)/32*32), (int)((pos.y+1)/32*32));
+    throw SuperTuxException(errmsg, __FILE__, __LINE__);
+  }
+
+
   if (!(tile->attributes & Tile::FULLBOX))
     return;
                                                                                 
@@ -655,7 +704,7 @@ Sector::tryemptybox(const Vector& pos, Direction col_side)
     {
     case 1: // Box with a distro!
       add_bouncy_distro(Vector(posx, posy));
-      play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER);
+      sound_manager->play_sound(sounds[SND_DISTRO]);
       player_status.score = player_status.score + SCORE_DISTRO;
       player_status.distros++;
       break;
@@ -665,7 +714,7 @@ Sector::tryemptybox(const Vector& pos, Direction col_side)
         add_upgrade(Vector(posx, posy), col_side, UPGRADE_GROWUP);
       else     /* Tux is big, add a fireflower: */
         add_upgrade(Vector(posx, posy), col_side, UPGRADE_FIREFLOWER);
-      play_sound(sounds[SND_UPGRADE], SOUND_CENTER_SPEAKER);
+      sound_manager->play_sound(sounds[SND_UPGRADE]);
       break;
                                                                                 
     case 5: // Add an ice flower upgrade!
@@ -673,7 +722,7 @@ Sector::tryemptybox(const Vector& pos, Direction col_side)
         add_upgrade(Vector(posx, posy), col_side, UPGRADE_GROWUP);
       else     /* Tux is big, add an iceflower: */
         add_upgrade(Vector(posx, posy), col_side, UPGRADE_ICEFLOWER);
-      play_sound(sounds[SND_UPGRADE], SOUND_CENTER_SPEAKER);
+      sound_manager->play_sound(sounds[SND_UPGRADE]);
       break;
                                                                                 
     case 3: // Add a golden herring
@@ -696,11 +745,19 @@ void
 Sector::trygrabdistro(const Vector& pos, int bounciness)
 {
   Tile* tile = solids->get_tile_at(pos);
+  if (!tile)
+  {
+    char errmsg[64];
+    sprintf(errmsg, "Invalid tile at %i,%i", (int)((pos.x+1)/32*32), (int)((pos.y+1)/32*32));
+    throw SuperTuxException(errmsg, __FILE__, __LINE__);
+  }
+
+
   if (!(tile->attributes & Tile::COIN))
     return;
 
   solids->change_at(pos, tile->next_tile);
-  play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER);
+  sound_manager->play_sound(sounds[SND_DISTRO]);
                                                                             
   if (bounciness == BOUNCE)
     {
@@ -744,7 +801,7 @@ Sector::load_music()
   char* song_path;
   char* song_subtitle;
                                                                                 
-  level_song = music_manager->load_music(datadir + "/music/" + song_title);
+  level_song = sound_manager->load_music(datadir + "/music/" + song_title);
                                                                                 
   song_path = (char *) malloc(sizeof(char) * datadir.length() +
                               strlen(song_title.c_str()) + 8 + 5);
@@ -752,10 +809,10 @@ Sector::load_music()
   strcpy(strstr(song_subtitle, "."), "\0");
   sprintf(song_path, "%s/music/%s-fast%s", datadir.c_str(),
           song_subtitle, strstr(song_title.c_str(), "."));
-  if(!music_manager->exists_music(song_path)) {
+  if(!sound_manager->exists_music(song_path)) {
     level_song_fast = level_song;
   } else {
-    level_song_fast = music_manager->load_music(song_path);
+    level_song_fast = sound_manager->load_music(song_path);
   }
   free(song_subtitle);
   free(song_path);
@@ -767,16 +824,16 @@ Sector::play_music(int type)
   currentmusic = type;
   switch(currentmusic) {
     case HURRYUP_MUSIC:
-      music_manager->play_music(level_song_fast);
+      sound_manager->play_music(level_song_fast);
       break;
     case LEVEL_MUSIC:
-      music_manager->play_music(level_song);
+      sound_manager->play_music(level_song);
       break;
     case HERRING_MUSIC:
-      music_manager->play_music(herring_song);
+      sound_manager->play_music(herring_song);
       break;
     default:
-      music_manager->halt_music();
+      sound_manager->halt_music();
       break;
   }
 }