2009-04-15 17:03:31 +03:00
/*
* CCreatureHandler . 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
*
2009-04-16 14:14:13 +03:00
*/
2017-07-13 10:26:03 +02:00
# pragma once
# include "HeroBonus.h"
# include "ConstTransitivePtr.h"
# include "ResourceSet.h"
# include "GameConstants.h"
# include "JsonNode.h"
# include "IHandlerBase.h"
# include "CRandomGenerator.h"
2009-04-16 14:14:13 +03:00
2012-08-25 11:44:51 +03:00
class CLegacyConfigParser ;
2010-05-02 21:20:26 +03:00
class CCreatureHandler ;
2010-08-24 17:26:57 +03:00
class CCreature ;
2009-04-16 14:14:13 +03:00
2011-12-14 00:23:17 +03:00
class DLL_LINKAGE CCreature : public CBonusSystemNode
2009-04-16 14:14:13 +03:00
{
public :
2015-08-24 10:55:45 +02:00
std : : string identifier ;
2013-03-02 19:55:51 +03:00
std : : string nameRef ; // reference name, stringID
std : : string nameSing ; // singular name, e.g. Centaur
std : : string namePl ; // plural name, e.g. Centaurs
2009-04-16 14:14:13 +03:00
std : : string abilityText ; //description of abilities
2013-03-02 19:55:51 +03:00
2013-02-11 02:24:57 +03:00
CreatureID idNumber ;
2013-03-02 19:55:51 +03:00
TFaction faction ;
2013-09-06 01:11:13 +03:00
ui8 level ; // 0 - unknown; 1-7 for "usual" creatures
2013-03-02 19:55:51 +03:00
//stats that are not handled by bonus system
ui32 fightValue , AIValue , growth , hordeGrowth ;
ui32 ammMin , ammMax ; // initial size of stack of these creatures on adventure map (if not set in editor)
2013-02-07 20:34:50 +03:00
bool doubleWide ;
2013-03-02 19:55:51 +03:00
bool special ; // Creature is not available normally (war machines, commanders, several unused creatures, etc
TResources cost ; //cost[res_id] - amount of that resource required to buy creature from dwelling
std : : set < CreatureID > upgrades ; // IDs of creatures to which this creature can be upgraded
2009-04-16 14:14:13 +03:00
2013-03-02 19:55:51 +03:00
std : : string animDefName ; // creature animation used during battles
std : : string advMapDef ; //for new creatures only, image for adventure map
si32 iconIndex ; // index of icon in files like twcrport
2013-04-22 22:51:22 +03:00
/// names of files with appropriate icons. Used only during loading
std : : string smallIconName ;
std : : string largeIconName ;
2013-03-02 19:55:51 +03:00
struct CreatureAnimation
{
2013-11-06 16:42:58 +03:00
double timeBetweenFidgets , idleAnimationTime ,
walkAnimationTime , attackAnimationTime , flightAnimationDistance ;
2013-03-02 19:55:51 +03:00
int upperRightMissleOffsetX , rightMissleOffsetX , lowerRightMissleOffsetX ,
upperRightMissleOffsetY , rightMissleOffsetY , lowerRightMissleOffsetY ;
2013-04-04 16:18:38 +03:00
std : : vector < double > missleFrameAngles ;
2013-03-02 19:55:51 +03:00
int troopCountLocationOffset , attackClimaxFrame ;
std : : string projectileImageName ;
2013-04-04 16:18:38 +03:00
//bool projectileSpin; //if true, appropriate projectile is spinning during flight
2013-03-02 19:55:51 +03:00
template < typename Handler > void serialize ( Handler & h , const int version )
{
2017-07-31 15:35:42 +02:00
h & timeBetweenFidgets ;
h & idleAnimationTime ;
h & walkAnimationTime ;
h & attackAnimationTime ;
h & flightAnimationDistance ;
h & upperRightMissleOffsetX ;
h & rightMissleOffsetX ;
h & lowerRightMissleOffsetX ;
h & upperRightMissleOffsetY ;
h & rightMissleOffsetY ;
h & lowerRightMissleOffsetY ;
h & missleFrameAngles ;
h & troopCountLocationOffset ;
h & attackClimaxFrame ;
2013-04-04 16:18:38 +03:00
h & projectileImageName ;
2013-03-02 19:55:51 +03:00
}
} animation ;
2009-04-16 14:14:13 +03:00
2012-09-17 22:00:26 +03:00
//sound info
2013-03-02 19:55:51 +03:00
struct CreatureBattleSounds
2012-09-17 22:00:26 +03:00
{
std : : string attack ;
std : : string defend ;
std : : string killed ; // was killed or died
std : : string move ;
std : : string shoot ; // range attack
std : : string wince ; // attacked but did not die
2013-04-11 22:24:14 +03:00
std : : string startMoving ;
std : : string endMoving ;
2012-09-17 22:00:26 +03:00
template < typename Handler > void serialize ( Handler & h , const int version )
{
2017-07-31 15:35:42 +02:00
h & attack ;
h & defend ;
h & killed ;
h & move ;
h & shoot ;
h & wince ;
h & startMoving ;
h & endMoving ;
2012-09-17 22:00:26 +03:00
}
} sounds ;
2017-05-26 18:51:45 +02:00
ArtifactID warMachine ;
2012-05-18 23:50:16 +03:00
bool isItNativeTerrain ( int terrain ) const ;
2009-04-16 14:14:13 +03:00
bool isDoubleWide ( ) const ; //returns true if unit is double wide on battlefield
bool isFlying ( ) const ; //returns true if it is a flying unit
bool isShooting ( ) const ; //returns true if unit can shoot
2009-04-16 17:01:27 +03:00
bool isUndead ( ) const ; //returns true if unit is undead
2009-08-24 20:40:20 +03:00
bool isGood ( ) const ;
bool isEvil ( ) const ;
2009-04-16 14:14:13 +03:00
si32 maxAmount ( const std : : vector < si32 > & res ) const ; //how many creatures can be bought
2017-07-25 23:00:29 +02:00
static int getQuantityID ( const int & quantity ) ; //1 - a few, 2 - several, 3 - pack, 4 - lots, 5 - horde, 6 - throng, 7 - swarm, 8 - zounds, 9 - legion
2011-12-14 00:23:17 +03:00
static int estimateCreatureCount ( ui32 countID ) ; //reverse version of above function, returns middle of range
2010-07-12 13:20:25 +03:00
bool isMyUpgrade ( const CCreature * anotherCre ) const ;
2009-04-16 14:14:13 +03:00
2010-11-27 22:17:28 +02:00
bool valid ( ) const ;
2013-05-19 22:53:03 +03:00
void setId ( CreatureID ID ) ; //assigns idNumber and updates bonuses to reference it
2013-02-16 17:03:47 +03:00
void addBonus ( int val , Bonus : : BonusType type , int subtype = - 1 ) ;
2012-12-03 19:00:17 +03:00
std : : string nodeName ( ) const override ;
2010-07-12 13:20:25 +03:00
2009-07-09 22:15:22 +03:00
template < typename RanGen >
2011-12-31 13:03:29 +03:00
int getRandomAmount ( RanGen ranGen ) const
2009-07-09 22:15:22 +03:00
{
if ( ammMax = = ammMin )
return ammMax ;
else
return ammMin + ( ranGen ( ) % ( ammMax - ammMin ) ) ;
}
2009-04-16 14:14:13 +03:00
template < typename Handler > void serialize ( Handler & h , const int version )
{
2010-05-02 21:20:26 +03:00
h & static_cast < CBonusSystemNode & > ( * this ) ;
2017-07-31 15:35:42 +02:00
h & namePl ;
h & nameSing ;
h & nameRef ;
h & cost ;
h & upgrades ;
h & fightValue ;
h & AIValue ;
h & growth ;
h & hordeGrowth ;
h & ammMin ;
h & ammMax ;
h & level ;
h & abilityText ;
h & animDefName ;
h & advMapDef ;
h & iconIndex ;
h & smallIconName ;
h & largeIconName ;
h & idNumber ;
h & faction ;
h & sounds ;
h & animation ;
h & doubleWide ;
h & special ;
2016-02-04 11:28:12 +02:00
if ( version > = 759 )
2015-08-24 10:55:45 +02:00
{
h & identifier ;
2016-01-15 19:24:17 +02:00
}
2017-05-26 18:51:45 +02:00
if ( version > = 771 )
{
h & warMachine ;
}
else if ( ! h . saving )
{
fillWarMachine ( ) ;
}
2009-04-16 14:14:13 +03:00
}
2010-05-02 21:20:26 +03:00
CCreature ( ) ;
2017-05-26 18:51:45 +02:00
private :
void fillWarMachine ( ) ;
2009-04-16 14:14:13 +03:00
} ;
2013-04-21 15:49:26 +03:00
class DLL_LINKAGE CCreatureHandler : public IHandlerBase
2011-02-11 10:20:26 +02:00
{
2012-12-23 13:23:41 +03:00
private :
2011-12-14 00:23:17 +03:00
CBonusSystemNode allCreatures ;
CBonusSystemNode creaturesOfLevel [ GameConstants : : CREATURES_PER_TOWN + 1 ] ; //index 0 is used for creatures of unknown tier or outside <1-7> range
2012-12-23 13:23:41 +03:00
2013-04-21 15:49:26 +03:00
/// load one creature from json config
2015-08-24 10:55:45 +02:00
CCreature * loadFromJson ( const JsonNode & node , const std : : string & identifier ) ;
2013-04-21 15:49:26 +03:00
2013-04-11 22:24:14 +03:00
void loadJsonAnimation ( CCreature * creature , const JsonNode & graphics ) ;
2013-03-02 19:55:51 +03:00
void loadStackExperience ( CCreature * creature , const JsonNode & input ) ;
2012-12-23 13:23:41 +03:00
void loadCreatureJson ( CCreature * creature , const JsonNode & config ) ;
2011-02-22 11:47:25 +02:00
2012-11-13 14:52:23 +03:00
/// loading functions
2013-03-02 19:55:51 +03:00
/// adding abilities from ZCRTRAIT.TXT
2013-04-11 22:24:14 +03:00
void loadBonuses ( JsonNode & creature , std : : string bonuses ) ;
2012-11-13 14:52:23 +03:00
/// load all creatures from H3 files
2013-03-06 21:49:56 +03:00
void load ( ) ;
2013-04-11 22:24:14 +03:00
void loadCommanders ( ) ;
2013-03-02 19:55:51 +03:00
/// load creature from json structure
void load ( std : : string creatureID , const JsonNode & node ) ;
2012-11-13 14:52:23 +03:00
/// read cranim.txt file from H3
2013-04-11 22:24:14 +03:00
void loadAnimationInfo ( std : : vector < JsonNode > & h3Data ) ;
2012-11-13 14:52:23 +03:00
/// read one line from cranim.txt
2013-04-11 22:24:14 +03:00
void loadUnitAnimInfo ( JsonNode & unit , CLegacyConfigParser & parser ) ;
2012-11-13 14:52:23 +03:00
/// parse crexpbon.txt file from H3
2012-08-25 11:44:51 +03:00
void loadStackExp ( Bonus & b , BonusList & bl , CLegacyConfigParser & parser ) ;
2012-11-13 14:52:23 +03:00
/// help function for parsing CREXPBON.txt
int stringToNumber ( std : : string & s ) ;
2013-04-21 15:49:26 +03:00
public :
std : : set < CreatureID > doubledCreatures ; //they get double week
std : : vector < ConstTransitivePtr < CCreature > > creatures ; //creature ID -> creature info.
//stack exp
std : : vector < std : : vector < ui32 > > expRanks ; // stack experience needed for certain rank, index 0 for other tiers (?)
std : : vector < ui32 > maxExpPerBattle ; //%, tiers same as above
si8 expAfterUpgrade ; //multiplier in %
//Commanders
BonusList commanderLevelPremy ; //bonus values added with each level-up
std : : vector < std : : vector < ui8 > > skillLevels ; //how much of a bonus will be given to commander with every level. SPELL_POWER also gives CASTS and RESISTANCE
2016-09-19 23:36:35 +02:00
std : : vector < std : : pair < std : : shared_ptr < Bonus > , std : : pair < ui8 , ui8 > > > skillRequirements ; // first - Bonus, second - which two skills are needed to use it
2009-08-24 20:40:20 +03:00
2016-01-15 19:24:17 +02:00
const CCreature * getCreature ( const std : : string & scope , const std : : string & identifier ) const ;
2012-11-13 14:52:23 +03:00
void deserializationFix ( ) ;
2014-03-17 22:51:07 +03:00
CreatureID pickRandomMonster ( CRandomGenerator & rand , int tier = - 1 ) const ; //tier <1 - CREATURES_PER_TOWN> or -1 for any
2016-09-19 23:36:35 +02:00
void addBonusForTier ( int tier , std : : shared_ptr < Bonus > b ) ; //tier must be <1-7>
void addBonusForAllCreatures ( std : : shared_ptr < Bonus > b ) ;
2010-07-24 00:05:49 +03:00
2013-04-21 15:49:26 +03:00
CCreatureHandler ( ) ;
~ CCreatureHandler ( ) ;
/// load all creatures from H3 files
void loadCrExpBon ( ) ;
/// generates tier-specific bonus tree entries
void buildBonusTreeForTiers ( ) ;
2015-10-12 15:47:10 +02:00
void afterLoadFinalization ( ) override ;
2014-01-03 02:48:38 +03:00
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 ;
std : : vector < bool > getDefaultAllowed ( ) const override ;
2009-04-16 14:14:13 +03:00
template < typename Handler > void serialize ( Handler & h , const int version )
{
//TODO: should be optimized, not all these informations needs to be serialized (same for ccreature)
2017-07-31 15:35:42 +02:00
h & doubledCreatures ;
h & creatures ;
h & expRanks ;
h & maxExpPerBattle ;
h & expAfterUpgrade ;
h & skillLevels ;
h & skillRequirements ;
h & commanderLevelPremy ;
2011-02-10 15:12:53 +02:00
h & allCreatures ;
h & creaturesOfLevel ;
2011-02-22 11:47:25 +02:00
BONUS_TREE_DESERIALIZATION_FIX
2009-04-16 14:14:13 +03:00
}
} ;