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 "highlight_visitor.hpp"
00021
00022 #include "action.hpp"
00023 #include "attack.hpp"
00024 #include "manager.hpp"
00025 #include "move.hpp"
00026 #include "recall.hpp"
00027 #include "recruit.hpp"
00028 #include "side_actions.hpp"
00029 #include "suppose_dead.hpp"
00030
00031 #include "arrow.hpp"
00032 #include "foreach.hpp"
00033 #include "play_controller.hpp"
00034 #include "resources.hpp"
00035 #include "unit_map.hpp"
00036
00037 namespace wb
00038 {
00039
00040 highlight_visitor::highlight_visitor(unit_map& unit_map, side_actions_ptr side_actions)
00041 : visitor()
00042 , mode_(NONE)
00043 , unit_map_(unit_map)
00044 , mouseover_hex_()
00045 , exclusive_display_hexes_()
00046 , owner_unit_(NULL)
00047 , selection_candidate_(NULL)
00048 , selected_action_()
00049 , main_highlight_()
00050 , secondary_highlights_()
00051 , side_actions_(side_actions)
00052 {
00053 }
00054
00055 highlight_visitor::~highlight_visitor()
00056 {
00057 if (resources::screen && owner_unit_)
00058 unhighlight();
00059 }
00060
00061 void highlight_visitor::set_mouseover_hex(const map_location& hex)
00062 {
00063 clear();
00064
00065 if (!hex.valid())
00066 return;
00067
00068 real_map ensure_real_map;
00069 mouseover_hex_ = hex;
00070
00071 unit_map::iterator it = unit_map_.find(hex);
00072 if (it != unit_map_.end())
00073 {
00074 selection_candidate_ = &(*it);
00075
00076 if(resources::teams->at(it->side()-1).get_side_actions()->unit_has_actions(&*it))
00077 {
00078 owner_unit_ = &(*it);
00079 }
00080
00081
00082
00083
00084
00085
00086
00087
00088 }
00089
00090
00091 if(owner_unit_)
00092 {
00093 side_actions::iterator itor = side_actions_->find_first_action_of(owner_unit_);
00094 if(itor != side_actions_->end())
00095 selected_action_ = *itor;
00096 }
00097
00098
00099 if(side_actions_->empty()) {
00100 return;
00101 }
00102 BOOST_REVERSE_FOREACH(action_ptr act, *side_actions_)
00103 {
00104
00105
00106
00107
00108 if(act->is_numbering_hex(hex))
00109 {
00110 selected_action_ = act;
00111 break;
00112 }
00113 }
00114 }
00115
00116 void highlight_visitor::clear()
00117 {
00118 unhighlight();
00119 main_highlight_.reset();
00120 owner_unit_ = NULL;
00121 secondary_highlights_.clear();
00122 selected_action_.reset();
00123 }
00124
00125 void highlight_visitor::highlight()
00126 {
00127
00128 find_main_highlight();
00129
00130 if (action_ptr main = main_highlight_.lock())
00131 {
00132
00133 mode_ = HIGHLIGHT_MAIN;
00134 main->accept(*this);
00135 }
00136
00137 if (owner_unit_)
00138 {
00139
00140 find_secondary_highlights();
00141
00142
00143 resources::screen->add_exclusive_draw(owner_unit_->get_location(), *owner_unit_);
00144 exclusive_display_hexes_.insert(owner_unit_->get_location());
00145
00146 if (!secondary_highlights_.empty())
00147 {
00148
00149 mode_ = HIGHLIGHT_SECONDARY;
00150 foreach(weak_action_ptr weak, secondary_highlights_)
00151 {
00152 if (action_ptr action = weak.lock())
00153 {
00154 action->accept(*this);
00155 }
00156 }
00157 }
00158 }
00159 }
00160
00161 void highlight_visitor::unhighlight()
00162 {
00163
00164 if (action_ptr main = main_highlight_.lock() )
00165 {
00166 mode_ = UNHIGHLIGHT_MAIN;
00167 main->accept(*this);
00168 }
00169
00170
00171 mode_ = UNHIGHLIGHT_SECONDARY;
00172 foreach(weak_action_ptr weak, secondary_highlights_)
00173 {
00174 if (action_ptr action = weak.lock())
00175 {
00176 action->accept(*this);
00177 }
00178 }
00179
00180
00181 foreach(map_location hex, exclusive_display_hexes_)
00182 {
00183 resources::screen->remove_exclusive_draw(hex);
00184 }
00185 exclusive_display_hexes_.clear();
00186 }
00187
00188 action_ptr highlight_visitor::get_execute_target()
00189 {
00190 if(action_ptr locked = selected_action_.lock())
00191 return *side_actions_->find_first_action_of(locked->get_unit());
00192 else
00193 return action_ptr();
00194 }
00195 action_ptr highlight_visitor::get_delete_target()
00196 {
00197 if(action_ptr locked = selected_action_.lock())
00198 return *side_actions_->find_last_action_of(locked->get_unit());
00199 else
00200 return action_ptr();
00201 }
00202
00203 action_ptr highlight_visitor::get_bump_target()
00204 {
00205 return selected_action_.lock();
00206 }
00207
00208 unit* highlight_visitor::get_selection_target()
00209 {
00210 if (owner_unit_)
00211 return owner_unit_;
00212 else
00213 return selection_candidate_;
00214 }
00215
00216 void highlight_visitor::visit(move_ptr move)
00217 {
00218 switch (mode_)
00219 {
00220 case FIND_MAIN_HIGHLIGHT:
00221 if (move->get_dest_hex() == mouseover_hex_)
00222 {
00223 main_highlight_ = move;
00224 }
00225 break;
00226 case FIND_SECONDARY_HIGHLIGHTS:
00227 if (move->get_unit() == owner_unit_
00228 && move != main_highlight_.lock())
00229 {
00230 secondary_highlights_.push_back(move);
00231 }
00232 break;
00233 case HIGHLIGHT_MAIN:
00234 if (move->arrow_)
00235 {
00236 move->set_arrow_brightness(move::ARROW_BRIGHTNESS_FOCUS);
00237 }
00238 if (move->fake_unit_)
00239 {
00240
00241 move->fake_unit_->set_ghosted(true);
00242
00243 resources::screen->add_exclusive_draw(move->fake_unit_->get_location(), *move->fake_unit_);
00244 exclusive_display_hexes_.insert(move->fake_unit_->get_location());
00245 }
00246 break;
00247 case HIGHLIGHT_SECONDARY:
00248 if (move->arrow_)
00249 {
00250 move->set_arrow_brightness(move::ARROW_BRIGHTNESS_HIGHLIGHTED);
00251 }
00252 if (move->fake_unit_)
00253 {
00254 move->fake_unit_->set_ghosted(true);
00255
00256 resources::screen->add_exclusive_draw(move->fake_unit_->get_location(), *move->fake_unit_);
00257 exclusive_display_hexes_.insert(move->fake_unit_->get_location());
00258 }
00259 break;
00260 case UNHIGHLIGHT_MAIN:
00261 case UNHIGHLIGHT_SECONDARY:
00262 if (move->arrow_)
00263 {
00264 move->set_arrow_brightness(move::ARROW_BRIGHTNESS_STANDARD);
00265 }
00266 if (move->fake_unit_)
00267 {
00268 move->fake_unit_->set_disabled_ghosted(false);
00269 }
00270 break;
00271 default:
00272 assert (false);
00273 break;
00274 }
00275
00276
00277
00278 if (move->fake_unit_)
00279 {
00280 side_actions& sa = *resources::teams->at(move->team_index()).get_side_actions();
00281 side_actions::iterator last_action = sa.find_last_action_of(move->get_unit());
00282 side_actions::iterator second_to_last_action =
00283 last_action != sa.end() && last_action != sa.begin() ? last_action - 1 : sa.end();
00284 bool this_is_last_action = last_action != sa.end() && move == *last_action;
00285 bool last_action_has_fake_unit = last_action != sa.end() && (*last_action)->get_fake_unit();
00286 bool this_is_second_to_last_action = (second_to_last_action != sa.end()
00287 && move == *second_to_last_action);
00288
00289 if (this_is_last_action
00290 || (this_is_second_to_last_action && !last_action_has_fake_unit))
00291 {
00292 move->fake_unit_->set_standing(true);
00293 }
00294 }
00295 }
00296
00297 void highlight_visitor::visit(attack_ptr attack)
00298 {
00299 visit(boost::static_pointer_cast<move>(attack));
00300
00301 }
00302
00303 void highlight_visitor::visit(recruit_ptr recruit)
00304 {
00305 switch (mode_)
00306 {
00307 case FIND_MAIN_HIGHLIGHT:
00308 if (recruit->recruit_hex_ == mouseover_hex_)
00309 {
00310 main_highlight_ = recruit;
00311 }
00312 break;
00313 case FIND_SECONDARY_HIGHLIGHTS:
00314 break;
00315 case HIGHLIGHT_MAIN:
00316 if (recruit->fake_unit_)
00317 {
00318
00319
00320
00321 resources::screen->add_exclusive_draw(recruit->fake_unit_->get_location(), *recruit->fake_unit_);
00322 exclusive_display_hexes_.insert(recruit->fake_unit_->get_location());
00323 }
00324 break;
00325 case HIGHLIGHT_SECONDARY:
00326 break;
00327 case UNHIGHLIGHT_MAIN:
00328 case UNHIGHLIGHT_SECONDARY:
00329 if (recruit->fake_unit_)
00330 {
00331
00332 }
00333 break;
00334 default:
00335 assert (false);
00336 }
00337 }
00338
00339 void highlight_visitor::visit(recall_ptr recall)
00340 {
00341 switch (mode_)
00342 {
00343 case FIND_MAIN_HIGHLIGHT:
00344 if (recall->recall_hex_ == mouseover_hex_)
00345 {
00346 main_highlight_ = recall;
00347 }
00348 break;
00349 case FIND_SECONDARY_HIGHLIGHTS:
00350 break;
00351 case HIGHLIGHT_MAIN:
00352 if (recall->fake_unit_)
00353 {
00354
00355 }
00356 break;
00357 case HIGHLIGHT_SECONDARY:
00358 break;
00359 case UNHIGHLIGHT_MAIN:
00360 case UNHIGHLIGHT_SECONDARY:
00361 if (recall->fake_unit_)
00362 {
00363
00364
00365
00366 resources::screen->add_exclusive_draw(recall->fake_unit_->get_location(), *recall->fake_unit_);
00367 exclusive_display_hexes_.insert(recall->fake_unit_->get_location());
00368 }
00369 break;
00370 default:
00371 assert (false);
00372 }
00373 }
00374
00375 void highlight_visitor::visit(suppose_dead_ptr sup_d)
00376 {
00377 switch(mode_)
00378 {
00379 case FIND_MAIN_HIGHLIGHT:
00380 if (sup_d->get_source_hex() == mouseover_hex_)
00381 {
00382 main_highlight_ = sup_d;
00383 }
00384 break;
00385 case FIND_SECONDARY_HIGHLIGHTS:
00386 break;
00387 case HIGHLIGHT_MAIN:
00388 break;
00389 case HIGHLIGHT_SECONDARY:
00390 break;
00391 case UNHIGHLIGHT_MAIN:
00392 break;
00393 case UNHIGHLIGHT_SECONDARY:
00394 break;
00395 default:
00396 assert (false);
00397 }
00398 }
00399
00400 void highlight_visitor::find_main_highlight()
00401 {
00402
00403
00404 mode_ = FIND_MAIN_HIGHLIGHT;
00405 assert(main_highlight_.expired());
00406
00407
00408
00409
00410
00411 reverse_visit_all();
00412 }
00413
00414
00415 bool highlight_visitor::process(size_t, team&, side_actions&, side_actions::iterator itor)
00416 {
00417 (*itor)->accept(*this);
00418 if (action_ptr main = main_highlight_.lock())
00419 {
00420 owner_unit_ = main->get_unit();
00421 return false;
00422 }
00423 return true;
00424 }
00425
00426 void highlight_visitor::find_secondary_highlights()
00427 {
00428 assert(owner_unit_);
00429 assert(secondary_highlights_.empty());
00430 mode_ = FIND_SECONDARY_HIGHLIGHTS;
00431 visit_all_actions();
00432 }
00433
00434 }