NetPacksLib.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573
  1. #define VCMI_DLL
  2. #include "../lib/NetPacks.h"
  3. #include "../hch/CGeneralTextHandler.h"
  4. #include "../hch/CDefObjInfoHandler.h"
  5. #include "../hch/CArtHandler.h"
  6. #include "../hch/CHeroHandler.h"
  7. #include "../hch/CObjectHandler.h"
  8. #include "../lib/VCMI_Lib.h"
  9. #include "../map.h"
  10. #include "../hch/CSpellHandler.h"
  11. #include <boost/bind.hpp>
  12. #include <boost/foreach.hpp>
  13. #include <boost/thread.hpp>
  14. #include <boost/thread/shared_mutex.hpp>
  15. /*
  16. * NetPacksLib.cpp, part of VCMI engine
  17. *
  18. * Authors: listed in file AUTHORS in main folder
  19. *
  20. * License: GNU General Public License v2.0 or later
  21. * Full text of license available in license.txt file, in main folder
  22. *
  23. */
  24. DLL_EXPORT void SetResource::applyGs( CGameState *gs )
  25. {
  26. gs->getPlayer(player)->resources[resid] = val;
  27. }
  28. DLL_EXPORT void SetResources::applyGs( CGameState *gs )
  29. {
  30. for(int i=0;i<res.size();i++)
  31. gs->getPlayer(player)->resources[i] = res[i];
  32. }
  33. DLL_EXPORT void SetPrimSkill::applyGs( CGameState *gs )
  34. {
  35. CGHeroInstance *hero = gs->getHero(id);
  36. if(which <4)
  37. {
  38. if(abs)
  39. hero->primSkills[which] = val;
  40. else
  41. hero->primSkills[which] += val;
  42. }
  43. else if(which == 4) //XP
  44. {
  45. if(abs)
  46. hero->exp = val;
  47. else
  48. hero->exp += val;
  49. }
  50. }
  51. DLL_EXPORT void SetSecSkill::applyGs( CGameState *gs )
  52. {
  53. CGHeroInstance *hero = gs->getHero(id);
  54. if(hero->getSecSkillLevel(which) == 0)
  55. {
  56. hero->secSkills.push_back(std::pair<int,int>(which, val));
  57. }
  58. else
  59. {
  60. for(unsigned i=0;i<hero->secSkills.size();i++)
  61. {
  62. if(hero->secSkills[i].first == which)
  63. {
  64. if(abs)
  65. hero->secSkills[i].second = val;
  66. else
  67. hero->secSkills[i].second += val;
  68. }
  69. }
  70. }
  71. }
  72. DLL_EXPORT void HeroVisitCastle::applyGs( CGameState *gs )
  73. {
  74. CGHeroInstance *h = gs->getHero(hid);
  75. CGTownInstance *t = gs->getTown(tid);
  76. if(start())
  77. {
  78. if(garrison())
  79. {
  80. t->garrisonHero = h;
  81. h->visitedTown = t;
  82. h->inTownGarrison = true;
  83. }
  84. else
  85. {
  86. t->visitingHero = h;
  87. h->visitedTown = t;
  88. h->inTownGarrison = false;
  89. }
  90. }
  91. else
  92. {
  93. if(garrison())
  94. {
  95. t->garrisonHero = NULL;
  96. h->visitedTown = NULL;
  97. h->inTownGarrison = false;
  98. }
  99. else
  100. {
  101. t->visitingHero = NULL;
  102. h->visitedTown = NULL;
  103. h->inTownGarrison = false;
  104. }
  105. }
  106. }
  107. DLL_EXPORT void ChangeSpells::applyGs( CGameState *gs )
  108. {
  109. CGHeroInstance *hero = gs->getHero(hid);
  110. if(learn)
  111. BOOST_FOREACH(ui32 sid, spells)
  112. hero->spells.insert(sid);
  113. else
  114. BOOST_FOREACH(ui32 sid, spells)
  115. hero->spells.erase(sid);
  116. }
  117. DLL_EXPORT void SetMana::applyGs( CGameState *gs )
  118. {
  119. CGHeroInstance *hero = gs->getHero(hid);
  120. hero->mana = val;
  121. }
  122. DLL_EXPORT void SetMovePoints::applyGs( CGameState *gs )
  123. {
  124. CGHeroInstance *hero = gs->getHero(hid);
  125. hero->movement = val;
  126. }
  127. DLL_EXPORT void FoWChange::applyGs( CGameState *gs )
  128. {
  129. BOOST_FOREACH(int3 t, tiles)
  130. gs->getPlayer(player)->fogOfWarMap[t.x][t.y][t.z] = mode;
  131. }
  132. DLL_EXPORT void SetAvailableHeroes::applyGs( CGameState *gs )
  133. {
  134. gs->getPlayer(player)->availableHeroes.clear();
  135. CGHeroInstance *h = (hid1>=0 ? gs->hpool.heroesPool[hid1] : NULL);
  136. gs->getPlayer(player)->availableHeroes.push_back(h);
  137. if(h && flags & 1)
  138. {
  139. h->army.slots.clear();
  140. h->army.slots[0] = std::pair<ui32,si32>(VLC->creh->nameToID[h->type->refTypeStack[0]],1);
  141. }
  142. h = (hid2>=0 ? gs->hpool.heroesPool[hid2] : NULL);
  143. gs->getPlayer(player)->availableHeroes.push_back(h);
  144. if(flags & 2)
  145. {
  146. h->army.slots.clear();
  147. h->army.slots[0] = std::pair<ui32,si32>(VLC->creh->nameToID[h->type->refTypeStack[0]],1);
  148. }
  149. }
  150. DLL_EXPORT void GiveBonus::applyGs( CGameState *gs )
  151. {
  152. CGHeroInstance *h = gs->getHero(hid);
  153. h->bonuses.push_back(bonus);
  154. h->bonuses.back().description = toString(bdescr);
  155. }
  156. DLL_EXPORT void ChangeObjPos::applyGs( CGameState *gs )
  157. {
  158. CGObjectInstance *obj = gs->map->objects[objid];
  159. if(!obj)
  160. {
  161. tlog1 << "Wrong ChangeObjPos: object " << objid << " doesn't exist!\n";
  162. return;
  163. }
  164. gs->map->removeBlockVisTiles(obj);
  165. obj->pos = nPos;
  166. gs->map->addBlockVisTiles(obj);
  167. }
  168. DLL_EXPORT void RemoveObject::applyGs( CGameState *gs )
  169. {
  170. CGObjectInstance *obj = gs->map->objects[id];
  171. if(obj->ID==HEROI_TYPE)
  172. {
  173. CGHeroInstance *h = static_cast<CGHeroInstance*>(obj);
  174. std::vector<CGHeroInstance*>::iterator nitr = std::find(gs->map->heroes.begin(), gs->map->heroes.end(),h);
  175. gs->map->heroes.erase(nitr);
  176. int player = h->tempOwner;
  177. nitr = std::find(gs->getPlayer(player)->heroes.begin(), gs->getPlayer(player)->heroes.end(), h);
  178. gs->getPlayer(player)->heroes.erase(nitr);
  179. if(h->visitedTown)
  180. {
  181. if(h->inTownGarrison)
  182. h->visitedTown->garrisonHero = NULL;
  183. else
  184. h->visitedTown->visitingHero = NULL;
  185. h->visitedTown = NULL;
  186. }
  187. //TODO: add to the pool?
  188. }
  189. gs->map->objects[id] = NULL;
  190. //unblock tiles
  191. if(obj->defInfo)
  192. {
  193. gs->map->removeBlockVisTiles(obj);
  194. }
  195. }
  196. void TryMoveHero::applyGs( CGameState *gs )
  197. {
  198. CGHeroInstance *h = gs->getHero(id);
  199. h->movement = movePoints;
  200. if(start!=end && result)
  201. {
  202. gs->map->removeBlockVisTiles(h);
  203. h->pos = end;
  204. gs->map->addBlockVisTiles(h);
  205. }
  206. BOOST_FOREACH(int3 t, fowRevealed)
  207. gs->getPlayer(h->getOwner())->fogOfWarMap[t.x][t.y][t.z] = 1;
  208. }
  209. DLL_EXPORT void SetGarrisons::applyGs( CGameState *gs )
  210. {
  211. for(std::map<ui32,CCreatureSet>::iterator i = garrs.begin(); i!=garrs.end(); i++)
  212. {
  213. CArmedInstance *ai = static_cast<CArmedInstance*>(gs->map->objects[i->first]);
  214. ai->army = i->second;
  215. if(ai->ID==TOWNI_TYPE && (static_cast<CGTownInstance*>(ai))->garrisonHero) //if there is a hero in garrison then we must update also his army
  216. const_cast<CGHeroInstance*>((static_cast<CGTownInstance*>(ai))->garrisonHero)->army = i->second;
  217. else if(ai->ID==HEROI_TYPE)
  218. {
  219. CGHeroInstance *h = static_cast<CGHeroInstance*>(ai);
  220. if(h->visitedTown && h->inTownGarrison)
  221. h->visitedTown->army = i->second;
  222. }
  223. }
  224. }
  225. DLL_EXPORT void NewStructures::applyGs( CGameState *gs )
  226. {
  227. CGTownInstance*t = gs->getTown(tid);
  228. BOOST_FOREACH(si32 id,bid)
  229. t->builtBuildings.insert(id);
  230. t->builded = builded;
  231. }
  232. DLL_EXPORT void SetAvailableCreatures::applyGs( CGameState *gs )
  233. {
  234. gs->getTown(tid)->strInfo.creatures = creatures;
  235. }
  236. DLL_EXPORT void SetHeroesInTown::applyGs( CGameState *gs )
  237. {
  238. CGTownInstance *t = gs->getTown(tid);
  239. CGHeroInstance *v = gs->getHero(visiting),
  240. *g = gs->getHero(garrison);
  241. t->visitingHero = v;
  242. t->garrisonHero = g;
  243. if(v)
  244. {
  245. v->visitedTown = t;
  246. v->inTownGarrison = false;
  247. gs->map->addBlockVisTiles(v);
  248. }
  249. if(g)
  250. {
  251. g->visitedTown = t;
  252. g->inTownGarrison = true;
  253. gs->map->removeBlockVisTiles(g);
  254. }
  255. }
  256. DLL_EXPORT void SetHeroArtifacts::applyGs( CGameState *gs )
  257. {
  258. CGHeroInstance *h = gs->getHero(hid);
  259. std::vector<ui32> equiped, unequiped;
  260. for(std::map<ui16,ui32>::const_iterator i = h->artifWorn.begin(); i != h->artifWorn.end(); i++)
  261. if(!vstd::contains(artifWorn,i->first) || artifWorn[i->first] != i->second)
  262. unequiped.push_back(i->second);
  263. for(std::map<ui16,ui32>::const_iterator i = artifWorn.begin(); i != artifWorn.end(); i++)
  264. if(!vstd::contains(h->artifWorn,i->first) || h->artifWorn[i->first] != i->second)
  265. equiped.push_back(i->second);
  266. h->artifacts = artifacts;
  267. h->artifWorn = artifWorn;
  268. BOOST_FOREACH(ui32 id, unequiped)
  269. {
  270. while(1)
  271. {
  272. std::list<HeroBonus>::iterator hlp = std::find_if(h->bonuses.begin(),h->bonuses.end(),boost::bind(HeroBonus::IsFrom,_1,HeroBonus::ARTIFACT,id));
  273. if(hlp != h->bonuses.end())
  274. {
  275. lost.push_back(&*hlp);
  276. h->bonuses.erase(hlp);
  277. }
  278. else
  279. {
  280. break;
  281. }
  282. }
  283. }
  284. BOOST_FOREACH(ui32 id, equiped)
  285. {
  286. CArtifact &art = VLC->arth->artifacts[id];
  287. for(std::list<HeroBonus>::iterator i = art.bonuses.begin(); i != art.bonuses.end(); i++)
  288. {
  289. gained.push_back(&*i);
  290. h->bonuses.push_back(*i);
  291. }
  292. }
  293. }
  294. DLL_EXPORT void SetHeroArtifacts::setArtAtPos(ui16 pos, int art)
  295. {
  296. if(art<0)
  297. {
  298. if(pos<19)
  299. artifWorn.erase(pos);
  300. else
  301. artifacts -= artifacts[pos-19];
  302. }
  303. else
  304. {
  305. if(pos<19)
  306. artifWorn[pos] = art;
  307. else
  308. if(pos-19 < artifacts.size())
  309. artifacts[pos-19] = art;
  310. else
  311. artifacts.push_back(art);
  312. }
  313. }
  314. DLL_EXPORT void HeroRecruited::applyGs( CGameState *gs )
  315. {
  316. CGHeroInstance *h = gs->hpool.heroesPool[hid];
  317. CGTownInstance *t = gs->getTown(tid);
  318. h->setOwner(player);
  319. h->pos = tile;
  320. h->movement = h->maxMovePoints(true);
  321. gs->hpool.heroesPool.erase(hid);
  322. if(h->id < 0)
  323. {
  324. h->id = gs->map->objects.size();
  325. gs->map->objects.push_back(h);
  326. }
  327. else
  328. gs->map->objects[h->id] = h;
  329. h->initHeroDefInfo();
  330. gs->map->heroes.push_back(h);
  331. gs->getPlayer(h->getOwner())->heroes.push_back(h);
  332. gs->map->addBlockVisTiles(h);
  333. t->visitingHero = h;
  334. h->visitedTown = t;
  335. h->inTownGarrison = false;
  336. }
  337. DLL_EXPORT void GiveHero::applyGs( CGameState *gs )
  338. {
  339. CGHeroInstance *h = gs->getHero(id);
  340. gs->map->removeBlockVisTiles(h,true);
  341. h->setOwner(player);
  342. h->movement = h->maxMovePoints(true);
  343. h->initHeroDefInfo();
  344. gs->map->heroes.push_back(h);
  345. gs->getPlayer(h->getOwner())->heroes.push_back(h);
  346. gs->map->addBlockVisTiles(h);
  347. h->inTownGarrison = false;
  348. }
  349. DLL_EXPORT void NewTurn::applyGs( CGameState *gs )
  350. {
  351. gs->day = day;
  352. BOOST_FOREACH(NewTurn::Hero h, heroes) //give mana/movement point
  353. {
  354. CGHeroInstance *hero = gs->getHero(h.id);
  355. hero->movement = h.move;
  356. hero->mana = h.mana;
  357. }
  358. BOOST_FOREACH(SetResources h, res) //give resources
  359. h.applyGs(gs);
  360. BOOST_FOREACH(SetAvailableCreatures h, cres) //set available creatures in towns
  361. h.applyGs(gs);
  362. if(resetBuilded) //reset amount of structures set in this turn in towns
  363. BOOST_FOREACH(CGTownInstance* t, gs->map->towns)
  364. t->builded = 0;
  365. BOOST_FOREACH(CGHeroInstance *h, gs->map->heroes)
  366. h->bonuses.remove_if(HeroBonus::OneDay);
  367. if(gs->getDate(1) == 7) //new week
  368. BOOST_FOREACH(CGHeroInstance *h, gs->map->heroes)
  369. h->bonuses.remove_if(HeroBonus::OneWeek);
  370. }
  371. DLL_EXPORT void SetObjectProperty::applyGs( CGameState *gs )
  372. {
  373. CGObjectInstance *obj = gs->map->objects[id];
  374. if(!obj)
  375. tlog1 << "Wrong object ID - property cannot be set!\n";
  376. else
  377. obj->setProperty(what,val);
  378. }
  379. DLL_EXPORT void SetHoverName::applyGs( CGameState *gs )
  380. {
  381. gs->map->objects[id]->hoverName = toString(name);
  382. }
  383. DLL_EXPORT void HeroLevelUp::applyGs( CGameState *gs )
  384. {
  385. gs->getHero(heroid)->level = level;
  386. }
  387. DLL_EXPORT void BattleStart::applyGs( CGameState *gs )
  388. {
  389. gs->curB = info;
  390. }
  391. DLL_EXPORT void BattleNextRound::applyGs( CGameState *gs )
  392. {
  393. gs->curB->castedSpells[0] = gs->curB->castedSpells[1] = 0;
  394. gs->curB->round = round;
  395. BOOST_FOREACH(CStack *s, gs->curB->stacks)
  396. {
  397. s->state -= DEFENDING;
  398. s->state -= WAITING;
  399. s->state -= MOVED;
  400. s->state -= HAD_MORALE;
  401. s->counterAttacks = 1;
  402. //remove effects and restore only those with remaining turns in duration
  403. std::vector<CStack::StackEffect> tmpEffects = s->effects;
  404. s->effects.clear();
  405. for(int i=0; i < tmpEffects.size(); i++)
  406. {
  407. tmpEffects[i].turnsRemain--;
  408. if(tmpEffects[i].turnsRemain > 0)
  409. s->effects.push_back(tmpEffects[i]);
  410. }
  411. }
  412. }
  413. DLL_EXPORT void BattleSetActiveStack::applyGs( CGameState *gs )
  414. {
  415. gs->curB->activeStack = stack;
  416. CStack *st = gs->curB->getStack(stack);
  417. if(vstd::contains(st->state,MOVED)) //if stack is moving second time this turn it must had a high morale bonus
  418. st->state.insert(HAD_MORALE);
  419. }
  420. void BattleResult::applyGs( CGameState *gs )
  421. {
  422. for(unsigned i=0;i<gs->curB->stacks.size();i++)
  423. delete gs->curB->stacks[i];
  424. //remove any "until next battle" bonuses
  425. CGHeroInstance *h;
  426. h = gs->getHero(gs->curB->hero1);
  427. if(h)
  428. h->bonuses.remove_if(HeroBonus::OneBattle);
  429. h = gs->getHero(gs->curB->hero2);
  430. if(h)
  431. h->bonuses.remove_if(HeroBonus::OneBattle);
  432. delete gs->curB;
  433. gs->curB = NULL;
  434. }
  435. void BattleStackMoved::applyGs( CGameState *gs )
  436. {
  437. gs->curB->getStack(stack)->position = tile;
  438. }
  439. DLL_EXPORT void BattleStackAttacked::applyGs( CGameState *gs )
  440. {
  441. CStack * at = gs->curB->getStack(stackAttacked);
  442. at->amount = newAmount;
  443. at->firstHPleft = newHP;
  444. if(killed())
  445. at->state -= ALIVE;
  446. }
  447. DLL_EXPORT void BattleAttack::applyGs( CGameState *gs )
  448. {
  449. CStack *attacker = gs->curB->getStack(stackAttacking);
  450. if(counter())
  451. attacker->counterAttacks--;
  452. if(shot())
  453. attacker->shots--;
  454. BOOST_FOREACH(BattleStackAttacked stackAttacked, bsa)
  455. stackAttacked.applyGs(gs);
  456. }
  457. DLL_EXPORT void StartAction::applyGs( CGameState *gs )
  458. {
  459. CStack *st = gs->curB->getStack(ba.stackNumber);
  460. switch(ba.actionType)
  461. {
  462. case 3:
  463. st->state.insert(DEFENDING);
  464. break;
  465. case 8:
  466. st->state.insert(WAITING);
  467. break;
  468. case 2: case 6: case 7: case 9: case 10: case 11:
  469. st->state.insert(MOVED);
  470. break;
  471. }
  472. }
  473. DLL_EXPORT void SpellCasted::applyGs( CGameState *gs )
  474. {
  475. CGHeroInstance *h = (side) ? gs->getHero(gs->curB->hero2) : gs->getHero(gs->curB->hero1);
  476. if(h)
  477. {
  478. h->mana -= VLC->spellh->spells[id].costs[skill];
  479. if(h->mana < 0) h->mana = 0;
  480. }
  481. if(side >= 0 && side < 2)
  482. {
  483. gs->curB->castedSpells[side]++;
  484. }
  485. }
  486. DLL_EXPORT void SetStackEffect::applyGs( CGameState *gs )
  487. {
  488. BOOST_FOREACH(ui32 id, stacks)
  489. {
  490. CStack *s = gs->curB->getStack(id);
  491. if(s)
  492. s->effects.push_back(effect);
  493. else
  494. tlog1 << "Cannot find stack " << id << std::endl;
  495. }
  496. }
  497. DLL_EXPORT void StacksInjured::applyGs( CGameState *gs )
  498. {
  499. BOOST_FOREACH(BattleStackAttacked stackAttacked, stacks)
  500. stackAttacked.applyGs(gs);
  501. }
  502. DLL_EXPORT void YourTurn::applyGs( CGameState *gs )
  503. {
  504. gs->currentPlayer = player;
  505. }
  506. DLL_EXPORT void SetSelection::applyGs( CGameState *gs )
  507. {
  508. gs->getPlayer(player)->currentSelection = id;
  509. }