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:
parent
5072bda7e6
commit
6b9e64de91
@ -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();
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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 );
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -267,6 +267,7 @@ struct DLL_EXPORT CGPath
|
||||
|
||||
struct DLL_EXPORT CPathsInfo
|
||||
{
|
||||
bool isValid;
|
||||
const CGHeroInstance *hero;
|
||||
int3 hpos;
|
||||
int3 sizes;
|
||||
|
Loading…
Reference in New Issue
Block a user