diff --git a/src/actions.cpp b/src/actions.cpp index 9d8cf078dad..483d101593d 100644 --- a/src/actions.cpp +++ b/src/actions.cpp @@ -95,7 +95,7 @@ std::string recruit_unit(const gamemap& map, int side, recruit_location,new_unit)); if(disp != NULL && !disp->turbo() && - !disp->shrouded(recruit_location.x,recruit_location.y)) { + !disp->fogged(recruit_location.x,recruit_location.y)) { disp->draw(true,true); for(double alpha = 0.0; alpha <= 1.0; alpha += 0.1) { @@ -596,7 +596,7 @@ void calculate_healing(display& disp, const gamemap& map, const gamemap::location& loc = h->first; const bool show_healing = !disp.turbo() && !recorder.skipping() && - !disp.shrouded(loc.x,loc.y); + !disp.fogged(loc.x,loc.y); assert(units.count(loc) == 1); @@ -908,8 +908,9 @@ void clear_shroud_loc(const gamemap& map, team& tm, adj[6] = loc; for(int i = 0; i != 6; ++i) { if(map.on_board(adj[i])) { - if(tm.shrouded(adj[i].x,adj[i].y)) { + if(tm.fogged(adj[i].x,adj[i].y)) { tm.clear_shroud(adj[i].x,adj[i].y); + tm.clear_fog(adj[i].x,adj[i].y); if(cleared != NULL) { cleared->push_back(adj[i]); } @@ -940,9 +941,11 @@ void clear_shroud_unit(const gamemap& map, const game_data& gamedata, bool clear_shroud(display& disp, const gamemap& map, const game_data& gamedata, const unit_map& units, std::vector& teams, int team) { - if(teams[team].uses_shroud() == false) + if(teams[team].uses_shroud() == false && teams[team].uses_fog() == false) return false; + teams[team].refog(); + for(unit_map::const_iterator i = units.begin(); i != units.end(); ++i) { if(i->second.side() == team+1) { diff --git a/src/ai.cpp b/src/ai.cpp index 318f4cb069e..295612687e7 100644 --- a/src/ai.cpp +++ b/src/ai.cpp @@ -119,7 +119,7 @@ void move_unit(const game_data& gameinfo, display& disp, ignore_zocs,teleport); paths_wiper wiper(disp); - if(!disp.shrouded(from.x,from.y)) + if(!disp.fogged(from.x,from.y)) disp.set_paths(¤t_paths); disp.scroll_to_tiles(from.x,from.y,to.x,to.y); diff --git a/src/display.cpp b/src/display.cpp index 8d5bd53542f..19277b7ac75 100644 --- a/src/display.cpp +++ b/src/display.cpp @@ -169,7 +169,7 @@ SDL_Rect display::screen_area() const void display::select_hex(gamemap::location hex) { - if(team_valid() && teams_[currentTeam_].shrouded(hex.x,hex.y)) { + if(team_valid() && teams_[currentTeam_].fogged(hex.x,hex.y)) { return; } @@ -882,6 +882,10 @@ void display::draw_tile(int x, int y, SDL_Surface* unit_image, image::TYPE image_type = image::SCALED; + if(fogged(x,y)) { + image_type = image::FOGGED; + } + //find if this tile should be greyed if(pathsList_ != NULL && pathsList_->routes.find(gamemap::location(x,y)) == pathsList_->routes.end()) { @@ -1155,7 +1159,7 @@ void display::draw_tile(int x, int y, SDL_Surface* unit_image, draw_footstep(loc,xpos-xsrc,ypos-ysrc); } - if(unit_image == NULL || energy_image == NULL || is_shrouded) + if(unit_image == NULL || energy_image == NULL || fogged(x,y)) return; if(loc != hiddenUnit_) { @@ -1607,7 +1611,7 @@ bool display::unit_attack_ranged(const gamemap::location& a, const gamemap::location& b, int damage, const attack_type& attack) { - const bool hide = update_locked() || shrouded(a.x,a.y) && shrouded(b.x,b.y) + const bool hide = update_locked() || fogged(a.x,a.y) && fogged(b.x,b.y) || preferences::show_combat() == false; const unit_map::iterator att = units_.find(a); @@ -1766,7 +1770,7 @@ bool display::unit_attack_ranged(const gamemap::location& a, void display::unit_die(const gamemap::location& loc, SDL_Surface* image) { - if(update_locked() || shrouded(loc.x,loc.y) + if(update_locked() || fogged(loc.x,loc.y) || preferences::show_combat() == false) return; @@ -1799,7 +1803,7 @@ bool display::unit_attack(const gamemap::location& a, const gamemap::location& b, int damage, const attack_type& attack) { - const bool hide = update_locked() || shrouded(a.x,a.y) && shrouded(b.x,b.y) + const bool hide = update_locked() || fogged(a.x,a.y) && fogged(b.x,b.y) || preferences::show_combat() == false; if(!hide) { @@ -1982,8 +1986,8 @@ void display::move_unit_between(const gamemap::location& a, const unit& u) { if(update_locked() || team_valid() - && teams_[currentTeam_].shrouded(a.x,a.y) - && teams_[currentTeam_].shrouded(b.x,b.y)) + && teams_[currentTeam_].fogged(a.x,a.y) + && teams_[currentTeam_].fogged(b.x,b.y)) return; const bool face_left = u.facing_left(); @@ -2341,6 +2345,14 @@ bool display::shrouded(int x, int y) const return false; } +bool display::fogged(int x, int y) const +{ + if(team_valid()) + return teams_[currentTeam_].fogged(x,y); + else + return false; +} + bool display::team_valid() const { return currentTeam_ < teams_.size(); diff --git a/src/display.hpp b/src/display.hpp index 0d6f76a286d..c200abb55b2 100644 --- a/src/display.hpp +++ b/src/display.hpp @@ -238,6 +238,8 @@ public: //function which returns true if location (x,y) is covered in shroud. bool shrouded(int x, int y) const; + bool fogged(int x, int y) const; + private: display(const display&); void operator=(const display&); diff --git a/src/image.cpp b/src/image.cpp index d4a8ee6aa80..0d96340b588 100644 --- a/src/image.cpp +++ b/src/image.cpp @@ -11,7 +11,7 @@ namespace { typedef std::map image_map; -image_map images_,scaledImages_,greyedImages_,brightenedImages_; +image_map images_,scaledImages_,greyedImages_,brightenedImages_,foggedImages_; int red_adjust = 0, green_adjust = 0, blue_adjust = 0; @@ -106,6 +106,7 @@ void flush_cache() { clear_surfaces(images_); clear_surfaces(scaledImages_); + clear_surfaces(foggedImages_); clear_surfaces(greyedImages_); clear_surfaces(brightenedImages_); } @@ -134,6 +135,7 @@ void set_colour_adjustment(int r, int g, int b) green_adjust = g; blue_adjust = b; clear_surfaces(scaledImages_); + clear_surfaces(foggedImages_); clear_surfaces(greyedImages_); clear_surfaces(brightenedImages_); } @@ -144,6 +146,7 @@ void set_zoom(double amount) if(amount != zoom) { zoom = amount; clear_surfaces(scaledImages_); + clear_surfaces(foggedImages_); clear_surfaces(greyedImages_); clear_surfaces(brightenedImages_); } @@ -156,13 +159,27 @@ SDL_Surface* get_image(const std::string& filename,TYPE type) return NULL; } - if(type == GREYED) + if(type == GREYED) { return get_tinted(filename,GREY_IMAGE); - - else if(type == BRIGHTENED) + } else if(type == BRIGHTENED) { return get_tinted(filename,BRIGHTEN_IMAGE); + } else if(type == FOGGED) { + const image_map::iterator i = foggedImages_.find(filename); + if(i != foggedImages_.end()) + return i->second; - std::map::iterator i; + SDL_Surface* const surf = get_image(filename,SCALED); + if(surf == NULL) + return NULL; + + SDL_Surface* const image = scale_surface(surf,surf->w,surf->h); + adjust_surface_colour(image,-50,-50,-50); + foggedImages_.insert(std::pair(filename, + image)); + return image; + } + + image_map::iterator i; if(type == SCALED) { i = scaledImages_.find(filename); diff --git a/src/image.hpp b/src/image.hpp index 5b17c45200b..790b37aa733 100644 --- a/src/image.hpp +++ b/src/image.hpp @@ -42,7 +42,7 @@ namespace image { //scaled images. void set_zoom(double zoom); - enum TYPE { UNSCALED, SCALED, GREYED, BRIGHTENED }; + enum TYPE { UNSCALED, SCALED, FOGGED, GREYED, BRIGHTENED }; //function to get the surface corresponding to an image. SDL_Surface* get_image(const std::string& filename,TYPE type=SCALED); diff --git a/src/team.cpp b/src/team.cpp index 4a17c933b11..1849d3f23d6 100644 --- a/src/team.cpp +++ b/src/team.cpp @@ -10,6 +10,7 @@ See the COPYING file for more details. */ + #include "game_config.hpp" #include "replay.hpp" #include "team.hpp" @@ -92,6 +93,7 @@ team::team_info::team_info(const config& cfg) } use_shroud = (cfg["shroud"] == "yes"); + use_fog = (cfg["fog"] == "yes"); music = cfg["music"]; } @@ -240,6 +242,47 @@ void team::clear_shroud(size_t x, size_t y) shroud_[x][y] = true; } +bool team::uses_fog() const +{ + return info_.use_fog; +} + +bool team::fogged(size_t x, size_t y) const +{ + if(info_.use_fog == false) + return shrouded(x,y); + + if(x >= fog_.size()) + return true; + + if(y >= fog_[x].size()) + return true; + + return !fog_[x][y]; +} + +void team::clear_fog(size_t x, size_t y) +{ + if(info_.use_fog == false) + return; + + if(x >= fog_.size()) + fog_.resize(x+1); + + if(y >= fog_[x].size()) + fog_[x].resize(y+1); + + fog_[x][y] = true; +} + +void team::refog() +{ + for(std::vector >::iterator i = fog_.begin(); + i != fog_.end(); ++i) { + std::fill(i->begin(),i->end(),false); + } +} + const std::string& team::music() const { return info_.music; diff --git a/src/team.hpp b/src/team.hpp index f9501a43c33..2ca68836ad5 100644 --- a/src/team.hpp +++ b/src/team.hpp @@ -50,7 +50,7 @@ public: std::vector targets; - bool use_shroud; + bool use_shroud, use_fog; std::string music; }; @@ -88,12 +88,18 @@ public: bool shrouded(size_t x, size_t y) const; void clear_shroud(size_t x, size_t y); + bool uses_fog() const; + bool fogged(size_t x, size_t y) const; + void clear_fog(size_t x, size_t y); + void refog(); + const std::string& music() const; private: int gold_; std::set towers_; std::vector > shroud_; + std::vector > fog_; team_info info_; };