1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-01-24 03:47:18 +02:00

* fixed crash when there was no sabegames in Games/ subfolder

* fixed crash when loading map with a mine belonging to human player
* fixed crash on moving hero into town garrison
* fixed r-click infowindow for towns
* new sight radious calculation. Works as OH3 for heroes, towns and probably all objects. (to be tested)
This commit is contained in:
Michał W. Urbańczyk 2009-03-11 23:25:59 +00:00
parent a7680d3957
commit d6283fd1ca
11 changed files with 117 additions and 65 deletions

View File

@ -468,9 +468,9 @@ void CTerrainRect::clickRight(tribool down)
} }
case 98: 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; break;
} }
CInfoPopup * ip = new CInfoPopup(graphics->townWins[obj->id], CInfoPopup * ip = new CInfoPopup(graphics->townWins[obj->id],

View File

@ -601,7 +601,7 @@ bool CCallback::battleCanShoot(int ID, int dest)
void CCallback::swapGarrisonHero( const CGTownInstance *town ) void CCallback::swapGarrisonHero( const CGTownInstance *town )
{ {
if(town->tempOwner != player) return; 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) void CCallback::buyArtifact(const CGHeroInstance *hero, int aid)

View File

@ -997,20 +997,39 @@ void CGameState::init(StartInfo * si, Mapa * map, int Seed)
for(int h=0; h<map->height; ++h) for(int h=0; h<map->height; ++h)
for(int v=0; v<map->twoLevel+1; ++v) for(int v=0; v<map->twoLevel+1; ++v)
k->second.fogOfWarMap[g][h][v] = 0; k->second.fogOfWarMap[g][h][v] = 0;
for(int xd=0; xd<map->width; ++xd) //revealing part of map around heroes
BOOST_FOREACH(CGObjectInstance *obj, map->objects)
{ {
for(int yd=0; yd<map->height; ++yd) if(obj->tempOwner != k->first) continue; //not a flagged object
int3 objCenter = obj->getSightCenter();
int radious = obj->getSightRadious();
for (int xd = std::max<int>(objCenter.x - radious , 0); xd <= std::min<int>(objCenter.x + radious, map->width - 1); xd++)
{ {
for(int ch=0; ch<k->second.heroes.size(); ++ch) for (int yd = std::max<int>(objCenter.y - radious, 0); yd <= std::min<int>(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); double distance = objCenter.dist2d(int3(xd,yd,objCenter.z)) - 0.5;
int deltaY = (k->second.heroes[ch]->getPosition(false).y-yd)*(k->second.heroes[ch]->getPosition(false).y-yd); if(distance <= radious)
if(deltaX+deltaY<k->second.heroes[ch]->getSightDistance()*k->second.heroes[ch]->getSightDistance()) k->second.fogOfWarMap[xd][yd][objCenter.z] = 1;
k->second.fogOfWarMap[xd][yd][k->second.heroes[ch]->getPosition(false).z] = 1;
} }
} }
} }
//for(int xd=0; xd<map->width; ++xd) //revealing part of map around heroes
//{
// for(int yd=0; yd<map->height; ++yd)
// {
// for(int ch=0; ch<k->second.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+deltaY<k->second.heroes[ch]->getSightDistance()*k->second.heroes[ch]->getSightDistance())
// k->second.fogOfWarMap[xd][yd][k->second.heroes[ch]->getPosition(false).z] = 1;
// }
// }
//}
//starting bonus //starting bonus
if(si->playerInfos[k->second.serial].bonus==brandom) if(si->playerInfos[k->second.serial].bonus==brandom)
si->playerInfos[k->second.serial].bonus = ran()%3; 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) if(k->first==-1 || k->first==255)
continue; continue;
for(int xd=0; xd<map->width; ++xd) //revealing part of map around towns // for(int xd=0; xd<map->width; ++xd) //revealing part of map around towns
{ // {
for(int yd=0; yd<map->height; ++yd) // for(int yd=0; yd<map->height; ++yd)
{ // {
for(int ch=0; ch<k->second.towns.size(); ++ch) // for(int ch=0; ch<k->second.towns.size(); ++ch)
{ // {
int deltaX = (k->second.towns[ch]->pos.x-xd)*(k->second.towns[ch]->pos.x-xd); // 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); // int deltaY = (k->second.towns[ch]->pos.y-yd)*(k->second.towns[ch]->pos.y-yd);
if(deltaX+deltaY<k->second.towns[ch]->getSightDistance()*k->second.towns[ch]->getSightDistance()) // if(deltaX+deltaY<k->second.towns[ch]->getSightDistance()*k->second.towns[ch]->getSightDistance())
k->second.fogOfWarMap[xd][yd][k->second.towns[ch]->pos.z] = 1; // k->second.fogOfWarMap[xd][yd][k->second.towns[ch]->pos.z] = 1;
} // }
} // }
} // }
//init visiting and garrisoned heroes //init visiting and garrisoned heroes
for(int l=0; l<k->second.heroes.size();l++) for(int l=0; l<k->second.heroes.size();l++)
@ -1307,33 +1326,21 @@ float CGameState::getMarketEfficiency( int player, int mode/*=0*/ )
} }
std::set<int3> CGameState::tilesToReveal(int3 pos, int radious, int player) const std::set<int3> CGameState::tilesToReveal(int3 pos, int radious, int player) const
{ {
std::set<int3> ret; std::set<int3> ret;
int xbeg = pos.x - radious - 2; if(player >= PLAYER_LIMIT)
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<xend; ++xd) //revealing part of map around heroes
{ {
for(int yd=ybeg; yd<yend; ++yd) tlog1 << "Illegal call to tilesToReveal!\n";
return ret;
}
for (int xd = std::max<int>(pos.x - radious , 0); xd <= std::min<int>(pos.x + radious, map->width); xd++)
{
for (int yd = std::max<int>(pos.y - radious, 0); std::min<int>(yd <= pos.y + radious, map->height); yd++)
{ {
int deltaX = (pos.x-xd)*(pos.x-xd); double distance = pos.dist2d(int3(xd,yd,pos.z)) - 0.5;
int deltaY = (pos.y-yd)*(pos.y-yd); if(distance <= radious && (player<0 || players.find(player)->second.fogOfWarMap[xd][yd][pos.z]==0))
if(deltaX+deltaY<radious*radious) ret.insert(int3(xd,yd,pos.z));
{
if(player<0 || players.find(player)->second.fogOfWarMap[xd][yd][pos.z]==0)
{
ret.insert(int3(xd,yd,pos.z));
}
}
} }
} }
return ret; return ret;

View File

@ -1943,6 +1943,8 @@ void CPlayerInterface::heroMovePointsChanged(const CGHeroInstance * hero)
void CPlayerInterface::receivedResource(int type, int val) void CPlayerInterface::receivedResource(int type, int val)
{ {
boost::unique_lock<boost::recursive_mutex> un(*pim); boost::unique_lock<boost::recursive_mutex> un(*pim);
if(!curint)
return;
if(curint==adventureInt || screen->h > 600 || screen->w > 800) if(curint==adventureInt || screen->h > 600 || screen->w > 800)
adventureInt->resdatabar.draw(); adventureInt->resdatabar.draw();
if(curint==castleInt && !curint->subInt) if(curint==castleInt && !curint->subInt)

View File

@ -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 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) 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 "<<id<<": NULL defInfo!\n";
return false; return false;
if((defInfo->visitMap[y+6-getHeight()] >> (7-(8-getWidth()+x) )) & 1) }
if((defInfo->visitMap[y] >> (7-x) ) & 1)
{
return true; return true;
}
return false; return false;
} }
bool CGObjectInstance::blockingAt(int x, int y) const 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 ) 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) int lowestSpeed(const CGHeroInstance * chi)
{ {
if(!chi->army.slots.size()) if(!chi->army.slots.size())
@ -288,10 +310,6 @@ int3 CGHeroInstance::getPosition(bool h3m) const //h3m=true - returns position o
return convertPosition(pos,false); return convertPosition(pos,false);
} }
} }
int CGHeroInstance::getSightDistance() const //returns sight distance of this hero
{
return 5 + getSecSkillLevel(3); //default + scouting
}
si32 CGHeroInstance::manaLimit() const si32 CGHeroInstance::manaLimit() const
{ {
@ -729,9 +747,20 @@ void CGHeroInstance::setPropertyDer( ui8 what, ui32 val )
if(what == 3) if(what == 3)
army.slots[0].second = val; 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 int CGTownInstance::fortLevel() const //0 - none, 1 - fort, 2 - citadel, 3 - castle
{ {
@ -870,6 +899,11 @@ void CGTownInstance::initObj()
hoverName = toString(ms); hoverName = toString(ms);
} }
int3 CGTownInstance::getSightCenter() const
{
return pos - int3(2,0,0);
}
void CGVisitableOPH::onHeroVisit( const CGHeroInstance * h ) const void CGVisitableOPH::onHeroVisit( const CGHeroInstance * h ) const
{ {
if(visitors.find(h->id)==visitors.end()) if(visitors.find(h->id)==visitors.end())

View File

@ -107,6 +107,8 @@ public:
ui8 tempOwner; ui8 tempOwner;
ui8 blockVisit; //if non-zero then blocks the tile but is visitable from neighbouring tile 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; int getOwner() const;
void setOwner(int ow); void setOwner(int ow);
int getWidth() const; //returns width of object graphic in tiles int getWidth() const; //returns width of object graphic in tiles
@ -206,6 +208,10 @@ public:
type = VLC->heroh->heroes[subID]; type = VLC->heroh->heroes[subID];
//visitied town pointer will be restored by map serialization method //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; const HeroBonus *getBonus(int from, int id) const;
@ -216,7 +222,6 @@ public:
unsigned int getAdditiveMoveBonus() const; unsigned int getAdditiveMoveBonus() const;
float getMultiplicativeMoveBonus() const; float getMultiplicativeMoveBonus() const;
int3 getPosition(bool h3m) const; //h3m=true - returns position of hero object; h3m=false - returns position of hero 'manifestation' 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) si32 manaLimit() const; //maximum mana value for this hero (basically 10*knowledge)
bool canWalkOnSea() const; bool canWalkOnSea() const;
int getCurrentLuck(int stack=-1, bool town=false) 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; bool needsLastStack() const;
int getSightDistance() const; //returns sight distance
int fortLevel() const; //0 - none, 1 - fort, 2 - citadel, 3 - castle 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 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 int mageGuildLevel() const; // -1 - none, 0 - village, 1 - town, 2 - city, 3 - capitol

View File

@ -197,7 +197,7 @@ int CLoadFile::read( const void * data, unsigned size )
CTypeList::CTypeList() CTypeList::CTypeList()
{ {
registerTypes(*this);
} }
ui16 CTypeList::registerType( const type_info *type ) ui16 CTypeList::registerType( const type_info *type )

View File

@ -56,7 +56,7 @@ enum SerializationLvl
struct TypeComparer 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); return a->before(*b);
} }
@ -69,7 +69,7 @@ class DLL_EXPORT CTypeList
public: public:
CTypeList(); CTypeList();
ui16 registerType(const type_info *type); ui16 registerType(const type_info *type);
template <typename T> ui16 registerType(const T * t) template <typename T> ui16 registerType(const T * t = NULL)
{ {
return registerType(getTypeInfo(t)); return registerType(getTypeInfo(t));
} }

View File

@ -16,4 +16,5 @@ void foofoofoo()
registerTypes((COSer<CConnection>&)*ccc); registerTypes((COSer<CConnection>&)*ccc);
registerTypes((CSaveFile&)*ccc); registerTypes((CSaveFile&)*ccc);
registerTypes((CLoadFile&)*ccc); registerTypes((CLoadFile&)*ccc);
registerTypes((CTypeList&)*ccc);
} }

View File

@ -140,7 +140,7 @@
Name="VCLinkerTool" Name="VCLinkerTool"
AdditionalDependencies="zdll.lib" AdditionalDependencies="zdll.lib"
Version="" Version=""
AdditionalLibraryDirectories="" AdditionalLibraryDirectories="../../libs;"
GenerateDebugInformation="false" GenerateDebugInformation="false"
OptimizeReferences="2" OptimizeReferences="2"
EnableCOMDATFolding="2" EnableCOMDATFolding="2"
@ -225,7 +225,7 @@
Name="VCLinkerTool" Name="VCLinkerTool"
AdditionalDependencies="zdll.lib" AdditionalDependencies="zdll.lib"
Version="" Version=""
AdditionalLibraryDirectories="" AdditionalLibraryDirectories="../../libs;"
GenerateDebugInformation="true" GenerateDebugInformation="true"
GenerateMapFile="true" GenerateMapFile="true"
OptimizeReferences="2" OptimizeReferences="2"

View File

@ -1229,7 +1229,7 @@ void CGameHandler::moveHero(si32 hid, int3 dst, ui8 instant, ui8 asker)
{ {
obj->onHeroLeave(h); 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); sendAndApply(&tmh);
tlog5 << "Moved to " <<tmh.end<<std::endl; tlog5 << "Moved to " <<tmh.end<<std::endl;
@ -1256,7 +1256,7 @@ void CGameHandler::moveHero(si32 hid, int3 dst, ui8 instant, ui8 asker)
} }
} }
tmh.result = instant+1; tmh.result = instant+1;
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); sendAndApply(&tmh);
} }
} }