1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-10 09:50:17 +02:00
vcmi/lib/CGameState.h

308 lines
10 KiB
C
Raw Normal View History

/*
* 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
*
*/
#pragma once
#include "CCreatureHandler.h"
2009-05-20 13:08:56 +03:00
#include "VCMI_Lib.h"
#include "HeroBonus.h"
#include "CCreatureSet.h"
#include "ConstTransitivePtr.h"
#include "IGameCallback.h"
#include "ResourceSet.h"
#include "int3.h"
#include "CRandomGenerator.h"
#include "CGameStateFwd.h"
#include "CPathfinder.h"
class CTown;
class CCallback;
class IGameCallback;
class CCreatureSet;
class CQuest;
class CGHeroInstance;
class CGTownInstance;
class CArmedInstance;
class CGDwelling;
class CObjectScript;
class CGObjectInstance;
class CCreature;
class CMap;
struct StartInfo;
class CMapHandler;
struct SetObjectProperty;
struct MetaString;
2009-03-07 00:25:19 +02:00
struct CPack;
2009-05-07 18:19:52 +03:00
class CSpell;
struct TerrainTile;
2010-02-07 17:06:14 +02:00
class CHeroClass;
2010-05-08 21:56:38 +03:00
class CCampaign;
class CCampaignState;
class IModableArt;
2011-05-03 06:14:18 +03:00
class CGGarrison;
class CGameInfo;
struct QuestInfo;
class CQuest;
class CCampaignScenario;
2013-12-29 18:48:56 +03:00
struct EventCondition;
2014-01-03 19:36:22 +03:00
class CScenarioTravel;
Spells configuration version 2 (effect-based) * Indirect spell effects loading * Json serializer improvements * spell->canBeCastAt do not allow useless cast for any spell * Added proxy caster class for spell-created obstacles * Handle damage from spell-created obstacles inside mechanics * Experimental GameState integration/regression tests * Ignore mod settings and load only "vcmi" mod when running tests * fixed https://bugs.vcmi.eu/view.php?id=2765 (with tests) * Huge improvements of BattleAI regarding spell casts * AI can cast almost any combat spell except TELEPORT, SACRIFICE and obstacle placement spells. * Possible fix for https://bugs.vcmi.eu/view.php?id=1811 * CStack factored out to several classes * [Battle] Allowed RETURN_AFTER_STRIKE effect on server side to be optional * [Battle] Allowed BattleAction have multiple destinations * [Spells] Converted limit|immunity to target condition * [Spells] Use partial configuration reload for backward compatibility handling * [Tests] Started tests for CUnitState * Partial fixes of fire shield effect * [Battle] Do HP calculations in 64 bits * [BattleAI] Use threading for spell cast evaluation * [BattleAI] Made AI be able to evaluate modified turn order (on hypothetical battle state) * Implemented https://bugs.vcmi.eu/view.php?id=2811 * plug rare freeze when hypnotized unit shots vertically * Correctly apply ONLY_MELEE_FIGHT / ONLY_DISTANCE_FIGHT for unit damage, attack & defense * [BattleAI] Try to not waste a cast if battle is actually won already * Extended JsonSerializeFormat API * fixed https://bugs.vcmi.eu/view.php?id=2847 * Any unit effect can be now chained (not only damage like Chain Lightning) ** only damage effect for now actually uses "chainFactor" * Possible quick fix for https://bugs.vcmi.eu/view.php?id=2860
2017-07-20 06:08:49 +02:00
class IMapService;
namespace boost
{
class shared_mutex;
}
template<typename T> class CApplier;
class CBaseForGSApply;
struct DLL_LINKAGE SThievesGuildInfo
2010-02-01 19:51:33 +02:00
{
2013-03-03 20:06:03 +03:00
std::vector<PlayerColor> playerColors; //colors of players that are in-game
2010-02-01 19:51:33 +02:00
2013-03-03 20:06:03 +03:00
std::vector< std::vector< PlayerColor > > numOfTowns, numOfHeroes, gold, woodOre, mercSulfCrystGems, obelisks, artifacts, army, income; // [place] -> [colours of players]
2010-02-01 19:51:33 +02:00
2013-03-03 20:06:03 +03:00
std::map<PlayerColor, InfoAboutHero> colorToBestHero; //maps player's color to his best heros'
2010-02-01 19:51:33 +02:00
2013-03-03 20:06:03 +03: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
// template <typename Handler> void serialize(Handler &h, const int version)
// {
// h & playerColors;
// h & numOfTowns;
// h & numOfHeroes;
// h & gold;
// h & woodOre;
// h & mercSulfCrystGems;
// h & obelisks;
// h & artifacts;
// h & army;
// h & income;
// h & colorToBestHero;
// h & personality;
// h & bestCreature;
// }
2010-02-01 19:51:33 +02:00
};
struct DLL_LINKAGE RumorState
{
enum ERumorType : ui8
{
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
};
ERumorType type;
std::map<ERumorType, std::pair<int, int>> last;
2015-12-23 16:23:56 +02:00
RumorState(){type = TYPE_NONE;};
bool update(int id, int extra);
template <typename Handler> void serialize(Handler &h, const int version)
{
h & type;
h & last;
}
};
struct UpgradeInfo
{
CreatureID oldID; //creature to be upgraded
std::vector<CreatureID> newID; //possible upgrades
std::vector<TResources> cost; // cost[upgrade_serial] -> set of pairs<resource_ID,resource_amount>; cost is for single unit (not entire stack)
UpgradeInfo(){oldID = CreatureID::NONE;};
};
Spells configuration version 2 (effect-based) * Indirect spell effects loading * Json serializer improvements * spell->canBeCastAt do not allow useless cast for any spell * Added proxy caster class for spell-created obstacles * Handle damage from spell-created obstacles inside mechanics * Experimental GameState integration/regression tests * Ignore mod settings and load only "vcmi" mod when running tests * fixed https://bugs.vcmi.eu/view.php?id=2765 (with tests) * Huge improvements of BattleAI regarding spell casts * AI can cast almost any combat spell except TELEPORT, SACRIFICE and obstacle placement spells. * Possible fix for https://bugs.vcmi.eu/view.php?id=1811 * CStack factored out to several classes * [Battle] Allowed RETURN_AFTER_STRIKE effect on server side to be optional * [Battle] Allowed BattleAction have multiple destinations * [Spells] Converted limit|immunity to target condition * [Spells] Use partial configuration reload for backward compatibility handling * [Tests] Started tests for CUnitState * Partial fixes of fire shield effect * [Battle] Do HP calculations in 64 bits * [BattleAI] Use threading for spell cast evaluation * [BattleAI] Made AI be able to evaluate modified turn order (on hypothetical battle state) * Implemented https://bugs.vcmi.eu/view.php?id=2811 * plug rare freeze when hypnotized unit shots vertically * Correctly apply ONLY_MELEE_FIGHT / ONLY_DISTANCE_FIGHT for unit damage, attack & defense * [BattleAI] Try to not waste a cast if battle is actually won already * Extended JsonSerializeFormat API * fixed https://bugs.vcmi.eu/view.php?id=2847 * Any unit effect can be now chained (not only damage like Chain Lightning) ** only damage effect for now actually uses "chainFactor" * Possible quick fix for https://bugs.vcmi.eu/view.php?id=2860
2017-07-20 06:08:49 +02:00
class BattleInfo;
DLL_LINKAGE std::ostream & operator<<(std::ostream & os, const EVictoryLossCheckResult & victoryLossCheckResult);
class DLL_LINKAGE CGameState : public CNonConstInfoCallback
{
2009-03-07 00:11:17 +02:00
public:
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)
CGHeroInstance * pickHeroFor(bool native, PlayerColor player, const CTown *town,
std::map<ui32, ConstTransitivePtr<CGHeroInstance> > &available, CRandomGenerator & rand, const CHeroClass *bannedClass = nullptr) const;
template <typename Handler> void serialize(Handler &h, const int version)
{
h & heroesPool;
h & pavailable;
}
} hpool; //we have here all heroes available on this map that are not hired
2013-12-18 21:18:12 +03:00
CGameState();
virtual ~CGameState();
void preInit(Services * services);
Spells configuration version 2 (effect-based) * Indirect spell effects loading * Json serializer improvements * spell->canBeCastAt do not allow useless cast for any spell * Added proxy caster class for spell-created obstacles * Handle damage from spell-created obstacles inside mechanics * Experimental GameState integration/regression tests * Ignore mod settings and load only "vcmi" mod when running tests * fixed https://bugs.vcmi.eu/view.php?id=2765 (with tests) * Huge improvements of BattleAI regarding spell casts * AI can cast almost any combat spell except TELEPORT, SACRIFICE and obstacle placement spells. * Possible fix for https://bugs.vcmi.eu/view.php?id=1811 * CStack factored out to several classes * [Battle] Allowed RETURN_AFTER_STRIKE effect on server side to be optional * [Battle] Allowed BattleAction have multiple destinations * [Spells] Converted limit|immunity to target condition * [Spells] Use partial configuration reload for backward compatibility handling * [Tests] Started tests for CUnitState * Partial fixes of fire shield effect * [Battle] Do HP calculations in 64 bits * [BattleAI] Use threading for spell cast evaluation * [BattleAI] Made AI be able to evaluate modified turn order (on hypothetical battle state) * Implemented https://bugs.vcmi.eu/view.php?id=2811 * plug rare freeze when hypnotized unit shots vertically * Correctly apply ONLY_MELEE_FIGHT / ONLY_DISTANCE_FIGHT for unit damage, attack & defense * [BattleAI] Try to not waste a cast if battle is actually won already * Extended JsonSerializeFormat API * fixed https://bugs.vcmi.eu/view.php?id=2847 * Any unit effect can be now chained (not only damage like Chain Lightning) ** only damage effect for now actually uses "chainFactor" * Possible quick fix for https://bugs.vcmi.eu/view.php?id=2860
2017-07-20 06:08:49 +02:00
void init(const IMapService * mapService, StartInfo * si, bool allowSavingRandomMap = false);
void updateOnLoad(StartInfo * si);
2013-12-18 21:18:12 +03: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;
RumorState rumor;
2013-12-18 21:18:12 +03:00
2017-06-14 06:59:41 +02:00
static boost::shared_mutex mutex;
2013-12-18 21:18:12 +03:00
void updateEntity(Metatype metatype, int32_t index, const JsonNode & data) override;
void giveHeroArtifact(CGHeroInstance *h, ArtifactID aid);
2012-02-17 22:30:40 +03:00
2009-03-07 00:25:19 +02:00
void apply(CPack *pack);
2022-06-22 10:41:02 +02:00
BattleField battleGetBattlefieldType(int3 tile, CRandomGenerator & rand);
2010-07-15 06:04:57 +03:00
UpgradeInfo getUpgradeInfo(const CStackInstance &stack);
2013-03-03 20:06:03 +03:00
PlayerRelations::PlayerRelations getPlayerRelations(PlayerColor color1, PlayerColor color2);
bool checkForVisitableDir(const int3 & src, const int3 & dst) const; //check if src tile is visitable from dst tile
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
void calculatePaths(std::shared_ptr<PathfinderConfig> config) override;
int3 guardingCreaturePosition (int3 pos) const override;
std::vector<CGObjectInstance*> guardingCreatures (int3 pos) const;
void updateRumor();
// ----- victory, loss condition checks -----
EVictoryLossCheckResult checkForVictoryAndLoss(PlayerColor player) const;
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
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 20:06:03 +03:00
bool isVisible(int3 pos, PlayerColor player);
bool isVisible(const CGObjectInstance *obj, boost::optional<PlayerColor> player);
int getDate(Date::EDateType mode=Date::DAY) const override; //mode=0 - total days in game, mode=1 - day of week, mode=2 - current week, mode=3 - current month
2013-12-18 21:18:12 +03:00
// ----- getters, setters -----
/// 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
CRandomGenerator & getRandomGenerator();
template <typename Handler> void serialize(Handler &h, const int version)
{
h & scenarioOps;
h & initialOpts;
h & currentPlayer;
h & day;
h & map;
h & players;
h & teams;
h & hpool;
h & globalEffects;
h & rand;
h & rumor;
BONUS_TREE_DESERIALIZATION_FIX
}
private:
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;
};
// ----- initialization -----
void preInitAuto();
Spells configuration version 2 (effect-based) * Indirect spell effects loading * Json serializer improvements * spell->canBeCastAt do not allow useless cast for any spell * Added proxy caster class for spell-created obstacles * Handle damage from spell-created obstacles inside mechanics * Experimental GameState integration/regression tests * Ignore mod settings and load only "vcmi" mod when running tests * fixed https://bugs.vcmi.eu/view.php?id=2765 (with tests) * Huge improvements of BattleAI regarding spell casts * AI can cast almost any combat spell except TELEPORT, SACRIFICE and obstacle placement spells. * Possible fix for https://bugs.vcmi.eu/view.php?id=1811 * CStack factored out to several classes * [Battle] Allowed RETURN_AFTER_STRIKE effect on server side to be optional * [Battle] Allowed BattleAction have multiple destinations * [Spells] Converted limit|immunity to target condition * [Spells] Use partial configuration reload for backward compatibility handling * [Tests] Started tests for CUnitState * Partial fixes of fire shield effect * [Battle] Do HP calculations in 64 bits * [BattleAI] Use threading for spell cast evaluation * [BattleAI] Made AI be able to evaluate modified turn order (on hypothetical battle state) * Implemented https://bugs.vcmi.eu/view.php?id=2811 * plug rare freeze when hypnotized unit shots vertically * Correctly apply ONLY_MELEE_FIGHT / ONLY_DISTANCE_FIGHT for unit damage, attack & defense * [BattleAI] Try to not waste a cast if battle is actually won already * Extended JsonSerializeFormat API * fixed https://bugs.vcmi.eu/view.php?id=2847 * Any unit effect can be now chained (not only damage like Chain Lightning) ** only damage effect for now actually uses "chainFactor" * Possible quick fix for https://bugs.vcmi.eu/view.php?id=2860
2017-07-20 06:08:49 +02:00
void initNewGame(const IMapService * mapService, bool allowSavingRandomMap);
void initCampaign();
2013-12-18 21:18:12 +03:00
void checkMapChecksum();
void initGrailPosition();
void initRandomFactionsForPlayers();
void randomizeMapObjects();
void randomizeObject(CGObjectInstance *cur);
void initPlayerStates();
void placeCampaignHeroes();
CrossoverHeroesList getCrossoverHeroesFromPreviousScenarios() const;
2014-01-03 19:36:22 +03:00
/// returns heroes and placeholders in where heroes will be put
std::vector<CampaignHeroReplacement> generateCampaignHeroesToReplace(CrossoverHeroesList & crossoverHeroes);
/// gets prepared and copied hero instances with crossover heroes from prev. scenario and travel options from current scenario
void prepareCrossoverHeroes(std::vector<CampaignHeroReplacement> & campaignHeroReplacements, const CScenarioTravel & travelOptions);
void replaceHeroesPlaceholders(const std::vector<CampaignHeroReplacement> & campaignHeroReplacements);
2013-12-18 21:18:12 +03:00
void placeStartingHeroes();
void placeStartingHero(PlayerColor playerColor, HeroTypeID heroTypeId, int3 townPos);
2013-12-18 21:18:12 +03:00
void initStartingResources();
void initHeroes();
void giveCampaignBonusToHero(CGHeroInstance * hero);
void initFogOfWar();
void initStartingBonus();
void initTowns();
void initMapObjects();
void initVisitingAndGarrisonedHeroes();
// ----- bonus system handling -----
2013-12-18 21:18:12 +03:00
void buildBonusSystemTree();
void attachArmedObjects();
void buildGlobalTeamPlayerTree();
void deserializationFix();
// ---- misc helpers -----
CGHeroInstance * getUsedHero(HeroTypeID hid) const;
2013-12-18 21:18:12 +03: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>
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 -----
std::shared_ptr<CApplier<CBaseForGSApply>> applier;
CRandomGenerator rand;
Services * services;
2013-12-18 21:18:12 +03:00
friend class CCallback;
friend class CClient;
friend class IGameCallback;
friend class CMapHandler;
friend class CGameHandler;
};