diff --git a/src/actions.cpp b/src/actions.cpp index 8d905b7e111..b89a1ddc866 100644 --- a/src/actions.cpp +++ b/src/actions.cpp @@ -283,6 +283,8 @@ battle_stats evaluate_battle_stats( * combat_modifier(state,units,a->first,a->second.type().alignment())) * (charge ? 2 : 1) * (backstab ? 2 : 1); + std::cerr << "damage defender takes: " << double(d->second.damage_against(attack)) << "*" <first,a->second.type().alignment()) << "*" << (charge ? 2:1) << " = " << res.damage_defender_takes << "\n"; + if(under_leadership(units,attacker)) res.damage_defender_takes += res.damage_defender_takes/8 + 1; @@ -847,8 +849,8 @@ size_t move_unit(display* disp, const gamemap& map, //if we can't get all the way there and have to set a go-to if(steps.size() != route.size()) { - ui->second.set_goto(route.back()); - u.set_goto(route.back()); + ui->second.add_goto(route.back()); + u.add_goto(route.back()); } if(steps.size() < 2) { @@ -890,7 +892,7 @@ size_t move_unit(display* disp, const gamemap& map, } if(disp != NULL) { - disp->set_route(NULL); + disp->set_routes(std::vector()); disp->draw(); } @@ -975,7 +977,7 @@ bool unit_can_move(const gamemap::location& loc, const unit_map& units, //units with goto commands that have already done their gotos this turn //(i.e. don't have full movement left) should be red - if(u.movement_left() < u.total_movement() && u.get_goto().valid()) { + if(u.movement_left() < u.total_movement() && !u.get_gotos().empty()) { return false; } diff --git a/src/display.cpp b/src/display.cpp index 92a446eb2f1..df28ef11ee8 100644 --- a/src/display.cpp +++ b/src/display.cpp @@ -1238,26 +1238,37 @@ void display::draw_tile(int x, int y, SDL_Surface* unit_image, void display::draw_footstep(const gamemap::location& loc, int xloc, int yloc) { - std::vector::const_iterator i = - std::find(route_.steps.begin(),route_.steps.end(),loc); + std::vector::const_iterator rt; + std::vector::const_iterator i; + + for(rt = routes_.begin(); rt != routes_.end(); ++rt) { + i = std::find(rt->steps.begin(),rt->steps.end(),loc); + if(i != rt->steps.end()) + break; + } - if(i == route_.steps.begin() || i == route_.steps.end()) + if(rt == routes_.end()) return; - const bool show_time = (i+1 == route_.steps.end()); + const paths::route& route = *rt; - const bool left_foot = is_even(i - route_.steps.begin()); + if(i == route.steps.begin() || i == route.steps.end()) + return; + + const bool show_time = (i+1 == route.steps.end()); + + const bool left_foot = is_even(i - route.steps.begin()); //generally we want the footsteps facing toward the direction they're going //to go next. //if we're on the last step, then we want them facing according to where //they came from, so we move i back by one - if(i+1 == route_.steps.end() && i != route_.steps.begin()) + if(i+1 == route.steps.end() && i != route.steps.begin()) --i; gamemap::location::DIRECTION direction = gamemap::location::NORTH; - if(i+1 != route_.steps.end()) { + if(i+1 != route.steps.end()) { for(int n = 0; n != 6; ++n) { direction = gamemap::location::DIRECTION(n); if(i->get_direction(direction) == *(i+1)) { @@ -1302,9 +1313,9 @@ void display::draw_footstep(const gamemap::location& loc, int xloc, int yloc) draw_unit(xloc,yloc,image,hflip,vflip,0.5); - if(show_time && route_.move_left > 0 && route_.move_left < 10) { + if(show_time && route.move_left > 0 && route.move_left < 10) { static std::string str(1,'x'); - str[0] = '0' + route_.move_left + 1; + str[0] = '0' + route.move_left + 1; const SDL_Rect& text_area = font::draw_text(NULL,screen_area(),18,font::BUTTON_COLOUR,str,0,0); const int x = xloc + int(zoom_/2.0) - text_area.w/2; @@ -1554,9 +1565,12 @@ void display::set_paths(const paths* paths_list) void display::invalidate_route() { - for(std::vector::const_iterator i = route_.steps.begin(); - i != route_.steps.end(); ++i) { - invalidate(*i); + for(std::vector::const_iterator r = routes_.begin(); + r != routes_.end(); ++r) { + for(std::vector::const_iterator i = r->steps.begin(); + i != r->steps.end(); ++i) { + invalidate(*i); + } } } @@ -1564,10 +1578,18 @@ void display::set_route(const paths::route* route) { invalidate_route(); - if(route != NULL) - route_ = *route; - else - route_.steps.clear(); + routes_.clear(); + if(route != NULL) { + routes_.push_back(*route); + invalidate_route(); + } +} + +void display::set_routes(const std::vector& routes) +{ + invalidate_route(); + + routes_ = routes; invalidate_route(); } diff --git a/src/display.hpp b/src/display.hpp index 630c4aba011..16b4e8169ba 100644 --- a/src/display.hpp +++ b/src/display.hpp @@ -71,6 +71,7 @@ public: //route does not have to remain valid after being set void set_route(const paths::route* route); + void set_routes(const std::vector& routes); double get_location_x(const gamemap::location& loc) const; double get_location_y(const gamemap::location& loc) const; @@ -177,7 +178,7 @@ private: SDL_Surface* minimap_; const paths* pathsList_; - paths::route route_; + std::vector routes_; const gamestatus& status_; diff --git a/src/playturn.cpp b/src/playturn.cpp index 51e14a90f8d..bacb3648adc 100644 --- a/src/playturn.cpp +++ b/src/playturn.cpp @@ -74,10 +74,12 @@ void play_turn(game_data& gameinfo, game_state& state_of_game, std::vector gotos; for(unit_map::iterator ui = units.begin(); ui != units.end(); ++ui) { - if(ui->second.get_goto() == ui->first) - ui->second.set_goto(gamemap::location()); + const std::vector& go = ui->second.get_gotos(); + while(!go.empty() && go.front() == ui->first) + ui->second.done_goto(); - if(ui->second.side() == team_num && map.on_board(ui->second.get_goto())) + if(!go.empty() && ui->second.side() == team_num && + map.on_board(go.front())) gotos.push_back(ui->first); } @@ -94,8 +96,8 @@ void play_turn(game_data& gameinfo, game_state& state_of_game, const std::set* const teleports = u.type().teleports() ? ¤t_team.towers() : NULL; - paths::route route = a_star_search(ui->first,ui->second.get_goto(), - 10000.0,calc,teleports); + paths::route route = a_star_search(ui->first, + ui->second.get_gotos().front(),10000.0,calc,teleports); if(route.steps.empty()) continue; @@ -103,8 +105,11 @@ void play_turn(game_data& gameinfo, game_state& state_of_game, route.move_left = route_turns_to_complete(ui->second,map,route); gui.set_route(&route); - move_unit(&gui,map,units,teams,route.steps, - &recorder,&turn_data.undos()); + const int res = move_unit(&gui,map,units,teams,route.steps, + &recorder,&turn_data.undos()); + + if(res == route.steps.size()) + ui->second.done_goto(); } std::cerr << "done gotos\n"; @@ -264,6 +269,12 @@ void turn_info::mouse_motion(const SDL_MouseMotionEvent& event) const unit_map::const_iterator un = units_.find(selected_hex_); if(un != units_.end()) { + std::vector gotos = un->second.get_gotos(); + if(!key_[SDLK_LCTRL] && !key_[SDLK_RCTRL]) { + gotos.clear(); + } + + const shortest_path_calculator calc(un->second,current_team, units_,map_); const bool can_teleport = un->second.type().teleports(); @@ -481,7 +492,9 @@ void turn_info::left_click(const SDL_MouseButtonEvent& event) enemy == units_.end() && !current_route_.steps.empty() && current_route_.steps.front() == selected_hex_) { - + if(!key_[SDLK_LCTRL] && !key_[SDLK_RCTRL]) { + + } const size_t moves = move_unit(&gui_,map_,units_,teams_, current_route_.steps,&recorder,&undo_stack_); @@ -532,7 +545,8 @@ void turn_info::left_click(const SDL_MouseButtonEvent& event) selected_hex_ = hex; gui_.select_hex(hex); current_route_.steps.clear(); - gui_.set_route(NULL); + + std::vector routes; const unit_map::iterator it = units_.find(hex); if(it != units_.end() && it->second.side() == team_num_) { @@ -543,21 +557,28 @@ void turn_info::left_click(const SDL_MouseButtonEvent& event) gui_.set_paths(¤t_paths_); unit u = it->second; - const gamemap::location go_to = u.get_goto(); - if(map_.on_board(go_to)) { + const std::vector& gotos = u.get_gotos(); + + for(std::vector::const_iterator g = gotos.begin(); + g != gotos.end(); ++g) { + const shortest_path_calculator calc(u,current_team, units_,map_); const std::set* const teleports = teleport ? ¤t_team.towers() : NULL; - paths::route route = a_star_search(it->first,go_to, + const gamemap::location& src = g == gotos.begin() ? it->first : + *(g-1); + + paths::route route = a_star_search(src,*g, 10000.0,calc,teleports); route.move_left = route_turns_to_complete(it->second,map_,route); - gui_.set_route(&route); } } + + gui_.set_routes(routes); } } diff --git a/src/unit.cpp b/src/unit.cpp index 38b5c8e2fef..b107a25c798 100644 --- a/src/unit.cpp +++ b/src/unit.cpp @@ -540,14 +540,27 @@ bool unit::is_guardian() const return guardian_; } -const gamemap::location& unit::get_goto() const +const std::vector& unit::get_gotos() const { - return goto_; + return gotos_; } void unit::set_goto(const gamemap::location& new_goto) { - goto_ = new_goto; + gotos_.clear(); + add_goto(new_goto); +} + +void unit::add_goto(const gamemap::location& new_goto) +{ + if(new_goto.valid()) + gotos_.push_back(new_goto); +} + +void unit::done_goto() +{ + if(gotos_.empty() == false) + gotos_.erase(gotos_.begin()); } void unit::add_modification(const std::string& type, diff --git a/src/unit.hpp b/src/unit.hpp index d852c093522..7a5dd544b54 100644 --- a/src/unit.hpp +++ b/src/unit.hpp @@ -95,8 +95,10 @@ public: int value() const; bool is_guardian() const; - const gamemap::location& get_goto() const; + const std::vector& get_gotos() const; void set_goto(const gamemap::location& new_goto); + void add_goto(const gamemap::location& new_goto); + void done_goto(); int upkeep() const; @@ -141,7 +143,7 @@ private: bool guardian_; - gamemap::location goto_; + std::vector gotos_; bool loyal_;