1 /*
2    Copyright (C) 2003 - 2018 by David White <dave@whitevine.net>
3    Part of the Battle for Wesnoth Project https://www.wesnoth.org/
4 
5    This program is free software; you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation; either version 2 of the License, or
8    (at your option) any later version.
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY.
11 
12    See the COPYING file for more details.
13 */
14 
15 /**
16  * @file
17  * Various functions related to the creation of units (recruits, recalls,
18  * and placed units).
19  */
20 
21 #pragma once
22 
23 class team;
24 class unit_type;
25 
26 #include "unit_creator.hpp"
27 
28 #include "map/location.hpp"
29 #include "units/ptr.hpp"
30 
31 #include <tuple>
32 
33 namespace actions {
34 
35 /// The possible results of finding a location for recruiting (or recalling).
36 enum RECRUIT_CHECK {
37 	RECRUIT_NO_LEADER,         	/// No leaders exist
38 	RECRUIT_NO_ABLE_LEADER,    	/// No leaders able to recall/recruit the given unit/type.
39 	RECRUIT_NO_KEEP_LEADER,    	/// No able leaders are on a keep.
40 	RECRUIT_NO_VACANCY,        	/// No vacant castle tiles around a leader on a keep.
41 	RECRUIT_ALTERNATE_LOCATION,	/// Recruitment OK, but not at the specified location.
42 	RECRUIT_OK                 	/// Recruitment OK.
43 };
44 
45 /**
46  * Checks if there is a location on which to place a recruited unit.
47  * A leader of the @a side must be on a keep connected by castle to a
48  * legal recruiting location to get an "OK" or "ALTERNATE_LOCATION" result.
49  *
50  * If "OK" is returned, then the location provided in @a recruit_location
51  * is legal. If "ALTERNATE_LOCATION" is returned, the provided location was
52  * illegal, so its value was replaced by a location where recruitment can
53  * occur.
54  *
55  * The location of the recruiting leader is stored in @a recruited_from.
56  * The incoming value of this parameter is used as a hint for finding a
57  * legal recruiter, but this hint is given lower priority than finding a
58  * leader who can recruit at recruit_location.
59  *
60  * The @a unit_type is needed in case this is a leader-specific recruit.
61  */
62 RECRUIT_CHECK check_recruit_location(const int side, map_location &recruit_location,
63                                      map_location& recruited_from,
64                                      const std::string& unit_type);
65 
66 /**
67  * Finds a location on which to place a unit.
68  * A leader of the @a side must be on a keep
69  * connected by castle to a legal recruiting location. Otherwise, an error
70  * message explaining this is returned.
71  *
72  * If no errors are encountered, the location where a unit can be recruited
73  * is stored in @a recruit_location. Its value is considered first, if it is a
74  * legal option.
75  * Also, the location of the recruiting leader is stored in @a recruited_from.
76  * The incoming value of recruited_from is used as a hint for finding a
77  * legal recruiter, but this hint is given lower priority than finding a
78  * leader who can recruit at recruit_location.
79  *
80  * The @a unit_type is needed in case this is a leader-specific recruit.
81  *
82  * @return an empty string on success. Otherwise a human-readable message
83  *         describing the failure is returned.
84  */
85 std::string find_recruit_location(const int side, map_location &recruit_location, map_location& recruited_from, const std::string& unit_type);
86 
87 /**
88  * Checks if there is a location on which to recall @a unit_recall.
89  * A leader of the @a side must be on a keep connected by castle to a legal
90  * recalling location to get an "OK" or "ALTERNATE_LOCATION" result.
91  *
92  * If "OK" is returned, then the location provided in @a recall_location
93  * is legal. If "ALTERNATE_LOCATION" is returned, the provided location was
94  * illegal, so its value was replaced by a location where recalling can
95  * occur.
96  *
97  * The location of the recalling leader is stored in @a recall_from.
98  * The incoming value of this parameter is used as a hint for finding a
99  * legal recaller, but this hint is given lower priority than finding a
100  * leader who can recall at recall_location.
101  */
102 RECRUIT_CHECK check_recall_location(const int side, map_location& recall_location,
103                                     map_location& recall_from,
104                                     const unit &unit_recall);
105 
106 /**
107  * Finds a location on which to recall @a unit_recall.
108  * A leader of the @a side must be on a keep
109  * connected by castle to a legal recalling location. Otherwise, an error
110  * message explaining this is returned.
111  *
112  * If no errors are encountered, the location where a unit can be recalled
113  * is stored in @a recall_location. Its value is considered first, if it is a
114  * legal option.
115  * Also, the location of the recalling leader is stored in @a recall_from.
116  * The incoming value of this parameter is used as a hint for finding a
117  * legal recaller, but this hint is given lower priority than finding a
118  * leader who can recall at recall_location.
119  *
120  * @return an empty string on success. Otherwise a human-readable message
121  *         describing the failure is returned.
122  */
123 std::string find_recall_location(const int side, map_location& recall_location, map_location& recall_from, const unit &unit_recall);
124 
125 /**
126  * Gets the recruitable units from a side's leaders' personal recruit lists who can recruit on or from a specific hex field.
127  * @param side of the leaders to search for their personal recruit lists.
128  * @param recruit_location the hex field being part of the castle the player wants to recruit on or from.
129  * @return a set of units that can be recruited either by the leader on @a recruit_location or by leaders on keeps connected by castle tiles to @a recruit_location.
130  */
131 const std::set<std::string> get_recruits(int side, const map_location &recruit_location);
132 
133 /**
134  * Gets the recallable units for a side, restricted by that side's leaders' personal abilities to recall on or from a specific hex field.
135  * If no leader is able to recall on or from the given location, the full recall list of the side is returned.
136  * @param side of the leaders to search for their personal recall filters.
137  * @param recall_loc the hex field being part of the castle the player wants to recruit on or from.
138  * @return a set of units that can be recalled by @a side on (or from) @a recall_loc or the full recall list of @a side.
139  */
140 std::vector<unit_const_ptr > get_recalls(int side, const map_location &recall_loc);
141 
142 typedef std::tuple<bool /*event modified*/, int /*previous village owner side*/, bool /*capture bonus time*/> place_recruit_result;
143 
144 /**
145  * Place a unit into the game.
146  * The unit will be placed on @a recruit_location, which should be retrieved
147  * through a call to recruit_location().
148  * @param facing the desired facing for the unit, map_location::NDIRECTIONS to determine facing automatically.
149  * @returns true if an event (or fog clearing) has mutated the game state.
150  */
151 place_recruit_result place_recruit(unit_ptr u, const map_location &recruit_location, const map_location& recruited_from,
152 	int cost, bool is_recall, map_location::DIRECTION facing = map_location::NDIRECTIONS, bool show = false, bool fire_event = true, bool full_movement = false, bool wml_triggered = false);
153 
154 /**
155  * Recruits a unit of the given type for the given side.
156  * This is the point at which the code merges for recruits originating from players,
157  * the AI, and replays. It starts just after the recruit location is successfully
158  * found, and it handles creating the unit, paying gold, firing events, tracking
159  * statistics, and (unless @a is_ai) updating the undo stack.
160  */
161 void recruit_unit(const unit_type & u_type, int side_num, const map_location & loc,
162                   const map_location & from, bool show=true, bool use_undo=true);
163 
164 /**
165  * Recalls the unit with the indicated ID for the provided team.
166  * The ID can be a reference to data in the recall list.
167  * This is the point at which the code merges for recalls originating from players,
168  * the AI, and replays. It starts just after the recall location is successfully
169  * found, and it handles moving the unit to the board, paying gold, firing events,
170  * tracking statistics, updating the undo stack (unless @a use_undo is false), and
171  * recording the recall (unless @a use_recorder is false).
172  * @param facing the desired facing for the unit, map_location::NDIRECTIONS to determine facing automatically.
173  * @returns false if the recall could not be found in the team's recall list.
174  */
175 bool recall_unit(const std::string & id, team & current_team,
176                  const map_location & loc, const map_location & from,
177                  map_location::DIRECTION facing = map_location::NDIRECTIONS,
178                  bool show=true, bool use_undo=true);
179 }//namespace actions
180