2008-06-13 11:16:51 +03:00
# define VCMI_DLL
2008-01-09 19:21:31 +02:00
# include "../stdafx.h"
2007-06-07 23:16:19 +03:00
# include "CArtHandler.h"
2007-08-29 15:18:31 +03:00
# include "CLodHandler.h"
2008-11-30 02:15:38 +02:00
# include "CGeneralTextHandler.h"
2010-05-09 22:10:59 +03:00
# include <boost/bind.hpp>
# include <boost/foreach.hpp>
2008-06-13 11:16:51 +03:00
# include <boost/assign/std/vector.hpp>
# include <boost/assign/list_of.hpp>
2009-07-14 19:20:15 +03:00
# include <boost/lexical_cast.hpp>
2010-02-08 23:17:22 +02:00
# include <boost/foreach.hpp>
2010-06-28 08:07:21 +03:00
# include <boost/random/linear_congruential.hpp>
2010-11-10 02:06:25 +02:00
# include <boost/algorithm/string/replace.hpp>
2008-06-17 20:48:32 +03:00
# include "../lib/VCMI_Lib.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"
2008-06-13 11:16:51 +03:00
extern CLodHandler * bitmaph ;
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 ;
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
//
// bool CArtifact::isModable () const
// {
// return (bool)dynamic_cast<const IModableArt *>(this);
// }
2009-12-30 17:33:28 +02:00
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;
//
// // 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;
//
// // 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;
//
// VLC->arth->unequipArtifact(tempArtifWorn, slotID);
//
// BOOST_FOREACH(ui32 constituentID, *constituents)
// {
// const CArtifact& constituent = *VLC->arth->artifacts[constituentID];
// const int slot = constituent.possibleSlots[0];
//
// if (slot == 6 || slot == 7)
// rings++;
// else if ((slot >= 9 && slot <= 12) || slot == 18)
// misc++;
// else if (tempArtifWorn.find(slot) != tempArtifWorn.end())
// return false;
// }
//
// // Ensure enough ring slots are free
// for (int i = 0; i < sizeof(ringSlots)/sizeof(*ringSlots); i++)
// {
// if (tempArtifWorn.find(ringSlots[i]) == tempArtifWorn.end() || ringSlots[i] == slotID)
// rings--;
// }
// if (rings > 0)
// return false;
//
// // Ensure enough misc slots are free.
// for (int i = 0; i < sizeof(miscSlots)/sizeof(*miscSlots); i++)
// {
// if (tempArtifWorn.find(miscSlots[i]) == tempArtifWorn.end() || miscSlots[i] == slotID)
// misc--;
// }
// if (misc > 0)
// return false;
// }
//
// 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;
//
// const CArtifact &artifact = *VLC->arth->artifacts[artifactID];
// assert(artifact.constituents);
//
// BOOST_FOREACH(ui32 constituentID, *artifact.constituents)
// {
// bool found = false;
// for (std::map<ui16, const CArtifact*>::const_iterator it = artifWorn.begin(); it != artifWorn.end(); ++it)
// {
// if (it->second->id == constituentID)
// {
// found = true;
// break;
// }
// }
// if (!found)
// return false;
// }
//
// 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
{
2010-07-20 21:34:32 +03:00
nodeType = 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
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 ) ;
2011-01-28 04:11:58 +02:00
//modableArtifacts = boost::assign::map_list_of(1, 1)(146,3)(147,3)(148,3)(150,3)(151,3)(152,3)(154,3)(156,2);
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 ;
2009-08-26 17:09:55 +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 ) ;
2008-06-13 11:16:51 +03:00
std : : string buf = bitmaph - > getTextFile ( " ARTRAITS.TXT " ) , dump , pom ;
2007-08-04 22:01:22 +03:00
int it = 0 ;
for ( int i = 0 ; i < 2 ; + + i )
2007-06-07 23:16:19 +03:00
{
2008-06-13 11:16:51 +03:00
loadToIt ( dump , buf , it , 3 ) ;
2007-06-07 23:16:19 +03:00
}
2008-11-30 02:15:38 +02:00
VLC - > generaltexth - > artifNames . resize ( ARTIFACTS_QUANTITY ) ;
VLC - > generaltexth - > artifDescriptions . resize ( ARTIFACTS_QUANTITY ) ;
2010-11-10 02:06:25 +02:00
std : : map < ui32 , ui8 > : : iterator itr ;
2007-08-04 22:01:22 +03:00
for ( int i = 0 ; i < ARTIFACTS_QUANTITY ; i + + )
2007-06-07 23:16:19 +03:00
{
2011-01-28 04:11:58 +02:00
CArtifact * art = new CArtifact ( ) ;
// if ((itr = modableArtifacts.find(i)) != modableArtifacts.end())
// {
// switch (itr->second)
// {
// case 1:
// art = new CScroll;
// break;
// case 2:
// art = new CCustomizableArt;
// break;
// case 3:
// art = new CCommanderArt;
// break;
// };
// }
// else
// art = new CArtifact;
2010-11-10 02:06:25 +02:00
2010-06-26 19:02:10 +03:00
CArtifact & nart = * art ;
2009-05-04 02:15:18 +03:00
nart . id = i ;
2008-11-30 02:15:38 +02:00
loadToIt ( VLC - > generaltexth - > artifNames [ i ] , buf , it , 4 ) ;
2008-06-13 11:16:51 +03:00
loadToIt ( pom , buf , it , 4 ) ;
2007-08-04 22:01:22 +03:00
nart . price = atoi ( pom . c_str ( ) ) ;
2008-06-13 11:16:51 +03:00
for ( int j = 0 ; j < slots . size ( ) ; j + + )
2007-06-07 23:16:19 +03:00
{
2008-06-13 11:16:51 +03:00
loadToIt ( pom , buf , it , 4 ) ;
2010-02-20 15:24:38 +02:00
if ( pom . size ( ) & & pom [ 0 ] = = ' x ' )
2008-08-26 00:14:00 +03:00
nart . possibleSlots . push_back ( slots [ j ] ) ;
2007-06-07 23:16:19 +03:00
}
2008-06-13 11:16:51 +03:00
loadToIt ( pom , buf , it , 4 ) ;
nart . aClass = classes [ pom [ 0 ] ] ;
2009-05-04 02:15:18 +03:00
//load description and remove quotation marks
std : : string & desc = VLC - > generaltexth - > artifDescriptions [ i ] ;
loadToIt ( desc , buf , it , 3 ) ;
if ( desc [ 0 ] = = ' \" ' & & desc [ desc . size ( ) - 1 ] = = ' \" ' )
desc = desc . substr ( 1 , desc . size ( ) - 2 ) ;
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 ;
2010-06-01 02:26:46 +03:00
switch ( nart . id )
{
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
}
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.
2010-06-26 19:02:10 +03:00
BOOST_FOREACH ( CArtifact * artifact , artifacts )
{
if ( artifact - > constituents ! = NULL )
{
BOOST_FOREACH ( ui32 constituentID , * artifact - > constituents )
{
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 ( )
{
2010-07-26 23:56: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
}
2010-06-28 08:07:21 +03:00
void CArtHandler : : erasePickedArt ( si32 id )
{
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 ;
}
ptr - > erase ( std : : find ( ptr - > begin ( ) , ptr - > end ( ) , art ) ) ; //remove the artifact from avaliable list
}
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 ( ) ] ;
return art - > id ;
}
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 ) ;
if ( ! out . size ( ) ) //no arts are avaliable
{
out . resize ( 64 ) ;
std : : fill_n ( out . begin ( ) , 64 , artifacts [ 2 ] ) ; //magic
}
}
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
{
if ( arts - > empty ( ) ) //restock avaliable arts
{
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 ) ;
}
}
2010-08-06 13:46:40 +03:00
void CArtHandler : : giveArtBonus ( int aid , Bonus : : BonusType type , int val , int subtype , int valType , ILimiter * limiter )
2008-11-30 02:15:38 +02:00
{
2010-11-20 02:03:31 +02:00
Bonus * added = new Bonus ( Bonus : : PERMANENT , type , Bonus : : ARTIFACT , val , aid , subtype ) ;
added - > valType = valType ;
added - > limiter . reset ( limiter ) ;
2010-05-02 21:20:26 +03:00
if ( type = = Bonus : : MORALE | | Bonus : : LUCK )
2010-11-20 02:03:31 +02:00
added - > description = " \n " + artifacts [ aid ] - > Name ( ) + ( val > 0 ? " + " : " " ) + boost : : lexical_cast < std : : string > ( val ) ;
2010-11-19 00:06:56 +02:00
artifacts [ aid ] - > addNewBonus ( added ) ;
2008-11-30 02:15:38 +02:00
}
2009-04-04 01:34:31 +03:00
void CArtHandler : : addBonuses ( )
2008-11-30 02:15:38 +02:00
{
2010-05-02 21:20:26 +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)
2009-04-04 01:34:31 +03:00
# 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)
//Attack bonus artifacts (Weapons)
ART_PRIM_SKILL ( 7 , 0 , + 2 ) ; //Centaur Axe
2009-08-21 22:31:41 +03:00
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
2009-04-04 01:34:31 +03:00
//Defense bonus artifacts (Shields)
ART_PRIM_SKILL ( 13 , 1 , + 2 ) ; //Shield of the Dwarven Lords
2009-08-21 22:31:41 +03:00
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
2009-04-04 01:34:31 +03:00
//Knowledge bonus artifacts (Helmets)
ART_PRIM_SKILL ( 19 , 3 , + 1 ) ; //Helm of the Alabaster Unicorn
2009-08-21 22:31:41 +03:00
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
2009-04-04 01:34:31 +03:00
//Spell power bonus artifacts (Armours)
ART_PRIM_SKILL ( 25 , 2 , + 1 ) ; //Breastplate of Petrified Wood
2009-08-21 22:31:41 +03:00
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
2009-04-04 01:34:31 +03:00
//All primary skills (various)
ART_ALL_PRIM_SKILLS ( 31 , + 1 ) ; //Armor of Wonder
2009-08-21 22:31:41 +03:00
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
2009-04-04 01:34:31 +03:00
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
2009-08-21 22:31:41 +03:00
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
2009-04-04 01:34:31 +03:00
//Spell power and Knowledge (various)
ART_POWER_AND_KNOWLEDGE ( 41 , + 1 ) ; //Dragonbone Greaves
2009-08-21 22:31:41 +03:00
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
2009-04-04 01:34:31 +03:00
//Luck and morale
ART_MORALE ( 45 , + 1 ) ; //Still Eye of the Dragon
2009-05-24 17:32:36 +03:00
ART_LUCK ( 45 , + 1 ) ; //Still Eye of the Dragon
2009-04-04 01:34:31 +03:00
ART_LUCK ( 46 , + 1 ) ; //Clover of Fortune
ART_LUCK ( 47 , + 1 ) ; //Cards of Prophecy
ART_LUCK ( 48 , + 1 ) ; //Ladybird of Luck
2009-07-27 20:55:56 +03:00
ART_MORALE ( 49 , + 1 ) ; //Badge of Courage -> +1 morale and immunity to hostile mind spells:
2010-08-05 14:47:57 +03:00
giveArtBonus ( 49 , Bonus : : SPELL_IMMUNITY , 0 , 50 ) ; //sorrow
giveArtBonus ( 49 , Bonus : : SPELL_IMMUNITY , 0 , 59 ) ; //berserk
giveArtBonus ( 49 , Bonus : : SPELL_IMMUNITY , 0 , 60 ) ; //hypnotize
giveArtBonus ( 49 , Bonus : : SPELL_IMMUNITY , 0 , 61 ) ; //forgetfulness
giveArtBonus ( 49 , Bonus : : SPELL_IMMUNITY , 0 , 62 ) ; //blind
2009-04-04 01:34:31 +03:00
ART_MORALE ( 50 , + 1 ) ; //Crest of Valor
ART_MORALE ( 51 , + 1 ) ; //Glyph of Gallantry
2010-05-02 21:20:26 +03:00
giveArtBonus ( 52 , Bonus : : SIGHT_RADIOUS , + 1 ) ; //Speculum
giveArtBonus ( 53 , Bonus : : SIGHT_RADIOUS , + 1 ) ; //Spyglass
2009-04-04 01:34:31 +03:00
//necromancy bonus
2010-07-17 20:02:11 +03:00
giveArtBonus ( 54 , Bonus : : SECONDARY_SKILL_PREMY , + 5 , 12 , Bonus : : ADDITIVE_VALUE ) ; //Amulet of the Undertaker
giveArtBonus ( 55 , Bonus : : SECONDARY_SKILL_PREMY , + 10 , 12 , Bonus : : ADDITIVE_VALUE ) ; //Vampire's Cowl
giveArtBonus ( 56 , Bonus : : SECONDARY_SKILL_PREMY , + 15 , 12 , Bonus : : ADDITIVE_VALUE ) ; //Dead Man's Boots
2009-04-04 01:34:31 +03:00
2010-05-02 21:20:26 +03:00
giveArtBonus ( 57 , Bonus : : MAGIC_RESISTANCE , + 5 ) ; //Garniture of Interference
giveArtBonus ( 58 , Bonus : : MAGIC_RESISTANCE , + 10 ) ; //Surcoat of Counterpoise
giveArtBonus ( 59 , Bonus : : MAGIC_RESISTANCE , + 15 ) ; //Boots of Polarity
2009-04-04 01:34:31 +03:00
//archery bonus
2010-07-17 20:02:11 +03:00
giveArtBonus ( 60 , Bonus : : SECONDARY_SKILL_PREMY , + 5 , 1 , Bonus : : ADDITIVE_VALUE ) ; //Bow of Elven Cherrywood
giveArtBonus ( 61 , Bonus : : SECONDARY_SKILL_PREMY , + 10 , 1 , Bonus : : ADDITIVE_VALUE ) ; //Bowstring of the Unicorn's Mane
giveArtBonus ( 62 , Bonus : : SECONDARY_SKILL_PREMY , + 15 , 1 , Bonus : : ADDITIVE_VALUE ) ; //Angel Feather Arrows
2009-04-04 01:34:31 +03:00
//eagle eye bonus
2010-07-17 20:02:11 +03:00
giveArtBonus ( 63 , Bonus : : SECONDARY_SKILL_PREMY , + 5 , 11 , Bonus : : ADDITIVE_VALUE ) ; //Bird of Perception
giveArtBonus ( 64 , Bonus : : SECONDARY_SKILL_PREMY , + 10 , 11 , Bonus : : ADDITIVE_VALUE ) ; //Stoic Watchman
giveArtBonus ( 65 , Bonus : : SECONDARY_SKILL_PREMY , + 15 , 11 , Bonus : : ADDITIVE_VALUE ) ; //Emblem of Cognizance
2009-04-04 01:34:31 +03:00
//reducing cost of surrendering
2010-05-02 21:20:26 +03:00
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
2010-05-15 18:00:19 +03:00
giveArtBonus ( 72 , Bonus : : FLYING_MOVEMENT , 0 , 1 ) ; //Angel Wings
2010-05-02 21:20:26 +03:00
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 , Bonus : : BLOCK_SPELLS_ABOVE_LEVEL , 3 ) ; //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
2010-05-15 18:00:19 +03:00
giveArtBonus ( 90 , Bonus : : WATER_WALKING , 0 , 1 ) ; //Boots of Levitation
2010-05-02 21:20:26 +03:00
giveArtBonus ( 91 , Bonus : : NO_SHOTING_PENALTY , 0 ) ; //Golden Bow
2010-08-05 14:47:57 +03:00
giveArtBonus ( 92 , Bonus : : SPELL_IMMUNITY , 0 , 35 ) ; //Sphere of Permanence
2010-05-02 21:20:26 +03:00
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
2010-08-05 14:47:57 +03:00
giveArtBonus ( 100 , Bonus : : SPELL_IMMUNITY , 0 , 59 ) ; //Pendant of Dispassion
giveArtBonus ( 101 , Bonus : : SPELL_IMMUNITY , 0 , 62 ) ; //Pendant of Second Sight
giveArtBonus ( 102 , Bonus : : SPELL_IMMUNITY , 0 , 42 ) ; //Pendant of Holiness
giveArtBonus ( 103 , Bonus : : SPELL_IMMUNITY , 0 , 24 ) ; //Pendant of Life
giveArtBonus ( 104 , Bonus : : SPELL_IMMUNITY , 0 , 25 ) ; //Pendant of Death
giveArtBonus ( 105 , Bonus : : SPELL_IMMUNITY , 0 , 60 ) ; //Pendant of Free Will
giveArtBonus ( 106 , Bonus : : SPELL_IMMUNITY , 0 , 17 ) ; //Pendant of Negativity
giveArtBonus ( 107 , Bonus : : SPELL_IMMUNITY , 0 , 61 ) ; //Pendant of Total Recall
2010-05-02 21:20:26 +03:00
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 , 6 ) ; //Endless Sack of Gold
giveArtBonus ( 116 , Bonus : : GENERATE_RESOURCE , + 750 , 6 ) ; //Endless Bag of Gold
giveArtBonus ( 117 , Bonus : : GENERATE_RESOURCE , + 500 , 6 ) ; //Endless Purse of Gold
giveArtBonus ( 118 , Bonus : : CREATURE_GROWTH , + 5 , 1 ) ; //Legs of Legion
giveArtBonus ( 119 , Bonus : : CREATURE_GROWTH , + 4 , 2 ) ; //Loins of Legion
giveArtBonus ( 120 , Bonus : : CREATURE_GROWTH , + 3 , 3 ) ; //Torso of Legion
giveArtBonus ( 121 , Bonus : : CREATURE_GROWTH , + 2 , 4 ) ; //Arms of Legion
giveArtBonus ( 122 , Bonus : : CREATURE_GROWTH , + 1 , 5 ) ; //Head of Legion
2009-04-04 01:34:31 +03:00
//Sea Captain's Hat
2010-05-02 21:20:26 +03:00
giveArtBonus ( 123 , Bonus : : WHIRLPOOL_PROTECTION , 0 ) ;
giveArtBonus ( 123 , Bonus : : SEA_MOVEMENT , + 500 ) ;
2010-08-05 12:11:38 +03:00
giveArtBonus ( 123 , Bonus : : SPELL , 3 , 0 , Bonus : : INDEPENDENT_MAX ) ;
giveArtBonus ( 123 , Bonus : : SPELL , 3 , 1 , Bonus : : INDEPENDENT_MAX ) ;
2009-04-04 01:34:31 +03:00
2010-05-02 21:20:26 +03:00
giveArtBonus ( 124 , Bonus : : SPELLS_OF_LEVEL , 3 , 1 ) ; //Spellbinder's Hat
giveArtBonus ( 125 , Bonus : : ENEMY_CANT_ESCAPE , 0 ) ; //Shackles of War
giveArtBonus ( 126 , Bonus : : BLOCK_SPELLS_ABOVE_LEVEL , 0 ) ; //Orb of Inhibition
2009-08-21 22:31:41 +03:00
2010-08-06 13:46:40 +03:00
//vial of dragon blood
giveArtBonus ( 127 , Bonus : : PRIMARY_SKILL , + 5 , PrimarySkill : : ATTACK , Bonus : : BASE_NUMBER , new HasAnotherBonusLimiter ( Bonus : : DRAGON_NATURE ) ) ;
giveArtBonus ( 127 , Bonus : : PRIMARY_SKILL , + 5 , PrimarySkill : : DEFENSE , Bonus : : BASE_NUMBER , new HasAnotherBonusLimiter ( Bonus : : DRAGON_NATURE ) ) ;
2009-08-21 22:31:41 +03:00
//Armageddon's Blade
2010-08-05 12:11:38 +03:00
giveArtBonus ( 128 , Bonus : : SPELL , 3 , 26 , Bonus : : INDEPENDENT_MAX ) ;
2010-08-05 14:47:57 +03:00
giveArtBonus ( 128 , Bonus : : SPELL_IMMUNITY , 0 , 26 ) ;
2009-08-21 22:31:41 +03:00
ART_ATTACK_AND_DEFENSE ( 128 , + 3 ) ;
ART_PRIM_SKILL ( 128 , 2 , + 3 ) ;
ART_PRIM_SKILL ( 128 , 3 , + 6 ) ;
//Angelic Alliance
2010-05-02 21:20:26 +03:00
giveArtBonus ( 129 , Bonus : : NONEVIL_ALIGNMENT_MIX , 0 ) ;
giveArtBonus ( 129 , Bonus : : OPENING_BATTLE_SPELL , 10 , 29 ) ; // Prayer
2009-08-21 22:31:41 +03:00
//Cloak of the Undead King
2010-05-02 21:20:26 +03:00
giveArtBonus ( 130 , Bonus : : IMPROVED_NECROMANCY , 0 ) ;
2009-08-21 22:31:41 +03:00
2009-08-21 23:20:46 +03:00
//Elixir of Life
2010-05-02 21:20:26 +03:00
giveArtBonus ( 131 , Bonus : : STACK_HEALTH , + 25 , - 1 , Bonus : : PERCENT_TO_BASE ) ;
giveArtBonus ( 131 , Bonus : : HP_REGENERATION , + 50 ) ;
2009-08-21 23:20:46 +03:00
2009-08-21 22:31:41 +03:00
//Armor of the Damned
2010-05-02 21:20:26 +03:00
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
2009-08-23 23:33:05 +03:00
2009-12-23 03:46:15 +02:00
// Statue of Legion - gives only 50% growth
2010-09-25 23:23:55 +03:00
giveArtBonus ( 133 , Bonus : : CREATURE_GROWTH_PERCENT , 50 , - 1 ) ;
2009-08-21 22:31:41 +03:00
//Power of the Dragon Father
2010-05-02 21:20:26 +03:00
giveArtBonus ( 134 , Bonus : : LEVEL_SPELL_IMMUNITY , 4 ) ;
2009-08-21 22:31:41 +03:00
//Titan's Thunder
2010-05-09 22:10:59 +03:00
// FIXME: should also add a permanent spell book, somehow.
2010-05-02 21:20:26 +03:00
giveArtBonus ( 135 , Bonus : : SPELL , 3 , 57 ) ;
2009-08-21 22:31:41 +03:00
//Admiral's Hat
2010-05-02 21:20:26 +03:00
giveArtBonus ( 136 , Bonus : : FREE_SHIP_BOARDING , 0 ) ;
2009-08-21 22:31:41 +03:00
//Bow of the Sharpshooter
2010-05-02 21:20:26 +03:00
giveArtBonus ( 137 , Bonus : : NO_SHOTING_PENALTY , 0 ) ;
giveArtBonus ( 137 , Bonus : : FREE_SHOOTING , 0 ) ;
2009-08-22 15:50:23 +03:00
//Wizard's Well
2010-05-02 21:20:26 +03:00
giveArtBonus ( 138 , Bonus : : FULL_MANA_REGENERATION , 0 ) ;
2009-08-21 22:31:41 +03:00
//Ring of the Magi
2010-05-09 22:10:59 +03:00
giveArtBonus ( 139 , Bonus : : SPELL_DURATION , + 50 ) ;
2009-08-21 22:31:41 +03:00
//Cornucopia
2010-05-09 22:10:59 +03:00
giveArtBonus ( 140 , Bonus : : GENERATE_RESOURCE , + 4 , 1 ) ;
giveArtBonus ( 140 , Bonus : : GENERATE_RESOURCE , + 4 , 3 ) ;
giveArtBonus ( 140 , Bonus : : GENERATE_RESOURCE , + 4 , 4 ) ;
giveArtBonus ( 140 , Bonus : : GENERATE_RESOURCE , + 4 , 5 ) ;
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
}
2011-01-28 04:11:58 +02:00
// /**
// * Locally equips an artifact to a hero's worn slots. Unequips an already present artifact.
// * Does not test if the operation is legal.
// * @param artifWorn A hero's set of worn artifacts.
// * @param bonuses Optional list of bonuses to update.
// */
// void CArtHandler::equipArtifact( std::map<ui16, const CArtifact*> &artifWorn, ui16 slotID, const CArtifact* art ) const
// {
// unequipArtifact(artifWorn, slotID);
//
// if (art) //false when artifact is NULL -> slot set to empty
// {
// const CArtifact &artifact = *art;
//
// // Add artifact.
// artifWorn[slotID] = art;
//
// // Add locks, in reverse order of being removed.
// if (artifact.constituents != NULL)
// {
// bool destConsumed = false; // Determines which constituent that will be counted for together with the artifact.
//
// BOOST_FOREACH(ui32 constituentID, *artifact.constituents)
// {
// const CArtifact &constituent = *artifacts[constituentID];
//
// if (!destConsumed && vstd::contains(constituent.possibleSlots, slotID))
// {
// destConsumed = true;
// }
// else
// {
// BOOST_FOREACH(ui16 slot, constituent.possibleSlots)
// {
// if (!vstd::contains(artifWorn, slot))
// {
// artifWorn[slot] = VLC->arth->artifacts[145]; //lock
// break;
// }
// }
// }
// }
// }
// }
// }
//
// /**
// * Locally unequips an artifact from a hero's worn slots.
// * Does not test if the operation is legal.
// * @param artifWorn A hero's set of worn artifacts.
// * @param bonuses Optional list of bonuses to update.
// */
// void CArtHandler::unequipArtifact(std::map<ui16, const CArtifact*> &artifWorn, ui16 slotID) const
// {
// if (!vstd::contains(artifWorn, slotID))
// return;
//
// const CArtifact &artifact = *artifWorn[slotID];
//
// // Remove artifact, if it's not already removed.
// artifWorn.erase(slotID);
//
// // Remove locks, in reverse order of being added.
// if (artifact.constituents != NULL)
// {
// bool destConsumed = false;
//
// BOOST_FOREACH(ui32 constituentID, *artifact.constituents)
// {
// const CArtifact &constituent = *artifacts[constituentID];
//
// if (!destConsumed && vstd::contains(constituent.possibleSlots, slotID))
// {
// destConsumed = true;
// }
// else
// {
// BOOST_REVERSE_FOREACH(ui16 slot, constituent.possibleSlots)
// {
// if (vstd::contains(artifWorn, slot) && artifWorn[slot]->id == 145)
// {
// artifWorn.erase(slot);
// break;
// }
// }
// }
// }
// }
// }
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 ] ) ;
}
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 )
{
CArtifactInstance * ret = new CArtifactInstance ( VLC - > arth - > artifacts [ 93 ] ) ;
Bonus * b = new Bonus ( Bonus : : PERMANENT , Bonus : : SPELL , Bonus : : ARTIFACT_INSTANCE , - 1 , s - > id ) ;
ret - > addNewBonus ( b ) ;
return ret ;
}
void CArtifactInstance : : init ( )
{
2010-12-26 16:34:11 +02:00
id = - 1 ;
}
int CArtifactInstance : : firstAvailableSlot ( const CGHeroInstance * h ) const
{
BOOST_FOREACH ( ui16 slot , artType - > possibleSlots )
{
2011-01-18 20:56:14 +02:00
if ( canBePutAt ( ArtifactLocation ( 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 ) ;
}
int CArtifactInstance : : firstBackpackSlot ( const CGHeroInstance * h ) const
{
if ( ! artType - > isBig ( ) ) //discard big artifact
return Arts : : BACKPACK_START + h - > artifactsInBackpack . size ( ) ;
return - 1 ;
}
2010-12-29 23:04:22 +02:00
bool CArtifactInstance : : canBePutAt ( const ArtifactLocation & al , bool assumeDestRemoved /*= false*/ ) const
2010-12-26 16:34:11 +02:00
{
2010-12-29 23:04:22 +02:00
if ( al . slot > = Arts : : BACKPACK_START )
{
if ( artType - > isBig ( ) )
return false ;
//TODO backpack limit
return true ;
}
2010-12-26 16:34:11 +02:00
if ( ! vstd : : contains ( artType - > possibleSlots , al . slot ) )
return false ;
2011-01-24 01:49:17 +02:00
return al . hero - > isPositionFree ( al . slot , assumeDestRemoved ) ;
2010-12-26 16:34:11 +02:00
}
void CArtifactInstance : : putAt ( CGHeroInstance * h , ui16 slot )
{
assert ( canBePutAt ( ArtifactLocation ( h , slot ) ) ) ;
2011-01-22 05:43:20 +02:00
h - > setNewArtSlot ( slot , this , false ) ;
2011-01-06 22:00:19 +02:00
if ( slot < Arts : : BACKPACK_START )
h - > attachTo ( this ) ;
2010-12-26 16:34:11 +02:00
}
void CArtifactInstance : : removeFrom ( CGHeroInstance * h , ui16 slot )
{
assert ( h - > CArtifactSet : : getArt ( slot ) = = this ) ;
2011-01-22 05:43:20 +02:00
h - > eraseArtSlot ( slot ) ;
2010-12-26 16:34:11 +02:00
if ( slot < Arts : : BACKPACK_START )
h - > detachFrom ( this ) ;
//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
}
std : : vector < const CArtifact * > CArtifactInstance : : assemblyPossibilities ( const CGHeroInstance * h ) const
{
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 ;
2011-01-18 20:56:14 +02: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 ;
}
2011-01-15 19:58:08 +02:00
void CArtifactInstance : : move ( ArtifactLocation & src , ArtifactLocation & dst )
{
removeFrom ( src . hero , src . slot ) ;
putAt ( dst . hero , dst . slot ) ;
}
2011-01-18 20:56:14 +02:00
CArtifactInstance * CArtifactInstance : : createNewArtifactInstance ( CArtifact * Art )
{
if ( ! Art - > constituents )
return new CArtifactInstance ( Art ) ;
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 ] ) ;
}
2010-12-29 23:04:22 +02:00
bool CCombinedArtifactInstance : : canBePutAt ( const ArtifactLocation & al , bool assumeDestRemoved /*= false*/ ) const
{
2011-01-28 04:11:58 +02:00
bool canMainArtifactBePlaced = CArtifactInstance : : canBePutAt ( al , assumeDestRemoved ) ;
if ( ! canMainArtifactBePlaced )
return false ; //no is no...
if ( al . slot > = Arts : : BACKPACK_START )
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
//we iterate over all active slots and check if constituents fits them
for ( int i = 0 ; i < Arts : : BACKPACK_START ; i + + )
{
for ( std : : vector < ConstituentInfo > : : iterator art = constituentsToBePlaced . begin ( ) ; art ! = constituentsToBePlaced . end ( ) ; art + + )
{
if ( art - > art - > canBePutAt ( ArtifactLocation ( al . hero , i ) , i = = al . slot ) ) // i == al.slot because we can remove already worn artifact only from that slot that is our main destination
{
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 )
: CArtifactInstance ( Art )
{
}
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 ) ) ;
assert ( art - > parents . size ( ) = = 1 & & art - > parents . front ( ) = = art - > artType ) ;
constituentsInfo . push_back ( ConstituentInfo ( art , slot ) ) ;
2011-01-28 04:11:58 +02:00
attachTo ( art ) ;
2011-01-22 05:43:20 +02:00
}
void CCombinedArtifactInstance : : putAt ( CGHeroInstance * h , ui16 slot )
{
if ( slot > = Arts : : BACKPACK_START )
{
CArtifactInstance : : putAt ( h , slot ) ;
BOOST_FOREACH ( ConstituentInfo & ci , constituentsInfo )
ci . slot = - 1 ;
}
else
{
CArtifactInstance * mainConstituent = figureMainConstituent ( slot ) ; //it'll be replaced with combined artifact, not a lock
2011-01-24 01:49:17 +02:00
CArtifactInstance : : putAt ( h , slot ) ; //puts combined art (this)
2011-01-22 05:43:20 +02:00
BOOST_FOREACH ( ConstituentInfo & ci , constituentsInfo )
{
if ( ci . art ! = mainConstituent )
{
int pos = - 1 ;
if ( isbetw ( ci . slot , 0 , Arts : : BACKPACK_START ) & & ci . art - > canBePutAt ( ArtifactLocation ( h , ci . slot ) ) ) //there is a valid suggestion where to place lock
pos = ci . slot ;
else
ci . slot = pos = ci . art - > firstAvailableSlot ( h ) ;
assert ( pos < Arts : : BACKPACK_START ) ;
h - > setNewArtSlot ( pos , ci . art , true ) ; //sets as lock
}
else
{
ci . slot = - 1 ;
}
}
}
}
void CCombinedArtifactInstance : : removeFrom ( CGHeroInstance * h , ui16 slot )
{
if ( slot > = Arts : : BACKPACK_START )
{
CArtifactInstance : : removeFrom ( h , slot ) ;
}
else
{
BOOST_FOREACH ( ConstituentInfo & ci , constituentsInfo )
{
if ( ci . slot > = 0 )
{
h - > eraseArtSlot ( ci . slot ) ;
ci . slot = - 1 ;
}
else
{
//main constituent
CArtifactInstance : : removeFrom ( h , slot ) ;
}
}
2011-01-18 20:56:14 +02:00
}
}
2011-01-22 05:43:20 +02:00
CArtifactInstance * CCombinedArtifactInstance : : figureMainConstituent ( ui16 slot )
{
CArtifactInstance * mainConstituent = NULL ; //it'll be replaced with combined artifact, not a lock
BOOST_FOREACH ( ConstituentInfo & ci , constituentsInfo )
if ( ci . slot = = slot )
mainConstituent = ci . art ;
if ( ! mainConstituent )
{
BOOST_FOREACH ( ConstituentInfo & ci , constituentsInfo )
{
if ( vstd : : contains ( ci . art - > artType - > possibleSlots , slot ) )
{
mainConstituent = ci . art ;
}
}
}
return mainConstituent ;
}
2011-01-18 20:56:14 +02:00
CCombinedArtifactInstance : : ConstituentInfo : : ConstituentInfo ( CArtifactInstance * Art /*= NULL*/ , ui16 Slot /*= -1*/ )
{
art = Art ;
slot = Slot ;
2010-12-17 20:47:07 +02:00
}