The Battle for Wesnoth  1.19.0-dev
move.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2010 - 2024
3  by Gabriel Morin <gabrielmorin (at) gmail (dot) com>
4  Part of the Battle for Wesnoth Project https://www.wesnoth.org/
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY.
12 
13  See the COPYING file for more details.
14 */
15 
16 /**
17  * @file
18  */
19 
20 #include "whiteboard/move.hpp"
21 
22 #include "whiteboard/visitor.hpp"
24 #include "whiteboard/utility.hpp"
25 
26 #include "arrow.hpp"
27 #include "config.hpp"
28 #include "fake_unit_ptr.hpp"
29 #include "font/standard_colors.hpp"
30 #include "game_board.hpp"
31 #include "game_end_exceptions.hpp"
32 #include "map/map.hpp"
33 #include "mouse_events.hpp"
34 #include "play_controller.hpp"
35 #include "resources.hpp"
36 #include "team.hpp"
37 #include "units/unit.hpp"
39 #include "units/udisplay.hpp"
40 #include "units/map.hpp"
41 
42 namespace wb {
43 
44 std::ostream& operator<<(std::ostream &s, move_ptr move)
45 {
46  assert(move);
47  return move->print(s);
48 }
49 
50 std::ostream& operator<<(std::ostream &s, move_const_ptr move)
51 {
52  assert(move);
53  return move->print(s);
54 }
55 
56 std::ostream& move::print(std::ostream &s) const
57 {
58  if(!get_unit()) {
59  s << "Move for unknown unit [" << unit_underlying_id_ << "] " << "from (" << get_source_hex() << ") to (" << get_dest_hex() << ")";
60  }
61  else {
62  s << "Move for unit " << get_unit()->name() << " [" << get_unit()->id() << "] "
63  << "from (" << get_source_hex() << ") to (" << get_dest_hex() << ")";
64  }
65  return s;
66 }
67 
68 move::move(std::size_t team_index, bool hidden, unit& u, const pathfind::marked_route& route,
69  arrow_ptr arrow, fake_unit_ptr fake_unit)
70 : action(team_index,hidden),
71  unit_underlying_id_(u.underlying_id()),
72  unit_id_(),
73  route_(new pathfind::marked_route(route)),
74  movement_cost_(0),
75  turn_number_(0),
76  arrow_(arrow),
77  fake_unit_(std::move(fake_unit)),
78  arrow_brightness_(),
79  arrow_texture_(),
80  mover_(),
81  fake_unit_hidden_(false)
82 {
83  assert(!route_->steps.empty());
84 
85  if(hidden)
86  fake_unit_->set_hidden(true);
87 
88  this->init();
89 }
90 
91 move::move(const config& cfg, bool hidden)
92  : action(cfg,hidden)
93  , unit_underlying_id_(0)
94  , unit_id_()
95  , route_(new pathfind::marked_route())
96  , movement_cost_(0)
97  , turn_number_(0)
98  , arrow_(new arrow(hidden))
99  , fake_unit_()
100  , arrow_brightness_()
101  , arrow_texture_()
102  , mover_()
103  , fake_unit_hidden_(false)
104 {
105  // Construct and validate unit_
106  unit_map::iterator unit_itor = resources::gameboard->units().find(cfg["unit_"]);
107  if(unit_itor == resources::gameboard->units().end())
108  throw action::ctor_err("move: Invalid underlying_id");
109  unit_underlying_id_ = unit_itor->underlying_id();
110 
111  // Construct and validate route_
112  auto route_cfg = cfg.optional_child("route_");
113  if(!route_cfg)
114  throw action::ctor_err("move: Invalid route_");
115  route_->move_cost = route_cfg["move_cost"];
116  for(const config& loc_cfg : route_cfg->child_range("step")) {
117  route_->steps.emplace_back(loc_cfg["x"],loc_cfg["y"], wml_loc());
118  }
119  for(const config& mark_cfg : route_cfg->child_range("mark")) {
120  route_->marks[map_location(mark_cfg["x"],mark_cfg["y"], wml_loc())]
121  = pathfind::marked_route::mark(mark_cfg["turns"],
122  mark_cfg["zoc"].to_bool(),
123  mark_cfg["capture"].to_bool(),
124  mark_cfg["invisible"].to_bool());
125  }
126 
127  // Validate route_ some more
128  const std::vector<map_location>& steps = route_->steps;
129  if(steps.empty())
130  throw action::ctor_err("move: Invalid route_");
131 
132  // Construct arrow_
134  arrow_->set_style(arrow::STYLE_STANDARD);
135  arrow_->set_path(route_->steps);
136 
137  // Construct fake_unit_
139  if(hidden)
140  fake_unit_->set_hidden(true);
141  fake_unit_->anim_comp().set_ghosted(true);
142  unit_display::move_unit(route_->steps, fake_unit_.get_unit_ptr(), false); //get facing right
143  fake_unit_->set_location(route_->steps.back());
144 
145  this->init();
146 }
147 
148 void move::init(unit* u)
149 {
150  if(get_unit()) {
151  unit_id_ = get_unit()->id();
152  }
153  else if(u) {
154  unit_id_ = u->id();
155  }
156  //This action defines the future position of the unit, make its fake unit more visible
157  //than previous actions' fake units
158  if (fake_unit_)
159  {
160  fake_unit_->anim_comp().set_ghosted(true);
161  }
162  side_actions_ptr side_actions = resources::gameboard->teams().at(team_index()).get_side_actions();
164  if (action != side_actions->end())
165  {
166  if (move_ptr move = std::dynamic_pointer_cast<class move>(*action))
167  {
168  if (move->fake_unit_)
169  move->fake_unit_->anim_comp().set_disabled_ghosted(true);
170  }
171  }
172 
173  // Initialize arrow_brightness_ and arrow_texture_ using arrow_->style_
174  std::string arrow_style = arrow_->get_style();
175  if(arrow_style == arrow::STYLE_STANDARD)
176  {
179  }
180  else if(arrow_style == arrow::STYLE_HIGHLIGHTED)
181  {
184  }
185  else if(arrow_style == arrow::STYLE_FOCUS)
186  {
189  }
190  else if(arrow_style == arrow::STYLE_FOCUS_INVALID)
191  {
194  }
195 }
196 
198 
200 {
201  v.visit(shared_from_this());
202 }
203 
204 void move::execute(bool& success, bool& complete)
205 {
206  if(!valid()) {
207  success = false;
208  //Setting complete to true signifies to side_actions to delete the planned action.
209  complete = true;
210  return;
211  }
212 
213  if(get_source_hex() == get_dest_hex()) {
214  //zero-hex move, used by attack subclass
215  success = complete = true;
216  return;
217  }
218 
219  LOG_WB << "Executing: " << shared_from_this();
220 
221  // Copy the current route to ensure it remains valid throughout the animation.
222  const std::vector<map_location> steps = route_->steps;
223 
225  hide_fake_unit();
226 
227  std::size_t num_steps;
228  bool interrupted;
229  try {
231  num_steps = mouse_handler.move_unit_along_route(steps, interrupted);
232  } catch (const return_to_play_side_exception&) {
234  throw; // we rely on the caller to delete this action
235  }
236  const map_location & final_location = steps[num_steps];
237  unit_map::const_iterator unit_it = resources::gameboard->units().find(final_location);
238 
239  if ( num_steps == 0 )
240  {
241  LOG_WB << "Move execution resulted in zero movement.";
242  success = false;
243  complete = true;
244  }
245  else if ( unit_it == resources::gameboard->units().end() || (unit_id_.empty() && ( unit_it->id() != unit_id_ )))
246  {
247  WRN_WB << "Unit disappeared from map during move execution.";
248  success = false;
249  complete = true;
250  }
251  else
252  {
253  complete = num_steps + 1 == steps.size();
254  success = complete && !interrupted;
255 
256  if ( !success )
257  {
258  if ( complete )
259  {
260  LOG_WB << "Move completed, but interrupted on final hex. Halting.";
261  //reset to a single-hex path, just in case *this is a wb::attack
262  route_->steps = std::vector<map_location>(1, final_location);
263  arrow_.reset();
264  }
265  else
266  {
267  LOG_WB << "Move finished at (" << final_location << ") instead of at (" << get_dest_hex() << "). Setting new path.";
268  route_->steps = std::vector<map_location>(steps.begin() + num_steps, steps.end());
269  //FIXME: probably better to use the new calculate_new_route() instead of the above:
270  //calculate_new_route(final_location, steps.back());
271  // Of course, "better" would need to be verified.
272 
273  //Update route_->move_cost
274  route_.reset(new pathfind::marked_route(mark_route(route_->route, true)));
275  arrow_->set_path(route_->steps);
276  }
277  }
278  }
279 
280  if(!complete)
281  {
283  show_fake_unit();
284  }
285 }
286 
288 {
290  if (itor.valid())
291  return itor.get_shared_ptr();
292  else
293  return unit_ptr();
294 }
295 
297 {
298  assert(route_ && !route_->steps.empty());
299  return route_->steps.front();
300 }
301 
303 {
304  assert(route_ && !route_->steps.empty());
305  return route_->steps.back();
306 }
307 
309 {
310  route_.reset(new pathfind::marked_route(route));
311  arrow_->set_path(route_->steps);
312 }
313 
314 void move::modify_unit(unit& new_unit)
315 {
316  unit_underlying_id_ = new_unit.underlying_id();
317  unit_id_ = new_unit.id();
318 }
319 
320 bool move::calculate_new_route(const map_location& source_hex, const map_location& dest_hex)
321 {
322  pathfind::plain_route new_plain_route;
324  resources::gameboard->teams().at(team_index()),
325  resources::gameboard->teams(), resources::gameboard->map());
326  new_plain_route = pathfind::a_star_search(source_hex,
327  dest_hex, 10000, path_calc, resources::gameboard->map().w(), resources::gameboard->map().h());
328  if (new_plain_route.move_cost >= path_calc.getNoPathValue()) return false;
329  route_.reset(new pathfind::marked_route(pathfind::mark_route(new_plain_route)));
330  return true;
331 }
332 
334 {
335  if (get_source_hex() == get_dest_hex())
336  return; //zero-hex move, used by attack subclass
337 
338  // Safety: Make sure the old temporary_unit_mover (if any) is destroyed
339  // before creating a new one.
340  mover_.reset();
341 
342  //@todo: deal with multi-turn moves, which may for instance end their first turn
343  // by capturing a village
344 
345  //@todo: we may need to change unit status here and change it back in remove_temp_modifier
346  unit* unit;
347  {
349  assert(unit_it != unit_map.end());
350  unit = &*unit_it;
351  }
352 
353  if (route_->move_cost == -1) {
354  // TODO: check_validity also calls pathfind::mark_route(get_route().route), optimize/refactor this to only call that once.
355  route_->move_cost = pathfind::mark_route(get_route().route, true).move_cost;
356  }
357  //Modify movement points
358  DBG_WB <<"Move: Changing movement points for unit " << unit->name() << " [" << unit->id()
359  << "] from " << unit->movement_left() << " to "
360  << calculate_moves_left(*unit) << ".";
361  // Move the unit
362  DBG_WB << "Move: Temporarily moving unit " << unit->name() << " [" << unit->id()
363  << "] from (" << get_source_hex() << ") to (" << get_dest_hex() <<")";
365 
366  //Update status of fake unit (not undone by remove_temp_modifiers)
367  //@todo this contradicts the name "temp_modifiers"
368  fake_unit_->set_movement(unit->movement_left(), true);
369 }
370 
372 {
373  if (get_source_hex() == get_dest_hex())
374  return; //zero-hex move, probably used by attack subclass
375 
376  // Debug movement points
377  if ( !lg::debug().dont_log(log_whiteboard) )
378  {
379  unit* unit;
380  {
382  assert(unit_it != resources::gameboard->units().end());
383  unit = &*unit_it;
384  }
385  DBG_WB << "Move: Movement points for unit " << unit->name() << " [" << unit->id()
386  << "] should get changed from " << unit->movement_left() << " to "
387  << calculate_moves_left(*unit) << ".";
388  }
389 
390  // Restore the unit to its original position and movement.
391  mover_.reset();
392 }
393 
394 void move::draw_hex(const map_location& hex)
395 {
396  //display turn info for turns 2 and above
397  if (hex == get_dest_hex() && turn_number_ >= 2)
398  {
399  std::stringstream turn_text;
400  turn_text << turn_number_;
402  }
403 }
404 
406 {
407  arrow_->hide();
408  if(!fake_unit_hidden_)
409  fake_unit_->set_hidden(true);
410 }
411 
413 {
414  arrow_->show();
415  if(!fake_unit_hidden_)
416  fake_unit_->set_hidden(false);
417 }
418 
420 {
421  fake_unit_hidden_ = true;
422  if(!hidden())
423  fake_unit_->set_hidden(true);
424 }
425 
427 {
428  fake_unit_hidden_ = false;
429  if(!hidden())
430  fake_unit_->set_hidden(false);
431 }
432 
434 {
435  return get_dest_hex();
436 }
437 
439 {
440  // Used to deal with multiple return paths.
441  class arrow_texture_setter {
442  public:
443  arrow_texture_setter(const move *target, move::ARROW_TEXTURE current_texture, move::ARROW_TEXTURE setting_texture):
444  target(target),
445  current_texture(current_texture),
446  setting_texture(setting_texture) {}
447 
448  ~arrow_texture_setter() {
449  if(current_texture!=setting_texture) {
450  target->set_arrow_texture(setting_texture);
451  }
452  }
453 
454  void set_texture(move::ARROW_TEXTURE texture) { setting_texture=texture; }
455 
456  private:
457  const move *target;
458  move::ARROW_TEXTURE current_texture, setting_texture;
459  };
460 
461  arrow_texture_setter setter(this, arrow_texture_, ARROW_TEXTURE_INVALID);
462 
463  if(!(get_source_hex().valid() && get_dest_hex().valid())) {
464  return INVALID_LOCATION;
465  }
466 
467  //Check that the unit still exists in the source hex
468  unit_map::iterator unit_it;
470  if(unit_it == resources::gameboard->units().end()) {
471  return NO_UNIT;
472  }
473 
474  //check if the unit in the source hex has the same unit id as before,
475  //i.e. that it's the same unit
476  if((!unit_id_.empty() && unit_id_ != unit_it->id()) || unit_underlying_id_ != unit_it->underlying_id()) {
477  return UNIT_CHANGED;
478  }
479 
480  //If the path has at least two hexes (it can have less with the attack subclass), ensure destination hex is free
481  if(get_route().steps.size() >= 2 && resources::gameboard->get_visible_unit(get_dest_hex(),resources::gameboard->teams().at(viewer_team())) != nullptr) {
482  return LOCATION_OCCUPIED;
483  }
484 
485  //check that the path is good
486  if(get_source_hex() != get_dest_hex()) { //skip zero-hex move used by attack subclass
487 
488  // Mark the plain route to see if the move can still be done in one turn,
489  // which is always the case for planned moves
490  // TODO: this check is rather slow, skip it if the gamestat has not changed.
491  pathfind::marked_route checked_route = pathfind::mark_route(get_route().route);
492 
493  if(checked_route.marks[checked_route.steps.back()].turns != 1) {
494  return TOO_FAR;
495  }
496  }
497 
498  // The move is valid, so correct the setter.
499  setter.set_texture(ARROW_TEXTURE_VALID);
500 
501  return OK;
502 }
503 
505 {
506  config final_cfg = action::to_config();
507 
508  final_cfg["type"]="move";
509  final_cfg["unit_"]=static_cast<int>(unit_underlying_id_);
510 // final_cfg["movement_cost_"]=movement_cost_; //Unnecessary
511 // final_cfg["unit_id_"]=unit_id_; //Unnecessary
512 
513  //Serialize route_
514  config route_cfg;
515  route_cfg["move_cost"]=route_->move_cost;
516  for(const map_location& loc : route_->steps)
517  {
518  config loc_cfg;
519  loc_cfg["x"]=loc.wml_x();
520  loc_cfg["y"]=loc.wml_y();
521  route_cfg.add_child("step", std::move(loc_cfg));
522  }
523  typedef std::pair<map_location,pathfind::marked_route::mark> pair_loc_mark;
524  for(const pair_loc_mark item : route_->marks)
525  {
526  config mark_cfg;
527  mark_cfg["x"]=item.first.wml_x();
528  mark_cfg["y"]=item.first.wml_y();
529  mark_cfg["turns"]=item.second.turns;
530  mark_cfg["zoc"]=item.second.zoc;
531  mark_cfg["capture"]=item.second.capture;
532  mark_cfg["invisible"]=item.second.invisible;
533  route_cfg.add_child("mark", std::move(mark_cfg));
534  }
535  final_cfg.add_child("route_", std::move(route_cfg));
536 
537  return final_cfg;
538 }
539 
541 {
542  assert(route_);
544  {
545 
546  // @todo: find a better treatment of movement points when defining moves out-of-turn
547  if(u.movement_left() - route_->move_cost < 0
549  WRN_WB << shared_from_this() << " defined with insufficient movement left.";
550  }
551 
552  // If unit finishes move in a village it captures, set the move cost to unit's movement_left()
553  if (route_->marks[get_dest_hex()].capture)
554  {
555  return 0;
556  }
557  else
558  {
559  return u.movement_left() - route_->move_cost;
560  }
561  }
562  return 0;
563 }
564 
566 {
570 }
571 
572 //If you add more arrow styles, this will need to change
573 /* private */
575 {
577  {
579  return;
580  }
581 
582  switch(arrow_brightness_)
583  {
585  arrow_->set_style(arrow::STYLE_STANDARD);
586  break;
588  arrow_->set_style(arrow::STYLE_HIGHLIGHTED);
589  break;
591  arrow_->set_style(arrow::STYLE_FOCUS);
592  break;
593  }
594 }
595 
596 } // end namespace wb
const std::vector< map_location > & route_
Definition: move.cpp:294
Arrows destined to be drawn on the map.
Arrows destined to be drawn on the map.
Definition: arrow.hpp:30
static const std::string STYLE_FOCUS_INVALID
Definition: arrow.hpp:70
static const std::string STYLE_FOCUS
Definition: arrow.hpp:69
static const std::string STYLE_STANDARD
If you add more styles, you should look at move::update_arrow_style()
Definition: arrow.hpp:67
static const std::string STYLE_HIGHLIGHTED
Definition: arrow.hpp:68
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:159
child_itors child_range(config_key_type key)
Definition: config.cpp:273
optional_config_impl< config > optional_child(config_key_type key, int n=0)
Euivalent to mandatory_child, but returns an empty optional if the nth child was not found.
Definition: config.cpp:385
config & add_child(config_key_type key)
Definition: config.cpp:441
void draw_text_in_hex(const map_location &loc, const drawing_layer layer, const std::string &text, std::size_t font_size, color_t color, double x_in_hex=0.5, double y_in_hex=0.5)
Draw text on a hex.
Definition: display.cpp:1476
int viewing_side() const
The 1-based equivalent of the 0-based viewing_team() function.
Definition: display.hpp:131
bool invalidate(const map_location &loc)
Function to invalidate a specific tile for redrawing.
Definition: display.cpp:3145
@ LAYER_MOVE_INFO
Movement info (defense%, etc...).
Definition: display.hpp:858
static display * get_singleton()
Returns the display object if a display object exists.
Definition: display.hpp:102
std::size_t move_unit_along_route(const std::vector< map_location > &steps, bool &interrupted)
Moves a unit across the board for a player.
Holds a temporary unit that can be drawn on the map without being placed in the unit_map.
internal_ptr get_unit_ptr()
Get a copy of the internal unit pointer.
virtual const std::vector< team > & teams() const override
Definition: game_board.hpp:79
unit * get_visible_unit(const map_location &loc, const team &current_team, bool see_all=false)
Definition: game_board.cpp:213
virtual const unit_map & units() const override
Definition: game_board.hpp:106
events::mouse_handler & get_mouse_handler_base() override
Get a reference to a mouse handler member a derived class uses.
int current_side() const
Returns the number of the side whose turn it is.
Exception used to escape form the ai or ui code to playsingle_controller::play_side.
static std::string get_side_color_id(unsigned side)
Definition: team.cpp:971
Wrapper class to encapsulate creation and management of an SDL_Texture.
Definition: texture.hpp:33
Container associating units to locations.
Definition: map.hpp:98
unit_iterator end()
Definition: map.hpp:428
unit_iterator find(std::size_t id)
Definition: map.cpp:302
This class represents a single unit of a specific type.
Definition: unit.hpp:133
Abstract base class for all the whiteboard planned actions.
Definition: action.hpp:34
bool hidden() const
Definition: action.hpp:64
bool valid()
Returns whether this action is valid or not.
Definition: action.hpp:135
std::size_t team_index() const
Returns the index of the team that owns this action.
Definition: action.hpp:84
virtual config to_config() const
Constructs and returns a config object representing this object.
Definition: action.cpp:51
error
Possible errors.
Definition: action.hpp:107
@ INVALID_LOCATION
Definition: action.hpp:109
@ UNIT_CHANGED
Definition: action.hpp:111
@ LOCATION_OCCUPIED
Definition: action.hpp:112
int side_number() const
Returns the number of the side that owns this action, i.e.
Definition: action.hpp:86
A planned move, represented on the map by an arrow and a ghosted unit in the destination hex.
Definition: move.hpp:36
move(std::size_t team_index, bool hidden, unit &mover, const pathfind::marked_route &route, arrow_ptr arrow, fake_unit_ptr fake_unit)
Definition: move.cpp:68
void hide_fake_unit()
Definition: move.cpp:419
void redraw()
Redrawing function, called each time the action situation might have changed.
Definition: move.cpp:565
virtual void accept(visitor &v)
Definition: move.cpp:199
void show_fake_unit()
Definition: move.cpp:426
virtual void remove_temp_modifier(unit_map &unit_map)
Removes the result of this action from the specified unit map.
Definition: move.cpp:371
virtual unit_ptr get_unit() const
Return the unit targeted by this action.
Definition: move.cpp:287
virtual error check_validity() const
Check the validity of the action.
Definition: move.cpp:438
std::string unit_id_
Definition: move.hpp:111
std::unique_ptr< pathfind::marked_route > route_
Definition: move.hpp:112
virtual void draw_hex(const map_location &hex)
Gets called by display when drawing a hex, to allow actions to draw to the screen.
Definition: move.cpp:394
virtual ~move()
Definition: move.cpp:197
void set_arrow_texture(ARROW_TEXTURE x) const
Definition: move.hpp:100
arrow_ptr arrow_
Definition: move.hpp:117
void modify_unit(unit &new_unit)
Definition: move.cpp:314
bool fake_unit_hidden_
Definition: move.hpp:133
virtual void do_hide()
Called by the non-virtual hide() and show(), respectively.
Definition: move.cpp:405
virtual std::ostream & print(std::ostream &s) const
Definition: move.cpp:56
virtual map_location get_dest_hex() const
Definition: move.cpp:302
virtual void do_show()
Definition: move.cpp:412
std::size_t unit_underlying_id_
Definition: move.hpp:110
virtual void set_route(const pathfind::marked_route &route)
Definition: move.cpp:308
void set_arrow_brightness(ARROW_BRIGHTNESS x) const
Definition: move.hpp:98
std::unique_ptr< temporary_unit_mover > mover_
Definition: move.hpp:132
virtual const pathfind::marked_route & get_route() const
Definition: move.hpp:70
ARROW_TEXTURE arrow_texture_
Definition: move.hpp:121
virtual bool calculate_new_route(const map_location &source_hex, const map_location &dest_hex)
attempts to pathfind a new marked route for this path between these two hexes; returns true and assig...
Definition: move.cpp:320
virtual config to_config() const
Constructs and returns a config object representing this object.
Definition: move.cpp:504
int turn_number_
Turn end number to draw if greater than zero.
Definition: move.hpp:115
int calculate_moves_left(unit &u)
Definition: move.cpp:540
std::shared_ptr< move > shared_from_this()
Definition: move.hpp:104
virtual map_location get_source_hex() const
Definition: move.cpp:296
void init(unit *u=nullptr)
Definition: move.cpp:148
virtual void execute(bool &success, bool &complete)
Output parameters: success: Whether or not to continue an execute-all after this execution complete: ...
Definition: move.cpp:204
void update_arrow_style()
Definition: move.cpp:574
ARROW_BRIGHTNESS arrow_brightness_
Definition: move.hpp:120
@ ARROW_BRIGHTNESS_FOCUS
Definition: move.hpp:97
@ ARROW_BRIGHTNESS_STANDARD
Definition: move.hpp:97
@ ARROW_BRIGHTNESS_HIGHLIGHTED
Definition: move.hpp:97
fake_unit_ptr fake_unit_
Definition: move.hpp:118
ARROW_TEXTURE
Definition: move.hpp:99
@ ARROW_TEXTURE_INVALID
Definition: move.hpp:99
@ ARROW_TEXTURE_VALID
Definition: move.hpp:99
virtual map_location get_numbering_hex() const
Definition: move.cpp:433
virtual void apply_temp_modifier(unit_map &unit_map)
Applies temporarily the result of this action to the specified unit map.
Definition: move.cpp:333
This internal whiteboard class holds the planned action queues for a team, and offers many utility me...
iterator find_last_action_of(const unit &unit, iterator start_position)
Finds the last action that belongs to this unit, starting the search backwards from the specified pos...
container::iterator iterator
iterator end()
Returns the iterator for the position after the last executed action within the actions queue.
Abstract base class for all the visitors (cf GoF Visitor Design Pattern) the whiteboard uses.
Definition: visitor.hpp:33
virtual void visit(move_ptr move)=0
int movement_cost_
int w
Contains the exception interfaces used to signal completion of a scenario, campaign or turn.
const std::string & id() const
Gets this unit's id.
Definition: unit.hpp:380
std::size_t underlying_id() const
This unit's unique internal ID.
Definition: unit.hpp:392
const t_string & name() const
Gets this unit's translatable display name.
Definition: unit.hpp:403
int movement_left() const
Gets how far a unit can move, considering the incapacitated flag.
Definition: unit.hpp:1303
const color_t NORMAL_COLOR
std::pair< std::string, unsigned > item
Definition: help_impl.hpp:412
logger & debug()
Definition: log.cpp:320
plain_route a_star_search(const map_location &src, const map_location &dst, double stop_at, const cost_calculator &calc, const std::size_t width, const std::size_t height, const teleport_map *teleports, bool border)
marked_route mark_route(const plain_route &rt, bool update_move_cost)
Add marks on a route rt assuming that the unit located at the first hex of rt travels along it.
Definition: pathfind.cpp:658
game_board * gameboard
Definition: resources.cpp:20
fake_unit_manager * fake_units
Definition: resources.cpp:30
play_controller * controller
Definition: resources.cpp:21
static std::string at(const std::string &file, int line)
void move_unit(const std::vector< map_location > &path, unit_ptr u, bool animate, map_location::DIRECTION dir, bool force_scroll)
Display a unit moving along a given path.
Definition: udisplay.cpp:506
Definition: display.hpp:45
std::ostream & operator<<(std::ostream &s, action_ptr action)
Definition: action.cpp:34
std::shared_ptr< move > move_ptr
Definition: typedefs.hpp:68
std::size_t viewer_team()
Definition: utility.cpp:38
std::shared_ptr< side_actions > side_actions_ptr
Definition: typedefs.hpp:66
std::shared_ptr< arrow > arrow_ptr
Definition: typedefs.hpp:60
std::shared_ptr< move const > move_const_ptr
Definition: typedefs.hpp:69
std::shared_ptr< unit > unit_ptr
Definition: ptr.hpp:26
Encapsulates the map of the game.
Definition: location.hpp:38
int wml_y() const
Definition: location.hpp:154
int wml_x() const
Definition: location.hpp:153
static double getNoPathValue()
Definition: pathfind.hpp:65
Structure which holds a single route and marks for special events.
Definition: pathfind.hpp:142
std::vector< map_location > & steps
Definition: pathfind.hpp:187
Structure which holds a single route between one location and another.
Definition: pathfind.hpp:133
int move_cost
Movement cost for reaching the end of the route.
Definition: pathfind.hpp:137
This object is used to temporary move a unit in the unit map, swapping out any unit that is already t...
Definition: game_board.hpp:224
bool valid() const
Definition: map.hpp:273
pointer get_shared_ptr() const
This is exactly the same as operator-> but it's slightly more readable, and can replace &*iter syntax...
Definition: map.hpp:217
static map_location::DIRECTION s
static std::string mark
Definition: tstring.cpp:70
#define WRN_WB
Definition: typedefs.hpp:26
static lg::log_domain log_whiteboard("whiteboard")
#define DBG_WB
Definition: typedefs.hpp:28
#define LOG_WB
Definition: typedefs.hpp:27
Display units performing various actions: moving, attacking, and dying.
visitor is an abstract interface : action.accept(visitor) calls visitor.visit(action)
#define h