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:
{
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],

View File

@ -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)

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 v=0; v<map->twoLevel+1; ++v)
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);
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;
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; 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
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; xd<map->width; ++xd) //revealing part of map around towns
{
for(int yd=0; yd<map->height; ++yd)
{
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 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())
k->second.fogOfWarMap[xd][yd][k->second.towns[ch]->pos.z] = 1;
}
}
}
// for(int xd=0; xd<map->width; ++xd) //revealing part of map around towns
// {
// for(int yd=0; yd<map->height; ++yd)
// {
// 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 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())
// k->second.fogOfWarMap[xd][yd][k->second.towns[ch]->pos.z] = 1;
// }
// }
// }
//init visiting and garrisoned heroes
for(int l=0; l<k->second.heroes.size();l++)
@ -1309,33 +1328,21 @@ float CGameState::getMarketEfficiency( int player, int mode/*=0*/ )
std::set<int3> CGameState::tilesToReveal(int3 pos, int radious, int player) const
{
std::set<int3> 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<xend; ++xd) //revealing part of map around heroes
if(player >= PLAYER_LIMIT)
{
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++)
{
int deltaX = (pos.x-xd)*(pos.x-xd);
int deltaY = (pos.y-yd)*(pos.y-yd);
if(deltaX+deltaY<radious*radious)
{
if(player<0 || players.find(player)->second.fogOfWarMap[xd][yd][pos.z]==0)
for (int yd = std::max<int>(pos.y - radious, 0); std::min<int>(yd <= pos.y + radious, map->height); yd++)
{
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;
}

View File

@ -1943,6 +1943,8 @@ void CPlayerInterface::heroMovePointsChanged(const CGHeroInstance * hero)
void CPlayerInterface::receivedResource(int type, int val)
{
boost::unique_lock<boost::recursive_mutex> un(*pim);
if(!curint)
return;
if(curint==adventureInt || screen->h > 600 || screen->w > 800)
adventureInt->resdatabar.draw();
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
{
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 "<<id<<": NULL defInfo!\n";
return false;
if((defInfo->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())

View File

@ -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

View File

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

View File

@ -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 <typename T> ui16 registerType(const T * t)
template <typename T> ui16 registerType(const T * t = NULL)
{
return registerType(getTypeInfo(t));
}

View File

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

View File

@ -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"

View File

@ -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 " <<tmh.end<<std::endl;
@ -1256,7 +1256,7 @@ void CGameHandler::moveHero(si32 hid, int3 dst, ui8 instant, ui8 asker)
}
}
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);
}
}