CGameState.cpp 44 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539
  1. #define VCMI_DLL
  2. #include <algorithm>
  3. #include <queue>
  4. #include <fstream>
  5. #include "CGameState.h"
  6. #include <boost/random/linear_congruential.hpp>
  7. #include "hch/CDefObjInfoHandler.h"
  8. #include "hch/CArtHandler.h"
  9. #include "hch/CTownHandler.h"
  10. #include "hch/CSpellHandler.h"
  11. #include "hch/CHeroHandler.h"
  12. #include "hch/CObjectHandler.h"
  13. #include "hch/CCreatureHandler.h"
  14. #include "lib/VCMI_Lib.h"
  15. #include "map.h"
  16. #include "StartInfo.h"
  17. #include "lib/NetPacks.h"
  18. #include <boost/foreach.hpp>
  19. #include <boost/thread.hpp>
  20. #include <boost/thread/shared_mutex.hpp>
  21. boost::rand48 ran;
  22. #ifdef min
  23. #undef min
  24. #endif
  25. #ifdef max
  26. #undef max
  27. #endif
  28. CGObjectInstance * createObject(int id, int subid, int3 pos, int owner)
  29. {
  30. CGObjectInstance * nobj;
  31. switch(id)
  32. {
  33. case 34: //hero
  34. {
  35. CGHeroInstance * nobj = new CGHeroInstance();
  36. nobj->pos = pos;
  37. nobj->tempOwner = owner;
  38. nobj->subID = subid;
  39. //nobj->initHero(ran);
  40. return nobj;
  41. }
  42. case 98: //town
  43. nobj = new CGTownInstance;
  44. break;
  45. default: //rest of objects
  46. nobj = new CGObjectInstance;
  47. nobj->defInfo = VLC->dobjinfo->gobjs[id][subid];
  48. break;
  49. }
  50. nobj->ID = id;
  51. nobj->subID = subid;
  52. if(!nobj->defInfo)
  53. tlog3 <<"No def declaration for " <<id <<" "<<subid<<std::endl;
  54. nobj->pos = pos;
  55. //nobj->state = NULL;//new CLuaObjectScript();
  56. nobj->tempOwner = owner;
  57. nobj->info = NULL;
  58. nobj->defInfo->id = id;
  59. nobj->defInfo->subid = subid;
  60. //assigning defhandler
  61. if(nobj->ID==34 || nobj->ID==98)
  62. return nobj;
  63. nobj->defInfo = VLC->dobjinfo->gobjs[id][subid];
  64. return nobj;
  65. }
  66. CStack * BattleInfo::getStack(int stackID)
  67. {
  68. for(int g=0; g<stacks.size(); ++g)
  69. {
  70. if(stacks[g]->ID == stackID)
  71. return stacks[g];
  72. }
  73. return NULL;
  74. }
  75. CStack * BattleInfo::getStackT(int tileID)
  76. {
  77. for(int g=0; g<stacks.size(); ++g)
  78. {
  79. if(stacks[g]->position == tileID
  80. || (stacks[g]->creature->isDoubleWide() && stacks[g]->attackerOwned && stacks[g]->position-1 == tileID)
  81. || (stacks[g]->creature->isDoubleWide() && !stacks[g]->attackerOwned && stacks[g]->position+1 == tileID))
  82. {
  83. if(stacks[g]->alive())
  84. {
  85. return stacks[g];
  86. }
  87. }
  88. }
  89. return NULL;
  90. }
  91. void BattleInfo::getAccessibilityMap(bool *accessibility, int stackToOmmit)
  92. {
  93. memset(accessibility,1,187); //initialize array with trues
  94. for(int g=0; g<stacks.size(); ++g)
  95. {
  96. if(!stacks[g]->alive() || stacks[g]->ID==stackToOmmit) //we don't want to lock position of this stack
  97. continue;
  98. accessibility[stacks[g]->position] = false;
  99. if(stacks[g]->creature->isDoubleWide()) //if it's a double hex creature
  100. {
  101. if(stacks[g]->attackerOwned)
  102. accessibility[stacks[g]->position-1] = false;
  103. else
  104. accessibility[stacks[g]->position+1] = false;
  105. }
  106. }
  107. //TODO: obstacles
  108. }
  109. void BattleInfo::getAccessibilityMapForTwoHex(bool *accessibility, bool atackerSide, int stackToOmmit) //send pointer to at least 187 allocated bytes
  110. {
  111. bool mac[187];
  112. getAccessibilityMap(mac,stackToOmmit);
  113. memcpy(accessibility,mac,187);
  114. for(int b=0; b<187; ++b)
  115. {
  116. if( mac[b] && !(atackerSide ? mac[b-1] : mac[b+1]))
  117. {
  118. accessibility[b] = false;
  119. }
  120. }
  121. //removing accessibility for side hexes
  122. for(int v=0; v<187; ++v)
  123. if(atackerSide ? (v%17)==1 : (v%17)==15)
  124. accessibility[v] = false;
  125. }
  126. void BattleInfo::makeBFS(int start, bool*accessibility, int *predecessor, int *dists) //both pointers must point to the at least 187-elements int arrays
  127. {
  128. //inits
  129. for(int b=0; b<187; ++b)
  130. predecessor[b] = -1;
  131. for(int g=0; g<187; ++g)
  132. dists[g] = 100000000;
  133. std::queue<int> hexq; //bfs queue
  134. hexq.push(start);
  135. dists[hexq.front()] = 0;
  136. int curNext = -1; //for bfs loop only (helper var)
  137. while(!hexq.empty()) //bfs loop
  138. {
  139. int curHex = hexq.front();
  140. std::vector<int> neighbours = neighbouringTiles(curHex);
  141. hexq.pop();
  142. for(int nr=0; nr<neighbours.size(); nr++)
  143. {
  144. curNext = neighbours[nr];
  145. if(!accessibility[curNext] || (dists[curHex]+1)>=dists[curNext])
  146. continue;
  147. hexq.push(curNext);
  148. dists[curNext] = dists[curHex] + 1;
  149. predecessor[curNext] = curHex;
  150. }
  151. }
  152. };
  153. std::vector<int> BattleInfo::getAccessibility(int stackID)
  154. {
  155. std::vector<int> ret;
  156. bool ac[187];
  157. CStack *s = getStack(stackID);
  158. if(s->creature->isDoubleWide())
  159. getAccessibilityMapForTwoHex(ac,s->attackerOwned,stackID);
  160. else
  161. getAccessibilityMap(ac,stackID);
  162. int pr[187], dist[187];
  163. makeBFS(s->position,ac,pr,dist);
  164. for(int i=0;i<187;i++)
  165. if(dist[i] <= s->creature->speed)
  166. ret.push_back(i);
  167. return ret;
  168. }
  169. bool BattleInfo::isStackBlocked(int ID)
  170. {
  171. CStack *our = getStack(ID);
  172. for(int i=0; i<stacks.size();i++)
  173. {
  174. if( !stacks[i]->alive()
  175. || stacks[i]->owner==our->owner
  176. )
  177. continue; //we ommit dead and allied stacks
  178. if( mutualPosition(stacks[i]->position,our->position) >= 0 )
  179. return true;
  180. }
  181. return false;
  182. }
  183. signed char BattleInfo::mutualPosition(int hex1, int hex2)
  184. {
  185. if(hex2 == hex1 - ( (hex1/17)%2 ? 18 : 17 )) //top left
  186. return 0;
  187. if(hex2 == hex1 - ( (hex1/17)%2 ? 17 : 16 )) //top right
  188. return 1;
  189. if(hex2 == hex1 - 1 && hex1%17 != 0) //left
  190. return 5;
  191. if(hex2 == hex1 + 1 && hex1%17 != 16) //right
  192. return 2;
  193. if(hex2 == hex1 + ( (hex1/17)%2 ? 16 : 17 )) //bottom left
  194. return 4;
  195. if(hex2 == hex1 + ( (hex1/17)%2 ? 17 : 18 )) //bottom right
  196. return 3;
  197. return -1;
  198. }
  199. std::vector<int> BattleInfo::neighbouringTiles(int hex)
  200. {
  201. #define CHECK_AND_PUSH(tile) {int hlp = (tile); if(hlp>=0 && hlp<187 && (hlp%17!=16) && hlp%17) ret.push_back(hlp);}
  202. std::vector<int> ret;
  203. CHECK_AND_PUSH(hex - ( (hex/17)%2 ? 18 : 17 ));
  204. CHECK_AND_PUSH(hex - ( (hex/17)%2 ? 17 : 16 ));
  205. CHECK_AND_PUSH(hex - 1);
  206. CHECK_AND_PUSH(hex + 1);
  207. CHECK_AND_PUSH(hex + ( (hex/17)%2 ? 16 : 17 ));
  208. CHECK_AND_PUSH(hex + ( (hex/17)%2 ? 17 : 18 ));
  209. #undef CHECK_AND_PUSH
  210. return ret;
  211. }
  212. std::vector<int> BattleInfo::getPath(int start, int dest, bool*accessibility)
  213. {
  214. int predecessor[187]; //for getting the Path
  215. int dist[187]; //calculated distances
  216. makeBFS(start,accessibility,predecessor,dist);
  217. //making the Path
  218. std::vector<int> path;
  219. int curElem = dest;
  220. while(curElem != start)
  221. {
  222. path.push_back(curElem);
  223. curElem = predecessor[curElem];
  224. }
  225. return path;
  226. }
  227. CStack::CStack(CCreature * C, int A, int O, int I, bool AO, int S)
  228. :creature(C),amount(A), baseAmount(A), owner(O), position(-1), ID(I), attackerOwned(AO), firstHPleft(C->hitPoints), slot(S), counterAttacks(1)
  229. {
  230. abilities = C->abilities;
  231. state.insert(ALIVE);
  232. }
  233. CGHeroInstance* CGameState::HeroesPool::pickHeroFor(bool native, int player, const CTown *town, int notThatOne)
  234. {
  235. if(player<0 || player>=PLAYER_LIMIT)
  236. {
  237. tlog1 << "Cannot pick hero for " << town->name << ". Wrong owner!\n";
  238. return NULL;
  239. }
  240. std::vector<CGHeroInstance *> pool;
  241. int sum=0, r;
  242. if(native)
  243. {
  244. for(std::map<ui32,CGHeroInstance *>::iterator i=heroesPool.begin(); i!=heroesPool.end(); i++)
  245. {
  246. if(pavailable[i->first] & 1<<player
  247. && i->second->type->heroType/2 == town->typeID
  248. && i->second->subID != notThatOne
  249. )
  250. {
  251. pool.push_back(i->second);
  252. }
  253. }
  254. if(!pool.size())
  255. return pickHeroFor(false,player,town,notThatOne);
  256. else
  257. return pool[rand()%pool.size()];
  258. }
  259. else
  260. {
  261. for(std::map<ui32,CGHeroInstance *>::iterator i=heroesPool.begin(); i!=heroesPool.end(); i++)
  262. {
  263. if(pavailable[i->first] & 1<<player
  264. && i->second->subID != notThatOne
  265. )
  266. {
  267. pool.push_back(i->second);
  268. sum += i->second->type->heroClass->selectionProbability[town->typeID];
  269. }
  270. }
  271. if(!pool.size())
  272. {
  273. tlog1 << "There are no heroes available for player " << player<<"!\n";
  274. return NULL;
  275. }
  276. r = rand()%sum;
  277. for(int i=0; i<pool.size(); i++)
  278. {
  279. r -= pool[i]->type->heroClass->selectionProbability[town->typeID];
  280. if(r<0)
  281. return pool[i];
  282. }
  283. return pool[pool.size()-1];
  284. }
  285. }
  286. void CGameState::applyNL(IPack * pack)
  287. {
  288. switch(pack->getType())
  289. {
  290. case 101://NewTurn
  291. {
  292. NewTurn * n = static_cast<NewTurn*>(pack);
  293. day = n->day;
  294. BOOST_FOREACH(NewTurn::Hero h, n->heroes) //give mana/movement point
  295. {
  296. static_cast<CGHeroInstance*>(map->objects[h.id])->movement = h.move;
  297. static_cast<CGHeroInstance*>(map->objects[h.id])->mana = h.mana;
  298. }
  299. BOOST_FOREACH(SetResources h, n->res) //give resources
  300. applyNL(&h);
  301. BOOST_FOREACH(SetAvailableCreatures h, n->cres) //set available creatures in towns
  302. applyNL(&h);
  303. if(n->resetBuilded) //reset amount of structures set in this turn in towns
  304. BOOST_FOREACH(CGTownInstance* t, map->towns)
  305. t->builded = 0;
  306. break;
  307. }
  308. case 102: //set resource amount
  309. {
  310. SetResource *sr = static_cast<SetResource*>(pack);
  311. players[sr->player].resources[sr->resid] = sr->val;
  312. break;
  313. }
  314. case 104:
  315. {
  316. SetResources *sr = static_cast<SetResources*>(pack);
  317. for(int i=0;i<sr->res.size();i++)
  318. players[sr->player].resources[i] = sr->res[i];
  319. break;
  320. }
  321. case 105:
  322. {
  323. SetPrimSkill *sr = static_cast<SetPrimSkill*>(pack);
  324. CGHeroInstance *hero = getHero(sr->id);
  325. if(sr->which <4)
  326. {
  327. if(sr->abs)
  328. hero->primSkills[sr->which] = sr->val;
  329. else
  330. hero->primSkills[sr->which] += sr->val;
  331. }
  332. else if(sr->which == 4) //XP
  333. {
  334. if(sr->abs)
  335. hero->exp = sr->val;
  336. else
  337. hero->exp += sr->val;
  338. }
  339. break;
  340. }
  341. case 106:
  342. {
  343. SetSecSkill *sr = static_cast<SetSecSkill*>(pack);
  344. CGHeroInstance *hero = getHero(sr->id);
  345. if(hero->getSecSkillLevel(sr->which) == 0)
  346. {
  347. hero->secSkills.push_back(std::pair<int,int>(sr->which, sr->val));
  348. }
  349. else
  350. {
  351. for(unsigned i=0;i<hero->secSkills.size();i++)
  352. {
  353. if(hero->secSkills[i].first == sr->which)
  354. {
  355. if(sr->abs)
  356. hero->secSkills[i].second = sr->val;
  357. else
  358. hero->secSkills[i].second += sr->val;
  359. }
  360. }
  361. }
  362. break;
  363. }
  364. case 108:
  365. {
  366. HeroVisitCastle *vc = static_cast<HeroVisitCastle*>(pack);
  367. CGHeroInstance *h = getHero(vc->hid);
  368. CGTownInstance *t = getTown(vc->tid);
  369. if(vc->start())
  370. {
  371. if(vc->garrison())
  372. {
  373. t->garrisonHero = h;
  374. h->visitedTown = t;
  375. h->inTownGarrison = true;
  376. }
  377. else
  378. {
  379. t->visitingHero = h;
  380. h->visitedTown = t;
  381. h->inTownGarrison = false;
  382. }
  383. }
  384. else
  385. {
  386. if(vc->garrison())
  387. {
  388. t->garrisonHero = NULL;
  389. h->visitedTown = NULL;
  390. h->inTownGarrison = false;
  391. }
  392. else
  393. {
  394. t->visitingHero = NULL;
  395. h->visitedTown = NULL;
  396. h->inTownGarrison = false;
  397. }
  398. }
  399. break;
  400. }
  401. case 109:
  402. {
  403. ChangeSpells *rh = static_cast<ChangeSpells*>(pack);
  404. CGHeroInstance *hero = getHero(rh->hid);
  405. if(rh->learn)
  406. BOOST_FOREACH(ui32 sid, rh->spells)
  407. hero->spells.insert(sid);
  408. else
  409. BOOST_FOREACH(ui32 sid, rh->spells)
  410. hero->spells.erase(sid);
  411. break;
  412. }
  413. case 110:
  414. {
  415. SetMana *rh = static_cast<SetMana*>(pack);
  416. CGHeroInstance *hero = getHero(rh->hid);
  417. hero->mana = rh->val;
  418. break;
  419. }
  420. case 111:
  421. {
  422. SetMovePoints *rh = static_cast<SetMovePoints*>(pack);
  423. CGHeroInstance *hero = getHero(rh->hid);
  424. hero->movement = rh->val;
  425. break;
  426. }
  427. case 112:
  428. {
  429. FoWChange *rh = static_cast<FoWChange*>(pack);
  430. BOOST_FOREACH(int3 t, rh->tiles)
  431. players[rh->player].fogOfWarMap[t.x][t.y][t.z] = rh->mode;
  432. break;
  433. }
  434. case 113:
  435. {
  436. SetAvailableHeroes *rh = static_cast<SetAvailableHeroes*>(pack);
  437. players[rh->player].availableHeroes.clear();
  438. players[rh->player].availableHeroes.push_back(hpool.heroesPool[rh->hid1]);
  439. players[rh->player].availableHeroes.push_back(hpool.heroesPool[rh->hid2]);
  440. if(rh->flags & 1)
  441. {
  442. hpool.heroesPool[rh->hid1]->army.slots.clear();
  443. hpool.heroesPool[rh->hid1]->army.slots[0] = std::pair<ui32,si32>(VLC->creh->nameToID[hpool.heroesPool[rh->hid1]->type->refTypeStack[0]],1);
  444. }
  445. if(rh->flags & 2)
  446. {
  447. hpool.heroesPool[rh->hid2]->army.slots.clear();
  448. hpool.heroesPool[rh->hid2]->army.slots[0] = std::pair<ui32,si32>(VLC->creh->nameToID[hpool.heroesPool[rh->hid2]->type->refTypeStack[0]],1);
  449. }
  450. break;
  451. }
  452. case 500:
  453. {
  454. RemoveObject *rh = static_cast<RemoveObject*>(pack);
  455. CGObjectInstance *obj = map->objects[rh->id];
  456. if(obj->ID==34)
  457. {
  458. CGHeroInstance *h = static_cast<CGHeroInstance*>(obj);
  459. std::vector<CGHeroInstance*>::iterator nitr = std::find(map->heroes.begin(), map->heroes.end(),h);
  460. map->heroes.erase(nitr);
  461. int player = h->tempOwner;
  462. nitr = std::find(players[player].heroes.begin(), players[player].heroes.end(), h);
  463. players[player].heroes.erase(nitr);
  464. if(h->visitedTown)
  465. {
  466. if(h->inTownGarrison)
  467. h->visitedTown->garrisonHero = NULL;
  468. else
  469. h->visitedTown->visitingHero = NULL;
  470. h->visitedTown = NULL;
  471. }
  472. }
  473. map->objects[rh->id] = NULL;
  474. //unblock tiles
  475. if(obj->defInfo)
  476. {
  477. map->removeBlockVisTiles(obj);
  478. }
  479. break;
  480. }
  481. case 501://hero try-move
  482. {
  483. TryMoveHero * n = static_cast<TryMoveHero*>(pack);
  484. CGHeroInstance *h = static_cast<CGHeroInstance*>(map->objects[n->id]);
  485. h->movement = n->movePoints;
  486. if(n->start!=n->end && n->result)
  487. {
  488. map->removeBlockVisTiles(h);
  489. h->pos = n->end;
  490. map->addBlockVisTiles(h);
  491. }
  492. BOOST_FOREACH(int3 t, n->fowRevealed)
  493. players[h->getOwner()].fogOfWarMap[t.x][t.y][t.z] = 1;
  494. break;
  495. }
  496. case 502:
  497. {
  498. SetGarrisons * n = static_cast<SetGarrisons*>(pack);
  499. for(std::map<ui32,CCreatureSet>::iterator i = n->garrs.begin(); i!=n->garrs.end(); i++)
  500. {
  501. CArmedInstance *ai = static_cast<CArmedInstance*>(map->objects[i->first]);
  502. ai->army = i->second;
  503. if(ai->ID==98 && (static_cast<CGTownInstance*>(ai))->garrisonHero) //if there is a hero in garrison then we must update also his army
  504. const_cast<CGHeroInstance*>((static_cast<CGTownInstance*>(ai))->garrisonHero)->army = i->second;
  505. else if(ai->ID==34)
  506. {
  507. CGHeroInstance *h = static_cast<CGHeroInstance*>(ai);
  508. if(h->visitedTown && h->inTownGarrison)
  509. h->visitedTown->army = i->second;
  510. }
  511. }
  512. break;
  513. }
  514. case 503:
  515. {
  516. //SetStrInfo *ssi = static_cast<SetStrInfo*>(pack);
  517. //static_cast<CGTownInstance*>(map->objects[ssi->tid])->strInfo.creatures = ssi->cres;
  518. break;
  519. }
  520. case 504:
  521. {
  522. NewStructures *ns = static_cast<NewStructures*>(pack);
  523. CGTownInstance*t = static_cast<CGTownInstance*>(map->objects[ns->tid]);
  524. BOOST_FOREACH(si32 bid,ns->bid)
  525. t->builtBuildings.insert(bid);
  526. t->builded = ns->builded;
  527. break;
  528. }
  529. case 506:
  530. {
  531. SetAvailableCreatures *sac = static_cast<SetAvailableCreatures*>(pack);
  532. static_cast<CGTownInstance*>(map->objects[sac->tid])->strInfo.creatures = sac->creatures;
  533. break;
  534. }
  535. case 508:
  536. {
  537. SetHeroesInTown *sac = static_cast<SetHeroesInTown*>(pack);
  538. CGTownInstance *t = getTown(sac->tid);
  539. CGHeroInstance *v = getHero(sac->visiting), *g = getHero(sac->garrison);
  540. t->visitingHero = v;
  541. t->garrisonHero = g;
  542. if(v)
  543. {
  544. v->visitedTown = t;
  545. v->inTownGarrison = false;
  546. map->addBlockVisTiles(v);
  547. }
  548. if(g)
  549. {
  550. g->visitedTown = t;
  551. g->inTownGarrison = true;
  552. map->removeBlockVisTiles(g);
  553. }
  554. break;
  555. }
  556. case 509:
  557. {
  558. SetHeroArtifacts *sha = static_cast<SetHeroArtifacts*>(pack);
  559. CGHeroInstance *h = getHero(sha->hid);
  560. h->artifacts = sha->artifacts;
  561. h->artifWorn = sha->artifWorn;
  562. break;
  563. }
  564. case 515:
  565. {
  566. HeroRecruited *sha = static_cast<HeroRecruited*>(pack);
  567. CGHeroInstance *h = hpool.heroesPool[sha->hid];
  568. CGTownInstance *t = getTown(sha->tid);
  569. h->setOwner(sha->player);
  570. h->pos = sha->tile;
  571. h->movement = h->maxMovePoints(true);
  572. hpool.heroesPool.erase(sha->hid);
  573. if(h->id < 0)
  574. {
  575. h->id = map->objects.size();
  576. map->objects.push_back(h);
  577. }
  578. else
  579. map->objects[h->id] = h;
  580. map->heroes.push_back(h);
  581. players[h->tempOwner].heroes.push_back(h);
  582. map->addBlockVisTiles(h);
  583. t->visitingHero = h;
  584. h->visitedTown = t;
  585. h->inTownGarrison = false;
  586. break;
  587. }
  588. case 1001://set object property
  589. {
  590. SetObjectProperty *p = static_cast<SetObjectProperty*>(pack);
  591. if(p->what == 3) //set creatures amount
  592. {
  593. tlog5 << "Setting creatures amount in " << p->id << std::endl;
  594. static_cast<CCreatureObjInfo*>(map->objects[p->id]->info)->number = p->val;
  595. break;
  596. }
  597. ui8 CGObjectInstance::*point;
  598. switch(p->what)
  599. {
  600. case 1:
  601. point = &CGObjectInstance::tempOwner;
  602. break;
  603. case 2:
  604. point = &CGObjectInstance::blockVisit;
  605. break;
  606. }
  607. map->objects[p->id]->*point = p->val;
  608. break;
  609. }
  610. case 2000:
  611. {
  612. HeroLevelUp * bs = static_cast<HeroLevelUp*>(pack);
  613. getHero(bs->heroid)->level = bs->level;
  614. break;
  615. }
  616. case 3000:
  617. {
  618. BattleStart * bs = static_cast<BattleStart*>(pack);
  619. curB = bs->info;
  620. break;
  621. }
  622. case 3001:
  623. {
  624. BattleNextRound *ns = static_cast<BattleNextRound*>(pack);
  625. curB->round = ns->round;
  626. for(int i=0; i<curB->stacks.size();i++)
  627. curB->stacks[i]->counterAttacks = 1;
  628. break;
  629. }
  630. case 3002:
  631. {
  632. BattleSetActiveStack *ns = static_cast<BattleSetActiveStack*>(pack);
  633. curB->activeStack = ns->stack;
  634. break;
  635. }
  636. case 3003:
  637. {
  638. BattleResult *br = static_cast<BattleResult*>(pack);
  639. //TODO: give exp, artifacts to winner, decrease armies (casualties)
  640. for(unsigned i=0;i<curB->stacks.size();i++)
  641. delete curB->stacks[i];
  642. delete curB;
  643. curB = NULL;
  644. break;
  645. }
  646. case 3004:
  647. {
  648. BattleStackMoved *br = static_cast<BattleStackMoved*>(pack);
  649. curB->getStack(br->stack)->position = br->tile;
  650. break;
  651. }
  652. case 3005:
  653. {
  654. BattleStackAttacked *br = static_cast<BattleStackAttacked*>(pack);
  655. CStack * at = curB->getStack(br->stackAttacked);
  656. at->amount = br->newAmount;
  657. at->firstHPleft = br->newHP;
  658. if(br->killed())
  659. at->state -= ALIVE;
  660. break;
  661. }
  662. case 3006:
  663. {
  664. BattleAttack *br = static_cast<BattleAttack*>(pack);
  665. CStack *attacker = curB->getStack(br->stackAttacking);
  666. if(br->counter())
  667. attacker->counterAttacks--;
  668. if(br->shot())
  669. attacker->shots--;
  670. applyNL(&br->bsa);
  671. break;
  672. }
  673. case 3009:
  674. {
  675. SpellCasted *sc = static_cast<SpellCasted*>(pack);
  676. CGHeroInstance *h = (sc->side) ? getHero(curB->hero2) : getHero(curB->hero1);
  677. if(h)
  678. h->mana -= VLC->spellh->spells[sc->id].costs[sc->skill];
  679. //TODO: counter
  680. break;
  681. }
  682. }
  683. }
  684. void CGameState::apply(IPack * pack)
  685. {
  686. while(!mx->try_lock())
  687. boost::this_thread::sleep(boost::posix_time::milliseconds(50)); //give other threads time to finish
  688. applyNL(pack);
  689. mx->unlock();
  690. }
  691. int CGameState::pickHero(int owner)
  692. {
  693. int h=-1;
  694. if(!map->getHero(h = scenarioOps->getIthPlayersSettings(owner).hero,0) && h>=0) //we haven't used selected hero
  695. return h;
  696. int f = scenarioOps->getIthPlayersSettings(owner).castle;
  697. int i=0;
  698. do //try to find free hero of our faction
  699. {
  700. i++;
  701. h = scenarioOps->getIthPlayersSettings(owner).castle*HEROES_PER_TYPE*2+(ran()%(HEROES_PER_TYPE*2));//->scenarioOps->playerInfos[pru].hero = VLC->
  702. } while( map->getHero(h) && i<175);
  703. if(i>174) //probably no free heroes - there's no point in further search, we'll take first free
  704. {
  705. tlog3 << "Warning: cannot find free hero - trying to get first available..."<<std::endl;
  706. for(int j=0; j<HEROES_PER_TYPE * 2 * F_NUMBER; j++)
  707. if(!map->getHero(j))
  708. h=j;
  709. }
  710. return h;
  711. }
  712. CGHeroInstance *CGameState::getHero(int objid)
  713. {
  714. if(objid<0 || objid>=map->objects.size())
  715. return NULL;
  716. return static_cast<CGHeroInstance *>(map->objects[objid]);
  717. }
  718. CGTownInstance *CGameState::getTown(int objid)
  719. {
  720. if(objid<0 || objid>=map->objects.size())
  721. return NULL;
  722. return static_cast<CGTownInstance *>(map->objects[objid]);
  723. }
  724. std::pair<int,int> CGameState::pickObject(CGObjectInstance *obj)
  725. {
  726. switch(obj->ID)
  727. {
  728. case 65: //random artifact
  729. return std::pair<int,int>(5,(ran()%136)+7); //tylko sensowny zakres - na poczatku sa katapulty itp, na koncu specjalne i blanki
  730. case 66: //random treasure artifact
  731. return std::pair<int,int>(5,VLC->arth->treasures[ran()%VLC->arth->treasures.size()]->id);
  732. case 67: //random minor artifact
  733. return std::pair<int,int>(5,VLC->arth->minors[ran()%VLC->arth->minors.size()]->id);
  734. case 68: //random major artifact
  735. return std::pair<int,int>(5,VLC->arth->majors[ran()%VLC->arth->majors.size()]->id);
  736. case 69: //random relic artifact
  737. return std::pair<int,int>(5,VLC->arth->relics[ran()%VLC->arth->relics.size()]->id);
  738. case 70: //random hero
  739. {
  740. return std::pair<int,int>(34,pickHero(obj->tempOwner));
  741. }
  742. case 71: //random monster
  743. {
  744. int r;
  745. do
  746. {
  747. r = ran()%197;
  748. } while (vstd::contains(VLC->creh->notUsedMonsters,r));
  749. return std::pair<int,int>(54,r);
  750. }
  751. case 72: //random monster lvl1
  752. return std::pair<int,int>(54,VLC->creh->levelCreatures[1][ran()%VLC->creh->levelCreatures[1].size()]->idNumber);
  753. case 73: //random monster lvl2
  754. return std::pair<int,int>(54,VLC->creh->levelCreatures[2][ran()%VLC->creh->levelCreatures[2].size()]->idNumber);
  755. case 74: //random monster lvl3
  756. return std::pair<int,int>(54,VLC->creh->levelCreatures[3][ran()%VLC->creh->levelCreatures[3].size()]->idNumber);
  757. case 75: //random monster lvl4
  758. return std::pair<int,int>(54,VLC->creh->levelCreatures[4][ran()%VLC->creh->levelCreatures[4].size()]->idNumber);
  759. case 76: //random resource
  760. return std::pair<int,int>(79,ran()%7); //now it's OH3 style, use %8 for mithril
  761. case 77: //random town
  762. {
  763. int align = ((CGTownInstance*)obj)->alignment,
  764. f;
  765. if(align>PLAYER_LIMIT-1)//same as owner / random
  766. {
  767. if(obj->tempOwner > PLAYER_LIMIT-1)
  768. f = -1; //random
  769. else
  770. f = scenarioOps->getIthPlayersSettings(obj->tempOwner).castle;
  771. }
  772. else
  773. {
  774. f = scenarioOps->getIthPlayersSettings(align).castle;
  775. }
  776. if(f<0) f = ran()%VLC->townh->towns.size();
  777. return std::pair<int,int>(98,f);
  778. }
  779. case 162: //random monster lvl5
  780. return std::pair<int,int>(54,VLC->creh->levelCreatures[5][ran()%VLC->creh->levelCreatures[5].size()]->idNumber);
  781. case 163: //random monster lvl6
  782. return std::pair<int,int>(54,VLC->creh->levelCreatures[6][ran()%VLC->creh->levelCreatures[6].size()]->idNumber);
  783. case 164: //random monster lvl7
  784. return std::pair<int,int>(54,VLC->creh->levelCreatures[7][ran()%VLC->creh->levelCreatures[7].size()]->idNumber);
  785. case 216: //random dwelling
  786. {
  787. int faction = ran()%F_NUMBER;
  788. CCreGen2ObjInfo* info =(CCreGen2ObjInfo*)obj->info;
  789. if (info->asCastle)
  790. {
  791. for(int i=0;i<map->objects.size();i++)
  792. {
  793. if(map->objects[i]->ID==77 && dynamic_cast<CGTownInstance*>(map->objects[i])->identifier == info->identifier)
  794. {
  795. randomizeObject(map->objects[i]); //we have to randomize the castle first
  796. faction = map->objects[i]->subID;
  797. break;
  798. }
  799. else if(map->objects[i]->ID==98 && dynamic_cast<CGTownInstance*>(map->objects[i])->identifier == info->identifier)
  800. {
  801. faction = map->objects[i]->subID;
  802. break;
  803. }
  804. }
  805. }
  806. else
  807. {
  808. while((!(info->castles[0]&(1<<faction))))
  809. {
  810. if((faction>7) && (info->castles[1]&(1<<(faction-8))))
  811. break;
  812. faction = ran()%F_NUMBER;
  813. }
  814. }
  815. int level = ((info->maxLevel-info->minLevel) ? (ran()%(info->maxLevel-info->minLevel)+info->minLevel) : (info->minLevel));
  816. int cid = VLC->townh->towns[faction].basicCreatures[level];
  817. for(int i=0;i<VLC->objh->cregens.size();i++)
  818. if(VLC->objh->cregens[i]==cid)
  819. return std::pair<int,int>(17,i);
  820. tlog3 << "Cannot find a dwelling for creature "<<cid <<std::endl;
  821. return std::pair<int,int>(17,0);
  822. }
  823. case 217:
  824. {
  825. int faction = ran()%F_NUMBER;
  826. CCreGenObjInfo* info =(CCreGenObjInfo*)obj->info;
  827. if (info->asCastle)
  828. {
  829. for(int i=0;i<map->objects.size();i++)
  830. {
  831. if(map->objects[i]->ID==77 && dynamic_cast<CGTownInstance*>(map->objects[i])->identifier == info->identifier)
  832. {
  833. randomizeObject(map->objects[i]); //we have to randomize the castle first
  834. faction = map->objects[i]->subID;
  835. break;
  836. }
  837. else if(map->objects[i]->ID==98 && dynamic_cast<CGTownInstance*>(map->objects[i])->identifier == info->identifier)
  838. {
  839. faction = map->objects[i]->subID;
  840. break;
  841. }
  842. }
  843. }
  844. else
  845. {
  846. while((!(info->castles[0]&(1<<faction))))
  847. {
  848. if((faction>7) && (info->castles[1]&(1<<(faction-8))))
  849. break;
  850. faction = ran()%F_NUMBER;
  851. }
  852. }
  853. int cid = VLC->townh->towns[faction].basicCreatures[obj->subID];
  854. for(int i=0;i<VLC->objh->cregens.size();i++)
  855. if(VLC->objh->cregens[i]==cid)
  856. return std::pair<int,int>(17,i);
  857. tlog3 << "Cannot find a dwelling for creature "<<cid <<std::endl;
  858. return std::pair<int,int>(17,0);
  859. }
  860. case 218:
  861. {
  862. CCreGen3ObjInfo* info =(CCreGen3ObjInfo*)obj->info;
  863. int level = ((info->maxLevel-info->minLevel) ? (ran()%(info->maxLevel-info->minLevel)+info->minLevel) : (info->minLevel));
  864. int cid = VLC->townh->towns[obj->subID].basicCreatures[level];
  865. for(int i=0;i<VLC->objh->cregens.size();i++)
  866. if(VLC->objh->cregens[i]==cid)
  867. return std::pair<int,int>(17,i);
  868. tlog3 << "Cannot find a dwelling for creature "<<cid <<std::endl;
  869. return std::pair<int,int>(17,0);
  870. }
  871. }
  872. return std::pair<int,int>(-1,-1);
  873. }
  874. void CGameState::randomizeObject(CGObjectInstance *cur)
  875. {
  876. std::pair<int,int> ran = pickObject(cur);
  877. if(ran.first<0 || ran.second<0) //this is not a random object, or we couldn't find anything
  878. {
  879. if(cur->ID==98) //town - set def
  880. {
  881. CGTownInstance *t = dynamic_cast<CGTownInstance*>(cur);
  882. if(t->hasCapitol())
  883. t->defInfo = capitols[t->subID];
  884. else if(t->hasFort())
  885. t->defInfo = forts[t->subID];
  886. else
  887. t->defInfo = villages[t->subID];
  888. }
  889. return;
  890. }
  891. else if(ran.first==34)//special code for hero
  892. {
  893. CGHeroInstance *h = dynamic_cast<CGHeroInstance *>(cur);
  894. if(!h) {tlog2<<"Wrong random hero at "<<cur->pos<<std::endl; return;}
  895. cur->ID = ran.first;
  896. h->portrait = cur->subID = ran.second;
  897. h->type = VLC->heroh->heroes[ran.second];
  898. map->heroes.push_back(h);
  899. return; //TODO: maybe we should do something with definfo?
  900. }
  901. else if(ran.first==98)//special code for town
  902. {
  903. CGTownInstance *t = dynamic_cast<CGTownInstance*>(cur);
  904. if(!t) {tlog2<<"Wrong random town at "<<cur->pos<<std::endl; return;}
  905. cur->ID = ran.first;
  906. cur->subID = ran.second;
  907. t->town = &VLC->townh->towns[ran.second];
  908. if(t->hasCapitol())
  909. t->defInfo = capitols[t->subID];
  910. else if(t->hasFort())
  911. t->defInfo = forts[t->subID];
  912. else
  913. t->defInfo = villages[t->subID];
  914. map->towns.push_back(t);
  915. return;
  916. }
  917. //we have to replace normal random object
  918. cur->ID = ran.first;
  919. cur->subID = ran.second;
  920. map->defs.insert(cur->defInfo = VLC->dobjinfo->gobjs[ran.first][ran.second]);
  921. if(!cur->defInfo)
  922. {
  923. tlog1<<"*BIG* WARNING: Missing def declaration for "<<cur->ID<<" "<<cur->subID<<std::endl;
  924. return;
  925. }
  926. }
  927. int CGameState::getDate(int mode) const
  928. {
  929. int temp;
  930. switch (mode)
  931. {
  932. case 0:
  933. return day;
  934. break;
  935. case 1:
  936. temp = (day)%7;
  937. if (temp)
  938. return temp;
  939. else return 7;
  940. break;
  941. case 2:
  942. temp = ((day-1)/7)+1;
  943. if (!(temp%4))
  944. return 4;
  945. else
  946. return (temp%4);
  947. break;
  948. case 3:
  949. return ((day-1)/28)+1;
  950. break;
  951. }
  952. return 0;
  953. }
  954. CGameState::CGameState()
  955. {
  956. mx = new boost::shared_mutex();
  957. }
  958. CGameState::~CGameState()
  959. {
  960. delete mx;
  961. }
  962. void CGameState::init(StartInfo * si, Mapa * map, int Seed)
  963. {
  964. day = 0;
  965. seed = Seed;
  966. ran.seed((boost::int32_t)seed);
  967. scenarioOps = si;
  968. this->map = map;
  969. for(int i=0;i<F_NUMBER;i++)
  970. {
  971. villages[i] = new CGDefInfo(*VLC->dobjinfo->castles[i]);
  972. forts[i] = VLC->dobjinfo->castles[i];
  973. capitols[i] = new CGDefInfo(*VLC->dobjinfo->castles[i]);
  974. }
  975. //picking random factions for players
  976. for(int i=0;i<scenarioOps->playerInfos.size();i++)
  977. {
  978. if(scenarioOps->playerInfos[i].castle==-1)
  979. {
  980. int f;
  981. do
  982. {
  983. f = ran()%F_NUMBER;
  984. }while(!(map->players[scenarioOps->playerInfos[i].color].allowedFactions & 1<<f));
  985. scenarioOps->playerInfos[i].castle = f;
  986. }
  987. }
  988. //randomizing objects
  989. for(int no=0; no<map->objects.size(); ++no)
  990. {
  991. randomizeObject(map->objects[no]);
  992. if(map->objects[no]->ID==26)
  993. {
  994. map->objects[no]->defInfo->handler=NULL;
  995. map->removeBlockVisTiles(map->objects[no]);
  996. map->objects[no]->defInfo->blockMap[5] = 255;
  997. map->addBlockVisTiles(map->objects[no]);
  998. }
  999. map->objects[no]->hoverName = VLC->objh->names[map->objects[no]->ID];
  1000. }
  1001. //std::cout<<"\tRandomizing objects: "<<th.getDif()<<std::endl;
  1002. /*********give starting hero****************************************/
  1003. for(int i=0;i<PLAYER_LIMIT;i++)
  1004. {
  1005. if((map->players[i].generateHeroAtMainTown && map->players[i].hasMainTown) || (map->players[i].hasMainTown && map->version==RoE))
  1006. {
  1007. int3 hpos = map->players[i].posOfMainTown;
  1008. hpos.x+=1;// hpos.y+=1;
  1009. int j;
  1010. for(j=0; j<scenarioOps->playerInfos.size(); j++)
  1011. if(scenarioOps->playerInfos[j].color == i)
  1012. break;
  1013. if(j == scenarioOps->playerInfos.size())
  1014. continue;
  1015. int h=pickHero(i);
  1016. CGHeroInstance * nnn = static_cast<CGHeroInstance*>(createObject(34,h,hpos,i));
  1017. nnn->id = map->objects.size();
  1018. hpos = map->players[i].posOfMainTown;hpos.x+=2;
  1019. for(int o=0;o<map->towns.size();o++) //find main town
  1020. {
  1021. if(map->towns[o]->pos == hpos)
  1022. {
  1023. map->towns[o]->visitingHero = nnn;
  1024. nnn->visitedTown = map->towns[o];
  1025. nnn->inTownGarrison = false;
  1026. break;
  1027. }
  1028. }
  1029. nnn->initHero();
  1030. map->heroes.push_back(nnn);
  1031. map->objects.push_back(nnn);
  1032. map->addBlockVisTiles(nnn);
  1033. }
  1034. }
  1035. /*********creating players entries in gs****************************************/
  1036. for (int i=0; i<scenarioOps->playerInfos.size();i++)
  1037. {
  1038. std::pair<int,PlayerState> ins(scenarioOps->playerInfos[i].color,PlayerState());
  1039. ins.second.color=ins.first;
  1040. ins.second.serial=i;
  1041. players.insert(ins);
  1042. }
  1043. /******************RESOURCES****************************************************/
  1044. //TODO: computer player should receive other amount of resource than computer (depending on difficulty)
  1045. std::vector<int> startres;
  1046. std::ifstream tis("config/startres.txt");
  1047. int k;
  1048. for (int j=0;j<scenarioOps->difficulty;j++)
  1049. {
  1050. tis >> k;
  1051. for (int z=0;z<RESOURCE_QUANTITY;z++)
  1052. tis>>k;
  1053. }
  1054. tis >> k;
  1055. for (int i=0;i<RESOURCE_QUANTITY;i++)
  1056. {
  1057. tis >> k;
  1058. startres.push_back(k);
  1059. }
  1060. tis.close();
  1061. tis.clear();
  1062. for (std::map<ui8,PlayerState>::iterator i = players.begin(); i!=players.end(); i++)
  1063. {
  1064. (*i).second.resources.resize(RESOURCE_QUANTITY);
  1065. for (int x=0;x<RESOURCE_QUANTITY;x++)
  1066. (*i).second.resources[x] = startres[x];
  1067. }
  1068. tis.open("config/resources.txt");
  1069. tis >> k;
  1070. int pom;
  1071. for(int i=0;i<k;i++)
  1072. {
  1073. tis >> pom;
  1074. resVals.push_back(pom);
  1075. }
  1076. /*************************HEROES************************************************/
  1077. std::set<int> hids;
  1078. for(int i=0; i<map->allowedHeroes.size(); i++) //add to hids all allowed heroes
  1079. if(map->allowedHeroes[i])
  1080. hids.insert(i);
  1081. for (int i=0; i<map->heroes.size();i++) //heroes instances
  1082. {
  1083. if (map->heroes[i]->getOwner()<0)
  1084. {
  1085. tlog2 << "Warning - hero with uninitialized owner!\n";
  1086. continue;
  1087. }
  1088. CGHeroInstance * vhi = (map->heroes[i]);
  1089. vhi->initHero();
  1090. players[vhi->getOwner()].heroes.push_back(vhi);
  1091. hids.erase(vhi->subID);
  1092. }
  1093. for(int i=0; i<map->predefinedHeroes.size(); i++)
  1094. {
  1095. if(!vstd::contains(hids,map->predefinedHeroes[i]->subID))
  1096. continue;
  1097. map->predefinedHeroes[i]->initHero();
  1098. hpool.heroesPool[map->predefinedHeroes[i]->subID] = map->predefinedHeroes[i];
  1099. hpool.pavailable[map->predefinedHeroes[i]->subID] = 0xff;
  1100. hids.erase(map->predefinedHeroes[i]->subID);
  1101. }
  1102. BOOST_FOREACH(int hid, hids) //all not used allowed heroes go into the pool
  1103. {
  1104. CGHeroInstance * vhi = new CGHeroInstance();
  1105. vhi->initHero(hid);
  1106. hpool.heroesPool[hid] = vhi;
  1107. hpool.pavailable[hid] = 0xff;
  1108. }
  1109. for(int i=0; i<map->disposedHeroes.size(); i++)
  1110. {
  1111. hpool.pavailable[map->disposedHeroes[i].ID] = map->disposedHeroes[i].players;
  1112. }
  1113. /*************************FOG**OF**WAR******************************************/
  1114. for(std::map<ui8, PlayerState>::iterator k=players.begin(); k!=players.end(); ++k)
  1115. {
  1116. k->second.fogOfWarMap.resize(map->width);
  1117. for(int g=0; g<map->width; ++g)
  1118. k->second.fogOfWarMap[g].resize(map->height);
  1119. for(int g=-0; g<map->width; ++g)
  1120. for(int h=0; h<map->height; ++h)
  1121. k->second.fogOfWarMap[g][h].resize(map->twoLevel+1, 0);
  1122. for(int g=0; g<map->width; ++g)
  1123. for(int h=0; h<map->height; ++h)
  1124. for(int v=0; v<map->twoLevel+1; ++v)
  1125. k->second.fogOfWarMap[g][h][v] = 0;
  1126. for(int xd=0; xd<map->width; ++xd) //revealing part of map around heroes
  1127. {
  1128. for(int yd=0; yd<map->height; ++yd)
  1129. {
  1130. for(int ch=0; ch<k->second.heroes.size(); ++ch)
  1131. {
  1132. int deltaX = (k->second.heroes[ch]->getPosition(false).x-xd)*(k->second.heroes[ch]->getPosition(false).x-xd);
  1133. int deltaY = (k->second.heroes[ch]->getPosition(false).y-yd)*(k->second.heroes[ch]->getPosition(false).y-yd);
  1134. if(deltaX+deltaY<k->second.heroes[ch]->getSightDistance()*k->second.heroes[ch]->getSightDistance())
  1135. k->second.fogOfWarMap[xd][yd][k->second.heroes[ch]->getPosition(false).z] = 1;
  1136. }
  1137. }
  1138. }
  1139. //starting bonus
  1140. if(si->playerInfos[k->second.serial].bonus==brandom)
  1141. si->playerInfos[k->second.serial].bonus = ran()%3;
  1142. switch(si->playerInfos[k->second.serial].bonus)
  1143. {
  1144. case bgold:
  1145. k->second.resources[6] += 500 + (ran()%6)*100;
  1146. break;
  1147. case bresource:
  1148. {
  1149. int res = VLC->townh->towns[si->playerInfos[k->second.serial].castle].primaryRes;
  1150. if(res == 127)
  1151. {
  1152. k->second.resources[0] += 5 + ran()%6;
  1153. k->second.resources[2] += 5 + ran()%6;
  1154. }
  1155. else
  1156. {
  1157. k->second.resources[res] += 3 + ran()%4;
  1158. }
  1159. break;
  1160. }
  1161. case bartifact:
  1162. {
  1163. if(!k->second.heroes.size())
  1164. {
  1165. tlog5 << "Cannot give starting artifact - no heroes!" << std::endl;
  1166. break;
  1167. }
  1168. CArtifact *toGive;
  1169. do
  1170. {
  1171. toGive = VLC->arth->treasures[ran() % VLC->arth->treasures.size()];
  1172. } while (!map->allowedArtifact[toGive->id]);
  1173. CGHeroInstance *hero = k->second.heroes[0];
  1174. std::vector<ui16>::iterator slot = vstd::findFirstNot(hero->artifWorn,toGive->possibleSlots);
  1175. if(slot!=toGive->possibleSlots.end())
  1176. hero->artifWorn[*slot] = toGive->id;
  1177. else
  1178. hero->artifacts.push_back(toGive->id);
  1179. }
  1180. }
  1181. }
  1182. /****************************TOWNS************************************************/
  1183. for (int i=0;i<map->towns.size();i++)
  1184. {
  1185. CGTownInstance * vti =(map->towns[i]);
  1186. if(!vti->town)
  1187. vti->town = &VLC->townh->towns[vti->subID];
  1188. if (vti->name.length()==0) // if town hasn't name we draw it
  1189. vti->name=vti->town->names[ran()%vti->town->names.size()];
  1190. //init buildings
  1191. if(vti->builtBuildings.find(-50)!=vti->builtBuildings.end()) //give standard set of buildings
  1192. {
  1193. vti->builtBuildings.erase(-50);
  1194. vti->builtBuildings.insert(10);
  1195. vti->builtBuildings.insert(5);
  1196. vti->builtBuildings.insert(30);
  1197. if(ran()%2)
  1198. vti->builtBuildings.insert(31);
  1199. }
  1200. //init spells
  1201. vti->spells.resize(SPELL_LEVELS);
  1202. CSpell *s;
  1203. for(int z=0; z<vti->obligatorySpells.size();z++)
  1204. {
  1205. s = &VLC->spellh->spells[vti->obligatorySpells[z]];
  1206. vti->spells[s->level-1].push_back(s->id);
  1207. vti->possibleSpells -= s->id;
  1208. }
  1209. while(vti->possibleSpells.size())
  1210. {
  1211. ui32 total=0, sel=-1;
  1212. for(int ps=0;ps<vti->possibleSpells.size();ps++)
  1213. total += VLC->spellh->spells[vti->possibleSpells[ps]].probabilities[vti->subID];
  1214. int r = (total)? ran()%total : -1;
  1215. for(int ps=0; ps<vti->possibleSpells.size();ps++)
  1216. {
  1217. r -= VLC->spellh->spells[vti->possibleSpells[ps]].probabilities[vti->subID];
  1218. if(r<0)
  1219. {
  1220. sel = ps;
  1221. break;
  1222. }
  1223. }
  1224. if(sel<0)
  1225. sel=0;
  1226. CSpell *s = &VLC->spellh->spells[vti->possibleSpells[sel]];
  1227. vti->spells[s->level-1].push_back(s->id);
  1228. vti->possibleSpells -= s->id;
  1229. }
  1230. //init garrisons
  1231. for (std::map<si32,std::pair<ui32,si32> >::iterator j=vti->army.slots.begin(); j!=vti->army.slots.end();j++)
  1232. {
  1233. if(j->second.first > 196 && j->second.first < 211)
  1234. {
  1235. if(j->second.first%2)
  1236. j->second.first = vti->town->basicCreatures[ (j->second.first-197) / 2 ];
  1237. else
  1238. j->second.first = vti->town->upgradedCreatures[ (j->second.first-197) / 2 ];
  1239. }
  1240. }
  1241. players[vti->getOwner()].towns.push_back(vti);
  1242. }
  1243. for(std::map<ui8, PlayerState>::iterator k=players.begin(); k!=players.end(); ++k)
  1244. {
  1245. if(k->first==-1 || k->first==255)
  1246. continue;
  1247. for(int xd=0; xd<map->width; ++xd) //revealing part of map around towns
  1248. {
  1249. for(int yd=0; yd<map->height; ++yd)
  1250. {
  1251. for(int ch=0; ch<k->second.towns.size(); ++ch)
  1252. {
  1253. int deltaX = (k->second.towns[ch]->pos.x-xd)*(k->second.towns[ch]->pos.x-xd);
  1254. int deltaY = (k->second.towns[ch]->pos.y-yd)*(k->second.towns[ch]->pos.y-yd);
  1255. if(deltaX+deltaY<k->second.towns[ch]->getSightDistance()*k->second.towns[ch]->getSightDistance())
  1256. k->second.fogOfWarMap[xd][yd][k->second.towns[ch]->pos.z] = 1;
  1257. }
  1258. }
  1259. }
  1260. //init visiting and garrisoned heroes
  1261. for(int l=0; l<k->second.heroes.size();l++)
  1262. {
  1263. for(int m=0; m<k->second.towns.size();m++)
  1264. {
  1265. int3 vistile = k->second.towns[m]->pos; vistile.x--; //tile next to the entrance
  1266. if(vistile == k->second.heroes[l]->pos || k->second.heroes[l]->pos==k->second.towns[m]->pos)
  1267. {
  1268. k->second.towns[m]->visitingHero = k->second.heroes[l];
  1269. k->second.heroes[l]->visitedTown = k->second.towns[m];
  1270. k->second.heroes[l]->inTownGarrison = false;
  1271. if(k->second.heroes[l]->pos==k->second.towns[m]->pos)
  1272. k->second.heroes[l]->pos.x -= 1;
  1273. break;
  1274. }
  1275. //else if(k->second.heroes[l]->pos == k->second.towns[m]->pos)
  1276. //{
  1277. // k->second.towns[m]->garrisonHero = k->second.heroes[l];
  1278. // k->second.towns[m]->army = k->second.heroes[l]->army;
  1279. // k->second.heroes[l]->visitedTown = k->second.towns[m];
  1280. // k->second.heroes[l]->inTownGarrison = true;
  1281. // k->second.heroes[l]->pos.x -= 1;
  1282. // goto mainplheloop;
  1283. //}
  1284. }
  1285. }
  1286. }
  1287. }
  1288. bool CGameState::battleShootCreatureStack(int ID, int dest)
  1289. {
  1290. return true;
  1291. }
  1292. int CGameState::battleGetStack(int pos)
  1293. {
  1294. if(!curB)
  1295. return -1;
  1296. for(int g=0; g<curB->stacks.size(); ++g)
  1297. {
  1298. if(curB->stacks[g]->position == pos ||
  1299. ( curB->stacks[g]->creature->isDoubleWide() &&
  1300. ( (curB->stacks[g]->attackerOwned && curB->stacks[g]->position-1 == pos) ||
  1301. (!curB->stacks[g]->attackerOwned && curB->stacks[g]->position+1 == pos)
  1302. )
  1303. )
  1304. )
  1305. return curB->stacks[g]->ID;
  1306. }
  1307. return -1;
  1308. }
  1309. UpgradeInfo CGameState::getUpgradeInfo(CArmedInstance *obj, int stackPos)
  1310. {
  1311. UpgradeInfo ret;
  1312. CCreature *base = &VLC->creh->creatures[obj->army.slots[stackPos].first];
  1313. if((obj->ID == 98) || ((obj->ID == 34) && static_cast<const CGHeroInstance*>(obj)->visitedTown))
  1314. {
  1315. CGTownInstance * t;
  1316. if(obj->ID == 98)
  1317. t = static_cast<CGTownInstance *>(const_cast<CArmedInstance *>(obj));
  1318. else
  1319. t = static_cast<const CGHeroInstance*>(obj)->visitedTown;
  1320. for(std::set<si32>::iterator i=t->builtBuildings.begin(); i!=t->builtBuildings.end(); i++)
  1321. {
  1322. if( (*i) >= 37 && (*i) < 44 ) //upgraded creature dwelling
  1323. {
  1324. int nid = t->town->upgradedCreatures[(*i)-37]; //upgrade offered by that building
  1325. if(base->upgrades.find(nid) != base->upgrades.end()) //possible upgrade
  1326. {
  1327. ret.newID.push_back(nid);
  1328. ret.cost.push_back(std::set<std::pair<int,int> >());
  1329. for(int j=0;j<RESOURCE_QUANTITY;j++)
  1330. {
  1331. int dif = VLC->creh->creatures[nid].cost[j] - base->cost[j];
  1332. if(dif)
  1333. ret.cost[ret.cost.size()-1].insert(std::make_pair(j,dif));
  1334. }
  1335. }
  1336. }
  1337. }//end for
  1338. }
  1339. //TODO: check if hero ability makes some upgrades possible
  1340. if(ret.newID.size())
  1341. ret.oldID = base->idNumber;
  1342. return ret;
  1343. }
  1344. float CGameState::getMarketEfficiency( int player, int mode/*=0*/ )
  1345. {
  1346. boost::shared_lock<boost::shared_mutex> lock(*mx);
  1347. if(mode) return -1; //todo - support other modes
  1348. int mcount = 0;
  1349. for(int i=0;i<players[player].towns.size();i++)
  1350. if(vstd::contains(players[player].towns[i]->builtBuildings,14))
  1351. mcount++;
  1352. float ret = std::min(((float)mcount+1.0f)/20.0f,0.5f);
  1353. return ret;
  1354. }
  1355. std::set<int3> CGameState::tilesToReveal(int3 pos, int radious, int player)
  1356. {
  1357. std::set<int3> ret;
  1358. int xbeg = pos.x - radious - 2;
  1359. if(xbeg < 0)
  1360. xbeg = 0;
  1361. int xend = pos.x + radious + 2;
  1362. if(xend >= map->width)
  1363. xend = map->width;
  1364. int ybeg = pos.y - radious - 2;
  1365. if(ybeg < 0)
  1366. ybeg = 0;
  1367. int yend = pos.y + radious + 2;
  1368. if(yend >= map->height)
  1369. yend = map->height;
  1370. for(int xd=xbeg; xd<xend; ++xd) //revealing part of map around heroes
  1371. {
  1372. for(int yd=ybeg; yd<yend; ++yd)
  1373. {
  1374. int deltaX = (pos.x-xd)*(pos.x-xd);
  1375. int deltaY = (pos.y-yd)*(pos.y-yd);
  1376. if(deltaX+deltaY<radious*radious)
  1377. {
  1378. if(player<0 || players[player].fogOfWarMap[xd][yd][pos.z]==0)
  1379. {
  1380. ret.insert(int3(xd,yd,pos.z));
  1381. }
  1382. }
  1383. }
  1384. }
  1385. return ret;
  1386. }
  1387. int BattleInfo::calculateDmg(const CStack* attacker, const CStack* defender, const CGHeroInstance * attackerHero, const CGHeroInstance * defendingHero, bool shooting)
  1388. {
  1389. int attackDefenseBonus = attacker->creature->attack + (attackerHero ? attackerHero->getPrimSkillLevel(0) : 0) - (defender->creature->defence + (defendingHero ? defendingHero->getPrimSkillLevel(1) : 0));
  1390. int damageBase = 0;
  1391. if(attacker->creature->damageMax == attacker->creature->damageMin) //constant damage
  1392. {
  1393. damageBase = attacker->creature->damageMin;
  1394. }
  1395. else
  1396. {
  1397. damageBase = rand()%(attacker->creature->damageMax - attacker->creature->damageMin) + attacker->creature->damageMin + 1;
  1398. }
  1399. float dmgBonusMultiplier = 1.0f;
  1400. if(attackDefenseBonus < 0) //decreasing dmg
  1401. {
  1402. if(0.02f * (-attackDefenseBonus) > 0.3f)
  1403. {
  1404. dmgBonusMultiplier += -0.3f;
  1405. }
  1406. else
  1407. {
  1408. dmgBonusMultiplier += 0.02f * attackDefenseBonus;
  1409. }
  1410. }
  1411. else //increasing dmg
  1412. {
  1413. if(0.05f * attackDefenseBonus > 4.0f)
  1414. {
  1415. dmgBonusMultiplier += 4.0f;
  1416. }
  1417. else
  1418. {
  1419. dmgBonusMultiplier += 0.05f * attackDefenseBonus;
  1420. }
  1421. }
  1422. //handling secondary abilities
  1423. if(attackerHero)
  1424. {
  1425. if(shooting)
  1426. {
  1427. switch(attackerHero->getSecSkillLevel(1)) //archery
  1428. {
  1429. case 1: //basic
  1430. dmgBonusMultiplier *= 1.1f;
  1431. break;
  1432. case 2: //advanced
  1433. dmgBonusMultiplier *= 1.25f;
  1434. break;
  1435. case 3: //expert
  1436. dmgBonusMultiplier *= 1.5f;
  1437. break;
  1438. }
  1439. }
  1440. else
  1441. {
  1442. switch(attackerHero->getSecSkillLevel(22)) //offence
  1443. {
  1444. case 1: //basic
  1445. dmgBonusMultiplier *= 1.1f;
  1446. break;
  1447. case 2: //advanced
  1448. dmgBonusMultiplier *= 1.2f;
  1449. break;
  1450. case 3: //expert
  1451. dmgBonusMultiplier *= 1.3f;
  1452. break;
  1453. }
  1454. }
  1455. }
  1456. if(defendingHero)
  1457. {
  1458. switch(defendingHero->getSecSkillLevel(23)) //armourer
  1459. {
  1460. case 1: //basic
  1461. dmgBonusMultiplier *= 0.95f;
  1462. break;
  1463. case 2: //advanced
  1464. dmgBonusMultiplier *= 0.9f;
  1465. break;
  1466. case 3: //expert
  1467. dmgBonusMultiplier *= 0.85f;
  1468. break;
  1469. }
  1470. }
  1471. return (float)damageBase * (float)attacker->amount * dmgBonusMultiplier;
  1472. }
  1473. void BattleInfo::calculateCasualties( std::set<std::pair<ui32,si32> > *casualties )
  1474. {
  1475. for(int i=0; i<stacks.size();i++)//setting casualties
  1476. {
  1477. if(!stacks[i]->alive())
  1478. {
  1479. casualties[!stacks[i]->attackerOwned].insert(std::pair<ui32,si32>(stacks[i]->creature->idNumber,stacks[i]->baseAmount));
  1480. }
  1481. else if(stacks[i]->amount != stacks[i]->baseAmount)
  1482. {
  1483. casualties[!stacks[i]->attackerOwned].insert(std::pair<ui32,si32>(stacks[i]->creature->idNumber,stacks[i]->baseAmount - stacks[i]->amount));
  1484. }
  1485. }
  1486. }