2011-12-14 00:23:17 +03:00
# pragma once
2009-04-16 14:14:13 +03:00
2012-08-30 17:57:24 +03:00
# include "HeroBonus.h"
# include "ConstTransitivePtr.h"
2011-07-05 09:14:07 +03:00
# include "ResourceSet.h"
2011-12-14 00:23:17 +03:00
# include "GameConstants.h"
2012-08-30 17:57:24 +03:00
# include "JsonNode.h"
2013-04-21 15:49:26 +03:00
# include "IHandlerBase.h"
2014-03-17 22:51:07 +03:00
# include "CRandomGenerator.h"
2009-04-26 02:31:39 +03:00
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
*/
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 )
{
2013-11-06 16:42:58 +03:00
h & timeBetweenFidgets & idleAnimationTime ;
h & walkAnimationTime & attackAnimationTime & flightAnimationDistance ;
2013-03-02 19:55:51 +03:00
h & upperRightMissleOffsetX & rightMissleOffsetX & lowerRightMissleOffsetX ;
h & upperRightMissleOffsetY & rightMissleOffsetY & lowerRightMissleOffsetY ;
h & missleFrameAngles & troopCountLocationOffset & 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 )
{
2013-04-11 22:24:14 +03:00
h & attack & defend & killed & move & shoot & wince & startMoving & endMoving ;
2012-09-17 22:00:26 +03:00
}
} sounds ;
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
static int getQuantityID ( const int & quantity ) ; //0 - a few, 1 - several, 2 - pack, 3 - lots, 4 - horde, 5 - throng, 6 - swarm, 7 - zounds, 8 - 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 ) ;
2009-04-16 14:14:13 +03:00
h & namePl & nameSing & nameRef
2012-12-03 19:00:17 +03:00
& cost & upgrades
2012-08-30 17:57:24 +03:00
& fightValue & AIValue & growth & hordeGrowth
& ammMin & ammMax & level
2013-03-02 19:55:51 +03:00
& abilityText & animDefName & advMapDef ;
2013-04-22 22:51:22 +03:00
h & iconIndex & smallIconName & largeIconName ;
2009-04-16 14:14:13 +03:00
2013-03-02 19:55:51 +03:00
h & idNumber & faction & sounds & animation ;
2009-11-13 21:04:36 +02:00
2013-03-02 19:55:51 +03:00
h & doubleWide & 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
}
2009-04-16 14:14:13 +03:00
}
2010-05-02 21:20:26 +03:00
CCreature ( ) ;
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
2013-06-17 18:45:55 +03:00
std : : vector < std : : pair < 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
2011-02-10 15:12:53 +02:00
void addBonusForTier ( int tier , Bonus * b ) ; //tier must be <1-7>
void addBonusForAllCreatures ( 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)
2013-03-02 19:55:51 +03:00
h & doubledCreatures & creatures ;
2013-03-06 21:49:56 +03:00
h & expRanks & maxExpPerBattle & expAfterUpgrade ;
2012-12-19 19:35:58 +03:00
h & skillLevels & skillRequirements & 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
}
} ;