Make local copies of paths so that...
...they are sure to remain valid during movement. Fixes bug# 20199.
This commit is contained in:
parent
0960610764
commit
281e2c7467
3 changed files with 25 additions and 16 deletions
|
@ -723,6 +723,9 @@ void mouse_handler::deselect_hex() {
|
|||
*/
|
||||
bool mouse_handler::move_unit_along_current_route()
|
||||
{
|
||||
// Copy the current route to ensure it remains valid throughout the animation.
|
||||
const std::vector<map_location> steps = current_route_.steps;
|
||||
|
||||
// do not show footsteps during movement
|
||||
gui().set_route(NULL);
|
||||
gui().unhighlight_reach();
|
||||
|
@ -732,12 +735,12 @@ bool mouse_handler::move_unit_along_current_route()
|
|||
gui().select_hex(map_location());
|
||||
|
||||
bool interrupted = false;
|
||||
if ( current_route_.steps.size() > 1 )
|
||||
if ( steps.size() > 1 )
|
||||
{
|
||||
size_t num_moves = move_unit_along_route(current_route_, interrupted);
|
||||
size_t num_moves = move_unit_along_route(steps, interrupted);
|
||||
|
||||
interrupted = interrupted || num_moves + 1 < current_route_.steps.size();
|
||||
next_unit_ = current_route_.steps[num_moves];
|
||||
interrupted = interrupted || num_moves + 1 < steps.size();
|
||||
next_unit_ = steps[num_moves];
|
||||
}
|
||||
|
||||
// invalid after the move
|
||||
|
@ -752,18 +755,21 @@ bool mouse_handler::move_unit_along_current_route()
|
|||
* This is specifically for movement at the time it is initiated by a player,
|
||||
* whether via a mouse click or executing whiteboard actions. Continued moves
|
||||
* (including goto execution) can bypass this and call ::move_unit() directly.
|
||||
* This function call may include time for an animation, so make sure the
|
||||
* provided route will remain unchanged (the caller should probably make a local
|
||||
* copy).
|
||||
*
|
||||
* @param[in] route The route to be traveled. The unit to be moved is at the beginning of this route.
|
||||
* @param[in] steps The route to be traveled. The unit to be moved is at the beginning of this route.
|
||||
* @param[out] interrupted This is set to true if information was uncovered that warrants interrupting a chain of actions (and set to false otherwise).
|
||||
*
|
||||
* @returns The number of hexes entered. This can safely be used as an index
|
||||
* into route.steps to get the location where movement ended, provided
|
||||
* route.steps is not empty (the return value is guaranteed to be less
|
||||
* than route.steps.size() ).
|
||||
* into steps to get the location where movement ended, provided
|
||||
* steps is not empty (the return value is guaranteed to be less
|
||||
* than steps.size() ).
|
||||
*/
|
||||
size_t mouse_handler::move_unit_along_route(pathfind::marked_route const& route, bool & interrupted)
|
||||
size_t mouse_handler::move_unit_along_route(const std::vector<map_location> & steps,
|
||||
bool & interrupted)
|
||||
{
|
||||
const std::vector<map_location> steps = route.steps;
|
||||
if(steps.empty()) {
|
||||
interrupted = false;
|
||||
return 0;
|
||||
|
|
|
@ -72,7 +72,7 @@ public:
|
|||
void attack_enemy(const map_location& attacker_loc, const map_location& defender_loc, int choice);
|
||||
|
||||
/// Moves a unit across the board for a player.
|
||||
size_t move_unit_along_route(pathfind::marked_route const& route, bool & interrupted);
|
||||
size_t move_unit_along_route(const std::vector<map_location> & steps, bool & interrupted);
|
||||
|
||||
void select_hex(const map_location& hex, const bool browse,
|
||||
const bool highlight = true,
|
||||
|
|
|
@ -207,6 +207,9 @@ void move::execute(bool& success, bool& complete)
|
|||
|
||||
LOG_WB << "Executing: " << shared_from_this() << "\n";
|
||||
|
||||
// Copy the current route to ensure it remains valid throughout the animation.
|
||||
const std::vector<map_location> steps = route_->steps;
|
||||
|
||||
set_arrow_brightness(ARROW_BRIGHTNESS_HIGHLIGHTED);
|
||||
hide_fake_unit();
|
||||
|
||||
|
@ -214,12 +217,12 @@ void move::execute(bool& success, bool& complete)
|
|||
bool interrupted;
|
||||
try {
|
||||
events::mouse_handler& mouse_handler = resources::controller->get_mouse_handler_base();
|
||||
num_steps = mouse_handler.move_unit_along_route(*route_, interrupted);
|
||||
num_steps = mouse_handler.move_unit_along_route(steps, interrupted);
|
||||
} catch (end_turn_exception&) {
|
||||
set_arrow_brightness(ARROW_BRIGHTNESS_STANDARD);
|
||||
throw; // we rely on the caller to delete this action
|
||||
}
|
||||
const map_location final_location = route_->steps[num_steps];
|
||||
const map_location & final_location = steps[num_steps];
|
||||
unit_map::const_iterator unit_it = resources::units->find(final_location);
|
||||
|
||||
if ( num_steps == 0 )
|
||||
|
@ -236,7 +239,7 @@ void move::execute(bool& success, bool& complete)
|
|||
}
|
||||
else
|
||||
{
|
||||
complete = num_steps + 1 == route_->steps.size();
|
||||
complete = num_steps + 1 == steps.size();
|
||||
success = complete && !interrupted;
|
||||
|
||||
if ( !success )
|
||||
|
@ -251,9 +254,9 @@ void move::execute(bool& success, bool& complete)
|
|||
else
|
||||
{
|
||||
LOG_WB << "Move finished at (" << final_location << ") instead of at (" << get_dest_hex() << "). Setting new path.\n";
|
||||
route_->steps = std::vector<map_location>(route_->steps.begin() + num_steps, route_->steps.end());
|
||||
route_->steps = std::vector<map_location>(steps.begin() + num_steps, steps.end());
|
||||
//FIXME: probably better to use the new calculate_new_route() instead of the above:
|
||||
//calculate_new_route(final_location, route_->steps.back());
|
||||
//calculate_new_route(final_location, steps.back());
|
||||
// Of course, "better" would need to be verified.
|
||||
arrow_->set_path(route_->steps);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue