The Battle for Wesnoth  1.13.4+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
undo_recall_action.cpp
Go to the documentation of this file.
1 #include "undo_recall_action.hpp"
2 #include "create.hpp"
3 
5 #include "resources.hpp"
6 #include "team.hpp"
7 #include "replay.hpp"
8 #include "units/map.hpp"
9 #include "statistics.hpp"
10 #include "log.hpp"
11 #include "game_display.hpp"
12 
13 static lg::log_domain log_engine("engine");
14 #define ERR_NG LOG_STREAM(err, log_engine)
15 #define LOG_NG LOG_STREAM(info, log_engine)
16 
17 namespace actions
18 {
19 namespace undo
20 {
21 
22 /**
23  * Writes this into the provided config.
24  */
25 void recall_action::write(config & cfg) const
26 {
27  undo_action::write(cfg);
29 
30  recall_from.write(cfg.add_child("leader"));
31  cfg["id"] = id;
32 }
33 
34 /**
35  * Undoes this action.
36  * @return true on success; false on an error.
37  */
38 bool recall_action::undo(int side)
39 {
42  team &current_team = (*resources::teams)[side-1];
43 
44  const map_location & recall_loc = route.front();
45  unit_map::iterator un_it = units.find(recall_loc);
46  if ( un_it == units.end() ) {
47  return false;
48  }
49 
50  unit_ptr un = un_it.get_shared_ptr();
51  if (!un) {
52  return false;
53  }
54 
56  int cost = statistics::un_recall_unit_cost(*un);
57  if (cost < 0) {
58  current_team.spend_gold(-current_team.recall_cost());
59  }
60  else {
61  current_team.spend_gold(-cost);
62  }
63 
64  current_team.recall_list().add(un);
65  // invalidate before erasing allow us
66  // to also do the overlapped hexes
67  gui.invalidate(recall_loc);
68  units.erase(recall_loc);
69  this->return_village();
71  return true;
72 }
73 
74 /**
75  * Redoes this action.
76  * @return true on success; false on an error.
77  */
78 bool recall_action::redo(int side)
79 {
81  team &current_team = (*resources::teams)[side-1];
82 
83  map_location loc = route.front();
85 
86  unit_ptr un = current_team.recall_list().find_if_matches_id(id);
87  if ( !un ) {
88  ERR_NG << "Trying to redo a recall of '" << id
89  << "', but that unit is not in the recall list.";
90  return false;
91  }
92 
93  const std::string &msg = find_recall_location(side, loc, from, *un);
94  if ( msg.empty() ) {
98  recall_unit(id, current_team, loc, from, true, false);
99 
100  // Quick error check. (Abuse of [allow_undo]?)
101  if ( loc != route.front() ) {
102  ERR_NG << "When redoing a recall at " << route.front()
103  << ", the location was moved to " << loc << ".\n";
104  // Not really fatal, I suppose. Just update the action so
105  // undoing this works.
106  route.front() = loc;
107  }
108  sync.do_final_checkup();
109  } else {
111  return false;
112  }
113 
114  return true;
115 }
116 }
117 }
unit_iterator end()
Definition: map.hpp:311
bool invalidate(const map_location &loc)
Function to invalidate a specific tile for redrawing.
Definition: display.cpp:3536
void do_final_checkup(bool dont_throw=false)
void un_recall_unit(const unit &u)
Definition: statistics.cpp:494
#define ERR_NG
game_display * screen
Definition: resources.cpp:27
General purpose widgets.
virtual bool undo(int side)
Undoes this action.
void show_transient_message(CVideo &video, const std::string &title, const std::string &message, const std::string &image, const bool message_use_markup, const bool title_use_markup, const bool restore_background)
Shows a transient message to the user.
Replay control code.
void clear()
Definition: config.cpp:1055
-file sdl_utils.hpp
void return_village()
Change village owner on undo.
This class stores all the data for a single 'side' (in game nomenclature).
Definition: team.hpp:50
virtual bool redo(int side)
Redoes this action.
int recall_cost() const
Definition: team.hpp:198
unit_ptr find_if_matches_id(const std::string &unit_id)
Find a unit by id. Null pointer if not found.
void redo(const config &dst)
Definition: replay.cpp:410
pointer get_shared_ptr() const
Definition: map.hpp:180
int un_recall_unit_cost(const unit &u)
Definition: statistics.cpp:508
config & add_child(const std::string &key)
Definition: config.cpp:743
replay * recorder
Definition: resources.cpp:30
void spend_gold(const int amount)
Definition: team.hpp:213
void write(config &cfg) const
Definition: location.cpp:205
Encapsulates the map of the game.
Definition: location.hpp:38
virtual void write(config &cfg) const
Writes this into the provided config.
Various functions related to the creation of units (recruits, recalls, and placed units)...
t_route route
The hexes occupied by the affected unit during this action.
static lg::log_domain log_engine("engine")
std::string find_recall_location(const int side, map_location &recall_location, map_location &recall_from, const unit &unit_recall)
Finds a location on which to recall unit_recall.
Definition: create.cpp:328
static void msg(const char *act, debug_info &i, const char *to="", const char *result="")
Definition: debugger.cpp:112
virtual void write(config &cfg) const
Writes this into the provided config.
size_t erase(const map_location &l)
Erases the unit at location l, if any.
Definition: map.cpp:277
Standard logging facilities (interface).
CVideo & video()
Gets the underlying screen object.
Definition: display.hpp:202
bool recall_unit(const std::string &id, team &current_team, const map_location &loc, const map_location &from, bool show, bool use_undo)
Recalls the unit with the indicated ID for the provided team.
Definition: create.cpp:731
recall_list_manager & recall_list()
Definition: team.hpp:220
void add(const unit_ptr &ptr)
Add a unit to the list.
Container associating units to locations.
Definition: map.hpp:90
unit_iterator find(size_t id)
Definition: map.cpp:285
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:83
config replay_data
the replay data to do this action, this is only !empty() when this action is on the redo stack we nee...
Definition: undo_action.hpp:69
GLsizei const GLcharARB ** string
Definition: glew.h:4503
unit_map * units
Definition: resources.cpp:35