1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00

Lazy updates of hero paths.

This commit is contained in:
Michał W. Urbańczyk 2011-09-03 02:54:33 +00:00
parent 5072bda7e6
commit 6b9e64de91
7 changed files with 27 additions and 28 deletions

View File

@ -312,7 +312,7 @@ bool CCallback::getPath2( int3 dest, CGPath &ret )
const CGHeroInstance *h = cl->IGameCallback::getSelectedHero(player);
assert(cl->pathInfo->hero == h);
if(cl->pathInfo->hpos != h->getPosition(false)) //hero position changed, must update paths
if(cl->pathInfo->hpos != h->getPosition(false) || !cl->pathInfo->isValid) //hero position changed, must update paths
{
recalculatePaths();
}

View File

@ -263,7 +263,6 @@ void CPlayerInterface::heroMoved(const TryMoveHero & details)
{
if(adventureInt->terrain.currentPath)
eraseCurrentPathOf(ho);
cb->recalculatePaths();
return; //teleport - no fancy moving animation
//TODO: smooth disappear / appear effect
}
@ -1079,7 +1078,6 @@ void CPlayerInterface::heroBonusChanged( const CGHeroInstance *hero, const Bonus
if ((bonus.type == Bonus::FLYING_MOVEMENT || bonus.type == Bonus::WATER_WALKING) && !gain)
{
//recalculate paths because hero has lost bonus influencing pathfinding
cb->recalculatePaths();
eraseCurrentPathOf(hero, false);
}
}
@ -1172,7 +1170,6 @@ bool CPlayerInterface::moveHero( const CGHeroInstance *h, CGPath path )
cb->getGsMutex().lock_shared();
pim->lock();
eventsM.lock();
cb->recalculatePaths();
return result;
}
@ -1936,7 +1933,6 @@ void CPlayerInterface::advmapSpellCast(const CGHeroInstance * caster, int spellI
{
if (spellID == Spells::FLY || spellID == Spells::WATER_WALK)
{
cb->recalculatePaths();
eraseCurrentPathOf(caster, false);
}
}

View File

@ -647,6 +647,12 @@ void CClient::commenceTacticPhaseForInt(CBattleGameInterface *battleInt)
} HANDLE_EXCEPTION
}
void CClient::invalidatePaths(const CGHeroInstance *h /*= NULL*/)
{
if(!h || pathInfo->hero == h)
pathInfo->isValid = false;
}
template void CClient::serialize( CISer<CLoadFile> &h, const int version );
template void CClient::serialize( COSer<CSaveFile> &h, const int version );

View File

@ -100,6 +100,7 @@ public:
void run();
void finishCampaign( CCampaignState * camp );
void proposeNextMission( CCampaignState * camp );
void invalidatePaths(const CGHeroInstance *h = NULL); //invalidates paths for hero h or for any hero if h is NULL => they'll got recalculated when the next query comes
void calculatePaths(const CGHeroInstance *h);
void updatePaths(); //calls calculatePaths for same hero for which we previously calculated paths

View File

@ -151,12 +151,7 @@ void SetMana::applyCl( CClient *cl )
void SetMovePoints::applyCl( CClient *cl )
{
const CGHeroInstance *h = cl->getHero(hid);
if (cl->IGameCallback::getSelectedHero(LOCPLINT->playerID) == h)//if we have selected that hero
{
cl->calculatePaths(h);
}
cl->invalidatePaths(h);
INTERFACE_CALL_IF_PRESENT(h->tempOwner, heroMovePointsChanged, h);
}
@ -167,7 +162,7 @@ void FoWChange::applyCl( CClient *cl )
else
INTERFACE_CALL_IF_PRESENT(player, tileHidden, tiles);
cl->updatePaths();
cl->invalidatePaths();
}
void SetAvailableHeroes::applyCl( CClient *cl )
@ -243,14 +238,13 @@ void HeroVisit::applyCl( CClient *cl )
void NewTurn::applyCl( CClient *cl )
{
//cl->updatePaths(); => may fail when there is no selected (mechanically) hero
if(cl->pathInfo->hero)
cl->calculatePaths(cl->pathInfo->hero);
cl->invalidatePaths();
}
void GiveBonus::applyCl( CClient *cl )
{
cl->invalidatePaths();
switch(who)
{
case HERO:
@ -280,7 +274,7 @@ void ChangeObjPos::applyCl( CClient *cl )
if(flags & 1)
CGI->mh->printObject(obj);
cl->updatePaths();
cl->invalidatePaths();
}
void PlayerEndsGame::applyCl( CClient *cl )
@ -290,6 +284,7 @@ void PlayerEndsGame::applyCl( CClient *cl )
void RemoveBonus::applyCl( CClient *cl )
{
cl->invalidatePaths();
switch(who)
{
case HERO:
@ -325,18 +320,14 @@ void RemoveObject::applyFirstCl( CClient *cl )
//notify interfaces about removal
for(std::map<ui8, CGameInterface*>::iterator i=cl->playerint.begin();i!=cl->playerint.end();i++)
{
if(i->first >= PLAYER_LIMIT) continue;
if(GS(cl)->getPlayerTeam(i->first)->fogOfWarMap[pos.x][pos.y][pos.z])
{
if(GS(cl)->isVisible(o, i->first))
i->second->objectRemoved(o);
}
}
}
void RemoveObject::applyCl( CClient *cl )
{
if(cl->pathInfo->hero && cl->pathInfo->hero->id != id)
cl->updatePaths();
cl->invalidatePaths();
}
void TryMoveHero::applyFirstCl( CClient *cl )
@ -365,6 +356,7 @@ void TryMoveHero::applyFirstCl( CClient *cl )
void TryMoveHero::applyCl( CClient *cl )
{
const CGHeroInstance *h = cl->getHero(id);
cl->invalidatePaths();
if(result == TELEPORTATION || result == EMBARK || result == DISEMBARK)
{
@ -781,7 +773,9 @@ void ShowInInfobox::applyCl(CClient *cl)
void AdvmapSpellCast::applyCl(CClient *cl)
{
cl->playerint[caster->getOwner()]->advmapSpellCast(caster, spellID);
cl->invalidatePaths();
//consider notifying other interfaces that see hero?
INTERFACE_CALL_IF_PRESENT(caster->getOwner(),advmapSpellCast, caster, spellID);
}
void OpenWindow::applyCl(CClient *cl)
@ -870,12 +864,8 @@ void NewObject::applyCl(CClient *cl)
for(std::map<ui8, CGameInterface*>::iterator i=cl->playerint.begin();i!=cl->playerint.end();i++)
{
//TODO: check if any covered tile is visible
if(i->first >= PLAYER_LIMIT) continue;
if(GS(cl)->getPlayerTeam(i->first)->fogOfWarMap[obj->pos.x][obj->pos.y][obj->pos.z])
{
if(GS(cl)->isVisible(obj, i->first))
i->second->newObject(obj);
}
}
}

View File

@ -2005,6 +2005,7 @@ bool CGameState::getPath(int3 src, int3 dest, const CGHeroInstance * hero, CPath
void CGameState::calculatePaths(const CGHeroInstance *hero, CPathsInfo &out, int3 src, int movement)
{
assert(hero);
assert(hero == getHero(hero->id));
if(src.x < 0)
src = hero->getPosition(false);
if(movement < 0)
@ -2209,6 +2210,8 @@ void CGameState::calculatePaths(const CGHeroInstance *hero, CPathsInfo &out, int
}
} //neighbours loop
} //queue loop
out.isValid = true;
}
/**
@ -2824,6 +2827,8 @@ CGPathNode::CGPathNode()
bool CPathsInfo::getPath( const int3 &dst, CGPath &out )
{
assert(isValid);
out.nodes.clear();
const CGPathNode *curnode = &nodes[dst.x][dst.y][dst.z];
if(!curnode->theNodeBefore || curnode->accessible == CGPathNode::FLYABLE)

View File

@ -267,6 +267,7 @@ struct DLL_EXPORT CGPath
struct DLL_EXPORT CPathsInfo
{
bool isValid;
const CGHeroInstance *hero;
int3 hpos;
int3 sizes;