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