The Battle for Wesnoth  1.17.17+dev
move.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2010 - 2023
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"
23 #include "whiteboard/manager.hpp"
25 #include "whiteboard/utility.hpp"
26 
27 #include "arrow.hpp"
28 #include "config.hpp"
29 #include "fake_unit_manager.hpp"
30 #include "fake_unit_ptr.hpp"
31 #include "font/standard_colors.hpp"
32 #include "game_board.hpp"
33 #include "game_end_exceptions.hpp"
34 #include "map/map.hpp"
35 #include "mouse_events.hpp"
36 #include "play_controller.hpp"
37 #include "replay.hpp"
38 #include "resources.hpp"
39 #include "team.hpp"
40 #include "units/unit.hpp"
42 #include "units/udisplay.hpp"
43 #include "units/map.hpp"
44 
45 namespace wb {
46 
47 std::ostream& operator<<(std::ostream &s, move_ptr move)
48 {
49  assert(move);
50  return move->print(s);
51 }
52 
53 std::ostream& operator<<(std::ostream &s, move_const_ptr move)
54 {
55  assert(move);
56  return move->print(s);
57 }
58 
59 std::ostream& move::print(std::ostream &s) const
60 {
61  if(!get_unit()) {
62  s << "Move for unknown unit [" << unit_underlying_id_ << "] " << "from (" << get_source_hex() << ") to (" << get_dest_hex() << ")";
63  }
64  else {
65  s << "Move for unit " << get_unit()->name() << " [" << get_unit()->id() << "] "
66  << "from (" << get_source_hex() << ") to (" << get_dest_hex() << ")";
67  }
68  return s;
69 }
70 
71 move::move(std::size_t team_index, bool hidden, unit& u, const pathfind::marked_route& route,
72  arrow_ptr arrow, fake_unit_ptr fake_unit)
73 : action(team_index,hidden),
74  unit_underlying_id_(u.underlying_id()),
75  unit_id_(),
76  route_(new pathfind::marked_route(route)),
77  movement_cost_(0),
78  turn_number_(0),
79  arrow_(arrow),
80  fake_unit_(std::move(fake_unit)),
81  arrow_brightness_(),
82  arrow_texture_(),
83  mover_(),
84  fake_unit_hidden_(false)
85 {
86  assert(!route_->steps.empty());
87 
88  if(hidden)
89  fake_unit_->set_hidden(true);
90 
91  this->init();
92 }
93 
94 move::move(const config& cfg, bool hidden)
95  : action(cfg,hidden)
96  , unit_underlying_id_(0)
97  , unit_id_()
98  , route_(new pathfind::marked_route())
99  , movement_cost_(0)
100  , turn_number_(0)
101  , arrow_(new arrow(hidden))
102  , fake_unit_()
103  , arrow_brightness_()
104  , arrow_texture_()
105  , mover_()
106  , fake_unit_hidden_(false)
107 {
108  // Construct and validate unit_
109  unit_map::iterator unit_itor = resources::gameboard->units().find(cfg["unit_"]);
110  if(unit_itor == resources::gameboard->units().end())
111  throw action::ctor_err("move: Invalid underlying_id");
112  unit_underlying_id_ = unit_itor->underlying_id();
113 
114  // Construct and validate route_
115  auto route_cfg = cfg.optional_child("route_");
116  if(!route_cfg)
117  throw action::ctor_err("move: Invalid route_");
118  route_->move_cost = route_cfg["move_cost"];
119  for(const config& loc_cfg : route_cfg->child_range("step")) {
120  route_->steps.emplace_back(loc_cfg["x"],loc_cfg["y"], wml_loc());
121  }
122  for(const config& mark_cfg : route_cfg->child_range("mark")) {
123  route_->marks[map_location(mark_cfg["x"],mark_cfg["y"], wml_loc())]
124  = pathfind::marked_route::mark(mark_cfg["turns"],
125  mark_cfg["zoc"].to_bool(),
126  mark_cfg["capture"].to_bool(),
127  mark_cfg["invisible"].to_bool());
128  }
129 
130  // Validate route_ some more
131  const std::vector<map_location>& steps = route_->steps;
132  if(steps.empty())
133  throw action::ctor_err("move: Invalid route_");
134 
135  // Construct arrow_
137  arrow_->set_style(arrow::STYLE_STANDARD);
138  arrow_->set_path(route_->steps);
139 
140  // Construct fake_unit_
142  if(hidden)
143  fake_unit_->set_hidden(true);
144  fake_unit_->anim_comp().set_ghosted(true);
145  unit_display::move_unit(route_->steps, fake_unit_.get_unit_ptr(), false); //get facing right
146  fake_unit_->set_location(route_->steps.back());
147 
148  this->init();
149 }
150 
151 void move::init(unit* u)
152 {
153  if(get_unit()) {
154  unit_id_ = get_unit()->id();
155  }
156  else if(u) {
157  unit_id_ = u->id();
158  }
159  //This action defines the future position of the unit, make its fake unit more visible
160  //than previous actions' fake units
161  if (fake_unit_)
162  {
163  fake_unit_->anim_comp().set_ghosted(true);
164  }
165  side_actions_ptr side_actions = resources::gameboard->teams().at(team_index()).get_side_actions();
167  if (action != side_actions->end())
168  {
169  if (move_ptr move = std::dynamic_pointer_cast<class move>(*action))
170  {
171  if (move->fake_unit_)
172  move->fake_unit_->anim_comp().set_disabled_ghosted(true);
173  }
174  }
175 
176  // Initialize arrow_brightness_ and arrow_texture_ using arrow_->style_
177  std::string arrow_style = arrow_->get_style();
178  if(arrow_style == arrow::STYLE_STANDARD)
179  {
182  }
183  else if(arrow_style == arrow::STYLE_HIGHLIGHTED)
184  {
187  }
188  else if(arrow_style == arrow::STYLE_FOCUS)
189  {
192  }
193  else if(arrow_style == arrow::STYLE_FOCUS_INVALID)
194  {
197  }
198 }
199 
201 
203 {
204  v.visit(shared_from_this());
205 }
206 
207 void move::execute(bool& success, bool& complete)
208 {
209  if(!valid()) {
210  success = false;
211  //Setting complete to true signifies to side_actions to delete the planned action.
212  complete = true;
213  return;
214  }
215 
216  if(get_source_hex() == get_dest_hex()) {
217  //zero-hex move, used by attack subclass
218  success = complete = true;
219  return;
220  }
221 
222  LOG_WB << "Executing: " << shared_from_this();
223 
224  // Copy the current route to ensure it remains valid throughout the animation.
225  const std::vector<map_location> steps = route_->steps;
226 
228  hide_fake_unit();
229 
230  std::size_t num_steps;
231  bool interrupted;
232  try {
234  num_steps = mouse_handler.move_unit_along_route(steps, interrupted);
235  } catch (const return_to_play_side_exception&) {
237  throw; // we rely on the caller to delete this action
238  }
239  const map_location & final_location = steps[num_steps];
240  unit_map::const_iterator unit_it = resources::gameboard->units().find(final_location);
241 
242  if ( num_steps == 0 )
243  {
244  LOG_WB << "Move execution resulted in zero movement.";
245  success = false;
246  complete = true;
247  }
248  else if ( unit_it == resources::gameboard->units().end() || (unit_id_.empty() && ( unit_it->id() != unit_id_ )))
249  {
250  WRN_WB << "Unit disappeared from map during move execution.";
251  success = false;
252  complete = true;
253  }
254  else
255  {
256  complete = num_steps + 1 == steps.size();
257  success = complete && !interrupted;
258 
259  if ( !success )
260  {
261  if ( complete )
262  {
263  LOG_WB << "Move completed, but interrupted on final hex. Halting.";
264  //reset to a single-hex path, just in case *this is a wb::attack
265  route_->steps = std::vector<map_location>(1, final_location);
266  arrow_.reset();
267  }
268  else
269  {
270  LOG_WB << "Move finished at (" << final_location << ") instead of at (" << get_dest_hex() << "). Setting new path.";
271  route_->steps = std::vector<map_location>(steps.begin() + num_steps, steps.end());
272  //FIXME: probably better to use the new calculate_new_route() instead of the above:
273  //calculate_new_route(final_location, steps.back());
274  // Of course, "better" would need to be verified.
275 
276  //Update route_->move_cost
277  route_.reset(new pathfind::marked_route(mark_route(route_->route, true)));
278  arrow_->set_path(route_->steps);
279  }
280  }
281  }
282 
283  if(!complete)
284  {
286  show_fake_unit();
287  }
288 }
289 
291 {
293  if (itor.valid())
294  return itor.get_shared_ptr();
295  else
296  return unit_ptr();
297 }
298 
300 {
301  assert(route_ && !route_->steps.empty());
302  return route_->steps.front();
303 }
304 
306 {
307  assert(route_ && !route_->steps.empty());
308  return route_->steps.back();
309 }
310 
312 {
313  route_.reset(new pathfind::marked_route(route));
314  arrow_->set_path(route_->steps);
315 }
316 
317 void move::modify_unit(unit& new_unit)
318 {
319  unit_underlying_id_ = new_unit.underlying_id();
320  unit_id_ = new_unit.id();
321 }
322 
323 bool move::calculate_new_route(const map_location& source_hex, const map_location& dest_hex)
324 {
325  pathfind::plain_route new_plain_route;
327  resources::gameboard->teams().at(team_index()),
328  resources::gameboard->teams(), resources::gameboard->map());
329  new_plain_route = pathfind::a_star_search(source_hex,
330  dest_hex, 10000, path_calc, resources::gameboard->map().w(), resources::gameboard->map().h());
331  if (new_plain_route.move_cost >= path_calc.getNoPathValue()) return false;
332  route_.reset(new pathfind::marked_route(pathfind::mark_route(new_plain_route)));
333  return true;
334 }
335 
337 {
338  if (get_source_hex() == get_dest_hex())
339  return; //zero-hex move, used by attack subclass
340 
341  // Safety: Make sure the old temporary_unit_mover (if any) is destroyed
342  // before creating a new one.
343  mover_.reset();
344 
345  //@todo: deal with multi-turn moves, which may for instance end their first turn
346  // by capturing a village
347 
348  //@todo: we may need to change unit status here and change it back in remove_temp_modifier
349  unit* unit;
350  {
352  assert(unit_it != unit_map.end());
353  unit = &*unit_it;
354  }
355 
356  if (route_->move_cost == -1) {
357  // TODO: check_validity also calls pathfind::mark_route(get_route().route), optimize/refactor this to only call that once.
358  route_->move_cost = pathfind::mark_route(get_route().route, true).move_cost;
359  }
360  //Modify movement points
361  DBG_WB <<"Move: Changing movement points for unit " << unit->name() << " [" << unit->id()
362  << "] from " << unit->movement_left() << " to "
363  << calculate_moves_left(*unit) << ".";
364  // Move the unit
365  DBG_WB << "Move: Temporarily moving unit " << unit->name() << " [" << unit->id()
366  << "] from (" << get_source_hex() << ") to (" << get_dest_hex() <<")";
368 
369  //Update status of fake unit (not undone by remove_temp_modifiers)
370  //@todo this contradicts the name "temp_modifiers"
371  fake_unit_->set_movement(unit->movement_left(), true);
372 }
373 
375 {
376  if (get_source_hex() == get_dest_hex())
377  return; //zero-hex move, probably used by attack subclass
378 
379  // Debug movement points
380  if ( !lg::debug().dont_log(log_whiteboard) )
381  {
382  unit* unit;
383  {
385  assert(unit_it != resources::gameboard->units().end());
386  unit = &*unit_it;
387  }
388  DBG_WB << "Move: Movement points for unit " << unit->name() << " [" << unit->id()
389  << "] should get changed from " << unit->movement_left() << " to "
390  << calculate_moves_left(*unit) << ".";
391  }
392 
393  // Restore the unit to its original position and movement.
394  mover_.reset();
395 }
396 
397 void move::draw_hex(const map_location& hex)
398 {
399  //display turn info for turns 2 and above
400  if (hex == get_dest_hex() && turn_number_ >= 2)
401  {
402  std::stringstream turn_text;
403  turn_text << turn_number_;
405  }
406 }
407 
409 {
410  arrow_->hide();
411  if(!fake_unit_hidden_)
412  fake_unit_->set_hidden(true);
413 }
414 
416 {
417  arrow_->show();
418  if(!fake_unit_hidden_)
419  fake_unit_->set_hidden(false);
420 }
421 
423 {
424  fake_unit_hidden_ = true;
425  if(!hidden())
426  fake_unit_->set_hidden(true);
427 }
428 
430 {
431  fake_unit_hidden_ = false;
432  if(!hidden())
433  fake_unit_->set_hidden(false);
434 }
435 
437 {
438  return get_dest_hex();
439 }
440 
442 {
443  // Used to deal with multiple return paths.
444  class arrow_texture_setter {
445  public:
446  arrow_texture_setter(const move *target, move::ARROW_TEXTURE current_texture, move::ARROW_TEXTURE setting_texture):
447  target(target),
448  current_texture(current_texture),
449  setting_texture(setting_texture) {}
450 
451  ~arrow_texture_setter() {
452  if(current_texture!=setting_texture) {
453  target->set_arrow_texture(setting_texture);
454  }
455  }
456 
457  void set_texture(move::ARROW_TEXTURE texture) { setting_texture=texture; }
458 
459  private:
460  const move *target;
461  move::ARROW_TEXTURE current_texture, setting_texture;
462  };
463 
464  arrow_texture_setter setter(this, arrow_texture_, ARROW_TEXTURE_INVALID);
465 
466  if(!(get_source_hex().valid() && get_dest_hex().valid())) {
467  return INVALID_LOCATION;
468  }
469 
470  //Check that the unit still exists in the source hex
471  unit_map::iterator unit_it;
473  if(unit_it == resources::gameboard->units().end()) {
474  return NO_UNIT;
475  }
476 
477  //check if the unit in the source hex has the same unit id as before,
478  //i.e. that it's the same unit
479  if((!unit_id_.empty() && unit_id_ != unit_it->id()) || unit_underlying_id_ != unit_it->underlying_id()) {
480  return UNIT_CHANGED;
481  }
482 
483  //If the path has at least two hexes (it can have less with the attack subclass), ensure destination hex is free
484  if(get_route().steps.size() >= 2 && resources::gameboard->get_visible_unit(get_dest_hex(),resources::gameboard->teams().at(viewer_team())) != nullptr) {
485  return LOCATION_OCCUPIED;
486  }
487 
488  //check that the path is good
489  if(get_source_hex() != get_dest_hex()) { //skip zero-hex move used by attack subclass
490 
491  // Mark the plain route to see if the move can still be done in one turn,
492  // which is always the case for planned moves
493  // TODO: this check is rather slow, skip it if the gamestat has not changed.
494  pathfind::marked_route checked_route = pathfind::mark_route(get_route().route);
495 
496  if(checked_route.marks[checked_route.steps.back()].turns != 1) {
497  return TOO_FAR;
498  }
499  }
500 
501  // The move is valid, so correct the setter.
502  setter.set_texture(ARROW_TEXTURE_VALID);
503 
504  return OK;
505 }
506 
508 {
509  config final_cfg = action::to_config();
510 
511  final_cfg["type"]="move";
512  final_cfg["unit_"]=static_cast<int>(unit_underlying_id_);
513 // final_cfg["movement_cost_"]=movement_cost_; //Unnecessary
514 // final_cfg["unit_id_"]=unit_id_; //Unnecessary
515 
516  //Serialize route_
517  config route_cfg;
518  route_cfg["move_cost"]=route_->move_cost;
519  for(const map_location& loc : route_->steps)
520  {
521  config loc_cfg;
522  loc_cfg["x"]=loc.wml_x();
523  loc_cfg["y"]=loc.wml_y();
524  route_cfg.add_child("step", std::move(loc_cfg));
525  }
526  typedef std::pair<map_location,pathfind::marked_route::mark> pair_loc_mark;
527  for(const pair_loc_mark item : route_->marks)
528  {
529  config mark_cfg;
530  mark_cfg["x"]=item.first.wml_x();
531  mark_cfg["y"]=item.first.wml_y();
532  mark_cfg["turns"]=item.second.turns;
533  mark_cfg["zoc"]=item.second.zoc;
534  mark_cfg["capture"]=item.second.capture;
535  mark_cfg["invisible"]=item.second.invisible;
536  route_cfg.add_child("mark", std::move(mark_cfg));
537  }
538  final_cfg.add_child("route_", std::move(route_cfg));
539 
540  return final_cfg;
541 }
542 
544 {
545  assert(route_);
547  {
548 
549  // @todo: find a better treatment of movement points when defining moves out-of-turn
550  if(u.movement_left() - route_->move_cost < 0
552  WRN_WB << shared_from_this() << " defined with insufficient movement left.";
553  }
554 
555  // If unit finishes move in a village it captures, set the move cost to unit's movement_left()
556  if (route_->marks[get_dest_hex()].capture)
557  {
558  return 0;
559  }
560  else
561  {
562  return u.movement_left() - route_->move_cost;
563  }
564  }
565  return 0;
566 }
567 
569 {
573 }
574 
575 //If you add more arrow styles, this will need to change
576 /* private */
578 {
580  {
582  return;
583  }
584 
585  switch(arrow_brightness_)
586  {
588  arrow_->set_style(arrow::STYLE_STANDARD);
589  break;
591  arrow_->set_style(arrow::STYLE_HIGHLIGHTED);
592  break;
594  arrow_->set_style(arrow::STYLE_FOCUS);
595  break;
596  }
597 }
598 
599 } // end namespace wb
const std::vector< map_location > & route_
Definition: move.cpp:295
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:161
child_itors child_range(config_key_type key)
Definition: config.cpp:277
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:389
config & add_child(config_key_type key)
Definition: config.cpp:445
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:1445
int viewing_side() const
The 1-based equivalent of the 0-based viewing_team() function.
Definition: display.hpp:130
bool invalidate(const map_location &loc)
Function to invalidate a specific tile for redrawing.
Definition: display.cpp:3122
@ LAYER_MOVE_INFO
Movement info (defense%, etc...).
Definition: display.hpp:841
static display * get_singleton()
Returns the display object if a display object exists.
Definition: display.hpp:101
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:86
unit * get_visible_unit(const map_location &loc, const team &current_team, bool see_all=false)
Definition: game_board.cpp:212
virtual const unit_map & units() const override
Definition: game_board.hpp:113
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:969
Wrapper class to encapsulate creation and management of an SDL_Texture.
Definition: texture.hpp:33
Container associating units to locations.
Definition: map.hpp:99
unit_iterator end()
Definition: map.hpp:429
unit_iterator find(std::size_t id)
Definition: map.cpp:301
This class represents a single unit of a specific type.
Definition: unit.hpp:134
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:71
void hide_fake_unit()
Definition: move.cpp:422
void redraw()
Redrawing function, called each time the action situation might have changed.
Definition: move.cpp:568
virtual void accept(visitor &v)
Definition: move.cpp:202
void show_fake_unit()
Definition: move.cpp:429
virtual void remove_temp_modifier(unit_map &unit_map)
Removes the result of this action from the specified unit map.
Definition: move.cpp:374
virtual unit_ptr get_unit() const
Return the unit targeted by this action.
Definition: move.cpp:290
virtual error check_validity() const
Check the validity of the action.
Definition: move.cpp:441
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:397
virtual ~move()
Definition: move.cpp:200
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:317
bool fake_unit_hidden_
Definition: move.hpp:133
virtual void do_hide()
Called by the non-virtual hide() and show(), respectively.
Definition: move.cpp:408
virtual std::ostream & print(std::ostream &s) const
Definition: move.cpp:59
virtual map_location get_dest_hex() const
Definition: move.cpp:305
virtual void do_show()
Definition: move.cpp:415
std::size_t unit_underlying_id_
Definition: move.hpp:110
virtual void set_route(const pathfind::marked_route &route)
Definition: move.cpp:311
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:323
virtual config to_config() const
Constructs and returns a config object representing this object.
Definition: move.cpp:507
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:543
std::shared_ptr< move > shared_from_this()
Definition: move.hpp:104
virtual map_location get_source_hex() const
Definition: move.cpp:299
void init(unit *u=nullptr)
Definition: move.cpp:151
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:207
void update_arrow_style()
Definition: move.cpp:577
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:436
virtual void apply_temp_modifier(unit_map &unit_map)
Applies temporarily the result of this action to the specified unit map.
Definition: move.cpp:336
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:381
std::size_t underlying_id() const
This unit's unique internal ID.
Definition: unit.hpp:393
const t_string & name() const
Gets this unit's translatable display name.
Definition: unit.hpp:404
int movement_left() const
Gets how far a unit can move, considering the incapacitated flag.
Definition: unit.hpp:1283
const color_t NORMAL_COLOR
std::pair< std::string, unsigned > item
Definition: help_impl.hpp:414
logger & debug()
Definition: log.cpp:238
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:21
fake_unit_manager * fake_units
Definition: resources.cpp:31
play_controller * controller
Definition: resources.cpp:22
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:509
Definition: display.hpp:49
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:41
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
Replay control code.
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:231
bool valid() const
Definition: map.hpp:274
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:218
static map_location::DIRECTION s
static std::string mark
Definition: tstring.cpp:71
#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