apply patch 3176 by jamit:

fog does not recover discovered hex until end of turn
This commit is contained in:
Jérémy Rosen 2012-03-14 21:35:03 +00:00
parent 0c6a9f8666
commit fcc5e09153
12 changed files with 111 additions and 32 deletions

View file

@ -98,6 +98,7 @@ Version 1.11.0-svn:
* Made add-ons with markup characters at the start of their titles
display normally in the add-ons management dialogs (e.g. without
colors)
* Re-fogging does not occur in the middle of the player's turn.
* Whiteboard
* Fixed bug #19369: Using planning mode can cause losing ability to move my units
* Fixed bug #19408: Crash shortly after executing invalid multi-turn move
@ -138,6 +139,7 @@ Version 1.11.0-svn:
a negative value in the [drain] or [heal_on_hit] weapon special.
* Negative drain amounts will not take a unit below 1 health.
* Added [show_if] support to [objectives] [note]
* New tags: [lift_fog] and [reset_fog].
* Miscellaneous and bug fixes:
* Fix wrong preferences path suffix (1.1 instead of 1.10) on Linux and other
platforms using XDG layout (no compiled-in preferences path override,

View file

@ -984,6 +984,9 @@
[entry]
name = "Herb Pah (haiz)"
[/entry]
[entry]
name = "J. Tyne (JaMiT)"
[/entry]
[entry]
name = "J.R. Blain (Cowboy)"
[/entry]

View file

@ -65,6 +65,7 @@ Version 1.11.0-svn:
* Added a Reset All button to Hotkey Settings dialog in preferences
(feature/bug #3797)
* Map editor now displays invisible overlay terrains on main map.
* Re-fogging does not occur in the middle of the player's turn.
* Whiteboard
* Fixed bug #19369 : Using planning mode can cause losing ability to move my

View file

@ -1258,6 +1258,7 @@ class attack
const battle_context_unit_stats *d_stats_;
int abs_n_attack_, abs_n_defend_;
// update_att_fog_ is not used, other than making some code simpler.
bool update_att_fog_, update_def_fog_, update_minimap_;
unit_info a_, d_;
@ -1293,7 +1294,6 @@ void attack::fire_event(const std::string& n)
return;
}
const int defender_side = d_.get_unit().side();
const int attacker_side = a_.get_unit().side();
game_events::fire(n, game_events::entity_location(a_.loc_, a_.id_),
game_events::entity_location(d_.loc_, d_.id_), ev_data);
@ -1302,7 +1302,6 @@ void attack::fire_event(const std::string& n)
refresh_bc();
if(!a_.valid() || !d_.valid() || !(*resources::teams)[a_.get_unit().side() - 1].is_enemy(d_.get_unit().side())) {
if (update_display_){
recalculate_fog(attacker_side);
recalculate_fog(defender_side);
resources::screen->recalculate_minimap();
resources::screen->draw(true, true);
@ -1821,7 +1820,6 @@ void attack::perform()
bool defender_strikes_first = (d_stats_->firststrike && !a_stats_->firststrike);
unsigned int rounds = std::max<unsigned int>(a_stats_->rounds, d_stats_->rounds) - 1;
const int attacker_side = a_.get_unit().side();
const int defender_side = d_.get_unit().side();
LOG_NG << "Fight: (" << a_.loc_ << ") vs (" << d_.loc_ << ") ATT: " << a_stats_->weapon->name() << " " << a_stats_->damage << "-" << a_stats_->num_blows << "(" << a_stats_->chance_to_hit << "%) vs DEF: " << (d_stats_->weapon ? d_stats_->weapon->name() : "none") << " " << d_stats_->damage << "-" << d_stats_->num_blows << "(" << d_stats_->chance_to_hit << "%)" << (defender_strikes_first ? " defender first-strike" : "") << "\n";
@ -1863,14 +1861,6 @@ void attack::perform()
}
// TODO: if we knew the viewing team, we could skip some of these display update
if (update_att_fog_ && (*resources::teams)[attacker_side - 1].uses_fog())
{
recalculate_fog(attacker_side);
if (update_display_) {
resources::screen->invalidate_all();
resources::screen->recalculate_minimap();
}
}
if (update_def_fog_ && (*resources::teams)[defender_side - 1].uses_fog())
{
recalculate_fog(defender_side);
@ -2379,6 +2369,16 @@ namespace {
}
/**
* Function that recalculates the fog of war.
*
* This is used at the end of a turn and for the defender at the end of
* combat. As a back-up, it is also called when clearing shroud at the
* beginning of a turn.
* This function does nothing if the indicated side does not use fog.
*
* @param[in] side The side whose fog will be recalculated.
*/
void recalculate_fog(int side)
{
team &tm = (*resources::teams)[side - 1];
@ -2402,7 +2402,18 @@ void recalculate_fog(int side)
game_events::pump();
}
bool clear_shroud(int side)
/**
* Function that will clear shroud (and fog) based on current unit positions.
*
* This will not re-fog hexes unless reset_fog is set to true.
* This function will do nothing if the side uses neither shroud nor fog.
*
* @param[in] side The side whose shroud (and fog) will be cleared.
* @param[in] reset_fog If set to true, the fog will also be recalculated
* (refogging hexes that can no longer be seen).
* @returns true if some shroud/fog is actually cleared away.
*/
bool clear_shroud(int side, bool reset_fog)
{
team &tm = (*resources::teams)[side - 1];
if (!tm.uses_shroud() && !tm.uses_fog())
@ -2423,7 +2434,7 @@ bool clear_shroud(int side)
// don't want to pump it here
game_events::pump();
if (tm.uses_fog()) {
if ( reset_fog ) {
recalculate_fog(side);
}

View file

@ -412,15 +412,11 @@ size_t move_unit(move_unit_spectator* move_spectator,
bool continue_move = false, bool should_clear_shroud=true, bool is_replay=false,
bool* units_sighted_result = NULL);
/** Function which recalculates the fog. */
/// Function that recalculates the fog of war.
void recalculate_fog(int side);
/**
* Function which will clear shroud away for the @a side
* based on current unit positions.
* Returns true if some shroud is actually cleared away.
*/
bool clear_shroud(int side);
/// Function that will clear shroud (and fog) based on current unit positions.
bool clear_shroud(int side, bool reset_fog=false);
/**
* Function to apply pending shroud changes in the undo stack.

View file

@ -716,17 +716,19 @@ namespace {
static void toggle_shroud(const bool remove, const vconfig& cfg)
{
// Filter the sides.
std::vector<int> sides = game_events::get_sides_vector(cfg);
size_t index;
// Filter the locations.
std::set<map_location> locs;
const terrain_filter filter(cfg, *resources::units);
filter.get_locations(locs, true);
foreach (const int &side_num, sides)
{
index = side_num - 1;
team &t = (*resources::teams)[index];
std::set<map_location> locs;
terrain_filter filter(cfg, *resources::units);
filter.restrict_size(game_config::max_loop);
filter.get_locations(locs, true);
foreach (map_location const &loc, locs)
{
@ -753,6 +755,45 @@ WML_HANDLER_FUNCTION(place_shroud, /*event_info*/,cfg)
toggle_shroud(false,cfg );
}
/* Implements the lifting and resetting of fog via WML.
*/
static void toggle_fog(const bool clear, const vconfig& cfg)
{
// Filter the sides.
const vconfig &ssf = cfg.child("filter_side");
const side_filter s_filter(ssf.null() ? vconfig::empty_vconfig() : ssf);
const std::vector<int> sides = s_filter.get_teams();
// Filter the locations.
std::set<map_location> locs;
const terrain_filter t_filter(cfg, *resources::units);
t_filter.get_locations(locs, true);
// Loop through sides.
foreach (const int &side_num, sides)
{
team &t = (*resources::teams)[side_num-1];
if ( clear )
t.add_fog_override(locs);
else
t.remove_fog_override(locs);
}
// Flag a screen update.
resources::screen->recalculate_minimap();
resources::screen->invalidate_all();
}
WML_HANDLER_FUNCTION(lift_fog, /*event_info*/, cfg)
{
toggle_fog(true, cfg);
}
WML_HANDLER_FUNCTION(reset_fog, /*event_info*/,cfg)
{
toggle_fog(false, cfg);
}
WML_HANDLER_FUNCTION(tunnel, /*event_info*/, cfg)
{
const bool remove = cfg["remove"].to_bool(false);

View file

@ -540,7 +540,7 @@ void play_controller::init_gui(){
gui_->update_tod();
for(std::vector<team>::iterator t = teams_.begin(); t != teams_.end(); ++t) {
::clear_shroud(t - teams_.begin() + 1);
clear_shroud(t - teams_.begin() + 1, true);
}
}
@ -646,7 +646,7 @@ void play_controller::do_init_side(const unsigned int team_index, bool is_replay
sound::play_sound(tod.sounds, sound::SOUND_SOURCES);
if (!recorder.is_skipping()){
::clear_shroud(team_index + 1);
clear_shroud(team_index + 1, true);
gui_->invalidate_all();
}

View file

@ -171,7 +171,6 @@ protected:
void place_sides_in_preferred_locations();
virtual void finish_side_turn();
void finish_turn();
bool clear_shroud();
bool enemies_visible() const;
void enter_textbox();

View file

@ -97,9 +97,6 @@ void playsingle_controller::init_gui(){
update_locker lock_display(gui_->video(),recorder.is_skipping());
events::raise_draw_event();
gui_->draw();
for(std::vector<team>::iterator t = teams_.begin(); t != teams_.end(); ++t) {
::clear_shroud(t - teams_.begin() + 1);
}
}
void playsingle_controller::recruit(){
@ -843,7 +840,7 @@ void playsingle_controller::play_ai_turn(){
turn_data.sync_network();
gui_->recalculate_minimap();
::clear_shroud(player_number_);
recalculate_fog(player_number_);
gui_->invalidate_unit();
gui_->invalidate_game_status();
gui_->invalidate_all();

View file

@ -457,7 +457,7 @@ void replay_controller::update_teams(){
gui_->set_team(show_team_ - 1, show_everything_);
}
::clear_shroud(next_team);
clear_shroud(next_team);
gui_->set_playing_team(next_team - 1);
gui_->invalidate_all();

View file

@ -279,6 +279,7 @@ team::team() :
villages_(),
shroud_(),
fog_(),
fog_clearer_(),
auto_shroud_updates_(true),
info_(),
countdown_time_(0),
@ -525,6 +526,10 @@ bool team::fogged(const map_location& loc) const
{
if(shrouded(loc)) return true;
// Check for an override of fog.
if ( fog_clearer_.count(loc) > 0 )
return false;
if(!teams)
return fog_.value(loc.x+1,loc.y+1);
@ -590,6 +595,24 @@ bool team::copy_ally_shroud()
return shroud_.copy_from(ally_shroud(*teams));
}
/**
* Removes the record of hexes that were cleared of fog via WML.
* @param[in] hexes The hexes to no longer keep clear.
*/
void team::remove_fog_override(const std::set<map_location> &hexes)
{
// Take a set difference.
std::vector<map_location> result(fog_clearer_.size());
std::vector<map_location>::iterator result_end =
std::set_difference(fog_clearer_.begin(), fog_clearer_.end(),
hexes.begin(), hexes.end(), result.begin());
// Put the result into fog_clearer_.
fog_clearer_.clear();
fog_clearer_.insert(result.begin(), result_end);
}
int team::nteams()
{
if(teams == NULL) {

View file

@ -248,6 +248,10 @@ public:
bool knows_about_team(size_t index, bool is_multiplayer) const;
bool copy_ally_shroud();
/// Records hexes that were cleared of fog via WML.
void add_fog_override(const std::set<map_location> &hexes) { fog_clearer_.insert(hexes.begin(), hexes.end()); }
/// Removes the record of hexes that were cleared of fog via WML.
void remove_fog_override(const std::set<map_location> &hexes);
bool auto_shroud_updates() const { return auto_shroud_updates_; }
void set_auto_shroud_updates(bool value) { auto_shroud_updates_ = value; }
@ -297,6 +301,8 @@ private:
std::set<map_location> villages_;
shroud_map shroud_, fog_;
/// Stores hexes that have been cleared of fog via WML.
std::set<map_location> fog_clearer_;
bool auto_shroud_updates_;