diff --git a/CCallback.h b/CCallback.h index 34475f6b6..e783ff3ab 100644 --- a/CCallback.h +++ b/CCallback.h @@ -1,7 +1,8 @@ #pragma once -#include "lib/IGameCallback.h" +#include "lib/CGameInfoCallback.h" +#include "int3.h" // for int3 /* * CCallback.h, part of VCMI engine @@ -29,6 +30,7 @@ struct CPathsInfo; struct CPack; class IBattleEventsReceiver; class IGameEventsReceiver; +struct ArtifactLocation; class IBattleCallback { diff --git a/lib/CGameInfoCallback.cpp b/lib/CGameInfoCallback.cpp new file mode 100644 index 000000000..39da01b9a --- /dev/null +++ b/lib/CGameInfoCallback.cpp @@ -0,0 +1,736 @@ +/* + * CGameInfoCallback.cpp, part of VCMI engine + * + * Authors: listed in file AUTHORS in main folder + * + * License: GNU General Public License v2.0 or later + * Full text of license available in license.txt file, in main folder + * + */ + +#include "StdInc.h" +#include "CGameInfoCallback.h" + +#include "CGameState.h" // PlayerState +#include "CObjectHandler.h" // for CGObjectInstance +#include "StartInfo.h" // for StartInfo +#include "BattleState.h" // for BattleInfo +#include "NetPacks.h" // for InfoWindow + +//TODO make clean +#define ERROR_VERBOSE_OR_NOT_RET_VAL_IF(cond, verbose, txt, retVal) do {if(cond){if(verbose)logGlobal->errorStream() << BOOST_CURRENT_FUNCTION << ": " << txt; return retVal;}} while(0) +#define ERROR_RET_IF(cond, txt) do {if(cond){logGlobal->errorStream() << BOOST_CURRENT_FUNCTION << ": " << txt; return;}} while(0) +#define ERROR_RET_VAL_IF(cond, txt, retVal) do {if(cond){logGlobal->errorStream() << BOOST_CURRENT_FUNCTION << ": " << txt; return retVal;}} while(0) + +PlayerColor CGameInfoCallback::getOwner(ObjectInstanceID heroID) const +{ + const CGObjectInstance *obj = getObj(heroID); + ERROR_RET_VAL_IF(!obj, "No such object!", PlayerColor::CANNOT_DETERMINE); + return obj->tempOwner; +} + +int CGameInfoCallback::getResource(PlayerColor Player, Res::ERes which) const +{ + const PlayerState *p = getPlayer(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* CGameInfoCallback::getSelectedHero( PlayerColor Player ) const +{ + const PlayerState *p = getPlayer(Player); + ERROR_RET_VAL_IF(!p, "No player info!", nullptr); + return getHero(p->currentSelection); +} + +const CGHeroInstance* CGameInfoCallback::getSelectedHero() const +{ + return getSelectedHero(gs->currentPlayer); +} + +const PlayerSettings * CGameInfoCallback::getPlayerSettings(PlayerColor color) const +{ + return &gs->scenarioOps->getIthPlayersSettings(color); +} + +bool CGameInfoCallback::isAllowed( int type, int id ) +{ + switch(type) + { + case 0: + return gs->map->allowedSpell[id]; + case 1: + return gs->map->allowedArtifact[id]; + case 2: + return gs->map->allowedAbilities[id]; + default: + ERROR_RET_VAL_IF(1, "Wrong type!", false); + } +} + +const PlayerState * CGameInfoCallback::getPlayer(PlayerColor color, bool verbose) const +{ + ERROR_VERBOSE_OR_NOT_RET_VAL_IF(!hasAccess(color), verbose, "Cannot access player " << color << "info!", nullptr); + ERROR_VERBOSE_OR_NOT_RET_VAL_IF(!vstd::contains(gs->players,color), verbose, "Cannot find player " << color << "info!", nullptr); + return &gs->players[color]; +} + +const CTown * CGameInfoCallback::getNativeTown(PlayerColor color) const +{ + const PlayerSettings *ps = getPlayerSettings(color); + ERROR_RET_VAL_IF(!ps, "There is no such player!", nullptr); + return VLC->townh->factions[ps->castle]->town; +} + +const CGObjectInstance * CGameInfoCallback::getObjByQuestIdentifier(int identifier) const +{ + ERROR_RET_VAL_IF(!vstd::contains(gs->map->questIdentifierToId, identifier), "There is no object with such quest identifier!", nullptr); + return getObj(gs->map->questIdentifierToId[identifier]); +} + +/************************************************************************/ +/* */ +/************************************************************************/ + +const CGObjectInstance* CGameInfoCallback::getObj(ObjectInstanceID objid, bool verbose) const +{ + si32 oid = objid.num; + if(oid < 0 || oid >= gs->map->objects.size()) + { + if(verbose) + logGlobal->errorStream() << "Cannot get object with id " << oid; + return nullptr; + } + + const CGObjectInstance *ret = gs->map->objects[oid]; + if(!ret) + { + if(verbose) + logGlobal->errorStream() << "Cannot get object with id " << oid << ". Object was removed."; + return nullptr; + } + + if(!isVisible(ret, player)) + { + if(verbose) + logGlobal->errorStream() << "Cannot get object with id " << oid << ". Object is not visible."; + return nullptr; + } + + return ret; +} + +const CGHeroInstance* CGameInfoCallback::getHero(ObjectInstanceID objid) const +{ + const CGObjectInstance *obj = getObj(objid, false); + if(obj) + return dynamic_cast(obj); + else + return nullptr; +} +const CGTownInstance* CGameInfoCallback::getTown(ObjectInstanceID objid) const +{ + const CGObjectInstance *obj = getObj(objid, false); + if(obj) + return dynamic_cast(obj); + else + return nullptr; +} + +void CGameInfoCallback::getUpgradeInfo(const CArmedInstance *obj, SlotID 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(bool beforeRandomization /*= false*/) const +{ + //boost::shared_lock lock(*gs->mx); + if(beforeRandomization) + return gs->initialOpts; + else + 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->battleGetSpellCost(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, nullptr, hero->getSpellSchoolLevel(sp), hero->getPrimSkillLevel(PrimarySkill::SPELL_POWER)); + 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, nullptr, ourHero->getSpellSchoolLevel(sp), ourHero->getPrimSkillLevel(PrimarySkill::SPELL_POWER)); +} + +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 == Obj::TOWN && !canGetFullInfo(obj), "Cannot get info about town guild object!"); + //TODO: advmap object -> check if they're visited by our hero + + if(obj->ID == Obj::TOWN || obj->ID == Obj::TAVERN) + { + gs->obtainPlayersStats(thi, gs->players[obj->tempOwner].towns.size()); + } + else if(obj->ID == Obj::DEN_OF_THIEVES) + { + gs->obtainPlayersStats(thi, 20); + } +} + +int CGameInfoCallback::howManyTowns(PlayerColor 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 == Obj::TOWN) + dest.initFromTown(static_cast(town), detailed); + else if(town->ID == Obj::GARRISON || town->ID == Obj::GARRISON2) + dest.initFromArmy(static_cast(town), detailed); + else + return false; + return true; +} + +int3 CGameInfoCallback::guardingCreaturePosition (int3 pos) const //FIXME: redundant? +{ + ERROR_RET_VAL_IF(!isVisible(pos), "Tile is not visible!", int3(-1,-1,-1)); + return gs->guardingCreaturePosition(pos); +} + +std::vector CGameInfoCallback::getGuardingCreatures (int3 pos) const +{ + ERROR_RET_VAL_IF(!isVisible(pos), "Tile is not visible!", std::vector()); + std::vector ret; + for(auto cr : gs->guardingCreatures(pos)) + { + ret.push_back(cr); + } + return ret; +} + +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(Date::EDateType 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 = getTile(pos); + ERROR_RET_VAL_IF(!t, "Not a valid tile given!", ret); + + + for(const CGObjectInstance * obj : t->blockingObjects) + ret.push_back(obj->getHoverText()); + return ret; +} + +bool CGameInfoCallback::isVisible(int3 pos, boost::optional Player) const +{ + //boost::shared_lock lock(*gs->mx); + return gs->map->isInTheMap(pos) && (!Player || gs->isVisible(pos, *Player)); +} + +bool CGameInfoCallback::isVisible(int3 pos) const +{ + return isVisible(pos, player); +} + +bool CGameInfoCallback::isVisible( const CGObjectInstance *obj, boost::optional 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 nullptr; +// else +// return armi; +// } + +std::vector < const CGObjectInstance * > CGameInfoCallback::getBlockingObjs( int3 pos ) const +{ + std::vector ret; + const TerrainTile *t = getTile(pos); + ERROR_RET_VAL_IF(!t, "Not a valid tile requested!", ret); + + for(const CGObjectInstance * obj : t->blockingObjects) + ret.push_back(obj); + return ret; +} + +std::vector CGameInfoCallback::getVisitableObjs(int3 pos, bool verbose /*= true*/) const +{ + std::vector ret; + const TerrainTile *t = getTile(pos, verbose); + ERROR_VERBOSE_OR_NOT_RET_VAL_IF(!t, verbose, pos << " is not visible!", ret); + + for(const CGObjectInstance * obj : t->visitableObjects) + { + if(player < nullptr || obj->ID != Obj::EVENT) //hide events from players + ret.push_back(obj); + } + + return ret; +} +const CGObjectInstance * CGameInfoCallback::getTopObj (int3 pos) const +{ + return vstd::backOrNull(getVisitableObjs(pos)); +} + +std::vector < const CGObjectInstance * > CGameInfoCallback::getFlaggableObjects(int3 pos) const +{ + std::vector ret; + const TerrainTile *t = getTile(pos); + ERROR_RET_VAL_IF(!t, "Not a valid tile requested!", ret); + for(const CGObjectInstance *obj : t->blockingObjects) + if(obj->tempOwner != PlayerColor::UNFLAGGABLE) + 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 ? 2 : 1); +} + +std::vector CGameInfoCallback::getAvailableHeroes(const CGObjectInstance * townOrTavern) const +{ + ASSERT_IF_CALLED_WITH_PLAYER + std::vector ret; + //ERROR_RET_VAL_IF(!isOwnedOrVisited(townOrTavern), "Town or tavern must be owned or visited!", ret); + //TODO: town needs to be owned, advmap tavern needs to be visited; to be reimplemented when visit tracking is done + range::copy(gs->players[*player].availableHeroes, std::back_inserter(ret)); + vstd::erase_if(ret, [](const CGHeroInstance *h) { return h == nullptr; }); + return ret; +} + +const TerrainTile * CGameInfoCallback::getTile( int3 tile, bool verbose) const +{ + ERROR_VERBOSE_OR_NOT_RET_VAL_IF(!isVisible(tile), verbose, tile << " is not visible!", nullptr); + + //boost::shared_lock lock(*gs->mx); + return &gs->map->getTile(tile); +} + +EBuildingState::EBuildingState CGameInfoCallback::canBuildStructure( const CGTownInstance *t, BuildingID ID ) +{ + ERROR_RET_VAL_IF(!canGetFullInfo(t), "Town is not owned!", EBuildingState::TOWN_NOT_OWNED); + + if(!t->town->buildings.count(ID)) + return EBuildingState::BUILDING_ERROR; + + const CBuilding * building = t->town->buildings.at(ID); + + + if(t->hasBuilt(ID)) //already built + return EBuildingState::ALREADY_PRESENT; + + //can we build it? + if(vstd::contains(t->forbiddenBuildings, ID)) + return EBuildingState::FORBIDDEN; //forbidden + + if(ID == BuildingID::CAPITOL) + { + const PlayerState *ps = getPlayer(t->tempOwner); + if(ps) + { + for(const CGTownInstance *t : ps->towns) + { + if(t->hasBuilt(BuildingID::CAPITOL)) + { + return EBuildingState::HAVE_CAPITAL; //no more than one capitol + } + } + } + } + else if(ID == BuildingID::SHIPYARD) + { + const TerrainTile *tile = getTile(t->bestLocation(), false); + + if(!tile || tile->terType != ETerrainType::WATER) + return EBuildingState::NO_WATER; //lack of water + } + + auto buildTest = [&](const BuildingID & id) + { + return t->hasBuilt(id); + }; + + if(t->builded >= VLC->modh->settings.MAX_BUILDING_PER_TURN) + return EBuildingState::CANT_BUILD_TODAY; //building limit + + if (!building->requirements.test(buildTest)) + return EBuildingState::PREREQUIRES; + + if (building->upgrade != BuildingID::NONE && !t->hasBuilt(building->upgrade)) + return EBuildingState::MISSING_BASE; + + //checking resources + if(!building->resources.canBeAfforded(getPlayer(t->tempOwner)->resources)) + return EBuildingState::NO_RESOURCES; //lack of res + + return EBuildingState::ALLOWED; +} + +const CMapHeader * CGameInfoCallback::getMapHeader() const +{ + return gs->map; +} + +bool CGameInfoCallback::hasAccess(boost::optional playerId) const +{ + return !player || gs->getPlayerRelations( *playerId, *player ) != PlayerRelations::ENEMIES; +} + +EPlayerStatus::EStatus CGameInfoCallback::getPlayerStatus(PlayerColor player, bool verbose) const +{ + const PlayerState *ps = gs->getPlayer(player, verbose); + ERROR_VERBOSE_OR_NOT_RET_VAL_IF(!ps, verbose, "No such player!", EPlayerStatus::WRONG); + + return ps->status; +} + +std::string CGameInfoCallback::getTavernGossip(const CGObjectInstance * townOrTavern) const +{ + return "GOSSIP TEST"; +} + +PlayerRelations::PlayerRelations CGameInfoCallback::getPlayerRelations( PlayerColor color1, PlayerColor color2 ) const +{ + return gs->getPlayerRelations(color1, color2); +} + +bool CGameInfoCallback::canGetFullInfo(const CGObjectInstance *obj) const +{ + return !obj || hasAccess(obj->tempOwner); +} + +int CGameInfoCallback::getHeroCount( PlayerColor 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(auto & elem : p->heroes) + if(!elem->inTownGarrison) + ret++; + return ret; +} + +bool CGameInfoCallback::isOwnedOrVisited(const CGObjectInstance *obj) const +{ + if(canGetFullInfo(obj)) + return true; + + const TerrainTile *t = getTile(obj->visitablePos()); //get entrance tile + const CGObjectInstance *visitor = t->visitableObjects.back(); //visitong hero if present or the obejct itself at last + return visitor->ID == Obj::HERO && canGetFullInfo(visitor); //owned or allied hero is a visitor +} + +PlayerColor CGameInfoCallback::getCurrentPlayer() const +{ + return gs->currentPlayer; +} + +CGameInfoCallback::CGameInfoCallback() +{ +} + +CGameInfoCallback::CGameInfoCallback(CGameState *GS, boost::optional Player) +{ + gs = GS; + player = Player; +} + +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, "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(const auto & i : gs->players) + { + for(const auto & town : i.second.towns) + { + if (i.first==player || (isVisible(town, player) && !onlyOur)) + { + ret.push_back(town); + } + } + } // 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(auto hero : gs->map->heroesOnMap) + { + if( !player || (hero->tempOwner == *player) || + (isVisible(hero->getPosition(false), player) && !onlyOur) ) + { + ret.push_back(hero); + } + } + return ret; +} + +boost::optional CPlayerSpecificInfoCallback::getMyColor() const +{ + return player; +} + +int CPlayerSpecificInfoCallback::getHeroSerial(const CGHeroInstance * hero, bool includeGarrisoned) const +{ + if (hero->inTownGarrison && !includeGarrisoned) + return -1; + + size_t index = 0; + auto & heroes = gs->players[*player].heroes; + + for (auto & heroe : heroes) + { + if (includeGarrisoned || !(heroe)->inTownGarrison) + index++; + + if (heroe == hero) + return index; + } + return -1; +} + +int3 CPlayerSpecificInfoCallback::getGrailPos( double &outKnownRatio ) +{ + if (!player || CGObelisk::obeliskCount == 0) + { + outKnownRatio = 0.0; + } + else + { + outKnownRatio = static_cast(CGObelisk::visited[gs->getPlayerTeam(*player)->id]) / CGObelisk::obeliskCount; + } + return gs->map->grailPos; +} + +std::vector < const CGObjectInstance * > CPlayerSpecificInfoCallback::getMyObjects() const +{ + std::vector < const CGObjectInstance * > ret; + for(const CGObjectInstance * obj : gs->map->objects) + { + if(obj && obj->tempOwner == player) + ret.push_back(obj); + } + return ret; +} + +std::vector < const CGDwelling * > CPlayerSpecificInfoCallback::getMyDwellings() const +{ + ASSERT_IF_CALLED_WITH_PLAYER + std::vector < const CGDwelling * > ret; + for(CGDwelling * dw : gs->getPlayer(*player)->dwellings) + { + ret.push_back(dw); + } + return ret; +} + +std::vector CPlayerSpecificInfoCallback::getMyQuests() const +{ + std::vector ret; + for (auto quest : gs->getPlayer(*player)->quests) + { + ret.push_back (quest); + } + return ret; +} + +int CPlayerSpecificInfoCallback::howManyHeroes(bool includeGarrisoned) const +{ + //boost::shared_lock lock(*gs->mx); + ERROR_RET_VAL_IF(!player, "Applicable only for player callbacks", -1); + return getHeroCount(*player,includeGarrisoned); +} + +const CGHeroInstance* CPlayerSpecificInfoCallback::getHeroBySerial(int serialId, bool includeGarrisoned) const +{ + ASSERT_IF_CALLED_WITH_PLAYER + const PlayerState *p = getPlayer(*player); + ERROR_RET_VAL_IF(!p, "No player info", nullptr); + + if (!includeGarrisoned) + { + for(ui32 i = 0; i < p->heroes.size() && i<=serialId; i++) + if(p->heroes[i]->inTownGarrison) + serialId++; + } + ERROR_RET_VAL_IF(serialId < 0 || serialId >= p->heroes.size(), "No player info", nullptr); + return p->heroes[serialId]; +} + +const CGTownInstance* CPlayerSpecificInfoCallback::getTownBySerial(int serialId) const +{ + ASSERT_IF_CALLED_WITH_PLAYER + const PlayerState *p = getPlayer(*player); + ERROR_RET_VAL_IF(!p, "No player info", nullptr); + ERROR_RET_VAL_IF(serialId < 0 || serialId >= p->towns.size(), "No player info", nullptr); + return p->towns[serialId]; +} + +int CPlayerSpecificInfoCallback::getResourceAmount(Res::ERes type) const +{ + //boost::shared_lock lock(*gs->mx); + ERROR_RET_VAL_IF(!player, "Applicable only for player callbacks", -1); + return getResource(*player, type); +} + +TResources CPlayerSpecificInfoCallback::getResourceAmount() const +{ + //boost::shared_lock lock(*gs->mx); + ERROR_RET_VAL_IF(!player, "Applicable only for player callbacks", TResources()); + return gs->players[*player].resources; +} + +const TeamState * CGameInfoCallback::getTeam( TeamID teamID ) const +{ + ERROR_RET_VAL_IF(!vstd::contains(gs->teams, teamID), "Cannot find info for team " << teamID, nullptr); + const TeamState *ret = &gs->teams[teamID]; + ERROR_RET_VAL_IF(!!player && !vstd::contains(ret->players, *player), "Illegal attempt to access team data!", nullptr); + return ret; +} + +const TeamState * CGameInfoCallback::getPlayerTeam( PlayerColor color ) const +{ + const PlayerState * ps = getPlayer(color); + if (ps) + return getTeam(ps->team); + return nullptr; +} + +const CGHeroInstance* CGameInfoCallback::getHeroWithSubid( int subid ) const +{ + for(const CGHeroInstance *h : gs->map->heroesOnMap) + if(h->subID == subid) + return h; + + return nullptr; +} + +PlayerColor CGameInfoCallback::getLocalPlayer() const +{ + return getCurrentPlayer(); +} + +bool CGameInfoCallback::isInTheMap(const int3 &pos) const +{ + return gs->map->isInTheMap(pos); +} + +const CArtifactInstance * CGameInfoCallback::getArtInstance( ArtifactInstanceID aid ) const +{ + return gs->map->artInstances[aid.num]; +} + +const CGObjectInstance * CGameInfoCallback::getObjInstance( ObjectInstanceID oid ) const +{ + return gs->map->objects[oid.num]; +} + +void IGameEventRealizer::showInfoDialog( InfoWindow *iw ) +{ + commitPackage(iw); +} + +void IGameEventRealizer::showInfoDialog(const std::string &msg, PlayerColor player) +{ + InfoWindow iw; + iw.player = player; + iw.text << msg; + showInfoDialog(&iw); +} + +void IGameEventRealizer::setObjProperty(ObjectInstanceID objid, int prop, si64 val) +{ + SetObjectProperty sob; + sob.id = objid; + sob.what = prop; + sob.val = static_cast(val); + commitPackage(&sob); +} + diff --git a/lib/CGameInfoCallback.h b/lib/CGameInfoCallback.h new file mode 100644 index 000000000..aeade6a56 --- /dev/null +++ b/lib/CGameInfoCallback.h @@ -0,0 +1,148 @@ +#pragma once + +#include "ResourceSet.h" // for Res::ERes +#include "CBattleCallback.h" //for CCallbackBase + +/* + * CGameInfoCallback.h, part of VCMI engine + * + * Authors: listed in file AUTHORS in main folder + * + * License: GNU General Public License v2.0 or later + * Full text of license available in license.txt file, in main folder + * + */ + +class CGObjectInstance; +struct InfoWindow; +struct PlayerSettings; +struct CPackForClient; +struct TerrainTile; +struct PlayerState; +class CTown; +struct StartInfo; +struct InfoAboutTown; +struct UpgradeInfo; +struct SThievesGuildInfo; +class CGDwelling; +class CMapHeader; +struct TeamState; +struct QuestInfo; +class int3; + + +class DLL_LINKAGE CGameInfoCallback : public virtual CCallbackBase +{ +protected: + CGameInfoCallback(); + CGameInfoCallback(CGameState *GS, boost::optional Player); + bool hasAccess(boost::optional playerId) const; + bool isVisible(int3 pos, boost::optional Player) const; + bool isVisible(const CGObjectInstance *obj, boost::optional Player) const; + bool isVisible(const CGObjectInstance *obj) const; + + bool canGetFullInfo(const CGObjectInstance *obj) const; //true we player owns obj or ally owns obj or privileged mode + bool isOwnedOrVisited(const CGObjectInstance *obj) const; + +public: + //various + int getDate(Date::EDateType mode=Date::DAY)const; //mode=0 - total days in game, mode=1 - day of week, mode=2 - current week, mode=3 - current month + const StartInfo * getStartInfo(bool beforeRandomization = false)const; + bool isAllowed(int type, int id); //type: 0 - spell; 1- artifact; 2 - secondary skill + + //player + const PlayerState * getPlayer(PlayerColor color, bool verbose = true) const; + int getResource(PlayerColor Player, Res::ERes which) const; + bool isVisible(int3 pos) const; + PlayerRelations::PlayerRelations getPlayerRelations(PlayerColor color1, PlayerColor color2) const; + void getThievesGuildInfo(SThievesGuildInfo & thi, const CGObjectInstance * obj); //get thieves' guild info obtainable while visiting given object + EPlayerStatus::EStatus getPlayerStatus(PlayerColor player, bool verbose = true) const; //-1 if no such player + PlayerColor getCurrentPlayer() const; //player that currently makes move // TODO synchronous turns + virtual PlayerColor getLocalPlayer() const; //player that is currently owning given client (if not a client, then returns current player) + const PlayerSettings * getPlayerSettings(PlayerColor color) const; + + + //armed object + void getUpgradeInfo(const CArmedInstance *obj, SlotID stackPos, UpgradeInfo &out)const; + + //hero + const CGHeroInstance* getHero(ObjectInstanceID objid) const; + const CGHeroInstance* getHeroWithSubid(int subid) const; + int getHeroCount(PlayerColor 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 + const CGHeroInstance* getSelectedHero(PlayerColor player) const; //nullptr if no hero is selected + const CGHeroInstance* getSelectedHero() const; //of current (active) player + const CArtifactInstance * getArtInstance(ArtifactInstanceID aid) const; + const CGObjectInstance * getObjInstance(ObjectInstanceID oid) const; + + //objects + const CGObjectInstance* getObj(ObjectInstanceID objid, bool verbose = true) const; + std::vector getBlockingObjs(int3 pos)const; + std::vector getVisitableObjs(int3 pos, bool verbose = true)const; + std::vector getFlaggableObjects(int3 pos) const; + const CGObjectInstance * getTopObj (int3 pos) const; + std::vector getObjDescriptions(int3 pos)const; //returns descriptions of objects at pos in order from the lowest to the highest + PlayerColor getOwner(ObjectInstanceID heroID) const; + const CGObjectInstance *getObjByQuestIdentifier(int identifier) const; //nullptr if object has been removed (eg. killed) + + //map + int3 guardingCreaturePosition (int3 pos) const; + std::vector getGuardingCreatures (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 * getTile(int3 tile, bool verbose = true) const; + bool isInTheMap(const int3 &pos) const; + + //town + const CGTownInstance* getTown(ObjectInstanceID objid) const; + int howManyTowns(PlayerColor 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; + EBuildingState::EBuildingState canBuildStructure(const CGTownInstance *t, BuildingID 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 + virtual bool getTownInfo(const CGObjectInstance *town, InfoAboutTown &dest) const; + const CTown *getNativeTown(PlayerColor color) const; + + //from gs + const TeamState *getTeam(TeamID teamID) const; + const TeamState *getPlayerTeam(PlayerColor color) const; + EBuildingState::EBuildingState canBuildStructure(const CGTownInstance *t, BuildingID ID) const;// 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 +}; + +class DLL_LINKAGE CPlayerSpecificInfoCallback : public CGameInfoCallback +{ +public: + int howManyTowns() const; + int howManyHeroes(bool includeGarrisoned = true) const; + int3 getGrailPos(double &outKnownRatio); + boost::optional getMyColor() const; + + std::vector getTownsInfo(bool onlyOur = true) const; //true -> only owned; false -> all visible + int getHeroSerial(const CGHeroInstance * hero, bool includeGarrisoned=true) const; + const CGTownInstance* getTownBySerial(int serialId) const; // serial id is [0, number of towns) + const CGHeroInstance* getHeroBySerial(int serialId, bool includeGarrisoned=true) 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 + std::vector getMyQuests() const; + + int getResourceAmount(Res::ERes type) const; + TResources getResourceAmount() const; + const std::vector< std::vector< std::vector > > & getVisibilityMap()const; //returns visibility map + const PlayerSettings * getPlayerSettings(PlayerColor color) const; +}; + +class DLL_LINKAGE IGameEventRealizer +{ +public: + virtual void commitPackage(CPackForClient *pack) = 0; + + virtual void showInfoDialog(InfoWindow *iw); + virtual void setObjProperty(ObjectInstanceID objid, int prop, si64 val); + + + virtual void showInfoDialog(const std::string &msg, PlayerColor player); +}; + diff --git a/lib/CGameState.h b/lib/CGameState.h index 5ab648b74..ac56c2455 100644 --- a/lib/CGameState.h +++ b/lib/CGameState.h @@ -15,7 +15,6 @@ #include "ResourceSet.h" #include "int3.h" #include "CObjectHandler.h" -#include "IGameCallback.h" #include "CRandomGenerator.h" /* diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 54ee9da33..66abd0eb3 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -7,6 +7,7 @@ include_directories(${Boost_INCLUDE_DIRS} ${SDL_INCLUDE_DIR} ${ZLIB_INCLUDE_DIR} set(lib_SRCS StdInc.cpp IGameCallback.cpp + CGameInfoCallback.cpp CGameState.cpp CObjectHandler.cpp Connection.cpp diff --git a/lib/CScriptingModule.h b/lib/CScriptingModule.h index cfb6402cb..a45be5d52 100644 --- a/lib/CScriptingModule.h +++ b/lib/CScriptingModule.h @@ -2,7 +2,6 @@ #include "IGameEventsReceiver.h" -#include "IGameCallback.h" /* * CScriptingModule.h, part of VCMI engine @@ -14,6 +13,9 @@ * */ +class IGameEventRealizer; +class CPrivilagedInfoCallback; + class CScriptingModule : public IGameEventsReceiver, public IBattleEventsReceiver { public: @@ -24,4 +26,5 @@ public: CScriptingModule(){} virtual ~CScriptingModule(){} -}; \ No newline at end of file +}; + diff --git a/lib/IGameCallback.cpp b/lib/IGameCallback.cpp index cd47cc630..48c74c3b0 100644 --- a/lib/IGameCallback.cpp +++ b/lib/IGameCallback.cpp @@ -11,66 +11,34 @@ #include "StdInc.h" #include "IGameCallback.h" -#include "CGameState.h" -#include "mapping/CMap.h" -#include "CObjectHandler.h" -#include "CHeroHandler.h" -#include "StartInfo.h" -#include "CArtHandler.h" -#include "CSpellHandler.h" -#include "VCMI_Lib.h" -#include "CTownHandler.h" -#include "BattleState.h" +#include "CHeroHandler.h" // for CHeroHandler +#include "CSpellHandler.h" // for CSpell #include "NetPacks.h" -#include "CBuildingHandler.h" -#include "GameConstants.h" -#include "CModHandler.h" -#include "CDefObjInfoHandler.h" -#include "CBonusTypeHandler.h" +#include "CBonusTypeHandler.h" // for CBonusTypeHandler -#include "Connection.h" +#include "Connection.h" // for SAVEGAME_MAGIC -//TODO make clean -#define ERROR_SILENT_RET_VAL_IF(cond, txt, retVal) do {if(cond){return retVal;}} while(0) -#define ERROR_VERBOSE_OR_NOT_RET_VAL_IF(cond, verbose, txt, retVal) do {if(cond){if(verbose)logGlobal->errorStream() << BOOST_CURRENT_FUNCTION << ": " << txt; return retVal;}} while(0) -#define ERROR_RET_IF(cond, txt) do {if(cond){logGlobal->errorStream() << BOOST_CURRENT_FUNCTION << ": " << txt; return;}} while(0) -#define ERROR_RET_VAL_IF(cond, txt, retVal) do {if(cond){logGlobal->errorStream() << BOOST_CURRENT_FUNCTION << ": " << txt; return retVal;}} while(0) - -CGameState * CPrivilagedInfoCallback::gameState () +void CPrivilagedInfoCallback::getFreeTiles (std::vector &tiles) const { - return gs; -} + std::vector floors; + for (int b = 0; b < (gs->map->twoLevel ? 2 : 1); ++b) + { + floors.push_back(b); + } + const TerrainTile *tinfo; + for (auto zd : floors) + { -PlayerColor CGameInfoCallback::getOwner(ObjectInstanceID heroID) const -{ - const CGObjectInstance *obj = getObj(heroID); - ERROR_RET_VAL_IF(!obj, "No such object!", PlayerColor::CANNOT_DETERMINE); - return obj->tempOwner; -} - -int CGameInfoCallback::getResource(PlayerColor Player, Res::ERes which) const -{ - const PlayerState *p = getPlayer(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* CGameInfoCallback::getSelectedHero( PlayerColor Player ) const -{ - const PlayerState *p = getPlayer(Player); - ERROR_RET_VAL_IF(!p, "No player info!", nullptr); - return getHero(p->currentSelection); -} - -const CGHeroInstance* CGameInfoCallback::getSelectedHero() const -{ - return getSelectedHero(gs->currentPlayer); -} - -const PlayerSettings * CGameInfoCallback::getPlayerSettings(PlayerColor color) const -{ - return &gs->scenarioOps->getIthPlayersSettings(color); + for (int xd = 0; xd < gs->map->width; xd++) + { + for (int yd = 0; yd < gs->map->height; yd++) + { + tinfo = getTile(int3 (xd,yd,zd)); + if (tinfo->terType != ETerrainType::WATER && !tinfo->blocked) //land and free + tiles.push_back (int3 (xd,yd,zd)); + } + } + } } void CPrivilagedInfoCallback::getTilesInRange( std::unordered_set &tiles, int3 pos, int radious, boost::optional player/*=uninit*/, int mode/*=0*/ ) const @@ -126,7 +94,7 @@ void CPrivilagedInfoCallback::getAllTiles (std::unordered_set & for (auto zd : floors) { - + for (int xd = 0; xd < gs->map->width; xd++) { for (int yd = 0; yd < gs->map->height; yd++) @@ -139,44 +107,6 @@ void CPrivilagedInfoCallback::getAllTiles (std::unordered_set & } } -void CPrivilagedInfoCallback::getFreeTiles (std::vector &tiles) const -{ - std::vector floors; - for (int b = 0; b < (gs->map->twoLevel ? 2 : 1); ++b) - { - floors.push_back(b); - } - const TerrainTile *tinfo; - for (auto zd : floors) - { - - for (int xd = 0; xd < gs->map->width; xd++) - { - for (int yd = 0; yd < gs->map->height; yd++) - { - tinfo = getTile(int3 (xd,yd,zd)); - if (tinfo->terType != ETerrainType::WATER && !tinfo->blocked) //land and free - tiles.push_back (int3 (xd,yd,zd)); - } - } - } -} - -bool CGameInfoCallback::isAllowed( int type, int id ) -{ - switch(type) - { - case 0: - return gs->map->allowedSpell[id]; - case 1: - return gs->map->allowedArtifact[id]; - case 2: - return gs->map->allowedAbilities[id]; - default: - ERROR_RET_VAL_IF(1, "Wrong type!", false); - } -} - void CPrivilagedInfoCallback::pickAllowedArtsSet(std::vector &out) { for (int j = 0; j < 3 ; j++) @@ -200,6 +130,10 @@ void CPrivilagedInfoCallback::getAllowedSpells(std::vector &out, ui16 l } } +CGameState * CPrivilagedInfoCallback::gameState () +{ + return gs; +} template void CPrivilagedInfoCallback::loadCommonState(Loader &in) @@ -238,6 +172,7 @@ void CPrivilagedInfoCallback::saveCommonState(Saver &out) const out << gs; } +// hardly memory usage for `-gdwarf-4` flag template DLL_LINKAGE void CPrivilagedInfoCallback::loadCommonState(CLoadIntegrityValidator&); template DLL_LINKAGE void CPrivilagedInfoCallback::loadCommonState(CLoadFile&); template DLL_LINKAGE void CPrivilagedInfoCallback::saveCommonState(CSaveFile&) const; @@ -249,604 +184,6 @@ TerrainTile * CNonConstInfoCallback::getTile( int3 pos ) return &gs->map->getTile(pos); } -const PlayerState * CGameInfoCallback::getPlayer(PlayerColor color, bool verbose) const -{ - ERROR_VERBOSE_OR_NOT_RET_VAL_IF(!hasAccess(color), verbose, "Cannot access player " << color << "info!", nullptr); - ERROR_VERBOSE_OR_NOT_RET_VAL_IF(!vstd::contains(gs->players,color), verbose, "Cannot find player " << color << "info!", nullptr); - return &gs->players[color]; -} - -const CTown * CGameInfoCallback::getNativeTown(PlayerColor color) const -{ - const PlayerSettings *ps = getPlayerSettings(color); - ERROR_RET_VAL_IF(!ps, "There is no such player!", nullptr); - return VLC->townh->factions[ps->castle]->town; -} - -const CGObjectInstance * CGameInfoCallback::getObjByQuestIdentifier(int identifier) const -{ - ERROR_RET_VAL_IF(!vstd::contains(gs->map->questIdentifierToId, identifier), "There is no object with such quest identifier!", nullptr); - return getObj(gs->map->questIdentifierToId[identifier]); -} - -/************************************************************************/ -/* */ -/************************************************************************/ - -const CGObjectInstance* CGameInfoCallback::getObj(ObjectInstanceID objid, bool verbose) const -{ - si32 oid = objid.num; - if(oid < 0 || oid >= gs->map->objects.size()) - { - if(verbose) - logGlobal->errorStream() << "Cannot get object with id " << oid; - return nullptr; - } - - const CGObjectInstance *ret = gs->map->objects[oid]; - if(!ret) - { - if(verbose) - logGlobal->errorStream() << "Cannot get object with id " << oid << ". Object was removed."; - return nullptr; - } - - if(!isVisible(ret, player)) - { - if(verbose) - logGlobal->errorStream() << "Cannot get object with id " << oid << ". Object is not visible."; - return nullptr; - } - - return ret; -} - -const CGHeroInstance* CGameInfoCallback::getHero(ObjectInstanceID objid) const -{ - const CGObjectInstance *obj = getObj(objid, false); - if(obj) - return dynamic_cast(obj); - else - return nullptr; -} -const CGTownInstance* CGameInfoCallback::getTown(ObjectInstanceID objid) const -{ - const CGObjectInstance *obj = getObj(objid, false); - if(obj) - return dynamic_cast(obj); - else - return nullptr; -} - -void CGameInfoCallback::getUpgradeInfo(const CArmedInstance *obj, SlotID 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(bool beforeRandomization /*= false*/) const -{ - //boost::shared_lock lock(*gs->mx); - if(beforeRandomization) - return gs->initialOpts; - else - 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->battleGetSpellCost(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, nullptr, hero->getSpellSchoolLevel(sp), hero->getPrimSkillLevel(PrimarySkill::SPELL_POWER)); - 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, nullptr, ourHero->getSpellSchoolLevel(sp), ourHero->getPrimSkillLevel(PrimarySkill::SPELL_POWER)); -} - -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 == Obj::TOWN && !canGetFullInfo(obj), "Cannot get info about town guild object!"); - //TODO: advmap object -> check if they're visited by our hero - - if(obj->ID == Obj::TOWN || obj->ID == Obj::TAVERN) - { - gs->obtainPlayersStats(thi, gs->players[obj->tempOwner].towns.size()); - } - else if(obj->ID == Obj::DEN_OF_THIEVES) - { - gs->obtainPlayersStats(thi, 20); - } -} - -int CGameInfoCallback::howManyTowns(PlayerColor 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 == Obj::TOWN) - dest.initFromTown(static_cast(town), detailed); - else if(town->ID == Obj::GARRISON || town->ID == Obj::GARRISON2) - dest.initFromArmy(static_cast(town), detailed); - else - return false; - return true; -} - -int3 CGameInfoCallback::guardingCreaturePosition (int3 pos) const //FIXME: redundant? -{ - ERROR_RET_VAL_IF(!isVisible(pos), "Tile is not visible!", int3(-1,-1,-1)); - return gs->guardingCreaturePosition(pos); -} - -std::vector CGameInfoCallback::getGuardingCreatures (int3 pos) const -{ - ERROR_RET_VAL_IF(!isVisible(pos), "Tile is not visible!", std::vector()); - std::vector ret; - for(auto cr : gs->guardingCreatures(pos)) - { - ret.push_back(cr); - } - return ret; -} - -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(Date::EDateType 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 = getTile(pos); - ERROR_RET_VAL_IF(!t, "Not a valid tile given!", ret); - - - for(const CGObjectInstance * obj : t->blockingObjects) - ret.push_back(obj->getHoverText()); - return ret; -} - -bool CGameInfoCallback::isVisible(int3 pos, boost::optional Player) const -{ - //boost::shared_lock lock(*gs->mx); - return gs->map->isInTheMap(pos) && (!Player || gs->isVisible(pos, *Player)); -} - -bool CGameInfoCallback::isVisible(int3 pos) const -{ - return isVisible(pos, player); -} - -bool CGameInfoCallback::isVisible( const CGObjectInstance *obj, boost::optional 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 nullptr; -// else -// return armi; -// } - -std::vector < const CGObjectInstance * > CGameInfoCallback::getBlockingObjs( int3 pos ) const -{ - std::vector ret; - const TerrainTile *t = getTile(pos); - ERROR_RET_VAL_IF(!t, "Not a valid tile requested!", ret); - - for(const CGObjectInstance * obj : t->blockingObjects) - ret.push_back(obj); - return ret; -} - -std::vector CGameInfoCallback::getVisitableObjs(int3 pos, bool verbose /*= true*/) const -{ - std::vector ret; - const TerrainTile *t = getTile(pos, verbose); - ERROR_VERBOSE_OR_NOT_RET_VAL_IF(!t, verbose, pos << " is not visible!", ret); - - for(const CGObjectInstance * obj : t->visitableObjects) - { - if(player < nullptr || obj->ID != Obj::EVENT) //hide events from players - ret.push_back(obj); - } - - return ret; -} -const CGObjectInstance * CGameInfoCallback::getTopObj (int3 pos) const -{ - return vstd::backOrNull(getVisitableObjs(pos)); -} - -std::vector < const CGObjectInstance * > CGameInfoCallback::getFlaggableObjects(int3 pos) const -{ - std::vector ret; - const TerrainTile *t = getTile(pos); - ERROR_RET_VAL_IF(!t, "Not a valid tile requested!", ret); - for(const CGObjectInstance *obj : t->blockingObjects) - if(obj->tempOwner != PlayerColor::UNFLAGGABLE) - 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 ? 2 : 1); -} - -std::vector CGameInfoCallback::getAvailableHeroes(const CGObjectInstance * townOrTavern) const -{ - ASSERT_IF_CALLED_WITH_PLAYER - std::vector ret; - //ERROR_RET_VAL_IF(!isOwnedOrVisited(townOrTavern), "Town or tavern must be owned or visited!", ret); - //TODO: town needs to be owned, advmap tavern needs to be visited; to be reimplemented when visit tracking is done - range::copy(gs->players[*player].availableHeroes, std::back_inserter(ret)); - vstd::erase_if(ret, [](const CGHeroInstance *h) { return h == nullptr; }); - return ret; -} - -const TerrainTile * CGameInfoCallback::getTile( int3 tile, bool verbose) const -{ - ERROR_VERBOSE_OR_NOT_RET_VAL_IF(!isVisible(tile), verbose, tile << " is not visible!", nullptr); - - //boost::shared_lock lock(*gs->mx); - return &gs->map->getTile(tile); -} - -EBuildingState::EBuildingState CGameInfoCallback::canBuildStructure( const CGTownInstance *t, BuildingID ID ) -{ - ERROR_RET_VAL_IF(!canGetFullInfo(t), "Town is not owned!", EBuildingState::TOWN_NOT_OWNED); - - if(!t->town->buildings.count(ID)) - return EBuildingState::BUILDING_ERROR; - - const CBuilding * building = t->town->buildings.at(ID); - - - if(t->hasBuilt(ID)) //already built - return EBuildingState::ALREADY_PRESENT; - - //can we build it? - if(vstd::contains(t->forbiddenBuildings, ID)) - return EBuildingState::FORBIDDEN; //forbidden - - if(ID == BuildingID::CAPITOL) - { - const PlayerState *ps = getPlayer(t->tempOwner); - if(ps) - { - for(const CGTownInstance *t : ps->towns) - { - if(t->hasBuilt(BuildingID::CAPITOL)) - { - return EBuildingState::HAVE_CAPITAL; //no more than one capitol - } - } - } - } - else if(ID == BuildingID::SHIPYARD) - { - const TerrainTile *tile = getTile(t->bestLocation(), false); - - if(!tile || tile->terType != ETerrainType::WATER) - return EBuildingState::NO_WATER; //lack of water - } - - auto buildTest = [&](const BuildingID & id) - { - return t->hasBuilt(id); - }; - - if(t->builded >= VLC->modh->settings.MAX_BUILDING_PER_TURN) - return EBuildingState::CANT_BUILD_TODAY; //building limit - - if (!building->requirements.test(buildTest)) - return EBuildingState::PREREQUIRES; - - if (building->upgrade != BuildingID::NONE && !t->hasBuilt(building->upgrade)) - return EBuildingState::MISSING_BASE; - - //checking resources - if(!building->resources.canBeAfforded(getPlayer(t->tempOwner)->resources)) - return EBuildingState::NO_RESOURCES; //lack of res - - return EBuildingState::ALLOWED; -} - -const CMapHeader * CGameInfoCallback::getMapHeader() const -{ - return gs->map; -} - -bool CGameInfoCallback::hasAccess(boost::optional playerId) const -{ - return !player || gs->getPlayerRelations( *playerId, *player ) != PlayerRelations::ENEMIES; -} - -EPlayerStatus::EStatus CGameInfoCallback::getPlayerStatus(PlayerColor player, bool verbose) const -{ - const PlayerState *ps = gs->getPlayer(player, verbose); - ERROR_VERBOSE_OR_NOT_RET_VAL_IF(!ps, verbose, "No such player!", EPlayerStatus::WRONG); - - return ps->status; -} - -std::string CGameInfoCallback::getTavernGossip(const CGObjectInstance * townOrTavern) const -{ - return "GOSSIP TEST"; -} - -PlayerRelations::PlayerRelations CGameInfoCallback::getPlayerRelations( PlayerColor color1, PlayerColor color2 ) const -{ - return gs->getPlayerRelations(color1, color2); -} - -bool CGameInfoCallback::canGetFullInfo(const CGObjectInstance *obj) const -{ - return !obj || hasAccess(obj->tempOwner); -} - -int CGameInfoCallback::getHeroCount( PlayerColor 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(auto & elem : p->heroes) - if(!elem->inTownGarrison) - ret++; - return ret; -} - -bool CGameInfoCallback::isOwnedOrVisited(const CGObjectInstance *obj) const -{ - if(canGetFullInfo(obj)) - return true; - - const TerrainTile *t = getTile(obj->visitablePos()); //get entrance tile - const CGObjectInstance *visitor = t->visitableObjects.back(); //visitong hero if present or the obejct itself at last - return visitor->ID == Obj::HERO && canGetFullInfo(visitor); //owned or allied hero is a visitor -} - -PlayerColor CGameInfoCallback::getCurrentPlayer() const -{ - return gs->currentPlayer; -} - -CGameInfoCallback::CGameInfoCallback() -{ -} - -CGameInfoCallback::CGameInfoCallback(CGameState *GS, boost::optional Player) -{ - gs = GS; - player = Player; -} - -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, "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(const auto & i : gs->players) - { - for(const auto & town : i.second.towns) - { - if (i.first==player || (isVisible(town, player) && !onlyOur)) - { - ret.push_back(town); - } - } - } // 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(auto hero : gs->map->heroesOnMap) - { - if( !player || (hero->tempOwner == *player) || - (isVisible(hero->getPosition(false), player) && !onlyOur) ) - { - ret.push_back(hero); - } - } - return ret; -} - -boost::optional CPlayerSpecificInfoCallback::getMyColor() const -{ - return player; -} - -int CPlayerSpecificInfoCallback::getHeroSerial(const CGHeroInstance * hero, bool includeGarrisoned) const -{ - if (hero->inTownGarrison && !includeGarrisoned) - return -1; - - size_t index = 0; - auto & heroes = gs->players[*player].heroes; - - for (auto & heroe : heroes) - { - if (includeGarrisoned || !(heroe)->inTownGarrison) - index++; - - if (heroe == hero) - return index; - } - return -1; -} - -int3 CPlayerSpecificInfoCallback::getGrailPos( double &outKnownRatio ) -{ - if (!player || CGObelisk::obeliskCount == 0) - { - outKnownRatio = 0.0; - } - else - { - outKnownRatio = static_cast(CGObelisk::visited[gs->getPlayerTeam(*player)->id]) / CGObelisk::obeliskCount; - } - return gs->map->grailPos; -} - -std::vector < const CGObjectInstance * > CPlayerSpecificInfoCallback::getMyObjects() const -{ - std::vector < const CGObjectInstance * > ret; - for(const CGObjectInstance * obj : gs->map->objects) - { - if(obj && obj->tempOwner == player) - ret.push_back(obj); - } - return ret; -} - -std::vector < const CGDwelling * > CPlayerSpecificInfoCallback::getMyDwellings() const -{ - ASSERT_IF_CALLED_WITH_PLAYER - std::vector < const CGDwelling * > ret; - for(CGDwelling * dw : gs->getPlayer(*player)->dwellings) - { - ret.push_back(dw); - } - return ret; -} - -std::vector CPlayerSpecificInfoCallback::getMyQuests() const -{ - std::vector ret; - for (auto quest : gs->getPlayer(*player)->quests) - { - ret.push_back (quest); - } - return ret; -} - -int CPlayerSpecificInfoCallback::howManyHeroes(bool includeGarrisoned) const -{ - //boost::shared_lock lock(*gs->mx); - ERROR_RET_VAL_IF(!player, "Applicable only for player callbacks", -1); - return getHeroCount(*player,includeGarrisoned); -} - -const CGHeroInstance* CPlayerSpecificInfoCallback::getHeroBySerial(int serialId, bool includeGarrisoned) const -{ - ASSERT_IF_CALLED_WITH_PLAYER - const PlayerState *p = getPlayer(*player); - ERROR_RET_VAL_IF(!p, "No player info", nullptr); - - if (!includeGarrisoned) - { - for(ui32 i = 0; i < p->heroes.size() && i<=serialId; i++) - if(p->heroes[i]->inTownGarrison) - serialId++; - } - ERROR_RET_VAL_IF(serialId < 0 || serialId >= p->heroes.size(), "No player info", nullptr); - return p->heroes[serialId]; -} - -const CGTownInstance* CPlayerSpecificInfoCallback::getTownBySerial(int serialId) const -{ - ASSERT_IF_CALLED_WITH_PLAYER - const PlayerState *p = getPlayer(*player); - ERROR_RET_VAL_IF(!p, "No player info", nullptr); - ERROR_RET_VAL_IF(serialId < 0 || serialId >= p->towns.size(), "No player info", nullptr); - return p->towns[serialId]; -} - -int CPlayerSpecificInfoCallback::getResourceAmount(Res::ERes type) const -{ - //boost::shared_lock lock(*gs->mx); - ERROR_RET_VAL_IF(!player, "Applicable only for player callbacks", -1); - return getResource(*player, type); -} - -TResources CPlayerSpecificInfoCallback::getResourceAmount() const -{ - //boost::shared_lock lock(*gs->mx); - ERROR_RET_VAL_IF(!player, "Applicable only for player callbacks", TResources()); - return gs->players[*player].resources; -} - CGHeroInstance *CNonConstInfoCallback::getHero(ObjectInstanceID objid) { return const_cast(CGameInfoCallback::getHero(objid)); @@ -882,73 +219,6 @@ CGObjectInstance * CNonConstInfoCallback::getObjInstance( ObjectInstanceID oid ) return gs->map->objects[oid.num]; } -const TeamState * CGameInfoCallback::getTeam( TeamID teamID ) const -{ - ERROR_RET_VAL_IF(!vstd::contains(gs->teams, teamID), "Cannot find info for team " << teamID, nullptr); - const TeamState *ret = &gs->teams[teamID]; - ERROR_RET_VAL_IF(!!player && !vstd::contains(ret->players, *player), "Illegal attempt to access team data!", nullptr); - return ret; -} - -const TeamState * CGameInfoCallback::getPlayerTeam( PlayerColor color ) const -{ - const PlayerState * ps = getPlayer(color); - if (ps) - return getTeam(ps->team); - return nullptr; -} - -const CGHeroInstance* CGameInfoCallback::getHeroWithSubid( int subid ) const -{ - for(const CGHeroInstance *h : gs->map->heroesOnMap) - if(h->subID == subid) - return h; - - return nullptr; -} - -PlayerColor CGameInfoCallback::getLocalPlayer() const -{ - return getCurrentPlayer(); -} - -bool CGameInfoCallback::isInTheMap(const int3 &pos) const -{ - return gs->map->isInTheMap(pos); -} - -const CArtifactInstance * CGameInfoCallback::getArtInstance( ArtifactInstanceID aid ) const -{ - return gs->map->artInstances[aid.num]; -} - -const CGObjectInstance * CGameInfoCallback::getObjInstance( ObjectInstanceID oid ) const -{ - return gs->map->objects[oid.num]; -} - -void IGameEventRealizer::showInfoDialog( InfoWindow *iw ) -{ - commitPackage(iw); -} - -void IGameEventRealizer::showInfoDialog(const std::string &msg, PlayerColor player) -{ - InfoWindow iw; - iw.player = player; - iw.text << msg; - showInfoDialog(&iw); -} - -void IGameEventRealizer::setObjProperty(ObjectInstanceID objid, int prop, si64 val) -{ - SetObjectProperty sob; - sob.id = objid; - sob.what = prop; - sob.val = static_cast(val); - commitPackage(&sob); -} - const CGObjectInstance * IGameCallback::putNewObject(Obj ID, int subID, int3 pos) { NewObject no; diff --git a/lib/IGameCallback.h b/lib/IGameCallback.h index 164e11d30..e6183e2b2 100644 --- a/lib/IGameCallback.h +++ b/lib/IGameCallback.h @@ -1,11 +1,6 @@ #pragma once - -#include "BattleHex.h" -#include "ResourceSet.h" -#include "int3.h" -#include "GameConstants.h" -#include "CBattleCallback.h" +#include "CGameInfoCallback.h" // for CGameInfoCallback /* * IGameCallback.h, part of VCMI engine @@ -19,150 +14,15 @@ struct SetMovePoints; struct GiveBonus; -class CGObjectInstance; -class CGTownInstance; -class CGHeroInstance; struct BlockingDialog; -struct InfoWindow; struct MetaString; struct ShowInInfobox; -struct BattleResult; -struct Component; -class CGameState; -struct PlayerSettings; -struct CPackForClient; -class CArtHandler; -class CArtifact; -class CArmedInstance; -struct TerrainTile; -struct PlayerState; -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; -class CSpell; class CCreatureSet; -class CCreature; class CStackBasicDescriptor; -struct TeamState; -struct QuestInfo; class CGCreature; -class CSaveFile; -class CLoadFile; - -class DLL_LINKAGE CGameInfoCallback : public virtual CCallbackBase -{ -protected: - CGameInfoCallback(); - CGameInfoCallback(CGameState *GS, boost::optional Player); - bool hasAccess(boost::optional playerId) const; - bool isVisible(int3 pos, boost::optional Player) const; - bool isVisible(const CGObjectInstance *obj, boost::optional Player) const; - bool isVisible(const CGObjectInstance *obj) const; - - bool canGetFullInfo(const CGObjectInstance *obj) const; //true we player owns obj or ally owns obj or privileged mode - bool isOwnedOrVisited(const CGObjectInstance *obj) const; - -public: - //various - int getDate(Date::EDateType mode=Date::DAY)const; //mode=0 - total days in game, mode=1 - day of week, mode=2 - current week, mode=3 - current month - const StartInfo * getStartInfo(bool beforeRandomization = false)const; - bool isAllowed(int type, int id); //type: 0 - spell; 1- artifact; 2 - secondary skill - - //player - const PlayerState * getPlayer(PlayerColor color, bool verbose = true) const; - int getResource(PlayerColor Player, Res::ERes which) const; - bool isVisible(int3 pos) const; - PlayerRelations::PlayerRelations getPlayerRelations(PlayerColor color1, PlayerColor color2) const; - void getThievesGuildInfo(SThievesGuildInfo & thi, const CGObjectInstance * obj); //get thieves' guild info obtainable while visiting given object - EPlayerStatus::EStatus getPlayerStatus(PlayerColor player, bool verbose = true) const; //-1 if no such player - PlayerColor getCurrentPlayer() const; //player that currently makes move // TODO synchronous turns - virtual PlayerColor getLocalPlayer() const; //player that is currently owning given client (if not a client, then returns current player) - const PlayerSettings * getPlayerSettings(PlayerColor color) const; - - - //armed object - void getUpgradeInfo(const CArmedInstance *obj, SlotID stackPos, UpgradeInfo &out)const; - - //hero - const CGHeroInstance* getHero(ObjectInstanceID objid) const; - const CGHeroInstance* getHeroWithSubid(int subid) const; - int getHeroCount(PlayerColor 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 - const CGHeroInstance* getSelectedHero(PlayerColor player) const; //nullptr if no hero is selected - const CGHeroInstance* getSelectedHero() const; //of current (active) player - const CArtifactInstance * getArtInstance(ArtifactInstanceID aid) const; - const CGObjectInstance * getObjInstance(ObjectInstanceID oid) const; - - //objects - const CGObjectInstance* getObj(ObjectInstanceID objid, bool verbose = true) const; - std::vector getBlockingObjs(int3 pos)const; - std::vector getVisitableObjs(int3 pos, bool verbose = true)const; - std::vector getFlaggableObjects(int3 pos) const; - const CGObjectInstance * getTopObj (int3 pos) const; - std::vector getObjDescriptions(int3 pos)const; //returns descriptions of objects at pos in order from the lowest to the highest - PlayerColor getOwner(ObjectInstanceID heroID) const; - const CGObjectInstance *getObjByQuestIdentifier(int identifier) const; //nullptr if object has been removed (eg. killed) - - //map - int3 guardingCreaturePosition (int3 pos) const; - std::vector getGuardingCreatures (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 * getTile(int3 tile, bool verbose = true) const; - bool isInTheMap(const int3 &pos) const; - - //town - const CGTownInstance* getTown(ObjectInstanceID objid) const; - int howManyTowns(PlayerColor 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; - EBuildingState::EBuildingState canBuildStructure(const CGTownInstance *t, BuildingID 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 - virtual bool getTownInfo(const CGObjectInstance *town, InfoAboutTown &dest) const; - const CTown *getNativeTown(PlayerColor color) const; - - //from gs - const TeamState *getTeam(TeamID teamID) const; - const TeamState *getPlayerTeam(PlayerColor color) const; - EBuildingState::EBuildingState canBuildStructure(const CGTownInstance *t, BuildingID ID) const;// 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 -}; - - -class DLL_LINKAGE CPlayerSpecificInfoCallback : public CGameInfoCallback -{ -public: - int howManyTowns() const; - int howManyHeroes(bool includeGarrisoned = true) const; - int3 getGrailPos(double &outKnownRatio); - boost::optional getMyColor() const; - - std::vector getTownsInfo(bool onlyOur = true) const; //true -> only owned; false -> all visible - int getHeroSerial(const CGHeroInstance * hero, bool includeGarrisoned=true) const; - const CGTownInstance* getTownBySerial(int serialId) const; // serial id is [0, number of towns) - const CGHeroInstance* getHeroBySerial(int serialId, bool includeGarrisoned=true) 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 - std::vector getMyQuests() const; - - int getResourceAmount(Res::ERes type) const; - TResources getResourceAmount() const; - const std::vector< std::vector< std::vector > > & getVisibilityMap()const; //returns visibility map - const PlayerSettings * getPlayerSettings(PlayerColor color) const; -}; +struct ShashInt3; class DLL_LINKAGE CPrivilagedInfoCallback : public CGameInfoCallback { @@ -181,31 +41,6 @@ public: void loadCommonState(Loader &in); //loads GS and VLC }; -class DLL_LINKAGE CNonConstInfoCallback : public CPrivilagedInfoCallback -{ -public: - PlayerState *getPlayer(PlayerColor color, bool verbose = true); - TeamState *getTeam(TeamID teamID);//get team by team ID - TeamState *getPlayerTeam(PlayerColor color);// get team by player color - CGHeroInstance *getHero(ObjectInstanceID objid); - CGTownInstance *getTown(ObjectInstanceID objid); - TerrainTile * getTile(int3 pos); - CArtifactInstance * getArtInstance(ArtifactInstanceID aid); - CGObjectInstance * getObjInstance(ObjectInstanceID oid); -}; - -class DLL_LINKAGE IGameEventRealizer -{ -public: - virtual void commitPackage(CPackForClient *pack) = 0; - - virtual void showInfoDialog(InfoWindow *iw); - virtual void setObjProperty(ObjectInstanceID objid, int prop, si64 val); - - - virtual void showInfoDialog(const std::string &msg, PlayerColor player); -}; - class DLL_LINKAGE IGameEventCallback : public IGameEventRealizer { public: @@ -260,6 +95,19 @@ public: virtual void addQuest(int player, QuestInfo & quest){}; }; +class DLL_LINKAGE CNonConstInfoCallback : public CPrivilagedInfoCallback +{ +public: + PlayerState *getPlayer(PlayerColor color, bool verbose = true); + TeamState *getTeam(TeamID teamID);//get team by team ID + TeamState *getPlayerTeam(PlayerColor color);// get team by player color + CGHeroInstance *getHero(ObjectInstanceID objid); + CGTownInstance *getTown(ObjectInstanceID objid); + TerrainTile * getTile(int3 pos); + CArtifactInstance * getArtInstance(ArtifactInstanceID aid); + CGObjectInstance * getObjInstance(ObjectInstanceID oid); +}; + /// Interface class for handling general game logic and actions class DLL_LINKAGE IGameCallback : public CPrivilagedInfoCallback, public IGameEventCallback { @@ -277,3 +125,4 @@ public: friend struct CPackForClient; friend struct CPackForServer; }; + diff --git a/lib/filesystem/CFileInputStream.cpp b/lib/filesystem/CFileInputStream.cpp index 8b9d1ce47..66b70e11d 100644 --- a/lib/filesystem/CFileInputStream.cpp +++ b/lib/filesystem/CFileInputStream.cpp @@ -55,7 +55,7 @@ si64 CFileInputStream::seek(si64 position) si64 CFileInputStream::tell() { - return fileStream.tellg() - dataStart; + return static_cast(fileStream.tellg()) - dataStart; } si64 CFileInputStream::skip(si64 delta) diff --git a/scripting/erm/ERMInterpreter.cpp b/scripting/erm/ERMInterpreter.cpp index bbd67507a..e769ddc14 100644 --- a/scripting/erm/ERMInterpreter.cpp +++ b/scripting/erm/ERMInterpreter.cpp @@ -6,6 +6,7 @@ #include "../../lib/CHeroHandler.h" #include "../../lib/CCreatureHandler.h" #include "../../lib/VCMIDirs.h" +#include "../../lib/IGameCallback.h" /* * ERMInterpreter.cpp, part of VCMI engine @@ -547,6 +548,7 @@ bool ERMInterpreter::isATrigger( const ERM::TLine & line ) break; } assert(0); + return false; } ERM::EVOtions ERMInterpreter::getExpType( const ERM::TVOption & opt )