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"
2013-05-09 14:09:23 +03:00
# include "../../lib/CDefObjInfoHandler.h"
2012-09-06 13:39:48 +03:00
# 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"
# include "../../lib/CSpellHandler.h"
# include "../../lib/CObjectHandler.h"
# include "../../lib/Connection.h"
# include "../../lib/CGameState.h"
2013-04-07 13:48:07 +03:00
# include "../../lib/mapping/CMap.h"
2012-09-06 13:39:48 +03:00
# include "../../lib/NetPacks.h"
# include "../../lib/CondSh.h"
2013-05-09 14:09:23 +03:00
2013-10-18 23:17:25 +03:00
static const int3 dirs [ ] = { int3 ( 0 , 1 , 0 ) , int3 ( 0 , - 1 , 0 ) , int3 ( - 1 , 0 , 0 ) , int3 ( + 1 , 0 , 0 ) ,
int3 ( 1 , 1 , 0 ) , int3 ( - 1 , 1 , 0 ) , int3 ( 1 , - 1 , 0 ) , int3 ( - 1 , - 1 , 0 ) } ;
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
2013-10-18 23:17:25 +03: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
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)
2013-09-28 02:46:58 +03:00
std : : vector < const CGObjectInstance * > objectsBeingVisited ;
bool ongoingHeroMovement ;
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 ) ;
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 ) ;
2013-09-28 02:46:58 +03:00
void heroVisit ( const CGObjectInstance * obj , bool started ) ;
2013-05-09 14:09:23 +03:00
template < typename Handler > void serialize ( Handler & h , const int version )
{
h & battle & remainingQueries & requestToQueryID & havingTurn ;
}
2012-02-14 21:04:45 +03:00
} ;
enum { NOT_VISIBLE = 0 , NOT_CHECKED = 1 , NOT_AVAILABLE } ;
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
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 ;
}
} ;
bool valid ; //some kind of lazy eval
std : : map < int3 , int3 > parent ;
2012-02-16 20:10:58 +03:00
std : : vector < std : : vector < std : : vector < unsigned char > > > sector ;
//std::vector<std::vector<std::vector<unsigned char>>> pathfinderSector;
2012-02-14 21:04:45 +03:00
std : : map < int , Sector > infoOnSectors ;
SectorMap ( ) ;
2014-02-15 22:39:03 +03:00
SectorMap ( HeroPtr h ) ;
2012-02-14 21:04:45 +03:00
void update ( ) ;
void clear ( ) ;
void exploreNewSector ( crint3 pos , int num ) ;
void write ( crstring fname ) ;
unsigned char & retreiveTile ( crint3 pos ) ;
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?
2012-02-14 21:04:45 +03:00
} ;
2013-12-23 23:46:01 +03:00
//Set of buildings for different goals. Does not include any prerequisites.
const BuildingID essential [ ] = { BuildingID : : TAVERN , BuildingID : : TOWN_HALL } ;
const BuildingID goldSource [ ] = { BuildingID : : TOWN_HALL , BuildingID : : CITY_HALL , BuildingID : : CAPITOL } ;
const BuildingID unitsSource [ ] = { BuildingID : : DWELL_LVL_1 , BuildingID : : DWELL_LVL_2 , BuildingID : : DWELL_LVL_3 ,
BuildingID : : DWELL_LVL_4 , BuildingID : : DWELL_LVL_5 , BuildingID : : DWELL_LVL_6 , BuildingID : : DWELL_LVL_7 } ;
const BuildingID unitsUpgrade [ ] = { BuildingID : : DWELL_LVL_1_UP , BuildingID : : DWELL_LVL_2_UP , BuildingID : : DWELL_LVL_3_UP ,
BuildingID : : DWELL_LVL_4_UP , BuildingID : : DWELL_LVL_5_UP , BuildingID : : DWELL_LVL_6_UP , BuildingID : : DWELL_LVL_7_UP } ;
const BuildingID unitGrowth [ ] = { BuildingID : : FORT , BuildingID : : CITADEL , BuildingID : : CASTLE , BuildingID : : HORDE_1 ,
BuildingID : : HORDE_1_UPGR , BuildingID : : HORDE_2 , BuildingID : : HORDE_2_UPGR } ;
const BuildingID spells [ ] = { BuildingID : : MAGES_GUILD_1 , BuildingID : : MAGES_GUILD_2 , BuildingID : : MAGES_GUILD_3 ,
BuildingID : : MAGES_GUILD_4 , BuildingID : : MAGES_GUILD_5 } ;
const BuildingID extra [ ] = { BuildingID : : RESOURCE_SILO , BuildingID : : SPECIAL_1 , BuildingID : : SPECIAL_2 , BuildingID : : SPECIAL_3 ,
BuildingID : : SPECIAL_4 , BuildingID : : SHIPYARD } ; // all remaining buildings
2012-04-17 15:46:21 +03:00
2012-02-14 21:04:45 +03:00
class VCAI : public CAdventureAI
{
2013-12-23 23:46:01 +03:00
public :
2012-05-19 19:22:34 +03:00
//internal methods for town development
//try build an unbuilt structure in maxDays at most (0 = indefinite)
2013-12-23 23:46:01 +03:00
/*bool canBuildStructure(const CGTownInstance * t, BuildingID building, unsigned int maxDays=7);*/
2013-12-19 20:29:35 +03:00
bool tryBuildStructure ( const CGTownInstance * t , BuildingID building , unsigned int maxDays = 7 ) ;
2012-05-19 19:22:34 +03:00
//try build ANY unbuilt structure
2013-12-23 23:46:01 +03:00
BuildingID canBuildAnyStructure ( const CGTownInstance * t , std : : vector < BuildingID > buildList , unsigned int maxDays = 7 ) ;
2013-12-19 20:29:35 +03:00
bool tryBuildAnyStructure ( const CGTownInstance * t , std : : vector < BuildingID > buildList , unsigned int maxDays = 7 ) ;
2012-05-19 19:22:34 +03:00
//try build first unbuilt structure
2013-12-19 20:29:35 +03:00
bool tryBuildNextStructure ( const CGTownInstance * t , std : : vector < BuildingID > buildList , unsigned int maxDays = 7 ) ;
2012-05-19 19:22:34 +03:00
2012-03-03 13:08:01 +03:00
friend class FuzzyHelper ;
2012-02-14 21:04:45 +03:00
std : : map < const CGObjectInstance * , const CGObjectInstance * > knownSubterraneanGates ;
2013-04-21 15:11:13 +03:00
//std::vector<const CGObjectInstance *> visitedThisWeek; //only OPWs
2013-12-25 16:38:20 +03: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
2013-12-25 16:38:20 +03:00
std : : map < HeroPtr , std : : set < const CGObjectInstance * > > reservedHeroesMap ; //objects reserved by specific heroes
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
TResources saving ;
AIStatus status ;
std : : string battlename ;
2013-06-22 17:47:20 +03:00
shared_ptr < CCallback > myCb ;
2012-02-14 21:04:45 +03:00
2013-05-09 14:09:23 +03:00
unique_ptr < boost : : thread > makingTurn ;
2012-03-05 22:11:28 +03:00
2013-05-09 14:09:23 +03:00
VCAI ( void ) ;
~ VCAI ( void ) ;
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 ) ;
void tryRealize ( Goals : : CollectRes & g ) ;
void tryRealize ( Goals : : Build & g ) ;
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 ) ;
2013-12-23 23:46:01 +03:00
int3 explorationNewPoint ( int radius , HeroPtr h , bool breakUnsafe = false ) ;
2012-02-14 21:04:45 +03:00
void recruitHero ( ) ;
2013-06-26 14:18:27 +03:00
virtual std : : string getBattleAIName ( ) const override ;
virtual void init ( shared_ptr < CCallback > CB ) override ;
virtual void yourTurn ( ) override ;
virtual 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
virtual void commanderGotLevel ( const CCommanderInstance * commander , std : : vector < ui32 > skills , QueryID queryID ) override ; //TODO
virtual 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.
virtual 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
virtual void saveGame ( COSer < CSaveFile > & h , const int version ) override ; //saving
virtual void loadGame ( CISer < CLoadFile > & h , const int version ) override ; //loading
virtual void finish ( ) override ;
virtual void availableCreaturesChanged ( const CGDwelling * town ) override ;
virtual void heroMoved ( const TryMoveHero & details ) override ;
virtual void stackChagedCount ( const StackLocation & location , const TQuantity & change , bool isAbsolute ) override ;
virtual void heroInGarrisonChange ( const CGTownInstance * town ) override ;
virtual void centerView ( int3 pos , int focusTime ) override ;
2013-06-29 16:05:48 +03:00
virtual void tileHidden ( const std : : unordered_set < int3 , ShashInt3 > & pos ) override ;
2013-06-26 14:18:27 +03:00
virtual void artifactMoved ( const ArtifactLocation & src , const ArtifactLocation & dst ) override ;
virtual void artifactAssembled ( const ArtifactLocation & al ) override ;
virtual void showTavernWindow ( const CGObjectInstance * townOrTavern ) override ;
virtual void showThievesGuildWindow ( const CGObjectInstance * obj ) override ;
2013-09-28 02:46:58 +03:00
virtual void playerBlocked ( int reason , bool start ) override ;
2013-06-26 14:18:27 +03:00
virtual void showPuzzleMap ( ) override ;
virtual void showShipyardDialog ( const IShipyard * obj ) override ;
2013-11-17 20:57:04 +03:00
virtual void gameOver ( PlayerColor player , const EVictoryLossCheckResult & victoryLossCheckResult ) override ;
2013-06-26 14:18:27 +03:00
virtual void artifactPut ( const ArtifactLocation & al ) override ;
virtual void artifactRemoved ( const ArtifactLocation & al ) override ;
virtual void stacksErased ( const StackLocation & location ) override ;
virtual void artifactDisassembled ( const ArtifactLocation & al ) override ;
virtual void heroVisit ( const CGHeroInstance * visitor , const CGObjectInstance * visitedObj , bool start ) override ;
virtual void availableArtifactsChanged ( const CGBlackMarket * bm = nullptr ) override ;
virtual void heroVisitsTown ( const CGHeroInstance * hero , const CGTownInstance * town ) override ;
2013-06-29 16:05:48 +03:00
virtual void tileRevealed ( const std : : unordered_set < int3 , ShashInt3 > & pos ) override ;
2013-06-26 14:18:27 +03:00
virtual void heroExchangeStarted ( ObjectInstanceID hero1 , ObjectInstanceID hero2 , QueryID query ) override ;
virtual void heroPrimarySkillChanged ( const CGHeroInstance * hero , int which , si64 val ) override ;
virtual void showRecruitmentDialog ( const CGDwelling * dwelling , const CArmedInstance * dst , int level ) override ;
virtual void heroMovePointsChanged ( const CGHeroInstance * hero ) override ;
virtual void stackChangedType ( const StackLocation & location , const CCreature & newType ) override ;
virtual void stacksRebalanced ( const StackLocation & src , const StackLocation & dst , TQuantity count ) override ;
virtual void newObject ( const CGObjectInstance * obj ) override ;
virtual void showHillFortWindow ( const CGObjectInstance * object , const CGHeroInstance * visitor ) override ;
virtual void playerBonusChanged ( const Bonus & bonus , bool gain ) override ;
virtual void newStackInserted ( const StackLocation & location , const CStackInstance & stack ) override ;
virtual void heroCreated ( const CGHeroInstance * ) override ;
virtual void advmapSpellCast ( const CGHeroInstance * caster , int spellID ) override ;
virtual void showInfoDialog ( const std : : string & text , const std : : vector < Component * > & components , int soundID ) override ;
virtual void requestRealized ( PackageApplied * pa ) override ;
virtual void receivedResource ( int type , int val ) override ;
virtual void stacksSwapped ( const StackLocation & loc1 , const StackLocation & loc2 ) override ;
virtual void objectRemoved ( const CGObjectInstance * obj ) override ;
virtual void showUniversityWindow ( const IMarket * market , const CGHeroInstance * visitor ) override ;
virtual void heroManaPointsChanged ( const CGHeroInstance * hero ) override ;
virtual void heroSecondarySkillChanged ( const CGHeroInstance * hero , int which , int val ) override ;
virtual void battleResultsApplied ( ) override ;
virtual void objectPropertyChanged ( const SetObjectProperty * sop ) override ;
virtual void buildChanged ( const CGTownInstance * town , BuildingID buildingID , int what ) override ;
virtual void heroBonusChanged ( const CGHeroInstance * hero , const Bonus & bonus , bool gain ) override ;
virtual void showMarketWindow ( const IMarket * market , const CGHeroInstance * visitor ) override ;
virtual void battleStart ( const CCreatureSet * army1 , const CCreatureSet * army2 , int3 tile , const CGHeroInstance * hero1 , const CGHeroInstance * hero2 , bool side ) override ;
virtual void battleEnd ( const BattleResult * br ) override ;
2012-02-14 21:04:45 +03:00
void makeTurn ( ) ;
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 ) ;
void completeGoal ( Goals : : TSubgoal goal ) ; //safely removes goal from reserved hero
2012-10-03 12:29:55 +03:00
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 ) ;
2013-12-21 22:17:27 +03:00
bool isGoodForVisit ( const CGObjectInstance * obj , HeroPtr h ) ;
2012-07-01 02:48:40 +03:00
std : : vector < const CGObjectInstance * > getPossibleDestinations ( HeroPtr h ) ;
2012-02-14 21:04:45 +03:00
void buildStructure ( const CGTownInstance * t ) ;
2012-03-05 22:11:28 +03:00
//void recruitCreatures(const CGTownInstance * t);
void recruitCreatures ( const CGDwelling * d ) ;
2012-08-29 12:19:20 +03: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
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 ( ) ;
void addVisitableObj ( const CGObjectInstance * obj ) ;
2012-03-14 16:02:38 +03:00
void markObjectVisited ( const CGObjectInstance * obj ) ;
2013-12-23 23:46:01 +03:00
void reserveObject ( HeroPtr h , const CGObjectInstance * obj ) ; //TODO: reserve all objects that heroes attempt to visit
2012-02-14 21:04:45 +03:00
//void removeVisitableObj(const CGObjectInstance *obj);
2013-04-21 15:11:13 +03:00
void validateObject ( const CGObjectInstance * obj ) ; //checks if object is still visible and if not, removes references to it
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 ( ) ;
void retreiveVisitableObjs ( std : : vector < const CGObjectInstance * > & out , bool includeOwned = false ) const ;
2013-12-25 16:38:20 +03:00
void retreiveVisitableObjs ( std : : set < const CGObjectInstance * > & out , bool includeOwned = false ) const ;
2012-02-14 21:04:45 +03:00
std : : vector < const CGObjectInstance * > getFlaggedObjects ( ) const ;
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
2013-06-26 14:18:27 +03: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 ;
2012-02-14 21:04:45 +03: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
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 ;
2013-09-12 00:57:08 +03:00
TResources freeResources ( ) const ; //owned resources minus gold reserve
2012-02-14 21:04:45 +03:00
TResources estimateIncome ( ) const ;
bool containsSavedRes ( const TResources & cost ) const ;
2012-07-18 13:10:14 +03:00
void checkHeroArmy ( HeroPtr h ) ;
2012-03-26 01:46:14 +03:00
2013-06-26 14:18:27 +03: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
2013-06-26 14:18:27 +03:00
void requestActionASAP ( std : : function < void ( ) > whatToDo ) ;
2013-05-09 14:09:23 +03:00
template < typename Handler > void serializeInternal ( Handler & h , const int version )
{
2014-01-06 17:17:56 +03:00
h & knownSubterraneanGates & townVisitsThisWeek & lockedHeroes & reservedHeroesMap ; //FIXME: cannot instantiate abstract class
2013-05-09 14:09:23 +03:00
h & visitableObjs & alreadyVisited & reservedObjs ;
h & saving & status & battlename ;
//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 ;
public :
explicit cannotFulfillGoalException ( crstring _Message ) : msg ( _Message )
{
}
virtual ~ cannotFulfillGoalException ( ) throw ( )
{
} ;
2013-06-26 14:18:27 +03:00
const char * what ( ) const throw ( ) override
2012-10-03 12:29:55 +03:00
{
return msg . c_str ( ) ;
}
} ;
class goalFulfilledException : public std : : exception
{
public :
2013-11-23 21:16:25 +03:00
Goals : : TSubgoal goal ;
2012-10-03 12:29:55 +03:00
2013-11-23 21:16:25 +03:00
explicit goalFulfilledException ( Goals : : TSubgoal Goal ) : goal ( Goal )
2012-10-03 12:29:55 +03:00
{
}
virtual ~ goalFulfilledException ( ) throw ( )
{
} ;
2013-06-26 14:18:27 +03:00
const char * what ( ) const throw ( ) override
2012-10-03 12:29:55 +03:00
{
2013-11-23 21:16:25 +03:00
return goal - > name ( ) . c_str ( ) ;
2012-10-03 12:29:55 +03:00
}
} ;
2012-02-14 21:04:45 +03:00
2012-10-01 21:25:43 +03:00
void makePossibleUpgrades ( const CArmedInstance * obj ) ;
2013-10-18 23:17:25 +03:00