diff --git a/AI/GeniusAI/BattleLogic.cpp b/AI/GeniusAI/BattleLogic.cpp index 892bac132..66bcf6062 100644 --- a/AI/GeniusAI/BattleLogic.cpp +++ b/AI/GeniusAI/BattleLogic.cpp @@ -215,7 +215,7 @@ void CBattleLogic::MakeStatistics(int currentCreatureId) (float)totalHitPoints / (float)totalEnemyHitPoints < 0.5f) { m_bEnemyDominates = true; - MsgBox("** EnemyDominates!"); + DbgBox("** EnemyDominates!"); } else { @@ -261,11 +261,11 @@ BattleAction CBattleLogic::MakeDecision(int stackID) { creatures = PerformDefaultAction(stackID, additionalInfo); } - /* - std::string message("Creature will be attacked - "); + + /*std::string message("Creature will be attacked - "); message += boost::lexical_cast(creature_to_attack); - MsgBox(message.c_str()); - */ + DbgBox(message.c_str());*/ + if (additionalInfo == -1 || creatures.empty()) { @@ -288,7 +288,9 @@ BattleAction CBattleLogic::MakeDecision(int stackID) } else { +#if defined PRINT_DEBUG PrintBattleAction(ba); +#endif return ba; } } @@ -567,7 +569,9 @@ BattleAction CBattleLogic::MakeAttack(int attackerID, int destinationID) { ba.additionalInfo = dest_tile; ba.actionType = action_walk_and_attack; +#if defined PRINT_DEBUG PrintBattleAction(ba); +#endif return ba; } } @@ -578,7 +582,7 @@ BattleAction CBattleLogic::MakeAttack(int attackerID, int destinationID) { // attack! ba.actionType = action_walk_and_attack; -#if defined _DEBUG +#if defined PRINT_DEBUG PrintBattleAction(ba); #endif return ba; @@ -594,12 +598,12 @@ BattleAction CBattleLogic::MakeAttack(int attackerID, int destinationID) message = "Attacker position X="; message += boost::lexical_cast(m_battleHelper.DecodeXPosition(nearest_pos)) + ", Y="; message += boost::lexical_cast(m_battleHelper.DecodeYPosition(nearest_pos)); - MsgBox(message.c_str()); + DbgBox(message.c_str()); ba.actionType = action_walk; ba.destinationTile = (ui16)nearest_pos; ba.additionalInfo = -1; -#if defined _DEBUG +#if defined PRINT_DEBUG PrintBattleAction(ba); #endif return ba; diff --git a/AI/GeniusAI/CGeniusAI.cpp b/AI/GeniusAI/CGeniusAI.cpp index fbbb3f0e1..931068df6 100644 --- a/AI/GeniusAI/CGeniusAI.cpp +++ b/AI/GeniusAI/CGeniusAI.cpp @@ -8,9 +8,11 @@ using namespace GeniusAI; #include #endif -void MsgBox(const char *msg, bool messageBox) +void DbgBox(const char *msg, bool messageBox) { +#if defined PRINT_DEBUG #if defined _DEBUG +//#if 0 # if defined (_MSC_VER) && (_MSC_VER >= 1020) if (messageBox) { @@ -19,10 +21,11 @@ void MsgBox(const char *msg, bool messageBox) # endif std::cout << msg << std::endl; #endif +#endif } CGeniusAI::CGeniusAI() - : m_generalAI(),turn(0) + : m_generalAI(),turn(0),firstTurn(true) { } @@ -40,7 +43,7 @@ void CGeniusAI::init(ICallback *CB) serialID = m_cb->getMySerial(); std::string info = std::string("GeniusAI initialized for player ") + boost::lexical_cast(playerID); m_battleLogic = NULL; - MsgBox(info.c_str()); + DbgBox(info.c_str()); } unsigned long randomFromInt(unsigned long in) @@ -48,79 +51,10 @@ unsigned long randomFromInt(unsigned long in) return (in*214013+2531011); } -void CGeniusAI::doHero(const CGHeroInstance * h) + +void CGeniusAI::reportResources() { - - - if(!h==NULL) - { - int3 destination, pos; - pos=h->convertPosition(h->pos,false); - - vector buildingPath; - - int movement = h->movement; - int usedMovement = 0; - int attempts = 0; - CPath path; - do{ - do{ - destination=pos; - attempts++; - destination.x+=randomFromInt((attempts*1243)+turn)%9-4; - destination.y+=randomFromInt((attempts*1243)+turn+1234)%9-4; - }while((!m_cb->getPath(pos,destination,h,path)||(path.nodes[0].dist>=(movement-usedMovement))) && attempts<100); - - if(attempts<100) - { - pos = destination; - usedMovement += path.nodes[0].dist; - path.convert(0); - for(int i = path.nodes.size()-2;i>=0;i--) - buildingPath.push_back(path.nodes[i].coord); - } - else break; - }while(movement-usedMovement>=50); - - for(int i = 0; i < buildingPath.size();i++) - { - m_cb->moveHero(h,buildingPath[i]); - //std::cout << "(" << buildingPath[i].x << ", " << buildingPath[i].y << ")" << std::endl; - } - - } - -} - -void CGeniusAI::doTown(const CGTownInstance * t) -{ - if(m_cb->howManyHeroes(true)<3) //recrute up to 3 heroes - { - if(t->visitingHero==NULL) - { - std::vector toBuy = m_cb->getAvailableHeroes(t); - if(toBuy[0]->army.slots.size()>1)//only buy heros with units - { - m_cb->recruitHero(t,toBuy[0]); - } - } - - } - -// m_cb->recruitCreatures(t, ui32 ID, ui32 amount) - - -} - - -void CGeniusAI::yourTurn() -{ - //static boost::mutex mutex; - //boost::mutex::scoped_lock scoped_lock(mutex); - turn++; - std::cout << "AI Player " <getMySerial()<< " with " << m_cb->howManyHeroes(true) << " heroes. " << std::endl; - std::cout << m_cb->getResourceAmount(0) << " wood. "; std::cout << m_cb->getResourceAmount(1) << " mercury. "; @@ -130,17 +64,171 @@ void CGeniusAI::yourTurn() std::cout << m_cb->getResourceAmount(5) << " gems. "; std::cout << m_cb->getResourceAmount(6) << " gold."; std::cout << std::endl; +} + +void CGeniusAI::addHeroObjectives(CGeniusAI::HypotheticalGameState::HeroModel &h, CGeniusAI::HypotheticalGameState &hgs) +{ + int3 hpos, destination; + CPath path; + hpos = h.pos; + int movement = h.remainingMovement; + for(std::set::const_iterator i = hgs.knownVisitableObjects.begin(); i != hgs.knownVisitableObjects.end();i++) + { + if(i->o->ID==54||i->o->ID==34) //creatures, another hero + continue; + + if(i->o->getOwner()==m_cb->getMyColor()) + continue; + + destination = i->o->getSightCenter(); + if(hpos.z==destination.z) + if(m_cb->getPath(hpos,destination,h.h,path)) + { + path.convert(0); + if(path.nodes[0].disto,&h); + std::set::iterator found = currentHeroObjectives.find(ho); + if(found==currentHeroObjectives.end()) + currentHeroObjectives.insert(ho); + else + found->whoCanAchieve.push_back(&h); + } + } + } +} +void CGeniusAI::addTownObjectives(HypotheticalGameState::TownModel &t, HypotheticalGameState & hgs) +{ + //recruitHero + //recruitCreatures + //upgradeCreatures + //buildBuilding + + if(hgs.heroModels.size()<3) //recruitHero + { + if(!t.visitingHero) + { + for(int i =0; i < hgs.AvailableHeroesToBuy.size();i++) + if(hgs.AvailableHeroesToBuy[i]->army.slots.size()>1)//only buy heros with units + { + TownObjective to(AIObjective::recruitHero,&t,0); + currentTownObjectives.insert(to); + } + + } + } + + +// for(int i = 0; i < t.t->creatures.size() ;i++) +// { +// int ID = t.t->creatures[i].second.back(); +// CCreature +// cout << "town has " << t.t->creatures[i].first << " level " << i+1 << " " << creature->namePl << endl; +// } + - std::vector < const CGHeroInstance *> heroes = m_cb->getHeroesInfo(); - for(std::vector < const CGHeroInstance *>::iterator i = heroes.begin(); i < heroes.end(); i++) - doHero(*i); +} -// std::vector < const CGTownInstance *> towns = m_cb->getTownsInfo(); -// for(std::vector < const CGTownInstance *>::iterator i = towns.begin(); i < towns.end(); i++) -// doTown(*i); +void CGeniusAI::TownObjective::fulfill(CGeniusAI & cg, HypotheticalGameState & hgs) +{ + switch(type) + { + case recruitHero: + cg.m_cb->recruitHero(whichTown->t,hgs.AvailableHeroesToBuy[which]); + hgs.heroModels.push_back(hgs.AvailableHeroesToBuy[which]); + whichTown->visitingHero = true; + //TODO: sub 2500 gold from hgs here + } +} +void CGeniusAI::getObjectives(CGeniusAI::HypotheticalGameState & hgs) +{ + currentHeroObjectives.clear(); + currentTownObjectives.clear(); + + for(std::vector ::iterator i = hgs.heroModels.begin(); i != hgs.heroModels.end(); i++) + addHeroObjectives(*i,hgs); + + for(std::vector ::iterator i = hgs.townModels.begin(); i != hgs.townModels.end(); i++) + addTownObjectives(*i,hgs); +} + +void CGeniusAI::HeroObjective::fulfill(CGeniusAI & cg, HypotheticalGameState & hgs) +{ + switch(type) + { + case visit: + HypotheticalGameState::HeroModel * h = whoCanAchieve[rand()%whoCanAchieve.size()]; + int3 hpos, destination; + CPath path; + hpos = h->pos; + //std::cout << "trying to visit " << object->hoverName << std::endl; + + destination = object->getSightCenter(); + if(cg.m_cb->getPath(hpos,destination,h->h,path)) + { + path.convert(0); + for(int i = path.nodes.size()-2;i>=0;i--) + cg.m_cb->moveHero(h->h,path.nodes[i].coord); + h->remainingMovement-=path.nodes[0].dist; + if(object->blockVisit) + h->pos = path.nodes[1].coord; + else + h->pos=destination; + std::set::iterator i = hgs.knownVisitableObjects.find(AIObjectContainer(object)); + if(i!=hgs.knownVisitableObjects.end()) + hgs.knownVisitableObjects.erase(i); + } + } +} + + +void CGeniusAI::yourTurn() +{ + static int seed = rand(); + srand(seed); + if(firstTurn) + { + //m_cb->sendMessage("vcmieagles"); + firstTurn = false; + + + } + knownVisitableObjects.clear(); + int3 pos = m_cb->getMapSize(); + for(int x = 0;x AIObjectiveQueue; + do{ + + //std::cout << "I have " << currentHeroObjectives.size() << " things I could do with my heroes!" << std::endl; + //std::cout << "I have " << currentTownObjectives.size() << " things I could do with my towns!" << std::endl; + + AIObjectiveQueue.clear(); + for(std::set::iterator i = currentHeroObjectives.begin(); i != currentHeroObjectives.end(); i++) + AIObjectiveQueue.push_back(AIObjectivePtrCont(&(*i))); + for(std::set::iterator i = currentTownObjectives.begin(); i != currentTownObjectives.end(); i++) + AIObjectiveQueue.push_back(AIObjectivePtrCont(&(*i))); + if(!AIObjectiveQueue.empty()) + max_element(AIObjectiveQueue.begin(),AIObjectiveQueue.end())->obj->fulfill(*this, hgs); + + getObjectives(hgs); + + }while(!currentHeroObjectives.empty()); + + + seed = rand(); m_cb->endTurn(); } @@ -154,12 +242,24 @@ void CGeniusAI::heroCreated(const CGHeroInstance *hero) } +void CGeniusAI::tileRevealed(int3 pos) +{ + std::vector < const CGObjectInstance * > objects = m_cb->getVisitableObjs(pos); + for(std::vector < const CGObjectInstance * >::iterator o = objects.begin();o!=objects.end();o++) + knownVisitableObjects.insert(*o); + objects = m_cb->getFlaggableObjects(pos); + for(std::vector < const CGObjectInstance * >::iterator o = objects.begin();o!=objects.end();o++) + knownVisitableObjects.insert(*o); +} + +void CGeniusAI::tileHidden(int3 pos) +{ + +} + void CGeniusAI::heroMoved(const TryMoveHero &TMH) { - MsgBox("** CGeniusAI::heroMoved **"); - - - + DbgBox("** CGeniusAI::heroMoved **"); } void CGeniusAI::heroGotLevel(const CGHeroInstance *hero, int pskill, std::vector &skills, boost::function &callback) @@ -187,7 +287,7 @@ void CGeniusAI::actionFinished(const BattleAction *action) message += "), side("; message += boost::lexical_cast((unsigned)action->side); message += ")"; - MsgBox(message.c_str()); + DbgBox(message.c_str()); } /** * occurs BEFORE every action taken by any stack or by the hero @@ -199,21 +299,21 @@ void CGeniusAI::actionStarted(const BattleAction *action) message += "), side("; message += boost::lexical_cast((unsigned)action->side); message += ")"; - MsgBox(message.c_str()); + DbgBox(message.c_str()); } /** * called when stack is performing attack */ void CGeniusAI::battleAttack(BattleAttack *ba) { - MsgBox("\t\t\tCGeniusAI::battleAttack"); + DbgBox("\t\t\tCGeniusAI::battleAttack"); } /** * called when stack receives damage (after battleAttack()) */ void CGeniusAI::battleStacksAttacked(std::set & bsa) { - MsgBox("\t\t\tCGeniusAI::battleStacksAttacked"); + DbgBox("\t\t\tCGeniusAI::battleStacksAttacked"); } /** * called by engine when battle starts; side=0 - left, side=1 - right @@ -224,7 +324,7 @@ void CGeniusAI::battleStart(CCreatureSet *army1, CCreatureSet *army2, int3 tile, assert(!m_battleLogic); //************** assert fails when AI starts two battles at same time? *************** m_battleLogic = new BattleAI::CBattleLogic(m_cb, army1, army2, tile, hero1, hero2, side); - MsgBox("** CGeniusAI::battleStart **"); + DbgBox("** CGeniusAI::battleStart **"); } /** * @@ -241,7 +341,7 @@ void CGeniusAI::battleEnd(BattleResult *br) delete m_battleLogic; m_battleLogic = NULL; - MsgBox("** CGeniusAI::battleEnd **"); + DbgBox("** CGeniusAI::battleEnd **"); } /** * called at the beggining of each turn, round=-1 is the tactic phase, round=0 is the first "normal" turn @@ -250,7 +350,7 @@ void CGeniusAI::battleNewRound(int round) { std::string message("\tCGeniusAI::battleNewRound - "); message += boost::lexical_cast(round); - MsgBox(message.c_str()); + DbgBox(message.c_str()); m_battleLogic->SetCurrentTurn(round); } @@ -264,42 +364,42 @@ void CGeniusAI::battleStackMoved(int ID, int dest, int distance, bool end) message += "), dest("; message += boost::lexical_cast(dest); message += ")"; - MsgBox(message.c_str()); + DbgBox(message.c_str()); } /** * */ void CGeniusAI::battleSpellCast(SpellCast *sc) { - MsgBox("\t\t\tCGeniusAI::battleSpellCast"); + DbgBox("\t\t\tCGeniusAI::battleSpellCast"); } /** * called when battlefield is prepared, prior the battle beginning */ void CGeniusAI::battlefieldPrepared(int battlefieldType, std::vector obstacles) { - MsgBox("CGeniusAI::battlefieldPrepared"); + DbgBox("CGeniusAI::battlefieldPrepared"); } /** * */ void CGeniusAI::battleStackMoved(int ID, int dest, bool startMoving, bool endMoving) { - MsgBox("\t\t\tCGeniusAI::battleStackMoved"); + DbgBox("\t\t\tCGeniusAI::battleStackMoved"); } /** * */ void CGeniusAI::battleStackAttacking(int ID, int dest) { - MsgBox("\t\t\tCGeniusAI::battleStackAttacking"); + DbgBox("\t\t\tCGeniusAI::battleStackAttacking"); } /** * */ void CGeniusAI::battleStackIsAttacked(int ID, int dmg, int killed, int IDby, bool byShooting) { - MsgBox("\t\t\tCGeniusAI::battleStackIsAttacked"); + DbgBox("\t\t\tCGeniusAI::battleStackIsAttacked"); } /** @@ -311,7 +411,7 @@ BattleAction CGeniusAI::activeStack(int stackID) message += boost::lexical_cast(stackID); message += ")"; - MsgBox(message.c_str()); + DbgBox(message.c_str()); return m_battleLogic->MakeDecision(stackID); }; diff --git a/AI/GeniusAI/CGeniusAI.h b/AI/GeniusAI/CGeniusAI.h index f554003b6..29daa4c77 100644 --- a/AI/GeniusAI/CGeniusAI.h +++ b/AI/GeniusAI/CGeniusAI.h @@ -1,55 +1,217 @@ -#ifndef __CGENIUSAI_H__ -#define __CGENIUSAI_H__ - -#include "Common.h" -#include "BattleLogic.h" -#include "GeneralAI.h" -namespace GeniusAI { - -class CGeniusAI : public CGlobalAI -{ -private: - ICallback* m_cb; - GeniusAI::BattleAI::CBattleLogic* m_battleLogic; - GeniusAI::GeneralAI::CGeneralAI m_generalAI; - - void doHero(const CGHeroInstance * h); - void doTown(const CGTownInstance * t); - int turn; - -public: - CGeniusAI(); - virtual ~CGeniusAI(); - - virtual void init(ICallback * CB); - virtual void yourTurn(); - virtual void heroKilled(const CGHeroInstance *); - virtual void heroCreated(const CGHeroInstance *); - virtual void heroMoved(const TryMoveHero &); - virtual void heroPrimarySkillChanged(const CGHeroInstance * hero, int which, int val) {}; - virtual void showSelDialog(std::string text, std::vector & components, int askID){}; - virtual void showBlockingDialog(const std::string &text, const std::vector &components, ui32 askID, const int soundID, bool selection, bool cancel); //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 tileRevealed(int3 pos){}; - virtual void tileHidden(int3 pos){}; - virtual void heroGotLevel(const CGHeroInstance *hero, int pskill, std::vector &skills, boost::function &callback); - virtual void showGarrisonDialog(const CArmedInstance *up, const CGHeroInstance *down, boost::function &onEnd); - // battle - virtual void actionFinished(const BattleAction *action);//occurs AFTER every action taken by any stack or by the hero - virtual void actionStarted(const BattleAction *action);//occurs BEFORE every action taken by any stack or by the hero - virtual void battleAttack(BattleAttack *ba); //called when stack is performing attack - virtual void battleStacksAttacked(std::set & bsa); //called when stack receives damage (after battleAttack()) - virtual void battleEnd(BattleResult *br); - virtual void battleNewRound(int round); //called at the beggining of each turn, round=-1 is the tactic phase, round=0 is the first "normal" turn - virtual void battleStackMoved(int ID, int dest, int distance, bool end); - virtual void battleSpellCast(SpellCast *sc); - virtual void battleStart(CCreatureSet *army1, CCreatureSet *army2, int3 tile, CGHeroInstance *hero1, CGHeroInstance *hero2, bool side); //called by engine when battle starts; side=0 - left, side=1 - right - virtual void battlefieldPrepared(int battlefieldType, std::vector obstacles); //called when battlefield is prepared, prior the battle beginning - // - virtual void battleStackMoved(int ID, int dest, bool startMoving, bool endMoving); - virtual void battleStackAttacking(int ID, int dest); - virtual void battleStackIsAttacked(int ID, int dmg, int killed, int IDby, bool byShooting); - virtual BattleAction activeStack(int stackID); -}; -} - -#endif // __CGENIUSAI_H__ +#ifndef __CGENIUSAI_H__ +#define __CGENIUSAI_H__ + +#include "Common.h" +#include "BattleLogic.h" +#include "GeneralAI.h" +#include "../../lib/VCMI_Lib.h" +#include +#include +#include +namespace GeniusAI { + +class CGeniusAI : public CGlobalAI +{ +private: + ICallback* m_cb; + GeniusAI::BattleAI::CBattleLogic* m_battleLogic; + GeniusAI::GeneralAI::CGeneralAI m_generalAI; + class AIObjectContainer + { + public: + AIObjectContainer(const CGObjectInstance * o):o(o){} + const CGObjectInstance * o; + bool operator<(const AIObjectContainer& b)const + { + if (o->pos!=b.o->pos) + return o->pospos; + return o->idid; + } + }; + std::set< AIObjectContainer > knownVisitableObjects; + + class HypotheticalGameState + { + public: + HypotheticalGameState(CGeniusAI & AI) + :knownVisitableObjects(AI.knownVisitableObjects) + { + std::vector < const CGHeroInstance *> heroes = AI.m_cb->getHeroesInfo(); + for(std::vector < const CGHeroInstance *>::iterator i = heroes.begin(); i != heroes.end(); i++) + heroModels.push_back(HeroModel(*i)); + + std::vector < const CGTownInstance *> towns = AI.m_cb->getTownsInfo(); + for(std::vector < const CGTownInstance *>::iterator i = towns.begin(); i != towns.end(); i++) + townModels.push_back(TownModel(*i)); + + if(AI.m_cb->howManyTowns()!=0) + AvailableHeroesToBuy = AI.m_cb->getAvailableHeroes(AI.m_cb->getTownInfo(0,0)); + } + + class TownModel + { + public: + TownModel(const CGTownInstance *t):t(t){visitingHero=(t->visitingHero!=NULL);} + const CGTownInstance *t; + bool visitingHero; + }; + class HeroModel + { + public: + HeroModel(const CGHeroInstance * h):h(h){ + pos = h->getPosition(false);remainingMovement = h->movement; + } + int3 pos; + int remainingMovement; + const CGHeroInstance * h; + }; + std::vector AvailableHeroesToBuy; + std::vector heroModels; + std::vector townModels; + std::set< AIObjectContainer > knownVisitableObjects; + }; + void addHeroObjectives(HypotheticalGameState::HeroModel &h, HypotheticalGameState & hgs); + void addTownObjectives(HypotheticalGameState::TownModel &h, HypotheticalGameState & hgs); + void getObjectives(HypotheticalGameState & hgs); + void reportResources(); + int turn; + bool firstTurn; + + + class AIObjective + { + public: + enum Type + { + //hero objectives + visit, + attack, + flee, + dismissUnits, + dismissYourself, + finishTurn, //uses up remaining motion to get somewhere nice. + + //town objectives + recruitHero, + recruitCreatures, + upgradeCreatures, + buildBuilding + }; + + Type type; + //virtual bool operator < (const AIObjective &)const=0; + //virtual bool stillPossible(const HypotheticalGameState &)const = 0; + virtual void fulfill(CGeniusAI &,HypotheticalGameState & hgs)=0; + virtual float getValue() const=0; //how much is it worth to the AI to achieve + }; + + class HeroObjective: public AIObjective + { + public: + int3 pos; + const CGObjectInstance * object; + std::vector whoCanAchieve; + + HeroObjective(){} + HeroObjective(Type t):object(NULL){type = t;} + HeroObjective(Type t,const CGObjectInstance * object,HypotheticalGameState::HeroModel *h):object(object) + { + pos = object->pos; + type = t; + whoCanAchieve.push_back(h); + _value = rand(); + } + bool operator < (const HeroObjective &other)const + { + if(type != other.type) + return typeid!=other.object->id) + return object->id < other.object->id; + return false; + } + //bool stillPossible(const HypotheticalGameState &) const; + void fulfill(CGeniusAI &,HypotheticalGameState & hgs); + float getValue() const{return _value;} + private: + float _value; + }; + + //town objectives + //recruitHero, + //recruitCreatures, + //upgradeCreatures, + //buildBuilding + + class TownObjective: public AIObjective + { + public: + HypotheticalGameState::TownModel * whichTown; + int which; //which hero, which building, which creature, + + TownObjective(Type t,HypotheticalGameState::TownModel * tn,int which):whichTown(tn),which(which){type = t;_value = rand();} + + bool operator < (const TownObjective &other)const + { + if(type != other.type) + return typet->id!=other.whichTown->t->id) + return whichTown->t->id < other.whichTown->t->id; + return false; + } + void fulfill(CGeniusAI &,HypotheticalGameState & hgs); + float getValue() const {return _value;} + private: + float _value; + }; + + class AIObjectivePtrCont + { + public: + AIObjectivePtrCont():obj(NULL){} + AIObjectivePtrCont(AIObjective * obj):obj(obj){}; + AIObjective * obj; + bool operator < (const AIObjectivePtrCont & other) const + {return obj->getValue()getValue();} + + }; + std::set currentHeroObjectives; //can be fulfilled right now + std::set currentTownObjectives; + +public: + CGeniusAI(); + virtual ~CGeniusAI(); + + virtual void init(ICallback * CB); + virtual void yourTurn(); + virtual void heroKilled(const CGHeroInstance *); + virtual void heroCreated(const CGHeroInstance *); + virtual void heroMoved(const TryMoveHero &); + virtual void heroPrimarySkillChanged(const CGHeroInstance * hero, int which, int val) {}; + virtual void showSelDialog(std::string text, std::vector & components, int askID){}; + virtual void showBlockingDialog(const std::string &text, const std::vector &components, ui32 askID, const int soundID, bool selection, bool cancel); //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 tileRevealed(int3 pos); + virtual void tileHidden(int3 pos); + virtual void heroGotLevel(const CGHeroInstance *hero, int pskill, std::vector &skills, boost::function &callback); + virtual void showGarrisonDialog(const CArmedInstance *up, const CGHeroInstance *down, boost::function &onEnd); + // battle + virtual void actionFinished(const BattleAction *action);//occurs AFTER every action taken by any stack or by the hero + virtual void actionStarted(const BattleAction *action);//occurs BEFORE every action taken by any stack or by the hero + virtual void battleAttack(BattleAttack *ba); //called when stack is performing attack + virtual void battleStacksAttacked(std::set & bsa); //called when stack receives damage (after battleAttack()) + virtual void battleEnd(BattleResult *br); + virtual void battleNewRound(int round); //called at the beggining of each turn, round=-1 is the tactic phase, round=0 is the first "normal" turn + virtual void battleStackMoved(int ID, int dest, int distance, bool end); + virtual void battleSpellCast(SpellCast *sc); + virtual void battleStart(CCreatureSet *army1, CCreatureSet *army2, int3 tile, CGHeroInstance *hero1, CGHeroInstance *hero2, bool side); //called by engine when battle starts; side=0 - left, side=1 - right + virtual void battlefieldPrepared(int battlefieldType, std::vector obstacles); //called when battlefield is prepared, prior the battle beginning + // + virtual void battleStackMoved(int ID, int dest, bool startMoving, bool endMoving); + virtual void battleStackAttacking(int ID, int dest); + virtual void battleStackIsAttacked(int ID, int dmg, int killed, int IDby, bool byShooting); + virtual BattleAction activeStack(int stackID); +}; +} + +#endif // __CGENIUSAI_H__ diff --git a/AI/GeniusAI/Common.h b/AI/GeniusAI/Common.h index 67f4213de..4b0e7a907 100644 --- a/AI/GeniusAI/Common.h +++ b/AI/GeniusAI/Common.h @@ -11,6 +11,6 @@ #include "../../AI_Base.h" #pragma warning (default: 4100 4244) -void MsgBox(const char *msg, bool messageBox = false); +void DbgBox(const char *msg, bool messageBox = false); #endif/*__GENIUS_COMMON__*/ \ No newline at end of file