IGameCallback.cpp 6.5 KB

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