2023-10-19 16:19:09 +02:00
/*
* Bonus . 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 "BonusEnum.h"
2023-10-22 17:36:41 +02:00
# include "BonusCustomTypes.h"
# include "../constants/VariantIdentifier.h"
# include "../constants/EntityIdentifiers.h"
2024-05-07 21:17:05 +02:00
# include "../serializer/Serializeable.h"
2024-07-20 14:55:17 +02:00
# include "../texts/MetaString.h"
2023-10-19 16:19:09 +02:00
VCMI_LIB_NAMESPACE_BEGIN
struct Bonus ;
class IBonusBearer ;
class CBonusSystemNode ;
class ILimiter ;
class IPropagator ;
class IUpdater ;
class BonusList ;
class CSelector ;
2023-10-22 17:36:41 +02:00
using BonusSubtypeID = VariantIdentifier < BonusCustomSubtype , SpellID , CreatureID , PrimarySkill , TerrainId , GameResID , SpellSchool > ;
using BonusSourceID = VariantIdentifier < BonusCustomSource , SpellID , CreatureID , ArtifactID , CampaignScenarioID , SecondarySkill , HeroTypeID , Obj , ObjectInstanceID , BuildingTypeUniqueID , BattleField > ;
2023-10-19 16:19:09 +02:00
using TBonusListPtr = std : : shared_ptr < BonusList > ;
using TConstBonusListPtr = std : : shared_ptr < const BonusList > ;
using TLimiterPtr = std : : shared_ptr < ILimiter > ;
using TPropagatorPtr = std : : shared_ptr < IPropagator > ;
using TUpdaterPtr = std : : shared_ptr < IUpdater > ;
class DLL_LINKAGE CAddInfo : public std : : vector < si32 >
{
public :
enum { NONE = - 1 } ;
CAddInfo ( ) ;
CAddInfo ( si32 value ) ;
bool operator = = ( si32 value ) const ;
bool operator ! = ( si32 value ) const ;
si32 & operator [ ] ( size_type pos ) ;
si32 operator [ ] ( size_type pos ) const ;
std : : string toString ( ) const ;
JsonNode toJsonNode ( ) const ;
} ;
2024-07-27 18:51:23 +02:00
# define BONUS_TREE_DESERIALIZATION_FIX if(!h.saving && h.loadingGamestate) deserializationFix();
2023-10-19 16:19:09 +02:00
/// Struct for handling bonuses of several types. Can be transferred to any hero
2024-05-07 21:17:05 +02:00
struct DLL_LINKAGE Bonus : public std : : enable_shared_from_this < Bonus > , public Serializeable
2023-10-19 16:19:09 +02:00
{
2024-07-14 16:56:58 +02:00
BonusDuration : : Type duration = BonusDuration : : PERMANENT ; //uses BonusDuration values - 2 bytes
2023-10-19 16:19:09 +02:00
si16 turnsRemain = 0 ; //used if duration is N_TURNS, N_DAYS or ONE_WEEK
2024-07-14 16:56:58 +02:00
si32 val = 0 ;
2023-10-19 16:19:09 +02:00
2024-07-14 16:56:58 +02:00
BonusValueType valType = BonusValueType : : ADDITIVE_VALUE ; // 1 byte
BonusSource source = BonusSource : : OTHER ; //source type" uses BonusSource values - what gave that bonus - 1 byte
BonusSource targetSourceType = BonusSource : : OTHER ; //Bonuses of what origin this amplifies, uses BonusSource values. Needed for PERCENT_TO_TARGET_TYPE. - 1 byte
2023-10-19 16:19:09 +02:00
BonusType type = BonusType : : NONE ; //uses BonusType values - says to what is this bonus - 1 byte
2024-07-14 16:56:58 +02:00
BonusLimitEffect effectRange = BonusLimitEffect : : NO_LIMIT ; // 1 byte
// 3 bytes padding
2023-10-19 16:19:09 +02:00
2024-07-14 16:56:58 +02:00
BonusSubtypeID subtype ;
2023-10-22 17:36:41 +02:00
BonusSourceID sid ; //source id: id of object/artifact/spell
2023-10-19 16:19:09 +02:00
std : : string stacking ; // bonuses with the same stacking value don't stack (e.g. Angel/Archangel morale bonus)
CAddInfo additionalInfo ;
TLimiterPtr limiter ;
TPropagatorPtr propagator ;
TUpdaterPtr updater ;
TUpdaterPtr propagationUpdater ;
2024-04-07 18:57:49 +02:00
MetaString description ;
2023-10-19 16:19:09 +02:00
2023-10-22 17:36:41 +02:00
Bonus ( BonusDuration : : Type Duration , BonusType Type , BonusSource Src , si32 Val , BonusSourceID sourceID ) ;
Bonus ( BonusDuration : : Type Duration , BonusType Type , BonusSource Src , si32 Val , BonusSourceID sourceID , BonusSubtypeID subtype ) ;
Bonus ( BonusDuration : : Type Duration , BonusType Type , BonusSource Src , si32 Val , BonusSourceID sourceID , BonusSubtypeID subtype , BonusValueType ValType ) ;
2023-10-19 16:19:09 +02:00
Bonus ( ) = default ;
2024-01-20 20:34:51 +02:00
template < typename Handler > void serialize ( Handler & h )
2023-10-19 16:19:09 +02:00
{
h & duration ;
h & type ;
h & subtype ;
h & source ;
h & val ;
h & sid ;
2024-04-09 15:42:20 +02:00
if ( h . version < Handler : : Version : : BONUS_META_STRING )
{
std : : string oldDescription ;
h & oldDescription ;
description = MetaString : : createFromRawString ( oldDescription ) ;
}
else
h & description ;
2023-10-19 16:19:09 +02:00
h & additionalInfo ;
h & turnsRemain ;
h & valType ;
h & stacking ;
h & effectRange ;
h & limiter ;
h & propagator ;
h & updater ;
h & propagationUpdater ;
h & targetSourceType ;
2024-03-23 23:03:06 +02:00
if ( h . version < Handler : : Version : : MANA_LIMIT & & type = = BonusType : : MANA_PER_KNOWLEDGE_PERCENTAGE )
{
if ( valType = = BonusValueType : : ADDITIVE_VALUE | | valType = = BonusValueType : : BASE_NUMBER )
val * = 100 ;
}
2023-10-19 16:19:09 +02:00
}
template < typename Ptr >
static bool compareByAdditionalInfo ( const Ptr & a , const Ptr & b )
{
return a - > additionalInfo < b - > additionalInfo ;
}
static bool NDays ( const Bonus * hb )
{
auto set = hb - > duration & BonusDuration : : N_DAYS ;
2024-07-14 16:56:58 +02:00
return set ! = 0 ;
2023-10-19 16:19:09 +02:00
}
static bool NTurns ( const Bonus * hb )
{
auto set = hb - > duration & BonusDuration : : N_TURNS ;
2024-07-14 16:56:58 +02:00
return set ! = 0 ;
2023-10-19 16:19:09 +02:00
}
static bool OneDay ( const Bonus * hb )
{
auto set = hb - > duration & BonusDuration : : ONE_DAY ;
2024-07-14 16:56:58 +02:00
return set ! = 0 ;
2023-10-19 16:19:09 +02:00
}
static bool OneWeek ( const Bonus * hb )
{
auto set = hb - > duration & BonusDuration : : ONE_WEEK ;
2024-07-14 16:56:58 +02:00
return set ! = 0 ;
2023-10-19 16:19:09 +02:00
}
static bool OneBattle ( const Bonus * hb )
{
auto set = hb - > duration & BonusDuration : : ONE_BATTLE ;
2024-07-14 16:56:58 +02:00
return set ! = 0 ;
2023-10-19 16:19:09 +02:00
}
static bool Permanent ( const Bonus * hb )
{
auto set = hb - > duration & BonusDuration : : PERMANENT ;
2024-07-14 16:56:58 +02:00
return set ! = 0 ;
2023-10-19 16:19:09 +02:00
}
static bool UntilGetsTurn ( const Bonus * hb )
{
auto set = hb - > duration & BonusDuration : : STACK_GETS_TURN ;
2024-07-14 16:56:58 +02:00
return set ! = 0 ;
2023-10-19 16:19:09 +02:00
}
static bool UntilAttack ( const Bonus * hb )
{
auto set = hb - > duration & BonusDuration : : UNTIL_ATTACK ;
2024-07-14 16:56:58 +02:00
return set ! = 0 ;
2023-10-19 16:19:09 +02:00
}
static bool UntilBeingAttacked ( const Bonus * hb )
{
auto set = hb - > duration & BonusDuration : : UNTIL_BEING_ATTACKED ;
2024-07-14 16:56:58 +02:00
return set ! = 0 ;
2023-10-19 16:19:09 +02:00
}
static bool UntilCommanderKilled ( const Bonus * hb )
{
auto set = hb - > duration & BonusDuration : : COMMANDER_KILLED ;
2024-07-14 16:56:58 +02:00
return set ! = 0 ;
2023-10-19 16:19:09 +02:00
}
2023-12-19 20:52:40 +02:00
static bool UntilOwnAttack ( const Bonus * hb )
{
auto set = hb - > duration & BonusDuration : : UNTIL_OWN_ATTACK ;
2024-07-14 16:56:58 +02:00
return set ! = 0 ;
2023-12-19 20:52:40 +02:00
}
2023-10-19 16:19:09 +02:00
inline bool operator = = ( const BonusType & cf ) const
{
return type = = cf ;
}
inline void operator + = ( const ui32 Val ) //no return
{
val + = Val ;
}
std : : string Description ( std : : optional < si32 > customValue = { } ) const ;
JsonNode toJsonNode ( ) const ;
std : : shared_ptr < Bonus > addLimiter ( const TLimiterPtr & Limiter ) ; //returns this for convenient chain-calls
std : : shared_ptr < Bonus > addPropagator ( const TPropagatorPtr & Propagator ) ; //returns this for convenient chain-calls
std : : shared_ptr < Bonus > addUpdater ( const TUpdaterPtr & Updater ) ; //returns this for convenient chain-calls
} ;
DLL_LINKAGE std : : ostream & operator < < ( std : : ostream & out , const Bonus & bonus ) ;
VCMI_LIB_NAMESPACE_END