Allow solidity of tilemaps to be changed at runtime. Do not change non-solids to...
authorChristoph Sommer <mail@christoph-sommer.de>
Mon, 23 Oct 2006 16:27:22 +0000 (16:27 +0000)
committerChristoph Sommer <mail@christoph-sommer.de>
Mon, 23 Oct 2006 16:27:22 +0000 (16:27 +0000)
SVN-Revision: 4418

src/object/particlesystem_interactive.cpp
src/object/tilemap.cpp
src/object/tilemap.hpp
src/sector.cpp
src/sector.hpp

index 2d4a3c2..b188d9b 100644 (file)
@@ -97,6 +97,7 @@ ParticleSystem_Interactive::collision(Particle* object, Vector movement)
 
   for(std::list<TileMap*>::const_iterator i = Sector::current()->solid_tilemaps.begin(); i != Sector::current()->solid_tilemaps.end(); i++) {
     TileMap* solids = *i;
+
     for(int x = starttilex; x*32 < max_x; ++x) {
       for(int y = starttiley; y*32 < max_y; ++y) {
        const Tile* tile = solids->get_tile(x, y);
index ec91db2..836401d 100644 (file)
@@ -145,6 +145,7 @@ TileMap::update(float elapsed_time)
       if (amt > 0) current_alpha = std::min(current_alpha + amt, alpha);
       if (amt < 0) current_alpha = std::max(current_alpha + amt, alpha);
     }
+    if (current_alpha < 0.25) set_solid(false);
   }
 
   // if we have a path to follow, follow it
@@ -284,6 +285,12 @@ TileMap::resize(int new_width, int new_height)
   width = new_width;
 }
 
+void 
+TileMap::set_solid(bool solid) 
+{
+  this->solid = solid;
+}
+
 const Tile*
 TileMap::get_tile(int x, int y) const
 {
index b70aca1..f86515d 100644 (file)
@@ -100,6 +100,11 @@ public:
   bool is_solid() const
   { return solid; }
 
+  /**
+   * Changes Tilemap's solidity, i.e. whether to consider it when doing collision detection.
+   */
+  void set_solid(bool solid = true);
+
   /// returns tile in row y and column y (of the tilemap)
   const Tile* get_tile(int x, int y) const;
   /// returns tile at position pos (in world coordinates)
index 8ff2d8f..f43170a 100644 (file)
@@ -355,6 +355,7 @@ Sector::fix_old_tiles()
 {
   for(std::list<TileMap*>::iterator 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) {
        const Tile* tile = solids->get_tile(x, y);
@@ -605,11 +606,38 @@ Sector::get_active_region()
     camera->get_translation() + Vector(1600, 1200));
 }
 
+namespace {
+  bool is_tilemap_solid(const TileMap* tm) { return tm->is_solid(); }
+  bool is_tilemap_nonsolid(const TileMap* tm) { return !tm->is_solid(); }
+}
+
+void
+Sector::update_solid_tilemap_list()
+{
+
+  // remove non-solid tilemaps from list
+  solid_tilemaps.erase(std::remove_if(solid_tilemaps.begin(), solid_tilemaps.end(), is_tilemap_nonsolid), solid_tilemaps.end());
+  
+  // if tilemaps are to be added, create new list of solid tilemaps
+  if (solid_tilemaps.size() != (unsigned int)std::count_if(tilemaps.begin(), tilemaps.end(), is_tilemap_solid)) {
+    log_debug << "Found new solid tilemaps - this is eeevil! Re-creating list of solid tilemaps." << std::endl;
+    solid_tilemaps.clear();
+    for(std::list<TileMap*>::iterator i = tilemaps.begin(); i != tilemaps.end(); i++) {
+      TileMap* tm = *i;
+      if (tm->is_solid()) solid_tilemaps.push_back(tm);
+    }
+  }
+
+}
+
 void
 Sector::update(float elapsed_time)
 {
   player->check_bounds(camera);
 
+  // update solid_tilemaps list
+  update_solid_tilemap_list();
+
   /* update objects */
   for(GameObjects::iterator i = gameobjects.begin();
           i != gameobjects.end(); ++i) {
@@ -676,8 +704,9 @@ Sector::before_object_add(GameObject* object)
   }
 
   TileMap* tilemap = dynamic_cast<TileMap*> (object);
-  if(tilemap != NULL && tilemap->is_solid()) {
-    solid_tilemaps.push_back(tilemap);
+  if(tilemap != NULL) {
+    tilemaps.push_back(tilemap);
+    if (tilemap->is_solid()) solid_tilemaps.push_back(tilemap);
   }
 
   Camera* camera = dynamic_cast<Camera*> (object);
@@ -734,6 +763,11 @@ Sector::before_object_remove(GameObject* object)
   if(portable != NULL) {
     portables.erase(std::find(portables.begin(), portables.end(), portable));
   }
+  TileMap* tilemap = dynamic_cast<TileMap*> (object);
+  if(tilemap != NULL) {
+    tilemaps.erase(std::find(tilemaps.begin(), tilemaps.end(), tilemap));
+    if (tilemap->is_solid()) solid_tilemaps.erase(std::find(solid_tilemaps.begin(), solid_tilemaps.end(), tilemap));
+  }
   Bullet* bullet = dynamic_cast<Bullet*> (object);
   if(bullet != NULL) {
     bullets.erase(std::find(bullets.begin(), bullets.end(), bullet));
@@ -1398,6 +1432,7 @@ Sector::inside(const Rect& rect) const
 {
   for(std::list<TileMap*>::const_iterator i = solid_tilemaps.begin(); i != solid_tilemaps.end(); i++) {
     TileMap* solids = *i;
+
     bool horizontally = ((rect.p2.x >= 0 + solids->get_x_offset()) && (rect.p1.x <= solids->get_width() * 32 + solids->get_x_offset()));
     bool vertically = (rect.p1.y <= solids->get_height() * 32 + solids->get_y_offset());
     if (horizontally && vertically) return true;
@@ -1411,6 +1446,7 @@ Sector::get_width() const
   float width = 0;
   for(std::list<TileMap*>::const_iterator i = solid_tilemaps.begin(); i != solid_tilemaps.end(); i++) {
     TileMap* solids = *i;
+
     if ((solids->get_width() * 32 + solids->get_x_offset()) > width) width = (solids->get_width() * 32 + solids->get_x_offset());
   }
   return width;
@@ -1422,6 +1458,7 @@ Sector::get_height() const
   float height = 0;
   for(std::list<TileMap*>::const_iterator i = solid_tilemaps.begin(); i != solid_tilemaps.end(); i++) {
     TileMap* solids = *i;
+
     if ((solids->get_height() * 32 + solids->get_y_offset()) > height) height = (solids->get_height() * 32 + solids->get_y_offset());
   }
   return height;
@@ -1432,6 +1469,7 @@ 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++) {
     TileMap* solids = *i;
+
     solids->change_all(old_tile_id, new_tile_id);
   }
 }
index cdc59b6..9706bce 100644 (file)
@@ -203,6 +203,11 @@ private:
   void try_unexpose(GameObject* object);
   void try_expose_me();
   void try_unexpose_me();
+  
+  /**
+   * Adds solid tilemaps to list, removes non-solid ones
+   */
+  void update_solid_tilemap_list();
 
   /** Checks for all possible collisions. And calls the
       collision_handlers, which the collision_objects provide for this
@@ -269,7 +274,8 @@ public: // TODO make this private again
   // some special objects, where we need direct access
   // (try to avoid accessing them directly)
   Player* player;
-  std::list<TileMap*> solid_tilemaps;
+  std::list<TileMap*> tilemaps; /**< list of all tilemaps in this sector */
+  std::list<TileMap*> solid_tilemaps; /**< list of tilemaps to consider for collision detection */
   Camera* camera;
 };