NetPacksLib.cpp 13 KB

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