2011-12-14 00:23:17 +03:00
# include "StdInc.h"
2007-06-07 23:16:19 +03:00
# include "CArtHandler.h"
2011-12-14 00:23:17 +03:00
2012-08-01 15:02:54 +03:00
# include "Filesystem/CResourceLoader.h"
2008-11-30 02:15:38 +02:00
# include "CGeneralTextHandler.h"
2010-06-28 08:07:21 +03:00
# include <boost/random/linear_congruential.hpp>
2012-08-01 15:02:54 +03:00
# include "VCMI_Lib.h"
2012-08-24 12:37:52 +03:00
# include "CModHandler.h"
2010-12-17 20:47:07 +02:00
# include "CSpellHandler.h"
2010-12-26 16:34:11 +02:00
# include "CObjectHandler.h"
# include "NetPacks.h"
2012-08-01 15:02:54 +03:00
# include "JsonNode.h"
2010-12-26 16:34:11 +02:00
2008-06-13 11:16:51 +03:00
using namespace boost : : assign ;
2009-04-04 01:34:31 +03:00
2009-04-15 17:03:31 +03:00
/*
* CArtHandler . cpp , part of VCMI engine
*
* Authors : listed in file AUTHORS in main folder
*
* License : GNU General Public License v2 .0 or later
* Full text of license available in license . txt file , in main folder
*
*/
2010-06-28 08:07:21 +03:00
extern boost : : rand48 ran ;
2012-07-16 19:18:02 +03:00
extern Bonus * ParseBonus ( const JsonVector & ability_vec ) ;
2010-06-28 08:07:21 +03:00
2009-04-04 01:34:31 +03:00
const std : : string & CArtifact : : Name ( ) const
{
if ( name . size ( ) )
return name ;
else
return VLC - > generaltexth - > artifNames [ id ] ;
}
const std : : string & CArtifact : : Description ( ) const
{
if ( description . size ( ) )
return description ;
else
return VLC - > generaltexth - > artifDescriptions [ id ] ;
}
2009-12-30 17:33:28 +02:00
2010-02-09 04:17:38 +02:00
bool CArtifact : : isBig ( ) const
2009-12-30 17:33:28 +02:00
{
return VLC - > arth - > isBigArtifact ( id ) ;
}
2011-01-28 04:11:58 +02:00
// /**
// * Checks whether the artifact fits at a given slot.
// * @param artifWorn A hero's set of worn artifacts.
// */
// bool CArtifact::fitsAt (const std::map<ui16, const CArtifact*> &artifWorn, ui16 slotID) const
// {
// if (!vstd::contains(possibleSlots, slotID))
// return false;
2012-09-15 22:16:16 +03:00
//
2011-01-28 04:11:58 +02:00
// // Can't put an artifact in a locked slot.
// std::map<ui16, const CArtifact*>::const_iterator it = artifWorn.find(slotID);
// if (it != artifWorn.end() && it->second->id == 145)
// return false;
2012-09-15 22:16:16 +03:00
//
2011-01-28 04:11:58 +02:00
// // Check if a combination artifact fits.
// // TODO: Might want a more general algorithm?
// // Assumes that misc & rings fits only in their slots, and others in only one slot and no duplicates.
// if (constituents != NULL)
// {
// std::map<ui16, const CArtifact*> tempArtifWorn = artifWorn;
// const ui16 ringSlots[] = {6, 7};
// const ui16 miscSlots[] = {9, 10, 11, 12, 18};
// int rings = 0;
// int misc = 0;
2012-09-15 22:16:16 +03:00
//
2011-01-28 04:11:58 +02:00
// VLC->arth->unequipArtifact(tempArtifWorn, slotID);
2012-09-15 22:16:16 +03:00
//
// BOOST_FOREACH(ui32 constituentID, *constituents)
2011-01-28 04:11:58 +02:00
// {
// const CArtifact& constituent = *VLC->arth->artifacts[constituentID];
// const int slot = constituent.possibleSlots[0];
2012-09-15 22:16:16 +03:00
//
2011-01-28 04:11:58 +02:00
// if (slot == 6 || slot == 7)
// rings++;
// else if ((slot >= 9 && slot <= 12) || slot == 18)
// misc++;
// else if (tempArtifWorn.find(slot) != tempArtifWorn.end())
// return false;
// }
2012-09-15 22:16:16 +03:00
//
2011-01-28 04:11:58 +02:00
// // Ensure enough ring slots are free
2012-09-15 22:16:16 +03:00
// for (int i = 0; i < sizeof(ringSlots)/sizeof(*ringSlots); i++)
2011-01-28 04:11:58 +02:00
// {
// if (tempArtifWorn.find(ringSlots[i]) == tempArtifWorn.end() || ringSlots[i] == slotID)
// rings--;
// }
// if (rings > 0)
// return false;
2012-09-15 22:16:16 +03:00
//
2011-01-28 04:11:58 +02:00
// // Ensure enough misc slots are free.
2012-09-15 22:16:16 +03:00
// for (int i = 0; i < sizeof(miscSlots)/sizeof(*miscSlots); i++)
2011-01-28 04:11:58 +02:00
// {
// if (tempArtifWorn.find(miscSlots[i]) == tempArtifWorn.end() || miscSlots[i] == slotID)
// misc--;
// }
// if (misc > 0)
// return false;
// }
2012-09-15 22:16:16 +03:00
//
2011-01-28 04:11:58 +02:00
// return true;
// }
2010-02-08 23:17:22 +02:00
2011-01-18 20:56:14 +02:00
// bool CArtifact::canBeAssembledTo (const std::map<ui16, const CArtifact*> &artifWorn, ui32 artifactID) const
// {
// if (constituentOf == NULL || !vstd::contains(*constituentOf, artifactID))
// return false;
2012-09-15 22:16:16 +03:00
//
2011-01-18 20:56:14 +02:00
// const CArtifact &artifact = *VLC->arth->artifacts[artifactID];
// assert(artifact.constituents);
2012-09-15 22:16:16 +03:00
//
// BOOST_FOREACH(ui32 constituentID, *artifact.constituents)
2011-01-18 20:56:14 +02:00
// {
// bool found = false;
2012-09-15 22:16:16 +03:00
// for (std::map<ui16, const CArtifact*>::const_iterator it = artifWorn.begin(); it != artifWorn.end(); ++it)
2011-01-18 20:56:14 +02:00
// {
2012-09-15 22:16:16 +03:00
// if (it->second->id == constituentID)
2011-01-18 20:56:14 +02:00
// {
// found = true;
// break;
// }
// }
// if (!found)
// return false;
// }
2012-09-15 22:16:16 +03:00
//
2011-01-18 20:56:14 +02:00
// return true;
// }
2010-02-16 16:39:56 +02:00
2010-07-20 21:34:32 +03:00
CArtifact : : CArtifact ( )
2010-05-09 22:10:59 +03:00
{
2011-07-13 21:39:02 +03:00
setNodeType ( ARTIFACT ) ;
2010-05-09 22:10:59 +03:00
}
2010-07-20 21:34:32 +03:00
CArtifact : : ~ CArtifact ( )
2010-05-09 22:10:59 +03:00
{
}
2010-07-23 15:02:15 +03:00
int CArtifact : : getArtClassSerial ( ) const
{
if ( id = = 1 )
return 4 ;
switch ( aClass )
{
case ART_TREASURE :
return 0 ;
case ART_MINOR :
return 1 ;
case ART_MAJOR :
return 2 ;
case ART_RELIC :
return 3 ;
case ART_SPECIAL :
return 5 ;
}
return - 1 ;
}
2010-12-17 20:47:07 +02:00
std : : string CArtifact : : nodeName ( ) const
{
return " Artifact: " + Name ( ) ;
}
2010-11-13 22:26:15 +02:00
// void CArtifact::getParents(TCNodes &out, const CBonusSystemNode *root /*= NULL*/) const
// {
// //combined artifact carries bonuses from its parts
// if(constituents)
// {
// BOOST_FOREACH(ui32 id, *constituents)
// out.insert(VLC->arth->artifacts[id]);
// }
// }
2010-07-26 18:37:58 +03:00
2011-01-28 04:11:58 +02:00
// void CScroll::Init()
// {
// // addNewBonus (Bonus (Bonus::PERMANENT, Bonus::SPELL, Bonus::ARTIFACT, 1, id, spellid, Bonus::INDEPENDENT_MAX));
// // //boost::algorithm::replace_first(description, "[spell name]", VLC->spellh->spells[spellid].name);
// }
2010-11-10 02:06:25 +02:00
2012-04-17 11:46:09 +03:00
void CArtifact : : setDescription ( std : : string desc )
{
description = desc ;
}
2012-07-16 19:18:02 +03:00
void CGrowingArtifact : : levelUpArtifact ( CArtifactInstance * art )
{
Bonus b ;
b . type = Bonus : : LEVEL_COUNTER ;
b . val = 1 ;
b . duration = Bonus : : COMMANDER_KILLED ;
art - > accumulateBonus ( b ) ;
BOOST_FOREACH ( auto bonus , bonusesPerLevel )
{
if ( art - > valOfBonuses ( Bonus : : LEVEL_COUNTER ) % bonus . first = = 0 ) //every n levels
{
art - > accumulateBonus ( bonus . second ) ;
}
}
BOOST_FOREACH ( auto bonus , thresholdBonuses )
{
if ( art - > valOfBonuses ( Bonus : : LEVEL_COUNTER ) = = bonus . first ) //every n levels
{
art - > addNewBonus ( & bonus . second ) ;
}
}
}
2008-06-17 20:48:32 +03:00
CArtHandler : : CArtHandler ( )
{
VLC - > arth = this ;
2009-12-02 01:19:43 +02:00
// War machines are the default big artifacts.
for ( ui32 i = 3 ; i < = 6 ; i + + )
bigArtifacts . insert ( i ) ;
2008-06-17 20:48:32 +03:00
}
2010-02-16 16:39:56 +02:00
CArtHandler : : ~ CArtHandler ( )
{
2010-12-17 20:47:07 +02:00
for ( std : : vector < ConstTransitivePtr < CArtifact > > : : iterator it = artifacts . begin ( ) ; it ! = artifacts . end ( ) ; + + it )
2010-11-10 02:06:25 +02:00
{
2010-06-26 19:02:10 +03:00
delete ( * it ) - > constituents ;
delete ( * it ) - > constituentOf ;
2010-02-16 16:39:56 +02:00
}
}
2009-01-12 22:05:56 +02:00
void CArtHandler : : loadArtifacts ( bool onlyTxt )
2007-06-07 23:16:19 +03:00
{
2008-08-26 00:14:00 +03:00
std : : vector < ui16 > slots ;
2010-02-08 23:17:22 +02:00
slots + = 17 , 16 , 15 , 14 , 13 , 18 , 12 , 11 , 10 , 9 , 8 , 7 , 6 , 5 , 4 , 3 , 2 , 1 , 0 ;
2012-07-16 19:18:02 +03:00
growingArtifacts + = 146 , 147 , 148 , 150 , 151 , 152 , 153 ;
2012-09-15 22:16:16 +03:00
static std : : map < char , CArtifact : : EartClass > classes =
2009-05-07 20:20:41 +03:00
map_list_of ( ' S ' , CArtifact : : ART_SPECIAL ) ( ' T ' , CArtifact : : ART_TREASURE ) ( ' N ' , CArtifact : : ART_MINOR ) ( ' J ' , CArtifact : : ART_MAJOR ) ( ' R ' , CArtifact : : ART_RELIC ) ;
2012-08-01 15:02:54 +03:00
2012-08-25 11:44:51 +03:00
CLegacyConfigParser parser ( " DATA/ARTRAITS.TXT " ) ;
parser . endLine ( ) ; // header
parser . endLine ( ) ;
2011-12-14 00:23:17 +03:00
VLC - > generaltexth - > artifNames . resize ( GameConstants : : ARTIFACTS_QUANTITY ) ;
VLC - > generaltexth - > artifDescriptions . resize ( GameConstants : : ARTIFACTS_QUANTITY ) ;
2010-11-10 02:06:25 +02:00
std : : map < ui32 , ui8 > : : iterator itr ;
2012-07-16 19:18:02 +03:00
2011-12-14 00:23:17 +03:00
for ( int i = 0 ; i < GameConstants : : ARTIFACTS_QUANTITY ; i + + )
2007-06-07 23:16:19 +03:00
{
2012-07-16 19:18:02 +03:00
CArtifact * art ;
if ( vstd : : contains ( growingArtifacts , i ) )
{
art = new CGrowingArtifact ( ) ;
}
else
{
art = new CArtifact ( ) ;
}
2010-06-26 19:02:10 +03:00
CArtifact & nart = * art ;
2009-05-04 02:15:18 +03:00
nart . id = i ;
2012-08-25 11:44:51 +03:00
VLC - > generaltexth - > artifNames [ i ] = parser . readString ( ) ;
nart . price = parser . readNumber ( ) ;
2012-04-14 05:20:22 +03:00
nart . possibleSlots [ ArtBearer : : HERO ] ; //we want to generate map entry even if it will be empty
nart . possibleSlots [ ArtBearer : : CREATURE ] ; //we want to generate map entry even if it will be empty
2012-05-20 11:39:19 +03:00
nart . possibleSlots [ ArtBearer : : COMMANDER ] ;
2012-08-25 11:44:51 +03:00
2008-06-13 11:16:51 +03:00
for ( int j = 0 ; j < slots . size ( ) ; j + + )
2007-06-07 23:16:19 +03:00
{
2012-08-25 11:44:51 +03:00
if ( parser . readString ( ) = = " x " )
2012-04-14 05:20:22 +03:00
nart . possibleSlots [ ArtBearer : : HERO ] . push_back ( slots [ j ] ) ;
2007-06-07 23:16:19 +03:00
}
2012-08-25 11:44:51 +03:00
nart . aClass = classes [ parser . readString ( ) [ 0 ] ] ;
2009-05-04 02:15:18 +03:00
//load description and remove quotation marks
2012-08-25 11:44:51 +03:00
VLC - > generaltexth - > artifDescriptions [ i ] = parser . readString ( ) ;
parser . endLine ( ) ;
2009-05-04 02:15:18 +03:00
2010-06-01 02:26:46 +03:00
if ( onlyTxt )
continue ;
2010-02-08 23:17:22 +02:00
// Fill in information about combined artifacts. Should perhaps be moved to a config file?
2010-02-16 16:39:56 +02:00
nart . constituentOf = NULL ;
2012-09-15 22:16:16 +03:00
switch ( nart . id )
2010-06-01 02:26:46 +03:00
{
2009-12-30 17:33:28 +02:00
case 129 : // Angelic Alliance
2010-02-08 23:17:22 +02:00
nart . constituents = new std : : vector < ui32 > ( ) ;
2009-12-30 17:33:28 +02:00
* nart . constituents + = 31 , 32 , 33 , 34 , 35 , 36 ;
break ;
case 130 : // Cloak of the Undead King
2010-02-08 23:17:22 +02:00
nart . constituents = new std : : vector < ui32 > ( ) ;
2009-12-30 17:33:28 +02:00
* nart . constituents + = 54 , 55 , 56 ;
break ;
case 131 : // Elixir of Life
2010-02-08 23:17:22 +02:00
nart . constituents = new std : : vector < ui32 > ( ) ;
2009-12-30 17:33:28 +02:00
* nart . constituents + = 94 , 95 , 96 ;
break ;
case 132 : // Armor of the Damned
2010-02-08 23:17:22 +02:00
nart . constituents = new std : : vector < ui32 > ( ) ;
2009-12-30 17:33:28 +02:00
* nart . constituents + = 8 , 14 , 20 , 26 ;
break ;
case 133 : // Statue of Legion
2010-02-08 23:17:22 +02:00
nart . constituents = new std : : vector < ui32 > ( ) ;
2009-12-30 17:33:28 +02:00
* nart . constituents + = 118 , 119 , 120 , 121 , 122 ;
break ;
case 134 : // Power of the Dragon Father
2010-02-08 23:17:22 +02:00
nart . constituents = new std : : vector < ui32 > ( ) ;
2009-12-30 17:33:28 +02:00
* nart . constituents + = 37 , 38 , 39 , 40 , 41 , 42 , 43 , 44 , 45 ;
break ;
case 135 : // Titan's Thunder
2010-02-08 23:17:22 +02:00
nart . constituents = new std : : vector < ui32 > ( ) ;
2009-12-30 17:33:28 +02:00
* nart . constituents + = 12 , 18 , 24 , 30 ;
break ;
case 136 : // Admiral's Hat
2010-02-08 23:17:22 +02:00
nart . constituents = new std : : vector < ui32 > ( ) ;
2009-12-30 17:33:28 +02:00
* nart . constituents + = 71 , 123 ;
break ;
case 137 : // Bow of the Sharpshooter
2010-02-08 23:17:22 +02:00
nart . constituents = new std : : vector < ui32 > ( ) ;
2009-12-30 17:33:28 +02:00
* nart . constituents + = 60 , 61 , 62 ;
break ;
case 138 : // Wizards' Well
2010-02-08 23:17:22 +02:00
nart . constituents = new std : : vector < ui32 > ( ) ;
2009-12-30 17:33:28 +02:00
* nart . constituents + = 73 , 74 , 75 ;
break ;
case 139 : // Ring of the Magi
2010-02-08 23:17:22 +02:00
nart . constituents = new std : : vector < ui32 > ( ) ;
2009-12-30 17:33:28 +02:00
* nart . constituents + = 76 , 77 , 78 ;
break ;
case 140 : // Cornucopia
2010-02-08 23:17:22 +02:00
nart . constituents = new std : : vector < ui32 > ( ) ;
2009-12-30 17:33:28 +02:00
* nart . constituents + = 109 , 110 , 111 , 113 ;
break ;
// TODO: WoG combinationals
default :
nart . constituents = NULL ;
break ;
}
2010-06-26 19:02:10 +03:00
artifacts . push_back ( & nart ) ;
2007-06-07 23:16:19 +03:00
}
2012-08-24 12:37:52 +03:00
if ( VLC - > modh - > modules . COMMANDERS )
2012-07-16 19:18:02 +03:00
{ //TODO: move all artifacts config to separate json file
2012-08-02 14:03:26 +03:00
const JsonNode config ( ResourceID ( " config/commanders.json " ) ) ;
2012-07-16 19:18:02 +03:00
BOOST_FOREACH ( const JsonNode & artifact , config [ " artifacts " ] . Vector ( ) )
{
2012-09-15 22:16:16 +03:00
auto ga = dynamic_cast < CGrowingArtifact * > ( artifacts [ artifact [ " id " ] . Float ( ) ] . get ( ) ) ;
2012-07-16 19:18:02 +03:00
BOOST_FOREACH ( auto b , artifact [ " bonusesPerLevel " ] . Vector ( ) )
{
ga - > bonusesPerLevel . push_back ( std : : pair < ui16 , Bonus > ( b [ " level " ] . Float ( ) , * ParseBonus ( b [ " bonus " ] . Vector ( ) ) ) ) ;
}
BOOST_FOREACH ( auto b , artifact [ " thresholdBonuses " ] . Vector ( ) )
{
2012-07-16 19:31:41 +03:00
ga - > thresholdBonuses . push_back ( std : : pair < ui16 , Bonus > ( b [ " level " ] . Float ( ) , * ParseBonus ( b [ " bonus " ] . Vector ( ) ) ) ) ;
2012-07-16 19:18:02 +03:00
}
}
}
2008-11-28 03:36:34 +02:00
sortArts ( ) ;
2010-06-01 02:26:46 +03:00
if ( onlyTxt )
return ;
addBonuses ( ) ;
2010-02-16 16:39:56 +02:00
// Populate reverse mappings of combinational artifacts.
2012-09-15 22:16:16 +03:00
BOOST_FOREACH ( CArtifact * artifact , artifacts )
2010-06-26 19:02:10 +03:00
{
2012-09-15 22:16:16 +03:00
if ( artifact - > constituents ! = NULL )
2010-06-26 19:02:10 +03:00
{
2012-09-15 22:16:16 +03:00
BOOST_FOREACH ( ui32 constituentID , * artifact - > constituents )
2010-06-26 19:02:10 +03:00
{
if ( artifacts [ constituentID ] - > constituentOf = = NULL )
artifacts [ constituentID ] - > constituentOf = new std : : vector < ui32 > ( ) ;
artifacts [ constituentID ] - > constituentOf - > push_back ( artifact - > id ) ;
2010-02-16 16:39:56 +02:00
}
}
}
2007-06-08 17:58:04 +03:00
}
2008-08-30 00:41:32 +03:00
int CArtHandler : : convertMachineID ( int id , bool creToArt )
{
int dif = 142 ;
if ( creToArt )
{
switch ( id )
{
case 147 :
dif - - ;
break ;
case 148 :
dif + + ;
break ;
}
dif = - dif ;
}
else
{
switch ( id )
{
case 6 :
dif - - ;
break ;
case 5 :
dif + + ;
break ;
}
}
return id + dif ;
2008-11-28 03:36:34 +02:00
}
void CArtHandler : : sortArts ( )
{
2011-06-18 08:55:39 +03:00
//for (int i=0; i<allowedArtifacts.size(); ++i) //do 144, bo nie chcemy bzdurek
//{
// switch (allowedArtifacts[i]->aClass)
// {
// case CArtifact::ART_TREASURE:
// treasures.push_back(allowedArtifacts[i]);
// break;
// case CArtifact::ART_MINOR:
// minors.push_back(allowedArtifacts[i]);
// break;
// case CArtifact::ART_MAJOR:
// majors.push_back(allowedArtifacts[i]);
// break;
// case CArtifact::ART_RELIC:
// relics.push_back(allowedArtifacts[i]);
// break;
// }
//}
2008-11-30 02:15:38 +02:00
}
2012-09-25 17:40:39 +03:00
void CArtHandler : : erasePickedArt ( TArtifactInstanceID id )
2010-06-28 08:07:21 +03:00
{
std : : vector < CArtifact * > * ptr ;
CArtifact * art = artifacts [ id ] ;
switch ( art - > aClass )
{
case CArtifact : : ART_TREASURE :
ptr = & treasures ;
break ;
case CArtifact : : ART_MINOR :
ptr = & minors ;
break ;
case CArtifact : : ART_MAJOR :
ptr = & majors ;
break ;
case CArtifact : : ART_RELIC :
ptr = & relics ;
break ;
default : //special artifacts should not be erased
return ;
}
2011-09-24 04:15:36 +03:00
ptr - > erase ( std : : find ( ptr - > begin ( ) , ptr - > end ( ) , art ) ) ; //remove the artifact from available list
2010-06-28 08:07:21 +03:00
}
ui16 CArtHandler : : getRandomArt ( int flags )
{
2010-12-17 20:47:07 +02:00
std : : vector < ConstTransitivePtr < CArtifact > > out ;
2010-06-28 08:07:21 +03:00
getAllowed ( out , flags ) ;
ui16 id = out [ ran ( ) % out . size ( ) ] - > id ;
erasePickedArt ( id ) ;
return id ;
}
ui16 CArtHandler : : getArtSync ( ui32 rand , int flags )
{
2010-12-17 20:47:07 +02:00
std : : vector < ConstTransitivePtr < CArtifact > > out ;
2010-06-28 08:07:21 +03:00
getAllowed ( out , flags ) ;
CArtifact * art = out [ rand % out . size ( ) ] ;
2012-09-15 22:16:16 +03:00
return art - > id ;
2010-06-28 08:07:21 +03:00
}
2010-12-17 20:47:07 +02:00
void CArtHandler : : getAllowed ( std : : vector < ConstTransitivePtr < CArtifact > > & out , int flags )
2010-06-28 08:07:21 +03:00
{
if ( flags & CArtifact : : ART_TREASURE )
getAllowedArts ( out , & treasures , CArtifact : : ART_TREASURE ) ;
if ( flags & CArtifact : : ART_MINOR )
getAllowedArts ( out , & minors , CArtifact : : ART_MINOR ) ;
if ( flags & CArtifact : : ART_MAJOR )
getAllowedArts ( out , & majors , CArtifact : : ART_MAJOR ) ;
if ( flags & CArtifact : : ART_RELIC )
getAllowedArts ( out , & relics , CArtifact : : ART_RELIC ) ;
2011-06-18 08:55:39 +03:00
if ( ! out . size ( ) ) //no artifact of specified rarity, we need to take another one
{
getAllowedArts ( out , & treasures , CArtifact : : ART_TREASURE ) ;
getAllowedArts ( out , & minors , CArtifact : : ART_MINOR ) ;
getAllowedArts ( out , & majors , CArtifact : : ART_MAJOR ) ;
getAllowedArts ( out , & relics , CArtifact : : ART_RELIC ) ;
}
2011-09-24 04:15:36 +03:00
if ( ! out . size ( ) ) //no arts are available at all
2010-06-28 08:07:21 +03:00
{
out . resize ( 64 ) ;
2011-06-18 08:55:39 +03:00
std : : fill_n ( out . begin ( ) , 64 , artifacts [ 2 ] ) ; //Give Grail - this can't be banned (hopefully)
2010-06-28 08:07:21 +03:00
}
}
2010-12-17 20:47:07 +02:00
void CArtHandler : : getAllowedArts ( std : : vector < ConstTransitivePtr < CArtifact > > & out , std : : vector < CArtifact * > * arts , int flag )
2010-06-28 08:07:21 +03:00
{
2011-09-24 04:15:36 +03:00
if ( arts - > empty ( ) ) //restock available arts
2010-06-28 08:07:21 +03:00
{
for ( int i = 0 ; i < allowedArtifacts . size ( ) ; + + i )
{
if ( allowedArtifacts [ i ] - > aClass = = flag )
arts - > push_back ( allowedArtifacts [ i ] ) ;
}
}
2008-11-30 02:15:38 +02:00
2010-06-28 08:07:21 +03:00
for ( int i = 0 ; i < arts - > size ( ) ; + + i )
{
CArtifact * art = ( * arts ) [ i ] ;
out . push_back ( art ) ;
}
}
2012-08-26 12:07:48 +03:00
2012-11-02 23:08:37 +03:00
Bonus * createBonus ( Bonus : : BonusType type , int val , int subtype , int valType , shared_ptr < ILimiter > limiter = shared_ptr < ILimiter > ( ) , int additionalInfo = 0 )
2008-11-30 02:15:38 +02:00
{
2012-08-26 12:07:48 +03:00
Bonus * added = new Bonus ( Bonus : : PERMANENT , type , Bonus : : ARTIFACT , val , - 1 , subtype ) ;
2012-04-17 11:46:09 +03:00
added - > additionalInfo = additionalInfo ;
2010-11-20 02:03:31 +02:00
added - > valType = valType ;
2012-08-26 12:07:48 +03:00
added - > limiter = limiter ;
return added ;
2011-08-26 23:32:05 +03:00
}
2012-11-02 23:08:37 +03:00
Bonus * createBonus ( Bonus : : BonusType type , int val , int subtype , shared_ptr < IPropagator > propagator = shared_ptr < IPropagator > ( ) , int additionalInfo = 0 )
2011-08-26 23:32:05 +03:00
{
2012-08-26 12:07:48 +03:00
Bonus * added = new Bonus ( Bonus : : PERMANENT , type , Bonus : : ARTIFACT , val , - 1 , subtype ) ;
2012-04-17 11:46:09 +03:00
added - > additionalInfo = additionalInfo ;
2011-08-26 23:32:05 +03:00
added - > valType = Bonus : : BASE_NUMBER ;
2012-08-26 12:07:48 +03:00
added - > propagator = propagator ;
return added ;
}
2012-09-23 21:01:04 +03:00
void CArtHandler : : giveArtBonus ( TArtifactID aid , Bonus : : BonusType type , int val , int subtype , int valType , shared_ptr < ILimiter > limiter , int additionalInfo )
2012-08-26 12:07:48 +03:00
{
giveArtBonus ( aid , createBonus ( type , val , subtype , valType , limiter , additionalInfo ) ) ;
}
2012-09-23 21:01:04 +03:00
void CArtHandler : : giveArtBonus ( TArtifactID aid , Bonus : : BonusType type , int val , int subtype , shared_ptr < IPropagator > propagator /*= NULL*/ , int additionalInfo )
2012-08-26 12:07:48 +03:00
{
giveArtBonus ( aid , createBonus ( type , val , subtype , propagator , additionalInfo ) ) ;
}
2012-09-23 21:01:04 +03:00
void CArtHandler : : giveArtBonus ( TArtifactID aid , Bonus * bonus )
2012-08-26 12:07:48 +03:00
{
bonus - > sid = aid ;
if ( bonus - > subtype = = Bonus : : MORALE | | bonus - > type = = Bonus : : LUCK )
bonus - > description = artifacts [ aid ] - > Name ( ) + ( bonus - > val > 0 ? " + " : " " ) + boost : : lexical_cast < std : : string > ( bonus - > val ) ;
2011-08-26 23:32:05 +03:00
else
2012-08-26 12:07:48 +03:00
bonus - > description = artifacts [ aid ] - > Name ( ) ;
artifacts [ aid ] - > addNewBonus ( bonus ) ;
2008-11-30 02:15:38 +02:00
}
2012-08-26 12:07:48 +03:00
2012-09-25 17:40:39 +03:00
void CArtHandler : : makeItCreatureArt ( TArtifactInstanceID aid , bool onlyCreature /*=true*/ )
2012-04-18 16:24:18 +03:00
{
CArtifact * a = artifacts [ aid ] ;
if ( onlyCreature )
{
a - > possibleSlots [ ArtBearer : : HERO ] . clear ( ) ;
2012-05-20 11:39:19 +03:00
a - > possibleSlots [ ArtBearer : : COMMANDER ] . clear ( ) ;
2012-04-18 16:24:18 +03:00
}
a - > possibleSlots [ ArtBearer : : CREATURE ] . push_back ( ArtifactPosition : : CREATURE_SLOT ) ;
2012-09-15 22:16:16 +03:00
}
2008-11-30 02:15:38 +02:00
2012-09-25 17:40:39 +03:00
void CArtHandler : : makeItCommanderArt ( TArtifactInstanceID aid , bool onlyCommander /*= true*/ )
2012-05-19 21:27:23 +03:00
{
2012-05-20 11:39:19 +03:00
CArtifact * a = artifacts [ aid ] ;
if ( onlyCommander )
{
a - > possibleSlots [ ArtBearer : : HERO ] . clear ( ) ;
a - > possibleSlots [ ArtBearer : : CREATURE ] . clear ( ) ;
}
for ( int i = ArtifactPosition : : COMMANDER1 ; i < = ArtifactPosition : : COMMANDER6 ; + + i )
a - > possibleSlots [ ArtBearer : : COMMANDER ] . push_back ( i ) ;
2012-09-15 22:16:16 +03:00
}
2012-05-19 21:27:23 +03:00
2009-04-04 01:34:31 +03:00
void CArtHandler : : addBonuses ( )
2008-11-30 02:15:38 +02:00
{
2012-10-03 21:11:19 +03:00
// #define ART_PRIM_SKILL(ID, whichSkill, val) giveArtBonus(ID,Bonus::PRIMARY_SKILL,val,whichSkill)
// #define ART_MORALE(ID, val) giveArtBonus(ID,Bonus::MORALE,val)
// #define ART_LUCK(ID, val) giveArtBonus(ID,Bonus::LUCK,val)
// #define ART_MORALE_AND_LUCK(ID, val) giveArtBonus(ID,Bonus::MORALE_AND_LUCK,val)
// #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)
// #define ART_ATTACK_AND_DEFENSE(ID, val) ART_PRIM_SKILL(ID,0,val); ART_PRIM_SKILL(ID,1,val)
// #define ART_POWER_AND_KNOWLEDGE(ID, val) ART_PRIM_SKILL(ID,2,val); ART_PRIM_SKILL(ID,3,val)
//
// //Propagators/limiters used more than once
// auto battleWidePropagator = bonusPropagatorMap["BATTLE_WIDE"];
// auto visitedTownPropagator = bonusPropagatorMap["VISITED_TOWN_AND_VISITOR"];
//
// auto shooterOnlyLimiter = bonusLimiterMap["SHOOTER_ONLY"];
// auto dragonNatureLimiter = bonusLimiterMap["DRAGON_NATURE"];
// auto isUndeadLimiter = bonusLimiterMap["IS_UNDEAD"];
2012-09-26 21:10:29 +03:00
2012-10-03 21:11:19 +03:00
const JsonNode config ( ResourceID ( " config/artifacts.json " ) ) ;
BOOST_FOREACH ( const JsonNode & artifact , config [ " artifacts " ] . Vector ( ) )
2012-02-10 13:32:21 +03:00
{
2012-10-03 21:11:19 +03:00
auto ga = artifacts [ artifact [ " id " ] . Float ( ) ] . get ( ) ;
BOOST_FOREACH ( auto b , artifact [ " bonuses " ] . Vector ( ) )
2012-05-19 21:27:23 +03:00
{
2012-10-03 21:11:19 +03:00
ga - > addNewBonus ( ParseBonus ( b ) ) ;
2012-05-19 21:27:23 +03:00
}
2012-10-03 21:11:19 +03:00
if ( artifact [ " type " ] . String ( ) = = " Creature " )
makeItCreatureArt ( ga - > id ) ;
else if ( artifact [ " type " ] . String ( ) = = " Commander " )
makeItCommanderArt ( ga - > id ) ;
2012-05-19 21:27:23 +03:00
}
2012-09-26 21:10:29 +03:00
2012-10-03 21:11:19 +03:00
// //Attack bonus artifacts (Weapons)
// ART_PRIM_SKILL(7,0,+2); //Centaur Axe
// ART_PRIM_SKILL(8,0,+3); //Blackshard of the Dead Knight
// ART_PRIM_SKILL(9,0,+4); //Greater Gnoll's Flail
// ART_PRIM_SKILL(10,0,+5); //Ogre's Club of Havoc
// ART_PRIM_SKILL(11,0,+6); //Sword of Hellfire
// ART_PRIM_SKILL(12,0,+12); //Titan's Gladius
// ART_PRIM_SKILL(12,1,-3); //Titan's Gladius
//
// //Defense bonus artifacts (Shields)
// ART_PRIM_SKILL(13,1,+2); //Shield of the Dwarven Lords
// ART_PRIM_SKILL(14,1,+3); //Shield of the Yawning Dead
// ART_PRIM_SKILL(15,1,+4); //Buckler of the Gnoll King
// ART_PRIM_SKILL(16,1,+5); //Targ of the Rampaging Ogre
// ART_PRIM_SKILL(17,1,+6); //Shield of the Damned
// ART_PRIM_SKILL(18,1,+12); //Sentinel's Shield
// ART_PRIM_SKILL(18,0,-3); //Sentinel's Shield
//
// //Knowledge bonus artifacts (Helmets)
// ART_PRIM_SKILL(19,3,+1); //Helm of the Alabaster Unicorn
// ART_PRIM_SKILL(20,3,+2); //Skull Helmet
// ART_PRIM_SKILL(21,3,+3); //Helm of Chaos
// ART_PRIM_SKILL(22,3,+4); //Crown of the Supreme Magi
// ART_PRIM_SKILL(23,3,+5); //Hellstorm Helmet
// ART_PRIM_SKILL(24,3,+10); //Thunder Helmet
// ART_PRIM_SKILL(24,2,-2); //Thunder Helmet
//
// //Spell power bonus artifacts (Armours)
// ART_PRIM_SKILL(25,2,+1); //Breastplate of Petrified Wood
// ART_PRIM_SKILL(26,2,+2); //Rib Cage
// ART_PRIM_SKILL(27,2,+3); //Scales of the Greater Basilisk
// ART_PRIM_SKILL(28,2,+4); //Tunic of the Cyclops King
// ART_PRIM_SKILL(29,2,+5); //Breastplate of Brimstone
// ART_PRIM_SKILL(30,2,+10); //Titan's Cuirass
// ART_PRIM_SKILL(30,3,-2); //Titan's Cuirass
//
// //All primary skills (various)
// ART_ALL_PRIM_SKILLS(31,+1); //Armor of Wonder
// ART_ALL_PRIM_SKILLS(32,+2); //Sandals of the Saint
// ART_ALL_PRIM_SKILLS(33,+3); //Celestial Necklace of Bliss
// ART_ALL_PRIM_SKILLS(34,+4); //Lion's Shield of Courage
// ART_ALL_PRIM_SKILLS(35,+5); //Sword of Judgement
// ART_ALL_PRIM_SKILLS(36,+6); //Helm of Heavenly Enlightenment
//
// //Attack and Defense (various)
// ART_ATTACK_AND_DEFENSE(37,+1); //Quiet Eye of the Dragon
// ART_ATTACK_AND_DEFENSE(38,+2); //Red Dragon Flame Tongue
// ART_ATTACK_AND_DEFENSE(39,+3); //Dragon Scale Shield
// ART_ATTACK_AND_DEFENSE(40,+4); //Dragon Scale Armor
//
// //Spell power and Knowledge (various)
// ART_POWER_AND_KNOWLEDGE(41,+1); //Dragonbone Greaves
// ART_POWER_AND_KNOWLEDGE(42,+2); //Dragon Wing Tabard
// ART_POWER_AND_KNOWLEDGE(43,+3); //Necklace of Dragonteeth
// ART_POWER_AND_KNOWLEDGE(44,+4); //Crown of Dragontooth
//
// //Luck and morale
// ART_MORALE(45,+1); //Still Eye of the Dragon
// ART_LUCK(45,+1); //Still Eye of the Dragon
// ART_LUCK(46,+1); //Clover of Fortune
// ART_LUCK(47,+1); //Cards of Prophecy
// ART_LUCK(48,+1); //Ladybird of Luck
// ART_MORALE(49,+1); //Badge of Courage -> +1 morale
// giveArtBonus(49,Bonus::MIND_IMMUNITY,0); //immunity to hostile mind spells:
// ART_MORALE(50,+1); //Crest of Valor
// ART_MORALE(51,+1); //Glyph of Gallantry
//
// giveArtBonus(52,Bonus::SIGHT_RADIOUS,+1);//Speculum
// giveArtBonus(53,Bonus::SIGHT_RADIOUS,+1);//Spyglass
//
// //necromancy bonus
// giveArtBonus(54,Bonus::SECONDARY_SKILL_PREMY,+5, CGHeroInstance::NECROMANCY, Bonus::ADDITIVE_VALUE);//Amulet of the Undertaker
// giveArtBonus(55,Bonus::SECONDARY_SKILL_PREMY,+10, CGHeroInstance::NECROMANCY, Bonus::ADDITIVE_VALUE);//Vampire's Cowl
// giveArtBonus(56,Bonus::SECONDARY_SKILL_PREMY,+15, CGHeroInstance::NECROMANCY, Bonus::ADDITIVE_VALUE);//Dead Man's Boots
//
// giveArtBonus(57,Bonus::MAGIC_RESISTANCE,+5, 0);//Garniture of Interference
// giveArtBonus(58,Bonus::MAGIC_RESISTANCE,+10, 0);//Surcoat of Counterpoise
// giveArtBonus(59,Bonus::MAGIC_RESISTANCE,+15, 0);//Boots of Polarity
//
// //archery bonus
// giveArtBonus(60,Bonus::SECONDARY_SKILL_PREMY,+5, CGHeroInstance::ARCHERY, Bonus::ADDITIVE_VALUE);//Bow of Elven Cherrywood
// giveArtBonus(61,Bonus::SECONDARY_SKILL_PREMY,+10,CGHeroInstance::ARCHERY, Bonus::ADDITIVE_VALUE);//Bowstring of the Unicorn's Mane
// giveArtBonus(62,Bonus::SECONDARY_SKILL_PREMY,+15,CGHeroInstance::ARCHERY, Bonus::ADDITIVE_VALUE);//Angel Feather Arrows
//
// //eagle eye bonus
// giveArtBonus(63,Bonus::SECONDARY_SKILL_PREMY,+5, CGHeroInstance::EAGLE_EYE, Bonus::ADDITIVE_VALUE);//Bird of Perception
// giveArtBonus(64,Bonus::SECONDARY_SKILL_PREMY,+10, CGHeroInstance::EAGLE_EYE, Bonus::ADDITIVE_VALUE);//Stoic Watchman
// giveArtBonus(65,Bonus::SECONDARY_SKILL_PREMY,+15, CGHeroInstance::EAGLE_EYE, Bonus::ADDITIVE_VALUE);//Emblem of Cognizance
//
// //reducing cost of surrendering
// giveArtBonus(66,Bonus::SURRENDER_DISCOUNT,+10);//Statesman's Medal
// giveArtBonus(67,Bonus::SURRENDER_DISCOUNT,+10);//Diplomat's Ring
// giveArtBonus(68,Bonus::SURRENDER_DISCOUNT,+10);//Ambassador's Sash
//
// giveArtBonus(69,Bonus::STACKS_SPEED,+1);//Ring of the Wayfarer
//
// giveArtBonus(70,Bonus::LAND_MOVEMENT,+300);//Equestrian's Gloves
// giveArtBonus(71,Bonus::SEA_MOVEMENT,+1000);//Necklace of Ocean Guidance
// giveArtBonus(72,Bonus::FLYING_MOVEMENT, 0, 1);//Angel Wings
//
// giveArtBonus(73,Bonus::MANA_REGENERATION,+1);//Charm of Mana
// giveArtBonus(74,Bonus::MANA_REGENERATION,+2);//Talisman of Mana
// giveArtBonus(75,Bonus::MANA_REGENERATION,+3);//Mystic Orb of Mana
//
// giveArtBonus(76,Bonus::SPELL_DURATION,+1);//Collar of Conjuring
// giveArtBonus(77,Bonus::SPELL_DURATION,+2);//Ring of Conjuring
// giveArtBonus(78,Bonus::SPELL_DURATION,+3);//Cape of Conjuring
//
// giveArtBonus(79,Bonus::AIR_SPELL_DMG_PREMY,+50);//Orb of the Firmament
// giveArtBonus(80,Bonus::EARTH_SPELL_DMG_PREMY,+50);//Orb of Silt
// giveArtBonus(81,Bonus::FIRE_SPELL_DMG_PREMY,+50);//Orb of Tempestuous Fire
// giveArtBonus(82,Bonus::WATER_SPELL_DMG_PREMY,+50);//Orb of Driving Rain
//
// giveArtBonus(83,createBonus(Bonus::BLOCK_MAGIC_ABOVE, 2, -1, Bonus::INDEPENDENT_MIN)->addPropagator(battleWidePropagator));//Recanter's Cloak
// giveArtBonus(84,Bonus::BLOCK_MORALE,0);//Spirit of Oppression
// giveArtBonus(85,Bonus::BLOCK_LUCK,0);//Hourglass of the Evil Hour
//
// giveArtBonus(86,Bonus::FIRE_SPELLS,0);//Tome of Fire Magic
// giveArtBonus(87,Bonus::AIR_SPELLS,0);//Tome of Air Magic
// giveArtBonus(88,Bonus::WATER_SPELLS,0);//Tome of Water Magic
// giveArtBonus(89,Bonus::EARTH_SPELLS,0);//Tome of Earth Magic
//
// giveArtBonus(90,Bonus::WATER_WALKING, 0, 1);//Boots of Levitation
// giveArtBonus(91,Bonus::NO_DISTANCE_PENALTY,0, 0, 0, shooterOnlyLimiter);//Golden Bow
// giveArtBonus(91,Bonus::NO_WALL_PENALTY, 0, 0, 0, shooterOnlyLimiter);
// giveArtBonus(92,Bonus::SPELL_IMMUNITY,0,35);//Sphere of Permanence
// giveArtBonus(93,Bonus::NEGATE_ALL_NATURAL_IMMUNITIES,0);//Orb of Vulnerability
//
// giveArtBonus(94,Bonus::STACK_HEALTH,+1);//Ring of Vitality
// giveArtBonus(95,Bonus::STACK_HEALTH,+1);//Ring of Life
// giveArtBonus(96,Bonus::STACK_HEALTH,+2);//Vial of Lifeblood
//
// giveArtBonus(97,Bonus::STACKS_SPEED,+1);//Necklace of Swiftness
// giveArtBonus(98,Bonus::LAND_MOVEMENT,+600);//Boots of Speed
// giveArtBonus(99,Bonus::STACKS_SPEED,+2);//Cape of Velocity
//
// giveArtBonus(100,Bonus::SPELL_IMMUNITY,0,Spells::BERSERK);//Pendant of Dispassion
// giveArtBonus(101,Bonus::SPELL_IMMUNITY,0,Spells::BLIND);//Pendant of Second Sight
// giveArtBonus(102,Bonus::SPELL_IMMUNITY,0,Spells::CURSE);//Pendant of Holiness
// giveArtBonus(103,Bonus::SPELL_IMMUNITY,0,Spells::DEATH_RIPPLE);//Pendant of Life
// giveArtBonus(104,Bonus::SPELL_IMMUNITY,0,Spells::DESTROY_UNDEAD, 1, isUndeadLimiter);//Pendant of Death does not display info for living stacks
// giveArtBonus(105,Bonus::SPELL_IMMUNITY,0,Spells::HYPNOTIZE);//Pendant of Free Will
// giveArtBonus(106,Bonus::SPELL_IMMUNITY,0,Spells::LIGHTNING_BOLT);//Pendant of Negativity
// giveArtBonus(106,Bonus::SPELL_IMMUNITY,0,Spells::CHAIN_LIGHTNING);//Pendant of Negativity
// giveArtBonus(107,Bonus::SPELL_IMMUNITY,0,Spells::FORGETFULNESS);//Pendant of Total Recall
// giveArtBonus(108,Bonus::MORALE,+3);//Pendant of Courage
// giveArtBonus(108,Bonus::LUCK,+3);//Pendant of Courage
//
// giveArtBonus(109,Bonus::GENERATE_RESOURCE,+1,4); //Everflowing Crystal Cloak
// giveArtBonus(110,Bonus::GENERATE_RESOURCE,+1,5); //Ring of Infinite Gems
// giveArtBonus(111,Bonus::GENERATE_RESOURCE,+1,1); //Everpouring Vial of Mercury
// giveArtBonus(112,Bonus::GENERATE_RESOURCE,+1,2); //Inexhaustible Cart of Ore
// giveArtBonus(113,Bonus::GENERATE_RESOURCE,+1,3); //Eversmoking Ring of Sulfur
// giveArtBonus(114,Bonus::GENERATE_RESOURCE,+1,0); //Inexhaustible Cart of Lumber
// giveArtBonus(115,Bonus::GENERATE_RESOURCE,+1000, Res::GOLD); //Endless Sack of Gold
// giveArtBonus(116,Bonus::GENERATE_RESOURCE,+750, Res::GOLD); //Endless Bag of Gold
// giveArtBonus(117,Bonus::GENERATE_RESOURCE,+500, Res::GOLD); //Endless Purse of Gold
//
//
// //Town will receive bonus if hero is visiting town or stays in its garrison.
// giveArtBonus(118,Bonus::CREATURE_GROWTH,+5,1, visitedTownPropagator); //Legs of Legion
// giveArtBonus(119,Bonus::CREATURE_GROWTH,+4,2, visitedTownPropagator); //Loins of Legion
// giveArtBonus(120,Bonus::CREATURE_GROWTH,+3,3, visitedTownPropagator); //Torso of Legion
// giveArtBonus(121,Bonus::CREATURE_GROWTH,+2,4, visitedTownPropagator); //Arms of Legion
// giveArtBonus(122,Bonus::CREATURE_GROWTH,+1,5, visitedTownPropagator); //Head of Legion
//
// //Sea Captain's Hat
// giveArtBonus(123,Bonus::WHIRLPOOL_PROTECTION,0);
// giveArtBonus(123,Bonus::SEA_MOVEMENT,+500);
// giveArtBonus(123,Bonus::SPELL,3,0, Bonus::INDEPENDENT_MAX);
// giveArtBonus(123,Bonus::SPELL,3,1, Bonus::INDEPENDENT_MAX);
//
// giveArtBonus(124, Bonus::SPELLS_OF_LEVEL,3,1); //Spellbinder's Hat
// giveArtBonus(125, Bonus::BATTLE_NO_FLEEING,0, 0, battleWidePropagator); //Shackles of War
// giveArtBonus(126, Bonus::BLOCK_ALL_MAGIC, 0, -1, battleWidePropagator);//Orb of Inhibition
//
// //vial of dragon blood
// giveArtBonus(127, Bonus::PRIMARY_SKILL, +5, PrimarySkill::ATTACK, Bonus::BASE_NUMBER, dragonNatureLimiter);
// giveArtBonus(127, Bonus::PRIMARY_SKILL, +5, PrimarySkill::DEFENSE, Bonus::BASE_NUMBER, dragonNatureLimiter);
//
// //Armageddon's Blade
// giveArtBonus(128, Bonus::SPELL, 3, 26, Bonus::INDEPENDENT_MAX);
// giveArtBonus(128, Bonus::SPELL_IMMUNITY,0, 26);
// ART_ATTACK_AND_DEFENSE(128, +3);
// ART_PRIM_SKILL(128, 2, +3);
// ART_PRIM_SKILL(128, 3, +6);
//
// //Angelic Alliance
// giveArtBonus(129, Bonus::NONEVIL_ALIGNMENT_MIX, 0);
// giveArtBonus(129, Bonus::OPENING_BATTLE_SPELL, 10, 48); // Prayer
//
// //Cloak of the Undead King
// giveArtBonus(130, Bonus::IMPROVED_NECROMANCY, 0);
//
// //Elixir of Life
// giveArtBonus(131, Bonus::STACK_HEALTH, +25, -1, Bonus::PERCENT_TO_BASE);
// giveArtBonus(131, Bonus::HP_REGENERATION, +50);
//
// //Armor of the Damned
// giveArtBonus(132, Bonus::OPENING_BATTLE_SPELL, 50, 54); // Slow
// giveArtBonus(132, Bonus::OPENING_BATTLE_SPELL, 50, 47); // Disrupting Ray
// giveArtBonus(132, Bonus::OPENING_BATTLE_SPELL, 50, 45); // Weakness
// giveArtBonus(132, Bonus::OPENING_BATTLE_SPELL, 50, 52); // Misfortune
//
// // Statue of Legion - gives only 50% growth
// giveArtBonus(133, Bonus::CREATURE_GROWTH_PERCENT, 50, -1, make_shared<CPropagatorNodeType>(CBonusSystemNode::PLAYER));
//
// //Power of the Dragon Father
// giveArtBonus(134, Bonus::LEVEL_SPELL_IMMUNITY, 4, -1, Bonus::INDEPENDENT_MAX);
//
// //Titan's Thunder
// giveArtBonus(135, Bonus::SPELL, 3, 57);
//
// //Admiral's Hat
// giveArtBonus(136, Bonus::FREE_SHIP_BOARDING, 0);
//
// //Bow of the Sharpshooter
// giveArtBonus(137, Bonus::NO_DISTANCE_PENALTY, 0, 0, 0, shooterOnlyLimiter);
// giveArtBonus(137, Bonus::NO_WALL_PENALTY, 0, 0, 0, shooterOnlyLimiter);
// giveArtBonus(137, Bonus::FREE_SHOOTING, 0, 0, 0, shooterOnlyLimiter);
//
// //Wizard's Well
// giveArtBonus(138, Bonus::FULL_MANA_REGENERATION, 0);
//
// //Ring of the Magi
// giveArtBonus(139, Bonus::SPELL_DURATION, +50);
//
// //Cornucopia
// giveArtBonus(140, Bonus::GENERATE_RESOURCE, +4, Res::MERCURY);
// giveArtBonus(140, Bonus::GENERATE_RESOURCE, +4, Res::SULFUR);
// giveArtBonus(140, Bonus::GENERATE_RESOURCE, +4, Res::CRYSTAL);
// giveArtBonus(140, Bonus::GENERATE_RESOURCE, +4, Res::GEMS);
//
//
// //Stack artifact test
// if (VLC->modh->modules.STACK_ARTIFACT)
// {
// makeItCreatureArt(141);
// makeItCreatureArt(142);
// makeItCreatureArt(143);
// makeItCreatureArt(156);
// //Magic Wand
// giveArtBonus(141, Bonus::CASTS, 10);
// giveArtBonus(141, Bonus::SPELLCASTER, 0, Spells::IMPLOSION);
// giveArtBonus(141, Bonus::SPELLCASTER, 0, Spells::FIREBALL);
// giveArtBonus(141, Bonus::RANDOM_SPELLCASTER, 0);
// giveArtBonus(141, Bonus::DAEMON_SUMMONING, 10, 63); //rise vampire lords
// giveArtBonus(141, Bonus::ENCHANTER, 0, Spells::LIGHTNING_BOLT, NULL, 2);
// giveArtBonus(141, Bonus::REBIRTH, 1, 1);
// giveArtBonus(141, Bonus::MANA_DRAIN, 10);
// giveArtBonus(141, Bonus::HEALER, 25);
// 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");
// //Tower Arrow
// giveArtBonus(142, Bonus::NO_DISTANCE_PENALTY, 0);
// giveArtBonus(142, Bonus::ADDITIONAL_ATTACK, 2);
// giveArtBonus(142, Bonus::SPELL_LIKE_ATTACK, 1, Spells::INFERNO);
// giveArtBonus(142, Bonus::CATAPULT, 0);
// giveArtBonus(142, Bonus::ACID_BREATH, 20);
// giveArtBonus(142, Bonus::SHOTS, 200, 0, Bonus::PERCENT_TO_BASE);
// giveArtBonus(142, Bonus::SPELL_BEFORE_ATTACK, 50, Spells::AGE, NULL, 1);
// giveArtBonus(142, Bonus::SPELL_AFTER_ATTACK, 50, Spells::BERSERK, NULL, 1);
// giveArtBonus(142, Bonus::SPELL_AFTER_ATTACK, 50, Spells::POISON, NULL, 1);
// giveArtBonus(142, Bonus::SPELL_AFTER_ATTACK, 50, Spells::DISRUPTING_RAY, NULL, 1);
// artifacts[142].get()->setDescription ("Triple shots, triple attack, casts various spells during attack, attacks have range of Inferno, no distance penalty, catapult");
// //Monster's Power
// giveArtBonus(143, Bonus::STACK_HEALTH, +100, -1, Bonus::PERCENT_TO_BASE);
// giveArtBonus(143, Bonus::CREATURE_DAMAGE, +100, 2, Bonus::PERCENT_TO_ALL);
// giveArtBonus(143, Bonus::HP_REGENERATION, 50);
// giveArtBonus(143, Bonus::NO_RETALIATION, 0);
// giveArtBonus(143, Bonus::RETURN_AFTER_STRIKE, 0);
// giveArtBonus(143, Bonus::ATTACKS_ALL_ADJACENT, 0);
// giveArtBonus(143, Bonus::SPELL_RESISTANCE_AURA, 100);
// giveArtBonus(143, Bonus::DIRECT_DAMAGE_IMMUNITY, 0);
// 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");
// //Warlord's banner
// giveArtBonus(156, Bonus::STACK_HEALTH, +2);
// artifacts[156].get()->setDescription ("+2 stack HP");
//
// }
// if (VLC->modh->modules.COMMANDERS)
// {
// for (int i = 146; i <= 155; ++i)
// {
// makeItCommanderArt (i);
// }
// ART_PRIM_SKILL (146, 0, +6); //Axe of Smashing
// giveArtBonus(147, Bonus::STACK_HEALTH, +12, -1, Bonus::PERCENT_TO_ALL); //Mithril Mail
// giveArtBonus(148, Bonus::CREATURE_DAMAGE, +12, 0, Bonus::PERCENT_TO_ALL); //Sword of Sharpness
// giveArtBonus(150, Bonus::CASTS, 1); //Pendant of Sorcery
// giveArtBonus(151, Bonus::STACKS_SPEED, 1); //Boots of haste
// ART_PRIM_SKILL (154, 0, +6); //Hardened Shield
// }
//
2012-09-29 20:36:48 +03:00
// JsonNode cfg;
2012-10-03 21:11:19 +03:00
// JsonNode artifs;
2012-09-29 20:36:48 +03:00
// BOOST_FOREACH(auto art, artifacts)
// {
// JsonNode jn;
// jn["id"].Float() = art->id;
// BOOST_FOREACH (auto b, art->getBonusList())
// {
// JsonNode bn;
// UnparseBonus(bn, b);
// jn["bonuses"].Vector().push_back(bn);
// }
//
2012-10-03 21:11:19 +03:00
// if(art->id < 140 || art-> id == 144 || art->id == 145 || art->id > 156)
// jn["type"].String() = "Hero";
// else if((art->id >= 141 && art->id < 144) || art->id == 156)
// jn["type"].String() = "Creature";
// else if(art-> id >= 146 && art->id <= 155)
// jn["type"].String() = "Commander";
//
// artifs.Vector().push_back(jn);
// }
// cfg["artifacts"] = artifs;
2012-09-29 20:36:48 +03:00
// std::ofstream artconfigOutput("config/artifacts.json");
2012-10-03 21:11:19 +03:00
// JsonWriter(artconfigOutput, cfg);
2009-04-04 01:34:31 +03:00
}
2009-05-30 19:00:26 +03:00
void CArtHandler : : clear ( )
{
2010-06-26 19:02:10 +03:00
BOOST_FOREACH ( CArtifact * art , artifacts )
delete art ;
2009-05-30 19:00:26 +03:00
artifacts . clear ( ) ;
2010-06-26 19:02:10 +03:00
2010-07-26 23:56:39 +03:00
clearHlpLists ( ) ;
2010-02-08 23:17:22 +02:00
}
2010-07-26 23:56:39 +03:00
void CArtHandler : : clearHlpLists ( )
{
treasures . clear ( ) ;
minors . clear ( ) ;
majors . clear ( ) ;
relics . clear ( ) ;
2010-08-18 12:50:25 +03:00
}
void CArtHandler : : initAllowedArtifactsList ( const std : : vector < ui8 > & allowed )
{
allowedArtifacts . clear ( ) ;
clearHlpLists ( ) ;
for ( int i = 0 ; i < 144 ; + + i ) //yes, 144
{
if ( allowed [ i ] )
allowedArtifacts . push_back ( artifacts [ i ] ) ;
}
2012-08-24 12:37:52 +03:00
if ( VLC - > modh - > modules . COMMANDERS ) //allow all commander artifacts for testing
2012-05-20 11:39:19 +03:00
{
for ( int i = 146 ; i < = 155 ; + + i )
{
allowedArtifacts . push_back ( artifacts [ i ] ) ;
}
}
2010-08-21 03:39:37 +03:00
}
2010-12-17 20:47:07 +02:00
CArtifactInstance : : CArtifactInstance ( )
{
init ( ) ;
}
CArtifactInstance : : CArtifactInstance ( CArtifact * Art )
{
init ( ) ;
setType ( Art ) ;
}
2011-01-18 20:56:14 +02:00
// CArtifactInstance::CArtifactInstance(int aid)
// {
// init();
// setType(VLC->arth->artifacts[aid]);
// }
2010-12-30 16:41:46 +02:00
2010-12-17 20:47:07 +02:00
void CArtifactInstance : : setType ( CArtifact * Art )
{
2010-12-26 16:34:11 +02:00
artType = Art ;
2010-12-17 20:47:07 +02:00
attachTo ( Art ) ;
}
std : : string CArtifactInstance : : nodeName ( ) const
{
2010-12-26 16:34:11 +02:00
return " Artifact instance of " + ( artType ? artType - > Name ( ) : std : : string ( " uninitialized " ) ) + " type " ;
2010-12-17 20:47:07 +02:00
}
CArtifactInstance * CArtifactInstance : : createScroll ( const CSpell * s )
{
2011-02-04 16:58:14 +02:00
CArtifactInstance * ret = new CArtifactInstance ( VLC - > arth - > artifacts [ 1 ] ) ;
Bonus * b = new Bonus ( Bonus : : PERMANENT , Bonus : : SPELL , Bonus : : ARTIFACT_INSTANCE , - 1 , 1 , s - > id ) ;
2010-12-17 20:47:07 +02:00
ret - > addNewBonus ( b ) ;
return ret ;
}
void CArtifactInstance : : init ( )
{
2010-12-26 16:34:11 +02:00
id = - 1 ;
2011-08-26 23:32:05 +03:00
setNodeType ( ARTIFACT_INSTANCE ) ;
2010-12-26 16:34:11 +02:00
}
2012-04-14 05:20:22 +03:00
int CArtifactInstance : : firstAvailableSlot ( const CArtifactSet * h ) const
2010-12-26 16:34:11 +02:00
{
2012-04-14 05:20:22 +03:00
BOOST_FOREACH ( ui16 slot , artType - > possibleSlots [ h - > bearerType ( ) ] )
2010-12-26 16:34:11 +02:00
{
2012-04-14 05:20:22 +03:00
if ( canBePutAt ( h , slot ) ) //if(artType->fitsAt(h->artifWorn, slot))
2010-12-26 16:34:11 +02:00
{
//we've found a free suitable slot.
return slot ;
}
}
//if haven't find proper slot, use backpack
return firstBackpackSlot ( h ) ;
}
2012-04-14 05:20:22 +03:00
int CArtifactInstance : : firstBackpackSlot ( const CArtifactSet * h ) const
2010-12-26 16:34:11 +02:00
{
if ( ! artType - > isBig ( ) ) //discard big artifact
2011-12-14 00:23:17 +03:00
return GameConstants : : BACKPACK_START + h - > artifactsInBackpack . size ( ) ;
2010-12-26 16:34:11 +02:00
return - 1 ;
}
2012-04-14 19:28:36 +03:00
bool CArtifactInstance : : canBePutAt ( const ArtifactLocation al , bool assumeDestRemoved /*= false*/ ) const
2010-12-26 16:34:11 +02:00
{
2012-04-14 05:20:22 +03:00
return canBePutAt ( al . getHolderArtSet ( ) , al . slot , assumeDestRemoved ) ;
}
2010-12-29 23:04:22 +02:00
2012-04-14 05:20:22 +03:00
bool CArtifactInstance : : canBePutAt ( const CArtifactSet * artSet , int slot , bool assumeDestRemoved /*= false*/ ) const
{
if ( slot > = GameConstants : : BACKPACK_START )
{
if ( artType - > isBig ( ) )
2012-01-30 19:07:52 +03:00
return false ;
2010-12-26 16:34:11 +02:00
2012-04-14 05:20:22 +03:00
//TODO backpack limit
return true ;
2012-01-30 19:07:52 +03:00
}
2012-04-14 05:20:22 +03:00
2012-05-22 02:39:35 +03:00
auto possibleSlots = artType - > possibleSlots . find ( artSet - > bearerType ( ) ) ;
if ( possibleSlots = = artType - > possibleSlots . end ( ) )
{
tlog3 < < " Warning: arrtifact " < < artType - > Name ( ) < < " doesn't have defined allowed slots for bearer of type "
< < artSet - > bearerType ( ) < < std : : endl ;
return false ;
}
if ( ! vstd : : contains ( possibleSlots - > second , slot ) )
2012-01-30 19:07:52 +03:00
return false ;
2012-04-14 05:20:22 +03:00
return artSet - > isPositionFree ( slot , assumeDestRemoved ) ;
2010-12-26 16:34:11 +02:00
}
2012-04-14 19:28:36 +03:00
void CArtifactInstance : : putAt ( ArtifactLocation al )
2010-12-26 16:34:11 +02:00
{
2012-04-14 05:20:22 +03:00
assert ( canBePutAt ( al ) ) ;
2010-12-26 16:34:11 +02:00
2012-04-14 05:20:22 +03:00
al . getHolderArtSet ( ) - > setNewArtSlot ( al . slot , this , false ) ;
if ( al . slot < GameConstants : : BACKPACK_START )
al . getHolderNode ( ) - > attachTo ( this ) ;
2010-12-26 16:34:11 +02:00
}
2012-04-14 19:28:36 +03:00
void CArtifactInstance : : removeFrom ( ArtifactLocation al )
2010-12-26 16:34:11 +02:00
{
2012-04-14 05:20:22 +03:00
assert ( al . getHolderArtSet ( ) - > getArt ( al . slot ) = = this ) ;
al . getHolderArtSet ( ) - > eraseArtSlot ( al . slot ) ;
if ( al . slot < GameConstants : : BACKPACK_START )
al . getHolderNode ( ) - > detachFrom ( this ) ;
2010-12-26 16:34:11 +02:00
//TODO delete me?
2010-12-29 23:04:22 +02:00
}
bool CArtifactInstance : : canBeDisassembled ( ) const
{
2011-01-24 01:49:17 +02:00
return artType - > constituents & & artType - > constituentOf - > size ( ) ;
2010-12-29 23:04:22 +02:00
}
2012-04-14 05:20:22 +03:00
std : : vector < const CArtifact * > CArtifactInstance : : assemblyPossibilities ( const CArtifactSet * h ) const
2010-12-29 23:04:22 +02:00
{
std : : vector < const CArtifact * > ret ;
2011-01-18 20:56:14 +02:00
if ( ! artType - > constituentOf //not a part of combined artifact
| | artType - > constituents ) //combined artifact already: no combining of combined artifacts... for now.
2010-12-29 23:04:22 +02:00
return ret ;
2012-09-15 22:16:16 +03:00
BOOST_FOREACH ( ui32 possibleCombinedArt , * artType - > constituentOf )
2010-12-29 23:04:22 +02:00
{
2011-01-18 20:56:14 +02:00
const CArtifact * const artifact = VLC - > arth - > artifacts [ possibleCombinedArt ] ;
assert ( artifact - > constituents ) ;
bool possible = true ;
BOOST_FOREACH ( ui32 constituentID , * artifact - > constituents ) //check if all constituents are available
2010-12-29 23:04:22 +02:00
{
2011-01-18 20:56:14 +02:00
if ( ! h - > hasArt ( constituentID , true ) ) //constituent must be equipped
{
possible = false ;
break ;
}
2010-12-29 23:04:22 +02:00
}
2011-01-18 20:56:14 +02:00
if ( possible )
ret . push_back ( artifact ) ;
2010-12-29 23:04:22 +02:00
}
return ret ;
}
2012-04-14 19:28:36 +03:00
void CArtifactInstance : : move ( ArtifactLocation src , ArtifactLocation dst )
2011-01-15 19:58:08 +02:00
{
2012-04-14 05:20:22 +03:00
removeFrom ( src ) ;
putAt ( dst ) ;
2011-01-15 19:58:08 +02:00
}
2011-01-18 20:56:14 +02:00
CArtifactInstance * CArtifactInstance : : createNewArtifactInstance ( CArtifact * Art )
{
if ( ! Art - > constituents )
2012-07-16 19:18:02 +03:00
{
auto ret = new CArtifactInstance ( Art ) ;
if ( dynamic_cast < CGrowingArtifact * > ( Art ) )
{
Bonus * bonus = new Bonus ;
bonus - > type = Bonus : : LEVEL_COUNTER ;
bonus - > val = 0 ;
ret - > addNewBonus ( bonus ) ;
}
return ret ;
}
2011-01-18 20:56:14 +02:00
else
2011-01-22 05:43:20 +02:00
{
CCombinedArtifactInstance * ret = new CCombinedArtifactInstance ( Art ) ;
ret - > createConstituents ( ) ;
return ret ;
}
2011-01-18 20:56:14 +02:00
}
CArtifactInstance * CArtifactInstance : : createNewArtifactInstance ( int aid )
{
return createNewArtifactInstance ( VLC - > arth - > artifacts [ aid ] ) ;
}
2011-02-04 16:58:14 +02:00
void CArtifactInstance : : deserializationFix ( )
{
setType ( artType ) ;
}
2011-03-12 23:55:31 +02:00
int CArtifactInstance : : getGivenSpellID ( ) const
{
2012-09-20 19:55:21 +03:00
const Bonus * b = getBonusLocalFirst ( Selector : : type ( Bonus : : SPELL ) ) ;
2011-03-12 23:55:31 +02:00
if ( ! b )
{
tlog3 < < " Warning: " < < nodeName ( ) < < " doesn't bear any spell! \n " ;
return - 1 ;
}
return b - > subtype ;
}
2011-07-03 04:03:46 +03:00
bool CArtifactInstance : : isPart ( const CArtifactInstance * supposedPart ) const
{
return supposedPart = = this ;
}
2012-09-15 22:16:16 +03:00
bool CCombinedArtifactInstance : : canBePutAt ( const CArtifactSet * artSet , int slot , bool assumeDestRemoved /*= false*/ ) const
2010-12-29 23:04:22 +02:00
{
2012-04-14 05:20:22 +03:00
bool canMainArtifactBePlaced = CArtifactInstance : : canBePutAt ( artSet , slot , assumeDestRemoved ) ;
2011-01-28 04:11:58 +02:00
if ( ! canMainArtifactBePlaced )
return false ; //no is no...
2012-04-14 05:20:22 +03:00
if ( slot > = GameConstants : : BACKPACK_START )
2011-01-28 04:11:58 +02:00
return true ; //we can always remove combined art to the backapck
assert ( artType - > constituents ) ;
std : : vector < ConstituentInfo > constituentsToBePlaced = constituentsInfo ; //we'll remove constituents from that list, as we find a suitable slot for them
2011-07-03 04:03:46 +03:00
//it may be that we picked a combined artifact in hero screen (though technically it's still there) to move it
//so we remove from the list all constituents that are already present on dst hero in the form of locks
BOOST_FOREACH ( const ConstituentInfo & constituent , constituentsInfo )
{
2012-04-14 05:20:22 +03:00
if ( constituent . art = = artSet - > getArt ( constituent . slot , false ) ) //no need to worry about locked constituent
2011-07-03 04:03:46 +03:00
constituentsToBePlaced - = constituent ;
}
2012-04-14 05:20:22 +03:00
2011-01-28 04:11:58 +02:00
//we iterate over all active slots and check if constituents fits them
2011-12-14 00:23:17 +03:00
for ( int i = 0 ; i < GameConstants : : BACKPACK_START ; i + + )
2011-01-28 04:11:58 +02:00
{
for ( std : : vector < ConstituentInfo > : : iterator art = constituentsToBePlaced . begin ( ) ; art ! = constituentsToBePlaced . end ( ) ; art + + )
{
2012-04-14 05:20:22 +03:00
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
2011-01-28 04:11:58 +02:00
{
constituentsToBePlaced . erase ( art ) ;
break ;
}
}
}
return constituentsToBePlaced . empty ( ) ;
2010-12-29 23:04:22 +02:00
}
bool CCombinedArtifactInstance : : canBeDisassembled ( ) const
{
return true ;
2011-01-18 20:56:14 +02:00
}
CCombinedArtifactInstance : : CCombinedArtifactInstance ( CArtifact * Art )
2011-06-21 12:31:08 +03:00
: CArtifactInstance ( Art ) //TODO: seems unued, but need to be written
2011-01-18 20:56:14 +02:00
{
}
CCombinedArtifactInstance : : CCombinedArtifactInstance ( )
{
}
void CCombinedArtifactInstance : : createConstituents ( )
{
assert ( artType ) ;
assert ( artType - > constituents ) ;
BOOST_FOREACH ( ui32 a , * artType - > constituents )
{
2011-01-22 05:43:20 +02:00
addAsConstituent ( CArtifactInstance : : createNewArtifactInstance ( a ) , - 1 ) ;
}
}
void CCombinedArtifactInstance : : addAsConstituent ( CArtifactInstance * art , int slot )
{
assert ( vstd : : contains ( * artType - > constituents , art - > artType - > id ) ) ;
2011-07-13 21:39:02 +03:00
assert ( art - > getParentNodes ( ) . size ( ) = = 1 & & art - > getParentNodes ( ) . front ( ) = = art - > artType ) ;
2011-01-22 05:43:20 +02:00
constituentsInfo . push_back ( ConstituentInfo ( art , slot ) ) ;
2011-01-28 04:11:58 +02:00
attachTo ( art ) ;
2011-01-22 05:43:20 +02:00
}
2012-04-14 19:28:36 +03:00
void CCombinedArtifactInstance : : putAt ( ArtifactLocation al )
2011-01-22 05:43:20 +02:00
{
2012-04-14 05:20:22 +03:00
if ( al . slot > = GameConstants : : BACKPACK_START )
2011-01-22 05:43:20 +02:00
{
2012-04-14 05:20:22 +03:00
CArtifactInstance : : putAt ( al ) ;
2011-01-22 05:43:20 +02:00
BOOST_FOREACH ( ConstituentInfo & ci , constituentsInfo )
ci . slot = - 1 ;
}
else
{
2012-04-14 05:20:22 +03:00
CArtifactInstance * mainConstituent = figureMainConstituent ( al ) ; //it'll be replaced with combined artifact, not a lock
CArtifactInstance : : putAt ( al ) ; //puts combined art (this)
2011-01-22 05:43:20 +02:00
BOOST_FOREACH ( ConstituentInfo & ci , constituentsInfo )
{
if ( ci . art ! = mainConstituent )
{
2012-04-14 05:20:22 +03:00
const ArtifactLocation suggestedPos ( al . artHolder , ci . slot ) ;
const bool inActiveSlot = vstd : : isbetween ( ci . slot , 0 , GameConstants : : BACKPACK_START ) ;
const bool suggestedPosValid = ci . art - > canBePutAt ( suggestedPos ) ;
2011-01-22 05:43:20 +02:00
int pos = - 1 ;
2012-09-15 22:16:16 +03:00
if ( inActiveSlot & & suggestedPosValid ) //there is a valid suggestion where to place lock
2011-01-22 05:43:20 +02:00
pos = ci . slot ;
else
2012-04-14 05:20:22 +03:00
ci . slot = pos = ci . art - > firstAvailableSlot ( al . getHolderArtSet ( ) ) ;
2011-01-22 05:43:20 +02:00
2011-12-14 00:23:17 +03:00
assert ( pos < GameConstants : : BACKPACK_START ) ;
2012-04-14 05:20:22 +03:00
al . getHolderArtSet ( ) - > setNewArtSlot ( pos , ci . art , true ) ; //sets as lock
2011-01-22 05:43:20 +02:00
}
else
{
ci . slot = - 1 ;
}
}
}
}
2012-04-14 19:28:36 +03:00
void CCombinedArtifactInstance : : removeFrom ( ArtifactLocation al )
2011-01-22 05:43:20 +02:00
{
2012-04-14 05:20:22 +03:00
if ( al . slot > = GameConstants : : BACKPACK_START )
2011-01-22 05:43:20 +02:00
{
2012-04-14 05:20:22 +03:00
CArtifactInstance : : removeFrom ( al ) ;
2011-01-22 05:43:20 +02:00
}
else
{
BOOST_FOREACH ( ConstituentInfo & ci , constituentsInfo )
{
if ( ci . slot > = 0 )
{
2012-04-14 05:20:22 +03:00
al . getHolderArtSet ( ) - > eraseArtSlot ( ci . slot ) ;
2011-01-22 05:43:20 +02:00
ci . slot = - 1 ;
}
else
{
//main constituent
2012-04-14 05:20:22 +03:00
CArtifactInstance : : removeFrom ( al ) ;
2011-01-22 05:43:20 +02:00
}
}
2011-01-18 20:56:14 +02:00
}
}
2012-04-14 19:28:36 +03:00
CArtifactInstance * CCombinedArtifactInstance : : figureMainConstituent ( const ArtifactLocation al )
2011-01-22 05:43:20 +02:00
{
CArtifactInstance * mainConstituent = NULL ; //it'll be replaced with combined artifact, not a lock
BOOST_FOREACH ( ConstituentInfo & ci , constituentsInfo )
2012-04-14 05:20:22 +03:00
if ( ci . slot = = al . slot )
2011-01-22 05:43:20 +02:00
mainConstituent = ci . art ;
if ( ! mainConstituent )
{
BOOST_FOREACH ( ConstituentInfo & ci , constituentsInfo )
{
2012-04-14 05:20:22 +03:00
if ( vstd : : contains ( ci . art - > artType - > possibleSlots [ al . getHolderArtSet ( ) - > bearerType ( ) ] , al . slot ) )
2011-01-22 05:43:20 +02:00
{
mainConstituent = ci . art ;
}
}
}
return mainConstituent ;
}
2011-01-18 20:56:14 +02:00
2011-02-04 16:58:14 +02:00
void CCombinedArtifactInstance : : deserializationFix ( )
{
BOOST_FOREACH ( ConstituentInfo & ci , constituentsInfo )
attachTo ( ci . art ) ;
}
2011-07-03 04:03:46 +03:00
bool CCombinedArtifactInstance : : isPart ( const CArtifactInstance * supposedPart ) const
{
bool me = CArtifactInstance : : isPart ( supposedPart ) ;
if ( me )
return true ;
//check for constituents
BOOST_FOREACH ( const ConstituentInfo & constituent , constituentsInfo )
if ( constituent . art = = supposedPart )
return true ;
return false ;
}
2011-01-18 20:56:14 +02:00
CCombinedArtifactInstance : : ConstituentInfo : : ConstituentInfo ( CArtifactInstance * Art /*= NULL*/ , ui16 Slot /*= -1*/ )
{
art = Art ;
slot = Slot ;
2011-06-24 20:43:02 +03:00
}
2011-07-03 04:03:46 +03:00
bool CCombinedArtifactInstance : : ConstituentInfo : : operator = = ( const ConstituentInfo & rhs ) const
{
return art = = rhs . art & & slot = = rhs . slot ;
}
2012-01-30 19:07:52 +03:00
2012-04-14 05:20:22 +03:00
const CArtifactInstance * CArtifactSet : : getArt ( ui16 pos , bool excludeLocked /*= true*/ ) const
2011-06-24 20:43:02 +03:00
{
if ( const ArtSlotInfo * si = getSlot ( pos ) )
{
if ( si - > artifact & & ( ! excludeLocked | | ! si - > locked ) )
return si - > artifact ;
}
return NULL ;
}
2012-04-14 05:20:22 +03:00
CArtifactInstance * CArtifactSet : : getArt ( ui16 pos , bool excludeLocked /*= true*/ )
2011-06-24 20:43:02 +03:00
{
2012-04-14 05:20:22 +03:00
return const_cast < CArtifactInstance * > ( ( const_cast < const CArtifactSet * > ( this ) ) - > getArt ( pos , excludeLocked ) ) ;
2011-06-24 20:43:02 +03:00
}
si32 CArtifactSet : : getArtPos ( int aid , bool onlyWorn /*= true*/ ) const
{
for ( std : : map < ui16 , ArtSlotInfo > : : const_iterator i = artifactsWorn . begin ( ) ; i ! = artifactsWorn . end ( ) ; i + + )
if ( i - > second . artifact - > artType - > id = = aid )
return i - > first ;
if ( onlyWorn )
return - 1 ;
for ( int i = 0 ; i < artifactsInBackpack . size ( ) ; i + + )
if ( artifactsInBackpack [ i ] . artifact - > artType - > id = = aid )
2011-12-14 00:23:17 +03:00
return GameConstants : : BACKPACK_START + i ;
2011-06-24 20:43:02 +03:00
return - 1 ;
}
si32 CArtifactSet : : getArtPos ( const CArtifactInstance * art ) const
{
for ( std : : map < ui16 , ArtSlotInfo > : : const_iterator i = artifactsWorn . begin ( ) ; i ! = artifactsWorn . end ( ) ; i + + )
if ( i - > second . artifact = = art )
return i - > first ;
for ( int i = 0 ; i < artifactsInBackpack . size ( ) ; i + + )
if ( artifactsInBackpack [ i ] . artifact = = art )
2011-12-14 00:23:17 +03:00
return GameConstants : : BACKPACK_START + i ;
2011-06-24 20:43:02 +03:00
return - 1 ;
}
2012-09-25 17:40:39 +03:00
const CArtifactInstance * CArtifactSet : : getArtByInstanceId ( TArtifactInstanceID artInstId ) const
2011-06-24 20:43:02 +03:00
{
for ( std : : map < ui16 , ArtSlotInfo > : : const_iterator i = artifactsWorn . begin ( ) ; i ! = artifactsWorn . end ( ) ; i + + )
if ( i - > second . artifact - > id = = artInstId )
return i - > second . artifact ;
for ( int i = 0 ; i < artifactsInBackpack . size ( ) ; i + + )
if ( artifactsInBackpack [ i ] . artifact - > id = = artInstId )
return artifactsInBackpack [ i ] . artifact ;
return NULL ;
}
2012-04-14 05:20:22 +03:00
bool CArtifactSet : : hasArt ( ui32 aid , bool onlyWorn /*= false*/ ) const
{
return getArtPos ( aid , onlyWorn ) ! = - 1 ;
}
2011-06-24 20:43:02 +03:00
const ArtSlotInfo * CArtifactSet : : getSlot ( ui16 pos ) const
{
if ( vstd : : contains ( artifactsWorn , pos ) )
return & artifactsWorn [ pos ] ;
2011-12-14 00:23:17 +03:00
if ( pos > = ArtifactPosition : : AFTER_LAST )
2011-06-24 20:43:02 +03:00
{
2011-12-14 00:23:17 +03:00
int backpackPos = ( int ) pos - GameConstants : : BACKPACK_START ;
2011-06-24 20:43:02 +03:00
if ( backpackPos < 0 | | backpackPos > = artifactsInBackpack . size ( ) )
return NULL ;
else
return & artifactsInBackpack [ backpackPos ] ;
}
return NULL ;
}
2012-04-14 05:20:22 +03:00
bool CArtifactSet : : isPositionFree ( ui16 pos , bool onlyLockCheck /*= false*/ ) const
{
if ( const ArtSlotInfo * s = getSlot ( pos ) )
return ( onlyLockCheck | | ! s - > artifact ) & & ! s - > locked ;
return true ; //no slot means not used
}
2011-06-24 20:43:02 +03:00
si32 CArtifactSet : : getArtTypeId ( ui16 pos ) const
{
const CArtifactInstance * const a = getArt ( pos ) ;
if ( ! a )
{
tlog2 < < ( dynamic_cast < const CGHeroInstance * > ( this ) ) - > name < < " has no artifact at " < < pos < < " (getArtTypeId) \n " ;
return - 1 ;
}
return a - > artType - > id ;
}
CArtifactSet : : ~ CArtifactSet ( )
{
}
ArtSlotInfo & CArtifactSet : : retreiveNewArtSlot ( ui16 slot )
{
assert ( ! vstd : : contains ( artifactsWorn , slot ) ) ;
2012-09-15 22:16:16 +03:00
ArtSlotInfo & ret = slot < GameConstants : : BACKPACK_START
2011-06-24 20:43:02 +03:00
? artifactsWorn [ slot ]
2011-12-14 00:23:17 +03:00
: * artifactsInBackpack . insert ( artifactsInBackpack . begin ( ) + ( slot - GameConstants : : BACKPACK_START ) , ArtSlotInfo ( ) ) ;
2011-06-24 20:43:02 +03:00
return ret ;
}
2012-04-14 05:20:22 +03:00
void CArtifactSet : : setNewArtSlot ( ui16 slot , CArtifactInstance * art , bool locked )
{
ArtSlotInfo & asi = retreiveNewArtSlot ( slot ) ;
asi . artifact = art ;
asi . locked = locked ;
}
2011-06-24 20:43:02 +03:00
void CArtifactSet : : eraseArtSlot ( ui16 slot )
{
2011-12-14 00:23:17 +03:00
if ( slot < GameConstants : : BACKPACK_START )
2011-06-24 20:43:02 +03:00
{
artifactsWorn . erase ( slot ) ;
}
else
{
2011-12-14 00:23:17 +03:00
slot - = GameConstants : : BACKPACK_START ;
2011-06-24 20:43:02 +03:00
artifactsInBackpack . erase ( artifactsInBackpack . begin ( ) + slot ) ;
}
2011-08-13 13:54:23 +03:00
}
2012-04-14 05:20:22 +03:00
void CArtifactSet : : artDeserializationFix ( CBonusSystemNode * node )
2011-08-13 13:54:23 +03:00
{
2012-04-14 05:20:22 +03:00
for ( bmap < ui16 , ArtSlotInfo > : : iterator i = artifactsWorn . begin ( ) ; i ! = artifactsWorn . end ( ) ; i + + )
if ( i - > second . artifact & & ! i - > second . locked )
node - > attachTo ( i - > second . artifact ) ;
2012-04-14 19:28:36 +03:00
}