CMap.cpp 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. #include "StdInc.h"
  2. #include "CMap.h"
  3. #include "../CObjectHandler.h"
  4. #include "../CArtHandler.h"
  5. #include "../CDefObjInfoHandler.h"
  6. SHeroName::SHeroName() : heroId(-1)
  7. {
  8. }
  9. PlayerInfo::PlayerInfo(): p7(0), p8(0), p9(0), powerPlaceholders(-1),
  10. canHumanPlay(false), canComputerPlay(false),
  11. aiTactic(EAiTactic::RANDOM), isFactionRandom(false), mainHeroPortrait(0), hasMainTown(false),
  12. generateHeroAtMainTown(false), team(255), generateHero(false)
  13. {
  14. }
  15. si8 PlayerInfo::defaultCastle() const
  16. {
  17. assert(!allowedFactions.empty()); // impossible?
  18. if(allowedFactions.size() == 1)
  19. {
  20. // only one faction is available - pick it
  21. return *allowedFactions.begin();
  22. }
  23. // set to random
  24. return -1;
  25. }
  26. si8 PlayerInfo::defaultHero() const
  27. {
  28. // we will generate hero in front of main town
  29. if((generateHeroAtMainTown && hasMainTown) || p8)
  30. {
  31. //random hero
  32. return -1;
  33. }
  34. return -2;
  35. }
  36. LossCondition::LossCondition() : typeOfLossCon(ELossConditionType::LOSSSTANDARD),
  37. pos(int3(-1, -1, -1)), timeLimit(-1), obj(nullptr)
  38. {
  39. }
  40. VictoryCondition::VictoryCondition() : condition(EVictoryConditionType::WINSTANDARD),
  41. allowNormalVictory(false), appliesToAI(false), pos(int3(-1, -1, -1)), objectId(0),
  42. count(0), obj(nullptr)
  43. {
  44. }
  45. DisposedHero::DisposedHero() : heroId(0), portrait(255), players(0)
  46. {
  47. }
  48. CMapEvent::CMapEvent() : players(0), humanAffected(0), computerAffected(0),
  49. firstOccurence(0), nextOccurence(0)
  50. {
  51. }
  52. bool CMapEvent::earlierThan(const CMapEvent & other) const
  53. {
  54. return firstOccurence < other.firstOccurence;
  55. }
  56. bool CMapEvent::earlierThanOrEqual(const CMapEvent & other) const
  57. {
  58. return firstOccurence <= other.firstOccurence;
  59. }
  60. CCastleEvent::CCastleEvent() : town(nullptr)
  61. {
  62. }
  63. TerrainTile::TerrainTile() : terType(ETerrainType::BORDER), terView(0), riverType(ERiverType::NO_RIVER),
  64. riverDir(0), roadType(ERoadType::NO_ROAD), roadDir(0), extTileFlags(0), visitable(false),
  65. blocked(false)
  66. {
  67. }
  68. bool TerrainTile::entrableTerrain(const TerrainTile * from /*= NULL*/) const
  69. {
  70. return entrableTerrain(from ? from->terType != ETerrainType::WATER : true, from ? from->terType == ETerrainType::WATER : true);
  71. }
  72. bool TerrainTile::entrableTerrain(bool allowLand, bool allowSea) const
  73. {
  74. return terType != ETerrainType::ROCK
  75. && ((allowSea && terType == ETerrainType::WATER) || (allowLand && terType != ETerrainType::WATER));
  76. }
  77. bool TerrainTile::isClear(const TerrainTile *from /*= NULL*/) const
  78. {
  79. return entrableTerrain(from) && !blocked;
  80. }
  81. int TerrainTile::topVisitableId() const
  82. {
  83. return visitableObjects.size() ? visitableObjects.back()->ID : -1;
  84. }
  85. bool TerrainTile::isCoastal() const
  86. {
  87. return extTileFlags & 64;
  88. }
  89. bool TerrainTile::hasFavourableWinds() const
  90. {
  91. return extTileFlags & 128;
  92. }
  93. bool TerrainTile::isWater() const
  94. {
  95. return terType == ETerrainType::WATER;
  96. }
  97. CMapHeader::CMapHeader() : version(EMapFormat::INVALID), areAnyPlayers(false),
  98. height(-1), width(-1), twoLevel(-1), difficulty(0), levelLimit(0),
  99. howManyTeams(0)
  100. {
  101. }
  102. CMapHeader::~CMapHeader()
  103. {
  104. }
  105. CMap::CMap() : checksum(0), terrain(nullptr), grailRadious(0)
  106. {
  107. }
  108. CMap::~CMap()
  109. {
  110. if(terrain)
  111. {
  112. for(int ii=0;ii<width;ii++)
  113. {
  114. for(int jj=0;jj<height;jj++)
  115. delete [] terrain[ii][jj];
  116. delete [] terrain[ii];
  117. }
  118. delete [] terrain;
  119. }
  120. for(std::list<ConstTransitivePtr<CMapEvent> >::iterator i = events.begin(); i != events.end(); i++)
  121. {
  122. i->dellNull();
  123. }
  124. }
  125. void CMap::removeBlockVisTiles(CGObjectInstance * obj, bool total)
  126. {
  127. for(int fx=0; fx<8; ++fx)
  128. {
  129. for(int fy=0; fy<6; ++fy)
  130. {
  131. int xVal = obj->pos.x + fx - 7;
  132. int yVal = obj->pos.y + fy - 5;
  133. int zVal = obj->pos.z;
  134. if(xVal>=0 && xVal<width && yVal>=0 && yVal<height)
  135. {
  136. TerrainTile & curt = terrain[xVal][yVal][zVal];
  137. if(total || ((obj->defInfo->visitMap[fy] >> (7 - fx)) & 1))
  138. {
  139. curt.visitableObjects -= obj;
  140. curt.visitable = curt.visitableObjects.size();
  141. }
  142. if(total || !((obj->defInfo->blockMap[fy] >> (7 - fx)) & 1))
  143. {
  144. curt.blockingObjects -= obj;
  145. curt.blocked = curt.blockingObjects.size();
  146. }
  147. }
  148. }
  149. }
  150. }
  151. void CMap::addBlockVisTiles(CGObjectInstance * obj)
  152. {
  153. for(int fx=0; fx<8; ++fx)
  154. {
  155. for(int fy=0; fy<6; ++fy)
  156. {
  157. int xVal = obj->pos.x + fx - 7;
  158. int yVal = obj->pos.y + fy - 5;
  159. int zVal = obj->pos.z;
  160. if(xVal>=0 && xVal<width && yVal>=0 && yVal<height)
  161. {
  162. TerrainTile & curt = terrain[xVal][yVal][zVal];
  163. if(((obj->defInfo->visitMap[fy] >> (7 - fx)) & 1))
  164. {
  165. curt.visitableObjects.push_back(obj);
  166. curt.visitable = true;
  167. }
  168. if(!((obj->defInfo->blockMap[fy] >> (7 - fx)) & 1))
  169. {
  170. curt.blockingObjects.push_back(obj);
  171. curt.blocked = true;
  172. }
  173. }
  174. }
  175. }
  176. }
  177. CGHeroInstance * CMap::getHero(int heroID)
  178. {
  179. for(ui32 i=0; i<heroes.size();i++)
  180. if(heroes[i]->subID == heroID)
  181. return heroes[i];
  182. return nullptr;
  183. }
  184. bool CMap::isInTheMap(const int3 &pos) const
  185. {
  186. if(pos.x<0 || pos.y<0 || pos.z<0 || pos.x >= width || pos.y >= height || pos.z > twoLevel)
  187. return false;
  188. else return true;
  189. }
  190. TerrainTile & CMap::getTile( const int3 & tile )
  191. {
  192. return terrain[tile.x][tile.y][tile.z];
  193. }
  194. const TerrainTile & CMap::getTile( const int3 & tile ) const
  195. {
  196. return terrain[tile.x][tile.y][tile.z];
  197. }
  198. bool CMap::isWaterTile(const int3 &pos) const
  199. {
  200. return isInTheMap(pos) && getTile(pos).terType == ETerrainType::WATER;
  201. }
  202. const CGObjectInstance *CMap::getObjectiveObjectFrom(int3 pos, bool lookForHero)
  203. {
  204. const std::vector <CGObjectInstance *> & objs = getTile(pos).visitableObjects;
  205. assert(objs.size());
  206. if(objs.size() > 1 && lookForHero && objs.front()->ID != Obj::HERO)
  207. {
  208. assert(objs.back()->ID == Obj::HERO);
  209. return objs.back();
  210. }
  211. else
  212. return objs.front();
  213. }
  214. void CMap::checkForObjectives()
  215. {
  216. if(isInTheMap(victoryCondition.pos))
  217. victoryCondition.obj = getObjectiveObjectFrom(victoryCondition.pos, victoryCondition.condition == EVictoryConditionType::BEATHERO);
  218. if(isInTheMap(lossCondition.pos))
  219. lossCondition.obj = getObjectiveObjectFrom(lossCondition.pos, lossCondition.typeOfLossCon == ELossConditionType::LOSSHERO);
  220. }
  221. void CMap::addNewArtifactInstance( CArtifactInstance *art )
  222. {
  223. art->id = artInstances.size();
  224. artInstances.push_back(art);
  225. }
  226. void CMap::eraseArtifactInstance(CArtifactInstance *art)
  227. {
  228. assert(artInstances[art->id] == art);
  229. artInstances[art->id].dellNull();
  230. }