2017-07-13 10:26:03 +02:00
/*
* VCAI . 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
*
*/
2012-02-14 21:04:45 +03:00
# pragma once
2012-09-06 13:39:48 +03:00
2013-10-18 23:17:25 +03:00
# include "AIUtility.h"
# include "Goals.h"
2012-09-06 13:39:48 +03:00
# include "../../lib/AI_Base.h"
# include "../../CCallback.h"
# include "../../lib/CThreadHelper.h"
2013-12-23 23:46:01 +03:00
# include "../../lib/GameConstants.h"
2012-09-06 13:39:48 +03:00
# include "../../lib/VCMI_Lib.h"
# include "../../lib/CBuildingHandler.h"
# include "../../lib/CCreatureHandler.h"
# include "../../lib/CTownHandler.h"
2015-12-02 21:05:10 +02:00
# include "../../lib/mapObjects/MiscObjects.h"
2015-02-02 10:25:26 +02:00
# include "../../lib/spells/CSpellHandler.h"
2012-09-06 13:39:48 +03:00
# include "../../lib/CondSh.h"
2013-05-09 14:09:23 +03:00
2013-10-18 23:17:25 +03:00
struct QuestInfo ;
2012-07-01 02:48:40 +03:00
2012-02-14 21:04:45 +03:00
class AIStatus
{
boost : : mutex mx ;
boost : : condition_variable cv ;
BattleState battle ;
2013-05-27 13:53:28 +03:00
std : : map < QueryID , std : : string > remainingQueries ;
std : : map < int , QueryID > requestToQueryID ; //IDs of answer-requests sent to server => query ids (so we can match answer confirmation from server to the query)
2018-04-07 10:44:14 +02:00
std : : vector < const CGObjectInstance * > objectsBeingVisited ;
2013-09-28 02:46:58 +03:00
bool ongoingHeroMovement ;
2015-03-08 16:23:56 +02:00
bool ongoingChannelProbing ; // true if AI currently explore bidirectional teleport channel exits
2012-07-15 18:34:00 +03:00
2012-02-14 21:04:45 +03:00
bool havingTurn ;
public :
AIStatus ( ) ;
~ AIStatus ( ) ;
void setBattle ( BattleState BS ) ;
2013-09-28 02:46:58 +03:00
void setMove ( bool ongoing ) ;
2015-03-08 16:23:56 +02:00
void setChannelProbing ( bool ongoing ) ;
bool channelProbing ( ) ;
2012-02-14 21:04:45 +03:00
BattleState getBattle ( ) ;
2013-05-27 13:53:28 +03:00
void addQuery ( QueryID ID , std : : string description ) ;
void removeQuery ( QueryID ID ) ;
2012-02-14 21:04:45 +03:00
int getQueriesCount ( ) ;
void startedTurn ( ) ;
void madeTurn ( ) ;
void waitTillFree ( ) ;
bool haveTurn ( ) ;
2013-05-27 13:53:28 +03:00
void attemptedAnsweringQuery ( QueryID queryID , int answerRequestID ) ;
2012-07-15 18:34:00 +03:00
void receivedAnswerConfirmation ( int answerRequestID , int result ) ;
2018-04-07 10:44:14 +02:00
void heroVisit ( const CGObjectInstance * obj , bool started ) ;
2013-05-09 14:09:23 +03:00
2018-04-07 10:44:14 +02:00
template < typename Handler > void serialize ( Handler & h , const int version )
2013-05-09 14:09:23 +03:00
{
2017-07-31 15:35:42 +02:00
h & battle ;
h & remainingQueries ;
h & requestToQueryID ;
h & havingTurn ;
2013-05-09 14:09:23 +03:00
}
2012-02-14 21:04:45 +03:00
} ;
2018-04-07 10:44:14 +02:00
enum
{
NOT_VISIBLE = 0 ,
NOT_CHECKED = 1 ,
NOT_AVAILABLE
} ;
2012-02-14 21:04:45 +03:00
struct SectorMap
{
//a sector is set of tiles that would be mutually reachable if all visitable objs would be passable (incl monsters)
struct Sector
{
int id ;
std : : vector < int3 > tiles ;
std : : vector < int3 > embarkmentPoints ; //tiles of other sectors onto which we can (dis)embark
2016-08-12 08:02:14 +02:00
std : : vector < const CGObjectInstance * > visitableObjs ;
2012-02-14 21:04:45 +03:00
bool water ; //all tiles of sector are land or water
2012-02-16 20:10:58 +03:00
Sector ( )
{
2012-02-14 21:04:45 +03:00
id = - 1 ;
2016-11-27 16:48:18 +02:00
water = false ;
2012-02-14 21:04:45 +03:00
}
} ;
2016-12-12 22:38:12 +02:00
typedef unsigned short TSectorID ; //smaller than int to allow -1 value. Max number of sectors 65K should be enough for any proper map.
typedef boost : : multi_array < TSectorID , 3 > TSectorArray ;
2012-02-14 21:04:45 +03:00
bool valid ; //some kind of lazy eval
std : : map < int3 , int3 > parent ;
2016-12-12 22:38:12 +02:00
TSectorArray sector ;
2012-02-16 20:10:58 +03:00
//std::vector<std::vector<std::vector<unsigned char>>> pathfinderSector;
2012-02-14 21:04:45 +03:00
std : : map < int , Sector > infoOnSectors ;
2018-04-07 10:44:14 +02:00
std : : shared_ptr < boost : : multi_array < TerrainTile * , 3 > > visibleTiles ;
2012-02-14 21:04:45 +03:00
SectorMap ( ) ;
2014-02-15 22:39:03 +03:00
SectorMap ( HeroPtr h ) ;
2012-02-14 21:04:45 +03:00
void update ( ) ;
void clear ( ) ;
2014-04-01 14:53:28 +03:00
void exploreNewSector ( crint3 pos , int num , CCallback * cbp ) ;
2012-02-14 21:04:45 +03:00
void write ( crstring fname ) ;
2018-04-07 10:44:14 +02:00
bool markIfBlocked ( TSectorID & sec , crint3 pos , const TerrainTile * t ) ;
bool markIfBlocked ( TSectorID & sec , crint3 pos ) ;
2018-02-10 20:52:23 +02:00
TSectorID & retrieveTile ( crint3 pos ) ;
TSectorID & retrieveTileN ( TSectorArray & vectors , const int3 & pos ) ;
2018-04-07 10:44:14 +02:00
const TSectorID & retrieveTileN ( const TSectorArray & vectors , const int3 & pos ) ;
TerrainTile * getTile ( crint3 pos ) const ;
2016-08-12 08:05:11 +02:00
std : : vector < const CGObjectInstance * > getNearbyObjs ( HeroPtr h , bool sectorsAround ) ;
2012-02-14 21:04:45 +03:00
void makeParentBFS ( crint3 source ) ;
2012-07-01 02:48:40 +03:00
int3 firstTileToGet ( HeroPtr h , crint3 dst ) ; //if h wants to reach tile dst, which tile he should visit to clear the way?
2014-02-23 19:55:42 +03:00
int3 findFirstVisitableTile ( HeroPtr h , crint3 dst ) ;
2012-02-14 21:04:45 +03:00
} ;
2018-07-26 12:06:55 +02:00
class DLL_EXPORT VCAI : public CAdventureAI
2012-02-14 21:04:45 +03:00
{
2013-12-23 23:46:01 +03:00
public :
2012-05-19 19:22:34 +03:00
//internal methods for town development
2018-07-26 12:06:55 +02:00
//TODO: refactor to separate class BuildManager
2012-05-19 19:22:34 +03:00
2018-07-26 12:06:55 +02:00
//try build anything in given town, and execute resulting Goal if any
bool tryBuildStructure ( const CGTownInstance * t ) ;
bool tryBuildAnyStructure ( const CGTownInstance * t , std : : vector < BuildingID > buildList , unsigned int maxDays = 7 ) ;
//try build first unbuilt structure
bool tryBuildThisStructure ( const CGTownInstance * t , BuildingID building , unsigned int maxDays = 7 ) ;
2012-05-19 19:22:34 +03:00
//try build ANY unbuilt structure
2018-07-19 20:39:37 +02:00
BuildingID canBuildAnyStructure ( const CGTownInstance * t , std : : vector < BuildingID > buildList , unsigned int maxDays = 7 ) const ;
2018-07-26 12:06:55 +02:00
bool tryBuildNextStructure ( const CGTownInstance * t , std : : vector < BuildingID > buildList , unsigned int maxDays = 7 ) ;
void buildStructure ( const CGTownInstance * t , BuildingID building ) ; //actually execute build operation
struct PotentialBuilding
{
BuildingID bid ;
TResources price ;
//days to build?
} ;
std : : vector < PotentialBuilding > potentialBuildings ; //what we can build in current town
2012-05-19 19:22:34 +03:00
2012-03-03 13:08:01 +03:00
friend class FuzzyHelper ;
2018-07-26 12:06:55 +02:00
friend class ResourceManager ;
2012-03-03 13:08:01 +03:00
2018-04-07 10:44:14 +02:00
std : : map < TeleportChannelID , std : : shared_ptr < TeleportChannel > > knownTeleportChannels ;
2012-02-14 21:04:45 +03:00
std : : map < const CGObjectInstance * , const CGObjectInstance * > knownSubterraneanGates ;
2015-03-08 16:47:58 +02:00
ObjectInstanceID destinationTeleport ;
2015-12-02 16:56:26 +02:00
int3 destinationTeleportPos ;
2015-03-08 16:47:58 +02:00
std : : vector < ObjectInstanceID > teleportChannelProbingList ; //list of teleport channel exits that not visible and need to be (re-)explored
2013-04-21 15:11:13 +03:00
//std::vector<const CGObjectInstance *> visitedThisWeek; //only OPWs
2018-04-07 10:44:14 +02:00
std : : map < HeroPtr , std : : set < const CGTownInstance * > > townVisitsThisWeek ;
2012-02-14 21:04:45 +03:00
2013-11-23 21:16:25 +03:00
std : : map < HeroPtr , Goals : : TSubgoal > lockedHeroes ; //TODO: allow non-elementar objectives
2018-04-07 10:44:14 +02:00
std : : map < HeroPtr , std : : set < const CGObjectInstance * > > reservedHeroesMap ; //objects reserved by specific heroes
2014-03-23 19:00:43 +03:00
std : : set < HeroPtr > heroesUnableToExplore ; //these heroes will not be polled for exploration in current state of game
2012-02-14 21:04:45 +03:00
2013-12-25 16:38:20 +03:00
//sets are faster to search, also do not contain duplicates
std : : set < const CGObjectInstance * > visitableObjs ;
std : : set < const CGObjectInstance * > alreadyVisited ;
std : : set < const CGObjectInstance * > reservedObjs ; //to be visited by specific hero
2012-02-14 21:04:45 +03:00
2018-04-07 10:44:14 +02:00
std : : map < HeroPtr , std : : shared_ptr < SectorMap > > cachedSectorMaps ; //TODO: serialize? not necessary
2015-10-26 17:38:17 +02:00
2012-02-14 21:04:45 +03:00
AIStatus status ;
std : : string battlename ;
2015-12-29 04:43:33 +02:00
std : : shared_ptr < CCallback > myCb ;
2012-02-14 21:04:45 +03:00
2015-12-29 04:43:33 +02:00
std : : unique_ptr < boost : : thread > makingTurn ;
2012-03-05 22:11:28 +03:00
2018-01-13 10:43:26 +02:00
VCAI ( ) ;
virtual ~ VCAI ( ) ;
2012-02-14 21:04:45 +03:00
2013-11-23 21:16:25 +03:00
//TODO: use only smart pointers?
void tryRealize ( Goals : : Explore & g ) ;
void tryRealize ( Goals : : RecruitHero & g ) ;
void tryRealize ( Goals : : VisitTile & g ) ;
void tryRealize ( Goals : : VisitHero & g ) ;
void tryRealize ( Goals : : BuildThis & g ) ;
void tryRealize ( Goals : : DigAtTile & g ) ;
2018-08-04 10:20:40 +02:00
void tryRealize ( Goals : : Trade & g ) ;
2013-11-23 21:16:25 +03:00
void tryRealize ( Goals : : Build & g ) ;
2018-07-26 12:06:55 +02:00
void tryRealize ( Goals : : BuyArmy & g ) ;
2013-11-23 21:16:25 +03:00
void tryRealize ( Goals : : Invalid & g ) ;
void tryRealize ( Goals : : AbstractGoal & g ) ;
2012-02-14 21:04:45 +03:00
2012-07-01 02:48:40 +03:00
int3 explorationBestNeighbour ( int3 hpos , int radius , HeroPtr h ) ;
2014-02-17 20:28:39 +03:00
int3 explorationNewPoint ( HeroPtr h ) ;
int3 explorationDesperate ( HeroPtr h ) ;
2015-04-10 08:50:21 +02:00
bool isTileNotReserved ( const CGHeroInstance * h , int3 t ) ; //the tile is not occupied by allied hero and the object is not reserved
2012-02-14 21:04:45 +03:00
2018-07-26 12:06:55 +02:00
std : : string getBattleAIName ( ) const override ;
2013-06-26 14:18:27 +03:00
2018-07-26 12:06:55 +02:00
void init ( std : : shared_ptr < CCallback > CB ) override ;
void yourTurn ( ) override ;
2013-06-26 14:18:27 +03:00
2018-07-26 12:06:55 +02:00
void heroGotLevel ( const CGHeroInstance * hero , PrimarySkill : : PrimarySkill pskill , std : : vector < SecondarySkill > & skills , QueryID queryID ) override ; //pskill is gained primary skill, interface has to choose one of given skills and call callback with selection id
void commanderGotLevel ( const CCommanderInstance * commander , std : : vector < ui32 > skills , QueryID queryID ) override ; //TODO
void showBlockingDialog ( const std : : string & text , const std : : vector < Component > & components , QueryID askID , const int soundID , bool selection , bool cancel ) override ; //Show a dialog, player must take decision. If selection then he has to choose between one of given components, if cancel he is allowed to not choose. After making choice, CCallback::selectionMade should be called with number of selected component (1 - n) or 0 for cancel (if allowed) and askID.
void showGarrisonDialog ( const CArmedInstance * up , const CGHeroInstance * down , bool removableUnits , QueryID queryID ) override ; //all stacks operations between these objects become allowed, interface has to call onEnd when done
void showTeleportDialog ( TeleportChannelID channel , TTeleportExitsList exits , bool impassable , QueryID askID ) override ;
2017-06-06 06:53:51 +02:00
void showMapObjectSelectDialog ( QueryID askID , const Component & icon , const MetaString & title , const MetaString & description , const std : : vector < ObjectInstanceID > & objects ) override ;
2018-07-26 12:06:55 +02:00
void saveGame ( BinarySerializer & h , const int version ) override ; //saving
void loadGame ( BinaryDeserializer & h , const int version ) override ; //loading
void finish ( ) override ;
void availableCreaturesChanged ( const CGDwelling * town ) override ;
void heroMoved ( const TryMoveHero & details ) override ;
void heroInGarrisonChange ( const CGTownInstance * town ) override ;
void centerView ( int3 pos , int focusTime ) override ;
void tileHidden ( const std : : unordered_set < int3 , ShashInt3 > & pos ) override ;
void artifactMoved ( const ArtifactLocation & src , const ArtifactLocation & dst ) override ;
void artifactAssembled ( const ArtifactLocation & al ) override ;
void showTavernWindow ( const CGObjectInstance * townOrTavern ) override ;
void showThievesGuildWindow ( const CGObjectInstance * obj ) override ;
void playerBlocked ( int reason , bool start ) override ;
void showPuzzleMap ( ) override ;
void showShipyardDialog ( const IShipyard * obj ) override ;
void gameOver ( PlayerColor player , const EVictoryLossCheckResult & victoryLossCheckResult ) override ;
void artifactPut ( const ArtifactLocation & al ) override ;
void artifactRemoved ( const ArtifactLocation & al ) override ;
void artifactDisassembled ( const ArtifactLocation & al ) override ;
void heroVisit ( const CGHeroInstance * visitor , const CGObjectInstance * visitedObj , bool start ) override ;
void availableArtifactsChanged ( const CGBlackMarket * bm = nullptr ) override ;
void heroVisitsTown ( const CGHeroInstance * hero , const CGTownInstance * town ) override ;
void tileRevealed ( const std : : unordered_set < int3 , ShashInt3 > & pos ) override ;
void heroExchangeStarted ( ObjectInstanceID hero1 , ObjectInstanceID hero2 , QueryID query ) override ;
void heroPrimarySkillChanged ( const CGHeroInstance * hero , int which , si64 val ) override ;
void showRecruitmentDialog ( const CGDwelling * dwelling , const CArmedInstance * dst , int level ) override ;
void heroMovePointsChanged ( const CGHeroInstance * hero ) override ;
void garrisonsChanged ( ObjectInstanceID id1 , ObjectInstanceID id2 ) override ;
void newObject ( const CGObjectInstance * obj ) override ;
void showHillFortWindow ( const CGObjectInstance * object , const CGHeroInstance * visitor ) override ;
void playerBonusChanged ( const Bonus & bonus , bool gain ) override ;
void heroCreated ( const CGHeroInstance * ) override ;
void advmapSpellCast ( const CGHeroInstance * caster , int spellID ) override ;
void showInfoDialog ( const std : : string & text , const std : : vector < Component > & components , int soundID ) override ;
void requestRealized ( PackageApplied * pa ) override ;
void receivedResource ( ) override ;
void objectRemoved ( const CGObjectInstance * obj ) override ;
void showUniversityWindow ( const IMarket * market , const CGHeroInstance * visitor ) override ;
void heroManaPointsChanged ( const CGHeroInstance * hero ) override ;
void heroSecondarySkillChanged ( const CGHeroInstance * hero , int which , int val ) override ;
void battleResultsApplied ( ) override ;
void objectPropertyChanged ( const SetObjectProperty * sop ) override ;
void buildChanged ( const CGTownInstance * town , BuildingID buildingID , int what ) override ;
void heroBonusChanged ( const CGHeroInstance * hero , const Bonus & bonus , bool gain ) override ;
void showMarketWindow ( const IMarket * market , const CGHeroInstance * visitor ) override ;
2016-11-26 14:14:43 +02:00
void showWorldViewEx ( const std : : vector < ObjectPosInfo > & objectPositions ) override ;
2013-06-26 14:18:27 +03:00
2018-07-26 12:06:55 +02:00
void battleStart ( const CCreatureSet * army1 , const CCreatureSet * army2 , int3 tile , const CGHeroInstance * hero1 , const CGHeroInstance * hero2 , bool side ) override ;
void battleEnd ( const BattleResult * br ) override ;
2012-02-14 21:04:45 +03:00
2018-07-26 12:06:55 +02:00
void makeTurn ( ) ;
2012-02-14 21:04:45 +03:00
void makeTurnInternal ( ) ;
void performTypicalActions ( ) ;
void buildArmyIn ( const CGTownInstance * t ) ;
2013-11-23 15:30:10 +03:00
void striveToGoal ( Goals : : TSubgoal ultimateGoal ) ;
2013-11-24 18:30:17 +03:00
Goals : : TSubgoal striveToGoalInternal ( Goals : : TSubgoal ultimateGoal , bool onlyAbstract ) ;
2012-02-14 21:04:45 +03:00
void endTurn ( ) ;
2012-07-01 02:48:40 +03:00
void wander ( HeroPtr h ) ;
2013-11-23 21:16:25 +03:00
void setGoal ( HeroPtr h , Goals : : TSubgoal goal ) ;
2016-11-27 19:10:20 +02:00
void evaluateGoal ( HeroPtr h ) ; //evaluates goal assigned to hero, if any
2018-04-07 10:44:14 +02:00
void completeGoal ( Goals : : TSubgoal goal ) ; //safely removes goal from reserved hero
void striveToQuest ( const QuestInfo & q ) ;
2012-02-14 21:04:45 +03:00
2013-02-09 20:37:38 +03:00
void recruitHero ( const CGTownInstance * t , bool throwing = false ) ;
2018-04-07 10:44:14 +02:00
bool isGoodForVisit ( const CGObjectInstance * obj , HeroPtr h , SectorMap & sm ) ;
2012-03-05 22:11:28 +03:00
//void recruitCreatures(const CGTownInstance * t);
2014-09-19 00:18:49 +03:00
void recruitCreatures ( const CGDwelling * d , const CArmedInstance * recruiter ) ;
2018-04-07 10:44:14 +02:00
bool canGetArmy ( const CGHeroInstance * h , const CGHeroInstance * source ) ; //can we get any better stacks from other hero?
2012-03-06 21:49:23 +03:00
void pickBestCreatures ( const CArmedInstance * army , const CArmedInstance * source ) ; //called when we can't find a slot for new stack
2015-04-07 22:48:35 +02:00
void pickBestArtifacts ( const CGHeroInstance * h , const CGHeroInstance * other = nullptr ) ;
2012-02-14 21:04:45 +03:00
void moveCreaturesToHero ( const CGTownInstance * t ) ;
2012-07-01 02:48:40 +03:00
bool goVisitObj ( const CGObjectInstance * obj , HeroPtr h ) ;
void performObjectInteraction ( const CGObjectInstance * obj , HeroPtr h ) ;
bool moveHeroToTile ( int3 dst , HeroPtr h ) ;
2012-02-14 21:04:45 +03:00
2012-07-01 02:48:40 +03:00
void lostHero ( HeroPtr h ) ; //should remove all references to hero (assigned tasks and so on)
2012-02-14 21:04:45 +03:00
void waitTillFree ( ) ;
2018-04-07 10:44:14 +02:00
void addVisitableObj ( const CGObjectInstance * obj ) ;
void markObjectVisited ( const CGObjectInstance * obj ) ;
void reserveObject ( HeroPtr h , const CGObjectInstance * obj ) ; //TODO: reserve all objects that heroes attempt to visit
void unreserveObject ( HeroPtr h , const CGObjectInstance * obj ) ;
2014-03-23 19:00:43 +03:00
2018-04-07 10:44:14 +02:00
void markHeroUnableToExplore ( HeroPtr h ) ;
void markHeroAbleToExplore ( HeroPtr h ) ;
bool isAbleToExplore ( HeroPtr h ) ;
2015-10-26 17:38:17 +02:00
void clearPathsInfo ( ) ;
2014-03-23 19:00:43 +03:00
2018-04-07 10:44:14 +02:00
void validateObject ( const CGObjectInstance * obj ) ; //checks if object is still visible and if not, removes references to it
2013-04-21 15:11:13 +03:00
void validateObject ( ObjectIdRef obj ) ; //checks if object is still visible and if not, removes references to it
2012-02-14 21:04:45 +03:00
void validateVisitableObjs ( ) ;
2018-04-07 10:44:14 +02:00
void retrieveVisitableObjs ( std : : vector < const CGObjectInstance * > & out , bool includeOwned = false ) const ;
2018-02-10 20:52:23 +02:00
void retrieveVisitableObjs ( ) ;
2018-07-26 12:06:55 +02:00
virtual std : : vector < const CGObjectInstance * > getFlaggedObjects ( ) const ;
2012-02-14 21:04:45 +03:00
2018-04-07 10:44:14 +02:00
const CGObjectInstance * lookForArt ( int aid ) const ;
bool isAccessible ( const int3 & pos ) ;
2012-07-01 02:48:40 +03:00
HeroPtr getHeroWithGrail ( ) const ;
2012-02-16 20:10:58 +03:00
2018-04-07 10:44:14 +02:00
const CGObjectInstance * getUnvisitedObj ( const std : : function < bool ( const CGObjectInstance * ) > & predicate ) ;
2012-07-01 02:48:40 +03:00
bool isAccessibleForHero ( const int3 & pos , HeroPtr h , bool includeAllies = false ) const ;
2015-10-26 17:38:17 +02:00
//optimization - use one SM for every hero call
2015-12-04 00:10:51 +02:00
std : : shared_ptr < SectorMap > getCachedSectorMap ( HeroPtr h ) ;
2012-02-14 21:04:45 +03:00
2018-04-07 10:44:14 +02:00
const CGTownInstance * findTownWithTavern ( ) const ;
2013-12-19 23:21:21 +03:00
bool canRecruitAnyHero ( const CGTownInstance * t = NULL ) const ;
2012-02-14 21:04:45 +03:00
2018-04-07 10:44:14 +02:00
Goals : : TSubgoal getGoal ( HeroPtr h ) const ;
2013-12-28 15:47:55 +03:00
bool canAct ( HeroPtr h ) const ;
2012-07-01 02:48:40 +03:00
std : : vector < HeroPtr > getUnblockedHeroes ( ) const ;
HeroPtr primaryHero ( ) const ;
2018-04-07 10:44:14 +02:00
void checkHeroArmy ( HeroPtr h ) ;
2012-03-26 01:46:14 +03:00
2018-04-07 10:44:14 +02:00
void requestSent ( const CPackForServer * pack , int requestID ) override ;
2013-05-27 13:53:28 +03:00
void answerQuery ( QueryID queryID , int selection ) ;
2012-03-26 01:46:14 +03:00
//special function that can be called ONLY from game events handling thread and will send request ASAP
2016-11-26 14:14:43 +02:00
void requestActionASAP ( std : : function < void ( ) > whatToDo ) ;
2013-05-09 14:09:23 +03:00
2018-02-25 09:31:17 +02:00
#if 0
//disabled due to issue 2890
2018-04-07 10:44:14 +02:00
template < typename Handler > void registerGoals ( Handler & h )
2014-02-20 23:18:49 +03:00
{
2014-02-21 15:27:56 +03:00
//h.template registerType<Goals::AbstractGoal, Goals::BoostHero>();
h . template registerType < Goals : : AbstractGoal , Goals : : Build > ( ) ;
h . template registerType < Goals : : AbstractGoal , Goals : : BuildThis > ( ) ;
//h.template registerType<Goals::AbstractGoal, Goals::CIssueCommand>();
h . template registerType < Goals : : AbstractGoal , Goals : : ClearWayTo > ( ) ;
h . template registerType < Goals : : AbstractGoal , Goals : : CollectRes > ( ) ;
h . template registerType < Goals : : AbstractGoal , Goals : : Conquer > ( ) ;
h . template registerType < Goals : : AbstractGoal , Goals : : DigAtTile > ( ) ;
h . template registerType < Goals : : AbstractGoal , Goals : : Explore > ( ) ;
h . template registerType < Goals : : AbstractGoal , Goals : : FindObj > ( ) ;
h . template registerType < Goals : : AbstractGoal , Goals : : GatherArmy > ( ) ;
h . template registerType < Goals : : AbstractGoal , Goals : : GatherTroops > ( ) ;
h . template registerType < Goals : : AbstractGoal , Goals : : GetArtOfType > ( ) ;
h . template registerType < Goals : : AbstractGoal , Goals : : GetObj > ( ) ;
h . template registerType < Goals : : AbstractGoal , Goals : : Invalid > ( ) ;
//h.template registerType<Goals::AbstractGoal, Goals::NotLose>();
h . template registerType < Goals : : AbstractGoal , Goals : : RecruitHero > ( ) ;
h . template registerType < Goals : : AbstractGoal , Goals : : VisitHero > ( ) ;
h . template registerType < Goals : : AbstractGoal , Goals : : VisitTile > ( ) ;
h . template registerType < Goals : : AbstractGoal , Goals : : Win > ( ) ;
2014-02-20 23:18:49 +03:00
}
2018-02-25 09:31:17 +02:00
# endif
2013-05-09 14:09:23 +03:00
2018-04-07 10:44:14 +02:00
template < typename Handler > void serializeInternal ( Handler & h , const int version )
2013-05-09 14:09:23 +03:00
{
2017-07-31 15:35:42 +02:00
h & knownTeleportChannels ;
h & knownSubterraneanGates ;
h & destinationTeleport ;
h & townVisitsThisWeek ;
2018-02-25 09:31:17 +02:00
#if 0
//disabled due to issue 2890
2017-07-31 15:35:42 +02:00
h & lockedHeroes ;
2018-02-25 09:31:17 +02:00
# else
{
ui32 length = 0 ;
h & length ;
if ( ! h . saving )
{
std : : set < ui32 > loadedPointers ;
lockedHeroes . clear ( ) ;
for ( ui32 index = 0 ; index < length ; index + + )
{
HeroPtr ignored1 ;
h & ignored1 ;
ui8 flag = 0 ;
h & flag ;
if ( flag )
{
ui32 pid = 0xffffffff ;
h & pid ;
if ( ! vstd : : contains ( loadedPointers , pid ) )
{
loadedPointers . insert ( pid ) ;
ui16 typeId = 0 ;
//this is the problem requires such hack
//we have to explicitly ignore invalid goal class type id
h & typeId ;
Goals : : AbstractGoal ignored2 ;
ignored2 . serialize ( h , version ) ;
}
}
}
}
}
# endif
2017-07-31 15:35:42 +02:00
h & reservedHeroesMap ; //FIXME: cannot instantiate abstract class
h & visitableObjs ;
h & alreadyVisited ;
h & reservedObjs ;
2018-07-26 12:06:55 +02:00
if ( version < 788 & & ! h . saving )
{
TResources saving ;
h & saving ; //mind the ambiguity
}
2017-07-31 15:35:42 +02:00
h & status ;
h & battlename ;
2014-03-23 19:00:43 +03:00
h & heroesUnableToExplore ;
2013-05-09 14:09:23 +03:00
//myCB is restored after load by init call
}
2012-02-14 21:04:45 +03:00
} ;
2012-10-03 12:29:55 +03:00
class cannotFulfillGoalException : public std : : exception
{
std : : string msg ;
2018-04-07 10:44:14 +02:00
2012-10-03 12:29:55 +03:00
public :
2018-04-07 10:44:14 +02:00
explicit cannotFulfillGoalException ( crstring _Message )
: msg ( _Message )
2012-10-03 12:29:55 +03:00
{
}
virtual ~ cannotFulfillGoalException ( ) throw ( )
{
} ;
2018-04-07 10:44:14 +02:00
const char * what ( ) const throw ( ) override
2012-10-03 12:29:55 +03:00
{
return msg . c_str ( ) ;
}
} ;
2018-04-07 10:44:14 +02:00
2012-10-03 12:29:55 +03:00
class goalFulfilledException : public std : : exception
{
2016-11-26 18:41:34 +02:00
std : : string msg ;
2018-04-07 10:44:14 +02:00
2012-10-03 12:29:55 +03:00
public :
2013-11-23 21:16:25 +03:00
Goals : : TSubgoal goal ;
2012-10-03 12:29:55 +03:00
2018-04-07 10:44:14 +02:00
explicit goalFulfilledException ( Goals : : TSubgoal Goal )
: goal ( Goal )
2012-10-03 12:29:55 +03:00
{
2016-11-26 18:41:34 +02:00
msg = goal - > name ( ) ;
2012-10-03 12:29:55 +03:00
}
virtual ~ goalFulfilledException ( ) throw ( )
{
} ;
2018-04-07 10:44:14 +02:00
const char * what ( ) const throw ( ) override
2012-10-03 12:29:55 +03:00
{
2016-11-26 18:41:34 +02:00
return msg . c_str ( ) ;
2012-10-03 12:29:55 +03:00
}
} ;
2012-02-14 21:04:45 +03:00
2018-04-07 10:44:14 +02:00
void makePossibleUpgrades ( const CArmedInstance * obj ) ;