Goals.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364
  1. #pragma once
  2. #include "../../lib/VCMI_Lib.h"
  3. #include "../../lib/mapObjects/CObjectHandler.h"
  4. #include "../../lib/CBuildingHandler.h"
  5. #include "../../lib/CCreatureHandler.h"
  6. #include "../../lib/CTownHandler.h"
  7. #include "AIUtility.h"
  8. /*
  9. * Goals.h, part of VCMI engine
  10. *
  11. * Authors: listed in file AUTHORS in main folder
  12. *
  13. * License: GNU General Public License v2.0 or later
  14. * Full text of license available in license.txt file, in main folder
  15. *
  16. */
  17. struct HeroPtr;
  18. class VCAI;
  19. class FuzzyHelper;
  20. namespace Goals
  21. {
  22. struct AbstractGoal;
  23. class VisitTile;
  24. typedef std::shared_ptr<Goals::AbstractGoal> TSubgoal;
  25. typedef std::vector<TSubgoal> TGoalVec;
  26. enum EGoals
  27. {
  28. INVALID = -1,
  29. WIN, DO_NOT_LOSE, CONQUER, BUILD, //build needs to get a real reasoning
  30. EXPLORE, GATHER_ARMY, BOOST_HERO,
  31. RECRUIT_HERO,
  32. BUILD_STRUCTURE, //if hero set, then in visited town
  33. COLLECT_RES,
  34. GATHER_TROOPS, // val of creatures with objid
  35. OBJECT_GOALS_BEGIN,
  36. GET_OBJ, //visit or defeat or collect the object
  37. FIND_OBJ, //find and visit any obj with objid + resid //TODO: consider universal subid for various types (aid, bid)
  38. VISIT_HERO, //heroes can move around - set goal abstract and track hero every turn
  39. GET_ART_TYPE,
  40. //BUILD_STRUCTURE,
  41. ISSUE_COMMAND,
  42. VISIT_TILE, //tile, in conjunction with hero elementar; assumes tile is reachable
  43. CLEAR_WAY_TO,
  44. DIG_AT_TILE //elementar with hero on tile
  45. };
  46. //method chaining + clone pattern
  47. #define VSETTER(type, field) virtual AbstractGoal & set ## field(const type &rhs) {field = rhs; return *this;};
  48. #define OSETTER(type, field) CGoal<T> & set ## field(const type &rhs) override { field = rhs; return *this; };
  49. #if 0
  50. #define SETTER
  51. #endif // _DEBUG
  52. enum {LOW_PR = -1};
  53. TSubgoal sptr(const AbstractGoal & tmp);
  54. class AbstractGoal
  55. {
  56. public:
  57. bool isElementar; VSETTER(bool, isElementar)
  58. bool isAbstract; VSETTER(bool, isAbstract)
  59. float priority; VSETTER(float, priority)
  60. int value; VSETTER(int, value)
  61. int resID; VSETTER(int, resID)
  62. int objid; VSETTER(int, objid)
  63. int aid; VSETTER(int, aid)
  64. int3 tile; VSETTER(int3, tile)
  65. HeroPtr hero; VSETTER(HeroPtr, hero)
  66. const CGTownInstance *town; VSETTER(CGTownInstance *, town)
  67. int bid; VSETTER(int, bid)
  68. AbstractGoal (EGoals goal = INVALID) : goalType (goal)
  69. {
  70. priority = 0;
  71. isElementar = false;
  72. isAbstract = false;
  73. value = 0;
  74. aid = -1;
  75. resID = -1;
  76. tile = int3(-1, -1, -1);
  77. town = nullptr;
  78. }
  79. virtual ~AbstractGoal(){};
  80. //FIXME: abstract goal should be abstract, but serializer fails to instantiate subgoals in such case
  81. virtual AbstractGoal * clone() const {return const_cast<AbstractGoal*>(this);};
  82. virtual TGoalVec getAllPossibleSubgoals() {TGoalVec vec; return vec;};
  83. virtual TSubgoal whatToDoToAchieve() {return sptr(AbstractGoal());};
  84. EGoals goalType;
  85. std::string name() const;
  86. virtual std::string completeMessage() const {return "This goal is unspecified!";};
  87. bool invalid() const;
  88. static TSubgoal goVisitOrLookFor(const CGObjectInstance *obj); //if obj is nullptr, then we'll explore
  89. static TSubgoal lookForArtSmart(int aid); //checks non-standard ways of obtaining art (merchants, quests, etc.)
  90. static TSubgoal tryRecruitHero();
  91. ///Visitor pattern
  92. //TODO: make accept work for shared_ptr... somehow
  93. virtual void accept (VCAI * ai); //unhandled goal will report standard error
  94. virtual float accept (FuzzyHelper * f);
  95. virtual bool operator== (AbstractGoal &g);
  96. virtual bool fulfillsMe (Goals::TSubgoal goal) //TODO: multimethod instead of type check
  97. {
  98. return false;
  99. }
  100. template <typename Handler> void serialize(Handler &h, const int version)
  101. {
  102. h & goalType & isElementar & isAbstract & priority;
  103. h & value & resID & objid & aid & tile & hero & town & bid;
  104. }
  105. };
  106. template <typename T> class CGoal : public AbstractGoal
  107. {
  108. public:
  109. CGoal<T> (EGoals goal = INVALID) : AbstractGoal (goal)
  110. {
  111. priority = 0;
  112. isElementar = false;
  113. isAbstract = false;
  114. value = 0;
  115. aid = -1;
  116. resID = -1;
  117. tile = int3(-1, -1, -1);
  118. town = nullptr;
  119. }
  120. OSETTER(bool, isElementar)
  121. OSETTER(bool, isAbstract)
  122. OSETTER(float, priority)
  123. OSETTER(int, value)
  124. OSETTER(int, resID)
  125. OSETTER(int, objid)
  126. OSETTER(int, aid)
  127. OSETTER(int3, tile)
  128. OSETTER(HeroPtr, hero)
  129. OSETTER(CGTownInstance *, town)
  130. OSETTER(int, bid)
  131. void accept (VCAI * ai) override;
  132. float accept (FuzzyHelper * f) override;
  133. CGoal<T> * clone() const override
  134. {
  135. return new T(static_cast<T const&>(*this)); //casting enforces template instantiation
  136. }
  137. TSubgoal iAmElementar()
  138. {
  139. setisElementar(true);
  140. shared_ptr<AbstractGoal> ptr;
  141. ptr.reset(clone());
  142. return ptr;
  143. }
  144. template <typename Handler> void serialize(Handler &h, const int version)
  145. {
  146. h & static_cast<AbstractGoal&> (*this);
  147. //h & goalType & isElementar & isAbstract & priority;
  148. //h & value & resID & objid & aid & tile & hero & town & bid;
  149. }
  150. };
  151. class Invalid : public CGoal<Invalid>
  152. {
  153. public:
  154. Invalid() : CGoal (Goals::INVALID) {priority = -1e10;};
  155. TGoalVec getAllPossibleSubgoals() override {return TGoalVec();};
  156. TSubgoal whatToDoToAchieve() override;
  157. };
  158. class Win : public CGoal<Win>
  159. {
  160. public:
  161. Win() : CGoal (Goals::WIN) {priority = 100;};
  162. TGoalVec getAllPossibleSubgoals() override {return TGoalVec();};
  163. TSubgoal whatToDoToAchieve() override;
  164. };
  165. class NotLose : public CGoal<NotLose>
  166. {
  167. public:
  168. NotLose() : CGoal (Goals::DO_NOT_LOSE) {priority = 100;};
  169. TGoalVec getAllPossibleSubgoals() override {return TGoalVec();};
  170. //TSubgoal whatToDoToAchieve() override;
  171. };
  172. class Conquer : public CGoal<Conquer>
  173. {
  174. public:
  175. Conquer() : CGoal (Goals::CONQUER) {priority = 10;};
  176. TGoalVec getAllPossibleSubgoals() override;
  177. TSubgoal whatToDoToAchieve() override;
  178. };
  179. class Build : public CGoal<Build>
  180. {
  181. public:
  182. Build() : CGoal (Goals::BUILD) {priority = 1;};
  183. TGoalVec getAllPossibleSubgoals() override {return TGoalVec();};
  184. TSubgoal whatToDoToAchieve() override;
  185. };
  186. class Explore : public CGoal<Explore>
  187. {
  188. public:
  189. Explore() : CGoal (Goals::EXPLORE){priority = 1;};
  190. Explore(HeroPtr h) : CGoal (Goals::EXPLORE){hero = h; priority = 1;};
  191. TGoalVec getAllPossibleSubgoals() override;
  192. TSubgoal whatToDoToAchieve() override;
  193. std::string completeMessage() const override;
  194. bool fulfillsMe (TSubgoal goal) override;
  195. };
  196. class GatherArmy : public CGoal<GatherArmy>
  197. {
  198. public:
  199. GatherArmy() : CGoal (Goals::GATHER_ARMY){};
  200. GatherArmy(int val) : CGoal (Goals::GATHER_ARMY){value = val; priority = 2.5;};
  201. TGoalVec getAllPossibleSubgoals() override;
  202. TSubgoal whatToDoToAchieve() override;
  203. std::string completeMessage() const override;
  204. };
  205. class BoostHero : public CGoal<BoostHero>
  206. {
  207. public:
  208. BoostHero() : CGoal (Goals::INVALID){priority = -1e10;}; //TODO
  209. TGoalVec getAllPossibleSubgoals() override {return TGoalVec();};
  210. //TSubgoal whatToDoToAchieve() override {return sptr(Invalid());};
  211. };
  212. class RecruitHero : public CGoal<RecruitHero>
  213. {
  214. public:
  215. RecruitHero() : CGoal (Goals::RECRUIT_HERO){priority = 1;};
  216. TGoalVec getAllPossibleSubgoals() override {return TGoalVec();};
  217. TSubgoal whatToDoToAchieve() override;
  218. };
  219. class BuildThis : public CGoal<BuildThis>
  220. {
  221. public:
  222. BuildThis() : CGoal (Goals::BUILD_STRUCTURE){}; //FIXME: should be not allowed (private)
  223. BuildThis(BuildingID Bid, const CGTownInstance *tid) : CGoal (Goals::BUILD_STRUCTURE) {bid = Bid; town = tid; priority = 5;};
  224. BuildThis(BuildingID Bid) : CGoal (Goals::BUILD_STRUCTURE) {bid = Bid; priority = 5;};
  225. TGoalVec getAllPossibleSubgoals() override {return TGoalVec();};
  226. TSubgoal whatToDoToAchieve() override;
  227. };
  228. class CollectRes : public CGoal<CollectRes>
  229. {
  230. public:
  231. CollectRes() : CGoal (Goals::COLLECT_RES){};
  232. CollectRes(int rid, int val) : CGoal (Goals::COLLECT_RES) {resID = rid; value = val; priority = 2;};
  233. TGoalVec getAllPossibleSubgoals() override {return TGoalVec();};
  234. TSubgoal whatToDoToAchieve() override;
  235. };
  236. class GatherTroops : public CGoal<GatherTroops>
  237. {
  238. public:
  239. GatherTroops() : CGoal (Goals::GATHER_TROOPS){priority = 2;};
  240. GatherTroops(int type, int val) : CGoal (Goals::GATHER_TROOPS){objid = type; value = val; priority = 2;};
  241. TGoalVec getAllPossibleSubgoals() override {return TGoalVec();};
  242. TSubgoal whatToDoToAchieve() override;
  243. };
  244. class GetObj : public CGoal<GetObj>
  245. {
  246. public:
  247. GetObj() {}; // empty constructor not allowed
  248. GetObj(int Objid) : CGoal(Goals::GET_OBJ) {objid = Objid; priority = 3;};
  249. TGoalVec getAllPossibleSubgoals() override {return TGoalVec();};
  250. TSubgoal whatToDoToAchieve() override;
  251. bool operator== (GetObj &g) {return g.objid == objid;}
  252. bool fulfillsMe (TSubgoal goal) override;
  253. std::string completeMessage() const override;
  254. };
  255. class FindObj : public CGoal<FindObj>
  256. {
  257. public:
  258. FindObj() {}; // empty constructor not allowed
  259. FindObj(int ID) : CGoal(Goals::FIND_OBJ) {objid = ID; priority = 1;};
  260. FindObj(int ID, int subID) : CGoal(Goals::FIND_OBJ) {objid = ID; resID = subID; priority = 1;};
  261. TGoalVec getAllPossibleSubgoals() override {return TGoalVec();};
  262. TSubgoal whatToDoToAchieve() override;
  263. };
  264. class VisitHero : public CGoal<VisitHero>
  265. {
  266. public:
  267. VisitHero() : CGoal (Goals::VISIT_HERO){};
  268. VisitHero(int hid) : CGoal (Goals::VISIT_HERO){objid = hid; priority = 4;};
  269. TGoalVec getAllPossibleSubgoals() override {return TGoalVec();};
  270. TSubgoal whatToDoToAchieve() override;
  271. //bool operator== (VisitHero &g) {return g.objid == objid;}
  272. bool fulfillsMe (TSubgoal goal) override;
  273. std::string completeMessage() const override;
  274. };
  275. class GetArtOfType : public CGoal<GetArtOfType>
  276. {
  277. public:
  278. GetArtOfType() : CGoal (Goals::GET_ART_TYPE){};
  279. GetArtOfType(int type) : CGoal (Goals::GET_ART_TYPE){aid = type; priority = 2;};
  280. TGoalVec getAllPossibleSubgoals() override {return TGoalVec();};
  281. TSubgoal whatToDoToAchieve() override;
  282. };
  283. class VisitTile : public CGoal<VisitTile>
  284. //tile, in conjunction with hero elementar; assumes tile is reachable
  285. {
  286. public:
  287. VisitTile() {}; // empty constructor not allowed
  288. VisitTile(int3 Tile) : CGoal (Goals::VISIT_TILE) {tile = Tile; priority = 5;};
  289. TGoalVec getAllPossibleSubgoals() override;
  290. TSubgoal whatToDoToAchieve() override;
  291. //bool operator== (VisitTile &g) {return g.tile == tile;}
  292. std::string completeMessage() const override;
  293. };
  294. class ClearWayTo : public CGoal<ClearWayTo>
  295. {
  296. public:
  297. ClearWayTo() : CGoal (Goals::CLEAR_WAY_TO){};
  298. ClearWayTo(int3 Tile) : CGoal (Goals::CLEAR_WAY_TO) {tile = Tile; priority = 5;};
  299. ClearWayTo(int3 Tile, HeroPtr h) : CGoal (Goals::CLEAR_WAY_TO) {tile = Tile; hero = h; priority = 5;};
  300. TGoalVec getAllPossibleSubgoals() override;
  301. TSubgoal whatToDoToAchieve() override;
  302. bool operator== (ClearWayTo &g) {return g.tile == tile;}
  303. };
  304. class DigAtTile : public CGoal<DigAtTile>
  305. //elementar with hero on tile
  306. {
  307. public:
  308. DigAtTile() : CGoal (Goals::DIG_AT_TILE){};
  309. DigAtTile(int3 Tile) : CGoal (Goals::DIG_AT_TILE) {tile = Tile; priority = 20;};
  310. TGoalVec getAllPossibleSubgoals() override {return TGoalVec();};
  311. TSubgoal whatToDoToAchieve() override;
  312. bool operator== (DigAtTile &g) {return g.tile == tile;}
  313. };
  314. class CIssueCommand : public CGoal<CIssueCommand>
  315. {
  316. std::function<bool()> command;
  317. public:
  318. CIssueCommand(): CGoal(ISSUE_COMMAND){};
  319. CIssueCommand(std::function<bool()> _command): CGoal(ISSUE_COMMAND), command(_command) {priority = 1e10;};
  320. TGoalVec getAllPossibleSubgoals() override {return TGoalVec();};
  321. //TSubgoal whatToDoToAchieve() override {return sptr(Invalid());};
  322. };
  323. }