2009-04-15 17:03:31 +03:00
/*
* CHeroHandler . 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/ConstTransitivePtr.h"
# include "GameConstants.h"
# include "HeroBonus.h"
# include "IHandlerBase.h"
2012-12-16 16:47:53 +03:00
2009-02-09 16:50:32 +02:00
class CHeroClass ;
class CGameInfo ;
class CGHeroInstance ;
2012-04-23 22:56:37 +03:00
struct BattleHex ;
2012-12-14 18:32:53 +03:00
class JsonNode ;
2014-04-10 20:11:09 +03:00
class CRandomGenerator ;
2010-08-17 17:58:13 +03:00
struct SSpecialtyInfo
2010-07-06 10:32:40 +03:00
{ si32 type ;
si32 val ;
si32 subtype ;
si32 additionalinfo ;
2010-12-25 21:23:30 +02:00
template < typename Handler > void serialize ( Handler & h , const int version )
{
2017-07-31 15:35:42 +02:00
h & type ;
h & val ;
h & subtype ;
h & additionalinfo ;
2010-12-25 21:23:30 +02:00
}
2010-07-06 10:32:40 +03:00
} ;
2010-08-17 17:58:13 +03:00
2013-01-19 20:38:37 +03:00
struct SSpecialtyBonus
/// temporary hold
{
ui8 growsWithLevel ;
BonusList bonuses ;
template < typename Handler > void serialize ( Handler & h , const int version )
{
2017-07-31 15:35:42 +02:00
h & growsWithLevel ;
h & bonuses ;
2013-01-19 20:38:37 +03:00
}
} ;
2011-12-14 00:23:17 +03:00
class DLL_LINKAGE CHero
2009-02-09 16:50:32 +02:00
{
public :
2012-12-03 19:00:17 +03:00
struct InitialArmyStack
{
ui32 minAmount ;
ui32 maxAmount ;
2013-02-11 02:24:57 +03:00
CreatureID creature ;
2012-12-03 19:00:17 +03:00
template < typename Handler > void serialize ( Handler & h , const int version )
{
2017-07-31 15:35:42 +02:00
h & minAmount ;
h & maxAmount ;
h & creature ;
2012-12-03 19:00:17 +03:00
}
} ;
2015-08-24 10:55:45 +02:00
std : : string identifier ;
2013-05-19 01:30:48 +03:00
HeroTypeID ID ;
2012-12-16 16:47:53 +03:00
si32 imageIndex ;
2012-12-03 19:00:17 +03:00
2012-12-16 16:47:53 +03:00
std : : vector < InitialArmyStack > initialArmy ;
2012-12-03 19:00:17 +03:00
2009-02-09 16:50:32 +02:00
CHeroClass * heroClass ;
2013-02-12 22:49:40 +03:00
std : : vector < std : : pair < SecondarySkill , ui8 > > secSkillsInit ; //initial secondary skills; first - ID of skill, second - level of skill (1 - basic, 2 - adv., 3 - expert)
2017-09-10 04:10:50 +02:00
std : : vector < SSpecialtyInfo > specDeprecated ;
std : : vector < SSpecialtyBonus > specialtyDeprecated ;
BonusList specialty ;
2013-02-11 02:24:57 +03:00
std : : set < SpellID > spells ;
2013-03-02 19:55:51 +03:00
bool haveSpellBook ;
bool special ; // hero is special and won't be placed in game (unless preset on map), e.g. campaign heroes
2010-08-25 17:57:58 +03:00
ui8 sex ; // default sex: 0=male, 1=female
2009-02-09 16:50:32 +02:00
2012-12-16 16:47:53 +03:00
/// Localized texts
std : : string name ; //name of hero
std : : string biography ;
std : : string specName ;
std : : string specDescr ;
std : : string specTooltip ;
/// Graphics
std : : string iconSpecSmall ;
std : : string iconSpecLarge ;
std : : string portraitSmall ;
std : : string portraitLarge ;
2018-08-27 08:42:36 +02:00
std : : string battleImage ;
2009-07-03 21:40:36 +03:00
2009-02-09 16:50:32 +02:00
template < typename Handler > void serialize ( Handler & h , const int version )
{
2017-07-31 15:35:42 +02:00
h & ID ;
h & imageIndex ;
h & initialArmy ;
h & heroClass ;
h & secSkillsInit ;
2018-02-18 12:32:52 +02:00
if ( version > = 781 )
2017-09-10 06:03:02 +02:00
{
h & specialty ;
}
else
{
h & specDeprecated ;
h & specialtyDeprecated ;
}
2017-07-31 15:35:42 +02:00
h & spells ;
h & haveSpellBook ;
h & sex ;
h & special ;
h & name ;
h & biography ;
h & specName ;
h & specDescr ;
h & specTooltip ;
h & iconSpecSmall ;
h & iconSpecLarge ;
h & portraitSmall ;
h & portraitLarge ;
if ( version > = 759 )
2015-08-24 10:55:45 +02:00
{
h & identifier ;
2016-02-04 11:28:12 +02:00
}
2018-08-27 08:42:36 +02:00
if ( version > = 790 )
{
h & battleImage ;
}
2009-02-09 16:50:32 +02:00
}
} ;
2017-09-10 04:10:50 +02:00
// convert deprecated format
2018-10-30 21:58:22 +02:00
std : : vector < std : : shared_ptr < Bonus > > SpecialtyInfoToBonuses ( const SSpecialtyInfo & spec , int sid = 0 ) ;
std : : vector < std : : shared_ptr < Bonus > > SpecialtyBonusToBonuses ( const SSpecialtyBonus & spec , int sid = 0 ) ;
2017-09-10 04:10:50 +02:00
2011-12-14 00:23:17 +03:00
class DLL_LINKAGE CHeroClass
2009-02-09 16:50:32 +02:00
{
public :
2013-12-13 21:27:54 +03:00
enum EClassAffinity
{
MIGHT ,
MAGIC
} ;
2012-12-14 18:32:53 +03:00
std : : string identifier ;
std : : string name ; // translatable
2013-03-12 17:56:23 +03:00
//double aggression; // not used in vcmi.
2012-12-14 18:32:53 +03:00
TFaction faction ;
ui8 id ;
2013-12-13 21:27:54 +03:00
ui8 affinity ; // affility, using EClassAffinity enum
2012-12-14 18:32:53 +03:00
2013-11-03 15:07:23 +03:00
// default chance for hero of specific class to appear in tavern, if field "tavern" was not set
// resulting chance = sqrt(town.chance * heroClass.chance)
ui32 defaultTavernChance ;
2013-12-13 21:27:54 +03:00
CCreature * commander ;
2012-12-14 18:32:53 +03:00
std : : vector < int > primarySkillInitial ; // initial primary skills
std : : vector < int > primarySkillLowLevel ; // probability (%) of getting point of primary skill when getting level
std : : vector < int > primarySkillHighLevel ; // same for high levels (> 10)
std : : vector < int > secSkillProbability ; //probabilities of gaining secondary skills (out of 112), in id order
2012-10-06 11:47:13 +03:00
std : : map < TFaction , int > selectionProbability ; //probability of selection in towns
2009-02-09 16:50:32 +02:00
2012-12-16 16:47:53 +03:00
std : : string imageBattleMale ;
std : : string imageBattleFemale ;
std : : string imageMapMale ;
std : : string imageMapFemale ;
2014-01-06 20:45:21 +03:00
CHeroClass ( ) ;
2013-09-09 18:23:59 +03:00
bool isMagicHero ( ) const ;
2014-04-10 20:11:09 +03:00
SecondarySkill chooseSecSkill ( const std : : set < SecondarySkill > & possibles , CRandomGenerator & rand ) const ; //picks secondary skill out from given possibilities
2009-02-09 16:50:32 +02:00
template < typename Handler > void serialize ( Handler & h , const int version )
{
2017-07-31 15:35:42 +02:00
h & identifier ;
h & name ;
h & faction ;
h & id ;
h & defaultTavernChance ;
h & primarySkillInitial ;
h & primarySkillLowLevel ;
h & primarySkillHighLevel ;
h & secSkillProbability ;
h & selectionProbability ;
h & affinity ;
h & commander ;
h & imageBattleMale ;
h & imageBattleFemale ;
h & imageMapMale ;
h & imageMapFemale ;
2020-10-19 21:39:57 +02:00
if ( ! h . saving )
{
for ( auto i = 0 ; i < secSkillProbability . size ( ) ; i + + )
if ( secSkillProbability [ i ] < 0 )
secSkillProbability [ i ] = 0 ;
}
2009-02-09 16:50:32 +02:00
}
2012-09-23 21:01:04 +03:00
EAlignment : : EAlignment getAlignment ( ) const ;
2009-02-09 16:50:32 +02:00
} ;
2011-12-14 00:23:17 +03:00
struct DLL_LINKAGE CObstacleInfo
2009-02-09 16:50:32 +02:00
{
2012-04-23 22:56:37 +03:00
si32 ID ;
std : : string defName ;
2013-02-13 01:24:48 +03:00
std : : vector < ETerrainType > allowedTerrains ;
std : : vector < BFieldType > allowedSpecialBfields ;
2012-04-23 22:56:37 +03:00
ui8 isAbsoluteObstacle ; //there may only one such obstacle in battle and its position is always the same
si32 width , height ; //how much space to the right and up is needed to place obstacle (affects only placement algorithm)
std : : vector < si16 > blockedTiles ; //offsets relative to obstacle position (that is its left bottom corner)
2011-12-22 16:05:19 +03:00
std : : vector < BattleHex > getBlocked ( BattleHex hex ) const ; //returns vector of hexes blocked by obstacle when it's placed on hex 'hex'
2012-04-23 22:56:37 +03:00
2013-02-13 01:24:48 +03:00
bool isAppropriate ( ETerrainType terrainType , int specialBattlefield = - 1 ) const ;
2012-04-23 22:56:37 +03:00
2009-02-09 16:50:32 +02:00
template < typename Handler > void serialize ( Handler & h , const int version )
{
2017-07-31 15:35:42 +02:00
h & ID ;
h & defName ;
h & allowedTerrains ;
h & allowedSpecialBfields ;
h & isAbsoluteObstacle ;
h & width ;
h & height ;
h & blockedTiles ;
2009-02-09 16:50:32 +02:00
}
} ;
2013-04-21 15:49:26 +03:00
class DLL_LINKAGE CHeroClassHandler : public IHandlerBase
2012-12-14 18:32:53 +03:00
{
2015-08-24 10:55:45 +02:00
CHeroClass * loadFromJson ( const JsonNode & node , const std : : string & identifier ) ;
2012-12-14 18:32:53 +03:00
public :
std : : vector < ConstTransitivePtr < CHeroClass > > heroClasses ;
2013-04-21 15:49:26 +03:00
std : : vector < JsonNode > loadLegacyData ( size_t dataSize ) override ;
2012-12-14 18:32:53 +03:00
2013-04-21 15:49:26 +03:00
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 ;
2012-12-14 18:32:53 +03:00
2015-10-12 15:47:10 +02:00
void afterLoadFinalization ( ) override ;
2013-11-03 15:07:23 +03:00
2015-10-12 15:47:10 +02:00
std : : vector < bool > getDefaultAllowed ( ) const override ;
2012-12-14 18:32:53 +03:00
~ CHeroClassHandler ( ) ;
template < typename Handler > void serialize ( Handler & h , const int version )
{
h & heroClasses ;
}
} ;
2013-04-21 15:49:26 +03:00
class DLL_LINKAGE CHeroHandler : public IHandlerBase
2009-02-09 16:50:32 +02:00
{
2012-12-15 16:40:22 +03:00
/// expPerLEvel[i] is amount of exp needed to reach level i;
/// consists of 201 values. Any higher levels require experience larger that ui64 can hold
std : : vector < ui64 > expPerLevel ;
2012-12-14 18:32:53 +03:00
2013-03-03 21:00:37 +03:00
/// helpers for loading to avoid huge load functions
void loadHeroArmy ( CHero * hero , const JsonNode & node ) ;
void loadHeroSkills ( CHero * hero , const JsonNode & node ) ;
void loadHeroSpecialty ( CHero * hero , const JsonNode & node ) ;
2013-04-21 15:49:26 +03:00
void loadExperience ( ) ;
void loadBallistics ( ) ;
void loadTerrains ( ) ;
void loadObstacles ( ) ;
/// Load single hero from json
2015-08-24 10:55:45 +02:00
CHero * loadFromJson ( const JsonNode & node , const std : : string & identifier ) ;
2013-04-21 15:49:26 +03:00
2009-02-09 16:50:32 +02:00
public :
2012-12-14 18:32:53 +03:00
CHeroClassHandler classes ;
2012-12-15 11:47:02 +03:00
std : : vector < ConstTransitivePtr < CHero > > heroes ;
2012-09-05 15:49:23 +03:00
2012-12-15 11:47:02 +03:00
//default costs of going through terrains. -1 means terrain is impassable
2012-09-05 15:49:23 +03:00
std : : vector < int > terrCosts ;
2013-02-05 00:58:42 +03:00
2009-02-09 16:50:32 +02:00
struct SBallisticsLevelInfo
{
ui8 keep , tower , gate , wall ; //chance to hit in percent (eg. 87 is 87%)
ui8 shots ; //how many shots we have
ui8 noDmg , oneDmg , twoDmg ; //chances for shot dealing certain dmg in percent (eg. 87 is 87%); must sum to 100
ui8 sum ; //I don't know if it is useful for anything, but it's in config file
template < typename Handler > void serialize ( Handler & h , const int version )
{
2017-07-31 15:35:42 +02:00
h & keep ;
h & tower ;
h & gate ;
h & wall ;
h & shots ;
h & noDmg ;
h & oneDmg ;
h & twoDmg ;
h & sum ;
2009-02-09 16:50:32 +02:00
}
} ;
std : : vector < SBallisticsLevelInfo > ballistics ; //info about ballistics ability per level; [0] - none; [1] - basic; [2] - adv; [3] - expert
std : : map < int , CObstacleInfo > obstacles ; //info about obstacles that may be placed on battlefield
2012-04-23 22:56:37 +03:00
std : : map < int , CObstacleInfo > absoluteObstacles ; //info about obstacles that may be placed on battlefield
2012-05-18 23:50:16 +03:00
2011-12-14 00:23:17 +03:00
ui32 level ( ui64 experience ) const ; //calculates level corresponding to given experience amount
ui64 reqExp ( ui32 level ) const ; //calculates experience required for given level
2009-02-09 16:50:32 +02:00
2013-04-21 15:49:26 +03:00
std : : vector < JsonNode > loadLegacyData ( size_t dataSize ) override ;
2012-12-15 11:47:02 +03:00
2019-01-19 12:52:02 +02:00
void beforeValidate ( JsonNode & object ) override ;
2013-04-21 15:49:26 +03:00
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 ;
2017-09-12 14:59:50 +02:00
void afterLoadFinalization ( ) override ;
2012-12-15 11:47:02 +03:00
2017-07-17 23:04:00 +02:00
CHeroHandler ( ) ;
~ CHeroHandler ( ) ;
2009-02-09 16:50:32 +02:00
2015-10-12 15:47:10 +02:00
std : : vector < bool > getDefaultAllowed ( ) const override ;
2012-11-20 20:53:45 +03:00
2016-02-21 21:13:20 +02:00
///json serialization helper
static si32 decodeHero ( const std : : string & identifier ) ;
///json serialization helper
static std : : string encodeHero ( const si32 index ) ;
2009-02-09 16:50:32 +02:00
template < typename Handler > void serialize ( Handler & h , const int version )
{
2017-07-31 15:35:42 +02:00
h & classes ;
h & heroes ;
h & expPerLevel ;
h & ballistics ;
h & terrCosts ;
h & obstacles ;
h & absoluteObstacles ;
2009-02-09 16:50:32 +02:00
}
} ;