Changed the method for fading out units that have planned moves...

...to a somewhat safer one: I apply the "ghosted" animation right
before drawing happens and remove it afterwards. Fixes bug #19619.
This commit is contained in:
Gabriel Morin 2012-04-05 11:04:26 +00:00
parent d9ec78ce44
commit 49851c2805
7 changed files with 84 additions and 31 deletions

View file

@ -2151,6 +2151,7 @@ void display::draw(bool update,bool force) {
//SDL_Delay(2*simulate_delay + rand() % 20);
}
draw_wrap(update, force);
post_draw();
}
map_labels& display::labels()

View file

@ -567,6 +567,13 @@ protected:
*/
virtual void pre_draw() {}
/**
* Called at the very end of each draw() call.
* Derived classes can use this to add extra actions after redrawing
* invalidated hexes takes place. No action here by default.
*/
virtual void post_draw() {}
/**
* Get the clipping rectangle for drawing.
* Virtual since the editor might use a slightly different approach.

View file

@ -266,6 +266,7 @@ void game_display::scroll_to_leader(unit_map& units, int side, SCROLL_TYPE scrol
}
void game_display::pre_draw() {
resources::whiteboard->pre_draw();
process_reachmap_changes();
/**
* @todo FIXME: must modify changed, but best to do it at the
@ -274,6 +275,11 @@ void game_display::pre_draw() {
prune_chat_messages();
}
void game_display::post_draw() {
resources::whiteboard->post_draw();
}
void game_display::draw_invalidated()
{
halo::unrender(invalidated_);

View file

@ -140,8 +140,13 @@ public:
protected:
/**
* game_display pre_draw does specific things related e.g. to unit rendering
* and calls the whiteboard pre-draw method.
*/
void pre_draw();
/**
* Calls the whiteboard's post-draw method.
*/
void post_draw();
void draw_invalidated();

View file

@ -304,16 +304,8 @@ void manager::on_finish_side_turn(int side)
LOG_WB << "on_finish_side_turn()\n";
}
void manager::pre_delete_action(action_ptr action)
void manager::pre_delete_action(action_ptr)
{
//If we're deleting the last planned move of a unit, reset it to normal animation
if (action->is_valid()
&& action->get_unit()
&& boost::dynamic_pointer_cast<move>(action)
&& viewer_actions()->count_actions_of(action->get_unit()) == 1)
{
action->get_unit()->set_standing(true);
}
}
void manager::post_delete_action(action_ptr action)
@ -458,6 +450,60 @@ static void draw_numbers(map_location const& hex, side_actions::numbers_t number
}
}
namespace
{
//Helper struct that finds all units teams whose planned actions are currently visible
//Only used by manager::pre_draw() and post_draw()
struct move_owners_finder
: private enable_visit_all<move_owners_finder>, public visitor
{
friend class enable_visit_all<move_owners_finder>;
public:
move_owners_finder(){
move_owners_.clear();
//Thanks to the default pre_visit_team, will only visit visible side_actions
visit_all_actions();
}
std::set<unit*> get_move_owners() {
return move_owners_;
}
using enable_visit_all<move_owners_finder>::visit_all;
private:
virtual void visit(move_ptr move) {
move_owners_.insert(move->get_unit());
}
virtual void visit(attack_ptr){}
virtual void visit(recruit_ptr){}
virtual void visit(recall_ptr){}
virtual void visit(suppose_dead_ptr){}
std::set<unit*> move_owners_;
};
}
void manager::pre_draw()
{
std::set<unit*> move_owners = move_owners_finder().get_move_owners();
foreach(unit* unit, move_owners)
{
ghost_owner_unit(unit);
}
}
void manager::post_draw()
{
std::set<unit*> move_owners = move_owners_finder().get_move_owners();
foreach(unit* unit, move_owners)
{
unghost_owner_unit(unit);
}
}
namespace
{
//Only used by manager::draw_hex()
@ -729,9 +775,6 @@ void manager::save_temp_move()
}
erase_temp_move();
//@todo rework this once I combine mapbuilder and verifier
ghost_owner_unit(u);
LOG_WB << *viewer_actions() << "\n";
print_help_once();
}
@ -751,13 +794,10 @@ void manager::save_temp_attack(const map_location& attacker_loc, const map_locat
arrow_ptr move_arrow;
fake_unit_ptr fake_unit;
map_location source_hex;
bool attack_move;
if (route_ && !route_->steps.empty())
{
//attack-move
attack_move = true;
assert(move_arrows_.size() == 1);
assert(fake_units_.size() == 1);
move_arrow = move_arrows_.front();
@ -771,8 +811,6 @@ void manager::save_temp_attack(const map_location& attacker_loc, const map_locat
else
{
//simple attack
attack_move = false;
move_arrow.reset(new arrow);
source_hex = attacker_loc;
route_.reset(new pathfind::marked_route);
@ -783,11 +821,6 @@ void manager::save_temp_attack(const map_location& attacker_loc, const map_locat
unit* attacking_unit = future_visible_unit(source_hex);
assert(attacking_unit);
if (attack_move) {
//@todo rework this once I combine mapbuilder and verifier
ghost_owner_unit(attacking_unit);
}
on_save_action(attacking_unit);
side_actions& sa = *viewer_actions();

View file

@ -111,8 +111,17 @@ public:
/** Whether the planned unit map is currently applied */
bool has_planned_unit_map() const { return planned_unit_map_active_; }
/**
* Callback from the display when drawing hexes, to allow the whiteboard to
* Called from the display before drawing.
*/
void pre_draw();
/**
* Called from the display after drawing.
*/
void post_draw();
/**
* Called from the display when drawing hexes, to allow the whiteboard to
* add visual elements. Some visual elements such as arrows and fake units
* are not handled through this function, but separately registered with the display.
*/

View file

@ -210,7 +210,6 @@ void move::execute(bool& success, bool& complete)
set_arrow_brightness(ARROW_BRIGHTNESS_HIGHLIGHTED);
hide_fake_unit();
unghost_owner_unit(get_unit());
events::mouse_handler& mouse_handler = resources::controller->get_mouse_handler_base();
std::set<map_location> adj_enemies = mouse_handler.get_adj_enemies(get_dest_hex(), side_number());
@ -304,13 +303,6 @@ void move::execute(bool& success, bool& complete)
{
set_arrow_brightness(ARROW_BRIGHTNESS_STANDARD);
show_fake_unit();
ghost_owner_unit(get_unit());
}
//if unit has other moves besides this one, set it back to ghosted visuals
//@todo handle this in a more centralized fashion
if (resources::teams->at(team_index()).get_side_actions()->count_actions_of(get_unit()) > 1) {
ghost_owner_unit(get_unit());
}
}