#define VCMI_DLL #include "IGameCallback.h" #include "../lib/CGameState.h" #include "../lib/map.h" #include "../hch/CObjectHandler.h" #include "../StartInfo.h" #include "../hch/CArtHandler.h" #include "../hch/CSpellHandler.h" #include "../lib/VCMI_Lib.h" #include #include "../hch/CTownHandler.h" /* * IGameCallback.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 * */ extern boost::rand48 ran; CGameState *const IGameCallback::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]); else return NULL; } int IGameCallback::getOwner(int heroID) { return gs->map->objects[heroID]->tempOwner; } int IGameCallback::getResource(int player, int which) { return gs->players.find(player)->second.resources[which]; } int IGameCallback::getDate(int mode) { return gs->getDate(mode); } const CGHeroInstance* IGameCallback::getSelectedHero( int player ) { if(gs->players.find(player)->second.currentSelection==-1) return NULL; return getHero(gs->players.find(player)->second.currentSelection); } const PlayerSettings * IGameCallback::getPlayerSettings( int color ) { 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( std::set &tiles, int3 pos, int radious, int player/*=-1*/, int mode/*=0*/ ) { if(player >= PLAYER_LIMIT) { tlog1 << "Illegal call to getTilesInRange!\n"; return; } if (radious == -1) //reveal entire map getAllTiles (tiles, player, -1, 0); else { const TeamState * team = gs->getPlayerTeam(player); for (int xd = std::max(pos.x - radious , 0); xd <= std::min(pos.x + radious, gs->map->width - 1); xd++) { for (int yd = std::max(pos.y - radious, 0); yd <= std::min(pos.y + radious, gs->map->height - 1); yd++) { double distance = pos.dist2d(int3(xd,yd,pos.z)) - 0.5; if(distance <= radious) { if(player < 0 || (mode == 1 && team->fogOfWarMap[xd][yd][pos.z]==0) || (mode == -1 && team->fogOfWarMap[xd][yd][pos.z]==1) ) tiles.insert(int3(xd,yd,pos.z)); } } } } } void IGameCallback::getAllTiles (std::set &tiles, int player/*=-1*/, int level, int surface ) { if(player >= PLAYER_LIMIT) { tlog1 << "Illegal call to getAllTiles !\n"; return; } bool water = surface == 0 || surface == 2, land = surface == 0 || surface == 1; std::vector floors; if(level == -1) { for (int xd = 0; xd <= gs->map->width - 1; xd++) 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 { floors.push_back(b); } } else floors.push_back(level); for (std::vector::const_iterator i = floors.begin(); i!= floors.end(); i++) { register int zd = *i; for (int xd = 0; xd < gs->map->width; xd++) { for (int yd = 0; yd < gs->map->height; yd++) { if ((getTile (int3 (xd,yd,zd))->tertype == 8 && water) || (getTile (int3 (xd,yd,zd))->tertype != 8 && land)) tiles.insert(int3(xd,yd,zd)); } } } } void IGameCallback::getFreeTiles (std::vector &tiles) { 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 { floors.push_back(b); } TerrainTile *tinfo; for (std::vector::const_iterator i = floors.begin(); i!= floors.end(); i++) { register int zd = *i; 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 != 8 && !tinfo->blocked) //land and free tiles.push_back (int3 (xd,yd,zd)); } } } } bool IGameCallback::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: tlog1 << "Wrong call to IGameCallback::isAllowed!\n"; return false; } } void IGameCallback::pickAllowedArtsSet(std::vector &out) { for (int i = 0; i < 2; i++) { for (int j = 0; j < 3 ; j++) { out.push_back(VLC->arth->artifacts[getRandomArt(CArtifact::ART_TREASURE << i)]); } } out.push_back(VLC->arth->artifacts[getRandomArt(CArtifact::ART_MAJOR)]); } ui16 IGameCallback::getRandomArt (int flags) { return VLC->arth->getRandomArt(flags); } ui16 IGameCallback::getArtSync (ui32 rand, int flags) { return VLC->arth->getArtSync (rand, flags); } void IGameCallback::erasePickedArt (si32 id) { VLC->arth->erasePickedArt(id); } void IGameCallback::getAllowedSpells(std::vector &out, ui16 level) { CSpell *spell; for (int i = 0; i < gs->map->allowedSpell.size(); i++) //spellh size appears to be greater (?) { spell = &(VLC->spellh->spells[i]); if (isAllowed (0, spell->id) && spell->level == level) { out.push_back(spell->id); } } } int3 IGameCallback::getMapSize() { return int3(gs->map->width, gs->map->height, gs->map->twoLevel + 1); } inline TerrainTile * IGameCallback::getTile( int3 pos ) { if(!gs->map->isInTheMap(pos)) return NULL; return &gs->map->getTile(pos); } const PlayerState * IGameCallback::getPlayerState( int color ) { return gs->getPlayer(color, false); } const CTown * IGameCallback::getNativeTown(int color) { return &VLC->townh->towns[gs->scenarioOps->getIthPlayersSettings(color).castle]; }