wesnoth-cvs-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Wesnoth-cvs-commits] wesnoth/src playturn.cpp playturn.hpp actions.c...


From: David White
Subject: [Wesnoth-cvs-commits] wesnoth/src playturn.cpp playturn.hpp actions.c...
Date: Thu, 02 Dec 2004 20:25:51 -0500

CVSROOT:        /cvsroot/wesnoth
Module name:    wesnoth
Branch:         
Changes by:     David White <address@hidden>    04/12/03 01:19:29

Modified files:
        src            : playturn.cpp playturn.hpp actions.cpp 
                         actions.hpp 

Log message:
        CHANGELOG: added feature to move and attack a unit in one go by 
clicking on an enemy that can be reached this turn.

CVSWeb URLs:
http://savannah.gnu.org/cgi-bin/viewcvs/wesnoth/wesnoth/src/playturn.cpp.diff?tr1=1.304&tr2=1.305&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/wesnoth/wesnoth/src/playturn.hpp.diff?tr1=1.55&tr2=1.56&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/wesnoth/wesnoth/src/actions.cpp.diff?tr1=1.169&tr2=1.170&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/wesnoth/wesnoth/src/actions.hpp.diff?tr1=1.46&tr2=1.47&r1=text&r2=text

Patches:
Index: wesnoth/src/actions.cpp
diff -u wesnoth/src/actions.cpp:1.169 wesnoth/src/actions.cpp:1.170
--- wesnoth/src/actions.cpp:1.169       Sat Nov 27 08:41:49 2004
+++ wesnoth/src/actions.cpp     Fri Dec  3 01:19:29 2004
@@ -1,4 +1,4 @@
-/* $Id: actions.cpp,v 1.169 2004/11/27 08:41:49 silene Exp $ */
+/* $Id: actions.cpp,v 1.170 2004/12/03 01:19:29 Sirp Exp $ */
 /*
    Copyright (C) 2003 by David White <address@hidden>
    Part of the Battle for Wesnoth Project http://wesnoth.whitevine.net
@@ -1575,7 +1575,7 @@
                  unit_map& units, std::vector<team>& teams,
                  std::vector<gamemap::location> route,
                  replay* move_recorder, undo_list* undo_stack,
-                 gamemap::location *next_unit, bool continue_move)
+                 gamemap::location *next_unit, bool continue_move, bool 
should_clear_shroud)
 {
        //stop the user from issuing any commands while the unit is moving
        const command_disabler disable_commands;
@@ -1595,7 +1595,7 @@
        const bool skirmisher = u.type().is_skirmisher();
 
        team& team = teams[team_num];
-       const bool check_shroud = team.auto_shroud_updates() &&
+       const bool check_shroud = should_clear_shroud && 
team.auto_shroud_updates() &&
                (team.uses_shroud() || team.uses_fog());
        
        //if we use shroud/fog of war, count out the units we can currently see
Index: wesnoth/src/actions.hpp
diff -u wesnoth/src/actions.hpp:1.46 wesnoth/src/actions.hpp:1.47
--- wesnoth/src/actions.hpp:1.46        Sat Nov 27 08:41:49 2004
+++ wesnoth/src/actions.hpp     Fri Dec  3 01:19:29 2004
@@ -1,4 +1,4 @@
-/* $Id: actions.hpp,v 1.46 2004/11/27 08:41:49 silene Exp $ */
+/* $Id: actions.hpp,v 1.47 2004/12/03 01:19:29 Sirp Exp $ */
 /*
    Copyright (C) 2003 by David White <address@hidden>
    Part of the Battle for Wesnoth Project http://wesnoth.whitevine.net
@@ -186,7 +186,7 @@
                                std::vector<gamemap::location> steps,
                                replay* move_recorder, undo_list* undos,
                                gamemap::location *next_unit = NULL,
-                               bool continue_move = false);
+                               bool continue_move = false, bool 
should_clear_shroud=true);
 
 //function which recalculates the fog
 void recalculate_fog(const gamemap& map, const gamestatus& status,
Index: wesnoth/src/playturn.cpp
diff -u wesnoth/src/playturn.cpp:1.304 wesnoth/src/playturn.cpp:1.305
--- wesnoth/src/playturn.cpp:1.304      Thu Dec  2 22:54:24 2004
+++ wesnoth/src/playturn.cpp    Fri Dec  3 01:19:29 2004
@@ -1,4 +1,4 @@
-/* $Id: playturn.cpp,v 1.304 2004/12/02 22:54:24 silene Exp $ */
+/* $Id: playturn.cpp,v 1.305 2004/12/03 01:19:29 Sirp Exp $ */
 /*
    Copyright (C) 2003 by David White <address@hidden>
    Part of the Battle for Wesnoth Project http://wesnoth.whitevine.net
@@ -299,8 +299,15 @@
                //the attack cursor
 
                const unit_map::const_iterator selected_unit = 
find_unit(selected_hex_);
-               const unit_map::const_iterator mouseover_unit = 
find_unit(new_hex);
-               if(selected_unit != units_.end() && 
current_paths_.routes.count(new_hex)) {
+               const unit_map::const_iterator mouseover_unit = 
find_unit(new_hex);
+
+               gamemap::location attack_from;
+               if(selected_unit != units_.end() && mouseover_unit != 
units_.end()) {
+                       attack_from = current_unit_attacks_from(new_hex);
+               }
+
+               if(selected_unit != units_.end() && 
(current_paths_.routes.count(new_hex) ||
+                                                    attack_from.valid())) {
                        if(mouseover_unit == units_.end()) {
                                cursor::set(cursor::MOVE);
                        } else 
if(current_team.is_enemy(mouseover_unit->second.side())) {
@@ -321,12 +328,14 @@
                if(new_hex == selected_hex_) {
                        current_route_.steps.clear();
                        gui_.set_route(NULL);
-               } else if(!enemy_paths_ && new_hex != last_hex_ &&
+               } else if(new_hex != last_hex_ &&
                   !current_paths_.routes.empty() && 
map_.on_board(selected_hex_) &&
-                  map_.on_board(new_hex)) {
+                  map_.on_board(new_hex)) {
+
+                       const gamemap::location& dest = attack_from.valid() ? 
attack_from : new_hex;
 
                        unit_map::const_iterator un = find_unit(selected_hex_);
-                       const unit_map::const_iterator dest_un = 
find_unit(new_hex);
+                       const unit_map::const_iterator dest_un = 
find_unit(dest);
 
                        if(un != units_.end() && dest_un == units_.end()) {
                                const shortest_path_calculator 
calc(un->second,current_team,
@@ -343,7 +352,7 @@
                                                
allowed_teleports.insert(un->first);
                                }
 
-                               current_route_ = 
a_star_search(selected_hex_,new_hex,
+                               current_route_ = 
a_star_search(selected_hex_,dest,
                                                               
10000.0,calc,teleports);
 
                                current_route_.move_left = 
route_turns_to_complete(un->second,map_,current_route_);
@@ -520,6 +529,208 @@
 }
 
 }
+
+bool turn_info::attack_enemy(unit_map::iterator attacker, unit_map::iterator 
defender)
+{
+       //we must get locations by value instead of by references, because the 
iterators
+       //may become invalidated later
+       const gamemap::location attacker_loc = attacker->first;
+       const gamemap::location defender_loc = defender->first;
+
+       const std::vector<attack_type>& attacks = attacker->second.attacks();
+       std::vector<std::string> items;
+
+       const int range = distance_between(attacker->first,defender->first);
+       std::vector<int> attacks_in_range;
+
+       int best_weapon_index = -1;
+       int best_weapon_rating = 0;
+
+       std::vector<battle_stats> stats;
+
+       for(size_t a = 0; a != attacks.size(); ++a) {
+               if(attacks[a].hexes() < range)
+                       continue;
+
+               attacks_in_range.push_back(a);
+
+               stats.push_back(evaluate_battle_stats(map_, attacker_loc, 
defender_loc,
+                                                     a, units_, status_));
+
+               int weapon_rating = stats.back().chance_to_hit_defender *
+                               stats.back().damage_defender_takes * 
stats.back().nattacks;
+               
+               if (best_weapon_index < 0 || best_weapon_rating < 
weapon_rating) {
+                       best_weapon_index = items.size();
+                       best_weapon_rating = weapon_rating;
+               }
+               
+               const battle_stats& st = stats.back();
+
+               const std::string& attack_name = st.attack_name;
+               const std::string& attack_special = st.attack_special.empty() ? 
"" : gettext(st.attack_special.c_str());
+               const std::string& defend_name = st.defend_name;
+               const std::string& defend_special = st.defend_special.empty() ? 
"" : gettext(st.defend_special.c_str());
+
+               const std::string& range = gettext(st.range == "Melee" ? 
N_("melee") : N_("ranged"));
+
+               //if there is an attack special or defend special, we output a 
single space for the other unit, to make sure
+               //that the attacks line up nicely.
+               std::string special_pad = (attack_special.empty() == false || 
defend_special.empty() == false) ? " " : "";
+
+               std::stringstream att;
+               att << IMAGE_PREFIX << stats.back().attack_icon << 
COLUMN_SEPARATOR
+                   << font::BOLD_TEXT << attack_name
+                   << "\n" << stats.back().damage_defender_takes << "-"
+                       << stats.back().nattacks << " " << range << " ("
+                       << stats.back().chance_to_hit_defender << "%)\n"
+                       << attack_special << special_pad;
+
+               att << COLUMN_SEPARATOR << _("vs") << COLUMN_SEPARATOR;
+               att << font::BOLD_TEXT << defend_name << "\n" << 
stats.back().damage_attacker_takes << "-"
+                       << stats.back().ndefends << " " << range << " ("
+                       << stats.back().chance_to_hit_attacker
+                   << "%)\n" << defend_special << special_pad << 
COLUMN_SEPARATOR
+                   << IMAGE_PREFIX << stats.back().defend_icon;
+
+               items.push_back(att.str());
+       }
+       
+       if (best_weapon_index >= 0) {
+               items[best_weapon_index] = "*" + items[best_weapon_index];
+       }
+               
+       //make it so that when we attack an enemy, the attacking unit
+       //is again shown in the status bar, so that we can easily
+       //compare between the attacking and defending unit
+       gui_.highlight_hex(gamemap::location());
+       gui_.draw(true,true);
+
+       attack_calculations_displayer calc_displayer(gui_,stats);
+       std::vector<gui::dialog_button> buttons;
+       buttons.push_back(gui::dialog_button(&calc_displayer,_("Damage 
Calculations")));
+
+       int res = 0;
+
+       {
+               const events::event_context dialog_events_context;
+               dialogs::unit_preview_pane 
attacker_preview(gui_,&map_,attacker->second,dialogs::unit_preview_pane::SHOW_BASIC,true);
+               dialogs::unit_preview_pane 
defender_preview(gui_,&map_,defender->second,dialogs::unit_preview_pane::SHOW_BASIC,false);
+               std::vector<gui::preview_pane*> preview_panes;
+               preview_panes.push_back(&attacker_preview);
+               preview_panes.push_back(&defender_preview);
+
+               res = gui::show_dialog(gui_,NULL,_("Attack Enemy"),
+                               _("Choose weapon")+std::string(":\n"),
+                               
gui::OK_CANCEL,&items,&preview_panes,"",NULL,-1,NULL,NULL,-1,-1,
+                               NULL,&buttons);
+       }
+
+       cursor::set(cursor::NORMAL);
+
+       if(size_t(res) < attacks_in_range.size()) {
+               res = attacks_in_range[res];
+
+               attacker->second.set_goto(gamemap::location());
+               clear_undo_stack();
+               redo_stack_.clear();
+
+               current_paths_ = paths();
+               gui_.set_paths(NULL);
+
+               game_events::fire("attack",attacker_loc,defender_loc);
+
+               //the event could have killed either the attacker or
+               //defender, so we have to make sure they still exist
+               attacker = units_.find(attacker_loc);
+               defender = units_.find(defender_loc);
+
+               if(attacker == units_.end() || defender == units_.end() || 
size_t(res) >= attacks.size()) {
+                       return true;
+               }
+
+               gui_.invalidate_all();
+               gui_.draw();
+
+               const bool defender_human = 
teams_[defender->second.side()-1].is_human();
+
+               recorder.add_attack(attacker_loc,defender_loc,res);
+
+               try {
+                       
attack(gui_,map_,teams_,attacker_loc,defender_loc,res,units_,status_,gameinfo_);
+               } catch(end_level_exception&) {
+                       //if the level ends due to a unit being killed, still 
see if
+                       //either the attacker or defender should advance
+                       
dialogs::advance_unit(gameinfo_,map_,units_,attacker_loc,gui_);
+                       
dialogs::advance_unit(gameinfo_,map_,units_,defender_loc,gui_,!defender_human);
+                       throw;
+               }
+
+               dialogs::advance_unit(gameinfo_,map_,units_,attacker_loc,gui_);
+               
dialogs::advance_unit(gameinfo_,map_,units_,defender_loc,gui_,!defender_human);
+
+               selected_hex_ = gamemap::location();
+               current_route_.steps.clear();
+               gui_.set_route(NULL);
+
+               check_victory(units_,teams_);
+
+               gui_.invalidate_all();
+               gui_.draw(); //clear the screen
+
+               return true;
+       } else {
+               return false;
+       }
+}
+
+bool turn_info::move_unit_along_current_route(bool check_shroud)
+{
+       const std::vector<gamemap::location> steps = current_route_.steps;
+       const size_t moves = 
::move_unit(&gui_,gameinfo_,status_,map_,units_,teams_,
+                          
steps,&recorder,&undo_stack_,&next_unit_,false,check_shroud);
+
+       cursor::set(cursor::NORMAL);
+
+       gui_.invalidate_game_status();
+
+       selected_hex_ = gamemap::location();
+       gui_.select_hex(gamemap::location());
+       
+       gui_.set_route(NULL);
+       gui_.set_paths(NULL);
+       current_paths_ = paths();
+
+       if(moves == 0)
+               return false;
+
+       redo_stack_.clear();
+
+       assert(moves <= steps.size());
+       const gamemap::location& dst = steps[moves-1];
+       const unit_map::const_iterator u = units_.find(dst);
+
+       //u may be equal to units_.end() in the case of e.g. a [teleport]
+       if(u != units_.end()) {
+               //Reselect the unit if the move was interrupted
+               if(dst != steps.back()) {
+                       selected_hex_ = dst;
+                       gui_.select_hex(dst);
+               }
+               
+               current_route_.steps.clear();
+               show_attack_options(u);
+               
+               if(current_paths_.routes.empty() == false) {
+                       current_paths_.routes[dst] = paths::route();
+                       selected_hex_ = dst;
+                       gui_.select_hex(dst);
+                       gui_.set_paths(&current_paths_);
+               }
+       }
+
+       return moves == steps.size();
+}
 
 void turn_info::left_click(const SDL_MouseButtonEvent& event)
 {
@@ -527,8 +738,6 @@
                return;
        }
 
-       const team& current_team = teams_[team_num_-1];
-
        // clicked on a hex on the minimap? then initiate minimap scrolling
        const gamemap::location& loc = 
gui_.minimap_location_on(event.x,event.y);
        minimap_scrolling_ = false;
@@ -554,155 +763,38 @@
                        route = enemy_paths_ ? current_paths_.routes.end() :
                                       current_paths_.routes.find(hex);
 
-       unit_map::iterator enemy = find_unit(hex);
+       unit_map::iterator enemy = find_unit(hex);
+
+       //see if we're trying to do a move-and-attack
+       if(!browse_ && u != units_.end() && enemy != units_.end()) {
+               const gamemap::location& attack_from = 
current_unit_attacks_from(hex);
+               if(attack_from.valid()) {
+                       if(move_unit_along_current_route(false)) { //move the 
unit without updating shroud
+                               u = find_unit(attack_from);
+                               enemy = find_unit(hex);
+                               if(u != units_.end() && u->second.side() == 
team_num_ &&
+                                  enemy != units_.end() && 
current_team().is_enemy(enemy->second.side())) {
+                                       if(attack_enemy(u,enemy) == false) {
+                                               undo();
+                                               return;
+                                       }
+                               }
+                       }
+
+                       if(clear_shroud()) {
+                               clear_undo_stack();
+                       }
+
+                       return;
+               }
+       }
 
        //see if we're trying to attack an enemy
        if(u != units_.end() && route != current_paths_.routes.end() && enemy 
!= units_.end() &&
           hex != selected_hex_ && !browse_ &&
           enemy->second.side() != u->second.side() &&
-          current_team.is_enemy(enemy->second.side())) {
-
-               const std::vector<attack_type>& attacks = u->second.attacks();
-               std::vector<std::string> items;
-
-               const int range = distance_between(u->first,enemy->first);
-               std::vector<int> attacks_in_range;
-
-               int best_weapon_index = -1;
-               int best_weapon_rating = 0;
-
-               std::vector<battle_stats> stats;
-
-               for(size_t a = 0; a != attacks.size(); ++a) {
-                       if(attacks[a].hexes() < range)
-                               continue;
-
-                       attacks_in_range.push_back(a);
-
-                       stats.push_back(evaluate_battle_stats(map_, 
selected_hex_, hex,
-                                                             a, units_, 
status_));
-
-                       int weapon_rating = stats.back().chance_to_hit_defender 
*
-                                       stats.back().damage_defender_takes * 
stats.back().nattacks;
-                       
-                       if (best_weapon_index < 0 || best_weapon_rating < 
weapon_rating) {
-                               best_weapon_index = items.size();
-                               best_weapon_rating = weapon_rating;
-                       }
-                       
-                       const battle_stats& st = stats.back();
-
-                       const std::string& attack_name = st.attack_name;
-                       const std::string& attack_special = 
st.attack_special.empty() ? "" : gettext(st.attack_special.c_str());
-                       const std::string& defend_name = st.defend_name;
-                       const std::string& defend_special = 
st.defend_special.empty() ? "" : gettext(st.defend_special.c_str());
-
-                       const std::string& range = gettext(st.range == "Melee" 
? N_("melee") : N_("ranged"));
-
-                       //if there is an attack special or defend special, we 
output a single space for the other unit, to make sure
-                       //that the attacks line up nicely.
-                       std::string special_pad = (attack_special.empty() == 
false || defend_special.empty() == false) ? " " : "";
-
-                       std::stringstream att;
-                       att << IMAGE_PREFIX << stats.back().attack_icon << 
COLUMN_SEPARATOR
-                           << font::BOLD_TEXT << attack_name
-                           << "\n" << stats.back().damage_defender_takes << "-"
-                               << stats.back().nattacks << " " << range << " ("
-                               << stats.back().chance_to_hit_defender << "%)\n"
-                               << attack_special << special_pad;
-
-                       att << COLUMN_SEPARATOR << _("vs") << COLUMN_SEPARATOR;
-                       att << font::BOLD_TEXT << defend_name << "\n" << 
stats.back().damage_attacker_takes << "-"
-                               << stats.back().ndefends << " " << range << " ("
-                               << stats.back().chance_to_hit_attacker
-                           << "%)\n" << defend_special << special_pad << 
COLUMN_SEPARATOR
-                           << IMAGE_PREFIX << stats.back().defend_icon;
-
-                       items.push_back(att.str());
-               }
-               
-               if (best_weapon_index >= 0) {
-                       items[best_weapon_index] = DEFAULT_ITEM + 
items[best_weapon_index];
-               }
-                       
-               //make it so that when we attack an enemy, the attacking unit
-               //is again shown in the status bar, so that we can easily
-               //compare between the attacking and defending unit
-               gui_.highlight_hex(gamemap::location());
-               gui_.draw(true,true);
-
-               attack_calculations_displayer calc_displayer(gui_,stats);
-               std::vector<gui::dialog_button> buttons;
-               buttons.push_back(gui::dialog_button(&calc_displayer,_("Damage 
Calculations")));
-
-               int res = 0;
-
-               {
-                       const events::event_context dialog_events_context;
-                       dialogs::unit_preview_pane 
attacker_preview(gui_,&map_,u->second,dialogs::unit_preview_pane::SHOW_BASIC,true);
-                       dialogs::unit_preview_pane 
defender_preview(gui_,&map_,enemy->second,dialogs::unit_preview_pane::SHOW_BASIC,false);
-                       std::vector<gui::preview_pane*> preview_panes;
-                       preview_panes.push_back(&attacker_preview);
-                       preview_panes.push_back(&defender_preview);
-
-                       res = gui::show_dialog(gui_,NULL,_("Attack Enemy"),
-                                       _("Choose weapon")+std::string(":\n"),
-                                       
gui::OK_CANCEL,&items,&preview_panes,"",NULL,-1,NULL,NULL,-1,-1,
-                                       NULL,&buttons);
-               }
-
-               cursor::set(cursor::NORMAL);
-
-               if(size_t(res) < attacks_in_range.size()) {
-                       res = attacks_in_range[res];
-
-                       u->second.set_goto(gamemap::location());
-                       clear_undo_stack();
-                       redo_stack_.clear();
-
-                       current_paths_ = paths();
-                       gui_.set_paths(NULL);
-
-                       game_events::fire("attack",selected_hex_,hex);
-
-                       //the event could have killed either the attacker or
-                       //defender, so we have to make sure they still exist
-                       u = units_.find(selected_hex_);
-                       enemy = units_.find(hex);
-
-                       if(u == units_.end() || enemy == units_.end() || 
size_t(res) >= attacks.size()) {
-                               return;
-                       }
-
-                       gui_.invalidate_all();
-                       gui_.draw();
-
-                       const bool defender_human = 
teams_[enemy->second.side()-1].is_human();
-
-                       recorder.add_attack(selected_hex_,hex,res);
-
-                       try {
-                               
attack(gui_,map_,teams_,selected_hex_,hex,res,units_,status_,gameinfo_);
-                       } catch(end_level_exception&) {
-                               //if the level ends due to a unit being killed, 
still see if
-                               //either the attacker or defender should advance
-                               
dialogs::advance_unit(gameinfo_,map_,units_,selected_hex_,gui_);
-                               
dialogs::advance_unit(gameinfo_,map_,units_,hex,gui_,!defender_human);
-                               throw;
-                       }
-
-                       
dialogs::advance_unit(gameinfo_,map_,units_,selected_hex_,gui_);
-                       
dialogs::advance_unit(gameinfo_,map_,units_,hex,gui_,!defender_human);
-
-                       selected_hex_ = gamemap::location();
-                       current_route_.steps.clear();
-                       gui_.set_route(NULL);
-
-                       check_victory(units_,teams_);
-
-                       gui_.invalidate_all();
-                       gui_.draw(); //clear the screen
-               }
+          current_team().is_enemy(enemy->second.side())) {
+               attack_enemy(u,enemy);
        }
 
        //otherwise we're trying to move to a hex
@@ -710,50 +802,9 @@
                     units_.count(selected_hex_) && !enemy_paths_ &&
                     enemy == units_.end() && !current_route_.steps.empty() &&
                     current_route_.steps.front() == selected_hex_) {
-
-               const std::vector<gamemap::location> steps = 
current_route_.steps;
-               const size_t moves = 
move_unit(&gui_,gameinfo_,status_,map_,units_,teams_,
-                                  steps,&recorder,&undo_stack_,&next_unit_);
-
-               cursor::set(cursor::NORMAL);
-
-               gui_.invalidate_game_status();
-
-               selected_hex_ = gamemap::location();
-               gui_.select_hex(gamemap::location());
-               
-               gui_.set_route(NULL);
-               gui_.set_paths(NULL);
-               current_paths_ = paths();
-
-               if(moves == 0)
-                       return;
-
-               redo_stack_.clear();
-
-               assert(moves <= steps.size());
-               const gamemap::location& dst = steps[moves-1];
-               const unit_map::const_iterator u = units_.find(dst);
-
-               //u may be equal to units_.end() in the case of e.g. a 
[teleport]
-               if(u != units_.end()) {
-                       //Reselect the unit if the move was interrupted
-                       if(dst != steps.back()) {
-                               selected_hex_ = dst;
-                               gui_.select_hex(dst);
-                       }
-                       
-                       current_route_.steps.clear();
-                       show_attack_options(u);
-                       
-                       if(current_paths_.routes.empty() == false) {
-                               current_paths_.routes[dst] = paths::route();
-                               selected_hex_ = dst;
-                               gui_.select_hex(dst);
-                               gui_.set_paths(&current_paths_);
-                       }
-
-                       if(clear_shroud()) clear_undo_stack();
+               move_unit_along_current_route();
+               if(clear_shroud()) {
+                       clear_undo_stack();
                }
        } else {
                gui_.set_paths(NULL);
@@ -781,16 +832,16 @@
                        unit u = it->second;
                        const gamemap::location go_to = u.get_goto();
                        if(map_.on_board(go_to)) {
-                               const shortest_path_calculator 
calc(u,current_team,
+                               const shortest_path_calculator 
calc(u,current_team(),
                                                                    
visible_units(),teams_,map_,status_);
 
                                const std::set<gamemap::location>* teleports = 
NULL;
 
                                std::set<gamemap::location> allowed_teleports;
                                if(u.type().teleports()) {
-                                       allowed_teleports = 
vacant_villages(current_team.villages(),units_);
+                                       allowed_teleports = 
vacant_villages(current_team().villages(),units_);
                                        teleports = &allowed_teleports;
-                                       
if(current_team.villages().count(it->first))
+                                       
if(current_team().villages().count(it->first))
                                                
allowed_teleports.insert(it->first);
 
                                }
@@ -818,6 +869,47 @@
                        current_paths_.routes[target->first] = paths::route();
                }
        }
+}
+
+gamemap::location turn_info::current_unit_attacks_from(const 
gamemap::location& loc) const
+{
+       const unit_map::const_iterator current = find_unit(selected_hex_);
+       if(current == units_.end() || current->second.side() != team_num_) {
+               return gamemap::location();
+       }
+
+       const unit_map::const_iterator enemy = find_unit(loc);
+       if(enemy == units_.end() || 
current_team().is_enemy(enemy->second.side()) == false) {
+               return gamemap::location();
+       }
+
+       int best_defense = 100;
+       gamemap::location res;
+       gamemap::location adj[6];
+       get_adjacent_tiles(loc,adj);
+       for(size_t n = 0; n != 6; ++n) {
+               if(map_.on_board(adj[n]) == false) {
+                       continue;
+               }
+
+               if(adj[n] == selected_hex_) {
+                       return gamemap::location();
+               }
+
+               if(find_unit(adj[n]) != units_.end()) {
+                       continue;
+               }
+
+               if(current_paths_.routes.count(adj[n])) {
+                       const int defense = 
current->second.defense_modifier(map_,map_.get_terrain(loc));
+                       if(defense < best_defense || res.valid() == false) {
+                               best_defense = defense;
+                               res = adj[n];
+                       }
+               }
+       }
+
+       return res;
 }
 
 void turn_info::move_unit_to_loc(const unit_map::const_iterator& ui, const 
gamemap::location& target, bool continue_move)
Index: wesnoth/src/playturn.hpp
diff -u wesnoth/src/playturn.hpp:1.55 wesnoth/src/playturn.hpp:1.56
--- wesnoth/src/playturn.hpp:1.55       Thu Dec  2 01:59:04 2004
+++ wesnoth/src/playturn.hpp    Fri Dec  3 01:19:29 2004
@@ -1,4 +1,4 @@
-/* $Id: playturn.hpp,v 1.55 2004/12/02 01:59:04 Sirp Exp $ */
+/* $Id: playturn.hpp,v 1.56 2004/12/03 01:19:29 Sirp Exp $ */
 /*
    Copyright (C) 2003 by David White <address@hidden>
    Part of the Battle for Wesnoth Project http://wesnoth.whitevine.net
@@ -184,7 +184,15 @@
        void left_click(const SDL_MouseButtonEvent& event);
        void show_menu(const std::vector<std::string>& items, int xloc, int 
yloc, bool context_menu);
 
-       void show_attack_options(unit_map::const_iterator u);
+       void show_attack_options(unit_map::const_iterator u);
+
+       //function which, given the location of a potential enemy to attack, 
will return the location
+       //that the currently selected unit would move to and attack it from 
this turn. Returns an
+       //invalid location if not possible.
+       gamemap::location current_unit_attacks_from(const gamemap::location& 
loc) const;
+
+       bool attack_enemy(unit_map::iterator attacker, unit_map::iterator 
defender);
+       bool move_unit_along_current_route(bool check_shroud=true);
 
        bool clear_shroud();
        void clear_undo_stack();




reply via email to

[Prev in Thread] Current Thread [Next in Thread]