Fix coverity #29604
[supertux.git] / src / supertux / sector.cpp
index 333a737..c9879c9 100644 (file)
@@ -46,6 +46,7 @@
 #include "object/text_object.hpp"
 #include "object/tilemap.hpp"
 #include "physfs/ifile_streambuf.hpp"
+#include "scripting/scripting.hpp"
 #include "scripting/squirrel_util.hpp"
 #include "supertux/collision.hpp"
 #include "supertux/constants.hpp"
@@ -57,6 +58,7 @@
 #include "supertux/savegame.hpp"
 #include "supertux/spawn_point.hpp"
 #include "supertux/tile.hpp"
+#include "trigger/secretarea_trigger.hpp"
 #include "trigger/sequence_trigger.hpp"
 #include "util/file_system.hpp"
 
@@ -75,6 +77,7 @@ Sector::Sector(Level* parent) :
   sector_table(),
   scripts(),
   ambient_light( 1.0f, 1.0f, 1.0f, 1.0f ),
+  foremost_layer(),
   gameobjects(),
   moving_objects(),
   spawnpoints(),
@@ -86,11 +89,11 @@ Sector::Sector(Level* parent) :
   camera(0),
   effect(0)
 {
-  add_object(new Player(GameSession::current()->get_savegame().get_player_status(), "Tux"));
-  add_object(new DisplayEffect("Effect"));
-  add_object(new TextObject("Text"));
+  add_object(std::make_shared<Player>(GameSession::current()->get_savegame().get_player_status(), "Tux"));
+  add_object(std::make_shared<DisplayEffect>("Effect"));
+  add_object(std::make_shared<TextObject>("Text"));
 
-  sound_manager->preload("sounds/shoot.wav");
+  SoundManager::current()->preload("sounds/shoot.wav");
 
   // create a new squirrel table for the sector
   using namespace scripting;
@@ -112,11 +115,17 @@ Sector::Sector(Level* parent) :
 Sector::~Sector()
 {
   using namespace scripting;
+  try
+  {
+    deactivate();
+  }
+  catch(const std::exception& err)
+  {
+    log_warning << err.what() << std::endl;
+  }
 
-  deactivate();
 
-  for(ScriptList::iterator i = scripts.begin();
-      i != scripts.end(); ++i) {
+  for(auto i = scripts.begin(); i != scripts.end(); ++i) {
     HSQOBJECT& object = *i;
     sq_release(global_vm, &object);
   }
@@ -126,16 +135,10 @@ Sector::~Sector()
   update_game_objects();
   assert(gameobjects_new.size() == 0);
 
-  for(GameObjects::iterator i = gameobjects.begin();
-      i != gameobjects.end(); ++i) {
-    GameObject* object = *i;
+  for(auto i = gameobjects.begin(); i != gameobjects.end(); ++i) {
+    GameObjectPtr object = *i;
     before_object_remove(object);
-    object->unref();
   }
-
-  for(SpawnPoints::iterator i = spawnpoints.begin(); i != spawnpoints.end();
-      ++i)
-    delete *i;
 }
 
 Level*
@@ -144,41 +147,41 @@ Sector::get_level()
   return level;
 }
 
-GameObject*
-Sector::parse_object(const std::string& name, const Reader& reader)
+GameObjectPtr
+Sector::parse_object(const std::string& name_, const Reader& reader)
 {
-  if(name == "camera") {
-    Camera* camera = new Camera(this, "Camera");
-    camera->parse(reader);
-    return camera;
-  } else if(name == "particles-snow") {
-    SnowParticleSystem* partsys = new SnowParticleSystem();
+  if(name_ == "camera") {
+    auto camera_ = std::make_shared<Camera>(this, "Camera");
+    camera_->parse(reader);
+    return camera_;
+  } else if(name_ == "particles-snow") {
+    auto partsys = std::make_shared<SnowParticleSystem>();
     partsys->parse(reader);
     return partsys;
-  } else if(name == "particles-rain") {
-    RainParticleSystem* partsys = new RainParticleSystem();
+  } else if(name_ == "particles-rain") {
+    auto partsys = std::make_shared<RainParticleSystem>();
     partsys->parse(reader);
     return partsys;
-  } else if(name == "particles-comets") {
-    CometParticleSystem* partsys = new CometParticleSystem();
+  } else if(name_ == "particles-comets") {
+    auto partsys = std::make_shared<CometParticleSystem>();
     partsys->parse(reader);
     return partsys;
-  } else if(name == "particles-ghosts") {
-    GhostParticleSystem* partsys = new GhostParticleSystem();
+  } else if(name_ == "particles-ghosts") {
+    auto partsys = std::make_shared<GhostParticleSystem>();
     partsys->parse(reader);
     return partsys;
-  } else if(name == "particles-clouds") {
-    CloudParticleSystem* partsys = new CloudParticleSystem();
+  } else if(name_ == "particles-clouds") {
+    auto partsys = std::make_shared<CloudParticleSystem>();
     partsys->parse(reader);
     return partsys;
-  } else if(name == "money") { // for compatibility with old maps
-    return new Jumpy(reader);
+  } else if(name_ == "money") { // for compatibility with old maps
+    return std::make_shared<Jumpy>(reader);
   } else {
     try {
-      return ObjectFactory::instance().create(name, reader);
+      return ObjectFactory::instance().create(name_, reader);
     } catch(std::exception& e) {
       log_warning << e.what() << "" << std::endl;
-      return 0;
+      return {};
     }
   }
 }
@@ -197,7 +200,7 @@ Sector::parse(const Reader& sector)
     } else if(token == "music") {
       iter.value()->get(music);
     } else if(token == "spawnpoint") {
-      SpawnPoint* sp = new SpawnPoint(*iter.lisp());
+      auto sp = std::make_shared<SpawnPoint>(*iter.lisp());
       spawnpoints.push_back(sp);
     } else if(token == "init-script") {
       iter.value()->get(init_script);
@@ -210,11 +213,11 @@ Sector::parse(const Reader& sector)
         ambient_light = Color( vColor );
       }
     } else {
-      GameObject* object = parse_object(token, *(iter.lisp()));
+      GameObjectPtr object = parse_object(token, *(iter.lisp()));
       if(object) {
-        if(dynamic_cast<Background *>(object)) {
+        if(std::dynamic_pointer_cast<Background>(object)) {
           has_background = true;
-        } else if(dynamic_cast<Gradient *>(object)) {
+        } else if(std::dynamic_pointer_cast<Gradient>(object)) {
           has_background = true;
         }
         add_object(object);
@@ -223,23 +226,24 @@ Sector::parse(const Reader& sector)
   }
 
   if(!has_background) {
-    Gradient* gradient = new Gradient();
+    auto gradient = std::make_shared<Gradient>();
     gradient->set_gradient(Color(0.3, 0.4, 0.75), Color(1, 1, 1));
     add_object(gradient);
   }
 
   update_game_objects();
 
-  if(solid_tilemaps.size() < 1) { log_warning << "sector '" << name << "' does not contain a solid tile layer." << std::endl; }
+  if(solid_tilemaps.empty()) { log_warning << "sector '" << name << "' does not contain a solid tile layer." << std::endl; }
 
   fix_old_tiles();
   if(!camera) {
     log_warning << "sector '" << name << "' does not contain a camera." << std::endl;
     update_game_objects();
-    add_object(new Camera(this, "Camera"));
+    add_object(std::make_shared<Camera>(this, "Camera"));
   }
 
   update_game_objects();
+  foremost_layer = calculate_foremost_layer();
 }
 
 void
@@ -281,11 +285,11 @@ Sector::parse_old_format(const Reader& reader)
   bkgd_bottom.blue = static_cast<float> (b) / 255.0f;
 
   if(backgroundimage != "") {
-    Background* background = new Background();
+    auto background = std::make_shared<Background>();
     background->set_image(backgroundimage, bgspeed);
     add_object(background);
   } else {
-    Gradient* gradient = new Gradient();
+    auto gradient = std::make_shared<Gradient>();
     gradient->set_gradient(bkgd_top, bkgd_bottom);
     add_object(gradient);
   }
@@ -293,17 +297,17 @@ Sector::parse_old_format(const Reader& reader)
   std::string particlesystem;
   reader.get("particle_system", particlesystem);
   if(particlesystem == "clouds")
-    add_object(new CloudParticleSystem());
+    add_object(std::make_shared<CloudParticleSystem>());
   else if(particlesystem == "snow")
-    add_object(new SnowParticleSystem());
+    add_object(std::make_shared<SnowParticleSystem>());
   else if(particlesystem == "rain")
-    add_object(new RainParticleSystem());
+    add_object(std::make_shared<RainParticleSystem>());
 
   Vector startpos(100, 170);
   reader.get("start_pos_x", startpos.x);
   reader.get("start_pos_y", startpos.y);
 
-  SpawnPoint* spawn = new SpawnPoint;
+  auto spawn = std::make_shared<SpawnPoint>();
   spawn->pos = startpos;
   spawn->name = "main";
   spawnpoints.push_back(spawn);
@@ -322,7 +326,7 @@ Sector::parse_old_format(const Reader& reader)
   std::vector<unsigned int> tiles;
   if(reader.get("interactive-tm", tiles)
      || reader.get("tilemap", tiles)) {
-    TileMap* tilemap = new TileMap(level->get_tileset());
+    auto tilemap = std::make_shared<TileMap>(level->get_tileset());
     tilemap->set(width, height, tiles, LAYER_TILES, true);
 
     // replace tile id 112 (old invisible tile) with 1311 (new invisible tile)
@@ -339,14 +343,14 @@ Sector::parse_old_format(const Reader& reader)
   }
 
   if(reader.get("background-tm", tiles)) {
-    TileMap* tilemap = new TileMap(level->get_tileset());
+    auto tilemap = std::make_shared<TileMap>(level->get_tileset());
     tilemap->set(width, height, tiles, LAYER_BACKGROUNDTILES, false);
     if (height < 19) tilemap->resize(width, 19);
     add_object(tilemap);
   }
 
   if(reader.get("foreground-tm", tiles)) {
-    TileMap* tilemap = new TileMap(level->get_tileset());
+    auto tilemap = std::make_shared<TileMap>(level->get_tileset());
     tilemap->set(width, height, tiles, LAYER_FOREGROUNDTILES, false);
 
     // fill additional space in foreground with tiles of ID 2035 (lightmap/black)
@@ -364,7 +368,7 @@ Sector::parse_old_format(const Reader& reader)
         Vector sp_pos;
         if(reader.get("x", sp_pos.x) && reader.get("y", sp_pos.y))
         {
-          SpawnPoint* sp = new SpawnPoint;
+          auto sp = std::make_shared<SpawnPoint>();
           sp->name = "main";
           sp->pos = sp_pos;
           spawnpoints.push_back(sp);
@@ -380,7 +384,7 @@ Sector::parse_old_format(const Reader& reader)
   if(objects) {
     lisp::ListIterator iter(objects);
     while(iter.next()) {
-      GameObject* object = parse_object(iter.item(), *(iter.lisp()));
+      auto object = parse_object(iter.item(), *(iter.lisp()));
       if(object) {
         add_object(object);
       } else {
@@ -390,12 +394,12 @@ Sector::parse_old_format(const Reader& reader)
   }
 
   // add a camera
-  Camera* camera = new Camera(this, "Camera");
-  add_object(camera);
+  auto camera_ = std::make_shared<Camera>(this, "Camera");
+  add_object(camera_);
 
   update_game_objects();
 
-  if(solid_tilemaps.size() < 1) { log_warning << "sector '" << name << "' does not contain a solid tile layer." << std::endl; }
+  if(solid_tilemaps.empty()) { log_warning << "sector '" << name << "' does not contain a solid tile layer." << std::endl; }
 
   fix_old_tiles();
   update_game_objects();
@@ -404,7 +408,7 @@ Sector::parse_old_format(const Reader& reader)
 void
 Sector::fix_old_tiles()
 {
-  for(std::list<TileMap*>::iterator i = solid_tilemaps.begin(); i != solid_tilemaps.end(); i++) {
+  for(auto i = solid_tilemaps.begin(); i != solid_tilemaps.end(); i++) {
     TileMap* solids = *i;
     for(size_t x=0; x < solids->get_width(); ++x) {
       for(size_t y=0; y < solids->get_height(); ++y) {
@@ -413,27 +417,29 @@ Sector::fix_old_tiles()
         Vector pos = solids->get_tile_position(x, y);
 
         if(id == 112) {
-          add_object(new InvisibleBlock(pos));
+          add_object(std::make_shared<InvisibleBlock>(pos));
           solids->change(x, y, 0);
         } else if(tile->getAttributes() & Tile::COIN) {
-          add_object(new Coin(pos, solids));
+          add_object(std::make_shared<Coin>(pos, solids));
           solids->change(x, y, 0);
         } else if(tile->getAttributes() & Tile::FULLBOX) {
-          add_object(new BonusBlock(pos, tile->getData()));
+          add_object(std::make_shared<BonusBlock>(pos, tile->getData()));
           solids->change(x, y, 0);
         } else if(tile->getAttributes() & Tile::BRICK) {
-          if( ( id == 78 ) || ( id == 105 ) ){
-            add_object( new Brick(pos, tile->getData(), "images/objects/bonus_block/brickIce.sprite") );
+          if( ( id == 3159 ) || ( id == 3160 ) ){
+            add_object( std::make_shared<Brick>(pos, tile->getData(), "images/objects/bonus_block/brickWeb.sprite") );
+          } else if( ( id == 78 ) || ( id == 105 ) ){
+            add_object( std::make_shared<Brick>(pos, tile->getData(), "images/objects/bonus_block/brickIce.sprite") );
           } else if( ( id == 77 ) || ( id == 104 ) ){
-            add_object( new Brick(pos, tile->getData(), "images/objects/bonus_block/brick.sprite") );
+            add_object( std::make_shared<Brick>(pos, tile->getData(), "images/objects/bonus_block/brick.sprite") );
           } else {
             log_warning << "attribute 'brick #t' is not supported for tile-id " << id << std::endl;
-            add_object( new Brick(pos, tile->getData(), "images/objects/bonus_block/brick.sprite") );
+            add_object( std::make_shared<Brick>(pos, tile->getData(), "images/objects/bonus_block/brick.sprite") );
           }
           solids->change(x, y, 0);
         } else if(tile->getAttributes() & Tile::GOAL) {
           std::string sequence = tile->getData() == 0 ? "endsequence" : "stoptux";
-          add_object(new SequenceTrigger(pos, sequence));
+          add_object(std::make_shared<SequenceTrigger>(pos, sequence));
           solids->change(x, y, 0);
         }
       }
@@ -441,8 +447,8 @@ Sector::fix_old_tiles()
   }
 
   // add lights for special tiles
-  for(GameObjects::iterator i = gameobjects.begin(); i != gameobjects.end(); i++) {
-    TileMap* tm = dynamic_cast<TileMap*>(*i);
+  for(auto i = gameobjects.begin(); i != gameobjects.end(); i++) {
+    TileMap* tm = dynamic_cast<TileMap*>(i->get());
     if (!tm) continue;
     for(size_t x=0; x < tm->get_width(); ++x) {
       for(size_t y=0; y < tm->get_height(); ++y) {
@@ -453,7 +459,7 @@ Sector::fix_old_tiles()
         // torch
         if (id == 1517) {
           float pseudo_rnd = (float)((int)pos.x % 10) / 10;
-          add_object(new PulsingLight(center, 1.0f + pseudo_rnd, 0.9f, 1.0f, Color(1.0f, 1.0f, 0.6f, 1.0f)));
+          add_object(std::make_shared<PulsingLight>(center, 1.0f + pseudo_rnd, 0.9f, 1.0f, Color(1.0f, 1.0f, 0.6f, 1.0f)));
         }
         // lava or lavaflow
         if ((id == 173) || (id == 1700) || (id == 1705) || (id == 1706)) {
@@ -462,7 +468,7 @@ Sector::fix_old_tiles()
                && (tm->get_tile_id(x, y-1) != tm->get_tile_id(x,y)))
               || ((x % 3 == 0) && (y % 3 == 0))) {
             float pseudo_rnd = (float)((int)pos.x % 10) / 10;
-            add_object(new PulsingLight(center, 1.0f + pseudo_rnd, 0.8f, 1.0f, Color(1.0f, 0.3f, 0.0f, 1.0f)));
+            add_object(std::make_shared<PulsingLight>(center, 1.0f + pseudo_rnd, 0.8f, 1.0f, Color(1.0f, 0.3f, 0.0f, 1.0f)));
           }
         }
 
@@ -478,8 +484,7 @@ Sector::run_script(std::istream& in, const std::string& sourcename)
   using namespace scripting;
 
   // garbage collect thread list
-  for(ScriptList::iterator i = scripts.begin();
-      i != scripts.end(); ) {
+  for(auto i = scripts.begin(); i != scripts.end(); ) {
     HSQOBJECT& object = *i;
     HSQUIRRELVM vm = object_to_vm(object);
 
@@ -511,30 +516,26 @@ Sector::run_script(std::istream& in, const std::string& sourcename)
 }
 
 void
-Sector::add_object(GameObject* object)
+Sector::add_object(GameObjectPtr object)
 {
   // make sure the object isn't already in the list
 #ifndef NDEBUG
-  for(GameObjects::iterator i = gameobjects.begin(); i != gameobjects.end();
-      ++i) {
+  for(auto i = gameobjects.begin(); i != gameobjects.end(); ++i) {
     assert(*i != object);
   }
-  for(GameObjects::iterator i = gameobjects_new.begin();
-      i != gameobjects_new.end(); ++i) {
+  for(auto i = gameobjects_new.begin(); i != gameobjects_new.end(); ++i) {
     assert(*i != object);
   }
 #endif
 
-  object->ref();
   gameobjects_new.push_back(object);
 }
 
 void
 Sector::activate(const std::string& spawnpoint)
 {
-  SpawnPoint* sp = 0;
-  for(SpawnPoints::iterator i = spawnpoints.begin(); i != spawnpoints.end();
-      ++i) {
+  std::shared_ptr<SpawnPoint> sp;
+  for(auto i = spawnpoints.begin(); i != spawnpoints.end(); ++i) {
     if((*i)->name == spawnpoint) {
       sp = *i;
       break;
@@ -569,9 +570,8 @@ Sector::activate(const Vector& player_pos)
       throw scripting::SquirrelError(vm, "Couldn't set sector in roottable");
     sq_pop(vm, 1);
 
-    for(GameObjects::iterator i = gameobjects.begin();
-        i != gameobjects.end(); ++i) {
-      GameObject* object = *i;
+    for(auto i = gameobjects.begin(); i != gameobjects.end(); ++i) {
+      GameObjectPtr object = *i;
 
       try_expose(object);
     }
@@ -581,9 +581,8 @@ Sector::activate(const Vector& player_pos)
 
   // two-player hack: move other players to main player's position
   // Maybe specify 2 spawnpoints in the level?
-  for(GameObjects::iterator i = gameobjects.begin();
-      i != gameobjects.end(); ++i) {
-    Player* p = dynamic_cast<Player*>(*i);
+  for(auto i = gameobjects.begin(); i != gameobjects.end(); ++i) {
+    Player* p = dynamic_cast<Player*>(i->get());
     if (!p) continue;
 
     // spawn smalltux below spawnpoint
@@ -595,7 +594,8 @@ Sector::activate(const Vector& player_pos)
 
     // spawning tux in the ground would kill him
     if(!is_free_of_tiles(p->get_bbox())) {
-      log_warning << "Tried spawning Tux in solid matter. Compensating." << std::endl;
+      std::string current_level = "[" + Sector::current()->get_level()->filename + "] ";
+      log_warning << current_level << "Tried spawning Tux in solid matter. Compensating." << std::endl;
       Vector npos = p->get_bbox().p1;
       npos.y-=32;
       p->move(npos);
@@ -645,9 +645,8 @@ Sector::deactivate()
     throw scripting::SquirrelError(vm, "Couldn't unset sector in roottable");
   sq_pop(vm, 1);
 
-  for(GameObjects::iterator i = gameobjects.begin();
-      i != gameobjects.end(); ++i) {
-    GameObject* object = *i;
+  for(auto i = gameobjects.begin(); i != gameobjects.end(); ++i) {
+    GameObjectPtr object = *i;
 
     try_unexpose(object);
   }
@@ -664,15 +663,44 @@ Sector::get_active_region()
     camera->get_translation() + Vector(1600, 1200) + Vector(SCREEN_WIDTH,SCREEN_HEIGHT));
 }
 
+int
+Sector::calculate_foremost_layer()
+{
+  int layer = LAYER_BACKGROUND0;
+  for(auto i = gameobjects.begin(); i != gameobjects.end(); ++i)
+  {
+    TileMap* tm = dynamic_cast<TileMap*>(i->get());
+    if (!tm) continue;
+    if(tm->get_layer() > layer)
+    {
+      if( (tm->get_alpha() < 1.0) )
+      {
+        layer = tm->get_layer() - 1;
+      }
+      else
+      {
+        layer = tm->get_layer() + 1;
+      }
+    }
+  }
+  log_debug << "Calculated baduy falling layer was: " << layer << std::endl;
+  return layer;
+}
+
+int
+Sector::get_foremost_layer()
+{
+  return foremost_layer;
+}
+
 void
 Sector::update(float elapsed_time)
 {
   player->check_bounds();
 
   /* update objects */
-  for(GameObjects::iterator i = gameobjects.begin();
-      i != gameobjects.end(); ++i) {
-    GameObject* object = *i;
+  for(auto i = gameobjects.begin(); i != gameobjects.end(); ++i) {
+    GameObjectPtr& object = *i;
     if(!object->is_valid())
       continue;
 
@@ -688,9 +716,9 @@ void
 Sector::update_game_objects()
 {
   /** cleanup marked objects */
-  for(std::vector<GameObject*>::iterator i = gameobjects.begin();
+  for(auto i = gameobjects.begin();
       i != gameobjects.end(); /* nothing */) {
-    GameObject* object = *i;
+    GameObjectPtr& object = *i;
 
     if(object->is_valid()) {
       ++i;
@@ -699,15 +727,14 @@ Sector::update_game_objects()
 
     before_object_remove(object);
 
-    object->unref();
     i = gameobjects.erase(i);
   }
 
   /* add newly created objects */
-  for(std::vector<GameObject*>::iterator i = gameobjects_new.begin();
+  for(auto i = gameobjects_new.begin();
       i != gameobjects_new.end(); ++i)
   {
-    GameObject* object = *i;
+    GameObjectPtr object = *i;
 
     before_object_add(object);
 
@@ -718,10 +745,9 @@ Sector::update_game_objects()
   /* update solid_tilemaps list */
   //FIXME: this could be more efficient
   solid_tilemaps.clear();
-  for(std::vector<GameObject*>::iterator i = gameobjects.begin();
-      i != gameobjects.end(); ++i)
+  for(auto i = gameobjects.begin(); i != gameobjects.end(); ++i)
   {
-    TileMap* tm = dynamic_cast<TileMap*>(*i);
+    TileMap* tm = dynamic_cast<TileMap*>(i->get());
     if (!tm) continue;
     if (tm->is_solid()) solid_tilemaps.push_back(tm);
   }
@@ -729,53 +755,56 @@ Sector::update_game_objects()
 }
 
 bool
-Sector::before_object_add(GameObject* object)
+Sector::before_object_add(GameObjectPtr object)
 {
-  Bullet* bullet = dynamic_cast<Bullet*> (object);
-  if(bullet != NULL) {
+  auto bullet = dynamic_cast<Bullet*>(object.get());
+  if (bullet)
+  {
     bullets.push_back(bullet);
   }
 
-  MovingObject* movingobject = dynamic_cast<MovingObject*> (object);
-  if(movingobject != NULL) {
+  auto movingobject = dynamic_cast<MovingObject*>(object.get());
+  if (movingobject)
+  {
     moving_objects.push_back(movingobject);
   }
 
-  Portable* portable = dynamic_cast<Portable*> (object);
-  if(portable != NULL) {
+  auto portable = dynamic_cast<Portable*>(object.get());
+  if(portable)
+  {
     portables.push_back(portable);
   }
 
-  TileMap* tilemap = dynamic_cast<TileMap*> (object);
-  if(tilemap != NULL && tilemap->is_solid()) {
+  auto tilemap = dynamic_cast<TileMap*>(object.get());
+  if(tilemap && tilemap->is_solid()) {
     solid_tilemaps.push_back(tilemap);
   }
 
-  Camera* camera = dynamic_cast<Camera*> (object);
-  if(camera != NULL) {
+  auto camera_ = dynamic_cast<Camera*>(object.get());
+  if(camera_) {
     if(this->camera != 0) {
       log_warning << "Multiple cameras added. Ignoring" << std::endl;
       return false;
     }
-    this->camera = camera;
+    this->camera = camera_;
   }
 
-  Player* player = dynamic_cast<Player*> (object);
-  if(player != NULL) {
+  auto player_ = dynamic_cast<Player*>(object.get());
+  if(player_) {
     if(this->player != 0) {
       log_warning << "Multiple players added. Ignoring" << std::endl;
       return false;
     }
-    this->player = player;
+    this->player = player_;
   }
 
-  DisplayEffect* effect = dynamic_cast<DisplayEffect*> (object);
-  if(effect != NULL) {
+  auto effect_ = dynamic_cast<DisplayEffect*>(object.get());
+  if(effect_) {
     if(this->effect != 0) {
       log_warning << "Multiple DisplayEffects added. Ignoring" << std::endl;
       return false;
     }
-    this->effect = effect;
+    this->effect = effect_;
   }
 
   if(_current == this) {
@@ -786,9 +815,9 @@ Sector::before_object_add(GameObject* object)
 }
 
 void
-Sector::try_expose(GameObject* object)
+Sector::try_expose(GameObjectPtr object)
 {
-  ScriptInterface* object_ = dynamic_cast<ScriptInterface*> (object);
+  ScriptInterface* object_ = dynamic_cast<ScriptInterface*>(object.get());
   if(object_ != NULL) {
     HSQUIRRELVM vm = scripting::global_vm;
     sq_pushobject(vm, sector_table);
@@ -802,24 +831,24 @@ Sector::try_expose_me()
 {
   HSQUIRRELVM vm = scripting::global_vm;
   sq_pushobject(vm, sector_table);
-  scripting::SSector* this_ = static_cast<scripting::SSector*> (this);
+  scripting::SSector* this_ = static_cast<scripting::SSector*>(this);
   expose_object(vm, -1, this_, "settings", false);
   sq_pop(vm, 1);
 }
 
 void
-Sector::before_object_remove(GameObject* object)
+Sector::before_object_remove(GameObjectPtr object)
 {
-  Portable* portable = dynamic_cast<Portable*> (object);
-  if(portable != NULL) {
+  Portable* portable = dynamic_cast<Portable*>(object.get());
+  if (portable) {
     portables.erase(std::find(portables.begin(), portables.end(), portable));
   }
-  Bullet* bullet = dynamic_cast<Bullet*> (object);
-  if(bullet != NULL) {
+  Bullet* bullet = dynamic_cast<Bullet*>(object.get());
+  if (bullet) {
     bullets.erase(std::find(bullets.begin(), bullets.end(), bullet));
   }
-  MovingObject* moving_object = dynamic_cast<MovingObject*> (object);
-  if(moving_object != NULL) {
+  MovingObject* moving_object = dynamic_cast<MovingObject*>(object.get());
+  if (moving_object) {
     moving_objects.erase(
       std::find(moving_objects.begin(), moving_objects.end(), moving_object));
   }
@@ -829,9 +858,9 @@ Sector::before_object_remove(GameObject* object)
 }
 
 void
-Sector::try_unexpose(GameObject* object)
+Sector::try_unexpose(GameObjectPtr object)
 {
-  ScriptInterface* object_ = dynamic_cast<ScriptInterface*> (object);
+  ScriptInterface* object_ = dynamic_cast<ScriptInterface*>(object.get());
   if(object_ != NULL) {
     HSQUIRRELVM vm = scripting::global_vm;
     SQInteger oldtop = sq_gettop(vm);
@@ -865,15 +894,14 @@ Sector::draw(DrawingContext& context)
   context.push_transform();
   context.set_translation(camera->get_translation());
 
-  for(GameObjects::iterator i = gameobjects.begin();
-      i != gameobjects.end(); ++i) {
-    GameObject* object = *i;
+  for(auto i = gameobjects.begin(); i != gameobjects.end(); ++i) {
+    GameObjectPtr& object = *i;
     if(!object->is_valid())
       continue;
 
     if (draw_solids_only)
     {
-      TileMap* tm = dynamic_cast<TileMap*>(object);
+      TileMap* tm = dynamic_cast<TileMap*>(object.get());
       if (tm && !tm->is_solid())
         continue;
     }
@@ -883,8 +911,7 @@ Sector::draw(DrawingContext& context)
 
   if(show_collrects) {
     Color color(1.0f, 0.0f, 0.0f, 0.75f);
-    for(MovingObjects::iterator i = moving_objects.begin();
-        i != moving_objects.end(); ++i) {
+    for(auto i = moving_objects.begin(); i != moving_objects.end(); ++i) {
       MovingObject* object = *i;
       const Rectf& rect = object->get_bbox();
 
@@ -983,7 +1010,7 @@ Sector::collision_tilemap(collision::Constraints* constraints,
   float y1 = dest.get_top();
   float y2 = dest.get_bottom();
 
-  for(std::list<TileMap*>::const_iterator i = solid_tilemaps.begin(); i != solid_tilemaps.end(); i++) {
+  for(auto i = solid_tilemaps.begin(); i != solid_tilemaps.end(); i++) {
     TileMap* solids = *i;
 
     // test with all tiles in this rectangle
@@ -1038,7 +1065,7 @@ Sector::collision_tile_attributes(const Rectf& dest) const
   float y2 = dest.p2.y;
 
   uint32_t result = 0;
-  for(std::list<TileMap*>::const_iterator i = solid_tilemaps.begin(); i != solid_tilemaps.end(); i++) {
+  for(auto i = solid_tilemaps.begin(); i != solid_tilemaps.end(); i++) {
     TileMap* solids = *i;
 
     // test with all tiles in this rectangle
@@ -1144,8 +1171,7 @@ Sector::collision_static(collision::Constraints* constraints,
   collision_tilemap(constraints, movement, dest, object);
 
   // collision with other (static) objects
-  for(MovingObjects::iterator i = moving_objects.begin();
-      i != moving_objects.end(); ++i) {
+  for(auto i = moving_objects.begin(); i != moving_objects.end(); ++i) {
     MovingObject* moving_object = *i;
     if(moving_object->get_group() != COLGROUP_STATIC
        && moving_object->get_group() != COLGROUP_MOVING_STATIC)
@@ -1268,8 +1294,7 @@ Sector::handle_collisions()
   using namespace collision;
 
   // calculate destination positions of the objects
-  for(MovingObjects::iterator i = moving_objects.begin();
-      i != moving_objects.end(); ++i) {
+  for(auto i = moving_objects.begin(); i != moving_objects.end(); ++i) {
     MovingObject* moving_object = *i;
     Vector mov = moving_object->get_movement();
 
@@ -1284,8 +1309,7 @@ Sector::handle_collisions()
   }
 
   // part1: COLGROUP_MOVING vs COLGROUP_STATIC and tilemap
-  for(MovingObjects::iterator i = moving_objects.begin();
-      i != moving_objects.end(); ++i) {
+  for(auto i = moving_objects.begin(); i != moving_objects.end(); ++i) {
     MovingObject* moving_object = *i;
     if((moving_object->get_group() != COLGROUP_MOVING
         && moving_object->get_group() != COLGROUP_MOVING_STATIC
@@ -1297,8 +1321,7 @@ Sector::handle_collisions()
   }
 
   // part2: COLGROUP_MOVING vs tile attributes
-  for(MovingObjects::iterator i = moving_objects.begin();
-      i != moving_objects.end(); ++i) {
+  for(auto i = moving_objects.begin(); i != moving_objects.end(); ++i) {
     MovingObject* moving_object = *i;
     if((moving_object->get_group() != COLGROUP_MOVING
         && moving_object->get_group() != COLGROUP_MOVING_STATIC
@@ -1313,16 +1336,14 @@ Sector::handle_collisions()
   }
 
   // part2.5: COLGROUP_MOVING vs COLGROUP_TOUCHABLE
-  for(MovingObjects::iterator i = moving_objects.begin();
-      i != moving_objects.end(); ++i) {
+  for(auto i = moving_objects.begin(); i != moving_objects.end(); ++i) {
     MovingObject* moving_object = *i;
     if((moving_object->get_group() != COLGROUP_MOVING
         && moving_object->get_group() != COLGROUP_MOVING_STATIC)
        || !moving_object->is_valid())
       continue;
 
-    for(MovingObjects::iterator i2 = moving_objects.begin();
-        i2 != moving_objects.end(); ++i2) {
+    for(auto i2 = moving_objects.begin(); i2 != moving_objects.end(); ++i2) {
       MovingObject* moving_object_2 = *i2;
       if(moving_object_2->get_group() != COLGROUP_TOUCHABLE
          || !moving_object_2->is_valid())
@@ -1345,8 +1366,7 @@ Sector::handle_collisions()
   }
 
   // part3: COLGROUP_MOVING vs COLGROUP_MOVING
-  for(MovingObjects::iterator i = moving_objects.begin();
-      i != moving_objects.end(); ++i) {
+  for(auto i = moving_objects.begin(); i != moving_objects.end(); ++i) {
     MovingObject* moving_object = *i;
 
     if((moving_object->get_group() != COLGROUP_MOVING
@@ -1354,8 +1374,7 @@ Sector::handle_collisions()
        || !moving_object->is_valid())
       continue;
 
-    for(MovingObjects::iterator i2 = i+1;
-        i2 != moving_objects.end(); ++i2) {
+    for(auto i2 = i+1; i2 != moving_objects.end(); ++i2) {
       MovingObject* moving_object_2 = *i2;
       if((moving_object_2->get_group() != COLGROUP_MOVING
           && moving_object_2->get_group() != COLGROUP_MOVING_STATIC)
@@ -1367,8 +1386,7 @@ Sector::handle_collisions()
   }
 
   // apply object movement
-  for(MovingObjects::iterator i = moving_objects.begin();
-      i != moving_objects.end(); ++i) {
+  for(auto i = moving_objects.begin(); i != moving_objects.end(); ++i) {
     MovingObject* moving_object = *i;
 
     moving_object->bbox = moving_object->dest;
@@ -1381,7 +1399,7 @@ Sector::is_free_of_tiles(const Rectf& rect, const bool ignoreUnisolid) const
 {
   using namespace collision;
 
-  for(std::list<TileMap*>::const_iterator i = solid_tilemaps.begin(); i != solid_tilemaps.end(); i++) {
+  for(auto i = solid_tilemaps.begin(); i != solid_tilemaps.end(); i++) {
     TileMap* solids = *i;
 
     // test with all tiles in this rectangle
@@ -1419,8 +1437,7 @@ Sector::is_free_of_statics(const Rectf& rect, const MovingObject* ignore_object,
 
   if (!is_free_of_tiles(rect, ignoreUnisolid)) return false;
 
-  for(MovingObjects::const_iterator i = moving_objects.begin();
-      i != moving_objects.end(); ++i) {
+  for(auto i = moving_objects.begin(); i != moving_objects.end(); ++i) {
     const MovingObject* moving_object = *i;
     if (moving_object == ignore_object) continue;
     if (!moving_object->is_valid()) continue;
@@ -1439,8 +1456,7 @@ Sector::is_free_of_movingstatics(const Rectf& rect, const MovingObject* ignore_o
 
   if (!is_free_of_tiles(rect)) return false;
 
-  for(MovingObjects::const_iterator i = moving_objects.begin();
-      i != moving_objects.end(); ++i) {
+  for(auto i = moving_objects.begin(); i != moving_objects.end(); ++i) {
     const MovingObject* moving_object = *i;
     if (moving_object == ignore_object) continue;
     if (!moving_object->is_valid()) continue;
@@ -1455,28 +1471,9 @@ Sector::is_free_of_movingstatics(const Rectf& rect, const MovingObject* ignore_o
 }
 
 bool
-Sector::add_bullet(const Vector& pos, const PlayerStatus* player_status, float xm, Direction dir)
-{
-  // TODO remove this function and move these checks elsewhere...
-
-  Bullet* new_bullet = 0;
-  if((player_status->bonus == FIRE_BONUS &&
-      (int)bullets.size() >= player_status->max_fire_bullets) ||
-     (player_status->bonus == ICE_BONUS &&
-      (int)bullets.size() >= player_status->max_ice_bullets))
-    return false;
-  new_bullet = new Bullet(pos, xm, dir, player_status->bonus);
-  add_object(new_bullet);
-
-  sound_manager->play("sounds/shoot.wav");
-
-  return true;
-}
-
-bool
 Sector::add_smoke_cloud(const Vector& pos)
 {
-  add_object(new SmokeCloud(pos));
+  add_object(std::make_shared<SmokeCloud>(pos));
   return true;
 }
 
@@ -1486,16 +1483,16 @@ Sector::play_music(MusicType type)
   currentmusic = type;
   switch(currentmusic) {
     case LEVEL_MUSIC:
-      sound_manager->play_music(music);
+      SoundManager::current()->play_music(music);
       break;
     case HERRING_MUSIC:
-      sound_manager->play_music("music/invincible.ogg");
+      SoundManager::current()->play_music("music/invincible.ogg");
       break;
     case HERRING_WARNING_MUSIC:
-      sound_manager->stop_music(TUX_INVINCIBLE_TIME_WARNING);
+      SoundManager::current()->stop_music(TUX_INVINCIBLE_TIME_WARNING);
       break;
     default:
-      sound_manager->play_music("");
+      SoundManager::current()->play_music("");
       break;
   }
 }
@@ -1510,9 +1507,8 @@ int
 Sector::get_total_badguys()
 {
   int total_badguys = 0;
-  for(GameObjects::iterator i = gameobjects.begin();
-      i != gameobjects.end(); ++i) {
-    BadGuy* badguy = dynamic_cast<BadGuy*> (*i);
+  for(auto i = gameobjects.begin(); i != gameobjects.end(); ++i) {
+    BadGuy* badguy = dynamic_cast<BadGuy*>(i->get());
     if (badguy && badguy->countMe)
       total_badguys++;
   }
@@ -1523,7 +1519,7 @@ Sector::get_total_badguys()
 bool
 Sector::inside(const Rectf& rect) const
 {
-  for(std::list<TileMap*>::const_iterator i = solid_tilemaps.begin(); i != solid_tilemaps.end(); i++) {
+  for(auto i = solid_tilemaps.begin(); i != solid_tilemaps.end(); i++) {
     TileMap* solids = *i;
 
     Rectf bbox = solids->get_bbox();
@@ -1539,8 +1535,7 @@ float
 Sector::get_width() const
 {
   float width = 0;
-  for(std::list<TileMap*>::const_iterator i = solid_tilemaps.begin();
-      i != solid_tilemaps.end(); i++) {
+  for(auto i = solid_tilemaps.begin(); i != solid_tilemaps.end(); i++) {
     TileMap* solids = *i;
     width = std::max(width, solids->get_bbox().get_right());
   }
@@ -1552,7 +1547,7 @@ float
 Sector::get_height() const
 {
   float height = 0;
-  for(std::list<TileMap*>::const_iterator i = solid_tilemaps.begin();
+  for(auto i = solid_tilemaps.begin();
       i != solid_tilemaps.end(); i++) {
     TileMap* solids = *i;
     height = std::max(height, solids->get_bbox().get_bottom());
@@ -1564,7 +1559,7 @@ Sector::get_height() const
 void
 Sector::change_solid_tiles(uint32_t old_tile_id, uint32_t new_tile_id)
 {
-  for(std::list<TileMap*>::const_iterator i = solid_tilemaps.begin(); i != solid_tilemaps.end(); i++) {
+  for(auto i = solid_tilemaps.begin(); i != solid_tilemaps.end(); i++) {
     TileMap* solids = *i;
     solids->change_all(old_tile_id, new_tile_id);
   }
@@ -1597,10 +1592,10 @@ Sector::get_ambient_blue()
 }
 
 void
-Sector::set_gravity(float gravity)
+Sector::set_gravity(float gravity_)
 {
   log_warning << "Changing a Sector's gravitational constant might have unforeseen side-effects" << std::endl;
-  this->gravity = gravity;
+  this->gravity = gravity_;
 }
 
 float
@@ -1616,9 +1611,7 @@ Sector::get_nearest_player (const Vector& pos)
   float nearest_dist = std::numeric_limits<float>::max();
 
   std::vector<Player*> players = Sector::current()->get_players();
-  for (std::vector<Player*>::iterator playerIter = players.begin();
-      playerIter != players.end();
-      ++playerIter)
+  for (auto playerIter = players.begin(); playerIter != players.end(); ++playerIter)
   {
     Player *this_player = *playerIter;
     if (this_player->is_dying() || this_player->is_dead())