#ifndef __CGAMESTATE_H__ #define __CGAMESTATE_H__ #include "../global.h" #include #ifndef _MSC_VER #include "CCreatureHandler.h" #include "VCMI_Lib.h" #include "map.h" #endif #include #include #include #include "HeroBonus.h" #include "CCreatureSet.h" #ifdef _WIN32 #include #else #include "../tchar_amigaos4.h" #endif #include "ConstTransitivePtr.h" /* * 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 * */ class CTown; class CScriptCallback; class CCallback; class IGameCallback; class CLuaCallback; class CCPPObjectScript; class CCreatureSet; class CStack; class CGHeroInstance; class CGTownInstance; class CArmedInstance; class CGDwelling; class CGDefInfo; class CObjectScript; class CGObjectInstance; class CCreature; struct Mapa; struct StartInfo; struct SDL_Surface; class CMapHandler; class CPathfinder; struct SetObjectProperty; struct MetaString; struct CPack; class CSpell; struct TerrainTile; class CHeroClass; class CCampaign; class CCampaignState; class IModableArt; namespace boost { class shared_mutex; } //numbers of creatures are exact numbers if detailed else they are quantity ids (0 - a few, 1 - several and so on; additionaly -1 - unknown) struct DLL_EXPORT ArmyDescriptor : public std::map { ArmyDescriptor(const CArmedInstance *army, bool detailed); //not detailed -> quantity ids as count ArmyDescriptor(); }; struct DLL_EXPORT InfoAboutHero { private: void assign(const InfoAboutHero & iah); public: struct DLL_EXPORT Details { std::vector primskills; int mana, luck, morale; } *details; char owner; const CHeroClass *hclass; std::string name; int portrait; ArmyDescriptor army; InfoAboutHero(); InfoAboutHero(const InfoAboutHero & iah); InfoAboutHero & operator=(const InfoAboutHero & iah); ~InfoAboutHero(); void initFromHero(const CGHeroInstance *h, bool detailed); }; // typedef si32 TResourceUnit; // typedef std::vector TResourceVector; // typedef std::set TResourceSet; struct DLL_EXPORT SThievesGuildInfo { std::vector playerColors; //colors of players that are in-game std::vector< std::list< ui8 > > numOfTowns, numOfHeroes, gold, woodOre, mercSulfCrystGems, obelisks, artifacts, army, income; // [place] -> [colours of players] std::map colorToBestHero; //maps player's color to his best heros' std::map personality; // color to personality // -1 - human, AI -> (00 - random, 01 - warrior, 02 - builder, 03 - explorer) std::map bestCreature; // color to ID // id or -1 if not known // template void serialize(Handler &h, const int version) // { // h & playerColors & numOfTowns & numOfHeroes & gold & woodOre & mercSulfCrystGems & obelisks & artifacts & army & income; // h & colorToBestHero & personality & bestCreature; // } }; struct DLL_EXPORT PlayerState : public CBonusSystemNode { public: enum EStatus {INGAME, LOSER, WINNER}; ui8 color; ui8 human; //true if human controlled player, false for AI ui32 currentSelection; //id of hero/town, 0xffffffff if none ui8 team; std::vector resources; std::vector > heroes; std::vector > towns; std::vector > availableHeroes; //heroes available in taverns std::vector > dwellings; //used for town growth ui8 enteredWinningCheatCode, enteredLosingCheatCode; //if true, this player has entered cheat codes for loss / victory ui8 status; //0 - in game, 1 - loser, 2 - winner <- uses EStatus enum ui8 daysWithoutCastle; PlayerState(); std::string nodeName() const OVERRIDE; //override //void getParents(TCNodes &out, const CBonusSystemNode *root = NULL) const; //void getBonuses(BonusList &out, const CSelector &selector, const CBonusSystemNode *root = NULL) const; template void serialize(Handler &h, const int version) { h & color & human & currentSelection & team & resources & status; h & heroes & towns & availableHeroes & dwellings & bonuses; h & status & daysWithoutCastle; h & enteredLosingCheatCode & enteredWinningCheatCode; h & static_cast(*this); } }; struct DLL_EXPORT TeamState : public CBonusSystemNode { public: ui8 id; //position in gameState::teams std::set players; // members of this team std::vector > > fogOfWarMap; //true - visible, false - hidden TeamState(); template void serialize(Handler &h, const int version) { h & id & players & fogOfWarMap; h & static_cast(*this); } }; struct UpgradeInfo { int oldID; //creature to be upgraded std::vector newID; //possible upgrades std::vector > > cost; // cost[upgrade_serial] -> set of pairs UpgradeInfo(){oldID = -1;}; }; struct CPathNode { bool accessible; //true if a hero can be on this node int dist; //distance from the first node of searching; -1 is infinity CPathNode * theNodeBefore; int3 coord; //coordiantes bool visited; }; struct CGPathNode { enum { ACCESSIBLE=1, //tile can be entered and passed VISITABLE, //tile can be entered as the last tile in path BLOCKVIS, //visitable from neighbouring tile but not passable BLOCKED, //tile can't be entered nor visited FLYABLE //if hero flies, he can pass this tile }; ui8 accessible; //the enum above ui8 land; ui8 turns; ui32 moveRemains; CGPathNode * theNodeBefore; int3 coord; //coordinates CGPathNode(); }; struct DLL_EXPORT CPath { std::vector nodes; //just get node by node int3 startPos() const; // start point int3 endPos() const; //destination point void convert(ui8 mode); //mode=0 -> from 'manifest' to 'object' }; struct DLL_EXPORT CGPath { std::vector nodes; //just get node by node int3 startPos() const; // start point int3 endPos() const; //destination point void convert(ui8 mode); //mode=0 -> from 'manifest' to 'object' }; struct DLL_EXPORT CPathsInfo { const CGHeroInstance *hero; int3 hpos; int3 sizes; CGPathNode ***nodes; //[w][h][level] bool getPath(const int3 &dst, CGPath &out); CPathsInfo(const int3 &Sizes); ~CPathsInfo(); }; struct DLL_EXPORT DuelParameters { si32 terType, bfieldType; struct SideSettings { struct StackSettings { si32 type; si32 count; template void serialize(Handler &h, const int version) { h & type & count; } StackSettings(); StackSettings(si32 Type, si32 Count); } stacks[ARMY_SIZE]; si32 heroId; //-1 if none std::set spells; SideSettings(); template void serialize(Handler &h, const int version) { h & stacks & heroId & spells; } } sides[2]; DuelParameters(); template void serialize(Handler &h, const int version) { h & terType & bfieldType & sides; } }; class BattleInfo; class DLL_EXPORT CGameState { public: ConstTransitivePtr scenarioOps, initialOpts; //second one is a copy of settings received from pregame (not randomized) ConstTransitivePtr campaign; ui32 seed; ui8 currentPlayer; //ID of player currently having turn ConstTransitivePtr curB; //current battle ui32 day; //total number of days in game ConstTransitivePtr map; bmap players; //ID <-> player state bmap teams; //ID <-> team state bmap > villages, forts, capitols; //def-info for town graphics CBonusSystemNode globalEffects; struct DLL_EXPORT HeroesPool { bmap > heroesPool; //[subID] - heroes available to buy; NULL if not available bmap pavailable; // [subid] -> which players can recruit hero (binary flags) CGHeroInstance * pickHeroFor(bool native, int player, const CTown *town, bmap > &available, const CHeroClass *bannedClass = NULL) const; template void serialize(Handler &h, const int version) { h & heroesPool & pavailable; } } hpool; //we have here all heroes available on this map that are not hired boost::shared_mutex *mx; PlayerState *getPlayer(ui8 color, bool verbose = true); TeamState *getTeam(ui8 teamID);//get team by team ID TeamState *getPlayerTeam(ui8 color);// get team by player color const PlayerState *getPlayer(ui8 color, bool verbose = true) const; const TeamState *getTeam(ui8 teamID) const; const TeamState *getPlayerTeam(ui8 color) const; void init(StartInfo * si, ui32 checksum, int Seed); void loadTownDInfos(); void randomizeObject(CGObjectInstance *cur); std::pair pickObject(CGObjectInstance *obj); //chooses type of object to be randomized, returns int pickHero(int owner); void apply(CPack *pack); CGHeroInstance *getHero(int objid); CGTownInstance *getTown(int objid); const CGHeroInstance *getHero(int objid) const; const CGTownInstance *getTown(int objid) const; int battleGetBattlefieldType(int3 tile = int3());// 1. sand/shore 2. sand/mesas 3. dirt/birches 4. dirt/hills 5. dirt/pines 6. grass/hills 7. grass/pines 8. lava 9. magic plains 10. snow/mountains 11. snow/trees 12. subterranean 13. swamp/trees 14. fiery fields 15. rock lands 16. magic clouds 17. lucid pools 18. holy ground 19. clover field 20. evil fog 21. "favourable winds" text on magic plains background 22. cursed ground 23. rough 24. ship to ship 25. ship UpgradeInfo getUpgradeInfo(const CStackInstance &stack); int getPlayerRelations(ui8 color1, ui8 color2);// 0 = enemy, 1 = ally, 2 = same player //float getMarketEfficiency(int player, int mode=0); std::set getBuildingRequiments(const CGTownInstance *t, int ID); int canBuildStructure(const CGTownInstance *t, int ID);// 0 - no more than one capitol, 1 - lack of water, 2 - forbidden, 3 - Add another level to Mage Guild, 4 - already built, 5 - cannot build, 6 - cannot afford, 7 - build, 8 - lack of requirements bool checkForVisitableDir(const int3 & src, const int3 & dst) const; //check if src tile is visitable from dst tile bool checkForVisitableDir(const int3 & src, const TerrainTile *pom, const int3 & dst) const; //check if src tile is visitable from dst tile bool getPath(int3 src, int3 dest, const CGHeroInstance * hero, CPath &ret); //calculates path between src and dest; returns pointer to newly allocated CPath or NULL if path does not exists void calculatePaths(const CGHeroInstance *hero, CPathsInfo &out, int3 src = int3(-1,-1,-1), int movement = -1); //calculates possible paths for hero, by default uses current hero position and movement left; returns pointer to newly allocated CPath or NULL if path does not exists int3 guardingCreaturePosition (int3 pos) const; int victoryCheck(ui8 player) const; //checks if given player is winner; -1 if std victory, 1 if special victory, 0 else int lossCheck(ui8 player) const; //checks if given player is loser; -1 if std loss, 1 if special, 0 else ui8 checkForStandardWin() const; //returns color of player that accomplished standard victory conditions or 255 if no winner bool checkForStandardLoss(ui8 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 bmap > unusedHeroesFromPool(); //heroes pool without heroes that are available in taverns BattleInfo * setupBattle(int3 tile, const CArmedInstance *armies[2], const CGHeroInstance * heroes[2], bool creatureBank, const CGTownInstance *town); void buildBonusSystemTree(); bool isVisible(int3 pos, int player); bool isVisible(const CGObjectInstance *obj, int player); CGameState(); //c-tor ~CGameState(); //d-tor void getNeighbours(const TerrainTile &srct, int3 tile, std::vector &vec, const boost::logic::tribool &onLand, bool limitCoastSailing); int getMovementCost(const CGHeroInstance *h, const int3 &src, const int3 &dest, int remainingMovePoints=-1, bool checkLast=true); int getDate(int mode=0) const; //mode=0 - total days in game, mode=1 - day of week, mode=2 - current week, mode=3 - current month template void serialize(Handler &h, const int version) { h & scenarioOps & seed & currentPlayer & day & map & players & teams & hpool & globalEffects & campaign; h & villages & forts & capitols; if(!h.saving) { loadTownDInfos(); } } friend class CCallback; friend class CLuaCallback; friend class CClient; friend void initGameState(Mapa * map, CGameInfo * cgi); friend class IGameCallback; friend class CMapHandler; friend class CGameHandler; }; #endif // __CGAMESTATE_H__