2023-10-19 16:19:09 +02: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
*
*/
# pragma once
# include "bonuses/Bonus.h"
# include "bonuses/CBonusSystemNode.h"
# include "ConstTransitivePtr.h"
# include "ResourceSet.h"
# include "GameConstants.h"
# include "IHandlerBase.h"
# include "Color.h"
# include "filesystem/ResourcePath.h"
# include <vcmi/Creature.h>
# include <vcmi/CreatureService.h>
VCMI_LIB_NAMESPACE_BEGIN
2024-06-01 17:28:17 +02:00
namespace vstd
{
class RNG ;
}
2023-10-19 16:19:09 +02:00
class CLegacyConfigParser ;
class CCreatureHandler ;
class CCreature ;
class JsonSerializeFormat ;
class DLL_LINKAGE CCreature : public Creature , public CBonusSystemNode
{
friend class CCreatureHandler ;
std : : string modScope ;
std : : string identifier ;
std : : string getNameTranslated ( ) const override ;
std : : string getNameTextID ( ) const override ;
CreatureID idNumber ;
FactionID faction = FactionID : : NEUTRAL ;
ui8 level = 0 ; // 0 - unknown; 1-7 for "usual" creatures
//stats that are not handled by bonus system
ui32 fightValue , AIValue , growth , hordeGrowth ;
bool doubleWide = false ;
TResources cost ; //cost[res_id] - amount of that resource required to buy creature from dwelling
public :
2024-04-27 18:41:21 +02:00
std : : string getDescriptionTranslated ( ) const ;
std : : string getDescriptionTextID ( ) const ;
2024-04-12 23:35:39 +02:00
2024-01-10 00:38:54 +02:00
ui32 ammMin ; // initial size of stack of these creatures on adventure map (if not set in editor)
ui32 ammMax ;
2023-10-19 16:19:09 +02:00
bool special = true ; // Creature is not available normally (war machines, commanders, several unused creatures, etc
2024-05-16 11:53:37 +02:00
bool excludeFromRandomization = false ;
2023-10-19 16:19:09 +02:00
std : : set < CreatureID > upgrades ; // IDs of creatures to which this creature can be upgraded
AnimationPath animDefName ; // creature animation used during battles
si32 iconIndex = - 1 ; // index of icon in files like twcrport, used in tests now.
/// names of files with appropriate icons. Used only during loading
std : : string smallIconName ;
std : : string largeIconName ;
enum class CreatureQuantityId
{
FEW = 1 ,
SEVERAL ,
PACK ,
LOTS ,
HORDE ,
THRONG ,
SWARM ,
ZOUNDS ,
LEGION
} ;
struct CreatureAnimation
{
struct RayColor {
ColorRGBA start ;
ColorRGBA end ;
} ;
double timeBetweenFidgets , idleAnimationTime ,
walkAnimationTime , attackAnimationTime ;
2024-06-24 03:23:26 +02:00
int upperRightMissileOffsetX , rightMissileOffsetX , lowerRightMissileOffsetX ,
upperRightMissileOffsetY , rightMissileOffsetY , lowerRightMissileOffsetY ;
2023-10-19 16:19:09 +02:00
2024-06-24 03:23:26 +02:00
std : : vector < double > missileFrameAngles ;
2023-10-19 16:19:09 +02:00
int attackClimaxFrame ;
AnimationPath projectileImageName ;
std : : vector < RayColor > projectileRay ;
2023-11-04 18:54:15 +02:00
2023-10-19 16:19:09 +02:00
} animation ;
//sound info
struct CreatureBattleSounds
{
AudioPath attack ;
AudioPath defend ;
AudioPath killed ; // was killed or died
AudioPath move ;
AudioPath shoot ; // range attack
AudioPath wince ; // attacked but did not die
AudioPath startMoving ;
AudioPath endMoving ;
} sounds ;
ArtifactID warMachine ;
std : : string getNamePluralTranslated ( ) const override ;
std : : string getNameSingularTranslated ( ) const override ;
std : : string getNamePluralTextID ( ) const override ;
std : : string getNameSingularTextID ( ) const override ;
2024-10-05 21:37:52 +02:00
FactionID getFactionID ( ) const override ;
2023-10-19 16:19:09 +02:00
int32_t getIndex ( ) const override ;
int32_t getIconIndex ( ) const override ;
std : : string getJsonKey ( ) const override ;
2024-08-10 16:08:04 +02:00
std : : string getModScope ( ) const override ;
2023-10-19 16:19:09 +02:00
void registerIcons ( const IconRegistar & cb ) const override ;
CreatureID getId ( ) const override ;
2024-02-10 21:22:08 +02:00
const IBonusBearer * getBonusBearer ( ) const override ;
2023-10-19 16:19:09 +02:00
int32_t getAdvMapAmountMin ( ) const override ;
int32_t getAdvMapAmountMax ( ) const override ;
int32_t getAIValue ( ) const override ;
int32_t getFightValue ( ) const override ;
int32_t getLevel ( ) const override ;
int32_t getGrowth ( ) const override ;
int32_t getHorde ( ) const override ;
int32_t getBaseAttack ( ) const override ;
int32_t getBaseDefense ( ) const override ;
int32_t getBaseDamageMin ( ) const override ;
int32_t getBaseDamageMax ( ) const override ;
int32_t getBaseHitPoints ( ) const override ;
int32_t getBaseSpellPoints ( ) const override ;
int32_t getBaseSpeed ( ) const override ;
int32_t getBaseShots ( ) const override ;
int32_t getRecruitCost ( GameResID resIndex ) const override ;
TResources getFullRecruitCost ( ) const override ;
bool isDoubleWide ( ) const override ; //returns true if unit is double wide on battlefield
bool hasUpgrades ( ) const override ;
bool isGood ( ) const ;
bool isEvil ( ) const ;
si32 maxAmount ( const TResources & res ) const ; //how many creatures can be bought
static CCreature : : CreatureQuantityId getQuantityID ( const int & quantity ) ;
static std : : string getQuantityRangeStringForId ( const CCreature : : CreatureQuantityId & quantityId ) ;
static int estimateCreatureCount ( ui32 countID ) ; //reverse version of above function, returns middle of range
bool isMyUpgrade ( const CCreature * anotherCre ) const ;
2023-10-22 17:36:41 +02:00
void addBonus ( int val , BonusType type ) ;
void addBonus ( int val , BonusType type , BonusSubtypeID subtype ) ;
2023-10-19 16:19:09 +02:00
std : : string nodeName ( ) const override ;
template < typename RanGen >
int getRandomAmount ( RanGen ranGen ) const
{
if ( ammMax = = ammMin )
return ammMax ;
else
return ammMin + ( ranGen ( ) % ( ammMax - ammMin ) ) ;
}
void updateFrom ( const JsonNode & data ) ;
void serializeJson ( JsonSerializeFormat & handler ) ;
CCreature ( ) ;
private :
static const std : : map < CreatureQuantityId , std : : string > creatureQuantityRanges ;
} ;
class DLL_LINKAGE CCreatureHandler : public CHandlerBase < CreatureID , Creature , CCreature , CreatureService >
{
private :
void loadJsonAnimation ( CCreature * creature , const JsonNode & graphics ) const ;
void loadStackExperience ( CCreature * creature , const JsonNode & input ) const ;
void loadCreatureJson ( CCreature * creature , const JsonNode & config ) const ;
/// load all creatures from H3 files
void load ( ) ;
void loadCommanders ( ) ;
/// load creature from json structure
void load ( std : : string creatureID , const JsonNode & node ) ;
/// read cranim.txt file from H3
void loadAnimationInfo ( std : : vector < JsonNode > & h3Data ) const ;
/// read one line from cranim.txt
void loadUnitAnimInfo ( JsonNode & unit , CLegacyConfigParser & parser ) const ;
/// parse crexpbon.txt file from H3
void loadStackExp ( Bonus & b , BonusList & bl , CLegacyConfigParser & parser ) const ;
/// help function for parsing CREXPBON.txt
int stringToNumber ( std : : string & s ) const ;
protected :
const std : : vector < std : : string > & getTypeNames ( ) const override ;
2024-05-17 00:05:51 +02:00
std : : shared_ptr < CCreature > loadFromJson ( const std : : string & scope , const JsonNode & node , const std : : string & identifier , size_t index ) override ;
2023-10-19 16:19:09 +02:00
public :
std : : set < CreatureID > doubledCreatures ; //they get double week
//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
std : : vector < std : : pair < std : : shared_ptr < Bonus > , std : : pair < ui8 , ui8 > > > skillRequirements ; // first - Bonus, second - which two skills are needed to use it
2024-06-01 17:28:17 +02:00
CreatureID pickRandomMonster ( vstd : : RNG & rand , int tier = - 1 ) const ; //tier <1 - CREATURES_PER_TOWN> or -1 for any
2023-10-19 16:19:09 +02:00
CCreatureHandler ( ) ;
~ CCreatureHandler ( ) ;
/// load all stack experience bonuses from H3 files
void loadCrExpBon ( CBonusSystemNode & globalEffects ) ;
/// load all stack modifier bonuses from H3 files. TODO: move this to json
void loadCrExpMod ( ) ;
void afterLoadFinalization ( ) override ;
std : : vector < JsonNode > loadLegacyData ( ) override ;
} ;
VCMI_LIB_NAMESPACE_END