2011-12-13 21:23:17 +00:00
# pragma once
2010-12-20 21:22:53 +00:00
# include "CCreatureHandler.h"
2009-05-20 10:08:56 +00:00
# include "VCMI_Lib.h"
2010-05-02 18:20:26 +00:00
2010-02-10 02:56:00 +00:00
# include "HeroBonus.h"
2010-05-02 18:20:26 +00:00
# include "CCreatureSet.h"
2010-12-20 13:04:24 +00:00
# include "ConstTransitivePtr.h"
2011-05-09 22:20:47 +00:00
# include "IGameCallback.h"
2011-07-05 06:14:07 +00:00
# include "ResourceSet.h"
2011-12-13 21:23:17 +00:00
# include "int3.h"
2014-03-17 19:51:07 +00:00
# include "CRandomGenerator.h"
2014-06-25 17:11:07 +03:00
# include "CGameStateFwd.h"
2015-10-27 03:34:47 +03:00
# include "CPathfinder.h"
2010-05-02 18:20:26 +00:00
2009-04-15 14:03:31 +00:00
/*
* CGameState . 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
*
*/
2008-12-27 01:01:59 +00:00
class CTown ;
class CCallback ;
2010-06-07 05:28:12 +00:00
class IGameCallback ;
2008-12-27 01:01:59 +00:00
class CCreatureSet ;
class CStack ;
2012-05-16 17:29:05 +00:00
class CQuest ;
2008-12-27 01:01:59 +00:00
class CGHeroInstance ;
class CGTownInstance ;
class CArmedInstance ;
2009-10-24 19:21:32 +00:00
class CGDwelling ;
2008-12-27 01:01:59 +00:00
class CObjectScript ;
class CGObjectInstance ;
class CCreature ;
2012-11-03 19:31:16 +00:00
class CMap ;
2008-12-27 01:01:59 +00:00
struct StartInfo ;
struct SDL_Surface ;
class CMapHandler ;
struct SetObjectProperty ;
struct MetaString ;
2009-03-06 22:25:19 +00:00
struct CPack ;
2009-05-07 15:19:52 +00:00
class CSpell ;
2009-08-30 12:47:40 +00:00
struct TerrainTile ;
2010-02-07 15:06:14 +00:00
class CHeroClass ;
2010-05-08 18:56:38 +00:00
class CCampaign ;
2010-08-04 11:18:13 +00:00
class CCampaignState ;
2010-11-10 00:06:25 +00:00
class IModableArt ;
2011-05-03 03:14:18 +00:00
class CGGarrison ;
2011-12-13 21:23:17 +00:00
class CGameInfo ;
2012-05-16 17:29:05 +00:00
struct QuestInfo ;
2012-07-07 08:45:45 +00:00
class CQuest ;
2013-12-20 13:07:58 +00:00
class CCampaignScenario ;
2013-12-29 15:48:56 +00:00
struct EventCondition ;
2014-01-03 16:36:22 +00:00
class CScenarioTravel ;
2008-12-27 01:01:59 +00:00
namespace boost
{
class shared_mutex ;
}
2011-12-13 21:23:17 +00:00
struct DLL_LINKAGE SThievesGuildInfo
2010-02-01 17:51:33 +00:00
{
2013-03-03 17:06:03 +00:00
std : : vector < PlayerColor > playerColors ; //colors of players that are in-game
2010-02-01 17:51:33 +00:00
2013-03-03 17:06:03 +00:00
std : : vector < std : : vector < PlayerColor > > numOfTowns , numOfHeroes , gold , woodOre , mercSulfCrystGems , obelisks , artifacts , army , income ; // [place] -> [colours of players]
2010-02-01 17:51:33 +00:00
2013-03-03 17:06:03 +00:00
std : : map < PlayerColor , InfoAboutHero > colorToBestHero ; //maps player's color to his best heros'
2010-02-01 17:51:33 +00:00
2013-03-03 17:06:03 +00:00
std : : map < PlayerColor , EAiTactic : : EAiTactic > personality ; // color to personality // ai tactic
std : : map < PlayerColor , si32 > bestCreature ; // color to ID // id or -1 if not known
2010-02-06 13:49:14 +00:00
2010-02-07 15:06:14 +00:00
// template <typename Handler> void serialize(Handler &h, const int version)
// {
// h & playerColors & numOfTowns & numOfHeroes & gold & woodOre & mercSulfCrystGems & obelisks & artifacts & army & income;
// h & colorToBestHero & personality & bestCreature;
// }
2010-02-01 17:51:33 +00:00
} ;
2015-12-01 00:44:58 +03:00
struct DLL_LINKAGE RumorState
{
enum ERumorType : ui8
{
2015-12-04 22:58:14 +03:00
TYPE_NONE = 0 , TYPE_RAND , TYPE_SPECIAL , TYPE_MAP
} ;
enum ERumorTypeSpecial : ui8
{
RUMOR_OBELISKS = 208 ,
RUMOR_ARTIFACTS = 209 ,
RUMOR_ARMY = 210 ,
RUMOR_INCOME = 211 ,
RUMOR_GRAIL = 212
2015-12-01 00:44:58 +03:00
} ;
ERumorType type ;
std : : map < ERumorType , std : : pair < int , int > > last ;
2015-12-23 15:23:56 +01:00
RumorState ( ) { type = TYPE_NONE ; } ;
2015-12-01 04:57:52 +03:00
bool update ( int id , int extra ) ;
2015-12-01 00:44:58 +03:00
template < typename Handler > void serialize ( Handler & h , const int version )
{
h & type & last ;
}
} ;
2008-12-27 01:01:59 +00:00
struct UpgradeInfo
{
2013-02-10 23:24:57 +00:00
CreatureID oldID ; //creature to be upgraded
std : : vector < CreatureID > newID ; //possible upgrades
2011-07-05 06:14:07 +00:00
std : : vector < TResources > cost ; // cost[upgrade_serial] -> set of pairs<resource_ID,resource_amount>; cost is for single unit (not entire stack)
2013-02-07 17:34:50 +00:00
UpgradeInfo ( ) { oldID = CreatureID : : NONE ; } ;
2008-12-27 01:01:59 +00:00
} ;
2012-07-26 00:48:44 +00:00
struct DLL_EXPORT DuelParameters
2011-01-21 02:36:30 +00:00
{
2013-02-12 22:24:48 +00:00
ETerrainType terType ;
BFieldType bfieldType ;
2012-07-26 00:48:44 +00:00
struct DLL_EXPORT SideSettings
2011-01-21 02:36:30 +00:00
{
2012-07-26 00:48:44 +00:00
struct DLL_EXPORT StackSettings
2011-01-21 02:36:30 +00:00
{
2013-02-10 23:24:57 +00:00
CreatureID type ;
2011-01-21 02:36:30 +00:00
si32 count ;
template < typename Handler > void serialize ( Handler & h , const int version )
{
h & type & count ;
}
StackSettings ( ) ;
2013-02-10 23:24:57 +00:00
StackSettings ( CreatureID Type , si32 Count ) ;
2012-07-26 00:48:44 +00:00
} stacks [ GameConstants : : ARMY_SIZE ] ;
2011-01-21 02:36:30 +00:00
si32 heroId ; //-1 if none
2012-07-26 00:48:44 +00:00
std : : vector < si32 > heroPrimSkills ; //may be empty
std : : map < si32 , CArtifactInstance * > artifacts ;
std : : vector < std : : pair < si32 , si8 > > heroSecSkills ; //may be empty; pairs <id, level>, level [0-3]
2013-02-10 23:24:57 +00:00
std : : set < SpellID > spells ;
2011-01-21 02:36:30 +00:00
SideSettings ( ) ;
template < typename Handler > void serialize ( Handler & h , const int version )
{
2012-07-26 00:48:44 +00:00
h & stacks & heroId & heroPrimSkills & artifacts & heroSecSkills & spells ;
2011-01-21 02:36:30 +00:00
}
} sides [ 2 ] ;
2015-12-29 05:43:33 +03:00
std : : vector < std : : shared_ptr < CObstacleInstance > > obstacles ;
2012-07-26 00:48:44 +00:00
static DuelParameters fromJSON ( const std : : string & fname ) ;
struct CusomCreature
{
int id ;
int attack , defense , dmg , HP , speed , shoots ;
2012-11-03 19:31:16 +00:00
CusomCreature ( )
2012-07-26 00:48:44 +00:00
{
id = attack = defense = dmg = HP = speed = shoots = - 1 ;
}
template < typename Handler > void serialize ( Handler & h , const int version )
{
h & id & attack & defense & dmg & HP & speed & shoots ;
}
} ;
std : : vector < CusomCreature > creatures ;
2011-01-21 02:36:30 +00:00
DuelParameters ( ) ;
template < typename Handler > void serialize ( Handler & h , const int version )
{
2012-07-26 00:48:44 +00:00
h & terType & bfieldType & sides & obstacles & creatures ;
2011-01-21 02:36:30 +00:00
}
} ;
2011-05-04 02:38:58 +00:00
struct BattleInfo ;
2010-12-25 19:23:30 +00:00
2013-11-17 17:57:04 +00:00
DLL_LINKAGE std : : ostream & operator < < ( std : : ostream & os , const EVictoryLossCheckResult & victoryLossCheckResult ) ;
2011-12-13 21:23:17 +00:00
class DLL_LINKAGE CGameState : public CNonConstInfoCallback
2008-12-27 01:01:59 +00:00
{
2009-03-06 22:11:17 +00:00
public :
2013-11-17 17:57:04 +00:00
struct DLL_LINKAGE HeroesPool
{
std : : map < ui32 , ConstTransitivePtr < CGHeroInstance > > heroesPool ; //[subID] - heroes available to buy; nullptr if not available
std : : map < ui32 , ui8 > pavailable ; // [subid] -> which players can recruit hero (binary flags)
2014-03-17 19:51:07 +00:00
CGHeroInstance * pickHeroFor ( bool native , PlayerColor player , const CTown * town ,
std : : map < ui32 , ConstTransitivePtr < CGHeroInstance > > & available , CRandomGenerator & rand , const CHeroClass * bannedClass = nullptr ) const ;
2013-11-17 17:57:04 +00:00
template < typename Handler > void serialize ( Handler & h , const int version )
{
2009-01-06 18:42:20 +00:00
h & heroesPool & pavailable ;
}
2008-12-27 01:01:59 +00:00
} hpool ; //we have here all heroes available on this map that are not hired
2013-12-18 18:18:12 +00:00
CGameState ( ) ;
virtual ~ CGameState ( ) ;
2011-05-09 22:20:47 +00:00
2012-04-14 02:20:22 +00:00
void init ( StartInfo * si ) ;
2012-07-26 00:48:44 +00:00
2013-12-18 18:18:12 +00:00
ConstTransitivePtr < StartInfo > scenarioOps , initialOpts ; //second one is a copy of settings received from pregame (not randomized)
PlayerColor currentPlayer ; //ID of player currently having turn
ConstTransitivePtr < BattleInfo > curB ; //current battle
ui32 day ; //total number of days in game
ConstTransitivePtr < CMap > map ;
std : : map < PlayerColor , PlayerState > players ;
std : : map < TeamID , TeamState > teams ;
CBonusSystemNode globalEffects ;
2015-12-01 00:44:58 +03:00
RumorState rumor ;
2013-12-18 18:18:12 +00:00
boost : : shared_mutex * mx ;
2013-02-18 22:37:22 +00:00
void giveHeroArtifact ( CGHeroInstance * h , ArtifactID aid ) ;
2012-02-17 19:30:40 +00:00
2009-03-06 22:25:19 +00:00
void apply ( CPack * pack ) ;
2016-09-09 20:30:36 +03:00
BFieldType battleGetBattlefieldType ( int3 tile , CRandomGenerator & rand ) ;
2010-07-15 03:04:57 +00:00
UpgradeInfo getUpgradeInfo ( const CStackInstance & stack ) ;
2013-03-03 17:06:03 +00:00
PlayerRelations : : PlayerRelations getPlayerRelations ( PlayerColor color1 , PlayerColor color2 ) ;
2009-08-30 12:47:40 +00:00
bool checkForVisitableDir ( const int3 & src , const int3 & dst ) const ; //check if src tile is visitable from dst tile
2014-09-21 16:42:08 +03:00
void calculatePaths ( const CGHeroInstance * hero , CPathsInfo & out ) ; //calculates possible paths for hero, by default uses current hero position and movement left; returns pointer to newly allocated CPath or nullptr if path does not exists
2010-05-06 12:13:31 +00:00
int3 guardingCreaturePosition ( int3 pos ) const ;
2012-11-14 21:19:32 +00:00
std : : vector < CGObjectInstance * > guardingCreatures ( int3 pos ) const ;
2015-12-01 00:44:58 +03:00
void updateRumor ( ) ;
2013-12-29 11:27:38 +00:00
// ----- victory, loss condition checks -----
2013-11-17 17:57:04 +00:00
EVictoryLossCheckResult checkForVictoryAndLoss ( PlayerColor player ) const ;
2013-12-29 11:27:38 +00:00
bool checkForVictory ( PlayerColor player , const EventCondition & condition ) const ; //checks if given player is winner
PlayerColor checkForStandardWin ( ) const ; //returns color of player that accomplished standard victory conditions or 255 (NEUTRAL) if no winner
bool checkForStandardLoss ( PlayerColor player ) const ; //checks if given player lost the game
2013-11-17 17:57:04 +00:00
void obtainPlayersStats ( SThievesGuildInfo & tgi , int level ) ; //fills tgi with info about other players that is available at given level of thieves' guild
std : : map < ui32 , ConstTransitivePtr < CGHeroInstance > > unusedHeroesFromPool ( ) ; //heroes pool without heroes that are available in taverns
2013-03-03 17:06:03 +00:00
bool isVisible ( int3 pos , PlayerColor player ) ;
bool isVisible ( const CGObjectInstance * obj , boost : : optional < PlayerColor > player ) ;
2009-07-30 12:49:45 +00:00
2013-02-02 08:29:57 +00:00
int getDate ( Date : : EDateType mode = Date : : DAY ) const ; //mode=0 - total days in game, mode=1 - day of week, mode=2 - current week, mode=3 - current month
2013-12-18 18:18:12 +00:00
2014-03-17 19:51:07 +00:00
// ----- getters, setters -----
2016-09-09 20:30:36 +03:00
/// This RNG should only be used inside GS or CPackForClient-derived applyGs
/// If this doesn't work for your code that mean you need a new netpack
///
/// Client-side must use CRandomGenerator::getDefault which is not serialized
///
/// CGameHandler have it's own getter for CRandomGenerator::getDefault
/// Any server-side code outside of GH must use CRandomGenerator::getDefault
2014-03-17 19:51:07 +00:00
CRandomGenerator & getRandomGenerator ( ) ;
2008-12-27 01:01:59 +00:00
template < typename Handler > void serialize ( Handler & h , const int version )
{
2014-04-10 19:11:09 +02:00
h & scenarioOps & initialOpts & currentPlayer & day & map & players & teams & hpool & globalEffects & rand ;
2015-12-06 02:51:54 +03:00
if ( version > = 755 ) //save format backward compatibility
2015-12-01 00:44:58 +03:00
{
h & rumor ;
}
2015-12-01 02:14:11 +03:00
else if ( ! h . saving )
2015-12-01 00:44:58 +03:00
rumor = RumorState ( ) ;
2011-02-23 03:57:45 +00:00
BONUS_TREE_DESERIALIZATION_FIX
2008-12-27 01:01:59 +00:00
}
2013-11-17 17:57:04 +00:00
private :
2014-01-30 18:56:31 +00:00
struct CrossoverHeroesList
{
std : : vector < CGHeroInstance * > heroesFromPreviousScenario , heroesFromAnyPreviousScenarios ;
void addHeroToBothLists ( CGHeroInstance * hero ) ;
void removeHeroFromBothLists ( CGHeroInstance * hero ) ;
} ;
struct CampaignHeroReplacement
{
CampaignHeroReplacement ( CGHeroInstance * hero , ObjectInstanceID heroPlaceholderId ) ;
CGHeroInstance * hero ;
ObjectInstanceID heroPlaceholderId ;
} ;
2013-12-20 13:07:58 +00:00
// ----- initialization -----
2013-12-18 18:18:12 +00:00
void initNewGame ( ) ;
void initCampaign ( ) ;
void initDuel ( ) ;
void checkMapChecksum ( ) ;
void initGrailPosition ( ) ;
void initRandomFactionsForPlayers ( ) ;
void randomizeMapObjects ( ) ;
void randomizeObject ( CGObjectInstance * cur ) ;
void initPlayerStates ( ) ;
2013-12-28 12:47:55 +00:00
void placeCampaignHeroes ( ) ;
2014-01-30 18:56:31 +00:00
CrossoverHeroesList getCrossoverHeroesFromPreviousScenarios ( ) const ;
2014-01-03 16:36:22 +00:00
/// returns heroes and placeholders in where heroes will be put
2014-01-30 18:56:31 +00:00
std : : vector < CampaignHeroReplacement > generateCampaignHeroesToReplace ( CrossoverHeroesList & crossoverHeroes ) ;
/// gets prepared and copied hero instances with crossover heroes from prev. scenario and travel options from current scenario
2016-09-09 20:30:36 +03:00
void prepareCrossoverHeroes ( std : : vector < CampaignHeroReplacement > & campaignHeroReplacements , const CScenarioTravel & travelOptions ) ;
2013-12-20 13:07:58 +00:00
2014-01-30 18:56:31 +00:00
void replaceHeroesPlaceholders ( const std : : vector < CampaignHeroReplacement > & campaignHeroReplacements ) ;
2013-12-18 18:18:12 +00:00
void placeStartingHeroes ( ) ;
2013-12-28 12:47:55 +00:00
void placeStartingHero ( PlayerColor playerColor , HeroTypeID heroTypeId , int3 townPos ) ;
2013-12-18 18:18:12 +00:00
void initStartingResources ( ) ;
void initHeroes ( ) ;
void giveCampaignBonusToHero ( CGHeroInstance * hero ) ;
void initFogOfWar ( ) ;
void initStartingBonus ( ) ;
void initTowns ( ) ;
void initMapObjects ( ) ;
void initVisitingAndGarrisonedHeroes ( ) ;
2013-12-20 13:07:58 +00:00
// ----- bonus system handling -----
2013-12-18 18:18:12 +00:00
void buildBonusSystemTree ( ) ;
void attachArmedObjects ( ) ;
void buildGlobalTeamPlayerTree ( ) ;
void deserializationFix ( ) ;
2013-12-20 13:07:58 +00:00
// ---- misc helpers -----
2013-12-30 15:34:28 +00:00
CGHeroInstance * getUsedHero ( HeroTypeID hid ) const ;
2013-12-18 18:18:12 +00:00
bool isUsedHero ( HeroTypeID hid ) const ; //looks in heroes and prisons
std : : set < HeroTypeID > getUnusedAllowedHeroes ( bool alsoIncludeNotAllowed = false ) const ;
std : : pair < Obj , int > pickObject ( CGObjectInstance * obj ) ; //chooses type of object to be randomized, returns <type, subtype>
2014-03-17 19:51:07 +00:00
int pickUnusedHeroTypeRandomly ( PlayerColor owner ) ; // picks a unused hero type randomly
int pickNextHeroType ( PlayerColor owner ) ; // picks next free hero type of the H3 hero init sequence -> chosen starting hero, then unused hero type randomly
// ---- data -----
CRandomGenerator rand ;
2013-12-18 18:18:12 +00:00
friend class CCallback ;
friend class CClient ;
friend class IGameCallback ;
friend class CMapHandler ;
friend class CGameHandler ;
2008-12-27 01:01:59 +00:00
} ;