IGameCallback.cpp 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. #define VCMI_DLL
  2. #include "IGameCallback.h"
  3. #include "../lib/CGameState.h"
  4. #include "../lib/map.h"
  5. #include "../hch/CObjectHandler.h"
  6. #include "../StartInfo.h"
  7. #include "../hch/CArtHandler.h"
  8. #include "../hch/CSpellHandler.h"
  9. #include "../lib/VCMI_Lib.h"
  10. #include <boost/random/linear_congruential.hpp>
  11. /*
  12. * IGameCallback.cpp, part of VCMI engine
  13. *
  14. * Authors: listed in file AUTHORS in main folder
  15. *
  16. * License: GNU General Public License v2.0 or later
  17. * Full text of license available in license.txt file, in main folder
  18. *
  19. */
  20. extern boost::rand48 ran;
  21. CGameState *const IGameCallback::gameState ()
  22. {
  23. return gs;
  24. }
  25. const CGObjectInstance* IGameCallback::getObj(int objid)
  26. {
  27. if(objid < 0 || objid >= gs->map->objects.size())
  28. {
  29. tlog1 << "Cannot get object with id " << objid << std::endl;
  30. return NULL;
  31. }
  32. else if (!gs->map->objects[objid])
  33. {
  34. tlog1 << "Cannot get object with id " << objid << ". Object was removed.\n";
  35. return NULL;
  36. }
  37. return gs->map->objects[objid];
  38. }
  39. const CGHeroInstance* IGameCallback::getHero(int objid)
  40. {
  41. const CGObjectInstance *obj = getObj(objid);
  42. if(obj)
  43. return dynamic_cast<const CGHeroInstance*>(obj);
  44. else
  45. return NULL;
  46. }
  47. const CGTownInstance* IGameCallback::getTown(int objid)
  48. {
  49. const CGObjectInstance *obj = getObj(objid);
  50. if(obj)
  51. return dynamic_cast<const CGTownInstance*>(gs->map->objects[objid]);
  52. else
  53. return NULL;
  54. }
  55. int IGameCallback::getOwner(int heroID)
  56. {
  57. return gs->map->objects[heroID]->tempOwner;
  58. }
  59. int IGameCallback::getResource(int player, int which)
  60. {
  61. return gs->players.find(player)->second.resources[which];
  62. }
  63. int IGameCallback::getDate(int mode)
  64. {
  65. return gs->getDate(mode);
  66. }
  67. const CGHeroInstance* IGameCallback::getSelectedHero( int player )
  68. {
  69. if(gs->players.find(player)->second.currentSelection==-1)
  70. return NULL;
  71. return getHero(gs->players.find(player)->second.currentSelection);
  72. }
  73. const PlayerSettings * IGameCallback::getPlayerSettings( int color )
  74. {
  75. return &gs->scenarioOps->getIthPlayersSettings(color);
  76. }
  77. int IGameCallback::getHeroCount( int player, bool includeGarrisoned )
  78. {
  79. int ret = 0;
  80. if(includeGarrisoned)
  81. return gs->getPlayer(player)->heroes.size();
  82. else
  83. for(int i=0; i < gs->getPlayer(player)->heroes.size(); i++)
  84. if(!gs->getPlayer(player)->heroes[i]->inTownGarrison)
  85. ret++;
  86. return ret;
  87. }
  88. void IGameCallback::getTilesInRange( std::set<int3> &tiles, int3 pos, int radious, int player/*=-1*/, int mode/*=0*/ )
  89. {
  90. if(player >= PLAYER_LIMIT)
  91. {
  92. tlog1 << "Illegal call to getTilesInRange!\n";
  93. return;
  94. }
  95. if (radious == -1) //reveal entire map
  96. getAllTiles (tiles, player, -1, 0);
  97. else
  98. {
  99. PlayerState * plr = &gs->players.find(player)->second;
  100. for (int xd = std::max<int>(pos.x - radious , 0); xd <= std::min<int>(pos.x + radious, gs->map->width - 1); xd++)
  101. {
  102. for (int yd = std::max<int>(pos.y - radious, 0); yd <= std::min<int>(pos.y + radious, gs->map->height - 1); yd++)
  103. {
  104. double distance = pos.dist2d(int3(xd,yd,pos.z)) - 0.5;
  105. if(distance <= radious)
  106. {
  107. if(player < 0
  108. || (mode == 1 && plr->fogOfWarMap[xd][yd][pos.z]==0)
  109. || (mode == -1 && plr->fogOfWarMap[xd][yd][pos.z]==1)
  110. )
  111. tiles.insert(int3(xd,yd,pos.z));
  112. }
  113. }
  114. }
  115. }
  116. }
  117. void IGameCallback::getAllTiles (std::set<int3> &tiles, int player/*=-1*/, int level, int surface )
  118. {
  119. if(player >= PLAYER_LIMIT)
  120. {
  121. tlog1 << "Illegal call to getAllTiles !\n";
  122. return;
  123. }
  124. bool water = surface == 0 || surface == 2,
  125. land = surface == 0 || surface == 1;
  126. std::vector<int> floors;
  127. if(level == -1)
  128. {
  129. for (int xd = 0; xd <= gs->map->width - 1; xd++)
  130. for(int b=0; b<gs->map->twoLevel + 1; ++b) //if gs->map->twoLevel is false then false (0) + 1 is 1, if it's true (1) then we have 2
  131. {
  132. floors.push_back(b);
  133. }
  134. }
  135. else
  136. floors.push_back(level);
  137. for (std::vector<int>::const_iterator i = floors.begin(); i!= floors.end(); i++)
  138. {
  139. register int zd = *i;
  140. for (int xd = 0; xd < gs->map->width; xd++)
  141. {
  142. for (int yd = 0; yd < gs->map->height; yd++)
  143. {
  144. if ((getTile (int3 (xd,yd,zd))->tertype == 8 && water)
  145. || (getTile (int3 (xd,yd,zd))->tertype != 8 && land))
  146. tiles.insert(int3(xd,yd,zd));
  147. }
  148. }
  149. }
  150. }
  151. bool IGameCallback::isAllowed( int type, int id )
  152. {
  153. switch(type)
  154. {
  155. case 0:
  156. return gs->map->allowedSpell[id];
  157. case 1:
  158. return gs->map->allowedArtifact[id];
  159. default:
  160. tlog1 << "Wrong call to IGameCallback::isAllowed!\n";
  161. return false;
  162. }
  163. }
  164. void IGameCallback::getAllowedArts(std::vector<CArtifact*> &out, std::vector<CArtifact*> CArtHandler::*arts, int flag)
  165. {
  166. if (!(VLC->arth->*arts).size()) //restock avaliable arts
  167. {
  168. for (int i = 0; i < VLC->arth->artifacts.size(); i++)
  169. {
  170. if (VLC->arth->artifacts[i].aClass == flag)
  171. (VLC->arth->*arts).push_back(&(VLC->arth->artifacts[i]));
  172. }
  173. }
  174. for (int i = 0; i < (VLC->arth->*arts).size(); i++)
  175. {
  176. CArtifact *art = (VLC->arth->*arts)[i];
  177. if(isAllowed(1, art->id))
  178. {
  179. out.push_back(art);
  180. }
  181. }
  182. }
  183. void IGameCallback::getAllowed(std::vector<CArtifact*> &out, int flags)
  184. {
  185. if(flags & CArtifact::ART_TREASURE)
  186. getAllowedArts(out,&CArtHandler::treasures, CArtifact::ART_TREASURE);
  187. if(flags & CArtifact::ART_MINOR)
  188. getAllowedArts(out,&CArtHandler::minors, CArtifact::ART_MINOR);
  189. if(flags & CArtifact::ART_MAJOR)
  190. getAllowedArts(out,&CArtHandler::majors, CArtifact::ART_MAJOR);
  191. if(flags & CArtifact::ART_RELIC)
  192. getAllowedArts(out,&CArtHandler::relics, CArtifact::ART_RELIC);
  193. }
  194. ui16 IGameCallback::getRandomArt (int flags)
  195. {
  196. std::vector<CArtifact*> out;
  197. getAllowed(out, flags);
  198. CArtifact *art = out[ran() % out.size()];
  199. std::vector<CArtifact*>* ptr;
  200. switch (art->aClass)
  201. {
  202. case CArtifact::ART_TREASURE:
  203. ptr = &VLC->arth->treasures;
  204. break;
  205. case CArtifact::ART_MINOR:
  206. ptr = &VLC->arth->minors;
  207. break;
  208. case CArtifact::ART_MAJOR:
  209. ptr = &VLC->arth->majors;
  210. break;
  211. case CArtifact::ART_RELIC:
  212. ptr = &VLC->arth->relics;
  213. break;
  214. }
  215. ptr->erase (std::find(ptr->begin(), ptr->end(), art)); //remove the artifact from avaliable list
  216. return art->id;
  217. }
  218. void IGameCallback::getAllowedSpells(std::vector<ui16> &out, ui16 level)
  219. {
  220. CSpell *spell;
  221. for (int i = 0; i < gs->map->allowedSpell.size(); i++) //spellh size appears to be greater (?)
  222. {
  223. spell = &(VLC->spellh->spells[i]);
  224. if (isAllowed (0, spell->id) && spell->level == level)
  225. {
  226. out.push_back(spell->id);
  227. }
  228. }
  229. }
  230. int3 IGameCallback::getMapSize()
  231. {
  232. return int3(gs->map->width, gs->map->height, gs->map->twoLevel + 1);
  233. }
  234. inline TerrainTile * IGameCallback::getTile( int3 pos )
  235. {
  236. if(!gs->map->isInTheMap(pos))
  237. return NULL;
  238. return &gs->map->getTile(pos);
  239. }
  240. const PlayerState * IGameCallback::getPlayerState( int color )
  241. {
  242. return gs->getPlayer(color, false);
  243. }