diff --git a/AI/GeniusAI/BattleLogic.cpp b/AI/GeniusAI/BattleLogic.cpp index 96e1411f5..ffbb70550 100644 --- a/AI/GeniusAI/BattleLogic.cpp +++ b/AI/GeniusAI/BattleLogic.cpp @@ -43,7 +43,7 @@ ui8 side; //who made this action: false - left, true - right player /** * Implementation of CBattleLogic class. */ -CBattleLogic::CBattleLogic(ICallback *cb, const CCreatureSet *army1, const CCreatureSet *army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, bool side) : +CBattleLogic::CBattleLogic(CCallback *cb, const CCreatureSet *army1, const CCreatureSet *army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, bool side) : m_iCurrentTurn(-2), m_bIsAttacker(!side), m_cb(cb), diff --git a/AI/GeniusAI/BattleLogic.h b/AI/GeniusAI/BattleLogic.h index cd704d262..2388ba8ee 100644 --- a/AI/GeniusAI/BattleLogic.h +++ b/AI/GeniusAI/BattleLogic.h @@ -63,7 +63,7 @@ private: int leftHitPoint_for_min; // scenario }; public: - CBattleLogic(ICallback *cb, const CCreatureSet *army1, const CCreatureSet *army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, bool side); + CBattleLogic(CCallback *cb, const CCreatureSet *army1, const CCreatureSet *army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, bool side); ~CBattleLogic(); void SetCurrentTurn(int turn); @@ -76,7 +76,7 @@ private: //BattleInfo m_battleInfo; int m_iCurrentTurn; bool m_bIsAttacker; - ICallback *m_cb; + CCallback *m_cb; const CCreatureSet *m_army1; const CCreatureSet *m_army2; int3 m_tile; diff --git a/AI/GeniusAI/CGeniusAI.cpp b/AI/GeniusAI/CGeniusAI.cpp index 515020530..29fdfaad5 100644 --- a/AI/GeniusAI/CGeniusAI.cpp +++ b/AI/GeniusAI/CGeniusAI.cpp @@ -84,7 +84,7 @@ CGeniusAI::HypotheticalGameState::HypotheticalGameState(CGeniusAI& ai) if (ai.m_cb->howManyTowns() != 0) { AvailableHeroesToBuy = - ai.m_cb->getAvailableHeroes(ai.m_cb->getTownInfo(0,0)); + ai.m_cb->getAvailableHeroes(ai.m_cb->getTownBySerial(0)); } for (int i = 0; i < 8; i++) @@ -126,7 +126,7 @@ void CGeniusAI::HypotheticalGameState::update(CGeniusAI& ai) if (ai.m_cb->howManyTowns()) { - AvailableHeroesToBuy = ai.m_cb->getAvailableHeroes(ai.m_cb->getTownInfo(0,0)); + AvailableHeroesToBuy = ai.m_cb->getAvailableHeroes(ai.m_cb->getTownBySerial(0)); } resourceAmounts.clear(); @@ -317,7 +317,8 @@ float CGeniusAI::TownObjective::getValue() const break; case upgradeCreatures: - UpgradeInfo ui = AI->m_cb->getUpgradeInfo(whichTown->t,which); + UpgradeInfo ui; + AI->m_cb->getUpgradeInfo(whichTown->t,which, ui); ID = whichTown->t->getCreature(which)->idNumber; howMany = whichTown->t->getStackCount(which); @@ -425,7 +426,8 @@ void CGeniusAI::TownObjective::print() const break; // case recruitCreatures. case upgradeCreatures: - UpgradeInfo ui = AI->m_cb->getUpgradeInfo (whichTown->t, which); + UpgradeInfo ui; + AI->m_cb->getUpgradeInfo (whichTown->t, which, ui); ID = whichTown->t->getCreature(which)->idNumber; tlog6 << "upgrade " << VLC->creh->creatures[ID]->namePl; //ui.cost @@ -446,7 +448,7 @@ CGeniusAI::~CGeniusAI() } -void CGeniusAI::init(ICallback *CB) +void CGeniusAI::init(CCallback *CB) { m_cb = CB; m_generalAI.init(CB); @@ -749,7 +751,8 @@ void CGeniusAI::HeroObjective::fulfill(CGeniusAI& cg, HypotheticalGameState& hgs tlog6 << "visiting town" << endl; for (TSlots::const_iterator i = h->h->Slots().begin(); i != h->h->Slots().end(); i++) { // For each hero slot. - UpgradeInfo ui = cg.m_cb->getUpgradeInfo(h->h,i->first); + UpgradeInfo ui; + cg.m_cb->getUpgradeInfo(h->h,i->first, ui); bool canUpgrade = false; if (ui.newID.size() != 0) @@ -878,7 +881,8 @@ void CGeniusAI::addTownObjectives (HypotheticalGameState::TownModel& t, Hypothet // Upgrade creatures. for (TSlots::const_iterator i = t.t->Slots().begin(); i != t.t->Slots().end(); i++) { - UpgradeInfo ui = m_cb->getUpgradeInfo(t.t, i->first); + UpgradeInfo ui; + m_cb->getUpgradeInfo(t.t, i->first, ui); if (ui.newID.size()) { bool canAfford = true; @@ -952,7 +956,8 @@ void CGeniusAI::TownObjective::fulfill(CGeniusAI& cg, break; case upgradeCreatures: - UpgradeInfo ui = cg.m_cb->getUpgradeInfo(whichTown->t, which); + UpgradeInfo ui; + cg.m_cb->getUpgradeInfo(whichTown->t, which, ui); ID = whichTown->t->getCreature(which)->idNumber; newID = ui.newID.back(); // TODO: reduce resources in hgs @@ -1070,8 +1075,8 @@ void CGeniusAI::startFirstTurn() { HypotheticalGameState hgs(*this); - const CGTownInstance * town = m_cb->getTownInfo(0,0); - const CGHeroInstance * heroInst = m_cb->getHeroInfo(0,0); + const CGTownInstance * town = m_cb->getTownBySerial(0); + const CGHeroInstance * heroInst = m_cb->getHeroBySerial(0); TownObjective(hgs, AIObjective::recruitHero, &hgs.townModels.front(), 0, this).fulfill(*this, hgs); diff --git a/AI/GeniusAI/CGeniusAI.h b/AI/GeniusAI/CGeniusAI.h index 477513e14..0a910e5ce 100644 --- a/AI/GeniusAI/CGeniusAI.h +++ b/AI/GeniusAI/CGeniusAI.h @@ -28,7 +28,7 @@ class CGeniusAI : public CGlobalAI { private: // TODO: cb... come back, croach busters!? - ICallback* m_cb; + CCallback* m_cb; geniusai::BattleAI::CBattleLogic* m_battleLogic; geniusai::GeneralAI::CGeneralAI m_generalAI; geniusai::Priorities* m_priorities; @@ -180,7 +180,7 @@ public: CGeniusAI(); virtual ~CGeniusAI(); - virtual void init(ICallback * CB); + virtual void init(CCallback * CB); virtual void yourTurn(); virtual void heroKilled(const CGHeroInstance *); virtual void heroCreated(const CGHeroInstance *); diff --git a/AI/GeniusAI/GeneralAI.cpp b/AI/GeniusAI/GeneralAI.cpp index 47f0d1def..c9dee7984 100644 --- a/AI/GeniusAI/GeneralAI.cpp +++ b/AI/GeniusAI/GeneralAI.cpp @@ -12,7 +12,7 @@ CGeneralAI::~CGeneralAI() { } -void CGeneralAI::init(ICallback *CB) +void CGeneralAI::init(CCallback *CB) { assert(CB != NULL); m_cb = CB; diff --git a/AI/GeniusAI/GeneralAI.h b/AI/GeniusAI/GeneralAI.h index 959b3e871..0a9bb99e5 100644 --- a/AI/GeniusAI/GeneralAI.h +++ b/AI/GeniusAI/GeneralAI.h @@ -11,9 +11,9 @@ namespace geniusai { namespace GeneralAI { CGeneralAI(); ~CGeneralAI(); - void init(ICallback* CB); + void init(CCallback* CB); private: - ICallback *m_cb; + CCallback *m_cb; }; }} diff --git a/AI/StupidAI/StupidAI.cpp b/AI/StupidAI/StupidAI.cpp index c99271bdd..37845c69b 100644 --- a/AI/StupidAI/StupidAI.cpp +++ b/AI/StupidAI/StupidAI.cpp @@ -8,7 +8,7 @@ #include //#include -IBattleCallback * cbc; +CBattleCallback * cbc; CStupidAI::CStupidAI(void) : side(-1), cb(NULL) @@ -22,7 +22,7 @@ CStupidAI::~CStupidAI(void) print("destroyed"); } -void CStupidAI::init( IBattleCallback * CB ) +void CStupidAI::init( CBattleCallback * CB ) { print("init called, saving ptr to IBattleCallback"); cbc = cb = CB; @@ -105,7 +105,7 @@ BattleAction CStupidAI::activeStack( const CStack * stack ) std::vector dists = cb->battleGetDistances(stack); std::vector enemiesShootable, enemiesReachable, enemiesUnreachable; - BOOST_FOREACH(const CStack *s, cb->battleGetStacks(IBattleCallback::ONLY_ENEMY)) + BOOST_FOREACH(const CStack *s, cb->battleGetStacks(CBattleCallback::ONLY_ENEMY)) { if(cb->battleCanShoot(stack, s->position)) { diff --git a/AI/StupidAI/StupidAI.h b/AI/StupidAI/StupidAI.h index 2590de7b4..ea547c378 100644 --- a/AI/StupidAI/StupidAI.h +++ b/AI/StupidAI/StupidAI.h @@ -3,14 +3,14 @@ class CStupidAI : public CBattleGameInterface { int side; - IBattleCallback *cb; + CBattleCallback *cb; void print(const std::string &text) const; public: CStupidAI(void); ~CStupidAI(void); - void init(IBattleCallback * CB) OVERRIDE; + void init(CBattleCallback * CB) OVERRIDE; void actionFinished(const BattleAction *action) OVERRIDE;//occurs AFTER every action taken by any stack or by the hero void actionStarted(const BattleAction *action) OVERRIDE;//occurs BEFORE every action taken by any stack or by the hero BattleAction activeStack(const CStack * stack) OVERRIDE; //called when it's turn of that stack diff --git a/CCallback.cpp b/CCallback.cpp index 3e4109f12..f351bc1a7 100644 --- a/CCallback.cpp +++ b/CCallback.cpp @@ -69,7 +69,6 @@ void CCallback::recruitCreatures(const CGObjectInstance *obj, ui32 ID, ui32 amou sendRequest(&pack); } - bool CCallback::dismissCreature(const CArmedInstance *obj, int stackPos) { if(((player>=0) && obj->tempOwner != player) || (obj->stacksCount()<2 && obj->needsLastStack())) @@ -79,322 +78,20 @@ bool CCallback::dismissCreature(const CArmedInstance *obj, int stackPos) sendRequest(&pack); return true; } + bool CCallback::upgradeCreature(const CArmedInstance *obj, int stackPos, int newID) { UpgradeCreature pack(stackPos,obj->id,newID); sendRequest(&pack); return false; } + void CCallback::endTurn() { tlog5 << "Player " << (unsigned)player << " ended his turn." << std::endl; EndTurn pack; sendRequest(&pack); //report that we ended turn } -UpgradeInfo CCallback::getUpgradeInfo(const CArmedInstance *obj, int stackPos) const -{ - boost::shared_lock lock(*gs->mx); - return gs->getUpgradeInfo(obj->getStack(stackPos)); -} - -const StartInfo * CCallback::getStartInfo() const -{ - boost::shared_lock lock(*gs->mx); - return gs->scenarioOps; -} - -int CCallback::getSpellCost(const CSpell * sp, const CGHeroInstance * caster) const -{ - boost::shared_lock lock(*gs->mx); - - //if there is a battle - if(gs->curB) - return gs->curB->getSpellCost(sp, caster); - - //if there is no battle - return caster->getSpellCost(sp); -} - -int CCallback::estimateSpellDamage(const CSpell * sp, const CGHeroInstance * hero) const -{ - boost::shared_lock lock(*gs->mx); - - if(!gs->curB) //no battle - { - if (hero) //but we see hero's spellbook - return gs->curB->calculateSpellDmg(sp, hero, NULL, hero->getSpellSchoolLevel(sp), hero->getPrimSkillLevel(2)); - else - return 0; //mage guild - } - //gs->getHero(gs->currentPlayer) - const CGHeroInstance * ourHero = gs->curB->heroes[0]->tempOwner == player ? gs->curB->heroes[0] : gs->curB->heroes[1]; - return gs->curB->calculateSpellDmg(sp, ourHero, NULL, ourHero->getSpellSchoolLevel(sp), ourHero->getPrimSkillLevel(2)); -} - -void CCallback::getThievesGuildInfo(SThievesGuildInfo & thi, const CGObjectInstance * obj) -{ - boost::shared_lock lock(*gs->mx); - - if(obj == NULL) - return; - - if(obj->ID == TOWNI_TYPE || obj->ID == 95) //it is a town or adv map tavern - { - gs->obtainPlayersStats(thi, gs->players[player].towns.size()); - } - else if(obj->ID == 97) //Den of Thieves - { - gs->obtainPlayersStats(thi, 20); - } -} - -int CCallback::howManyTowns() const -{ - boost::shared_lock lock(*gs->mx); - return gs->players[player].towns.size(); -} - -const CGTownInstance * CCallback::getTownInfo(int val, bool mode) const //mode = 0 -> val = serial; mode = 1 -> val = ID -{ - boost::shared_lock lock(*gs->mx); - if (!mode) - { - const std::vector > &towns = gs->players[gs->currentPlayer].towns; - if(val < towns.size()) - return towns[val]; - else - return NULL; - } - else if(mode == 1) - { - const CGObjectInstance *obj = getObjectInfo(val); - if(!obj) - return NULL; - if(obj->ID != TOWNI_TYPE) - return NULL; - else - return static_cast(obj); - } - return NULL; -} - -bool CCallback::getTownInfo( const CGObjectInstance *town, InfoAboutTown &dest ) const -{ - if(!isVisible(town, player)) //it's not a town or it's not visible for layer - return false; - - bool detailed = hasAccess(town->tempOwner); - - //TODO vision support - if(town->ID == TOWNI_TYPE) - dest.initFromTown(static_cast(town), detailed); - else if(town->ID == 33 || town->ID == 219) - dest.initFromGarrison(static_cast(town), detailed); - else - return false; - return true; -} - -int3 CCallback::guardingCreaturePosition (int3 pos) const -{ - return gs->guardingCreaturePosition(pos); -} - -int CCallback::howManyHeroes(bool includeGarrisoned) const -{ - boost::shared_lock lock(*gs->mx); - return cl->getHeroCount(player,includeGarrisoned); -} -const CGHeroInstance * CCallback::getHeroInfo(int val, int mode) const //mode = 0 -> val = serial; mode = 1 -> val = ID -{ - boost::shared_lock lock(*gs->mx); //TODO use me? - //if (gs->currentPlayer!=player) //TODO: checking if we are allowed to give that info - // return NULL; - if (!mode) //esrial id - { - if(valplayers[player].heroes.size()) - { - return gs->players[player].heroes[val]; - } - else - { - return NULL; - } - } - else if(mode==1) //it's hero type id - { - for (size_t i=0; i < gs->players[player].heroes.size(); ++i) - { - if (gs->players[player].heroes[i]->type->ID==val) - { - return gs->players[player].heroes[i]; - } - } - } - else //object id - { - return static_cast(gs->map->objects[val].get()); - } - return NULL; -} - -const CGObjectInstance * CCallback::getObjectInfo(int ID) const -{ - //TODO: check for visibility - return gs->map->objects[ID]; -} - -bool CCallback::getHeroInfo( const CGObjectInstance *hero, InfoAboutHero &dest ) const -{ - const CGHeroInstance *h = dynamic_cast(hero); - if(!h || !isVisible(h->getPosition(false))) //it's not a hero or it's not visible for layer - return false; - - //TODO vision support - dest.initFromHero(h, hasAccess(h->tempOwner)); - return true; -} - -int CCallback::getResourceAmount(int type) const -{ - boost::shared_lock lock(*gs->mx); - return gs->players[player].resources[type]; -} -std::vector CCallback::getResourceAmount() const -{ - boost::shared_lock lock(*gs->mx); - return gs->players[player].resources; -} -int CCallback::getDate(int mode) const -{ - boost::shared_lock lock(*gs->mx); - return gs->getDate(mode); -} -std::vector < std::string > CCallback::getObjDescriptions(int3 pos) const -{ - boost::shared_lock lock(*gs->mx); - std::vector ret; - if(!isVisible(pos,player)) - return ret; - BOOST_FOREACH(const CGObjectInstance * obj, gs->map->terrain[pos.x][pos.y][pos.z].blockingObjects) - ret.push_back(obj->getHoverText()); - return ret; -} -bool CCallback::verifyPath(CPath * path, bool blockSea) const -{ - for (size_t i=0; i < path->nodes.size(); ++i) - { - if ( CGI->mh->map->terrain[path->nodes[i].coord.x][path->nodes[i].coord.y][path->nodes[i].coord.z].blocked - && (! (CGI->mh->map->terrain[path->nodes[i].coord.x][path->nodes[i].coord.y][path->nodes[i].coord.z].visitable))) - return false; //path is wrong - one of the tiles is blocked - - if (blockSea) - { - if (i==0) - continue; - - if ( - ((CGI->mh->map->terrain[path->nodes[i].coord.x][path->nodes[i].coord.y][path->nodes[i].coord.z].tertype==TerrainTile::water) - && - (CGI->mh->map->terrain[path->nodes[i-1].coord.x][path->nodes[i-1].coord.y][path->nodes[i-1].coord.z].tertype!=TerrainTile::water)) - || - ((CGI->mh->map->terrain[path->nodes[i].coord.x][path->nodes[i].coord.y][path->nodes[i].coord.z].tertype!=TerrainTile::water) - && - (CGI->mh->map->terrain[path->nodes[i-1].coord.x][path->nodes[i-1].coord.y][path->nodes[i-1].coord.z].tertype==TerrainTile::water)) - || - (CGI->mh->map->terrain[path->nodes[i-1].coord.x][path->nodes[i-1].coord.y][path->nodes[i-1].coord.z].tertype==TerrainTile::rock) - - ) - return false; - } - - - } - return true; -} - -std::vector< std::vector< std::vector > > & CCallback::getVisibilityMap() const -{ - boost::shared_lock lock(*gs->mx); - return gs->getPlayerTeam(player)->fogOfWarMap; -} - - -bool CCallback::isVisible(int3 pos, int Player) const -{ - boost::shared_lock lock(*gs->mx); - return gs->map->isInTheMap(pos) && gs->isVisible(pos, Player); -} - -std::vector < const CGTownInstance *> CCallback::getTownsInfo(bool onlyOur) const -{ - boost::shared_lock lock(*gs->mx); - std::vector < const CGTownInstance *> ret = std::vector < const CGTownInstance *>(); - for ( std::map::iterator i=gs->players.begin() ; i!=gs->players.end();i++) - { - for (size_t j=0; j < (*i).second.towns.size(); ++j) - { - if ((*i).first==player - || (isVisible((*i).second.towns[j],player) && !onlyOur)) - { - ret.push_back((*i).second.towns[j]); - } - } - } // for ( std::map::iterator i=gs->players.begin() ; i!=gs->players.end();i++) - return ret; -} -std::vector < const CGHeroInstance *> CCallback::getHeroesInfo(bool onlyOur) const -{ - boost::shared_lock lock(*gs->mx); - std::vector < const CGHeroInstance *> ret; - for(size_t i=0;imap->heroes.size();i++) - { - if( (gs->map->heroes[i]->tempOwner==player) || - (isVisible(gs->map->heroes[i]->getPosition(false),player) && !onlyOur) ) - { - ret.push_back(gs->map->heroes[i]); - } - } - return ret; -} - -bool CCallback::isVisible(int3 pos) const -{ - boost::shared_lock lock(*gs->mx); - return isVisible(pos,player); -} - -bool CCallback::isVisible( const CGObjectInstance *obj, int Player ) const -{ - return gs->isVisible(obj, Player); -} - -int CCallback::getMyColor() const -{ - return player; -} - -int CCallback::getHeroSerial(const CGHeroInstance * hero) const -{ - boost::shared_lock lock(*gs->mx); - for (size_t i=0; iplayers[player].heroes.size();i++) - { - if (gs->players[player].heroes[i]==hero) - return i; - } - return -1; -} - -const CCreatureSet* CCallback::getGarrison(const CGObjectInstance *obj) const -{ - boost::shared_lock lock(*gs->mx); - const CArmedInstance *armi = dynamic_cast(obj); - if(!armi) - return NULL; - else - return armi; -} - int CCallback::swapCreatures(const CArmedInstance *s1, const CArmedInstance *s2, int p1, int p2) { ArrangeStacks pack(1,p1,p2,s1->id,s2->id,0); @@ -474,41 +171,6 @@ bool CCallback::buildBuilding(const CGTownInstance *town, si32 buildingID) return true; } -int CBattleCallback::battleGetBattlefieldType() -{ - boost::shared_lock lock(*gs->mx); - //return gs->battleGetBattlefieldType(); - - if(!gs->curB) - { - tlog2<<"battleGetBattlefieldType called when there is no battle!"<curB->battlefieldType; -} - -int CBattleCallback::battleGetObstaclesAtTile(THex tile) //returns bitfield -{ - //TODO - write - return -1; -} - -std::vector CBattleCallback::battleGetAllObstacles() -{ - boost::shared_lock lock(*gs->mx); - if(gs->curB) - return gs->curB->obstacles; - else - return std::vector(); -} - -const CStack* CBattleCallback::battleGetStackByID(int ID, bool onlyAlive) -{ - boost::shared_lock lock(*gs->mx); - if(!gs->curB) return NULL; - return gs->curB->getStack(ID, onlyAlive); -} - int CBattleCallback::battleMakeAction(BattleAction* action) { assert(action->actionType == BattleAction::HERO_SPELL); @@ -517,177 +179,6 @@ int CBattleCallback::battleMakeAction(BattleAction* action) return 0; } -const CStack* CBattleCallback::battleGetStackByPos(THex pos, bool onlyAlive) -{ - boost::shared_lock lock(*gs->mx); - return gs->curB->battleGetStack(pos, onlyAlive); -} - -THex CBattleCallback::battleGetPos(int stack) -{ - boost::shared_lock lock(*gs->mx); - if(!gs->curB) - { - tlog2<<"battleGetPos called when there is no battle!"<curB->stacks.size(); ++g) - { - if(gs->curB->stacks[g]->ID == stack) - return gs->curB->stacks[g]->position; - } - return THex::INVALID; -} - -TStacks CBattleCallback::battleGetStacks(EStackOwnership whose /*= MINE_AND_ENEMY*/, bool onlyAlive /*= true*/) -{ - boost::shared_lock lock(*gs->mx); - TStacks ret; - if(!gs->curB) //there is no battle - { - tlog2<<"battleGetStacks called when there is no battle!"<curB->stacks) - { - bool ownerMatches = whose == MINE_AND_ENEMY || whose == ONLY_MINE && s->owner == player || whose == ONLY_ENEMY && s->owner != player; - bool alivenessMatches = s->alive() || !onlyAlive; - if(ownerMatches && alivenessMatches) - ret.push_back(s); - } - - return ret; -} - -void CBattleCallback::getStackQueue( std::vector &out, int howMany ) -{ - if(!gs->curB) - { - tlog2 << "battleGetStackQueue called when there is not battle!" << std::endl; - return; - } - gs->curB->getStackQueue(out, howMany); -} - -std::vector CBattleCallback::battleGetAvailableHexes(const CStack * stack, bool addOccupiable, std::vector * attackable) -{ - boost::shared_lock lock(*gs->mx); - if(!gs->curB) - { - tlog2<<"battleGetAvailableHexes called when there is no battle!"<(); - } - return gs->curB->getAccessibility(stack, addOccupiable, attackable); - //return gs->battleGetRange(ID); -} - -bool CBattleCallback::battleCanShoot(const CStack * stack, THex dest) -{ - boost::shared_lock lock(*gs->mx); - - if(!gs->curB) return false; - - return gs->curB->battleCanShoot(stack, dest); -} - -bool CBattleCallback::battleCanCastSpell() -{ - if(!gs->curB) //there is no battle - return false; - - return gs->curB->battleCanCastSpell(player, SpellCasting::HERO_CASTING) == SpellCasting::OK; -} - -bool CBattleCallback::battleCanFlee() -{ - return gs->curB->battleCanFlee(player); -} - -const CGTownInstance *CBattleCallback::battleGetDefendedTown() -{ - if(!gs->curB || gs->curB->town == NULL) - return NULL; - - return gs->curB->town; -} - -ui8 CBattleCallback::battleGetWallState(int partOfWall) -{ - if(!gs->curB || gs->curB->siege == 0) - { - return 0; - } - return gs->curB->si.wallState[partOfWall]; -} - -int CBattleCallback::battleGetWallUnderHex(THex hex) -{ - if(!gs->curB || gs->curB->siege == 0) - { - return -1; - } - return gs->curB->hexToWallPart(hex); -} - -TDmgRange CBattleCallback::battleEstimateDamage(const CStack * attacker, const CStack * defender, TDmgRange * retaliationDmg) -{ - if(!gs->curB) - return std::make_pair(0, 0); - - const CGHeroInstance * attackerHero, * defenderHero; - bool shooting = battleCanShoot(attacker, defender->position); - - if(gs->curB->sides[0] == player) - { - attackerHero = gs->curB->heroes[0]; - defenderHero = gs->curB->heroes[1]; - } - else - { - attackerHero = gs->curB->heroes[1]; - defenderHero = gs->curB->heroes[0]; - } - - TDmgRange ret = gs->curB->calculateDmgRange(attacker, defender, attackerHero, defenderHero, shooting, 0, false, false); - - if(retaliationDmg) - { - if(shooting) - { - retaliationDmg->first = retaliationDmg->second = 0; - } - else - { - ui32 TDmgRange::* pairElems[] = {&TDmgRange::first, &TDmgRange::second}; - for (int i=0; i<2; ++i) - { - BattleStackAttacked bsa; - bsa.damageAmount = ret.*pairElems[i]; - retaliationDmg->*pairElems[!i] = gs->curB->calculateDmgRange(defender, attacker, bsa.newAmount, attacker->count, attackerHero, defenderHero, false, false, false, false).*pairElems[!i]; - } - } - } - - return ret; -} - -ui8 CBattleCallback::battleGetSiegeLevel() -{ - if(!gs->curB) - return 0; - - return gs->curB->siege; -} - -const CGHeroInstance * CBattleCallback::battleGetFightingHero(ui8 side) const -{ - if(!gs->curB) - return 0; - - return gs->curB->heroes[side]; -} - template void CBattleCallback::sendRequest(const T* request) { @@ -717,49 +208,6 @@ void CCallback::buyArtifact(const CGHeroInstance *hero, int aid) sendRequest(&pack); } -std::vector < const CGObjectInstance * > CCallback::getBlockingObjs( int3 pos ) const -{ - std::vector ret; - boost::shared_lock lock(*gs->mx); - if(!gs->map->isInTheMap(pos) || !isVisible(pos)) - return ret; - BOOST_FOREACH(const CGObjectInstance * obj, gs->map->terrain[pos.x][pos.y][pos.z].blockingObjects) - ret.push_back(obj); - return ret; -} - -std::vector < const CGObjectInstance * > CCallback::getVisitableObjs( int3 pos ) const -{ - std::vector ret; - boost::shared_lock lock(*gs->mx); - if(!gs->map->isInTheMap(pos) || !isVisible(pos)) - return ret; - BOOST_FOREACH(const CGObjectInstance * obj, gs->map->terrain[pos.x][pos.y][pos.z].visitableObjects) - ret.push_back(obj); - return ret; -} - -std::vector < const CGObjectInstance * > CCallback::getFlaggableObjects(int3 pos) const -{ - if(!isVisible(pos)) - return std::vector < const CGObjectInstance * >(); - - std::vector < const CGObjectInstance * > ret; - - const std::vector < std::pair > & objs = CGI->mh->ttiles[pos.x][pos.y][pos.z].objects; - for(size_t b=0; btempOwner!=254 && !((objs[b].first->defInfo->blockMap[pos.y - objs[b].first->pos.y + 5] >> (objs[b].first->pos.x - pos.x)) & 1)) - ret.push_back(CGI->mh->ttiles[pos.x][pos.y][pos.z].objects[b].first); - } - return ret; -} - -int3 CCallback::getMapSize() const -{ - return CGI->mh->sizes; -} - void CCallback::trade(const CGObjectInstance *market, int mode, int id1, int id2, int val1, const CGHeroInstance *hero/* = NULL*/) { TradeOnMarketplace pack; @@ -809,35 +257,6 @@ void CCallback::recruitHero(const CGObjectInstance *townOrTavern, const CGHeroIn } } -std::vector CCallback::getAvailableHeroes(const CGObjectInstance * townOrTavern) const -{ - std::vector ret(gs->players[player].availableHeroes.size()); - std::copy(gs->players[player].availableHeroes.begin(),gs->players[player].availableHeroes.end(),ret.begin()); - return ret; -} - -const TerrainTile * CCallback::getTileInfo( int3 tile ) const -{ - if(!gs->map->isInTheMap(tile)) - { - tlog1 << tile << "is outside the map! (call to getTileInfo)\n"; - return NULL; - } - if(!isVisible(tile, player)) return NULL; - boost::shared_lock lock(*gs->mx); - return &gs->map->getTile(tile); -} - -int CCallback::canBuildStructure( const CGTownInstance *t, int ID ) -{ - return gs->canBuildStructure(t,ID); -} - -std::set CCallback::getBuildingRequiments( const CGTownInstance *t, int ID ) -{ - return gs->getBuildingRequiments(t,ID); -} - bool CCallback::getPath(int3 src, int3 dest, const CGHeroInstance * hero, CPath &ret) { boost::shared_lock lock(*gs->mx); @@ -869,11 +288,6 @@ CCallback::CCallback( CGameState * GS, int Player, CClient *C ) waitTillRealize = false; } -const CMapHeader * CCallback::getMapHeader() const -{ - return gs->map; -} - const CGPathNode * CCallback::getPathInfo( int3 tile ) { return &cl->pathInfo->nodes[tile.x][tile.y][tile.z]; @@ -903,19 +317,6 @@ void CCallback::calculatePaths( const CGHeroInstance *hero, CPathsInfo &out, int gs->calculatePaths(hero, out, src, movement); } -int3 CCallback::getGrailPos( float &outKnownRatio ) -{ - if (CGObelisk::obeliskCount == 0) - { - outKnownRatio = 0.0f; - } - else - { - outKnownRatio = (float)CGObelisk::visited[gs->getPlayerTeam(player)->id] / CGObelisk::obeliskCount; - } - return gs->map->grailPos; -} - void CCallback::dig( const CGObjectInstance *hero ) { DigWithHero dwh; @@ -931,129 +332,6 @@ void CCallback::castSpell(const CGHeroInstance *hero, int spellID, const int3 &p cas.pos = pos; sendRequest(&cas); } - -bool CCallback::hasAccess(int playerId) const -{ - return gs->getPlayerRelations( playerId, player ) || player < 0; -} - -si8 CBattleCallback::battleHasDistancePenalty( const CStack * stack, THex destHex ) -{ - return gs->curB->hasDistancePenalty(stack, destHex); -} - -si8 CBattleCallback::battleHasWallPenalty( const CStack * stack, THex destHex ) -{ - return gs->curB->hasWallPenalty(stack, destHex); -} - -si8 CBattleCallback::battleCanTeleportTo(const CStack * stack, THex destHex, int telportLevel) -{ - return gs->curB->canTeleportTo(stack, destHex, telportLevel); -} - -int CCallback::getPlayerStatus(int player) const -{ - const PlayerState *ps = gs->getPlayer(player, false); - if(!ps) - return -1; - return ps->status; -} - -std::string CCallback::getTavernGossip(const CGObjectInstance * townOrTavern) const -{ - return "GOSSIP TEST"; -} - -std::vector < const CGObjectInstance * > CCallback::getMyObjects() const -{ - std::vector < const CGObjectInstance * > ret; - for (int g=0; gmap->objects.size(); ++g) - { - if (gs->map->objects[g] && gs->map->objects[g]->tempOwner == LOCPLINT->playerID) - { - ret.push_back(gs->map->objects[g]); - } - } - return ret; -} - -std::vector < const CGDwelling * > CCallback::getMyDwellings() const -{ - std::vector < const CGDwelling * > ret; - BOOST_FOREACH(CGDwelling * dw, gs->getPlayer(player)->dwellings) - { - ret.push_back(dw); - } - return ret; -} - -int CCallback::getPlayerRelations( ui8 color1, ui8 color2 ) const -{ - return gs->getPlayerRelations(color1, color2); -} - -InfoAboutTown::InfoAboutTown() -{ - tType = NULL; - details = NULL; - fortLevel = 0; - owner = -1; -} - -InfoAboutTown::~InfoAboutTown() -{ - delete details; -} - -void InfoAboutTown::initFromTown( const CGTownInstance *t, bool detailed ) -{ - obj = t; - army = ArmyDescriptor(t->getUpperArmy(), detailed); - built = t->builded; - fortLevel = t->fortLevel(); - name = t->name; - tType = t->town; - owner = t->tempOwner; - - if(detailed) - { - //include details about hero - details = new Details; - details->goldIncome = t->dailyIncome(); - details->customRes = vstd::contains(t->builtBuildings, 15); - details->hallLevel = t->hallLevel(); - details->garrisonedHero = t->garrisonHero; - } - //TODO: adjust undetailed info about army to our count of thieves guilds -} - -void InfoAboutTown::initFromGarrison(const CGGarrison *garr, bool detailed) -{ - obj = garr; - fortLevel = 0; - army = ArmyDescriptor(garr, detailed); - name = CGI->generaltexth->names[33]; // "Garrison" - owner = garr->tempOwner; - built = false; - tType = NULL; - - // Show detailed info only to owning player. - if(detailed) - { - details = new InfoAboutTown::Details; - details->customRes = false; - details->garrisonedHero = false; - details->goldIncome = -1; - details->hallLevel = -1; - } -} - -bool CBattleCallback::hasAccess( int playerId ) const -{ - return playerId == player || player < 0; -} - CBattleCallback::CBattleCallback(CGameState *GS, int Player, CClient *C ) { gs = GS; @@ -1061,73 +339,6 @@ CBattleCallback::CBattleCallback(CGameState *GS, int Player, CClient *C ) cl = C; } -std::vector CBattleCallback::battleGetDistances(const CStack * stack, THex hex /*= THex::INVALID*/, THex * predecessors /*= NULL*/) -{ - if(!hex.isValid()) - hex = stack->position; - - std::vector ret; - bool ac[BFIELD_SIZE] = {0}; - std::set occupyable; - gs->curB->getAccessibilityMap(ac, stack->doubleWide(), stack->attackerOwned, false, occupyable, stack->hasBonusOfType(Bonus::FLYING), stack); - THex pr[BFIELD_SIZE]; - int dist[BFIELD_SIZE]; - gs->curB->makeBFS(stack->position, ac, pr, dist, stack->doubleWide(), stack->attackerOwned, stack->hasBonusOfType(Bonus::FLYING), false); - - for(int i=0; icurB) - { - - tlog1 << "battleCanCastThisSpell called when there is no battle!\n"; - return SpellCasting::NO_HERO_TO_CAST_SPELL; - } - - return gs->curB->battleCanCastThisSpell(player, spell, SpellCasting::HERO_CASTING); -} - -si8 CBattleCallback::battleGetTacticDist() -{ - if (!gs->curB) - { - tlog1 << "battleGetTacticDist called when no battle!\n"; - return 0; - } - - if (gs->curB->sides[gs->curB->tacticsSide] == player) - { - return gs->curB->tacticDistance; - } - return 0; -} - -ui8 CBattleCallback::battleGetMySide() -{ - if (!gs->curB) - { - tlog1 << "battleGetMySide called when no battle!\n"; - return 0; - } - - return gs->curB->sides[1] == player; -} - bool CBattleCallback::battleMakeTacticAction( BattleAction * action ) { MakeAction ma; @@ -1135,14 +346,3 @@ bool CBattleCallback::battleMakeTacticAction( BattleAction * action ) sendRequest(&ma); return true; } - -int CBattleCallback::battleGetSurrenderCost() -{ - if (!gs->curB) - { - tlog1 << "battleGetSurrenderCost called when no battle!\n"; - return -1; - } - - return gs->curB->getSurrenderingCost(player); -} \ No newline at end of file diff --git a/CCallback.h b/CCallback.h index fc747ad4e..027254585 100644 --- a/CCallback.h +++ b/CCallback.h @@ -9,7 +9,8 @@ //support of unicode we should use ICU or some boost wraper areound it //(boost using this lib during compilation i dont know what for exactly) #endif -#include "lib/CGameState.h" + +#include "lib/IGameCallback.h" /* * CCallback.h, part of VCMI engine @@ -26,119 +27,49 @@ class CGameState; struct CPath; class CGObjectInstance; class CArmedInstance; -class SComponent; -class IChosen; -class CSelectableComponent; struct BattleAction; class CGTownInstance; -struct StartInfo; -class CStack; struct lua_State; class CClient; -struct TerrainTile; -class CHeroClass; class IShipyard; -struct CPackForServer; -class CMapHeader; struct CGPathNode; struct CGPath; -class CGGarrison; -class CObstacleInstance; -typedef std::vector TStacks; - -/// Struct which holds a short information about a town -struct InfoAboutTown -{ - struct Details - { - int hallLevel, goldIncome; - bool customRes; - bool garrisonedHero; - - } *details; - - const CArmedInstance * obj; - char fortLevel; //0 - none - char owner; - std::string name; - CTown *tType; - bool built; - - ArmyDescriptor army; //numbers of creatures are valid only if details - - InfoAboutTown(); - ~InfoAboutTown(); - void initFromTown(const CGTownInstance *t, bool detailed); - void initFromGarrison(const CGGarrison *garr, bool detailed); -}; +struct CPathsInfo; class IBattleCallback { public: - ///describes why player cannot cast a specific spell - - enum EStackOwnership - { - ONLY_MINE, ONLY_ENEMY, MINE_AND_ENEMY - }; - bool waitTillRealize; //if true, request functions will return after they are realized by server //battle - virtual int battleGetBattlefieldType()=0; // 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 - virtual int battleGetObstaclesAtTile(THex tile)=0; //returns bitfield - virtual std::vector battleGetAllObstacles()=0; //returns all obstacles on the battlefield - virtual const CStack * battleGetStackByID(int ID, bool onlyAlive = true)=0; //returns stack info by given ID - virtual const CStack * battleGetStackByPos(THex pos, bool onlyAlive = true)=0; //returns stack info by given pos - virtual THex battleGetPos(int stack)=0; //returns position (tile ID) of stack virtual int battleMakeAction(BattleAction* action)=0;//for casting spells by hero - DO NOT use it for moving active stack - virtual TStacks battleGetStacks(EStackOwnership whose = MINE_AND_ENEMY, bool onlyAlive = true)=0; //returns stacks on battlefield - virtual void getStackQueue( std::vector &out, int howMany )=0; //returns vector of stack in order of their move sequence - virtual std::vector battleGetAvailableHexes(const CStack * stack, bool addOccupiable, std::vector * attackable = NULL)=0; //returns numbers of hexes reachable by creature with id ID - virtual std::vector battleGetDistances(const CStack * stack, THex hex = THex::INVALID, THex * predecessors = NULL)=0; //returns vector of distances to [dest hex number] - virtual bool battleCanShoot(const CStack * stack, THex dest)=0; //returns true if unit with id ID can shoot to dest - virtual bool battleCanCastSpell()=0; //returns true, if caller can cast a spell - virtual SpellCasting::ESpellCastProblem battleCanCastThisSpell(const CSpell * spell)=0; //determines if given spell can be casted (and returns problem description) - virtual bool battleCanFlee()=0; //returns true if caller can flee from the battle - virtual int battleGetSurrenderCost()=0; //returns cost of surrendering battle, -1 if surrendering is not possible - virtual const CGTownInstance * battleGetDefendedTown()=0; //returns defended town if current battle is a siege, NULL instead - virtual ui8 battleGetWallState(int partOfWall)=0; //for determining state of a part of the wall; format: parameter [0] - keep, [1] - bottom tower, [2] - bottom wall, [3] - below gate, [4] - over gate, [5] - upper wall, [6] - uppert tower, [7] - gate; returned value: 1 - intact, 2 - damaged, 3 - destroyed; 0 - no battle - virtual int battleGetWallUnderHex(THex hex)=0; //returns part of destructible wall / gate / keep under given hex or -1 if not found - virtual TDmgRange battleEstimateDamage(const CStack * attacker, const CStack * defender, TDmgRange * retaliationDmg = NULL)=0; //estimates damage dealt by attacker to defender; it may be not precise especially when stack has randomly working bonuses; returns pair - virtual ui8 battleGetSiegeLevel()=0; //returns 0 when there is no siege, 1 if fort, 2 is citadel, 3 is castle - virtual const CGHeroInstance * battleGetFightingHero(ui8 side) const =0; //returns hero corresponding to given side (0 - attacker, 1 - defender) - virtual si8 battleHasDistancePenalty(const CStack * stack, THex destHex) =0; //checks if given stack has distance penalty - virtual si8 battleHasWallPenalty(const CStack * stack, THex destHex) =0; //checks if given stack has wall penalty - virtual si8 battleCanTeleportTo(const CStack * stack, THex destHex, int telportLevel) =0; //checks if teleportation of given stack to given position can take place - virtual si8 battleGetTacticDist() =0; //returns tactic distance for calling player or 0 if player is not in tactic phase - virtual ui8 battleGetMySide() =0; //return side of player in battle (attacker/defender) virtual bool battleMakeTacticAction(BattleAction * action) =0; // performs tactic phase actions - - //convienience methods using the ones above - TStacks battleGetAllStacks() //returns all stacks, alive or dead or undead or mechanical :) - { - return battleGetStacks(MINE_AND_ENEMY, false); - } }; -class ICallback : public virtual IBattleCallback +class IGameActionCallback { +// IGameActionCallback(CGameState * GS, int Player); +// bool isVisible(int3 pos, int Player) const; +// bool isVisible(const CGObjectInstance *obj, int Player) const; +// virtual bool hasAccess(int playerId) const; public: //hero virtual bool moveHero(const CGHeroInstance *h, int3 dst) =0; //dst must be free, neighbouring tile (this function can move hero only by one tile) virtual bool dismissHero(const CGHeroInstance * hero)=0; //dismisses given hero; true - successfuly, false - not successfuly - + virtual void dig(const CGObjectInstance *hero)=0; + virtual void castSpell(const CGHeroInstance *hero, int spellID, const int3 &pos = int3(-1, -1, -1))=0; //cast adventure map spell + //town virtual void recruitHero(const CGObjectInstance *townOrTavern, const CGHeroInstance *hero)=0; virtual bool buildBuilding(const CGTownInstance *town, si32 buildingID)=0; virtual void recruitCreatures(const CGObjectInstance *obj, ui32 ID, ui32 amount, si32 level=-1)=0; virtual bool upgradeCreature(const CArmedInstance *obj, int stackPos, int newID=-1)=0; //if newID==-1 then best possible upgrade will be made virtual void swapGarrisonHero(const CGTownInstance *town)=0; - + virtual void trade(const CGObjectInstance *market, int mode, int id1, int id2, int val1, const CGHeroInstance *hero = NULL)=0; //mode==0: sell val1 units of id1 resource for id2 resiurce - + virtual void selectionMade(int selection, int asker) =0; - virtual int swapCreatures(const CArmedInstance *s1, const CArmedInstance *s2, int p1, int p2)=0;//swaps creatures between two posiibly different garrisons // TODO: AI-unsafe code - fix it! - virtual int mergeStacks(const CArmedInstance *s1, const CArmedInstance *s2, int p1, int p2)=0;//joins first stack tothe second (creatures must be same type) + virtual int swapCreatures(const CArmedInstance *s1, const CArmedInstance *s2, int p1, int p2)=0;//swaps creatures between two possibly different garrisons // TODO: AI-unsafe code - fix it! + virtual int mergeStacks(const CArmedInstance *s1, const CArmedInstance *s2, int p1, int p2)=0;//joins first stack to the second (creatures must be same type) virtual int splitStack(const CArmedInstance *s1, const CArmedInstance *s2, int p1, int p2, int val)=0;//split creatures from the first stack virtual bool swapArtifacts(const CGHeroInstance * hero1, ui16 pos1, const CGHeroInstance * hero2, ui16 pos2)=0; //swaps artifacts between two given heroes virtual bool assembleArtifacts(const CGHeroInstance * hero, ui16 artifactSlot, bool assemble, ui32 assembleTo)=0; @@ -148,124 +79,43 @@ public: virtual void setFormation(const CGHeroInstance * hero, bool tight)=0; virtual void setSelection(const CArmedInstance * obj)=0; - + virtual void save(const std::string &fname) = 0; virtual void sendMessage(const std::string &mess) = 0; virtual void buildBoat(const IShipyard *obj) = 0; - -//get info - virtual bool verifyPath(CPath * path, bool blockSea)const =0; - virtual int getDate(int mode=0)const =0; //mode=0 - total days in game, mode=1 - day of week, mode=2 - current week, mode=3 - current month - virtual std::vector< std::vector< std::vector > > & getVisibilityMap()const =0; //returns visibility map (TODO: make it const) - virtual int getResourceAmount(int type)const =0; - virtual bool isVisible(int3 pos)const =0; - virtual int getMyColor()const =0; - virtual int getHeroSerial(const CGHeroInstance * hero)const =0; - virtual const StartInfo * getStartInfo()const =0; - virtual const CMapHeader * getMapHeader()const =0; - virtual int getSpellCost(const CSpell * sp, const CGHeroInstance * caster) const =0; //when called during battle, takes into account creatures' spell cost reduction - virtual int estimateSpellDamage(const CSpell * sp, const CGHeroInstance * hero) const =0; //estimates damage of given spell; returns 0 if spell causes no dmg - virtual void getThievesGuildInfo(SThievesGuildInfo & thi, const CGObjectInstance * obj)=0; //get thieves' guild info obtainable while visiting given object - virtual int3 getGrailPos(float &outKnownRatio)=0; - virtual int getPlayerStatus(int player) const = 0; //-1 if no such player - - //hero - virtual int howManyHeroes(bool includeGarrisoned = true)const =0; - virtual const CGHeroInstance * getHeroInfo(int val, int mode=2)const =0; //mode = 0 -> val = serial; mode = 1 -> val = ID - virtual std::vector < const CGHeroInstance *> getHeroesInfo(bool onlyOur=true)const =0; - virtual bool getHeroInfo(const CGObjectInstance *hero, InfoAboutHero &dest) const = 0; - virtual bool getPath(int3 src, int3 dest, const CGHeroInstance * hero, CPath &ret)=0; - virtual const CGPathNode *getPathInfo(int3 tile)=0; //uses main, client pathfinder info - virtual bool getPath2(int3 dest, CGPath &ret)=0; //uses main, client pathfinder info - virtual void calculatePaths(const CGHeroInstance *hero, CPathsInfo &out, int3 src = int3(-1,-1,-1), int movement = -1) =0; - virtual void recalculatePaths()=0; //updates main, client pathfinder info (should be called when moving hero is over) - virtual void dig(const CGObjectInstance *hero)=0; - virtual void castSpell(const CGHeroInstance *hero, int spellID, const int3 &pos = int3(-1, -1, -1))=0; //cast adventure map spell - - //map - virtual std::vector < const CGDwelling * > getMyDwellings() const =0; //returns all dwellings that belong to player - virtual std::vector < const CGObjectInstance * > getMyObjects() const =0; //returns all objects flagged by belonging player - virtual std::vector < const CGObjectInstance * > getBlockingObjs(int3 pos)const =0; - virtual std::vector < const CGObjectInstance * > getVisitableObjs(int3 pos)const =0; - virtual std::vector < const CGObjectInstance * > getFlaggableObjects(int3 pos) const =0; - virtual std::vector < std::string > getObjDescriptions(int3 pos)const =0; //returns descriptions of objects at pos in order from the lowest to the highest - - //town - virtual int howManyTowns()const =0; - virtual const CGTownInstance * getTownInfo(int val, bool mode)const =0; //mode = 0 -> val = player town serial; mode = 1 -> val = object id (serial) - virtual std::vector < const CGTownInstance *> getTownsInfo(bool onlyOur=true) const=0; - virtual std::vector getAvailableHeroes(const CGObjectInstance * townOrTavern) const =0; //heroes that can be recruited - virtual std::string getTavernGossip(const CGObjectInstance * townOrTavern) const =0; - virtual int canBuildStructure(const CGTownInstance *t, int ID) =0;//// 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 - virtual std::set getBuildingRequiments(const CGTownInstance *t, int ID) =0; - virtual bool getTownInfo(const CGObjectInstance *town, InfoAboutTown &dest) const = 0; - - virtual UpgradeInfo getUpgradeInfo(const CArmedInstance *obj, int stackPos)const =0; - virtual const CCreatureSet* getGarrison(const CGObjectInstance *obj)const =0; - - virtual int3 getMapSize() const =0; //returns size of map - z is 1 for one - level map and 2 for two level map - virtual const TerrainTile * getTileInfo(int3 tile) const = 0; - virtual int getPlayerRelations(ui8 color1, ui8 color2) const =0;// 0 = enemy, 1 = ally, 2 = same player }; -class CBattleCallback : public virtual IBattleCallback +class CBattleCallback : public IBattleCallback, public CBattleInfoCallback { private: - CGameState * gs; CBattleCallback(CGameState *GS, int Player, CClient *C); protected: template void sendRequest(const T*request); CClient *cl; - virtual bool hasAccess(int playerId) const; - int player; + //virtual bool hasAccess(int playerId) const; public: - //battle - int battleGetBattlefieldType() OVERRIDE; // 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 - int battleGetObstaclesAtTile(THex tile) OVERRIDE; //returns bitfield - std::vector battleGetAllObstacles() OVERRIDE; //returns all obstacles on the battlefield - const CStack * battleGetStackByID(int ID, bool onlyAlive = true) OVERRIDE; //returns stack info by given ID - const CStack * battleGetStackByPos(THex pos, bool onlyAlive = true) OVERRIDE; //returns stack info by given pos - THex battleGetPos(int stack) OVERRIDE; //returns position (tile ID) of stack int battleMakeAction(BattleAction* action) OVERRIDE;//for casting spells by hero - DO NOT use it for moving active stack - TStacks battleGetStacks(EStackOwnership whose = MINE_AND_ENEMY, bool onlyAlive = true) OVERRIDE; //returns stacks on battlefield - void getStackQueue( std::vector &out, int howMany ) OVERRIDE; //returns vector of stack in order of their move sequence - std::vector battleGetAvailableHexes(const CStack * stack, bool addOccupiable, std::vector * attackable = NULL) OVERRIDE; //returns numbers of hexes reachable by creature with id ID - std::vector battleGetDistances(const CStack * stack, THex hex = THex::INVALID, THex * predecessors = NULL) OVERRIDE; //returns vector of distances to [dest hex number]; if predecessors is not null, it must point to BFIELD_SIZE * sizeof(int) of allocated memory - bool battleCanShoot(const CStack * stack, THex dest) OVERRIDE; //returns true if unit with id ID can shoot to dest - bool battleCanCastSpell() OVERRIDE; //returns true, if caller can cast a spell - SpellCasting::ESpellCastProblem battleCanCastThisSpell(const CSpell * spell) OVERRIDE; //determines if given spell can be casted (and returns problem description) - bool battleCanFlee() OVERRIDE; //returns true if caller can flee from the battle - int battleGetSurrenderCost() OVERRIDE; //returns cost of surrendering battle, -1 if surrendering is not possible - const CGTownInstance * battleGetDefendedTown() OVERRIDE; //returns defended town if current battle is a siege, NULL instead - ui8 battleGetWallState(int partOfWall) OVERRIDE; //for determining state of a part of the wall; format: parameter [0] - keep, [1] - bottom tower, [2] - bottom wall, [3] - below gate, [4] - over gate, [5] - upper wall, [6] - uppert tower, [7] - gate; returned value: 1 - intact, 2 - damaged, 3 - destroyed; 0 - no battle - int battleGetWallUnderHex(THex hex) OVERRIDE; //returns part of destructible wall / gate / keep under given hex or -1 if not found - TDmgRange battleEstimateDamage(const CStack * attacker, const CStack * defender, TDmgRange * retaliationDmg = NULL) OVERRIDE; //estimates damage dealt by attacker to defender; it may be not precise especially when stack has randomly working bonuses; returns pair - ui8 battleGetSiegeLevel() OVERRIDE; //returns 0 when there is no siege, 1 if fort, 2 is citadel, 3 is castle - const CGHeroInstance * battleGetFightingHero(ui8 side) const OVERRIDE; //returns hero corresponding ot given side (0 - attacker, 1 - defender) - si8 battleHasDistancePenalty(const CStack * stack, THex destHex) OVERRIDE; //checks if given stack has distance penalty - si8 battleHasWallPenalty(const CStack * stack, THex destHex) OVERRIDE; //checks if given stack has wall penalty - si8 battleCanTeleportTo(const CStack * stack, THex destHex, int telportLevel) OVERRIDE; //checks if teleportation of given stack to given position can take place - si8 battleGetTacticDist() OVERRIDE; //returns tactic distance for calling player or 0 if player is not in tactic phase - ui8 battleGetMySide() OVERRIDE; //return side of player in battle (attacker/defender) bool battleMakeTacticAction(BattleAction * action) OVERRIDE; // performs tactic phase actions friend class CCallback; friend class CClient; }; -class CCallback : public ICallback, public CBattleCallback +class CCallback : public CPlayerSpecificInfoCallback, public IGameActionCallback, public CBattleCallback { private: CCallback(CGameState * GS, int Player, CClient *C); - bool isVisible(int3 pos, int Player) const; - bool isVisible(const CGObjectInstance *obj, int Player) const; -protected: - virtual bool hasAccess(int playerId) const OVERRIDE; - public: +//client-specific functionalities (pathfinding) + virtual bool getPath(int3 src, int3 dest, const CGHeroInstance * hero, CPath &ret); //DEPRACATED!!! + virtual const CGPathNode *getPathInfo(int3 tile); //uses main, client pathfinder info + virtual bool getPath2(int3 dest, CGPath &ret); //uses main, client pathfinder info + virtual void calculatePaths(const CGHeroInstance *hero, CPathsInfo &out, int3 src = int3(-1,-1,-1), int movement = -1); + virtual void recalculatePaths(); //updates main, client pathfinder info (should be called when moving hero is over) + //commands bool moveHero(const CGHeroInstance *h, int3 dst); //dst must be free, neighbouring tile (this function can move hero only by one tile) bool teleportHero(const CGHeroInstance *who, const CGTownInstance *where); @@ -293,64 +143,8 @@ public: void dig(const CGObjectInstance *hero); void castSpell(const CGHeroInstance *hero, int spellID, const int3 &pos = int3(-1, -1, -1)); -//get info - bool verifyPath(CPath * path, bool blockSea) const; - 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 - std::vector< std::vector< std::vector > > & getVisibilityMap() const; //returns visibility map (TODO: make it const) - const CGHeroInstance * getHeroInfo(int val, int mode=2) const; //mode = 0 -> val = serial; mode = 1 -> val = hero type id (subID); mode = 2 -> val = global object serial id (id) - const CGObjectInstance * getObjectInfo(int ID) const; //global object serial id (ID) - int getResourceAmount(int type) const; - std::vector getResourceAmount() const; - int howManyHeroes(bool includeGarrisoned = true) const; - const CGTownInstance * getTownInfo(int val, bool mode) const; //mode = 0 -> val = player town serial; mode = 1 -> val = object id (serial) - std::vector < const CGTownInstance *> getTownsInfo(bool onlyOur=true) const; - int howManyTowns()const; - std::vector < std::string > getObjDescriptions(int3 pos) const; //returns descriptions of objects at pos in order from the lowest to the highest - std::vector < const CGHeroInstance *> getHeroesInfo(bool onlyOur=true) const; - bool isVisible(int3 pos) const; - int getMyColor() const; - int getHeroSerial(const CGHeroInstance * hero) const; - //int getMySerial() const; - const CCreatureSet* getGarrison(const CGObjectInstance *obj) const; - UpgradeInfo getUpgradeInfo(const CArmedInstance *obj, int stackPos) const; - const StartInfo * getStartInfo() const; - const CMapHeader * getMapHeader()const ; - int getSpellCost(const CSpell * sp, const CGHeroInstance * caster) const; //when called during battle, takes into account creatures' spell cost reduction - int estimateSpellDamage(const CSpell * sp, const CGHeroInstance * hero) const; //estimates damage of given spell; returns 0 if spell causes no dmg - void getThievesGuildInfo(SThievesGuildInfo & thi, const CGObjectInstance * obj); //get thieves' guild info obtainable while visiting given object - int3 getGrailPos(float &outKnownRatio); //returns pos and (via arg) percent of discovered obelisks; TODO: relies on fairness of GUI/AI... :/ - - std::vector < const CGDwelling * > getMyDwellings() const; //returns all dwellings that belong to player - std::vector < const CGObjectInstance * > getMyObjects() const; //returns all objects flagged by belonging player - std::vector < const CGObjectInstance * > getBlockingObjs(int3 pos) const; - std::vector < const CGObjectInstance * > getVisitableObjs(int3 pos) const; - std::vector < const CGObjectInstance * > getFlaggableObjects(int3 pos) const; - int3 getMapSize() const; //returns size of map - z is 1 for one - level map and 2 for two level map - std::vector getAvailableHeroes(const CGObjectInstance * townOrTavern) const; //heroes that can be recruited - std::string getTavernGossip(const CGObjectInstance * townOrTavern) const; - const TerrainTile * getTileInfo(int3 tile) const; - 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 - std::set getBuildingRequiments(const CGTownInstance *t, int ID); - bool getPath(int3 src, int3 dest, const CGHeroInstance * hero, CPath &ret); - const CGPathNode *getPathInfo(int3 tile); - bool getPath2(int3 dest, CGPath &ret); - 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; - void recalculatePaths(); //updates pathfinder info (should be called when moving hero is over) - bool getHeroInfo(const CGObjectInstance *hero, InfoAboutHero &dest) const; - bool getTownInfo(const CGObjectInstance *town, InfoAboutTown &dest) const; - int3 guardingCreaturePosition (int3 pos) const; - int getPlayerStatus(int player) const; - int getPlayerRelations(ui8 color1, ui8 color2) const;// 0 = enemy, 1 = ally, 2 = same player - - -//XXX hmmm _tmain on _GNUC_ wtf? //friends friend class CClient; -#ifndef __GNUC__ - friend int _tmain(int argc, _TCHAR* argv[]); -#else - friend int main(int argc, char** argv); -#endif }; #endif // __CCALLBACK_H__ diff --git a/CGameInterface.h b/CGameInterface.h index 119b0b75e..5ab7b7551 100644 --- a/CGameInterface.h +++ b/CGameInterface.h @@ -18,7 +18,7 @@ using namespace boost::logic; class CCallback; -class IBattleCallback; +class CBattleCallback; class ICallback; class CGlobalAI; struct Component; @@ -63,7 +63,7 @@ public: virtual ~CBattleGameInterface() {}; - virtual void init(IBattleCallback * CB){}; + virtual void init(CBattleCallback * CB){}; //battle call-ins virtual void actionFinished(const BattleAction *action){};//occurs AFTER every action taken by any stack or by the hero @@ -74,7 +74,7 @@ public: virtual void battleEnd(const BattleResult *br){}; virtual void battleResultsApplied(){}; //called when all effects of last battle are applied virtual void battleNewRoundFirst(int round){}; //called at the beginning of each turn before changes are applied; - 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 battleNewRound(int round){}; //called at the beginning of each turn, round=-1 is the tactic phase, round=0 is the first "normal" turn virtual void battleStackMoved(const CStack * stack, THex dest, int distance, bool end){}; virtual void battleSpellCast(const BattleSpellCast *sc){}; virtual void battleStacksEffectsSet(const SetStackEffect & sse){};//called when a specific effect is set to stacks @@ -118,7 +118,7 @@ public: virtual void heroManaPointsChanged(const CGHeroInstance * hero){} //not called at the beginning of turn and after spell casts virtual void heroMovePointsChanged(const CGHeroInstance * hero){} //not called at the beginning of turn and after movement virtual void heroVisitsTown(const CGHeroInstance* hero, const CGTownInstance * town){}; - virtual void init(ICallback * CB){}; + virtual void init(CCallback * CB){}; virtual void receivedResource(int type, int val){}; virtual void showInfoDialog(const std::string &text, const std::vector &components, int soundID){}; virtual void showRecruitmentDialog(const CGDwelling *dwelling, const CArmedInstance *dst, int level){} diff --git a/client/CAdvmapInterface.cpp b/client/CAdvmapInterface.cpp index deee32474..3cbccc59d 100644 --- a/client/CAdvmapInterface.cpp +++ b/client/CAdvmapInterface.cpp @@ -1771,6 +1771,9 @@ void CAdvMapInt::startTurn() void CAdvMapInt::tileLClicked(const int3 &mp) { + if(!LOCPLINT->cb->isVisible(mp)) + return; + std::vector < const CGObjectInstance * > bobjs = LOCPLINT->cb->getBlockingObjs(mp), //blocking objects at tile vobjs = LOCPLINT->cb->getVisitableObjs(mp); //visitable objects const TerrainTile *tile = LOCPLINT->cb->getTileInfo(mp); @@ -1852,6 +1855,13 @@ void CAdvMapInt::tileLClicked(const int3 &mp) void CAdvMapInt::tileHovered(const int3 &tile) { + if(!LOCPLINT->cb->isVisible(tile)) + { + CCS->curh->changeGraphic(0, 0); + statusbar.clear(); + return; + } + std::vector temp = LOCPLINT->cb->getObjDescriptions(tile); if (temp.size()) { @@ -2040,6 +2050,11 @@ void CAdvMapInt::tileRClicked(const int3 &mp) leaveCastingMode(); return; } + if(!LOCPLINT->cb->isVisible(mp)) + { + CRClickPopup::createAndPush(VLC->generaltexth->allTexts[61]); //Uncharted Territory + return; + } std::vector < const CGObjectInstance * > objs = LOCPLINT->cb->getBlockingObjs(mp); if(!objs.size()) diff --git a/client/CBattleInterface.cpp b/client/CBattleInterface.cpp index a19fce94d..a190d1094 100644 --- a/client/CBattleInterface.cpp +++ b/client/CBattleInterface.cpp @@ -3452,7 +3452,7 @@ void CBattleInterface::endAction(const BattleAction* action) // std::set stacks; // stacks.insert(LOCPLINT->cb->battleGetStackByID(action->stackNumber)); // stacks.insert(LOCPLINT->cb->battleGetStackByPos(action->destinationTile)); - TStacks stacks = curInt->cb->battleGetStacks(IBattleCallback::MINE_AND_ENEMY); + TStacks stacks = curInt->cb->battleGetStacks(CBattleCallback::MINE_AND_ENEMY); BOOST_FOREACH(const CStack *s, stacks) { @@ -3612,7 +3612,7 @@ static bool immobile(const CStack *s) void CBattleInterface::bTacticNextStack() { - TStacks stacksOfMine = curInt->cb->battleGetStacks(IBattleCallback::ONLY_MINE); + TStacks stacksOfMine = curInt->cb->battleGetStacks(CBattleCallback::ONLY_MINE); stacksOfMine.erase(std::remove_if(stacksOfMine.begin(), stacksOfMine.end(), &immobile), stacksOfMine.end()); TStacks::iterator it = vstd::find(stacksOfMine, activeStack); if(it != stacksOfMine.end() && ++it != stacksOfMine.end()) diff --git a/client/CCastleInterface.cpp b/client/CCastleInterface.cpp index 1e31d9b13..3f2afeac2 100644 --- a/client/CCastleInterface.cpp +++ b/client/CCastleInterface.cpp @@ -976,7 +976,7 @@ void CCastleInterface::showAll(SDL_Surface *to) void CCastleInterface::castleTeleport(int where) { - const CGTownInstance * dest = LOCPLINT->cb->getTownInfo(where, 1); + const CGTownInstance * dest = LOCPLINT->cb->getTown(where); LOCPLINT->cb->teleportHero(town->visitingHero, dest); } @@ -1815,7 +1815,7 @@ CBlacksmithDialog::CBlacksmithDialog(bool possible, int creMachineID, int aid, i cancel = new AdventureMapButton(text,"",boost::bind(&CBlacksmithDialog::close, this), 224, 312,"ICANCEL.DEF",SDLK_ESCAPE); if(possible) - buy->callback += boost::bind(&CCallback::buyArtifact,LOCPLINT->cb,LOCPLINT->cb->getHeroInfo(hid,2),aid); + buy->callback += boost::bind(&CCallback::buyArtifact,LOCPLINT->cb,LOCPLINT->cb->getHero(hid),aid); else buy->block(true); diff --git a/client/CPlayerInterface.cpp b/client/CPlayerInterface.cpp index 6ece0365b..2afecc718 100644 --- a/client/CPlayerInterface.cpp +++ b/client/CPlayerInterface.cpp @@ -130,7 +130,7 @@ CPlayerInterface::~CPlayerInterface() LOCPLINT = NULL; } -void CPlayerInterface::init(ICallback * CB) +void CPlayerInterface::init(CCallback * CB) { cb = dynamic_cast(CB); if(observerInDuelMode) @@ -234,7 +234,7 @@ void CPlayerInterface::heroMoved(const TryMoveHero & details) if(LOCPLINT != this) return; boost::unique_lock un(*pim); - const CGHeroInstance * ho = cb->getHeroInfo(details.id); //object representing this hero + const CGHeroInstance * ho = cb->getHero(details.id); //object representing this hero int3 hp = details.start; adventureInt->centerOn(ho); //actualizing screen pos @@ -1194,7 +1194,7 @@ void CPlayerInterface::objectPropertyChanged(const SetObjectProperty * sop) boost::unique_lock un(*pim); if(sop->what == ObjProperty::OWNER) { - const CGObjectInstance * obj = cb->getObjectInfo(sop->id); + const CGObjectInstance * obj = cb->getObj(sop->id); std::set pos = obj->getBlockedPos(); for(std::set::const_iterator it = pos.begin(); it != pos.end(); ++it) { diff --git a/client/CPlayerInterface.h b/client/CPlayerInterface.h index c95e047bf..04e52c42b 100644 --- a/client/CPlayerInterface.h +++ b/client/CPlayerInterface.h @@ -244,7 +244,7 @@ public: void openHeroWindow(const CGHeroInstance * hero); //shows hero window with given hero SDL_Surface * infoWin(const CGObjectInstance * specific); //specific=0 => draws info about selected town/hero void updateInfo(const CGObjectInstance * specific); - void init(ICallback * CB); + void init(CCallback * CB); int3 repairScreenPos(int3 pos); //returns position closest to pos we can center screen on void showInfoDialog(const std::string &text, const std::vector & components = std::vector(), int soundID = 0, bool delComps = false); void showYesNoDialog(const std::string &text, const std::vector & components, CFunctionList onYes, CFunctionList onNo, bool DelComps); //deactivateCur - whether current main interface should be deactivated; delComps - if components will be deleted on window close diff --git a/client/CSpellWindow.cpp b/client/CSpellWindow.cpp index e929fde6a..0bc0980d3 100644 --- a/client/CSpellWindow.cpp +++ b/client/CSpellWindow.cpp @@ -581,7 +581,7 @@ Uint8 CSpellWindow::pagesWithinCurrentTab() void CSpellWindow::teleportTo( int town, const CGHeroInstance * hero ) { - const CGTownInstance * dest = LOCPLINT->cb->getTownInfo(town, 1); + const CGTownInstance * dest = LOCPLINT->cb->getTown(town); LOCPLINT->cb->castSpell(hero, Spells::TOWN_PORTAL, dest->visitablePos()); } @@ -718,7 +718,7 @@ void CSpellWindow::SpellArea::clickLeft(tribool down, bool previousState) double dist = -1; for (int g=0; gcb->getTownInfo(Towns[g]->id, 1); + const CGTownInstance * dest = LOCPLINT->cb->getTown(Towns[g]->id); double curDist = dest->pos.dist2d(h->pos); if (nearest == -1 || curDist < dist) { @@ -730,7 +730,7 @@ void CSpellWindow::SpellArea::clickLeft(tribool down, bool previousState) LOCPLINT->showInfoDialog(CGI->generaltexth->allTexts[123]); else { - const CGTownInstance * town = LOCPLINT->cb->getTownInfo(Towns[nearest]->id, 1); + const CGTownInstance * town = LOCPLINT->cb->getTown(Towns[nearest]->id); LOCPLINT->cb->castSpell(h, spell, town->visitablePos());// - town->getVisitableOffset()); } } diff --git a/client/GUIClasses.cpp b/client/GUIClasses.cpp index 589e2914d..6db4b79a3 100644 --- a/client/GUIClasses.cpp +++ b/client/GUIClasses.cpp @@ -184,7 +184,8 @@ void CGarrisonSlot::clickLeft(tribool down, bool previousState) { if(owner->highlighted == this) //view info { - UpgradeInfo pom = LOCPLINT->cb->getUpgradeInfo(getObj(), ID); + UpgradeInfo pom; + LOCPLINT->cb->getUpgradeInfo(getObj(), ID, pom); bool canUpgrade = getObj()->tempOwner == LOCPLINT->playerID && pom.oldID>=0; //upgrade is possible bool canDismiss = getObj()->tempOwner == LOCPLINT->playerID && (getObj()->stacksCount()>1 || !getObj()->needsLastStack()); @@ -999,7 +1000,7 @@ CSelWindow::CSelWindow(const std::string &Text, int player, int charperline, con buttons.back()->assignedKeys.insert(SDLK_ESCAPE); //last button - reacts on escape if(buttons.size() > 1 && askID >= 0) //cancel button functionality - buttons.back()->callback += boost::bind(&ICallback::selectionMade,LOCPLINT->cb,0,askID); + buttons.back()->callback += boost::bind(&CCallback::selectionMade,LOCPLINT->cb,0,askID); for(int i=0;icb->getHeroInfo(hero1, 2); - heroInst[1] = LOCPLINT->cb->getHeroInfo(hero2, 2); + heroInst[0] = LOCPLINT->cb->getHero(hero1); + heroInst[1] = LOCPLINT->cb->getHero(hero2); prepareBackground(); pos.x = screen->w/2 - bg->w/2; @@ -6388,7 +6389,8 @@ void CHillFortWindow::updateGarrisons() int newState = getState(i); if (newState != -1) { - UpgradeInfo info = LOCPLINT->cb->getUpgradeInfo(hero, i); + UpgradeInfo info; + LOCPLINT->cb->getUpgradeInfo(hero, i, info); if (info.newID.size())//we have upgrades here - update costs for(std::set >::iterator it=info.cost[0].begin(); it!=info.cost[0].end(); it++) { @@ -6427,7 +6429,8 @@ void CHillFortWindow::makeDeal(int slot) for (int i=0; icb->getUpgradeInfo(hero, i); + UpgradeInfo info; + LOCPLINT->cb->getUpgradeInfo(hero, i, info); LOCPLINT->cb->upgradeCreature(hero, i, info.newID[0]); } break; @@ -6506,7 +6509,8 @@ int CHillFortWindow::getState(int slot) if (hero->slotEmpty(slot))//no creature here return -1; - UpgradeInfo info = LOCPLINT->cb->getUpgradeInfo(hero, slot); + UpgradeInfo info; + LOCPLINT->cb->getUpgradeInfo(hero, slot, info); if (!info.newID.size())//already upgraded return 1; diff --git a/lib/CGameState.cpp b/lib/CGameState.cpp index 2fd63bfb6..f269248f2 100644 --- a/lib/CGameState.cpp +++ b/lib/CGameState.cpp @@ -145,6 +145,62 @@ public: } } *objCaller = NULL; +InfoAboutTown::InfoAboutTown() +{ + tType = NULL; + details = NULL; + fortLevel = 0; + owner = -1; +} + +InfoAboutTown::~InfoAboutTown() +{ + delete details; +} + +void InfoAboutTown::initFromTown( const CGTownInstance *t, bool detailed ) +{ + obj = t; + army = ArmyDescriptor(t->getUpperArmy(), detailed); + built = t->builded; + fortLevel = t->fortLevel(); + name = t->name; + tType = t->town; + owner = t->tempOwner; + + if(detailed) + { + //include details about hero + details = new Details; + details->goldIncome = t->dailyIncome(); + details->customRes = vstd::contains(t->builtBuildings, 15); + details->hallLevel = t->hallLevel(); + details->garrisonedHero = t->garrisonHero; + } + //TODO: adjust undetailed info about army to our count of thieves guilds +} + +void InfoAboutTown::initFromGarrison(const CGGarrison *garr, bool detailed) +{ + obj = garr; + fortLevel = 0; + army = ArmyDescriptor(garr, detailed); + name = VLC->generaltexth->names[33]; // "Garrison" + owner = garr->tempOwner; + built = false; + tType = NULL; + + // Show detailed info only to owning player. + if(detailed) + { + details = new InfoAboutTown::Details; + details->customRes = false; + details->garrisonedHero = false; + details->goldIncome = -1; + details->hallLevel = -1; + } +} + void MetaString::getLocalString(const std::pair &txt, std::string &dst) const { int type = txt.first, ser = txt.second; @@ -2376,7 +2432,10 @@ bool CGameState::isVisible(int3 pos, int player) bool CGameState::isVisible( const CGObjectInstance *obj, int player ) { - if(player == 255) //neutral player + if(player == -1) + return true; + + if(player == 255) //neutral player -> TODO ??? needed? return false; //object is visible when at least one blocked tile is visible for(int fx=0; fx<8; ++fx) diff --git a/lib/CGameState.h b/lib/CGameState.h index e287de3ce..506931e4b 100644 --- a/lib/CGameState.h +++ b/lib/CGameState.h @@ -64,6 +64,7 @@ class CHeroClass; class CCampaign; class CCampaignState; class IModableArt; +class CGGarrison; namespace boost { @@ -102,6 +103,32 @@ public: void initFromHero(const CGHeroInstance *h, bool detailed); }; +/// Struct which holds a short information about a town +struct DLL_EXPORT InfoAboutTown +{ + struct Details + { + int hallLevel, goldIncome; + bool customRes; + bool garrisonedHero; + + } *details; + + const CArmedInstance * obj; + char fortLevel; //0 - none + char owner; + std::string name; + CTown *tType; + bool built; + + ArmyDescriptor army; //numbers of creatures are valid only if details + + InfoAboutTown(); + ~InfoAboutTown(); + void initFromTown(const CGTownInstance *t, bool detailed); + void initFromGarrison(const CGGarrison *garr, bool detailed); +}; + // typedef si32 TResourceUnit; // typedef std::vector TResourceVector; // typedef std::set TResourceSet; @@ -177,8 +204,6 @@ public: }; - - struct UpgradeInfo { int oldID; //creature to be upgraded diff --git a/lib/IGameCallback.cpp b/lib/IGameCallback.cpp index b518991ee..c44a86d97 100644 --- a/lib/IGameCallback.cpp +++ b/lib/IGameCallback.cpp @@ -3,12 +3,17 @@ #include "../lib/CGameState.h" #include "../lib/map.h" #include "CObjectHandler.h" +#include "CHeroHandler.h" #include "../StartInfo.h" #include "CArtHandler.h" #include "CSpellHandler.h" #include "../lib/VCMI_Lib.h" #include #include "CTownHandler.h" +#include "BattleState.h" +#include +#include "NetPacks.h" +#include /* * IGameCallback.cpp, part of VCMI engine @@ -20,83 +25,353 @@ * */ +#define ERROR_SILENT_RET_VAL_IF(cond, txt, retVal) do {if(cond){return retVal;}} while(0) +#define ERROR_RET_IF(cond, txt) do {if(cond){tlog1 << BOOST_CURRENT_FUNCTION << ": " << txt << std::endl; return;}} while(0) +#define ERROR_RET_VAL_IF(cond, txt, retVal) do {if(cond){tlog1 << BOOST_CURRENT_FUNCTION << ": " << txt << std::endl; return retVal;}} while(0) +//#define ERROR_RET_IF(cond, printCond, txt, retVal) do {if(cond){ if(printCond) tlog1 << BOOST_CURRENT_FUNCTION << ": " << txt << std::endl; return retVal;}} while(0) + extern boost::rand48 ran; -CGameState *const IGameCallback::gameState () +si8 CBattleInfoCallback::battleHasDistancePenalty( const CStack * stack, THex destHex ) +{ + return gs->curB->hasDistancePenalty(stack, destHex); +} + +si8 CBattleInfoCallback::battleHasWallPenalty( const CStack * stack, THex destHex ) +{ + return gs->curB->hasWallPenalty(stack, destHex); +} + +si8 CBattleInfoCallback::battleCanTeleportTo(const CStack * stack, THex destHex, int telportLevel) +{ + return gs->curB->canTeleportTo(stack, destHex, telportLevel); +} + +std::vector CBattleInfoCallback::battleGetDistances(const CStack * stack, THex hex /*= THex::INVALID*/, THex * predecessors /*= NULL*/) +{ + if(!hex.isValid()) + hex = stack->position; + + std::vector ret; + bool ac[BFIELD_SIZE] = {0}; + std::set occupyable; + gs->curB->getAccessibilityMap(ac, stack->doubleWide(), stack->attackerOwned, false, occupyable, stack->hasBonusOfType(Bonus::FLYING), stack); + THex pr[BFIELD_SIZE]; + int dist[BFIELD_SIZE]; + gs->curB->makeBFS(stack->position, ac, pr, dist, stack->doubleWide(), stack->attackerOwned, stack->hasBonusOfType(Bonus::FLYING), false); + + for(int i=0; icurB) + { + + tlog1 << "battleCanCastThisSpell called when there is no battle!\n"; + return SpellCasting::NO_HERO_TO_CAST_SPELL; + } + + return gs->curB->battleCanCastThisSpell(player, spell, SpellCasting::HERO_CASTING); +} + +si8 CBattleInfoCallback::battleGetTacticDist() +{ + if (!gs->curB) + { + tlog1 << "battleGetTacticDist called when no battle!\n"; + return 0; + } + + if (gs->curB->sides[gs->curB->tacticsSide] == player) + { + return gs->curB->tacticDistance; + } + return 0; +} + +ui8 CBattleInfoCallback::battleGetMySide() +{ + if (!gs->curB) + { + tlog1 << "battleGetMySide called when no battle!\n"; + return 0; + } + + return gs->curB->sides[1] == player; +} + +int CBattleInfoCallback::battleGetSurrenderCost() +{ + if (!gs->curB) + { + tlog1 << "battleGetSurrenderCost called when no battle!\n"; + return -1; + } + + return gs->curB->getSurrenderingCost(player); +} + +int CBattleInfoCallback::battleGetBattlefieldType() +{ + //boost::shared_lock lock(*gs->mx); + //return gs->battleGetBattlefieldType(); + + if(!gs->curB) + { + tlog2<<"battleGetBattlefieldType called when there is no battle!"<curB->battlefieldType; +} + +int CBattleInfoCallback::battleGetObstaclesAtTile(THex tile) //returns bitfield +{ + //TODO - write + return -1; +} + +std::vector CBattleInfoCallback::battleGetAllObstacles() +{ + //boost::shared_lock lock(*gs->mx); + if(gs->curB) + return gs->curB->obstacles; + else + return std::vector(); +} + +const CStack* CBattleInfoCallback::battleGetStackByID(int ID, bool onlyAlive) +{ + //boost::shared_lock lock(*gs->mx); + if(!gs->curB) return NULL; + return gs->curB->getStack(ID, onlyAlive); +} + +const CStack* CBattleInfoCallback::battleGetStackByPos(THex pos, bool onlyAlive) +{ + //boost::shared_lock lock(*gs->mx); + return gs->curB->battleGetStack(pos, onlyAlive); +} + +THex CBattleInfoCallback::battleGetPos(int stack) +{ + //boost::shared_lock lock(*gs->mx); + if(!gs->curB) + { + tlog2<<"battleGetPos called when there is no battle!"<curB->stacks.size(); ++g) + { + if(gs->curB->stacks[g]->ID == stack) + return gs->curB->stacks[g]->position; + } + return THex::INVALID; +} + +TStacks CBattleInfoCallback::battleGetStacks(EStackOwnership whose /*= MINE_AND_ENEMY*/, bool onlyAlive /*= true*/) +{ + //boost::shared_lock lock(*gs->mx); + TStacks ret; + if(!gs->curB) //there is no battle + { + tlog2<<"battleGetStacks called when there is no battle!"<curB->stacks) + { + bool ownerMatches = whose == MINE_AND_ENEMY || whose == ONLY_MINE && s->owner == player || whose == ONLY_ENEMY && s->owner != player; + bool alivenessMatches = s->alive() || !onlyAlive; + if(ownerMatches && alivenessMatches) + ret.push_back(s); + } + + return ret; +} + +void CBattleInfoCallback::getStackQueue( std::vector &out, int howMany ) +{ + if(!gs->curB) + { + tlog2 << "battleGetStackQueue called when there is not battle!" << std::endl; + return; + } + gs->curB->getStackQueue(out, howMany); +} + +std::vector CBattleInfoCallback::battleGetAvailableHexes(const CStack * stack, bool addOccupiable, std::vector * attackable) +{ + //boost::shared_lock lock(*gs->mx); + if(!gs->curB) + { + tlog2<<"battleGetAvailableHexes called when there is no battle!"<(); + } + return gs->curB->getAccessibility(stack, addOccupiable, attackable); + //return gs->battleGetRange(ID); +} + +bool CBattleInfoCallback::battleCanShoot(const CStack * stack, THex dest) +{ + //boost::shared_lock lock(*gs->mx); + + if(!gs->curB) return false; + + return gs->curB->battleCanShoot(stack, dest); +} + +bool CBattleInfoCallback::battleCanCastSpell() +{ + if(!gs->curB) //there is no battle + return false; + + return gs->curB->battleCanCastSpell(player, SpellCasting::HERO_CASTING) == SpellCasting::OK; +} + +bool CBattleInfoCallback::battleCanFlee() +{ + return gs->curB->battleCanFlee(player); +} + +const CGTownInstance *CBattleInfoCallback::battleGetDefendedTown() +{ + if(!gs->curB || gs->curB->town == NULL) + return NULL; + + return gs->curB->town; +} + +ui8 CBattleInfoCallback::battleGetWallState(int partOfWall) +{ + if(!gs->curB || gs->curB->siege == 0) + { + return 0; + } + return gs->curB->si.wallState[partOfWall]; +} + +int CBattleInfoCallback::battleGetWallUnderHex(THex hex) +{ + if(!gs->curB || gs->curB->siege == 0) + { + return -1; + } + return gs->curB->hexToWallPart(hex); +} + +TDmgRange CBattleInfoCallback::battleEstimateDamage(const CStack * attacker, const CStack * defender, TDmgRange * retaliationDmg) +{ + if(!gs->curB) + return std::make_pair(0, 0); + + const CGHeroInstance * attackerHero, * defenderHero; + bool shooting = battleCanShoot(attacker, defender->position); + + if(gs->curB->sides[0] == attacker->owner) + { + attackerHero = gs->curB->heroes[0]; + defenderHero = gs->curB->heroes[1]; + } + else + { + attackerHero = gs->curB->heroes[1]; + defenderHero = gs->curB->heroes[0]; + } + + TDmgRange ret = gs->curB->calculateDmgRange(attacker, defender, attackerHero, defenderHero, shooting, 0, false, false); + + if(retaliationDmg) + { + if(shooting) + { + retaliationDmg->first = retaliationDmg->second = 0; + } + else + { + ui32 TDmgRange::* pairElems[] = {&TDmgRange::first, &TDmgRange::second}; + for (int i=0; i<2; ++i) + { + BattleStackAttacked bsa; + bsa.damageAmount = ret.*pairElems[i]; + retaliationDmg->*pairElems[!i] = gs->curB->calculateDmgRange(defender, attacker, bsa.newAmount, attacker->count, attackerHero, defenderHero, false, false, false, false).*pairElems[!i]; + } + } + } + + return ret; +} + +ui8 CBattleInfoCallback::battleGetSiegeLevel() +{ + if(!gs->curB) + return 0; + + return gs->curB->siege; +} + +const CGHeroInstance * CBattleInfoCallback::battleGetFightingHero(ui8 side) const +{ + if(!gs->curB) + return 0; + + return gs->curB->heroes[side]; +} + + + +CGameState *const CPrivilagedInfoCallback::gameState () { return gs; } -const CGObjectInstance* IGameCallback::getObj(int objid, bool verbose) -{ - if(objid < 0 || objid >= gs->map->objects.size()) - { - if(verbose) - tlog1 << "Cannot get object with id " << objid << std::endl; - return NULL; - } - else if (!gs->map->objects[objid]) - { - if(verbose) - tlog1 << "Cannot get object with id " << objid << ". Object was removed.\n"; - return NULL; - } - return gs->map->objects[objid]; -} -const CGHeroInstance* IGameCallback::getHero(int objid) -{ - const CGObjectInstance *obj = getObj(objid, false); - if(obj) - return dynamic_cast(obj); - else - return NULL; -} -const CGTownInstance* IGameCallback::getTown(int objid) -{ - const CGObjectInstance *obj = getObj(objid, false); - if(obj) - return dynamic_cast(gs->map->objects[objid].get()); - else - return NULL; -} -int IGameCallback::getOwner(int heroID) +int CGameInfoCallback::getOwner(int heroID) const { + const CGObjectInstance *obj = getObj(heroID); + ERROR_RET_VAL_IF(!obj, "No such object!", -1); return gs->map->objects[heroID]->tempOwner; } -int IGameCallback::getResource(int player, int which) + +int CGameInfoCallback::getResource(int Player, int which) const { - return gs->players.find(player)->second.resources[which]; -} -int IGameCallback::getDate(int mode) -{ - return gs->getDate(mode); + const PlayerState *p = getPlayerState(Player); + ERROR_RET_VAL_IF(!p, "No player info!", -1); + ERROR_RET_VAL_IF(p->resources.size() <= which || which < 0, "No such resource!", -1); + return p->resources[which]; } -const CGHeroInstance* IGameCallback::getSelectedHero( int player ) +const CGHeroInstance* CGameInfoCallback::getSelectedHero( int Player ) const { - if(gs->players.find(player)->second.currentSelection==-1) - return NULL; - return getHero(gs->players.find(player)->second.currentSelection); + const PlayerState *p = getPlayerState(Player); + ERROR_RET_VAL_IF(!p, "No player info!", NULL); + return getHero(p->currentSelection); } -const PlayerSettings * IGameCallback::getPlayerSettings( int color ) +int CGameInfoCallback::getSelectedHero() const +{ + const CGHeroInstance *h = getSelectedHero(gs->currentPlayer); + return h ? h->id : -1; // TODO synchronous turns? +} + +const PlayerSettings * CGameInfoCallback::getPlayerSettings(int color) const { return &gs->scenarioOps->getIthPlayersSettings(color); } -int IGameCallback::getHeroCount( int player, bool includeGarrisoned ) -{ - int ret = 0; - if(includeGarrisoned) - return gs->getPlayer(player)->heroes.size(); - else - for(int i=0; i < gs->getPlayer(player)->heroes.size(); i++) - if(!gs->getPlayer(player)->heroes[i]->inTownGarrison) - ret++; - return ret; -} - -void IGameCallback::getTilesInRange( boost::unordered_set &tiles, int3 pos, int radious, int player/*=-1*/, int mode/*=0*/ ) +void CPrivilagedInfoCallback::getTilesInRange( boost::unordered_set &tiles, int3 pos, int radious, int player/*=-1*/, int mode/*=0*/ ) const { if(player >= PLAYER_LIMIT) { @@ -126,9 +401,9 @@ void IGameCallback::getTilesInRange( boost::unordered_set &tile } } -void IGameCallback::getAllTiles (boost::unordered_set &tiles, int player/*=-1*/, int level, int surface ) +void CPrivilagedInfoCallback::getAllTiles (boost::unordered_set &tiles, int Player/*=-1*/, int level, int surface ) const { - if(player >= PLAYER_LIMIT) + if(Player >= PLAYER_LIMIT) { tlog1 << "Illegal call to getAllTiles !\n"; return; @@ -164,7 +439,7 @@ void IGameCallback::getAllTiles (boost::unordered_set &tiles, i } } -void IGameCallback::getFreeTiles (std::vector &tiles) +void CPrivilagedInfoCallback::getFreeTiles (std::vector &tiles) const { std::vector floors; for (int b=0; bmap->twoLevel + 1; ++b) //if gs->map->twoLevel is false then false (0) + 1 is 1, if it's true (1) then we have 2 @@ -179,16 +454,15 @@ void IGameCallback::getFreeTiles (std::vector &tiles) { for (int yd = 0; yd < gs->map->height; yd++) { - tinfo = getTile (int3 (xd,yd,zd)); + tinfo = getTile(int3 (xd,yd,zd)); if (tinfo->tertype != 8 && !tinfo->blocked) //land and free tiles.push_back (int3 (xd,yd,zd)); } } } - } -bool IGameCallback::isAllowed( int type, int id ) +bool CGameInfoCallback::isAllowed( int type, int id ) { switch(type) { @@ -199,12 +473,11 @@ bool IGameCallback::isAllowed( int type, int id ) case 2: return gs->map->allowedAbilities[id]; default: - tlog1 << "Wrong call to IGameCallback::isAllowed!\n"; - return false; + ERROR_RET_VAL_IF(1, "Wrong type!", false); } } -void IGameCallback::pickAllowedArtsSet(std::vector &out) +void CPrivilagedInfoCallback::pickAllowedArtsSet(std::vector &out) { for (int i = 0; i < 2; i++) { @@ -216,23 +489,23 @@ void IGameCallback::pickAllowedArtsSet(std::vector &out) out.push_back(VLC->arth->artifacts[getRandomArt(CArtifact::ART_MAJOR)]); } -ui16 IGameCallback::getRandomArt (int flags) +ui16 CPrivilagedInfoCallback::getRandomArt (int flags) { return VLC->arth->getRandomArt(flags); } -ui16 IGameCallback::getArtSync (ui32 rand, int flags) +ui16 CPrivilagedInfoCallback::getArtSync (ui32 rand, int flags) { return VLC->arth->getArtSync (rand, flags); } -void IGameCallback::erasePickedArt (si32 id) +void CPrivilagedInfoCallback::erasePickedArt (si32 id) { VLC->arth->erasePickedArt(id); } -void IGameCallback::getAllowedSpells(std::vector &out, ui16 level) +void CPrivilagedInfoCallback::getAllowedSpells(std::vector &out, ui16 level) { CSpell *spell; @@ -246,30 +519,525 @@ void IGameCallback::getAllowedSpells(std::vector &out, ui16 level) } } -int3 IGameCallback::getMapSize() -{ - return int3(gs->map->width, gs->map->height, gs->map->twoLevel + 1); -} - -inline TerrainTile * IGameCallback::getTile( int3 pos ) +inline TerrainTile * CPrivilagedInfoCallback::getTile( int3 pos ) const { if(!gs->map->isInTheMap(pos)) return NULL; return &gs->map->getTile(pos); } -const PlayerState * IGameCallback::getPlayerState( int color ) +const PlayerState * CGameInfoCallback::getPlayerState(int color) const { + ERROR_RET_VAL_IF(!hasAccess(color), "Cannot access player " << color << "info!", NULL); return gs->getPlayer(color, false); } -const CTown * IGameCallback::getNativeTown(int color) +const CTown * CGameInfoCallback::getNativeTown(int color) const { - return &VLC->townh->towns[gs->scenarioOps->getIthPlayersSettings(color).castle]; + const PlayerSettings *ps = getPlayerSettings(color); + ERROR_RET_VAL_IF(!ps, "There is no such player!", NULL); + return &VLC->townh->towns[ps->castle]; } -const CGObjectInstance * IGameCallback::getObjByQuestIdentifier(int identifier) +const CGObjectInstance * CGameInfoCallback::getObjByQuestIdentifier(int identifier) const { - assert(vstd::contains(gs->map->questIdentifierToId, identifier)); + ERROR_RET_VAL_IF(!vstd::contains(gs->map->questIdentifierToId, identifier), "There is no object with such quest identifier!", NULL); return getObj(gs->map->questIdentifierToId[identifier]); -} \ No newline at end of file +} + +/************************************************************************/ +/* */ +/************************************************************************/ + +const CGObjectInstance* CGameInfoCallback::getObj(int objid, bool verbose) const +{ + if(objid < 0 || objid >= gs->map->objects.size()) + { + if(verbose) + tlog1 << "Cannot get object with id " << objid << std::endl; + return NULL; + } + + const CGObjectInstance *ret = gs->map->objects[objid]; + if(!ret) + { + if(verbose) + tlog1 << "Cannot get object with id " << objid << ". Object was removed.\n"; + return NULL; + } + + if(!isVisible(ret, player)) + { + if(verbose) + tlog1 << "Cannot get object with id " << objid << ". Object is not visible.\n"; + return NULL; + } + + return ret; +} + +const CGHeroInstance* CGameInfoCallback::getHero(int objid) const +{ + const CGObjectInstance *obj = getObj(objid, false); + if(obj) + return dynamic_cast(obj); + else + return NULL; +} +const CGTownInstance* CGameInfoCallback::getTown(int objid) const +{ + const CGObjectInstance *obj = getObj(objid, false); + if(obj) + return dynamic_cast(gs->map->objects[objid].get()); + else + return NULL; +} + +void CGameInfoCallback::getUpgradeInfo(const CArmedInstance *obj, int stackPos, UpgradeInfo &out) const +{ + //boost::shared_lock lock(*gs->mx); + ERROR_RET_IF(!canGetFullInfo(obj), "Cannot get info about not owned object!"); + ERROR_RET_IF(!obj->hasStackAtSlot(stackPos), "There is no such stack!"); + out = gs->getUpgradeInfo(obj->getStack(stackPos)); + //return gs->getUpgradeInfo(obj->getStack(stackPos)); +} + +const StartInfo * CGameInfoCallback::getStartInfo() const +{ + //boost::shared_lock lock(*gs->mx); + return gs->scenarioOps; +} + +int CGameInfoCallback::getSpellCost(const CSpell * sp, const CGHeroInstance * caster) const +{ + //boost::shared_lock lock(*gs->mx); + ERROR_RET_VAL_IF(!canGetFullInfo(caster), "Cannot get info about caster!", -1); + //if there is a battle + if(gs->curB) + return gs->curB->getSpellCost(sp, caster); + + //if there is no battle + return caster->getSpellCost(sp); +} + +int CGameInfoCallback::estimateSpellDamage(const CSpell * sp, const CGHeroInstance * hero) const +{ + //boost::shared_lock lock(*gs->mx); + + ERROR_RET_VAL_IF(hero && !canGetFullInfo(hero), "Cannot get info about caster!", -1); + if(!gs->curB) //no battle + { + if (hero) //but we see hero's spellbook + return gs->curB->calculateSpellDmg(sp, hero, NULL, hero->getSpellSchoolLevel(sp), hero->getPrimSkillLevel(2)); + else + return 0; //mage guild + } + //gs->getHero(gs->currentPlayer) + //const CGHeroInstance * ourHero = gs->curB->heroes[0]->tempOwner == player ? gs->curB->heroes[0] : gs->curB->heroes[1]; + const CGHeroInstance * ourHero = hero; + return gs->curB->calculateSpellDmg(sp, ourHero, NULL, ourHero->getSpellSchoolLevel(sp), ourHero->getPrimSkillLevel(2)); +} + +void CGameInfoCallback::getThievesGuildInfo(SThievesGuildInfo & thi, const CGObjectInstance * obj) +{ + //boost::shared_lock lock(*gs->mx); + ERROR_RET_IF(!obj, "No guild object!"); + ERROR_RET_IF(obj->ID == TOWNI_TYPE && !canGetFullInfo(obj), "Cannot get info about town guild object!"); + //TODO: advmap object -> check if they're visited by our hero + + if(obj->ID == TOWNI_TYPE || obj->ID == 95) //it is a town or adv map tavern + { + gs->obtainPlayersStats(thi, gs->players[obj->tempOwner].towns.size()); + } + else if(obj->ID == 97) //Den of Thieves + { + gs->obtainPlayersStats(thi, 20); + } +} + +int CGameInfoCallback::howManyTowns(int Player) const +{ + ERROR_RET_VAL_IF(!hasAccess(Player), "Access forbidden!", -1); + return gs->players[Player].towns.size(); +} + +bool CGameInfoCallback::getTownInfo( const CGObjectInstance *town, InfoAboutTown &dest ) const +{ + ERROR_RET_VAL_IF(!isVisible(town, player), "Town is not visible!", false); //it's not a town or it's not visible for layer + bool detailed = hasAccess(town->tempOwner); + + //TODO vision support + if(town->ID == TOWNI_TYPE) + dest.initFromTown(static_cast(town), detailed); + else if(town->ID == 33 || town->ID == 219) + dest.initFromGarrison(static_cast(town), detailed); + else + return false; + return true; +} + +int3 CGameInfoCallback::guardingCreaturePosition (int3 pos) const +{ + ERROR_RET_VAL_IF(!isVisible(pos), "Tile is not visible!", int3(-1,-1,-1)); + return gs->guardingCreaturePosition(pos); +} + +bool CGameInfoCallback::getHeroInfo( const CGObjectInstance *hero, InfoAboutHero &dest ) const +{ + const CGHeroInstance *h = dynamic_cast(hero); + + ERROR_RET_VAL_IF(!h, "That's not a hero!", false); + ERROR_RET_VAL_IF(!isVisible(h->getPosition(false)), "That hero is not visible!", false); + + //TODO vision support + dest.initFromHero(h, hasAccess(h->tempOwner)); + return true; +} + +int CGameInfoCallback::getDate(int mode) const +{ + //boost::shared_lock lock(*gs->mx); + return gs->getDate(mode); +} +std::vector < std::string > CGameInfoCallback::getObjDescriptions(int3 pos) const +{ + //boost::shared_lock lock(*gs->mx); + std::vector ret; + const TerrainTile *t = getTileInfo(pos); + ERROR_RET_VAL_IF(!t, "Not a valid tile given!", ret); + + + BOOST_FOREACH(const CGObjectInstance * obj, t->blockingObjects) + ret.push_back(obj->getHoverText()); + return ret; +} +bool CGameInfoCallback::verifyPath(CPath * path, bool blockSea) const +{ + for (size_t i=0; i < path->nodes.size(); ++i) + { + const TerrainTile *t = getTileInfo(path->nodes[i].coord); //current tile + if (t->blocked && !t->visitable) + return false; //path is wrong - one of the tiles is blocked + + if (blockSea) + { + if (i==0) + continue; + + const TerrainTile *prev = getTileInfo(path->nodes[i-1].coord); //tile of previous node on the path + if (( t->tertype == TerrainTile::water && prev->tertype != TerrainTile::water) + || (t->tertype != TerrainTile::water && prev->tertype == TerrainTile::water) + || prev->tertype == TerrainTile::rock + ) + return false; + } + + + } + return true; +} + +bool CGameInfoCallback::isVisible(int3 pos, int Player) const +{ + //boost::shared_lock lock(*gs->mx); + return gs->map->isInTheMap(pos) && gs->isVisible(pos, Player); +} + +bool CGameInfoCallback::isVisible(int3 pos) const +{ + return isVisible(pos,player); +} + +bool CGameInfoCallback::isVisible( const CGObjectInstance *obj, int Player ) const +{ + return gs->isVisible(obj, Player); +} + +bool CGameInfoCallback::isVisible(const CGObjectInstance *obj) const +{ + return isVisible(obj, player); +} +// const CCreatureSet* CInfoCallback::getGarrison(const CGObjectInstance *obj) const +// { +// //boost::shared_lock lock(*gs->mx); +// if() +// const CArmedInstance *armi = dynamic_cast(obj); +// if(!armi) +// return NULL; +// else +// return armi; +// } + +std::vector < const CGObjectInstance * > CGameInfoCallback::getBlockingObjs( int3 pos ) const +{ + std::vector ret; + const TerrainTile *t = getTileInfo(pos); + ERROR_RET_VAL_IF(!t, "Not a valid tile requested!", ret); + + BOOST_FOREACH(const CGObjectInstance * obj, t->blockingObjects) + ret.push_back(obj); + return ret; +} + +std::vector < const CGObjectInstance * > CGameInfoCallback::getVisitableObjs( int3 pos ) const +{ + std::vector ret; + const TerrainTile *t = getTileInfo(pos); + ERROR_RET_VAL_IF(!t, "Not a valid tile requested!", ret); + //boost::shared_lock lock(*gs->mx); + + BOOST_FOREACH(const CGObjectInstance * obj, t->visitableObjects) + ret.push_back(obj); + return ret; +} + +std::vector < const CGObjectInstance * > CGameInfoCallback::getFlaggableObjects(int3 pos) const +{ + std::vector ret; + const TerrainTile *t = getTileInfo(pos); + ERROR_RET_VAL_IF(!t, "Not a valid tile requested!", ret); + BOOST_FOREACH(const CGObjectInstance *obj, t->blockingObjects) + if(obj->tempOwner != 254) + ret.push_back(obj); +// const std::vector < std::pair > & objs = CGI->mh->ttiles[pos.x][pos.y][pos.z].objects; +// for(size_t b=0; btempOwner!=254 && !((objs[b].first->defInfo->blockMap[pos.y - objs[b].first->pos.y + 5] >> (objs[b].first->pos.x - pos.x)) & 1)) +// ret.push_back(CGI->mh->ttiles[pos.x][pos.y][pos.z].objects[b].first); +// } + return ret; +} + +int3 CGameInfoCallback::getMapSize() const +{ + return int3(gs->map->width, gs->map->height, gs->map->twoLevel+1); +} + +std::vector CGameInfoCallback::getAvailableHeroes(const CGObjectInstance * townOrTavern) const +{ + std::vector ret; + ERROR_RET_VAL_IF(!isOwnedOrVisited(townOrTavern), "Town or tavern must be owned or visited!", ret); + ret.resize(gs->players[player].availableHeroes.size()); + std::copy(gs->players[player].availableHeroes.begin(),gs->players[player].availableHeroes.end(),ret.begin()); + return ret; +} + +const TerrainTile * CGameInfoCallback::getTileInfo( int3 tile ) const +{ + //ERROR_RET_VAL_IF(!gs->map->isInTheMap(tile), tile << " is outside the map!", NULL); + ERROR_SILENT_RET_VAL_IF(!isVisible(tile), tile << " is not visible!", NULL); + + //boost::shared_lock lock(*gs->mx); + return &gs->map->getTile(tile); +} + +int CGameInfoCallback::canBuildStructure( const CGTownInstance *t, int ID ) +{ + ERROR_RET_VAL_IF(!canGetFullInfo(t), "Town is not owned!", -1); + return gs->canBuildStructure(t,ID); +} + +std::set CGameInfoCallback::getBuildingRequiments( const CGTownInstance *t, int ID ) +{ + ERROR_RET_VAL_IF(!canGetFullInfo(t), "Town is not owned!", std::set()); + return gs->getBuildingRequiments(t,ID); +} + +const CMapHeader * CGameInfoCallback::getMapHeader() const +{ + return gs->map; +} + +bool CGameInfoCallback::hasAccess(int playerId) const +{ + return gs->getPlayerRelations( playerId, player ) || player < 0; +} + +int CGameInfoCallback::getPlayerStatus(int player) const +{ + const PlayerState *ps = gs->getPlayer(player, false); + if(!ps) + return -1; + return ps->status; +} + +std::string CGameInfoCallback::getTavernGossip(const CGObjectInstance * townOrTavern) const +{ + return "GOSSIP TEST"; +} + +int CGameInfoCallback::getPlayerRelations( ui8 color1, ui8 color2 ) const +{ + return gs->getPlayerRelations(color1, color2); +} + +bool CGameInfoCallback::canGetFullInfo(const CGObjectInstance *obj) const +{ + return !obj || hasAccess(obj->tempOwner); +} + +int CGameInfoCallback::getHeroCount( int player, bool includeGarrisoned ) const +{ + int ret = 0; + const PlayerState *p = gs->getPlayer(player); + ERROR_RET_VAL_IF(!p, "No such player!", -1); + + if(includeGarrisoned) + return p->heroes.size(); + else + for(int i=0; i < p->heroes.size(); i++) + if(!p->heroes[i]->inTownGarrison) + ret++; + return ret; +} + +bool CGameInfoCallback::isOwnedOrVisited(const CGObjectInstance *obj) const +{ + if(canGetFullInfo(obj)) + return true; + + const TerrainTile *t = getTileInfo(obj->visitablePos()); //get entrance tile + const CGObjectInstance *visitor = t->visitableObjects.back(); //visitong hero if present or the obejct itself at last + return visitor->ID == HEROI_TYPE && canGetFullInfo(visitor); //owned or allied hero is a visitor +} + +int CGameInfoCallback::getCurrentPlayer() const +{ + return gs->currentPlayer; +} + +CGameInfoCallback::CGameInfoCallback() +{ +} + +const std::vector< std::vector< std::vector > > & CPlayerSpecificInfoCallback::getVisibilityMap() const +{ + //boost::shared_lock lock(*gs->mx); + return gs->getPlayerTeam(player)->fogOfWarMap; +} + +int CPlayerSpecificInfoCallback::howManyTowns() const +{ + //boost::shared_lock lock(*gs->mx); + ERROR_RET_VAL_IF(player == -1, "Applicable only for player callbacks", -1); + return CGameInfoCallback::howManyTowns(player); +} + +std::vector < const CGTownInstance *> CPlayerSpecificInfoCallback::getTownsInfo(bool onlyOur) const +{ + //boost::shared_lock lock(*gs->mx); + std::vector < const CGTownInstance *> ret = std::vector < const CGTownInstance *>(); + for ( std::map::iterator i=gs->players.begin() ; i!=gs->players.end();i++) + { + for (size_t j=0; j < (*i).second.towns.size(); ++j) + { + if ((*i).first==player + || (isVisible((*i).second.towns[j],player) && !onlyOur)) + { + ret.push_back((*i).second.towns[j]); + } + } + } // for ( std::map::iterator i=gs->players.begin() ; i!=gs->players.end();i++) + return ret; +} +std::vector < const CGHeroInstance *> CPlayerSpecificInfoCallback::getHeroesInfo(bool onlyOur) const +{ + //boost::shared_lock lock(*gs->mx); + std::vector < const CGHeroInstance *> ret; + for(size_t i=0;imap->heroes.size();i++) + { + if( (gs->map->heroes[i]->tempOwner==player) || + (isVisible(gs->map->heroes[i]->getPosition(false),player) && !onlyOur) ) + { + ret.push_back(gs->map->heroes[i]); + } + } + return ret; +} + +int CPlayerSpecificInfoCallback::getMyColor() const +{ + return player; +} + +int CPlayerSpecificInfoCallback::getHeroSerial(const CGHeroInstance * hero) const +{ + //boost::shared_lock lock(*gs->mx); + for (size_t i=0; iplayers[player].heroes.size();i++) + { + if (gs->players[player].heroes[i]==hero) + return i; + } + return -1; +} + +int3 CPlayerSpecificInfoCallback::getGrailPos( float &outKnownRatio ) +{ + if (CGObelisk::obeliskCount == 0) + { + outKnownRatio = 0.0f; + } + else + { + outKnownRatio = (float)CGObelisk::visited[gs->getPlayerTeam(player)->id] / CGObelisk::obeliskCount; + } + return gs->map->grailPos; +} + +std::vector < const CGObjectInstance * > CPlayerSpecificInfoCallback::getMyObjects() const +{ + std::vector < const CGObjectInstance * > ret; + BOOST_FOREACH(const CGObjectInstance * obj, gs->map->objects) + { + if(obj && obj->tempOwner == player) + ret.push_back(obj); + } + return ret; +} + +std::vector < const CGDwelling * > CPlayerSpecificInfoCallback::getMyDwellings() const +{ + std::vector < const CGDwelling * > ret; + BOOST_FOREACH(CGDwelling * dw, gs->getPlayer(player)->dwellings) + { + ret.push_back(dw); + } + return ret; +} + +int CPlayerSpecificInfoCallback::howManyHeroes(bool includeGarrisoned) const +{ + //boost::shared_lock lock(*gs->mx); + ERROR_RET_VAL_IF(player == -1, "Applicable only for player callbacks", -1); + return getHeroCount(player,includeGarrisoned); +} + +const CGHeroInstance* CPlayerSpecificInfoCallback::getHeroBySerial(int serialId) const +{ + const PlayerState *p = getPlayerState(serialId); + ERROR_RET_VAL_IF(!p, "No player info", NULL); + ERROR_RET_VAL_IF(serialId < 0 || serialId >= p->heroes.size(), "No player info", NULL); + return p->heroes[serialId]; +} + +const CGTownInstance* CPlayerSpecificInfoCallback::getTownBySerial(int serialId) const +{ + const PlayerState *p = getPlayerState(serialId); + ERROR_RET_VAL_IF(!p, "No player info", NULL); + ERROR_RET_VAL_IF(serialId < 0 || serialId >= p->towns.size(), "No player info", NULL); + return p->towns[serialId]; +} + +int CPlayerSpecificInfoCallback::getResourceAmount(int type) const +{ + //boost::shared_lock lock(*gs->mx); + ERROR_RET_VAL_IF(player == -1, "Applicable only for player callbacks", -1); + return getResource(player, type); +} + +std::vector CPlayerSpecificInfoCallback::getResourceAmount() const +{ + //boost::shared_lock lock(*gs->mx); + ERROR_RET_VAL_IF(player == -1, "Applicable only for player callbacks", std::vector()); + return gs->players[player].resources; +} diff --git a/lib/IGameCallback.h b/lib/IGameCallback.h index 7ca7f5646..fadfe4feb 100644 --- a/lib/IGameCallback.h +++ b/lib/IGameCallback.h @@ -6,6 +6,7 @@ #include #include "../client/FunctionList.h" #include "CCreatureSet.h" +#include "BattleState.h" /* * IGameCallback.h, part of VCMI engine @@ -40,42 +41,192 @@ class CTown; struct StackLocation; struct ArtifactLocation; class CArtifactInstance; +struct StartInfo; +struct InfoAboutTown; +struct UpgradeInfo; +struct SThievesGuildInfo; +struct CPath; +class CGDwelling; +struct InfoAboutHero; +class CMapHeader; +struct BattleAction; +class CStack; -/// Interface class for handling general game logic and actions -class DLL_EXPORT IGameCallback +typedef std::vector TStacks; + +class CCallbackBase { protected: CGameState *gs; + int player; // -1 gives access to all information, otherwise limited to knowledge of given player + + CCallbackBase(CGameState *GS, int Player) + : gs(GS), player(Player) + {} + CCallbackBase() + : gs(NULL), player(-1) + {} +}; + +class DLL_EXPORT CBattleInfoCallback : public virtual CCallbackBase +{ +public: + enum EStackOwnership + { + ONLY_MINE, ONLY_ENEMY, MINE_AND_ENEMY + }; + + //battle + int battleGetBattlefieldType(); // 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 + int battleGetObstaclesAtTile(THex tile); //returns bitfield + std::vector battleGetAllObstacles(); //returns all obstacles on the battlefield + const CStack * battleGetStackByID(int ID, bool onlyAlive = true); //returns stack info by given ID + const CStack * battleGetStackByPos(THex pos, bool onlyAlive = true); //returns stack info by given pos + THex battleGetPos(int stack); //returns position (tile ID) of stack + TStacks battleGetStacks(EStackOwnership whose = MINE_AND_ENEMY, bool onlyAlive = true); //returns stacks on battlefield + void getStackQueue( std::vector &out, int howMany ); //returns vector of stack in order of their move sequence + std::vector battleGetAvailableHexes(const CStack * stack, bool addOccupiable, std::vector * attackable = NULL); //returns numbers of hexes reachable by creature with id ID + std::vector battleGetDistances(const CStack * stack, THex hex = THex::INVALID, THex * predecessors = NULL); //returns vector of distances to [dest hex number] + bool battleCanShoot(const CStack * stack, THex dest); //returns true if unit with id ID can shoot to dest + bool battleCanCastSpell(); //returns true, if caller can cast a spell + SpellCasting::ESpellCastProblem battleCanCastThisSpell(const CSpell * spell); //determines if given spell can be casted (and returns problem description) + bool battleCanFlee(); //returns true if caller can flee from the battle + int battleGetSurrenderCost(); //returns cost of surrendering battle, -1 if surrendering is not possible + const CGTownInstance * battleGetDefendedTown(); //returns defended town if current battle is a siege, NULL instead + ui8 battleGetWallState(int partOfWall); //for determining state of a part of the wall; format: parameter [0] - keep, [1] - bottom tower, [2] - bottom wall, [3] - below gate, [4] - over gate, [5] - upper wall, [6] - uppert tower, [7] - gate; returned value: 1 - intact, 2 - damaged, 3 - destroyed; 0 - no battle + int battleGetWallUnderHex(THex hex); //returns part of destructible wall / gate / keep under given hex or -1 if not found + TDmgRange battleEstimateDamage(const CStack * attacker, const CStack * defender, TDmgRange * retaliationDmg = NULL); //estimates damage dealt by attacker to defender; it may be not precise especially when stack has randomly working bonuses; returns pair + ui8 battleGetSiegeLevel(); //returns 0 when there is no siege, 1 if fort, 2 is citadel, 3 is castle + const CGHeroInstance * battleGetFightingHero(ui8 side) const; //returns hero corresponding to given side (0 - attacker, 1 - defender) + si8 battleHasDistancePenalty(const CStack * stack, THex destHex); //checks if given stack has distance penalty + si8 battleHasWallPenalty(const CStack * stack, THex destHex); //checks if given stack has wall penalty + si8 battleCanTeleportTo(const CStack * stack, THex destHex, int telportLevel); //checks if teleportation of given stack to given position can take place + si8 battleGetTacticDist(); //returns tactic distance for calling player or 0 if player is not in tactic phase + ui8 battleGetMySide(); //return side of player in battle (attacker/defender) + + //convienience methods using the ones above + TStacks battleGetAllStacks() //returns all stacks, alive or dead or undead or mechanical :) + { + return battleGetStacks(MINE_AND_ENEMY, false); + } +}; + +class DLL_EXPORT CGameInfoCallback : public virtual CCallbackBase +{ +protected: + CGameInfoCallback(); + CGameInfoCallback(CGameState *GS, int Player); + bool hasAccess(int playerId) const; + bool isVisible(int3 pos, int Player) const; + bool isVisible(const CGObjectInstance *obj, int Player) const; + bool isVisible(const CGObjectInstance *obj) const; + + bool canGetFullInfo(const CGObjectInstance *obj) const; //true we player owns obj or ally owns obj or privilaged mode + bool isOwnedOrVisited(const CGObjectInstance *obj) const; + +public: + //various + 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 + const StartInfo * getStartInfo()const; + bool isAllowed(int type, int id); //type: 0 - spell; 1- artifact; 2 - secondary skill + + //player + const PlayerState * getPlayerState(int color) const; + int getResource(int Player, int which) const; + bool isVisible(int3 pos) const; + int getPlayerRelations(ui8 color1, ui8 color2) const;// 0 = enemy, 1 = ally, 2 = same player + void getThievesGuildInfo(SThievesGuildInfo & thi, const CGObjectInstance * obj); //get thieves' guild info obtainable while visiting given object + int getPlayerStatus(int player) const; //-1 if no such player + int getCurrentPlayer() const; //player that currently makes move // TODO synchronous turns + const PlayerSettings * getPlayerSettings(int color) const; + + //armed object + void getUpgradeInfo(const CArmedInstance *obj, int stackPos, UpgradeInfo &out)const; + + //hero + int getHeroCount(int player, bool includeGarrisoned) const; + bool getHeroInfo(const CGObjectInstance *hero, InfoAboutHero &dest) const; + int getSpellCost(const CSpell * sp, const CGHeroInstance * caster) const; //when called during battle, takes into account creatures' spell cost reduction + int estimateSpellDamage(const CSpell * sp, const CGHeroInstance * hero) const; //estimates damage of given spell; returns 0 if spell causes no dmg + bool verifyPath(CPath * path, bool blockSea)const; + + //objects + const CGObjectInstance* getObj(int objid, bool verbose = true) const; + std::vector getBlockingObjs(int3 pos)const; + std::vector getVisitableObjs(int3 pos)const; + std::vector getFlaggableObjects(int3 pos) const; + std::vector getObjDescriptions(int3 pos)const; //returns descriptions of objects at pos in order from the lowest to the highest + int getOwner(int heroID) const; + + //map + int3 guardingCreaturePosition (int3 pos) const; + const CMapHeader * getMapHeader()const; + int3 getMapSize() const; //returns size of map - z is 1 for one - level map and 2 for two level map + const TerrainTile * getTileInfo(int3 tile) const; + + //town + int howManyTowns(int Player) const; + const CGTownInstance * getTownInfo(int val, bool mode)const; //mode = 0 -> val = player town serial; mode = 1 -> val = object id (serial) + std::vector getAvailableHeroes(const CGObjectInstance * townOrTavern) const; //heroes that can be recruited + std::string getTavernGossip(const CGObjectInstance * townOrTavern) const; + 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 + std::set getBuildingRequiments(const CGTownInstance *t, int ID); + virtual bool getTownInfo(const CGObjectInstance *town, InfoAboutTown &dest) const; + + //moved + const CGHeroInstance* getHero(int objid) const; + const CGTownInstance* getTown(int objid) const; + + const CGHeroInstance* getSelectedHero(int player) const; //NULL if no hero is selected + const CGObjectInstance *getObjByQuestIdentifier(int identifier) const; //NULL if object has been removed (eg. killed) + int getSelectedHero() const; + const CTown *getNativeTown(int color) const; +}; + + +class DLL_EXPORT CPlayerSpecificInfoCallback : public CGameInfoCallback +{ +public: + int howManyTowns() const; + int howManyHeroes(bool includeGarrisoned = true) const; + int3 getGrailPos(float &outKnownRatio); + int getMyColor() const; + + std::vector getTownsInfo(bool onlyOur = true) const; //true -> only owned; false -> all visible + int getHeroSerial(const CGHeroInstance * hero)const; + const CGTownInstance* getTownBySerial(int serialId) const; // serial id is [0, number of towns) + const CGHeroInstance* getHeroBySerial(int serialId) const; // serial id is [0, number of heroes) + std::vector getHeroesInfo(bool onlyOur = true) const; //true -> only owned; false -> all visible + std::vector getMyDwellings() const; //returns all dwellings that belong to player + std::vector getMyObjects() const; //returns all objects flagged by belonging player + + int getResourceAmount(int type)const; + std::vector getResourceAmount() const; + const std::vector< std::vector< std::vector > > & getVisibilityMap()const; //returns visibility map + const PlayerSettings * getPlayerSettings(int color) const; +}; + +class DLL_EXPORT CPrivilagedInfoCallback : public CGameInfoCallback +{ +public: + CGameState *const gameState (); + TerrainTile * getTile(int3 pos) const; + void getFreeTiles (std::vector &tiles) const; //used for random spawns + void getTilesInRange(boost::unordered_set &tiles, int3 pos, int radious, int player=-1, int mode=0) const; //mode 1 - only unrevealed tiles; mode 0 - all, mode -1 - only unrevealed + void getAllTiles (boost::unordered_set &tiles, int player=-1, int level=-1, int surface=0) const; //returns all tiles on given level (-1 - both levels, otherwise number of level); surface: 0 - land and water, 1 - only land, 2 - only water + ui16 getRandomArt (int flags); + ui16 getArtSync (ui32 rand, int flags); //synchronous + void pickAllowedArtsSet(std::vector &out); //gives 3 treasures, 3 minors, 1 major -> used by Black Market and Artifact Merchant + void erasePickedArt (si32 id); + void getAllowedSpells(std::vector &out, ui16 level); +}; + +/// Interface class for handling general game logic and actions +class DLL_EXPORT IGameCallback : public CPrivilagedInfoCallback +{ public: virtual ~IGameCallback(){}; - CGameState *const gameState (); - virtual int getOwner(int heroID); - virtual int getResource(int player, int which); - virtual int getDate(int mode=0); ////mode=0 - total days in game, mode=1 - day of week, mode=2 - current week, mode=3 - current month - virtual const CGObjectInstance* getObj(int objid, bool verbose = true); - virtual const CGHeroInstance* getHero(int objid); - virtual const CGTownInstance* getTown(int objid); - virtual const CGHeroInstance* getSelectedHero(int player); //NULL if no hero is selected - virtual const CGObjectInstance *getObjByQuestIdentifier(int identifier); //NULL if object has been removed (eg. killed) - virtual int getCurrentPlayer()=0; - virtual int getSelectedHero()=0; - virtual const PlayerSettings * getPlayerSettings(int color); - virtual int getHeroCount(int player, bool includeGarrisoned); - virtual void getTilesInRange(boost::unordered_set &tiles, int3 pos, int radious, int player=-1, int mode=0); //mode 1 - only unrevealed tiles; mode 0 - all, mode -1 - only unrevealed - virtual void getAllTiles (boost::unordered_set &tiles, int player=-1, int level=-1, int surface=0); //returns all tiles on given level (-1 - both levels, otherwise number of level); surface: 0 - land and water, 1 - only land, 2 - only water - virtual void getFreeTiles (std::vector &tiles); //used for random spawns - virtual bool isAllowed(int type, int id); //type: 0 - spell; 1- artifact; 2 - secondary skill - virtual ui16 getRandomArt (int flags); - virtual ui16 getArtSync (ui32 rand, int flags); //synchronic - virtual void pickAllowedArtsSet(std::vector &out); //gives 3 treasures, 3 minors, 1 major -> used by Black Market and Artifact Merchant - virtual void erasePickedArt (si32 id); - virtual void getAllowedSpells(std::vector &out, ui16 level); - virtual int3 getMapSize(); //returns size of the map - virtual TerrainTile * getTile(int3 pos); - virtual const PlayerState * getPlayerState(int color); - virtual const CTown *getNativeTown(int color); - //do sth virtual void changeSpells(int hid, bool give, const std::set &spells)=0; virtual bool removeObject(int objid)=0; @@ -112,13 +263,9 @@ public: virtual void showCompInfo(ShowInInfobox * comp)=0; virtual void heroVisitCastle(int obj, int heroID)=0; virtual void stopHeroVisitCastle(int obj, int heroID)=0; - //virtual void giveHeroArtifact(int artid, int hid, int position)=0; //pos==-1 - first free slot in backpack=0; pos==-2 - default if available or backpack - //virtual void giveNewArtifact(int hid, int position)=0; - //virtual bool removeArtifact(const CArtifact* art, int hid) = 0; virtual void startBattleI(const CArmedInstance *army1, const CArmedInstance *army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, bool creatureBank = false, boost::function cb = 0, const CGTownInstance *town = NULL)=0; //use hero=NULL for no hero virtual void startBattleI(const CArmedInstance *army1, const CArmedInstance *army2, int3 tile, boost::function cb = 0, bool creatureBank = false)=0; //if any of armies is hero, hero will be used virtual void startBattleI(const CArmedInstance *army1, const CArmedInstance *army2, boost::function cb = 0, bool creatureBank = false)=0; //if any of armies is hero, hero will be used, visitable tile of second obj is place of battle - //virtual void startBattleI(int heroID, CCreatureSet army, int3 tile, boost::function cb)=0; //for hero<=>neutral army virtual void setAmount(int objid, ui32 val)=0; virtual bool moveHero(si32 hid, int3 dst, ui8 instant, ui8 asker = 255)=0; virtual void giveHeroBonus(GiveBonus * bonus)=0; diff --git a/server/CGameHandler.cpp b/server/CGameHandler.cpp index 069cebc21..795014b4f 100644 --- a/server/CGameHandler.cpp +++ b/server/CGameHandler.cpp @@ -735,7 +735,7 @@ int CGameHandler::moveStack(int stack, THex dest) CGameHandler::CGameHandler(void) { QID = 1; - gs = NULL; + //gs = NULL; IObjectInterface::cb = this; applier = new CApplier; registerTypes3(*applier); @@ -1563,11 +1563,6 @@ ui32 CGameHandler::showBlockingDialog( BlockingDialog *iw ) return 0; } -int CGameHandler::getCurrentPlayer() -{ - return gs->currentPlayer; -} - void CGameHandler::giveResource(int player, int which, int val) { if(!val) return; //don't waste time on empty call @@ -1710,11 +1705,6 @@ void CGameHandler::changeSpells( int hid, bool give, const std::set &spell sendAndApply(&cs); } -int CGameHandler::getSelectedHero() -{ - return IGameCallback::getSelectedHero(getCurrentPlayer())->id; -} - void CGameHandler::setObjProperty( int objid, int prop, si64 val ) { SetObjectProperty sob; @@ -2476,8 +2466,8 @@ bool CGameHandler::garrisonSwap( si32 tid ) // Function moves artifact from src to dst. If dst is not a backpack and is already occupied, old dst art goes to backpack and is replaced. bool CGameHandler::moveArtifact(si32 srcHeroID, si32 destHeroID, ui16 srcSlot, ui16 destSlot) { - CGHeroInstance *srcHero = gs->getHero(srcHeroID); - CGHeroInstance *destHero = gs->getHero(destHeroID); + const CGHeroInstance *srcHero = getHero(srcHeroID); + const CGHeroInstance *destHero = getHero(destHeroID); ArtifactLocation src(srcHero, srcSlot), dst(destHero, destSlot); // Make sure exchange is even possible between the two heroes. diff --git a/server/CGameHandler.h b/server/CGameHandler.h index 944a3c51a..ec1ef0577 100644 --- a/server/CGameHandler.h +++ b/server/CGameHandler.h @@ -127,11 +127,6 @@ public: ////////////////////////////////////////////////////////////////////////// //from IGameCallback - //get info - int getCurrentPlayer() OVERRIDE; - int getSelectedHero() OVERRIDE; - - //do sth void changeSpells(int hid, bool give, const std::set &spells) OVERRIDE; bool removeObject(int objid) OVERRIDE;