Give animations a chance (optional) to progress...

...while fog/shroud clearing occurs.

This should help with bug #20324, maybe fix it.

The chance is optional because there are times when we do not want the
delays, such as when starting a scenario.
This commit is contained in:
J. Tyne 2013-02-03 19:05:22 +00:00
parent a72b9d42f7
commit dc94548255
4 changed files with 48 additions and 17 deletions

View file

@ -254,11 +254,12 @@ namespace { // Private helpers for move_unit()
inline bool check_for_obstructing_unit(const map_location & hex,
const map_location & prev_hex);
/// Moves the unit the next step.
inline void do_move(const route_iterator & step_from,
inline bool do_move(const route_iterator & step_from,
const route_iterator & step_to,
unit_display::unit_mover & animator);
/// Clears fog/shroud and handles units being sighted.
inline void handle_fog(const map_location & hex, bool ally_interrupts);
inline void handle_fog(const map_location & hex, bool ally_interrupts,
bool new_animation);
inline bool is_reasonable_stop(const map_location & hex) const;
/// Reveals the units stored in to_reveal_.
inline void reveal_ambushers() const;
@ -467,8 +468,9 @@ namespace { // Private helpers for move_unit()
* @a step_from is the hex before that in the route.
* (The unit is actually at *move_loc_.)
* @a animator is the unit_display::unit_mover being used.
* @return whether or not we started a new animation.
*/
inline void unit_mover::do_move(const route_iterator & step_from,
inline bool unit_mover::do_move(const route_iterator & step_from,
const route_iterator & step_to,
unit_display::unit_mover & animator)
{
@ -505,6 +507,8 @@ namespace { // Private helpers for move_unit()
do_move_track_ = current_tracking;
disp.redraw_minimap();
}
return move_result.second;
}
@ -514,11 +518,13 @@ namespace { // Private helpers for move_unit()
* @a hex is both the center of fog clearing and the filtered location of
* the moving unit when the sighted events will be fired.
*/
inline void unit_mover::handle_fog(const map_location & hex, bool ally_interrupts)
inline void unit_mover::handle_fog(const map_location & hex, bool ally_interrupts,
bool new_animation)
{
// Clear the fog.
if ( clearer_.clear_unit(hex, *move_it_, *current_team_, NULL,
&enemy_count_, &friend_count_, spectator_) )
&enemy_count_, &friend_count_, spectator_,
!new_animation) )
{
clearer_.invalidate_after_clear();
fog_changed_ = true;
@ -920,10 +926,10 @@ namespace { // Private helpers for move_unit()
break;
// We can leave *step_from. Make the move to *real_end_.
do_move(step_from, real_end_, animator);
bool new_animation = do_move(step_from, real_end_, animator);
// Update the fog.
if ( current_uses_fog_ )
handle_fog(*real_end_, ally_interrupts);
handle_fog(*real_end_, ally_interrupts, new_animation);
animator.wait_for_anims();
// Fire the events for this step.

View file

@ -643,7 +643,8 @@ size_t undo_list::apply_shroud_changes() const
std::vector<map_location>::const_iterator step;
for (step = action.route.begin(); step != action.route.end(); ++step) {
// Clear the shroud, collecting new sighted events.
if ( clearer.clear_unit(*step, *action.affected_unit, tm) ) {
// (This can be made gradual by changing "true" tp "false".)
if ( clearer.clear_unit(*step, *action.affected_unit, tm, true) ) {
cleared_shroud = true;
erase_to = i + 1;
}

View file

@ -279,6 +279,7 @@ bool shroud_clearer::clear_loc(team &tm, const map_location &loc,
* @param enemy_count Incremented for each enemy uncovered (excluding known_units).
* @param friend_count Incremented for each friend uncovered (excluding known_units).
* @param spectator Will be told of uncovered units (excluding known_units).
* @param instant If true, then drawing delays (used to make animations look better) are suppressed.
*
* @return whether or not information was uncovered (i.e. returns true if any
* locations in visual range were fogged/shrouded under shared vision/maps).
@ -287,8 +288,12 @@ bool shroud_clearer::clear_unit(const map_location &view_loc,
const unit &viewer, team &view_team,
const std::set<map_location>* known_units,
size_t * enemy_count, size_t * friend_count,
move_unit_spectator * spectator)
move_unit_spectator * spectator, bool instant)
{
// Give animations a chance to progress; see bug #20324.
if ( !instant && resources::screen )
resources::screen->draw(true);
bool cleared_something = false;
// Dummy variables to make some logic simpler.
size_t enemies=0, friends=0;
@ -298,11 +303,20 @@ bool shroud_clearer::clear_unit(const map_location &view_loc,
friend_count = &friends;
// Make sure the jamming map is up-to-date.
if ( view_team_ != &view_team )
if ( view_team_ != &view_team ) {
calculate_jamming(&view_team);
// Give animations a chance to progress; see bug #20324.
if ( !instant && resources::screen )
resources::screen->draw(true);
}
// Determine the hexes to clear.
pathfind::vision_path sight(*resources::game_map, viewer, view_loc, jamming_);
// Give animations a chance to progress; see bug #20324.
if ( !instant && resources::screen )
resources::screen->draw(true);
// Clear the fog.
pathfind::vision_path sight(*resources::game_map, viewer, view_loc, jamming_);
BOOST_FOREACH (const pathfind::paths::step &dest, sight.destinations) {
bool known = known_units && known_units->count(dest.curr) != 0;
if ( clear_loc(view_team, dest.curr, viewer, view_loc, !known,
@ -331,12 +345,14 @@ bool shroud_clearer::clear_unit(const map_location &view_loc,
* for the caller to check these.)
* In addition, if @a invalidate is left as true, invalidate_after_clear()
* will be called.
* Setting @a instant to true suppresses some drawing delays that are used to
* make animations look better.
*
* @return whether or not information was uncovered (i.e. returns true if any
* locations in visual range were fogged/shrouded under shared vision/maps).
*/
bool shroud_clearer::clear_unit(const map_location &view_loc, const unit &viewer,
bool can_delay, bool invalidate)
bool can_delay, bool invalidate, bool instant)
{
team & viewing_team = (*resources::teams)[viewer.side()-1];
@ -347,7 +363,7 @@ bool shroud_clearer::clear_unit(const map_location &view_loc, const unit &viewer
viewer.side() == resources::controller->current_side() )
return false;
if ( !clear_unit(view_loc, viewer, viewing_team) )
if ( !clear_unit(view_loc, viewer, viewing_team, instant) )
// Nothing uncovered.
return false;
@ -561,7 +577,8 @@ void recalculate_fog(int side)
BOOST_FOREACH(const unit &u, *resources::units)
{
if ( u.side() == side )
clearer.clear_unit(u.get_location(), u, tm, &visible_locs);
clearer.clear_unit(u.get_location(), u, tm, &visible_locs, NULL,
NULL, NULL, true);
}
// Update the screen.
clearer.invalidate_after_clear();
@ -597,7 +614,7 @@ bool clear_shroud(int side, bool reset_fog, bool fire_events)
BOOST_FOREACH(const unit &u, *resources::units)
{
if ( u.side() == side )
result |= clearer.clear_unit(u.get_location(), u, tm);
result |= clearer.clear_unit(u.get_location(), u, tm, true);
}
// Update the screen.
if ( result )

View file

@ -61,11 +61,18 @@ public:
const unit &viewer, team &view_team,
const std::set<map_location>* known_units = NULL,
size_t * enemy_count = NULL, size_t * friend_count = NULL,
move_unit_spectator * spectator = NULL);
move_unit_spectator * spectator = NULL, bool instant = false);
/// Clears shroud (and fog) around the provided location for @a view_team
/// as if @a viewer was standing there. Setting @a instant to true
/// suppresses some drawing delays that are used to make animations look better.
bool clear_unit(const map_location &view_loc, const unit &viewer,
team &view_team, bool instant)
{ return clear_unit(view_loc, viewer, view_team, NULL, NULL, NULL, NULL, instant); }
/// Clears shroud (and fog) around the provided location as if @a viewer
/// was standing there.
bool clear_unit(const map_location &view_loc, const unit &viewer,
bool can_delay = false, bool invalidate = true);
bool can_delay = false, bool invalidate = true,
bool instant = false);
/// Erases the record of sighted events from earlier fog/shroud clearing.
void drop_events();