whiteboard/mapbuilder.cpp

Go to the documentation of this file.
00001 /* $Id: mapbuilder.cpp 52533 2012-01-07 02:35:17Z shadowmaster $ */
00002 /*
00003  Copyright (C) 2010 - 2012 by Gabriel Morin <gabrielmorin (at) gmail (dot) com>
00004  Part of the Battle for Wesnoth Project http://www.wesnoth.org
00005 
00006  This program is free software; you can redistribute it and/or modify
00007  it under the terms of the GNU General Public License as published by
00008  the Free Software Foundation; either version 2 of the License, or
00009    (at your option) any later version.
00010  This program is distributed in the hope that it will be useful,
00011  but WITHOUT ANY WARRANTY.
00012 
00013  See the COPYING file for more details.
00014  */
00015 
00016 /**
00017  * @file
00018  */
00019 
00020 #include "mapbuilder.hpp"
00021 
00022 #include "action.hpp"
00023 #include "move.hpp"
00024 #include "side_actions.hpp"
00025 #include "utility.hpp"
00026 
00027 #include "foreach.hpp"
00028 #include "play_controller.hpp"
00029 #include "resources.hpp"
00030 #include "unit.hpp"
00031 #include "unit_map.hpp"
00032 
00033 namespace wb
00034 {
00035 
00036 mapbuilder::mapbuilder(unit_map& unit_map)
00037     : unit_map_(unit_map)
00038     , applied_actions_()
00039     , applied_actions_this_turn_()
00040     , resetters_()
00041     , removers_()
00042     , acted_this_turn_()
00043 {
00044 }
00045 
00046 mapbuilder::~mapbuilder()
00047 {
00048     restore_normal_map();
00049     //Remember that the member variable resetters_ is destructed here
00050 }
00051 
00052 void mapbuilder::pre_build()
00053 {
00054     foreach(team& t, *resources::teams)
00055     {
00056         //Reset spent gold to zero, it'll be recalculated during the map building
00057         t.get_side_actions()->reset_gold_spent();
00058     }
00059 
00060     int current_side = resources::controller->current_side();
00061     foreach(unit& u, *resources::units)
00062     {
00063         bool on_current_side = (u.side() == current_side);
00064 
00065         //Remove any unit the current side cannot see to avoid their detection by planning
00066         //Units will be restored to the unit map by destruction of removers_
00067 
00068         if (!on_current_side && !u.is_visible_to_team((*resources::teams)[viewer_team()], false))
00069         {
00070             removers_.push_back(new temporary_unit_remover(*resources::units, u.get_location()));
00071 
00072             //Don't do anything else to the removed unit!
00073             continue;
00074         }
00075 
00076         //Reset movement points, to be restored by destruction of resetters_
00077 
00078         //restore movement points only to units not on the current side
00079         resetters_.push_back(new unit_movement_resetter(u,!on_current_side));
00080         //make sure current side's units are not reset to full moves on first turn
00081         if(on_current_side)
00082             acted_this_turn_.insert(&u);
00083     }
00084 }
00085 
00086 void mapbuilder::build_map()
00087 {
00088     pre_build();
00089     if (wb::has_actions()) {
00090         visit_all();
00091     }
00092 }
00093 
00094 ///@return whether act is valid
00095 bool mapbuilder::process_helper(side_actions::iterator const& itor, action_ptr const& act)
00096 {
00097     validate(itor);
00098     if(act->is_valid())
00099     {
00100         act->apply_temp_modifier(unit_map_);
00101         applied_actions_.push_back(act);
00102         applied_actions_this_turn_.push_back(act);
00103         return true;
00104     }
00105     else //invalid
00106         return false;
00107 }
00108 
00109 bool mapbuilder::process(size_t, team&, side_actions&, side_actions::iterator action_it)
00110 {
00111     action_ptr action = *action_it;
00112 
00113     unit* unit = action->get_unit();
00114 
00115     if(!unit || !action->is_valid() || acted_this_turn_.find(unit) != acted_this_turn_.end())
00116         process_helper(action_it,action);
00117     else //gotta restore MP first
00118     {
00119         int original_moves = unit->movement_left();
00120 
00121         //reset MP
00122         unit->set_movement(unit->total_movement());
00123         acted_this_turn_.insert(unit);
00124 
00125         bool revert = !process_helper(action_it,action);
00126 
00127         if(revert) //< the action was invalid
00128         {
00129             //didn't need to restore MP after all ... so let's change it back
00130             acted_this_turn_.erase(unit);
00131             unit->set_movement(original_moves);
00132         }
00133     }
00134     return true;
00135 }
00136 
00137 bool mapbuilder::pre_visit_team(size_t /*turn*/, size_t /*team_index*/, team&, side_actions& sa)
00138 {
00139     return !sa.hidden();
00140 }
00141 
00142 bool mapbuilder::post_visit_team(size_t turn, size_t /*team_index*/, team&, side_actions&)
00143 {
00144     std::set<unit const*> seen;
00145 
00146     // Go backwards through the actions of this turn to identify
00147     // which ones are moves that end a turn.
00148     BOOST_REVERSE_FOREACH(action_ptr action, applied_actions_this_turn_)
00149     {
00150         move_ptr move = boost::dynamic_pointer_cast<class move>(action);
00151         if (move) {
00152             move->set_turn_number(0);
00153             if(move->get_route().steps.size() > 1 && seen.count(move->get_unit()) == 0)
00154             {
00155                 seen.insert(move->get_unit());
00156                 move->set_turn_number(turn + 1);
00157             }
00158         }
00159     }
00160 
00161     // Clear list of planned actions applied this turn
00162     applied_actions_this_turn_.clear();
00163     // Clear the list of units of this team that have acted this turn
00164     acted_this_turn_.clear();
00165     return true;
00166 }
00167 
00168 void mapbuilder::restore_normal_map()
00169 {
00170     //applied_actions_ contain only the actions that we applied to the unit map
00171     BOOST_REVERSE_FOREACH(action_ptr act, applied_actions_)
00172     {
00173         assert(act->is_valid());
00174         act->remove_temp_modifier(unit_map_);
00175     }
00176 }
00177 
00178 } // end namespace wb
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated by doxygen 1.7.1 on Fri May 25 2012 01:03:15 for The Battle for Wesnoth
Gna! | Forum | Wiki | CIA | devdocs