CCampaignHandler.cpp 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. #define VCMI_DLL
  2. #include "CCampaignHandler.h"
  3. #include <boost/filesystem.hpp>
  4. #include <stdio.h>
  5. #include <boost/algorithm/string/predicate.hpp>
  6. #include "CLodHandler.h"
  7. namespace fs = boost::filesystem;
  8. /*
  9. * CCampaignHandler.cpp, 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. std::vector<CCampaignHeader> CCampaignHandler::getCampaignHeaders()
  18. {
  19. std::vector<CCampaignHeader> ret;
  20. std::string dirname = DATA_DIR "/Maps";
  21. std::string ext = ".h3c";
  22. if(!boost::filesystem::exists(dirname))
  23. {
  24. tlog1 << "Cannot find " << dirname << " directory!\n";
  25. }
  26. fs::path tie(dirname);
  27. fs::directory_iterator end_iter;
  28. for ( fs::directory_iterator file (tie); file!=end_iter; ++file )
  29. {
  30. if(fs::is_regular_file(file->status())
  31. && boost::ends_with(file->path().filename(), ext))
  32. {
  33. ret.push_back( getHeader( file->path().string(), fs::file_size( file->path() ) ) );
  34. }
  35. }
  36. return ret;
  37. }
  38. CCampaignHeader CCampaignHandler::getHeader( const std::string & name, int size )
  39. {
  40. int realSize;
  41. unsigned char * cmpgn = CLodHandler::getUnpackedFile(name, &realSize);
  42. int it = 0;//iterator for reading
  43. CCampaignHeader ret = readHeaderFromMemory(cmpgn, it);
  44. delete [] cmpgn;
  45. return ret;
  46. }
  47. CCampaign * CCampaignHandler::getCampaign( const std::string & name )
  48. {
  49. CCampaign * ret = new CCampaign();
  50. int realSize;
  51. unsigned char * cmpgn = CLodHandler::getUnpackedFile(name, &realSize);
  52. int it = 0; //iterator for reading
  53. ret->header = readHeaderFromMemory(cmpgn, it);
  54. it += 112; //omitting rubbish
  55. CCampaignScenario sc = readScenarioFromMemory(cmpgn, it);
  56. CCampaignScenario sc2 = readScenarioFromMemory(cmpgn, it);
  57. delete [] cmpgn;
  58. return ret;
  59. }
  60. CCampaignHeader CCampaignHandler::readHeaderFromMemory( const unsigned char *buffer, int & outIt )
  61. {
  62. CCampaignHeader ret;
  63. ret.version = readNormalNr(buffer, outIt); outIt+=4;
  64. ret.mapVersion = readChar(buffer, outIt);
  65. ret.name = readString(buffer, outIt);
  66. ret.description = readString(buffer, outIt);
  67. ret.difficultyChoosenByPlayer = readChar(buffer, outIt);
  68. ret.music = readChar(buffer, outIt);
  69. return ret;
  70. }
  71. CCampaignScenario CCampaignHandler::readScenarioFromMemory( const unsigned char *buffer, int & outIt )
  72. {
  73. struct HLP
  74. {
  75. //reads prolog/epilog info from memory
  76. static CCampaignScenario::SScenarioPrologEpilog prologEpilogReader( const unsigned char *buffer, int & outIt )
  77. {
  78. CCampaignScenario::SScenarioPrologEpilog ret;
  79. ret.hasPrologEpilog = buffer[outIt++];
  80. if(ret.hasPrologEpilog)
  81. {
  82. ret.prologVideo = buffer[outIt++];
  83. ret.prologMusic = buffer[outIt++];
  84. ret.prologText = readString(buffer, outIt);
  85. }
  86. return ret;
  87. }
  88. };
  89. CCampaignScenario ret;
  90. ret.mapName = readString(buffer, outIt);
  91. ret.packedMapSize = readNormalNr(buffer, outIt); outIt += 4;
  92. ret.preconditionRegion = buffer[outIt++];
  93. ret.regionColor = buffer[outIt++];
  94. ret.difficulty = buffer[outIt++];
  95. ret.regionText = readString(buffer, outIt);
  96. ret.prolog = HLP::prologEpilogReader(buffer, outIt);
  97. ret.epilog = HLP::prologEpilogReader(buffer, outIt);
  98. ret.travelOptions = readScenarioTravelFromMemory(buffer, outIt);
  99. return ret;
  100. }
  101. CScenarioTravel CCampaignHandler::readScenarioTravelFromMemory( const unsigned char * buffer, int & outIt )
  102. {
  103. CScenarioTravel ret;
  104. ret.whatHeroKeeps = buffer[outIt++];
  105. memcpy(ret.monstersKeptByHero, buffer+outIt, ARRAY_COUNT(ret.monstersKeptByHero));
  106. outIt += ARRAY_COUNT(ret.monstersKeptByHero);
  107. memcpy(ret.artifsKeptByHero, buffer+outIt, ARRAY_COUNT(ret.artifsKeptByHero));
  108. outIt += ARRAY_COUNT(ret.artifsKeptByHero);
  109. ret.startOptions = buffer[outIt++];
  110. switch(ret.startOptions)
  111. {
  112. case 1: //reading of bonuses player can choose
  113. {
  114. ret.playerColor = buffer[outIt++];
  115. ui8 numOfBonuses = buffer[outIt++];
  116. for (int g=0; g<numOfBonuses; ++g)
  117. {
  118. CScenarioTravel::STravelBonus bonus;
  119. bonus.type = buffer[outIt++];
  120. switch(bonus.type)
  121. {
  122. case 0: //spell
  123. {
  124. bonus.info1 = readNormalNr(buffer, outIt, 2); outIt += 2; //hero
  125. bonus.info2 = buffer[outIt++]; //spell ID
  126. break;
  127. }
  128. case 1: //monster
  129. {
  130. bonus.info1 = readNormalNr(buffer, outIt, 2); outIt += 2; //hero
  131. bonus.info2 = readNormalNr(buffer, outIt, 2); outIt += 2; //monster type
  132. bonus.info3 = readNormalNr(buffer, outIt, 2); outIt += 2; //monster count
  133. break;
  134. }
  135. case 2: //building
  136. {
  137. //TODO
  138. break;
  139. }
  140. case 3: //artifact
  141. {
  142. bonus.info1 = readNormalNr(buffer, outIt, 2); outIt += 2; //hero
  143. bonus.info2 = readNormalNr(buffer, outIt, 2); outIt += 2; //artifact ID
  144. break;
  145. }
  146. case 4: //spell scroll
  147. {
  148. bonus.info1 = readNormalNr(buffer, outIt, 2); outIt += 2; //hero
  149. bonus.info2 = readNormalNr(buffer, outIt, 2); outIt += 2; //spell ID
  150. break;
  151. }
  152. case 5: //prim skill
  153. {
  154. bonus.info1 = readNormalNr(buffer, outIt, 2); outIt += 2; //hero
  155. bonus.info2 = readNormalNr(buffer, outIt, 4); outIt += 4; //bonuses (4 bytes for 4 skills)
  156. break;
  157. }
  158. case 6: //sec skills
  159. {
  160. bonus.info1 = readNormalNr(buffer, outIt, 2); outIt += 2; //hero
  161. bonus.info2 = buffer[outIt++]; //skill ID
  162. bonus.info3 = buffer[outIt++]; //skill level
  163. break;
  164. }
  165. case 7: //resources
  166. {
  167. bonus.info1 = buffer[outIt++]; //type
  168. //FD - wood+ore
  169. //FE - mercury+sulfur+crystal+gem
  170. bonus.info2 = readNormalNr(buffer, outIt, 4); outIt += 4; //count
  171. break;
  172. }
  173. }
  174. ret.bonusesToChoose.push_back(bonus);
  175. }
  176. break;
  177. }
  178. case 2: //reading of players (colors / scenarios ?) player can choose
  179. {
  180. ui8 numOfBonuses = buffer[outIt++];
  181. for (int g=0; g<numOfBonuses; ++g)
  182. {
  183. CScenarioTravel::STravelBonus bonus;
  184. bonus.type = 8;
  185. bonus.info1 = buffer[outIt++]; //player color
  186. bonus.info2 = buffer[outIt++]; //from what scenario
  187. ret.bonusesToChoose.push_back(bonus);
  188. }
  189. break;
  190. }
  191. case 3: //heroes player can choose between
  192. {
  193. ui8 numOfBonuses = buffer[outIt++];
  194. for (int g=0; g<numOfBonuses; ++g)
  195. {
  196. CScenarioTravel::STravelBonus bonus;
  197. bonus.type = 9;
  198. bonus.info1 = buffer[outIt++]; //player color
  199. bonus.info2 = readNormalNr(buffer, outIt, 2); outIt += 2; //hero, FF FF - random
  200. ret.bonusesToChoose.push_back(bonus);
  201. }
  202. break;
  203. }
  204. default:
  205. {
  206. tlog1<<"Corrupted h3c file"<<std::endl;
  207. break;
  208. }
  209. }
  210. return ret;
  211. }