2011-12-14 00:23:17 +03:00
# pragma once
2009-04-16 14:14:13 +03:00
2010-05-02 21:20:26 +03:00
# include "../lib/HeroBonus.h"
2010-12-17 20:47:07 +02:00
# include "../lib/ConstTransitivePtr.h"
2011-07-05 09:14:07 +03:00
# include "ResourceSet.h"
2011-12-14 00:23:17 +03:00
# include "GameConstants.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
*/
2010-08-29 10:49:04 +03:00
# define ALLCREATURESGETDOUBLEMONTHS false
2009-04-16 14:14:13 +03:00
class CLodHandler ;
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 :
std : : string namePl , nameSing , nameRef ; //name in singular and plural form; and reference name
2011-07-05 09:14:07 +03:00
TResources cost ; //cost[res_id] - amount of that resource
2009-04-16 14:14:13 +03:00
std : : set < ui32 > upgrades ; // IDs of creatures to which this creature can be upgraded
2010-05-12 05:32:56 +03:00
ui32 hitPoints , speed , attack , defence ;
2010-05-02 21:20:26 +03:00
ui32 fightValue , AIValue , growth , hordeGrowth , shots , spells ;
2009-04-16 14:14:13 +03:00
ui32 damageMin , damageMax ;
ui32 ammMin , ammMax ;
ui8 level ; // 0 - unknown
std : : string abilityText ; //description of abilities
2011-05-10 01:20:47 +03:00
std : : string abilityRefs ; //references to abilities, in text format
2009-04-16 14:14:13 +03:00
std : : string animDefName ;
2010-06-26 19:02:10 +03:00
si32 idNumber ;
2009-04-16 14:14:13 +03:00
si8 faction ; //-1 = neutral
2010-05-02 21:20:26 +03:00
ui8 doubleWide ;
2009-04-16 14:14:13 +03:00
///animation info
2011-12-14 00:23:17 +03:00
double timeBetweenFidgets , walkAnimationTime , attackAnimationTime , flightAnimationDistance ;
2009-04-16 14:14:13 +03:00
int upperRightMissleOffsetX , rightMissleOffsetX , lowerRightMissleOffsetX , upperRightMissleOffsetY , rightMissleOffsetY , lowerRightMissleOffsetY ;
2011-12-14 00:23:17 +03:00
double missleFrameAngles [ 12 ] ;
2009-04-16 14:14:13 +03:00
int troopCountLocationOffset , attackClimaxFrame ;
///end of anim info
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 ;
2010-05-02 21:20:26 +03:00
void addBonus ( int val , int type , int subtype = - 1 ) ;
2010-12-29 23:04:22 +02:00
std : : string nodeName ( ) const OVERRIDE ;
2010-11-13 22:26:15 +02:00
//void getParents(TCNodes &out, const CBonusSystemNode *root /*= NULL*/) const;
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
& cost & upgrades
& fightValue & AIValue & growth & hordeGrowth & hitPoints & speed & attack & defence & shots & spells
& damageMin & damageMax & ammMin & ammMax & level
& abilityText & abilityRefs & animDefName
2010-05-02 21:20:26 +03:00
& idNumber & faction
2009-04-16 14:14:13 +03:00
& timeBetweenFidgets & walkAnimationTime & attackAnimationTime & flightAnimationDistance
& upperRightMissleOffsetX & rightMissleOffsetX & lowerRightMissleOffsetX & upperRightMissleOffsetY & rightMissleOffsetY & lowerRightMissleOffsetY
& missleFrameAngles & troopCountLocationOffset & attackClimaxFrame ;
2009-11-13 21:04:36 +02:00
2010-06-01 22:02:40 +03:00
h & doubleWide ;
2009-04-16 14:14:13 +03:00
}
2010-05-02 21:20:26 +03:00
CCreature ( ) ;
2010-05-12 05:32:56 +03:00
friend class CCreatureHandler ;
2009-04-16 14:14:13 +03:00
} ;
2011-12-14 00:23:17 +03:00
class DLL_LINKAGE CCreatureHandler
2011-02-11 10:20:26 +02: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
2009-04-16 14:14:13 +03:00
public :
std : : set < int > notUsedMonsters ;
2010-08-29 10:49:04 +03:00
std : : set < TCreature > doubledCreatures ; //they get double week
2010-12-17 20:47:07 +02:00
std : : vector < ConstTransitivePtr < CCreature > > creatures ; //creature ID -> creature info
bmap < std : : string , int > nameToID ;
bmap < int , std : : string > idToProjectile ;
bmap < int , bool > idToProjectileSpin ; //if true, appropriate projectile is spinning during flight
2009-09-05 17:10:26 +03:00
std : : vector < si8 > factionAlignments ; //1 for good, 0 for neutral and -1 for evil with faction ID as index
2011-12-14 00:23:17 +03:00
int factionToTurretCreature [ GameConstants : : F_NUMBER ] ; //which creature's animation should be used to dispaly creature in turret while siege
2009-08-24 20:40:20 +03:00
2012-04-04 20:41:55 +03:00
//stack exp
2011-02-06 10:32:05 +02:00
std : : map < TBonusType , std : : pair < std : : string , std : : string > > stackBonuses ; // bonus => name, description
2011-02-20 11:24:53 +02:00
std : : vector < std : : vector < ui32 > > expRanks ; // stack experience needed for certain rank, index 0 for other tiers (?)
2011-02-12 20:48:11 +02:00
std : : vector < ui32 > maxExpPerBattle ; //%, tiers same as above
2011-02-12 18:21:48 +02:00
si8 expAfterUpgrade ; //multiplier in %
2011-02-02 20:49:48 +02:00
2012-04-04 20:41:55 +03:00
//Commanders
std : : map < ui8 , ui32 > factionCommanders ;
std : : vector < std : : vector < ui8 > > skillLevels ; //how much of a bonus will be given to commander with every level. We assume that number of casts equals skill level
std : : vector < std : : pair < Bonus , std : : pair < ui8 , ui8 > > > skillRequirements ; // first - Bonus, second - which two skills are needed to use it
BonusList commanderLevelPremy ; //bonus values added with each level-up
2011-02-22 11:47:25 +02:00
void deserializationFix ( ) ;
2009-04-16 14:14:13 +03:00
void loadCreatures ( ) ;
2011-02-22 11:47:25 +02:00
void buildBonusTreeForTiers ( ) ;
2009-04-16 14:14:13 +03:00
void loadAnimationInfo ( ) ;
void loadUnitAnimInfo ( CCreature & unit , std : : string & src , int & i ) ;
2011-02-11 10:20:26 +02:00
void loadStackExp ( Bonus & b , BonusList & bl , std : : string & src , int & it ) ;
2011-02-09 16:58:15 +02:00
int stringToNumber ( std : : string & s ) ; //help function for parsing CREXPBON.txt
2009-08-24 20:40:20 +03:00
bool isGood ( si8 faction ) const ;
bool isEvil ( si8 faction ) const ;
2011-02-10 15:12:53 +02:00
int pickRandomMonster ( const boost : : function < int ( ) > & randGen = 0 , int tier = - 1 ) const ; //tier <1 - CREATURES_PER_TOWN> or -1 for any
void addBonusForTier ( int tier , Bonus * b ) ; //tier must be <1-7>
void addBonusForAllCreatures ( Bonus * b ) ;
2010-07-24 00:05:49 +03:00
2009-04-16 14:14:13 +03:00
CCreatureHandler ( ) ;
~ CCreatureHandler ( ) ;
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)
2009-09-05 17:10:26 +03:00
h & notUsedMonsters & creatures & nameToID & idToProjectile & idToProjectileSpin & factionToTurretCreature ;
2011-02-22 11:47:25 +02:00
h & stackBonuses & expRanks & maxExpPerBattle & expAfterUpgrade ;
2012-04-04 20:41:55 +03:00
h & factionCommanders & 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
}
} ;