Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
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
00050 }
00051
00052 void mapbuilder::pre_build()
00053 {
00054 foreach(team& t, *resources::teams)
00055 {
00056
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
00066
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
00073 continue;
00074 }
00075
00076
00077
00078
00079 resetters_.push_back(new unit_movement_resetter(u,!on_current_side));
00080
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
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
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
00118 {
00119 int original_moves = unit->movement_left();
00120
00121
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)
00128 {
00129
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 , size_t , team&, side_actions& sa)
00138 {
00139 return !sa.hidden();
00140 }
00141
00142 bool mapbuilder::post_visit_team(size_t turn, size_t , team&, side_actions&)
00143 {
00144 std::set<unit const*> seen;
00145
00146
00147
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
00162 applied_actions_this_turn_.clear();
00163
00164 acted_this_turn_.clear();
00165 return true;
00166 }
00167
00168 void mapbuilder::restore_normal_map()
00169 {
00170
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 }