diff --git a/CAdvmapInterface.cpp b/CAdvmapInterface.cpp index e9e9fec26..914bfe9d8 100644 --- a/CAdvmapInterface.cpp +++ b/CAdvmapInterface.cpp @@ -468,9 +468,9 @@ void CTerrainRect::clickRight(tribool down) } case 98: { - if(!vstd::contains(graphics->townWins,obj->subID)) + if(!vstd::contains(graphics->townWins,obj->id)) { - tlog3 << "Warning - no infowin for town " << obj->subID << std::endl; + tlog3 << "Warning - no infowin for town " << obj->id << std::endl; break; } CInfoPopup * ip = new CInfoPopup(graphics->townWins[obj->id], diff --git a/CCallback.cpp b/CCallback.cpp index 62a5c6bdd..a4c7ea9de 100644 --- a/CCallback.cpp +++ b/CCallback.cpp @@ -601,7 +601,7 @@ bool CCallback::battleCanShoot(int ID, int dest) void CCallback::swapGarrisonHero( const CGTownInstance *town ) { if(town->tempOwner != player) return; - *cl->serv << ui16(508) << si32(town->id); + *cl->serv << &GarrisonHeroSwap(town->id); } void CCallback::buyArtifact(const CGHeroInstance *hero, int aid) diff --git a/CGameState.cpp b/CGameState.cpp index 490e6e277..7ab0e5640 100644 --- a/CGameState.cpp +++ b/CGameState.cpp @@ -997,20 +997,39 @@ void CGameState::init(StartInfo * si, Mapa * map, int Seed) for(int h=0; hheight; ++h) for(int v=0; vtwoLevel+1; ++v) k->second.fogOfWarMap[g][h][v] = 0; - for(int xd=0; xdwidth; ++xd) //revealing part of map around heroes + + BOOST_FOREACH(CGObjectInstance *obj, map->objects) { - for(int yd=0; ydheight; ++yd) + if(obj->tempOwner != k->first) continue; //not a flagged object + + int3 objCenter = obj->getSightCenter(); + int radious = obj->getSightRadious(); + + for (int xd = std::max(objCenter.x - radious , 0); xd <= std::min(objCenter.x + radious, map->width - 1); xd++) { - for(int ch=0; chsecond.heroes.size(); ++ch) + for (int yd = std::max(objCenter.y - radious, 0); yd <= std::min(objCenter.y + radious, map->height - 1); yd++) { - int deltaX = (k->second.heroes[ch]->getPosition(false).x-xd)*(k->second.heroes[ch]->getPosition(false).x-xd); - int deltaY = (k->second.heroes[ch]->getPosition(false).y-yd)*(k->second.heroes[ch]->getPosition(false).y-yd); - if(deltaX+deltaYsecond.heroes[ch]->getSightDistance()*k->second.heroes[ch]->getSightDistance()) - k->second.fogOfWarMap[xd][yd][k->second.heroes[ch]->getPosition(false).z] = 1; + double distance = objCenter.dist2d(int3(xd,yd,objCenter.z)) - 0.5; + if(distance <= radious) + k->second.fogOfWarMap[xd][yd][objCenter.z] = 1; } } } + //for(int xd=0; xdwidth; ++xd) //revealing part of map around heroes + //{ + // for(int yd=0; ydheight; ++yd) + // { + // for(int ch=0; chsecond.heroes.size(); ++ch) + // { + // int deltaX = (k->second.heroes[ch]->getPosition(false).x-xd)*(k->second.heroes[ch]->getPosition(false).x-xd); + // int deltaY = (k->second.heroes[ch]->getPosition(false).y-yd)*(k->second.heroes[ch]->getPosition(false).y-yd); + // if(deltaX+deltaYsecond.heroes[ch]->getSightDistance()*k->second.heroes[ch]->getSightDistance()) + // k->second.fogOfWarMap[xd][yd][k->second.heroes[ch]->getPosition(false).z] = 1; + // } + // } + //} + //starting bonus if(si->playerInfos[k->second.serial].bonus==brandom) si->playerInfos[k->second.serial].bonus = ran()%3; @@ -1125,19 +1144,19 @@ void CGameState::init(StartInfo * si, Mapa * map, int Seed) { if(k->first==-1 || k->first==255) continue; - for(int xd=0; xdwidth; ++xd) //revealing part of map around towns - { - for(int yd=0; ydheight; ++yd) - { - for(int ch=0; chsecond.towns.size(); ++ch) - { - int deltaX = (k->second.towns[ch]->pos.x-xd)*(k->second.towns[ch]->pos.x-xd); - int deltaY = (k->second.towns[ch]->pos.y-yd)*(k->second.towns[ch]->pos.y-yd); - if(deltaX+deltaYsecond.towns[ch]->getSightDistance()*k->second.towns[ch]->getSightDistance()) - k->second.fogOfWarMap[xd][yd][k->second.towns[ch]->pos.z] = 1; - } - } - } + // for(int xd=0; xdwidth; ++xd) //revealing part of map around towns + // { + // for(int yd=0; ydheight; ++yd) + // { + // for(int ch=0; chsecond.towns.size(); ++ch) + // { + // int deltaX = (k->second.towns[ch]->pos.x-xd)*(k->second.towns[ch]->pos.x-xd); + // int deltaY = (k->second.towns[ch]->pos.y-yd)*(k->second.towns[ch]->pos.y-yd); + // if(deltaX+deltaYsecond.towns[ch]->getSightDistance()*k->second.towns[ch]->getSightDistance()) + // k->second.fogOfWarMap[xd][yd][k->second.towns[ch]->pos.z] = 1; + // } + // } + // } //init visiting and garrisoned heroes for(int l=0; lsecond.heroes.size();l++) @@ -1307,33 +1326,21 @@ float CGameState::getMarketEfficiency( int player, int mode/*=0*/ ) } std::set CGameState::tilesToReveal(int3 pos, int radious, int player) const -{ +{ std::set ret; - int xbeg = pos.x - radious - 2; - if(xbeg < 0) - xbeg = 0; - int xend = pos.x + radious + 2; - if(xend >= map->width) - xend = map->width; - int ybeg = pos.y - radious - 2; - if(ybeg < 0) - ybeg = 0; - int yend = pos.y + radious + 2; - if(yend >= map->height) - yend = map->height; - for(int xd=xbeg; xd= PLAYER_LIMIT) { - for(int yd=ybeg; yd(pos.x - radious , 0); xd <= std::min(pos.x + radious, map->width); xd++) + { + for (int yd = std::max(pos.y - radious, 0); std::min(yd <= pos.y + radious, map->height); yd++) { - int deltaX = (pos.x-xd)*(pos.x-xd); - int deltaY = (pos.y-yd)*(pos.y-yd); - if(deltaX+deltaYsecond.fogOfWarMap[xd][yd][pos.z]==0) - { - ret.insert(int3(xd,yd,pos.z)); - } - } + double distance = pos.dist2d(int3(xd,yd,pos.z)) - 0.5; + if(distance <= radious && (player<0 || players.find(player)->second.fogOfWarMap[xd][yd][pos.z]==0)) + ret.insert(int3(xd,yd,pos.z)); } } return ret; diff --git a/CPlayerInterface.cpp b/CPlayerInterface.cpp index cb7655d91..a191e394d 100644 --- a/CPlayerInterface.cpp +++ b/CPlayerInterface.cpp @@ -1943,6 +1943,8 @@ void CPlayerInterface::heroMovePointsChanged(const CGHeroInstance * hero) void CPlayerInterface::receivedResource(int type, int val) { boost::unique_lock un(*pim); + if(!curint) + return; if(curint==adventureInt || screen->h > 600 || screen->w > 800) adventureInt->resdatabar.draw(); if(curint==castleInt && !curint->subInt) diff --git a/hch/CObjectHandler.cpp b/hch/CObjectHandler.cpp index 02ec670a8..db66bce21 100644 --- a/hch/CObjectHandler.cpp +++ b/hch/CObjectHandler.cpp @@ -139,14 +139,21 @@ int CGObjectInstance::getWidth() const//returns width of object graphic in tiles } int CGObjectInstance::getHeight() const //returns height of object graphic in tiles { - return defInfo->width; + return defInfo->height; } bool CGObjectInstance::visitableAt(int x, int y) const //returns true if object is visitable at location (x, y) form left top tile of image (x, y in tiles) { - if(x<0 || y<0 || x>=getWidth() || y>=getHeight() || defInfo==NULL) + if(defInfo==NULL) + { + tlog2 << "Warning: VisitableAt for obj "<visitMap[y+6-getHeight()] >> (7-(8-getWidth()+x) )) & 1) + } + + if((defInfo->visitMap[y] >> (7-x) ) & 1) + { return true; + } + return false; } bool CGObjectInstance::blockingAt(int x, int y) const @@ -204,6 +211,21 @@ void CGObjectInstance::setProperty( ui8 what, ui32 val ) void CGObjectInstance::setPropertyDer( ui8 what, ui32 val ) {} +int3 CGObjectInstance::getSightCenter() const +{ + //return vistiable tile if possible + for(int i=0; i < 8; i++) + for(int j=0; j < 6; j++) + if(visitableAt(i,j)) + return(pos + int3(i-7, j-5, 0)); + return pos; +} + +int CGObjectInstance::getSightRadious() const +{ + return 3; +} + int lowestSpeed(const CGHeroInstance * chi) { if(!chi->army.slots.size()) @@ -288,10 +310,6 @@ int3 CGHeroInstance::getPosition(bool h3m) const //h3m=true - returns position o return convertPosition(pos,false); } } -int CGHeroInstance::getSightDistance() const //returns sight distance of this hero -{ - return 5 + getSecSkillLevel(3); //default + scouting -} si32 CGHeroInstance::manaLimit() const { @@ -729,9 +747,20 @@ void CGHeroInstance::setPropertyDer( ui8 what, ui32 val ) if(what == 3) army.slots[0].second = val; } -int CGTownInstance::getSightDistance() const //returns sight distance + +int3 CGHeroInstance::getSightCenter() const { - return 10; + return getPosition(false); +} + +int CGHeroInstance::getSightRadious() const +{ + return 5 + getSecSkillLevel(3); //default + scouting +} + +int CGTownInstance::getSightRadious() const //returns sight distance +{ + return 5; } int CGTownInstance::fortLevel() const //0 - none, 1 - fort, 2 - citadel, 3 - castle { @@ -870,6 +899,11 @@ void CGTownInstance::initObj() hoverName = toString(ms); } +int3 CGTownInstance::getSightCenter() const +{ + return pos - int3(2,0,0); +} + void CGVisitableOPH::onHeroVisit( const CGHeroInstance * h ) const { if(visitors.find(h->id)==visitors.end()) diff --git a/hch/CObjectHandler.h b/hch/CObjectHandler.h index 8a982f4a9..1bedcf42a 100644 --- a/hch/CObjectHandler.h +++ b/hch/CObjectHandler.h @@ -107,6 +107,8 @@ public: ui8 tempOwner; ui8 blockVisit; //if non-zero then blocks the tile but is visitable from neighbouring tile + virtual int3 getSightCenter() const; //"center" tile from which the sight distance is calculated + virtual int getSightRadious() const; //sight distance (should be used if player-owned structure) int getOwner() const; void setOwner(int ow); int getWidth() const; //returns width of object graphic in tiles @@ -206,6 +208,10 @@ public: type = VLC->heroh->heroes[subID]; //visitied town pointer will be restored by map serialization method } + ////////////////////////////////////////////////////////////////////////// + + int3 getSightCenter() const; //"center" tile from which the sight distance is calculated + int getSightRadious() const; //sight distance (should be used if player-owned structure) ////////////////////////////////////////////////////////////////////////// const HeroBonus *getBonus(int from, int id) const; @@ -216,7 +222,6 @@ public: unsigned int getAdditiveMoveBonus() const; float getMultiplicativeMoveBonus() const; int3 getPosition(bool h3m) const; //h3m=true - returns position of hero object; h3m=false - returns position of hero 'manifestation' - int getSightDistance() const; //returns sight distance of this hero si32 manaLimit() const; //maximum mana value for this hero (basically 10*knowledge) bool canWalkOnSea() const; int getCurrentLuck(int stack=-1, bool town=false) const; @@ -294,9 +299,12 @@ public: ////////////////////////////////////////////////////////////////////////// + int3 getSightCenter() const; //"center" tile from which the sight distance is calculated + int getSightRadious() const; //returns sight distance + + ////////////////////////////////////////////////////////////////////////// bool needsLastStack() const; - int getSightDistance() const; //returns sight distance int fortLevel() const; //0 - none, 1 - fort, 2 - citadel, 3 - castle int hallLevel() const; // -1 - none, 0 - village, 1 - town, 2 - city, 3 - capitol int mageGuildLevel() const; // -1 - none, 0 - village, 1 - town, 2 - city, 3 - capitol diff --git a/lib/Connection.cpp b/lib/Connection.cpp index 4d6c5a282..091ad287e 100644 --- a/lib/Connection.cpp +++ b/lib/Connection.cpp @@ -197,7 +197,7 @@ int CLoadFile::read( const void * data, unsigned size ) CTypeList::CTypeList() { - + registerTypes(*this); } ui16 CTypeList::registerType( const type_info *type ) diff --git a/lib/Connection.h b/lib/Connection.h index 6bc80182f..eb8a36159 100644 --- a/lib/Connection.h +++ b/lib/Connection.h @@ -56,7 +56,7 @@ enum SerializationLvl struct TypeComparer { - bool operator()(const type_info *a, const type_info *b) + bool operator()(const type_info *a, const type_info *b) const { return a->before(*b); } @@ -69,7 +69,7 @@ class DLL_EXPORT CTypeList public: CTypeList(); ui16 registerType(const type_info *type); - template ui16 registerType(const T * t) + template ui16 registerType(const T * t = NULL) { return registerType(getTypeInfo(t)); } diff --git a/lib/RegisterTypes.cpp b/lib/RegisterTypes.cpp index 513dbe698..c3269fb59 100644 --- a/lib/RegisterTypes.cpp +++ b/lib/RegisterTypes.cpp @@ -16,4 +16,5 @@ void foofoofoo() registerTypes((COSer&)*ccc); registerTypes((CSaveFile&)*ccc); registerTypes((CLoadFile&)*ccc); + registerTypes((CTypeList&)*ccc); } \ No newline at end of file diff --git a/lib/VCMI_lib.vcproj b/lib/VCMI_lib.vcproj index 521109a10..ef90f2f89 100644 --- a/lib/VCMI_lib.vcproj +++ b/lib/VCMI_lib.vcproj @@ -140,7 +140,7 @@ Name="VCLinkerTool" AdditionalDependencies="zdll.lib" Version="" - AdditionalLibraryDirectories="" + AdditionalLibraryDirectories="../../libs;" GenerateDebugInformation="false" OptimizeReferences="2" EnableCOMDATFolding="2" @@ -225,7 +225,7 @@ Name="VCLinkerTool" AdditionalDependencies="zdll.lib" Version="" - AdditionalLibraryDirectories="" + AdditionalLibraryDirectories="../../libs;" GenerateDebugInformation="true" GenerateMapFile="true" OptimizeReferences="2" diff --git a/server/CGameHandler.cpp b/server/CGameHandler.cpp index 0c9fb242e..65ebb9473 100644 --- a/server/CGameHandler.cpp +++ b/server/CGameHandler.cpp @@ -1229,7 +1229,7 @@ void CGameHandler::moveHero(si32 hid, int3 dst, ui8 instant, ui8 asker) { obj->onHeroLeave(h); } - tmh.fowRevealed = gs->tilesToReveal(h->convertPosition(dst,false),h->getSightDistance(),h->tempOwner); + tmh.fowRevealed = gs->tilesToReveal(h->getSightCenter()+(tmh.end-tmh.start),h->getSightRadious(),h->tempOwner); sendAndApply(&tmh); tlog5 << "Moved to " <tilesToReveal(h->convertPosition(dst,false),h->getSightDistance(),h->tempOwner); + tmh.fowRevealed = gs->tilesToReveal(h->getSightCenter()+(tmh.end-tmh.start),h->getSightRadious(),h->tempOwner); sendAndApply(&tmh); } }