mirror of
https://github.com/vcmi/vcmi.git
synced 2025-01-12 02:28:11 +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);
|
const CGHeroInstance *h = cl->IGameCallback::getSelectedHero(player);
|
||||||
assert(cl->pathInfo->hero == h);
|
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();
|
recalculatePaths();
|
||||||
}
|
}
|
||||||
|
@ -263,7 +263,6 @@ void CPlayerInterface::heroMoved(const TryMoveHero & details)
|
|||||||
{
|
{
|
||||||
if(adventureInt->terrain.currentPath)
|
if(adventureInt->terrain.currentPath)
|
||||||
eraseCurrentPathOf(ho);
|
eraseCurrentPathOf(ho);
|
||||||
cb->recalculatePaths();
|
|
||||||
return; //teleport - no fancy moving animation
|
return; //teleport - no fancy moving animation
|
||||||
//TODO: smooth disappear / appear effect
|
//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)
|
if ((bonus.type == Bonus::FLYING_MOVEMENT || bonus.type == Bonus::WATER_WALKING) && !gain)
|
||||||
{
|
{
|
||||||
//recalculate paths because hero has lost bonus influencing pathfinding
|
//recalculate paths because hero has lost bonus influencing pathfinding
|
||||||
cb->recalculatePaths();
|
|
||||||
eraseCurrentPathOf(hero, false);
|
eraseCurrentPathOf(hero, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1172,7 +1170,6 @@ bool CPlayerInterface::moveHero( const CGHeroInstance *h, CGPath path )
|
|||||||
cb->getGsMutex().lock_shared();
|
cb->getGsMutex().lock_shared();
|
||||||
pim->lock();
|
pim->lock();
|
||||||
eventsM.lock();
|
eventsM.lock();
|
||||||
cb->recalculatePaths();
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1936,7 +1933,6 @@ void CPlayerInterface::advmapSpellCast(const CGHeroInstance * caster, int spellI
|
|||||||
{
|
{
|
||||||
if (spellID == Spells::FLY || spellID == Spells::WATER_WALK)
|
if (spellID == Spells::FLY || spellID == Spells::WATER_WALK)
|
||||||
{
|
{
|
||||||
cb->recalculatePaths();
|
|
||||||
eraseCurrentPathOf(caster, false);
|
eraseCurrentPathOf(caster, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -647,6 +647,12 @@ void CClient::commenceTacticPhaseForInt(CBattleGameInterface *battleInt)
|
|||||||
} HANDLE_EXCEPTION
|
} 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( CISer<CLoadFile> &h, const int version );
|
||||||
template void CClient::serialize( COSer<CSaveFile> &h, const int version );
|
template void CClient::serialize( COSer<CSaveFile> &h, const int version );
|
||||||
|
|
||||||
|
@ -100,6 +100,7 @@ public:
|
|||||||
void run();
|
void run();
|
||||||
void finishCampaign( CCampaignState * camp );
|
void finishCampaign( CCampaignState * camp );
|
||||||
void proposeNextMission( 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 calculatePaths(const CGHeroInstance *h);
|
||||||
void updatePaths(); //calls calculatePaths for same hero for which we previously calculated paths
|
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 )
|
void SetMovePoints::applyCl( CClient *cl )
|
||||||
{
|
{
|
||||||
const CGHeroInstance *h = cl->getHero(hid);
|
const CGHeroInstance *h = cl->getHero(hid);
|
||||||
|
cl->invalidatePaths(h);
|
||||||
if (cl->IGameCallback::getSelectedHero(LOCPLINT->playerID) == h)//if we have selected that hero
|
|
||||||
{
|
|
||||||
cl->calculatePaths(h);
|
|
||||||
}
|
|
||||||
|
|
||||||
INTERFACE_CALL_IF_PRESENT(h->tempOwner, heroMovePointsChanged, h);
|
INTERFACE_CALL_IF_PRESENT(h->tempOwner, heroMovePointsChanged, h);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -167,7 +162,7 @@ void FoWChange::applyCl( CClient *cl )
|
|||||||
else
|
else
|
||||||
INTERFACE_CALL_IF_PRESENT(player, tileHidden, tiles);
|
INTERFACE_CALL_IF_PRESENT(player, tileHidden, tiles);
|
||||||
|
|
||||||
cl->updatePaths();
|
cl->invalidatePaths();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetAvailableHeroes::applyCl( CClient *cl )
|
void SetAvailableHeroes::applyCl( CClient *cl )
|
||||||
@ -243,14 +238,13 @@ void HeroVisit::applyCl( CClient *cl )
|
|||||||
|
|
||||||
void NewTurn::applyCl( CClient *cl )
|
void NewTurn::applyCl( CClient *cl )
|
||||||
{
|
{
|
||||||
//cl->updatePaths(); => may fail when there is no selected (mechanically) hero
|
cl->invalidatePaths();
|
||||||
if(cl->pathInfo->hero)
|
|
||||||
cl->calculatePaths(cl->pathInfo->hero);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void GiveBonus::applyCl( CClient *cl )
|
void GiveBonus::applyCl( CClient *cl )
|
||||||
{
|
{
|
||||||
|
cl->invalidatePaths();
|
||||||
switch(who)
|
switch(who)
|
||||||
{
|
{
|
||||||
case HERO:
|
case HERO:
|
||||||
@ -280,7 +274,7 @@ void ChangeObjPos::applyCl( CClient *cl )
|
|||||||
if(flags & 1)
|
if(flags & 1)
|
||||||
CGI->mh->printObject(obj);
|
CGI->mh->printObject(obj);
|
||||||
|
|
||||||
cl->updatePaths();
|
cl->invalidatePaths();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlayerEndsGame::applyCl( CClient *cl )
|
void PlayerEndsGame::applyCl( CClient *cl )
|
||||||
@ -290,6 +284,7 @@ void PlayerEndsGame::applyCl( CClient *cl )
|
|||||||
|
|
||||||
void RemoveBonus::applyCl( CClient *cl )
|
void RemoveBonus::applyCl( CClient *cl )
|
||||||
{
|
{
|
||||||
|
cl->invalidatePaths();
|
||||||
switch(who)
|
switch(who)
|
||||||
{
|
{
|
||||||
case HERO:
|
case HERO:
|
||||||
@ -325,18 +320,14 @@ void RemoveObject::applyFirstCl( CClient *cl )
|
|||||||
//notify interfaces about removal
|
//notify interfaces about removal
|
||||||
for(std::map<ui8, CGameInterface*>::iterator i=cl->playerint.begin();i!=cl->playerint.end();i++)
|
for(std::map<ui8, CGameInterface*>::iterator i=cl->playerint.begin();i!=cl->playerint.end();i++)
|
||||||
{
|
{
|
||||||
if(i->first >= PLAYER_LIMIT) continue;
|
if(GS(cl)->isVisible(o, i->first))
|
||||||
if(GS(cl)->getPlayerTeam(i->first)->fogOfWarMap[pos.x][pos.y][pos.z])
|
|
||||||
{
|
|
||||||
i->second->objectRemoved(o);
|
i->second->objectRemoved(o);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RemoveObject::applyCl( CClient *cl )
|
void RemoveObject::applyCl( CClient *cl )
|
||||||
{
|
{
|
||||||
if(cl->pathInfo->hero && cl->pathInfo->hero->id != id)
|
cl->invalidatePaths();
|
||||||
cl->updatePaths();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TryMoveHero::applyFirstCl( CClient *cl )
|
void TryMoveHero::applyFirstCl( CClient *cl )
|
||||||
@ -365,6 +356,7 @@ void TryMoveHero::applyFirstCl( CClient *cl )
|
|||||||
void TryMoveHero::applyCl( CClient *cl )
|
void TryMoveHero::applyCl( CClient *cl )
|
||||||
{
|
{
|
||||||
const CGHeroInstance *h = cl->getHero(id);
|
const CGHeroInstance *h = cl->getHero(id);
|
||||||
|
cl->invalidatePaths();
|
||||||
|
|
||||||
if(result == TELEPORTATION || result == EMBARK || result == DISEMBARK)
|
if(result == TELEPORTATION || result == EMBARK || result == DISEMBARK)
|
||||||
{
|
{
|
||||||
@ -781,7 +773,9 @@ void ShowInInfobox::applyCl(CClient *cl)
|
|||||||
|
|
||||||
void AdvmapSpellCast::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)
|
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++)
|
for(std::map<ui8, CGameInterface*>::iterator i=cl->playerint.begin();i!=cl->playerint.end();i++)
|
||||||
{
|
{
|
||||||
//TODO: check if any covered tile is visible
|
if(GS(cl)->isVisible(obj, i->first))
|
||||||
if(i->first >= PLAYER_LIMIT) continue;
|
|
||||||
if(GS(cl)->getPlayerTeam(i->first)->fogOfWarMap[obj->pos.x][obj->pos.y][obj->pos.z])
|
|
||||||
{
|
|
||||||
i->second->newObject(obj);
|
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)
|
void CGameState::calculatePaths(const CGHeroInstance *hero, CPathsInfo &out, int3 src, int movement)
|
||||||
{
|
{
|
||||||
assert(hero);
|
assert(hero);
|
||||||
|
assert(hero == getHero(hero->id));
|
||||||
if(src.x < 0)
|
if(src.x < 0)
|
||||||
src = hero->getPosition(false);
|
src = hero->getPosition(false);
|
||||||
if(movement < 0)
|
if(movement < 0)
|
||||||
@ -2209,6 +2210,8 @@ void CGameState::calculatePaths(const CGHeroInstance *hero, CPathsInfo &out, int
|
|||||||
}
|
}
|
||||||
} //neighbours loop
|
} //neighbours loop
|
||||||
} //queue loop
|
} //queue loop
|
||||||
|
|
||||||
|
out.isValid = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2824,6 +2827,8 @@ CGPathNode::CGPathNode()
|
|||||||
|
|
||||||
bool CPathsInfo::getPath( const int3 &dst, CGPath &out )
|
bool CPathsInfo::getPath( const int3 &dst, CGPath &out )
|
||||||
{
|
{
|
||||||
|
assert(isValid);
|
||||||
|
|
||||||
out.nodes.clear();
|
out.nodes.clear();
|
||||||
const CGPathNode *curnode = &nodes[dst.x][dst.y][dst.z];
|
const CGPathNode *curnode = &nodes[dst.x][dst.y][dst.z];
|
||||||
if(!curnode->theNodeBefore || curnode->accessible == CGPathNode::FLYABLE)
|
if(!curnode->theNodeBefore || curnode->accessible == CGPathNode::FLYABLE)
|
||||||
|
@ -267,6 +267,7 @@ struct DLL_EXPORT CGPath
|
|||||||
|
|
||||||
struct DLL_EXPORT CPathsInfo
|
struct DLL_EXPORT CPathsInfo
|
||||||
{
|
{
|
||||||
|
bool isValid;
|
||||||
const CGHeroInstance *hero;
|
const CGHeroInstance *hero;
|
||||||
int3 hpos;
|
int3 hpos;
|
||||||
int3 sizes;
|
int3 sizes;
|
||||||
|
Loading…
Reference in New Issue
Block a user