From a8b7979d199a2165fe25533943bd8972fd81b275 Mon Sep 17 00:00:00 2001 From: Christoph Sommer Date: Mon, 23 Oct 2006 16:27:22 +0000 Subject: [PATCH] Allow solidity of tilemaps to be changed at runtime. Do not change non-solids to solid yet - no idea what the CD will make of this SVN-Revision: 4418 --- src/object/particlesystem_interactive.cpp | 1 + src/object/tilemap.cpp | 7 ++++++ src/object/tilemap.hpp | 5 ++++ src/sector.cpp | 42 +++++++++++++++++++++++++++++-- src/sector.hpp | 8 +++++- 5 files changed, 60 insertions(+), 3 deletions(-) diff --git a/src/object/particlesystem_interactive.cpp b/src/object/particlesystem_interactive.cpp index 2d4a3c2ee..b188d9bcd 100644 --- a/src/object/particlesystem_interactive.cpp +++ b/src/object/particlesystem_interactive.cpp @@ -97,6 +97,7 @@ ParticleSystem_Interactive::collision(Particle* object, Vector movement) for(std::list::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); diff --git a/src/object/tilemap.cpp b/src/object/tilemap.cpp index ec91db212..836401d2c 100644 --- a/src/object/tilemap.cpp +++ b/src/object/tilemap.cpp @@ -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 { diff --git a/src/object/tilemap.hpp b/src/object/tilemap.hpp index b70aca19e..f86515da3 100644 --- a/src/object/tilemap.hpp +++ b/src/object/tilemap.hpp @@ -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) diff --git a/src/sector.cpp b/src/sector.cpp index 8ff2d8f66..f43170afb 100644 --- a/src/sector.cpp +++ b/src/sector.cpp @@ -355,6 +355,7 @@ Sector::fix_old_tiles() { for(std::list::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::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 (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 (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 (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 (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::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::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::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::const_iterator i = solid_tilemaps.begin(); i != solid_tilemaps.end(); i++) { TileMap* solids = *i; + solids->change_all(old_tile_id, new_tile_id); } } diff --git a/src/sector.hpp b/src/sector.hpp index cdc59b6f4..9706bce91 100644 --- a/src/sector.hpp +++ b/src/sector.hpp @@ -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 solid_tilemaps; + std::list tilemaps; /**< list of all tilemaps in this sector */ + std::list solid_tilemaps; /**< list of tilemaps to consider for collision detection */ Camera* camera; }; -- 2.11.0