CArtHandler.cpp 46 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465
  1. #include "StdInc.h"
  2. #include "CArtHandler.h"
  3. #include "CLodHandler.h"
  4. #include "CGeneralTextHandler.h"
  5. #include <boost/random/linear_congruential.hpp>
  6. #include "../lib/VCMI_Lib.h"
  7. #include "CSpellHandler.h"
  8. #include "CObjectHandler.h"
  9. #include "NetPacks.h"
  10. extern CLodHandler *bitmaph;
  11. using namespace boost::assign;
  12. /*
  13. * CArtHandler.cpp, part of VCMI engine
  14. *
  15. * Authors: listed in file AUTHORS in main folder
  16. *
  17. * License: GNU General Public License v2.0 or later
  18. * Full text of license available in license.txt file, in main folder
  19. *
  20. */
  21. extern boost::rand48 ran;
  22. const std::string & CArtifact::Name() const
  23. {
  24. if(name.size())
  25. return name;
  26. else
  27. return VLC->generaltexth->artifNames[id];
  28. }
  29. const std::string & CArtifact::Description() const
  30. {
  31. if(description.size())
  32. return description;
  33. else
  34. return VLC->generaltexth->artifDescriptions[id];
  35. }
  36. bool CArtifact::isBig () const
  37. {
  38. return VLC->arth->isBigArtifact(id);
  39. }
  40. //
  41. // bool CArtifact::isModable () const
  42. // {
  43. // return (bool)dynamic_cast<const IModableArt *>(this);
  44. // }
  45. // /**
  46. // * Checks whether the artifact fits at a given slot.
  47. // * @param artifWorn A hero's set of worn artifacts.
  48. // */
  49. // bool CArtifact::fitsAt (const std::map<ui16, const CArtifact*> &artifWorn, ui16 slotID) const
  50. // {
  51. // if (!vstd::contains(possibleSlots, slotID))
  52. // return false;
  53. //
  54. // // Can't put an artifact in a locked slot.
  55. // std::map<ui16, const CArtifact*>::const_iterator it = artifWorn.find(slotID);
  56. // if (it != artifWorn.end() && it->second->id == 145)
  57. // return false;
  58. //
  59. // // Check if a combination artifact fits.
  60. // // TODO: Might want a more general algorithm?
  61. // // Assumes that misc & rings fits only in their slots, and others in only one slot and no duplicates.
  62. // if (constituents != NULL)
  63. // {
  64. // std::map<ui16, const CArtifact*> tempArtifWorn = artifWorn;
  65. // const ui16 ringSlots[] = {6, 7};
  66. // const ui16 miscSlots[] = {9, 10, 11, 12, 18};
  67. // int rings = 0;
  68. // int misc = 0;
  69. //
  70. // VLC->arth->unequipArtifact(tempArtifWorn, slotID);
  71. //
  72. // BOOST_FOREACH(ui32 constituentID, *constituents)
  73. // {
  74. // const CArtifact& constituent = *VLC->arth->artifacts[constituentID];
  75. // const int slot = constituent.possibleSlots[0];
  76. //
  77. // if (slot == 6 || slot == 7)
  78. // rings++;
  79. // else if ((slot >= 9 && slot <= 12) || slot == 18)
  80. // misc++;
  81. // else if (tempArtifWorn.find(slot) != tempArtifWorn.end())
  82. // return false;
  83. // }
  84. //
  85. // // Ensure enough ring slots are free
  86. // for (int i = 0; i < sizeof(ringSlots)/sizeof(*ringSlots); i++)
  87. // {
  88. // if (tempArtifWorn.find(ringSlots[i]) == tempArtifWorn.end() || ringSlots[i] == slotID)
  89. // rings--;
  90. // }
  91. // if (rings > 0)
  92. // return false;
  93. //
  94. // // Ensure enough misc slots are free.
  95. // for (int i = 0; i < sizeof(miscSlots)/sizeof(*miscSlots); i++)
  96. // {
  97. // if (tempArtifWorn.find(miscSlots[i]) == tempArtifWorn.end() || miscSlots[i] == slotID)
  98. // misc--;
  99. // }
  100. // if (misc > 0)
  101. // return false;
  102. // }
  103. //
  104. // return true;
  105. // }
  106. // bool CArtifact::canBeAssembledTo (const std::map<ui16, const CArtifact*> &artifWorn, ui32 artifactID) const
  107. // {
  108. // if (constituentOf == NULL || !vstd::contains(*constituentOf, artifactID))
  109. // return false;
  110. //
  111. // const CArtifact &artifact = *VLC->arth->artifacts[artifactID];
  112. // assert(artifact.constituents);
  113. //
  114. // BOOST_FOREACH(ui32 constituentID, *artifact.constituents)
  115. // {
  116. // bool found = false;
  117. // for (std::map<ui16, const CArtifact*>::const_iterator it = artifWorn.begin(); it != artifWorn.end(); ++it)
  118. // {
  119. // if (it->second->id == constituentID)
  120. // {
  121. // found = true;
  122. // break;
  123. // }
  124. // }
  125. // if (!found)
  126. // return false;
  127. // }
  128. //
  129. // return true;
  130. // }
  131. CArtifact::CArtifact()
  132. {
  133. setNodeType(ARTIFACT);
  134. }
  135. CArtifact::~CArtifact()
  136. {
  137. }
  138. int CArtifact::getArtClassSerial() const
  139. {
  140. if(id == 1)
  141. return 4;
  142. switch(aClass)
  143. {
  144. case ART_TREASURE:
  145. return 0;
  146. case ART_MINOR:
  147. return 1;
  148. case ART_MAJOR:
  149. return 2;
  150. case ART_RELIC:
  151. return 3;
  152. case ART_SPECIAL:
  153. return 5;
  154. }
  155. return -1;
  156. }
  157. std::string CArtifact::nodeName() const
  158. {
  159. return "Artifact: " + Name();
  160. }
  161. // void CArtifact::getParents(TCNodes &out, const CBonusSystemNode *root /*= NULL*/) const
  162. // {
  163. // //combined artifact carries bonuses from its parts
  164. // if(constituents)
  165. // {
  166. // BOOST_FOREACH(ui32 id, *constituents)
  167. // out.insert(VLC->arth->artifacts[id]);
  168. // }
  169. // }
  170. // void CScroll::Init()
  171. // {
  172. // // addNewBonus (Bonus (Bonus::PERMANENT, Bonus::SPELL, Bonus::ARTIFACT, 1, id, spellid, Bonus::INDEPENDENT_MAX));
  173. // // //boost::algorithm::replace_first(description, "[spell name]", VLC->spellh->spells[spellid].name);
  174. // }
  175. void CArtifact::setDescription (std::string desc)
  176. {
  177. description = desc;
  178. }
  179. CArtHandler::CArtHandler()
  180. {
  181. VLC->arth = this;
  182. // War machines are the default big artifacts.
  183. for (ui32 i = 3; i <= 6; i++)
  184. bigArtifacts.insert(i);
  185. }
  186. CArtHandler::~CArtHandler()
  187. {
  188. for (std::vector< ConstTransitivePtr<CArtifact> >::iterator it = artifacts.begin(); it != artifacts.end(); ++it)
  189. {
  190. delete (*it)->constituents;
  191. delete (*it)->constituentOf;
  192. }
  193. }
  194. void CArtHandler::loadArtifacts(bool onlyTxt)
  195. {
  196. std::vector<ui16> slots;
  197. slots += 17, 16, 15, 14, 13, 18, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0;
  198. static std::map<char, CArtifact::EartClass> classes =
  199. map_list_of('S',CArtifact::ART_SPECIAL)('T',CArtifact::ART_TREASURE)('N',CArtifact::ART_MINOR)('J',CArtifact::ART_MAJOR)('R',CArtifact::ART_RELIC);
  200. std::string buf = bitmaph->getTextFile("ARTRAITS.TXT"), dump, pom;
  201. int it=0;
  202. for(int i=0; i<2; ++i)
  203. {
  204. loadToIt(dump,buf,it,3);
  205. }
  206. VLC->generaltexth->artifNames.resize(GameConstants::ARTIFACTS_QUANTITY);
  207. VLC->generaltexth->artifDescriptions.resize(GameConstants::ARTIFACTS_QUANTITY);
  208. std::map<ui32,ui8>::iterator itr;
  209. for (int i=0; i<GameConstants::ARTIFACTS_QUANTITY; i++)
  210. {
  211. CArtifact *art = new CArtifact();
  212. CArtifact &nart = *art;
  213. nart.id=i;
  214. loadToIt(VLC->generaltexth->artifNames[i],buf,it,4);
  215. loadToIt(pom,buf,it,4);
  216. nart.price=atoi(pom.c_str());
  217. nart.possibleSlots[ArtBearer::HERO]; //we want to generate map entry even if it will be empty
  218. nart.possibleSlots[ArtBearer::CREATURE]; //we want to generate map entry even if it will be empty
  219. nart.possibleSlots[ArtBearer::COMMANDER];
  220. for(int j=0;j<slots.size();j++)
  221. {
  222. loadToIt(pom,buf,it,4);
  223. if(pom.size() && pom[0]=='x')
  224. nart.possibleSlots[ArtBearer::HERO].push_back(slots[j]);
  225. }
  226. loadToIt(pom,buf,it,4);
  227. nart.aClass = classes[pom[0]];
  228. //load description and remove quotation marks
  229. std::string &desc = VLC->generaltexth->artifDescriptions[i];
  230. loadToIt(desc,buf,it,3);
  231. if(desc[0] == '\"' && desc[desc.size()-1] == '\"')
  232. desc = desc.substr(1,desc.size()-2);
  233. if(onlyTxt)
  234. continue;
  235. // Fill in information about combined artifacts. Should perhaps be moved to a config file?
  236. nart.constituentOf = NULL;
  237. switch (nart.id)
  238. {
  239. case 129: // Angelic Alliance
  240. nart.constituents = new std::vector<ui32>();
  241. *nart.constituents += 31, 32, 33, 34, 35, 36;
  242. break;
  243. case 130: // Cloak of the Undead King
  244. nart.constituents = new std::vector<ui32>();
  245. *nart.constituents += 54, 55, 56;
  246. break;
  247. case 131: // Elixir of Life
  248. nart.constituents = new std::vector<ui32>();
  249. *nart.constituents += 94, 95, 96;
  250. break;
  251. case 132: // Armor of the Damned
  252. nart.constituents = new std::vector<ui32>();
  253. *nart.constituents += 8, 14, 20, 26;
  254. break;
  255. case 133: // Statue of Legion
  256. nart.constituents = new std::vector<ui32>();
  257. *nart.constituents += 118, 119, 120, 121, 122;
  258. break;
  259. case 134: // Power of the Dragon Father
  260. nart.constituents = new std::vector<ui32>();
  261. *nart.constituents += 37, 38, 39, 40, 41, 42, 43, 44, 45;
  262. break;
  263. case 135: // Titan's Thunder
  264. nart.constituents = new std::vector<ui32>();
  265. *nart.constituents += 12, 18, 24, 30;
  266. break;
  267. case 136: // Admiral's Hat
  268. nart.constituents = new std::vector<ui32>();
  269. *nart.constituents += 71, 123;
  270. break;
  271. case 137: // Bow of the Sharpshooter
  272. nart.constituents = new std::vector<ui32>();
  273. *nart.constituents += 60, 61, 62;
  274. break;
  275. case 138: // Wizards' Well
  276. nart.constituents = new std::vector<ui32>();
  277. *nart.constituents += 73, 74, 75;
  278. break;
  279. case 139: // Ring of the Magi
  280. nart.constituents = new std::vector<ui32>();
  281. *nart.constituents += 76, 77, 78;
  282. break;
  283. case 140: // Cornucopia
  284. nart.constituents = new std::vector<ui32>();
  285. *nart.constituents += 109, 110, 111, 113;
  286. break;
  287. // TODO: WoG combinationals
  288. default:
  289. nart.constituents = NULL;
  290. break;
  291. }
  292. artifacts.push_back(&nart);
  293. }
  294. sortArts();
  295. if(onlyTxt)
  296. return;
  297. addBonuses();
  298. // Populate reverse mappings of combinational artifacts.
  299. BOOST_FOREACH(CArtifact *artifact, artifacts)
  300. {
  301. if (artifact->constituents != NULL)
  302. {
  303. BOOST_FOREACH(ui32 constituentID, *artifact->constituents)
  304. {
  305. if (artifacts[constituentID]->constituentOf == NULL)
  306. artifacts[constituentID]->constituentOf = new std::vector<ui32>();
  307. artifacts[constituentID]->constituentOf->push_back(artifact->id);
  308. }
  309. }
  310. }
  311. }
  312. int CArtHandler::convertMachineID(int id, bool creToArt )
  313. {
  314. int dif = 142;
  315. if(creToArt)
  316. {
  317. switch (id)
  318. {
  319. case 147:
  320. dif--;
  321. break;
  322. case 148:
  323. dif++;
  324. break;
  325. }
  326. dif = -dif;
  327. }
  328. else
  329. {
  330. switch (id)
  331. {
  332. case 6:
  333. dif--;
  334. break;
  335. case 5:
  336. dif++;
  337. break;
  338. }
  339. }
  340. return id + dif;
  341. }
  342. void CArtHandler::sortArts()
  343. {
  344. //for (int i=0; i<allowedArtifacts.size(); ++i) //do 144, bo nie chcemy bzdurek
  345. //{
  346. // switch (allowedArtifacts[i]->aClass)
  347. // {
  348. // case CArtifact::ART_TREASURE:
  349. // treasures.push_back(allowedArtifacts[i]);
  350. // break;
  351. // case CArtifact::ART_MINOR:
  352. // minors.push_back(allowedArtifacts[i]);
  353. // break;
  354. // case CArtifact::ART_MAJOR:
  355. // majors.push_back(allowedArtifacts[i]);
  356. // break;
  357. // case CArtifact::ART_RELIC:
  358. // relics.push_back(allowedArtifacts[i]);
  359. // break;
  360. // }
  361. //}
  362. }
  363. void CArtHandler::erasePickedArt (si32 id)
  364. {
  365. std::vector<CArtifact*>* ptr;
  366. CArtifact *art = artifacts[id];
  367. switch (art->aClass)
  368. {
  369. case CArtifact::ART_TREASURE:
  370. ptr = &treasures;
  371. break;
  372. case CArtifact::ART_MINOR:
  373. ptr = &minors;
  374. break;
  375. case CArtifact::ART_MAJOR:
  376. ptr = &majors;
  377. break;
  378. case CArtifact::ART_RELIC:
  379. ptr = &relics;
  380. break;
  381. default: //special artifacts should not be erased
  382. return;
  383. }
  384. ptr->erase (std::find(ptr->begin(), ptr->end(), art)); //remove the artifact from available list
  385. }
  386. ui16 CArtHandler::getRandomArt(int flags)
  387. {
  388. std::vector<ConstTransitivePtr<CArtifact> > out;
  389. getAllowed(out, flags);
  390. ui16 id = out[ran() % out.size()]->id;
  391. erasePickedArt (id);
  392. return id;
  393. }
  394. ui16 CArtHandler::getArtSync (ui32 rand, int flags)
  395. {
  396. std::vector<ConstTransitivePtr<CArtifact> > out;
  397. getAllowed(out, flags);
  398. CArtifact *art = out[rand % out.size()];
  399. return art->id;
  400. }
  401. void CArtHandler::getAllowed(std::vector<ConstTransitivePtr<CArtifact> > &out, int flags)
  402. {
  403. if (flags & CArtifact::ART_TREASURE)
  404. getAllowedArts (out, &treasures, CArtifact::ART_TREASURE);
  405. if (flags & CArtifact::ART_MINOR)
  406. getAllowedArts (out, &minors, CArtifact::ART_MINOR);
  407. if (flags & CArtifact::ART_MAJOR)
  408. getAllowedArts (out, &majors, CArtifact::ART_MAJOR);
  409. if (flags & CArtifact::ART_RELIC)
  410. getAllowedArts (out, &relics, CArtifact::ART_RELIC);
  411. if (!out.size()) //no artifact of specified rarity, we need to take another one
  412. {
  413. getAllowedArts (out, &treasures, CArtifact::ART_TREASURE);
  414. getAllowedArts (out, &minors, CArtifact::ART_MINOR);
  415. getAllowedArts (out, &majors, CArtifact::ART_MAJOR);
  416. getAllowedArts (out, &relics, CArtifact::ART_RELIC);
  417. }
  418. if (!out.size()) //no arts are available at all
  419. {
  420. out.resize (64);
  421. std::fill_n (out.begin(), 64, artifacts[2]); //Give Grail - this can't be banned (hopefully)
  422. }
  423. }
  424. void CArtHandler::getAllowedArts(std::vector<ConstTransitivePtr<CArtifact> > &out, std::vector<CArtifact*> *arts, int flag)
  425. {
  426. if (arts->empty()) //restock available arts
  427. {
  428. for (int i = 0; i < allowedArtifacts.size(); ++i)
  429. {
  430. if (allowedArtifacts[i]->aClass == flag)
  431. arts->push_back(allowedArtifacts[i]);
  432. }
  433. }
  434. for (int i = 0; i < arts->size(); ++i)
  435. {
  436. CArtifact *art = (*arts)[i];
  437. out.push_back(art);
  438. }
  439. }
  440. void CArtHandler::giveArtBonus( int aid, Bonus::BonusType type, int val, int subtype, int valType, ILimiter * limiter, int additionalInfo)
  441. {
  442. Bonus *added = new Bonus(Bonus::PERMANENT,type,Bonus::ARTIFACT,val,aid,subtype);
  443. added->additionalInfo = additionalInfo;
  444. added->valType = valType;
  445. added->limiter.reset(limiter);
  446. if(type == Bonus::MORALE || type == Bonus::LUCK)
  447. added->description = artifacts[aid]->Name() + (val > 0 ? " +" : " ") + boost::lexical_cast<std::string>(val);
  448. else
  449. added->description = artifacts[aid]->Name();
  450. artifacts[aid]->addNewBonus(added);
  451. }
  452. void CArtHandler::giveArtBonus(int aid, Bonus::BonusType type, int val, int subtype, IPropagator* propagator /*= NULL*/, int additionalInfo)
  453. {
  454. Bonus *added = new Bonus(Bonus::PERMANENT,type,Bonus::ARTIFACT,val,aid,subtype);
  455. added->additionalInfo = additionalInfo;
  456. added->valType = Bonus::BASE_NUMBER;
  457. added->propagator.reset(propagator);
  458. if(type == Bonus::MORALE || type == Bonus::LUCK)
  459. added->description = artifacts[aid]->Name() + (val > 0 ? " +" : " ") + boost::lexical_cast<std::string>(val);
  460. else
  461. added->description = artifacts[aid]->Name();
  462. artifacts[aid]->addNewBonus(added);
  463. }
  464. void CArtHandler::makeItCreatureArt (int aid, bool onlyCreature /*=true*/)
  465. {
  466. CArtifact *a = artifacts[aid];
  467. if (onlyCreature)
  468. {
  469. a->possibleSlots[ArtBearer::HERO].clear();
  470. a->possibleSlots[ArtBearer::COMMANDER].clear();
  471. }
  472. a->possibleSlots[ArtBearer::CREATURE].push_back(ArtifactPosition::CREATURE_SLOT);
  473. };
  474. void CArtHandler::makeItCommanderArt (int aid, bool onlyCommander /*=true*/)
  475. {
  476. CArtifact *a = artifacts[aid];
  477. if (onlyCommander)
  478. {
  479. a->possibleSlots[ArtBearer::HERO].clear();
  480. a->possibleSlots[ArtBearer::CREATURE].clear();
  481. }
  482. for (int i = ArtifactPosition::COMMANDER1; i <= ArtifactPosition::COMMANDER6; ++i)
  483. a->possibleSlots[ArtBearer::COMMANDER].push_back(i);
  484. };
  485. void CArtHandler::addBonuses()
  486. {
  487. #define ART_PRIM_SKILL(ID, whichSkill, val) giveArtBonus(ID,Bonus::PRIMARY_SKILL,val,whichSkill)
  488. #define ART_MORALE(ID, val) giveArtBonus(ID,Bonus::MORALE,val)
  489. #define ART_LUCK(ID, val) giveArtBonus(ID,Bonus::LUCK,val)
  490. #define ART_MORALE_AND_LUCK(ID, val) giveArtBonus(ID,Bonus::MORALE_AND_LUCK,val)
  491. #define ART_ALL_PRIM_SKILLS(ID, val) ART_PRIM_SKILL(ID,0,val); ART_PRIM_SKILL(ID,1,val); ART_PRIM_SKILL(ID,2,val); ART_PRIM_SKILL(ID,3,val)
  492. #define ART_ATTACK_AND_DEFENSE(ID, val) ART_PRIM_SKILL(ID,0,val); ART_PRIM_SKILL(ID,1,val)
  493. #define ART_POWER_AND_KNOWLEDGE(ID, val) ART_PRIM_SKILL(ID,2,val); ART_PRIM_SKILL(ID,3,val)
  494. //Attack bonus artifacts (Weapons)
  495. ART_PRIM_SKILL(7,0,+2); //Centaur Axe
  496. ART_PRIM_SKILL(8,0,+3); //Blackshard of the Dead Knight
  497. ART_PRIM_SKILL(9,0,+4); //Greater Gnoll's Flail
  498. ART_PRIM_SKILL(10,0,+5); //Ogre's Club of Havoc
  499. ART_PRIM_SKILL(11,0,+6); //Sword of Hellfire
  500. ART_PRIM_SKILL(12,0,+12); //Titan's Gladius
  501. ART_PRIM_SKILL(12,1,-3); //Titan's Gladius
  502. //Defense bonus artifacts (Shields)
  503. ART_PRIM_SKILL(13,1,+2); //Shield of the Dwarven Lords
  504. ART_PRIM_SKILL(14,1,+3); //Shield of the Yawning Dead
  505. ART_PRIM_SKILL(15,1,+4); //Buckler of the Gnoll King
  506. ART_PRIM_SKILL(16,1,+5); //Targ of the Rampaging Ogre
  507. ART_PRIM_SKILL(17,1,+6); //Shield of the Damned
  508. ART_PRIM_SKILL(18,1,+12); //Sentinel's Shield
  509. ART_PRIM_SKILL(18,0,-3); //Sentinel's Shield
  510. //Knowledge bonus artifacts (Helmets)
  511. ART_PRIM_SKILL(19,3,+1); //Helm of the Alabaster Unicorn
  512. ART_PRIM_SKILL(20,3,+2); //Skull Helmet
  513. ART_PRIM_SKILL(21,3,+3); //Helm of Chaos
  514. ART_PRIM_SKILL(22,3,+4); //Crown of the Supreme Magi
  515. ART_PRIM_SKILL(23,3,+5); //Hellstorm Helmet
  516. ART_PRIM_SKILL(24,3,+10); //Thunder Helmet
  517. ART_PRIM_SKILL(24,2,-2); //Thunder Helmet
  518. //Spell power bonus artifacts (Armours)
  519. ART_PRIM_SKILL(25,2,+1); //Breastplate of Petrified Wood
  520. ART_PRIM_SKILL(26,2,+2); //Rib Cage
  521. ART_PRIM_SKILL(27,2,+3); //Scales of the Greater Basilisk
  522. ART_PRIM_SKILL(28,2,+4); //Tunic of the Cyclops King
  523. ART_PRIM_SKILL(29,2,+5); //Breastplate of Brimstone
  524. ART_PRIM_SKILL(30,2,+10); //Titan's Cuirass
  525. ART_PRIM_SKILL(30,3,-2); //Titan's Cuirass
  526. //All primary skills (various)
  527. ART_ALL_PRIM_SKILLS(31,+1); //Armor of Wonder
  528. ART_ALL_PRIM_SKILLS(32,+2); //Sandals of the Saint
  529. ART_ALL_PRIM_SKILLS(33,+3); //Celestial Necklace of Bliss
  530. ART_ALL_PRIM_SKILLS(34,+4); //Lion's Shield of Courage
  531. ART_ALL_PRIM_SKILLS(35,+5); //Sword of Judgement
  532. ART_ALL_PRIM_SKILLS(36,+6); //Helm of Heavenly Enlightenment
  533. //Attack and Defense (various)
  534. ART_ATTACK_AND_DEFENSE(37,+1); //Quiet Eye of the Dragon
  535. ART_ATTACK_AND_DEFENSE(38,+2); //Red Dragon Flame Tongue
  536. ART_ATTACK_AND_DEFENSE(39,+3); //Dragon Scale Shield
  537. ART_ATTACK_AND_DEFENSE(40,+4); //Dragon Scale Armor
  538. //Spell power and Knowledge (various)
  539. ART_POWER_AND_KNOWLEDGE(41,+1); //Dragonbone Greaves
  540. ART_POWER_AND_KNOWLEDGE(42,+2); //Dragon Wing Tabard
  541. ART_POWER_AND_KNOWLEDGE(43,+3); //Necklace of Dragonteeth
  542. ART_POWER_AND_KNOWLEDGE(44,+4); //Crown of Dragontooth
  543. //Luck and morale
  544. ART_MORALE(45,+1); //Still Eye of the Dragon
  545. ART_LUCK(45,+1); //Still Eye of the Dragon
  546. ART_LUCK(46,+1); //Clover of Fortune
  547. ART_LUCK(47,+1); //Cards of Prophecy
  548. ART_LUCK(48,+1); //Ladybird of Luck
  549. ART_MORALE(49,+1); //Badge of Courage -> +1 morale
  550. giveArtBonus(49,Bonus::MIND_IMMUNITY,0); //immunity to hostile mind spells:
  551. ART_MORALE(50,+1); //Crest of Valor
  552. ART_MORALE(51,+1); //Glyph of Gallantry
  553. giveArtBonus(52,Bonus::SIGHT_RADIOUS,+1);//Speculum
  554. giveArtBonus(53,Bonus::SIGHT_RADIOUS,+1);//Spyglass
  555. //necromancy bonus
  556. giveArtBonus(54,Bonus::SECONDARY_SKILL_PREMY,+5, CGHeroInstance::NECROMANCY, Bonus::ADDITIVE_VALUE);//Amulet of the Undertaker
  557. giveArtBonus(55,Bonus::SECONDARY_SKILL_PREMY,+10, CGHeroInstance::NECROMANCY, Bonus::ADDITIVE_VALUE);//Vampire's Cowl
  558. giveArtBonus(56,Bonus::SECONDARY_SKILL_PREMY,+15, CGHeroInstance::NECROMANCY, Bonus::ADDITIVE_VALUE);//Dead Man's Boots
  559. giveArtBonus(57,Bonus::MAGIC_RESISTANCE,+5, 0);//Garniture of Interference
  560. giveArtBonus(58,Bonus::MAGIC_RESISTANCE,+10, 0);//Surcoat of Counterpoise
  561. giveArtBonus(59,Bonus::MAGIC_RESISTANCE,+15, 0);//Boots of Polarity
  562. //archery bonus
  563. giveArtBonus(60,Bonus::SECONDARY_SKILL_PREMY,+5, CGHeroInstance::ARCHERY, Bonus::ADDITIVE_VALUE);//Bow of Elven Cherrywood
  564. giveArtBonus(61,Bonus::SECONDARY_SKILL_PREMY,+10,CGHeroInstance::ARCHERY, Bonus::ADDITIVE_VALUE);//Bowstring of the Unicorn's Mane
  565. giveArtBonus(62,Bonus::SECONDARY_SKILL_PREMY,+15,CGHeroInstance::ARCHERY, Bonus::ADDITIVE_VALUE);//Angel Feather Arrows
  566. //eagle eye bonus
  567. giveArtBonus(63,Bonus::SECONDARY_SKILL_PREMY,+5, CGHeroInstance::EAGLE_EYE, Bonus::ADDITIVE_VALUE);//Bird of Perception
  568. giveArtBonus(64,Bonus::SECONDARY_SKILL_PREMY,+10, CGHeroInstance::EAGLE_EYE, Bonus::ADDITIVE_VALUE);//Stoic Watchman
  569. giveArtBonus(65,Bonus::SECONDARY_SKILL_PREMY,+15, CGHeroInstance::EAGLE_EYE, Bonus::ADDITIVE_VALUE);//Emblem of Cognizance
  570. //reducing cost of surrendering
  571. giveArtBonus(66,Bonus::SURRENDER_DISCOUNT,+10);//Statesman's Medal
  572. giveArtBonus(67,Bonus::SURRENDER_DISCOUNT,+10);//Diplomat's Ring
  573. giveArtBonus(68,Bonus::SURRENDER_DISCOUNT,+10);//Ambassador's Sash
  574. giveArtBonus(69,Bonus::STACKS_SPEED,+1);//Ring of the Wayfarer
  575. giveArtBonus(70,Bonus::LAND_MOVEMENT,+300);//Equestrian's Gloves
  576. giveArtBonus(71,Bonus::SEA_MOVEMENT,+1000);//Necklace of Ocean Guidance
  577. giveArtBonus(72,Bonus::FLYING_MOVEMENT, 0, 1);//Angel Wings
  578. giveArtBonus(73,Bonus::MANA_REGENERATION,+1);//Charm of Mana
  579. giveArtBonus(74,Bonus::MANA_REGENERATION,+2);//Talisman of Mana
  580. giveArtBonus(75,Bonus::MANA_REGENERATION,+3);//Mystic Orb of Mana
  581. giveArtBonus(76,Bonus::SPELL_DURATION,+1);//Collar of Conjuring
  582. giveArtBonus(77,Bonus::SPELL_DURATION,+2);//Ring of Conjuring
  583. giveArtBonus(78,Bonus::SPELL_DURATION,+3);//Cape of Conjuring
  584. giveArtBonus(79,Bonus::AIR_SPELL_DMG_PREMY,+50);//Orb of the Firmament
  585. giveArtBonus(80,Bonus::EARTH_SPELL_DMG_PREMY,+50);//Orb of Silt
  586. giveArtBonus(81,Bonus::FIRE_SPELL_DMG_PREMY,+50);//Orb of Tempestuous Fire
  587. giveArtBonus(82,Bonus::WATER_SPELL_DMG_PREMY,+50);//Orb of Driving Rain
  588. giveArtBonus(83,Bonus::LEVEL_SPELL_IMMUNITY,3,-1,Bonus::INDEPENDENT_MAX);//Recanter's Cloak
  589. giveArtBonus(84,Bonus::BLOCK_MORALE,0);//Spirit of Oppression
  590. giveArtBonus(85,Bonus::BLOCK_LUCK,0);//Hourglass of the Evil Hour
  591. giveArtBonus(86,Bonus::FIRE_SPELLS,0);//Tome of Fire Magic
  592. giveArtBonus(87,Bonus::AIR_SPELLS,0);//Tome of Air Magic
  593. giveArtBonus(88,Bonus::WATER_SPELLS,0);//Tome of Water Magic
  594. giveArtBonus(89,Bonus::EARTH_SPELLS,0);//Tome of Earth Magic
  595. giveArtBonus(90,Bonus::WATER_WALKING, 0, 1);//Boots of Levitation
  596. giveArtBonus(91,Bonus::NO_DISTANCE_PENALTY,0, 0, 0, new HasAnotherBonusLimiter(Bonus::SHOOTER));//Golden Bow
  597. giveArtBonus(91,Bonus::NO_WALL_PENALTY, 0, 0, 0, new HasAnotherBonusLimiter(Bonus::SHOOTER));
  598. giveArtBonus(92,Bonus::SPELL_IMMUNITY,0,35);//Sphere of Permanence
  599. giveArtBonus(93,Bonus::NEGATE_ALL_NATURAL_IMMUNITIES,0);//Orb of Vulnerability
  600. giveArtBonus(94,Bonus::STACK_HEALTH,+1);//Ring of Vitality
  601. giveArtBonus(95,Bonus::STACK_HEALTH,+1);//Ring of Life
  602. giveArtBonus(96,Bonus::STACK_HEALTH,+2);//Vial of Lifeblood
  603. giveArtBonus(97,Bonus::STACKS_SPEED,+1);//Necklace of Swiftness
  604. giveArtBonus(98,Bonus::LAND_MOVEMENT,+600);//Boots of Speed
  605. giveArtBonus(99,Bonus::STACKS_SPEED,+2);//Cape of Velocity
  606. giveArtBonus(100,Bonus::SPELL_IMMUNITY,0,59);//Pendant of Dispassion
  607. giveArtBonus(101,Bonus::SPELL_IMMUNITY,0,62);//Pendant of Second Sight
  608. giveArtBonus(102,Bonus::SPELL_IMMUNITY,0,42);//Pendant of Holiness
  609. giveArtBonus(103,Bonus::SPELL_IMMUNITY,0,24);//Pendant of Life
  610. giveArtBonus(104,Bonus::SPELL_IMMUNITY,0,25, 1, new HasAnotherBonusLimiter(Bonus::UNDEAD));//Pendant of Death does not display info for living stacks
  611. giveArtBonus(105,Bonus::SPELL_IMMUNITY,0,60);//Pendant of Free Will
  612. giveArtBonus(106,Bonus::SPELL_IMMUNITY,0,17);//Pendant of Negativity
  613. giveArtBonus(107,Bonus::SPELL_IMMUNITY,0,61);//Pendant of Total Recall
  614. giveArtBonus(108,Bonus::MORALE,+3);//Pendant of Courage
  615. giveArtBonus(108,Bonus::LUCK,+3);//Pendant of Courage
  616. giveArtBonus(109,Bonus::GENERATE_RESOURCE,+1,4); //Everflowing Crystal Cloak
  617. giveArtBonus(110,Bonus::GENERATE_RESOURCE,+1,5); //Ring of Infinite Gems
  618. giveArtBonus(111,Bonus::GENERATE_RESOURCE,+1,1); //Everpouring Vial of Mercury
  619. giveArtBonus(112,Bonus::GENERATE_RESOURCE,+1,2); //Inexhaustible Cart of Ore
  620. giveArtBonus(113,Bonus::GENERATE_RESOURCE,+1,3); //Eversmoking Ring of Sulfur
  621. giveArtBonus(114,Bonus::GENERATE_RESOURCE,+1,0); //Inexhaustible Cart of Lumber
  622. giveArtBonus(115,Bonus::GENERATE_RESOURCE,+1000, Res::GOLD); //Endless Sack of Gold
  623. giveArtBonus(116,Bonus::GENERATE_RESOURCE,+750, Res::GOLD); //Endless Bag of Gold
  624. giveArtBonus(117,Bonus::GENERATE_RESOURCE,+500, Res::GOLD); //Endless Purse of Gold
  625. giveArtBonus(118,Bonus::CREATURE_GROWTH,+5,1, new CPropagatorNodeType(CBonusSystemNode::TOWN_AND_VISITOR)); //Legs of Legion
  626. giveArtBonus(119,Bonus::CREATURE_GROWTH,+4,2, new CPropagatorNodeType(CBonusSystemNode::TOWN_AND_VISITOR)); //Loins of Legion
  627. giveArtBonus(120,Bonus::CREATURE_GROWTH,+3,3, new CPropagatorNodeType(CBonusSystemNode::TOWN_AND_VISITOR)); //Torso of Legion
  628. giveArtBonus(121,Bonus::CREATURE_GROWTH,+2,4, new CPropagatorNodeType(CBonusSystemNode::TOWN_AND_VISITOR)); //Arms of Legion
  629. giveArtBonus(122,Bonus::CREATURE_GROWTH,+1,5, new CPropagatorNodeType(CBonusSystemNode::TOWN_AND_VISITOR)); //Head of Legion
  630. //Sea Captain's Hat
  631. giveArtBonus(123,Bonus::WHIRLPOOL_PROTECTION,0);
  632. giveArtBonus(123,Bonus::SEA_MOVEMENT,+500);
  633. giveArtBonus(123,Bonus::SPELL,3,0, Bonus::INDEPENDENT_MAX);
  634. giveArtBonus(123,Bonus::SPELL,3,1, Bonus::INDEPENDENT_MAX);
  635. giveArtBonus(124,Bonus::SPELLS_OF_LEVEL,3,1); //Spellbinder's Hat
  636. giveArtBonus(125,Bonus::ENEMY_CANT_ESCAPE,0); //Shackles of War
  637. giveArtBonus(126,Bonus::LEVEL_SPELL_IMMUNITY,GameConstants::SPELL_LEVELS,-1,Bonus::INDEPENDENT_MAX);//Orb of Inhibition
  638. //vial of dragon blood
  639. giveArtBonus(127, Bonus::PRIMARY_SKILL, +5, PrimarySkill::ATTACK, Bonus::BASE_NUMBER, new HasAnotherBonusLimiter(Bonus::DRAGON_NATURE));
  640. giveArtBonus(127, Bonus::PRIMARY_SKILL, +5, PrimarySkill::DEFENSE, Bonus::BASE_NUMBER, new HasAnotherBonusLimiter(Bonus::DRAGON_NATURE));
  641. //Armageddon's Blade
  642. giveArtBonus(128, Bonus::SPELL, 3, 26, Bonus::INDEPENDENT_MAX);
  643. giveArtBonus(128, Bonus::SPELL_IMMUNITY,0, 26);
  644. ART_ATTACK_AND_DEFENSE(128, +3);
  645. ART_PRIM_SKILL(128, 2, +3);
  646. ART_PRIM_SKILL(128, 3, +6);
  647. //Angelic Alliance
  648. giveArtBonus(129, Bonus::NONEVIL_ALIGNMENT_MIX, 0);
  649. giveArtBonus(129, Bonus::OPENING_BATTLE_SPELL, 10, 48); // Prayer
  650. //Cloak of the Undead King
  651. giveArtBonus(130, Bonus::IMPROVED_NECROMANCY, 0);
  652. //Elixir of Life
  653. giveArtBonus(131, Bonus::STACK_HEALTH, +25, -1, Bonus::PERCENT_TO_BASE);
  654. giveArtBonus(131, Bonus::HP_REGENERATION, +50);
  655. //Armor of the Damned
  656. giveArtBonus(132, Bonus::OPENING_BATTLE_SPELL, 50, 54); // Slow
  657. giveArtBonus(132, Bonus::OPENING_BATTLE_SPELL, 50, 47); // Disrupting Ray
  658. giveArtBonus(132, Bonus::OPENING_BATTLE_SPELL, 50, 45); // Weakness
  659. giveArtBonus(132, Bonus::OPENING_BATTLE_SPELL, 50, 52); // Misfortune
  660. // Statue of Legion - gives only 50% growth
  661. giveArtBonus(133, Bonus::CREATURE_GROWTH_PERCENT, 50, -1, new CPropagatorNodeType(CBonusSystemNode::PLAYER));
  662. //Power of the Dragon Father
  663. giveArtBonus(134, Bonus::LEVEL_SPELL_IMMUNITY, 4, -1, Bonus::INDEPENDENT_MAX);
  664. //Titan's Thunder
  665. giveArtBonus(135, Bonus::SPELL, 3, 57);
  666. //Admiral's Hat
  667. giveArtBonus(136, Bonus::FREE_SHIP_BOARDING, 0);
  668. //Bow of the Sharpshooter
  669. giveArtBonus(137, Bonus::NO_DISTANCE_PENALTY, 0, 0, 0, new HasAnotherBonusLimiter(Bonus::SHOOTER));
  670. giveArtBonus(137, Bonus::NO_WALL_PENALTY, 0, 0, 0, new HasAnotherBonusLimiter(Bonus::SHOOTER));
  671. giveArtBonus(137, Bonus::FREE_SHOOTING, 0, 0, 0, new HasAnotherBonusLimiter(Bonus::SHOOTER));
  672. //Wizard's Well
  673. giveArtBonus(138, Bonus::FULL_MANA_REGENERATION, 0);
  674. //Ring of the Magi
  675. giveArtBonus(139, Bonus::SPELL_DURATION, +50);
  676. //Cornucopia
  677. giveArtBonus(140, Bonus::GENERATE_RESOURCE, +4, Res::MERCURY);
  678. giveArtBonus(140, Bonus::GENERATE_RESOURCE, +4, Res::SULFUR);
  679. giveArtBonus(140, Bonus::GENERATE_RESOURCE, +4, Res::CRYSTAL);
  680. giveArtBonus(140, Bonus::GENERATE_RESOURCE, +4, Res::GEMS);
  681. //Stack artifact test
  682. if (GameConstants::STACK_ARTIFACT)
  683. {
  684. makeItCreatureArt(141);
  685. makeItCreatureArt(142);
  686. makeItCreatureArt(143);
  687. makeItCreatureArt(156);
  688. //Magic Wand
  689. giveArtBonus(141, Bonus::CASTS, 10);
  690. giveArtBonus(141, Bonus::SPELLCASTER, 0, Spells::IMPLOSION);
  691. giveArtBonus(141, Bonus::SPELLCASTER, 0, Spells::FIREBALL);
  692. giveArtBonus(141, Bonus::RANDOM_SPELLCASTER, 0);
  693. giveArtBonus(141, Bonus::DAEMON_SUMMONING, 10, 63); //rise vampire lords
  694. giveArtBonus(141, Bonus::ENCHANTER, 0, Spells::LIGHTNING_BOLT, NULL, 2);
  695. giveArtBonus(141, Bonus::REBIRTH, 1, 1);
  696. giveArtBonus(141, Bonus::MANA_DRAIN, 10);
  697. giveArtBonus(141, Bonus::HEALER, 25);
  698. artifacts[141].get()->setDescription ("Casts Implosion / Fireball, random Genie spell, summons Vampire Lords from corpses, casts Lighthning Bolt every 2 turns, rebirths at least one creature, drains enemy mana and heals");
  699. //Tower Arrow
  700. giveArtBonus(142, Bonus::NO_DISTANCE_PENALTY, 0);
  701. giveArtBonus(142, Bonus::ADDITIONAL_ATTACK, 2);
  702. giveArtBonus(142, Bonus::SPELL_LIKE_ATTACK, 1, Spells::INFERNO);
  703. giveArtBonus(142, Bonus::CATAPULT, 0);
  704. giveArtBonus(142, Bonus::ACID_BREATH, 20);
  705. giveArtBonus(142, Bonus::SHOTS, 200, 0, Bonus::PERCENT_TO_BASE);
  706. giveArtBonus(142, Bonus::SPELL_BEFORE_ATTACK, 50, Spells::AGE, NULL, 1);
  707. giveArtBonus(142, Bonus::SPELL_AFTER_ATTACK, 50, Spells::BERSERK, NULL, 1);
  708. giveArtBonus(142, Bonus::SPELL_AFTER_ATTACK, 50, Spells::POISON, NULL, 1);
  709. giveArtBonus(142, Bonus::SPELL_AFTER_ATTACK, 50, Spells::DISRUPTING_RAY, NULL, 1);
  710. artifacts[142].get()->setDescription ("Tripple shots, tripple attack, casts various spells during attack, attacks have range of Inferno, no distance penalty, catapult");
  711. //Monster's Power
  712. giveArtBonus(143, Bonus::STACK_HEALTH, +100, -1, Bonus::PERCENT_TO_BASE);
  713. giveArtBonus(143, Bonus::CREATURE_DAMAGE, +100, 2, Bonus::PERCENT_TO_ALL);
  714. giveArtBonus(143, Bonus::HP_REGENERATION, 50);
  715. giveArtBonus(143, Bonus::NO_RETALIATION, 0);
  716. giveArtBonus(143, Bonus::RETURN_AFTER_STRIKE, 0);
  717. giveArtBonus(143, Bonus::ATTACKS_ALL_ADJACENT, 0);
  718. giveArtBonus(143, Bonus::SPELL_RESISTANCE_AURA, 100);
  719. giveArtBonus(143, Bonus::DIRECT_DAMAGE_IMMUNITY, 0);
  720. artifacts[143].get()->setDescription ("Double health, double max damage, hp regeneration, can't retaliate, return after strike, attack all around, 100% spell reisstance aura, immune to direct damage spells");
  721. //Warlord's banner
  722. giveArtBonus(156, Bonus::STACK_HEALTH, +2);
  723. artifacts[156].get()->setDescription ("+2 stack HP");
  724. }
  725. if (GameConstants::COMMANDERS)
  726. {
  727. for (int i = 146; i <= 155; ++i)
  728. {
  729. makeItCommanderArt (i);
  730. }
  731. }
  732. }
  733. void CArtHandler::clear()
  734. {
  735. BOOST_FOREACH(CArtifact *art, artifacts)
  736. delete art;
  737. artifacts.clear();
  738. clearHlpLists();
  739. }
  740. // /**
  741. // * Locally equips an artifact to a hero's worn slots. Unequips an already present artifact.
  742. // * Does not test if the operation is legal.
  743. // * @param artifWorn A hero's set of worn artifacts.
  744. // * @param bonuses Optional list of bonuses to update.
  745. // */
  746. // void CArtHandler::equipArtifact( std::map<ui16, const CArtifact*> &artifWorn, ui16 slotID, const CArtifact* art ) const
  747. // {
  748. // unequipArtifact(artifWorn, slotID);
  749. //
  750. // if (art) //false when artifact is NULL -> slot set to empty
  751. // {
  752. // const CArtifact &artifact = *art;
  753. //
  754. // // Add artifact.
  755. // artifWorn[slotID] = art;
  756. //
  757. // // Add locks, in reverse order of being removed.
  758. // if (artifact.constituents != NULL)
  759. // {
  760. // bool destConsumed = false; // Determines which constituent that will be counted for together with the artifact.
  761. //
  762. // BOOST_FOREACH(ui32 constituentID, *artifact.constituents)
  763. // {
  764. // const CArtifact &constituent = *artifacts[constituentID];
  765. //
  766. // if (!destConsumed && vstd::contains(constituent.possibleSlots, slotID))
  767. // {
  768. // destConsumed = true;
  769. // }
  770. // else
  771. // {
  772. // BOOST_FOREACH(ui16 slot, constituent.possibleSlots)
  773. // {
  774. // if (!vstd::contains(artifWorn, slot))
  775. // {
  776. // artifWorn[slot] = VLC->arth->artifacts[145]; //lock
  777. // break;
  778. // }
  779. // }
  780. // }
  781. // }
  782. // }
  783. // }
  784. // }
  785. //
  786. // /**
  787. // * Locally unequips an artifact from a hero's worn slots.
  788. // * Does not test if the operation is legal.
  789. // * @param artifWorn A hero's set of worn artifacts.
  790. // * @param bonuses Optional list of bonuses to update.
  791. // */
  792. // void CArtHandler::unequipArtifact(std::map<ui16, const CArtifact*> &artifWorn, ui16 slotID) const
  793. // {
  794. // if (!vstd::contains(artifWorn, slotID))
  795. // return;
  796. //
  797. // const CArtifact &artifact = *artifWorn[slotID];
  798. //
  799. // // Remove artifact, if it's not already removed.
  800. // artifWorn.erase(slotID);
  801. //
  802. // // Remove locks, in reverse order of being added.
  803. // if (artifact.constituents != NULL)
  804. // {
  805. // bool destConsumed = false;
  806. //
  807. // BOOST_FOREACH(ui32 constituentID, *artifact.constituents)
  808. // {
  809. // const CArtifact &constituent = *artifacts[constituentID];
  810. //
  811. // if (!destConsumed && vstd::contains(constituent.possibleSlots, slotID))
  812. // {
  813. // destConsumed = true;
  814. // }
  815. // else
  816. // {
  817. // BOOST_REVERSE_FOREACH(ui16 slot, constituent.possibleSlots)
  818. // {
  819. // if (vstd::contains(artifWorn, slot) && artifWorn[slot]->id == 145)
  820. // {
  821. // artifWorn.erase(slot);
  822. // break;
  823. // }
  824. // }
  825. // }
  826. // }
  827. // }
  828. // }
  829. void CArtHandler::clearHlpLists()
  830. {
  831. treasures.clear();
  832. minors.clear();
  833. majors.clear();
  834. relics.clear();
  835. }
  836. void CArtHandler::initAllowedArtifactsList(const std::vector<ui8> &allowed)
  837. {
  838. allowedArtifacts.clear();
  839. clearHlpLists();
  840. for (int i=0; i<144; ++i) //yes, 144
  841. {
  842. if (allowed[i])
  843. allowedArtifacts.push_back(artifacts[i]);
  844. }
  845. if (GameConstants::COMMANDERS) //allow all commander artifacts for testing
  846. {
  847. for (int i = 146; i <= 155; ++i)
  848. {
  849. allowedArtifacts.push_back(artifacts[i]);
  850. }
  851. }
  852. }
  853. CArtifactInstance::CArtifactInstance()
  854. {
  855. init();
  856. }
  857. CArtifactInstance::CArtifactInstance( CArtifact *Art)
  858. {
  859. init();
  860. setType(Art);
  861. }
  862. // CArtifactInstance::CArtifactInstance(int aid)
  863. // {
  864. // init();
  865. // setType(VLC->arth->artifacts[aid]);
  866. // }
  867. void CArtifactInstance::setType( CArtifact *Art )
  868. {
  869. artType = Art;
  870. attachTo(Art);
  871. }
  872. std::string CArtifactInstance::nodeName() const
  873. {
  874. return "Artifact instance of " + (artType ? artType->Name() : std::string("uninitialized")) + " type";
  875. }
  876. CArtifactInstance * CArtifactInstance::createScroll( const CSpell *s)
  877. {
  878. CArtifactInstance *ret = new CArtifactInstance(VLC->arth->artifacts[1]);
  879. Bonus *b = new Bonus(Bonus::PERMANENT, Bonus::SPELL, Bonus::ARTIFACT_INSTANCE, -1, 1, s->id);
  880. ret->addNewBonus(b);
  881. return ret;
  882. }
  883. void CArtifactInstance::init()
  884. {
  885. id = -1;
  886. setNodeType(ARTIFACT_INSTANCE);
  887. }
  888. int CArtifactInstance::firstAvailableSlot(const CArtifactSet *h) const
  889. {
  890. BOOST_FOREACH(ui16 slot, artType->possibleSlots[h->bearerType()])
  891. {
  892. if(canBePutAt(h, slot)) //if(artType->fitsAt(h->artifWorn, slot))
  893. {
  894. //we've found a free suitable slot.
  895. return slot;
  896. }
  897. }
  898. //if haven't find proper slot, use backpack
  899. return firstBackpackSlot(h);
  900. }
  901. int CArtifactInstance::firstBackpackSlot(const CArtifactSet *h) const
  902. {
  903. if(!artType->isBig()) //discard big artifact
  904. return GameConstants::BACKPACK_START + h->artifactsInBackpack.size();
  905. return -1;
  906. }
  907. bool CArtifactInstance::canBePutAt(const ArtifactLocation al, bool assumeDestRemoved /*= false*/) const
  908. {
  909. return canBePutAt(al.getHolderArtSet(), al.slot, assumeDestRemoved);
  910. }
  911. bool CArtifactInstance::canBePutAt(const CArtifactSet *artSet, int slot, bool assumeDestRemoved /*= false*/) const
  912. {
  913. if(slot >= GameConstants::BACKPACK_START)
  914. {
  915. if(artType->isBig())
  916. return false;
  917. //TODO backpack limit
  918. return true;
  919. }
  920. auto possibleSlots = artType->possibleSlots.find(artSet->bearerType());
  921. if(possibleSlots == artType->possibleSlots.end())
  922. {
  923. tlog3 << "Warning: arrtifact " << artType->Name() << " doesn't have defined allowed slots for bearer of type "
  924. << artSet->bearerType() << std::endl;
  925. return false;
  926. }
  927. if(!vstd::contains(possibleSlots->second, slot))
  928. return false;
  929. return artSet->isPositionFree(slot, assumeDestRemoved);
  930. }
  931. void CArtifactInstance::putAt(ArtifactLocation al)
  932. {
  933. assert(canBePutAt(al));
  934. al.getHolderArtSet()->setNewArtSlot(al.slot, this, false);
  935. if(al.slot < GameConstants::BACKPACK_START)
  936. al.getHolderNode()->attachTo(this);
  937. }
  938. void CArtifactInstance::removeFrom(ArtifactLocation al)
  939. {
  940. assert(al.getHolderArtSet()->getArt(al.slot) == this);
  941. al.getHolderArtSet()->eraseArtSlot(al.slot);
  942. if(al.slot < GameConstants::BACKPACK_START)
  943. al.getHolderNode()->detachFrom(this);
  944. //TODO delete me?
  945. }
  946. bool CArtifactInstance::canBeDisassembled() const
  947. {
  948. return artType->constituents && artType->constituentOf->size();
  949. }
  950. std::vector<const CArtifact *> CArtifactInstance::assemblyPossibilities(const CArtifactSet *h) const
  951. {
  952. std::vector<const CArtifact *> ret;
  953. if(!artType->constituentOf //not a part of combined artifact
  954. || artType->constituents) //combined artifact already: no combining of combined artifacts... for now.
  955. return ret;
  956. BOOST_FOREACH(ui32 possibleCombinedArt, *artType->constituentOf)
  957. {
  958. const CArtifact * const artifact = VLC->arth->artifacts[possibleCombinedArt];
  959. assert(artifact->constituents);
  960. bool possible = true;
  961. BOOST_FOREACH(ui32 constituentID, *artifact->constituents) //check if all constituents are available
  962. {
  963. if(!h->hasArt(constituentID, true)) //constituent must be equipped
  964. {
  965. possible = false;
  966. break;
  967. }
  968. }
  969. if(possible)
  970. ret.push_back(artifact);
  971. }
  972. return ret;
  973. }
  974. void CArtifactInstance::move(ArtifactLocation src, ArtifactLocation dst)
  975. {
  976. removeFrom(src);
  977. putAt(dst);
  978. }
  979. CArtifactInstance * CArtifactInstance::createNewArtifactInstance(CArtifact *Art)
  980. {
  981. if(!Art->constituents)
  982. return new CArtifactInstance(Art);
  983. else
  984. {
  985. CCombinedArtifactInstance * ret = new CCombinedArtifactInstance(Art);
  986. ret->createConstituents();
  987. return ret;
  988. }
  989. }
  990. CArtifactInstance * CArtifactInstance::createNewArtifactInstance(int aid)
  991. {
  992. return createNewArtifactInstance(VLC->arth->artifacts[aid]);
  993. }
  994. void CArtifactInstance::deserializationFix()
  995. {
  996. setType(artType);
  997. }
  998. int CArtifactInstance::getGivenSpellID() const
  999. {
  1000. const Bonus * b = getBonus(Selector::type(Bonus::SPELL));
  1001. if(!b)
  1002. {
  1003. tlog3 << "Warning: " << nodeName() << " doesn't bear any spell!\n";
  1004. return -1;
  1005. }
  1006. return b->subtype;
  1007. }
  1008. bool CArtifactInstance::isPart(const CArtifactInstance *supposedPart) const
  1009. {
  1010. return supposedPart == this;
  1011. }
  1012. bool CCombinedArtifactInstance::canBePutAt(const CArtifactSet *artSet, int slot, bool assumeDestRemoved /*= false*/) const
  1013. {
  1014. bool canMainArtifactBePlaced = CArtifactInstance::canBePutAt(artSet, slot, assumeDestRemoved);
  1015. if(!canMainArtifactBePlaced)
  1016. return false; //no is no...
  1017. if(slot >= GameConstants::BACKPACK_START)
  1018. return true; //we can always remove combined art to the backapck
  1019. assert(artType->constituents);
  1020. std::vector<ConstituentInfo> constituentsToBePlaced = constituentsInfo; //we'll remove constituents from that list, as we find a suitable slot for them
  1021. //it may be that we picked a combined artifact in hero screen (though technically it's still there) to move it
  1022. //so we remove from the list all constituents that are already present on dst hero in the form of locks
  1023. BOOST_FOREACH(const ConstituentInfo &constituent, constituentsInfo)
  1024. {
  1025. if(constituent.art == artSet->getArt(constituent.slot, false)) //no need to worry about locked constituent
  1026. constituentsToBePlaced -= constituent;
  1027. }
  1028. //we iterate over all active slots and check if constituents fits them
  1029. for (int i = 0; i < GameConstants::BACKPACK_START; i++)
  1030. {
  1031. for(std::vector<ConstituentInfo>::iterator art = constituentsToBePlaced.begin(); art != constituentsToBePlaced.end(); art++)
  1032. {
  1033. if(art->art->canBePutAt(artSet, i, i == slot)) // i == al.slot because we can remove already worn artifact only from that slot that is our main destination
  1034. {
  1035. constituentsToBePlaced.erase(art);
  1036. break;
  1037. }
  1038. }
  1039. }
  1040. return constituentsToBePlaced.empty();
  1041. }
  1042. bool CCombinedArtifactInstance::canBeDisassembled() const
  1043. {
  1044. return true;
  1045. }
  1046. CCombinedArtifactInstance::CCombinedArtifactInstance(CArtifact *Art)
  1047. : CArtifactInstance(Art) //TODO: seems unued, but need to be written
  1048. {
  1049. }
  1050. CCombinedArtifactInstance::CCombinedArtifactInstance()
  1051. {
  1052. }
  1053. void CCombinedArtifactInstance::createConstituents()
  1054. {
  1055. assert(artType);
  1056. assert(artType->constituents);
  1057. BOOST_FOREACH(ui32 a, *artType->constituents)
  1058. {
  1059. addAsConstituent(CArtifactInstance::createNewArtifactInstance(a), -1);
  1060. }
  1061. }
  1062. void CCombinedArtifactInstance::addAsConstituent(CArtifactInstance *art, int slot)
  1063. {
  1064. assert(vstd::contains(*artType->constituents, art->artType->id));
  1065. assert(art->getParentNodes().size() == 1 && art->getParentNodes().front() == art->artType);
  1066. constituentsInfo.push_back(ConstituentInfo(art, slot));
  1067. attachTo(art);
  1068. }
  1069. void CCombinedArtifactInstance::putAt(ArtifactLocation al)
  1070. {
  1071. if(al.slot >= GameConstants::BACKPACK_START)
  1072. {
  1073. CArtifactInstance::putAt(al);
  1074. BOOST_FOREACH(ConstituentInfo &ci, constituentsInfo)
  1075. ci.slot = -1;
  1076. }
  1077. else
  1078. {
  1079. CArtifactInstance *mainConstituent = figureMainConstituent(al); //it'll be replaced with combined artifact, not a lock
  1080. CArtifactInstance::putAt(al); //puts combined art (this)
  1081. BOOST_FOREACH(ConstituentInfo &ci, constituentsInfo)
  1082. {
  1083. if(ci.art != mainConstituent)
  1084. {
  1085. const ArtifactLocation suggestedPos(al.artHolder, ci.slot);
  1086. const bool inActiveSlot = vstd::isbetween(ci.slot, 0, GameConstants::BACKPACK_START);
  1087. const bool suggestedPosValid = ci.art->canBePutAt(suggestedPos);
  1088. int pos = -1;
  1089. if(inActiveSlot && suggestedPosValid) //there is a valid suggestion where to place lock
  1090. pos = ci.slot;
  1091. else
  1092. ci.slot = pos = ci.art->firstAvailableSlot(al.getHolderArtSet());
  1093. assert(pos < GameConstants::BACKPACK_START);
  1094. al.getHolderArtSet()->setNewArtSlot(pos, ci.art, true); //sets as lock
  1095. }
  1096. else
  1097. {
  1098. ci.slot = -1;
  1099. }
  1100. }
  1101. }
  1102. }
  1103. void CCombinedArtifactInstance::removeFrom(ArtifactLocation al)
  1104. {
  1105. if(al.slot >= GameConstants::BACKPACK_START)
  1106. {
  1107. CArtifactInstance::removeFrom(al);
  1108. }
  1109. else
  1110. {
  1111. BOOST_FOREACH(ConstituentInfo &ci, constituentsInfo)
  1112. {
  1113. if(ci.slot >= 0)
  1114. {
  1115. al.getHolderArtSet()->eraseArtSlot(ci.slot);
  1116. ci.slot = -1;
  1117. }
  1118. else
  1119. {
  1120. //main constituent
  1121. CArtifactInstance::removeFrom(al);
  1122. }
  1123. }
  1124. }
  1125. }
  1126. CArtifactInstance * CCombinedArtifactInstance::figureMainConstituent(const ArtifactLocation al)
  1127. {
  1128. CArtifactInstance *mainConstituent = NULL; //it'll be replaced with combined artifact, not a lock
  1129. BOOST_FOREACH(ConstituentInfo &ci, constituentsInfo)
  1130. if(ci.slot == al.slot)
  1131. mainConstituent = ci.art;
  1132. if(!mainConstituent)
  1133. {
  1134. BOOST_FOREACH(ConstituentInfo &ci, constituentsInfo)
  1135. {
  1136. if(vstd::contains(ci.art->artType->possibleSlots[al.getHolderArtSet()->bearerType()], al.slot))
  1137. {
  1138. mainConstituent = ci.art;
  1139. }
  1140. }
  1141. }
  1142. return mainConstituent;
  1143. }
  1144. void CCombinedArtifactInstance::deserializationFix()
  1145. {
  1146. BOOST_FOREACH(ConstituentInfo &ci, constituentsInfo)
  1147. attachTo(ci.art);
  1148. }
  1149. bool CCombinedArtifactInstance::isPart(const CArtifactInstance *supposedPart) const
  1150. {
  1151. bool me = CArtifactInstance::isPart(supposedPart);
  1152. if(me)
  1153. return true;
  1154. //check for constituents
  1155. BOOST_FOREACH(const ConstituentInfo &constituent, constituentsInfo)
  1156. if(constituent.art == supposedPart)
  1157. return true;
  1158. return false;
  1159. }
  1160. CCombinedArtifactInstance::ConstituentInfo::ConstituentInfo(CArtifactInstance *Art /*= NULL*/, ui16 Slot /*= -1*/)
  1161. {
  1162. art = Art;
  1163. slot = Slot;
  1164. }
  1165. bool CCombinedArtifactInstance::ConstituentInfo::operator==(const ConstituentInfo &rhs) const
  1166. {
  1167. return art == rhs.art && slot == rhs.slot;
  1168. }
  1169. const CArtifactInstance* CArtifactSet::getArt(ui16 pos, bool excludeLocked /*= true*/) const
  1170. {
  1171. if(const ArtSlotInfo *si = getSlot(pos))
  1172. {
  1173. if(si->artifact && (!excludeLocked || !si->locked))
  1174. return si->artifact;
  1175. }
  1176. return NULL;
  1177. }
  1178. CArtifactInstance* CArtifactSet::getArt(ui16 pos, bool excludeLocked /*= true*/)
  1179. {
  1180. return const_cast<CArtifactInstance*>((const_cast<const CArtifactSet*>(this))->getArt(pos, excludeLocked));
  1181. }
  1182. si32 CArtifactSet::getArtPos(int aid, bool onlyWorn /*= true*/) const
  1183. {
  1184. for(std::map<ui16, ArtSlotInfo>::const_iterator i = artifactsWorn.begin(); i != artifactsWorn.end(); i++)
  1185. if(i->second.artifact->artType->id == aid)
  1186. return i->first;
  1187. if(onlyWorn)
  1188. return -1;
  1189. for(int i = 0; i < artifactsInBackpack.size(); i++)
  1190. if(artifactsInBackpack[i].artifact->artType->id == aid)
  1191. return GameConstants::BACKPACK_START + i;
  1192. return -1;
  1193. }
  1194. si32 CArtifactSet::getArtPos(const CArtifactInstance *art) const
  1195. {
  1196. for(std::map<ui16, ArtSlotInfo>::const_iterator i = artifactsWorn.begin(); i != artifactsWorn.end(); i++)
  1197. if(i->second.artifact == art)
  1198. return i->first;
  1199. for(int i = 0; i < artifactsInBackpack.size(); i++)
  1200. if(artifactsInBackpack[i].artifact == art)
  1201. return GameConstants::BACKPACK_START + i;
  1202. return -1;
  1203. }
  1204. const CArtifactInstance * CArtifactSet::getArtByInstanceId(int artInstId) const
  1205. {
  1206. for(std::map<ui16, ArtSlotInfo>::const_iterator i = artifactsWorn.begin(); i != artifactsWorn.end(); i++)
  1207. if(i->second.artifact->id == artInstId)
  1208. return i->second.artifact;
  1209. for(int i = 0; i < artifactsInBackpack.size(); i++)
  1210. if(artifactsInBackpack[i].artifact->id == artInstId)
  1211. return artifactsInBackpack[i].artifact;
  1212. return NULL;
  1213. }
  1214. bool CArtifactSet::hasArt(ui32 aid, bool onlyWorn /*= false*/) const
  1215. {
  1216. return getArtPos(aid, onlyWorn) != -1;
  1217. }
  1218. const ArtSlotInfo * CArtifactSet::getSlot(ui16 pos) const
  1219. {
  1220. if(vstd::contains(artifactsWorn, pos))
  1221. return &artifactsWorn[pos];
  1222. if(pos >= ArtifactPosition::AFTER_LAST )
  1223. {
  1224. int backpackPos = (int)pos - GameConstants::BACKPACK_START;
  1225. if(backpackPos < 0 || backpackPos >= artifactsInBackpack.size())
  1226. return NULL;
  1227. else
  1228. return &artifactsInBackpack[backpackPos];
  1229. }
  1230. return NULL;
  1231. }
  1232. bool CArtifactSet::isPositionFree(ui16 pos, bool onlyLockCheck /*= false*/) const
  1233. {
  1234. if(const ArtSlotInfo *s = getSlot(pos))
  1235. return (onlyLockCheck || !s->artifact) && !s->locked;
  1236. return true; //no slot means not used
  1237. }
  1238. si32 CArtifactSet::getArtTypeId(ui16 pos) const
  1239. {
  1240. const CArtifactInstance * const a = getArt(pos);
  1241. if(!a)
  1242. {
  1243. tlog2 << (dynamic_cast<const CGHeroInstance*>(this))->name << " has no artifact at " << pos << " (getArtTypeId)\n";
  1244. return -1;
  1245. }
  1246. return a->artType->id;
  1247. }
  1248. CArtifactSet::~CArtifactSet()
  1249. {
  1250. }
  1251. ArtSlotInfo & CArtifactSet::retreiveNewArtSlot(ui16 slot)
  1252. {
  1253. assert(!vstd::contains(artifactsWorn, slot));
  1254. ArtSlotInfo &ret = slot < GameConstants::BACKPACK_START
  1255. ? artifactsWorn[slot]
  1256. : *artifactsInBackpack.insert(artifactsInBackpack.begin() + (slot - GameConstants::BACKPACK_START), ArtSlotInfo());
  1257. return ret;
  1258. }
  1259. void CArtifactSet::setNewArtSlot(ui16 slot, CArtifactInstance *art, bool locked)
  1260. {
  1261. ArtSlotInfo &asi = retreiveNewArtSlot(slot);
  1262. asi.artifact = art;
  1263. asi.locked = locked;
  1264. }
  1265. void CArtifactSet::eraseArtSlot(ui16 slot)
  1266. {
  1267. if(slot < GameConstants::BACKPACK_START)
  1268. {
  1269. artifactsWorn.erase(slot);
  1270. }
  1271. else
  1272. {
  1273. slot -= GameConstants::BACKPACK_START;
  1274. artifactsInBackpack.erase(artifactsInBackpack.begin() + slot);
  1275. }
  1276. }
  1277. void CArtifactSet::artDeserializationFix(CBonusSystemNode *node)
  1278. {
  1279. for(bmap<ui16, ArtSlotInfo>::iterator i = artifactsWorn.begin(); i != artifactsWorn.end(); i++)
  1280. if(i->second.artifact && !i->second.locked)
  1281. node->attachTo(i->second.artifact);
  1282. }