2010-07-29 20:00:34 +03:00
/*
* CArtHandler . h , 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
*
*/
2017-07-13 10:26:03 +02:00
# pragma once
# include "../lib/HeroBonus.h"
//#include "../lib/ConstTransitivePtr.h"
//#include "JsonNode.h"
# include "GameConstants.h"
# include "IHandlerBase.h"
2013-03-02 19:55:51 +03:00
class CArtHandler ;
2010-11-10 02:06:25 +02:00
class CArtifact ;
2010-12-26 16:34:11 +02:00
class CGHeroInstance ;
struct ArtifactLocation ;
2012-04-14 05:20:22 +03:00
class CArtifactSet ;
2012-07-16 19:18:02 +03:00
class CArtifactInstance ;
2014-03-17 22:51:07 +03:00
class CRandomGenerator ;
2016-02-13 18:43:05 +02:00
class CMap ;
2016-11-13 12:38:42 +02:00
class JsonSerializeFormat ;
2010-07-29 20:00:34 +03:00
2012-12-10 16:55:54 +03:00
# define ART_BEARER_LIST \
ART_BEARER ( HERO ) \
ART_BEARER ( CREATURE ) \
ART_BEARER ( COMMANDER )
2012-04-14 05:20:22 +03:00
namespace ArtBearer
{
2013-02-07 20:34:50 +03:00
enum ArtBearer
2012-04-14 05:20:22 +03:00
{
2012-12-10 16:55:54 +03:00
# define ART_BEARER(x) x,
ART_BEARER_LIST
# undef ART_BEARER
2011-12-14 00:23:17 +03:00
} ;
}
class DLL_LINKAGE CArtifact : public CBonusSystemNode //container for artifacts
2010-07-29 20:00:34 +03:00
{
2010-11-10 02:06:25 +02:00
protected :
2010-07-29 20:00:34 +03:00
std : : string name , description ; //set if custom
2012-12-06 22:03:47 +03:00
std : : string eventText ; //short story displayed upon picking
2010-07-29 20:00:34 +03:00
public :
enum EartClass { ART_SPECIAL = 1 , ART_TREASURE = 2 , ART_MINOR = 4 , ART_MAJOR = 8 , ART_RELIC = 16 } ; //artifact classes
2016-01-24 01:27:14 +02:00
2015-08-24 10:55:45 +02:00
std : : string identifier ;
2012-12-10 16:55:54 +03:00
std : : string image ;
2012-12-13 17:27:33 +03:00
std : : string large ; // big image for cutom artifacts, used in drag & drop
2012-12-16 14:35:14 +03:00
std : : string advMapDef ; //used for adventure map object
2013-04-22 22:51:22 +03:00
si32 iconIndex ;
2016-11-27 21:07:01 +02:00
ui32 price ;
std : : map < ArtBearer : : ArtBearer , std : : vector < ArtifactPosition > > possibleSlots ; //Bearer Type => ids of slots where artifact can be placed
std : : unique_ptr < std : : vector < CArtifact * > > constituents ; // Artifacts IDs a combined artifact consists of, or nullptr.
std : : vector < CArtifact * > constituentOf ; // Reverse map of constituents - combined arts that include this art
EartClass aClass ;
ArtifactID id ;
2017-05-26 18:51:45 +02:00
CreatureID warMachine ;
2012-12-10 16:55:54 +03:00
2010-07-29 20:00:34 +03:00
const std : : string & Name ( ) const ; //getter
const std : : string & Description ( ) const ; //getter
2012-12-06 22:03:47 +03:00
const std : : string & EventText ( ) const ;
2013-03-02 19:55:51 +03:00
2010-07-29 20:00:34 +03:00
bool isBig ( ) const ;
2014-12-24 19:43:35 +02:00
bool isTradable ( ) const ;
2011-03-12 23:55:31 +02:00
2010-07-29 20:00:34 +03:00
int getArtClassSerial ( ) const ; //0 - treasure, 1 - minor, 2 - major, 3 - relic, 4 - spell scroll, 5 - other
2013-03-12 17:56:23 +03:00
std : : string nodeName ( ) const override ;
2016-09-19 23:36:35 +02:00
void addNewBonus ( const std : : shared_ptr < Bonus > & b ) override ;
2010-07-29 20:00:34 +03:00
2014-03-17 22:51:07 +03:00
virtual void levelUpArtifact ( CArtifactInstance * art ) { } ;
2010-07-29 20:00:34 +03:00
template < typename Handler > void serialize ( Handler & h , const int version )
{
2011-01-18 20:56:14 +02:00
h & static_cast < CBonusSystemNode & > ( * this ) ;
2017-07-31 15:35:42 +02:00
h & name ;
h & description ;
h & eventText ;
h & image ;
h & large ;
h & advMapDef ;
h & iconIndex ;
h & price ;
h & possibleSlots ;
h & constituents ;
h & constituentOf ;
h & aClass ;
h & id ;
if ( version > = 759 )
2015-08-24 10:55:45 +02:00
{
h & identifier ;
}
2017-05-26 18:51:45 +02:00
if ( version > = 771 )
{
h & warMachine ;
}
else if ( ! h . saving )
{
fillWarMachine ( ) ;
}
2010-07-29 20:00:34 +03:00
}
CArtifact ( ) ;
~ CArtifact ( ) ;
2013-03-02 19:55:51 +03:00
friend class CArtHandler ;
2017-05-26 18:51:45 +02:00
private :
void fillWarMachine ( ) ;
2010-07-29 20:00:34 +03:00
} ;
2012-07-16 19:18:02 +03:00
class DLL_LINKAGE CGrowingArtifact : public CArtifact //for example commander artifacts getting bonuses after battle
{
public :
std : : vector < std : : pair < ui16 , Bonus > > bonusesPerLevel ; //bonus given each n levels
std : : vector < std : : pair < ui16 , Bonus > > thresholdBonuses ; //after certain level they will be added once
2016-10-22 10:00:55 +02:00
void levelUpArtifact ( CArtifactInstance * art ) override ;
2012-07-16 19:18:02 +03:00
template < typename Handler > void serialize ( Handler & h , const int version )
{
h & static_cast < CArtifact & > ( * this ) ;
2017-07-31 15:35:42 +02:00
h & bonusesPerLevel ;
h & thresholdBonuses ;
2012-07-16 19:18:02 +03:00
}
} ;
2011-12-14 00:23:17 +03:00
class DLL_LINKAGE CArtifactInstance : public CBonusSystemNode
2010-12-17 20:47:07 +02:00
{
2011-01-18 20:56:14 +02:00
protected :
2010-12-25 03:43:40 +02:00
void init ( ) ;
2011-01-18 20:56:14 +02:00
CArtifactInstance ( CArtifact * Art ) ;
2010-12-17 20:47:07 +02:00
public :
2011-01-18 20:56:14 +02:00
CArtifactInstance ( ) ;
2013-01-21 21:27:00 +03:00
ConstTransitivePtr < CArtifact > artType ;
2013-02-14 02:55:42 +03:00
ArtifactInstanceID id ;
2010-12-17 20:47:07 +02:00
2011-01-18 20:56:14 +02:00
//CArtifactInstance(int aid);
2010-12-17 20:47:07 +02:00
2013-03-12 17:56:23 +03:00
std : : string nodeName ( ) const override ;
2011-02-04 16:58:14 +02:00
void deserializationFix ( ) ;
2010-12-17 20:47:07 +02:00
void setType ( CArtifact * Art ) ;
2016-01-21 19:23:45 +02:00
std : : string getEffectiveDescription ( const CGHeroInstance * hero = nullptr ) const ;
2013-02-12 22:49:40 +03:00
ArtifactPosition firstAvailableSlot ( const CArtifactSet * h ) const ;
ArtifactPosition firstBackpackSlot ( const CArtifactSet * h ) const ;
2013-02-13 01:24:48 +03:00
SpellID getGivenSpellID ( ) const ; //to be used with scrolls (and similar arts), -1 if none
2010-12-29 23:04:22 +02:00
2013-02-12 22:49:40 +03:00
virtual bool canBePutAt ( const CArtifactSet * artSet , ArtifactPosition slot , bool assumeDestRemoved = false ) const ;
2013-11-07 15:48:41 +03:00
bool canBePutAt ( const ArtifactLocation & al , bool assumeDestRemoved = false ) const ; //forwards to the above one
2010-12-29 23:04:22 +02:00
virtual bool canBeDisassembled ( ) const ;
2012-04-14 19:28:36 +03:00
virtual void putAt ( ArtifactLocation al ) ;
virtual void removeFrom ( ArtifactLocation al ) ;
2016-01-22 11:53:01 +02:00
/// Checks if this a part of this artifact: artifact instance is a part
/// of itself, additionally truth is returned for constituents of combined arts
virtual bool isPart ( const CArtifactInstance * supposedPart ) const ;
2010-12-26 16:34:11 +02:00
2012-04-14 05:20:22 +03:00
std : : vector < const CArtifact * > assemblyPossibilities ( const CArtifactSet * h ) const ;
2012-04-14 19:28:36 +03:00
void move ( ArtifactLocation src , ArtifactLocation dst ) ;
2010-12-26 16:34:11 +02:00
2010-12-17 20:47:07 +02:00
template < typename Handler > void serialize ( Handler & h , const int version )
{
h & static_cast < CBonusSystemNode & > ( * this ) ;
2017-07-31 15:35:42 +02:00
h & artType ;
h & id ;
2011-02-22 11:47:25 +02:00
BONUS_TREE_DESERIALIZATION_FIX
2010-12-17 20:47:07 +02:00
}
static CArtifactInstance * createScroll ( const CSpell * s ) ;
2016-01-21 19:23:45 +02:00
static CArtifactInstance * createScroll ( SpellID sid ) ;
2011-01-18 20:56:14 +02:00
static CArtifactInstance * createNewArtifactInstance ( CArtifact * Art ) ;
static CArtifactInstance * createNewArtifactInstance ( int aid ) ;
2016-02-13 18:43:05 +02:00
/**
* Creates an artifact instance .
*
* @ param aid the id of the artifact
* @ param spellID optional . the id of a spell if a spell scroll object should be created
* @ return the created artifact instance
*/
static CArtifactInstance * createArtifact ( CMap * map , int aid , int spellID = - 1 ) ;
2010-12-17 20:47:07 +02:00
} ;
2011-12-14 00:23:17 +03:00
class DLL_LINKAGE CCombinedArtifactInstance : public CArtifactInstance
2010-12-25 03:43:40 +02:00
{
2011-01-18 20:56:14 +02:00
CCombinedArtifactInstance ( CArtifact * Art ) ;
2010-12-25 03:43:40 +02:00
public :
2011-01-18 20:56:14 +02:00
struct ConstituentInfo
{
ConstTransitivePtr < CArtifactInstance > art ;
2013-02-12 22:49:40 +03:00
ArtifactPosition slot ;
2011-01-18 20:56:14 +02:00
template < typename Handler > void serialize ( Handler & h , const int version )
{
2017-07-31 15:35:42 +02:00
h & art ;
h & slot ;
2011-01-18 20:56:14 +02:00
}
2011-07-03 04:03:46 +03:00
bool operator = = ( const ConstituentInfo & rhs ) const ;
2013-06-26 14:18:27 +03:00
ConstituentInfo ( CArtifactInstance * art = nullptr , ArtifactPosition slot = ArtifactPosition : : PRE_FIRST ) ;
2011-01-18 20:56:14 +02:00
} ;
std : : vector < ConstituentInfo > constituentsInfo ;
2013-03-12 17:56:23 +03:00
bool canBePutAt ( const CArtifactSet * artSet , ArtifactPosition slot , bool assumeDestRemoved = false ) const override ;
bool canBeDisassembled ( ) const override ;
void putAt ( ArtifactLocation al ) override ;
void removeFrom ( ArtifactLocation al ) override ;
bool isPart ( const CArtifactInstance * supposedPart ) const override ;
2011-01-18 20:56:14 +02:00
void createConstituents ( ) ;
2013-02-12 22:49:40 +03:00
void addAsConstituent ( CArtifactInstance * art , ArtifactPosition slot ) ;
2016-01-22 11:53:01 +02:00
CArtifactInstance * figureMainConstituent ( const ArtifactLocation al ) ; //main constituent is replaced with us (combined art), not lock
2011-01-22 05:43:20 +02:00
CCombinedArtifactInstance ( ) ;
2011-01-18 20:56:14 +02:00
2011-02-04 16:58:14 +02:00
void deserializationFix ( ) ;
2011-01-18 20:56:14 +02:00
friend class CArtifactInstance ;
2011-05-04 05:38:58 +03:00
friend struct AssembledArtifact ;
2011-01-18 20:56:14 +02:00
template < typename Handler > void serialize ( Handler & h , const int version )
{
h & static_cast < CArtifactInstance & > ( * this ) ;
h & constituentsInfo ;
2011-02-22 11:47:25 +02:00
BONUS_TREE_DESERIALIZATION_FIX
2011-01-18 20:56:14 +02:00
}
2010-12-25 03:43:40 +02:00
} ;
2013-04-21 15:49:26 +03:00
class DLL_LINKAGE CArtHandler : public IHandlerBase //handles artifacts
2010-07-29 20:00:34 +03:00
{
public :
2013-02-13 01:24:48 +03:00
std : : vector < CArtifact * > treasures , minors , majors , relics ; //tmp vectors!!! do not touch if you don't know what you are doing!!!
2010-12-17 20:47:07 +02:00
std : : vector < ConstTransitivePtr < CArtifact > > artifacts ;
2010-07-29 20:00:34 +03:00
std : : vector < CArtifact * > allowedArtifacts ;
2013-02-11 02:24:57 +03:00
std : : set < ArtifactID > growingArtifacts ;
2010-07-29 20:00:34 +03:00
2013-03-02 19:55:51 +03:00
void addBonuses ( CArtifact * art , const JsonNode & bonusList ) ;
2013-02-19 01:37:22 +03:00
void fillList ( std : : vector < CArtifact * > & listToBeFilled , CArtifact : : EartClass artifactClass ) ; //fills given empty list with allowed artifacts of gibven class. No side effects
boost : : optional < std : : vector < CArtifact * > & > listFromClass ( CArtifact : : EartClass artifactClass ) ;
2014-03-17 22:51:07 +03:00
2014-06-22 13:39:40 +03:00
ArtifactPosition stringToSlot ( std : : string slotName ) ;
CArtifact : : EartClass stringToClass ( std : : string className ) ;
2014-03-17 22:51:07 +03:00
/// Gets a artifact ID randomly and removes the selected artifact from this handler.
ArtifactID pickRandomArtifact ( CRandomGenerator & rand , int flags ) ;
2014-06-22 13:39:40 +03:00
ArtifactID pickRandomArtifact ( CRandomGenerator & rand , std : : function < bool ( ArtifactID ) > accepts ) ;
ArtifactID pickRandomArtifact ( CRandomGenerator & rand , int flags , std : : function < bool ( ArtifactID ) > accepts ) ;
2013-02-13 01:24:48 +03:00
bool legalArtifact ( ArtifactID id ) ;
2013-02-05 00:58:42 +03:00
void initAllowedArtifactsList ( const std : : vector < bool > & allowed ) ; //allowed[art_id] -> 0 if not allowed, 1 if allowed
2012-12-27 14:00:28 +03:00
void makeItCreatureArt ( CArtifact * a , bool onlyCreature = true ) ;
2013-02-13 01:24:48 +03:00
void makeItCreatureArt ( ArtifactID aid , bool onlyCreature = true ) ;
2012-12-27 14:00:28 +03:00
void makeItCommanderArt ( CArtifact * a , bool onlyCommander = true ) ;
2013-02-13 01:24:48 +03:00
void makeItCommanderArt ( ArtifactID aid , bool onlyCommander = true ) ;
2013-04-21 15:49:26 +03:00
2010-07-29 20:00:34 +03:00
CArtHandler ( ) ;
~ CArtHandler ( ) ;
2013-04-21 15:49:26 +03:00
std : : vector < JsonNode > loadLegacyData ( size_t dataSize ) override ;
void loadObject ( std : : string scope , std : : string name , const JsonNode & data ) override ;
void loadObject ( std : : string scope , std : : string name , const JsonNode & data , size_t index ) override ;
2013-07-21 17:19:29 +03:00
void afterLoadFinalization ( ) override ;
2013-04-21 15:49:26 +03:00
std : : vector < bool > getDefaultAllowed ( ) const override ;
2013-01-06 22:30:12 +03:00
2016-02-21 19:58:09 +02:00
///json serialization helper
static si32 decodeArfifact ( const std : : string & identifier ) ;
///json serialization helper
static std : : string encodeArtifact ( const si32 index ) ;
2010-07-29 20:00:34 +03:00
template < typename Handler > void serialize ( Handler & h , const int version )
{
2017-07-31 15:35:42 +02:00
h & artifacts ;
h & allowedArtifacts ;
h & treasures ;
h & minors ;
h & majors ;
h & relics ;
h & growingArtifacts ;
2010-07-29 20:00:34 +03:00
}
2014-03-17 22:51:07 +03:00
private :
2015-08-24 10:55:45 +02:00
CArtifact * loadFromJson ( const JsonNode & node , const std : : string & identifier ) ;
2014-03-17 22:51:07 +03:00
void addSlot ( CArtifact * art , const std : : string & slotID ) ;
void loadSlots ( CArtifact * art , const JsonNode & node ) ;
void loadClass ( CArtifact * art , const JsonNode & node ) ;
void loadType ( CArtifact * art , const JsonNode & node ) ;
void loadComponents ( CArtifact * art , const JsonNode & node ) ;
void loadGrowingArt ( CGrowingArtifact * art , const JsonNode & node ) ;
2015-12-29 04:43:33 +02:00
void giveArtBonus ( ArtifactID aid , Bonus : : BonusType type , int val , int subtype = - 1 , Bonus : : ValueType valType = Bonus : : BASE_NUMBER , std : : shared_ptr < ILimiter > limiter = std : : shared_ptr < ILimiter > ( ) , int additionalinfo = 0 ) ;
void giveArtBonus ( ArtifactID aid , Bonus : : BonusType type , int val , int subtype , std : : shared_ptr < IPropagator > propagator , int additionalinfo = 0 ) ;
2016-09-19 23:36:35 +02:00
void giveArtBonus ( ArtifactID aid , std : : shared_ptr < Bonus > bonus ) ;
2014-03-17 22:51:07 +03:00
void erasePickedArt ( ArtifactID id ) ;
2010-07-29 20:00:34 +03:00
} ;
2011-12-14 00:23:17 +03:00
struct DLL_LINKAGE ArtSlotInfo
2011-06-24 20:43:02 +03:00
{
ConstTransitivePtr < CArtifactInstance > artifact ;
ui8 locked ; //if locked, then artifact points to the combined artifact
2016-01-22 11:53:01 +02:00
ArtSlotInfo ( ) : locked ( false ) { }
2011-06-24 20:43:02 +03:00
template < typename Handler > void serialize ( Handler & h , const int version )
{
2017-07-31 15:35:42 +02:00
h & artifact ;
h & locked ;
2011-06-24 20:43:02 +03:00
}
} ;
2012-04-14 05:20:22 +03:00
class DLL_LINKAGE CArtifactSet
2014-03-17 22:51:07 +03:00
{
public :
std : : vector < ArtSlotInfo > artifactsInBackpack ; //hero's artifacts from bag
std : : map < ArtifactPosition , ArtSlotInfo > artifactsWorn ; //map<position,artifact_id>; positions: 0 - head; 1 - shoulders; 2 - neck; 3 - right hand; 4 - left hand; 5 - torso; 6 - right ring; 7 - left ring; 8 - feet; 9 - misc1; 10 - misc2; 11 - misc3; 12 - misc4; 13 - mach1; 14 - mach2; 15 - mach3; 16 - mach4; 17 - spellbook; 18 - misc5
ArtSlotInfo & retreiveNewArtSlot ( ArtifactPosition slot ) ;
void setNewArtSlot ( ArtifactPosition slot , CArtifactInstance * art , bool locked ) ;
2013-02-12 22:49:40 +03:00
void eraseArtSlot ( ArtifactPosition slot ) ;
2011-06-24 20:43:02 +03:00
2013-02-12 22:49:40 +03:00
const ArtSlotInfo * getSlot ( ArtifactPosition pos ) const ;
2013-06-26 14:18:27 +03:00
const CArtifactInstance * getArt ( ArtifactPosition pos , bool excludeLocked = true ) const ; //nullptr - no artifact
CArtifactInstance * getArt ( ArtifactPosition pos , bool excludeLocked = true ) ; //nullptr - no artifact
2016-01-22 11:53:01 +02:00
/// Looks for equipped artifact with given ID and returns its slot ID or -1 if none
/// (if more than one such artifact lower ID is returned)
ArtifactPosition getArtPos ( int aid , bool onlyWorn = true ) const ;
2013-02-12 22:49:40 +03:00
ArtifactPosition getArtPos ( const CArtifactInstance * art ) const ;
2013-02-14 02:55:42 +03:00
const CArtifactInstance * getArtByInstanceId ( ArtifactInstanceID artInstId ) const ;
2016-01-22 11:53:01 +02:00
/// Search for constituents of assemblies in backpack which do not have an ArtifactPosition
const CArtifactInstance * getHiddenArt ( int aid ) const ;
const CCombinedArtifactInstance * getAssemblyByConstituent ( int aid ) const ;
/// Checks if hero possess artifact of given id (either in backack or worn)
bool hasArt ( ui32 aid , bool onlyWorn = false , bool searchBackpackAssemblies = false ) const ;
2013-02-12 22:49:40 +03:00
bool isPositionFree ( ArtifactPosition pos , bool onlyLockCheck = false ) const ;
2011-06-24 20:43:02 +03:00
2013-02-07 20:34:50 +03:00
virtual ArtBearer : : ArtBearer bearerType ( ) const = 0 ;
2016-11-13 12:38:42 +02:00
virtual void putArtifact ( ArtifactPosition pos , CArtifactInstance * art ) = 0 ;
virtual ~ CArtifactSet ( ) ;
2011-06-24 20:43:02 +03:00
template < typename Handler > void serialize ( Handler & h , const int version )
{
2017-07-31 15:35:42 +02:00
h & artifactsInBackpack ;
h & artifactsWorn ;
2011-06-24 20:43:02 +03:00
}
2013-01-21 21:27:00 +03:00
2012-04-14 05:20:22 +03:00
void artDeserializationFix ( CBonusSystemNode * node ) ;
2016-01-24 01:27:14 +02:00
2016-11-13 12:38:42 +02:00
void serializeJsonArtifacts ( JsonSerializeFormat & handler , const std : : string & fieldName , CMap * map ) ;
2016-01-24 01:27:14 +02:00
protected :
2016-01-24 14:39:41 +02:00
2016-11-13 12:38:42 +02:00
2016-01-22 11:53:01 +02:00
std : : pair < const CCombinedArtifactInstance * , const CArtifactInstance * > searchForConstituent ( int aid ) const ;
2016-11-13 12:38:42 +02:00
private :
void serializeJsonHero ( JsonSerializeFormat & handler , CMap * map ) ;
void serializeJsonCreature ( JsonSerializeFormat & handler , CMap * map ) ;
void serializeJsonCommander ( JsonSerializeFormat & handler , CMap * map ) ;
void serializeJsonSlot ( JsonSerializeFormat & handler , const ArtifactPosition & slot , CMap * map ) ; //normal slots
2011-08-13 13:54:23 +03:00
} ;