mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
Move hero/Next hero buttons being blocked when they should (#204)
This commit is contained in:
parent
8c2dd9fdce
commit
583aca8912
@ -1099,7 +1099,13 @@ void CAdvMapInt::fsleepWake()
|
||||
setHeroSleeping(h, newSleep);
|
||||
updateSleepWake(h);
|
||||
if (newSleep)
|
||||
{
|
||||
fnextHero();
|
||||
|
||||
//moveHero.block(true);
|
||||
//uncomment to enable original HoMM3 behaviour:
|
||||
//move button is disabled for hero going to sleep, even though it's enabled when you reselect him
|
||||
}
|
||||
}
|
||||
|
||||
void CAdvMapInt::fmoveHero()
|
||||
@ -1134,19 +1140,10 @@ void CAdvMapInt::fsystemOptions()
|
||||
|
||||
void CAdvMapInt::fnextHero()
|
||||
{
|
||||
if(!LOCPLINT->wanderingHeroes.size()) //no wandering heroes
|
||||
return;
|
||||
|
||||
int start = heroList.selected;
|
||||
int i = start;
|
||||
|
||||
do
|
||||
{
|
||||
i++;
|
||||
if(i >= LOCPLINT->wanderingHeroes.size())
|
||||
i = 0;
|
||||
} while ((!LOCPLINT->wanderingHeroes[i]->movement || isHeroSleeping(LOCPLINT->wanderingHeroes[i])) && i!=start);
|
||||
heroList.select(i);
|
||||
int next = getNextHeroIndex(heroList.selected);
|
||||
if (next < 0)
|
||||
return;
|
||||
heroList.select(next);
|
||||
}
|
||||
|
||||
void CAdvMapInt::fendTurn()
|
||||
@ -1155,7 +1152,7 @@ void CAdvMapInt::fendTurn()
|
||||
return;
|
||||
|
||||
for (int i = 0; i < LOCPLINT->wanderingHeroes.size(); i++)
|
||||
if (!isHeroSleeping(LOCPLINT->wanderingHeroes[i]) && (LOCPLINT->wanderingHeroes[i]->movement > 0)) // some other minimal threshold probably?
|
||||
if (!isHeroSleeping(LOCPLINT->wanderingHeroes[i]) && (LOCPLINT->wanderingHeroes[i]->movement > 0))
|
||||
{
|
||||
LOCPLINT->showYesNoDialog(CGI->generaltexth->allTexts[55], std::vector<SComponent*>(), boost::bind(&CAdvMapInt::endingTurn, this), 0, false);
|
||||
return;
|
||||
@ -1175,6 +1172,54 @@ void CAdvMapInt::updateSleepWake(const CGHeroInstance *h)
|
||||
sleepWake.update();
|
||||
}
|
||||
|
||||
void CAdvMapInt::updateMoveHero(const CGHeroInstance *h, tribool hasPath)
|
||||
{
|
||||
//default value is for everywhere but CPlayerInterface::moveHero, because paths are not updated from there immediately
|
||||
if (hasPath == tribool::indeterminate_value)
|
||||
hasPath = LOCPLINT->paths[h].nodes.size() ? true : false;
|
||||
if (!h)
|
||||
{
|
||||
moveHero.block(true);
|
||||
return;
|
||||
}
|
||||
moveHero.block(!hasPath || (h->movement == 0));
|
||||
}
|
||||
|
||||
int CAdvMapInt::getNextHeroIndex(int startIndex)
|
||||
{
|
||||
if (LOCPLINT->wanderingHeroes.size() == 0)
|
||||
return -1;
|
||||
if (startIndex < 0)
|
||||
startIndex = 0;
|
||||
int i = startIndex;
|
||||
do
|
||||
{
|
||||
i++;
|
||||
if (i >= LOCPLINT->wanderingHeroes.size())
|
||||
i = 0;
|
||||
}
|
||||
while (((LOCPLINT->wanderingHeroes[i]->movement == 0) || isHeroSleeping(LOCPLINT->wanderingHeroes[i])) && (i != startIndex));
|
||||
|
||||
if ((LOCPLINT->wanderingHeroes[i]->movement > 0) && !isHeroSleeping(LOCPLINT->wanderingHeroes[i]))
|
||||
return i;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
void CAdvMapInt::updateNextHero(const CGHeroInstance *h)
|
||||
{
|
||||
int start = heroList.getPosOfHero(h);
|
||||
int next = getNextHeroIndex(start);
|
||||
if (next < 0)
|
||||
{
|
||||
nextHero.block(true);
|
||||
return;
|
||||
}
|
||||
const CGHeroInstance *nextH = LOCPLINT->wanderingHeroes[next];
|
||||
bool noActiveHeroes = (next == start) && ((nextH->movement == 0) || isHeroSleeping(nextH));
|
||||
nextHero.block(noActiveHeroes);
|
||||
}
|
||||
|
||||
void CAdvMapInt::activate()
|
||||
{
|
||||
if(isActive())
|
||||
@ -1279,6 +1324,7 @@ void CAdvMapInt::setHeroSleeping(const CGHeroInstance *hero, bool sleep)
|
||||
LOCPLINT->sleepingHeroes += hero;
|
||||
else
|
||||
LOCPLINT->sleepingHeroes -= hero;
|
||||
updateNextHero(NULL);
|
||||
}
|
||||
|
||||
void CAdvMapInt::show(SDL_Surface *to)
|
||||
@ -1548,18 +1594,15 @@ void CAdvMapInt::select(const CArmedInstance *sel, bool centerView /*= true*/)
|
||||
terrain.currentPath = NULL;
|
||||
if(sel->ID==TOWNI_TYPE)
|
||||
{
|
||||
updateSleepWake(NULL);
|
||||
|
||||
int pos = vstd::findPos(LOCPLINT->towns,sel);
|
||||
townList.selected = pos;
|
||||
townList.fixPos();
|
||||
updateSleepWake(NULL);
|
||||
updateMoveHero(NULL);
|
||||
}
|
||||
else //hero selected
|
||||
{
|
||||
const CGHeroInstance *h = static_cast<const CGHeroInstance*>(sel);
|
||||
|
||||
updateSleepWake(h);
|
||||
|
||||
if(LOCPLINT->getWHero(heroList.selected) != h)
|
||||
{
|
||||
heroList.selected = heroList.getPosOfHero(h);
|
||||
@ -1567,6 +1610,9 @@ void CAdvMapInt::select(const CArmedInstance *sel, bool centerView /*= true*/)
|
||||
}
|
||||
|
||||
terrain.currentPath = LOCPLINT->getAndVerifyPath(h);
|
||||
|
||||
updateSleepWake(h);
|
||||
updateMoveHero(h);
|
||||
}
|
||||
townList.draw(screen);
|
||||
heroList.draw(screen);
|
||||
@ -1725,7 +1771,9 @@ void CAdvMapInt::tileLClicked(const int3 &mp)
|
||||
{
|
||||
CGPath &path = LOCPLINT->paths[currentHero];
|
||||
terrain.currentPath = &path;
|
||||
if(!LOCPLINT->cb->getPath2(mp, path)) //try getting path, erase if failed
|
||||
bool gotPath = LOCPLINT->cb->getPath2(mp, path); //try getting path, erase if failed
|
||||
updateMoveHero(currentHero);
|
||||
if (!gotPath)
|
||||
LOCPLINT->eraseCurrentPathOf(currentHero);
|
||||
else
|
||||
return;
|
||||
|
@ -235,6 +235,7 @@ public:
|
||||
|
||||
bool isHeroSleeping(const CGHeroInstance *hero);
|
||||
void setHeroSleeping(const CGHeroInstance *hero, bool sleep);
|
||||
int getNextHeroIndex(int startIndex); //for Next Hero button - cycles awake heroes with movement only
|
||||
|
||||
void setPlayer(int Player);
|
||||
void startHotSeatWait(int Player);
|
||||
@ -248,7 +249,10 @@ public:
|
||||
const CGHeroInstance * curHero() const;
|
||||
const CGTownInstance * curTown() const;
|
||||
const IShipyard * ourInaccessibleShipyard(const CGObjectInstance *obj) const; //checks if obj is our ashipyard and cursor is 0,0 -> returns shipyard or NULL else
|
||||
void updateSleepWake(const CGHeroInstance *h); //button update
|
||||
//button updates
|
||||
void updateSleepWake(const CGHeroInstance *h);
|
||||
void updateMoveHero(const CGHeroInstance *h, tribool hasPath = tribool::indeterminate_value);
|
||||
void updateNextHero(const CGHeroInstance *h);
|
||||
};
|
||||
|
||||
extern CAdvMapInt *adventureInt;
|
||||
|
@ -488,6 +488,7 @@ void CPlayerInterface::heroInGarrisonChange(const CGTownInstance *town)
|
||||
CGI->mh->printObject(town->visitingHero);
|
||||
wanderingHeroes.push_back(town->visitingHero);
|
||||
}
|
||||
adventureInt->updateNextHero(NULL);
|
||||
|
||||
if(CCastleInterface *c = castleInt)
|
||||
{
|
||||
@ -1142,6 +1143,7 @@ bool CPlayerInterface::moveHero( const CGHeroInstance *h, CGPath path )
|
||||
//but no authentic button click/sound ;-)
|
||||
}
|
||||
|
||||
int i = 1;
|
||||
//evil...
|
||||
eventsM.unlock();
|
||||
pim->unlock();
|
||||
@ -1159,7 +1161,7 @@ bool CPlayerInterface::moveHero( const CGHeroInstance *h, CGPath path )
|
||||
|
||||
const TerrainTile * curTile = cb->getTile(CGHeroInstance::convertPosition(h->pos, false));
|
||||
|
||||
for(int i=path.nodes.size()-1; i>0 && (stillMoveHero.data == CONTINUE_MOVE || curTile->blocked); i--)
|
||||
for(i=path.nodes.size()-1; i>0 && (stillMoveHero.data == CONTINUE_MOVE || curTile->blocked); i--)
|
||||
{
|
||||
//changing z coordinate means we're moving through subterranean gate -> it's done automatically upon the visit, so we don't have to request that move here
|
||||
if(path.nodes[i-1].coord.z != path.nodes[i].coord.z)
|
||||
@ -1209,6 +1211,13 @@ bool CPlayerInterface::moveHero( const CGHeroInstance *h, CGPath path )
|
||||
cb->getGsMutex().lock_shared();
|
||||
pim->lock();
|
||||
eventsM.lock();
|
||||
|
||||
if (adventureInt)
|
||||
{
|
||||
// (i == 0) means hero went through all the path
|
||||
adventureInt->updateMoveHero(h, (i != 0));
|
||||
adventureInt->updateNextHero(h);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -1336,6 +1345,8 @@ void CPlayerInterface::recreateHeroTownList()
|
||||
std::vector<const CGTownInstance*> townInfo = cb->getTownsInfo();
|
||||
for(size_t i = 0; i < townInfo.size(); i++)
|
||||
towns.push_back(townInfo[i]);
|
||||
|
||||
adventureInt->updateNextHero(NULL);
|
||||
}
|
||||
|
||||
const CGHeroInstance * CPlayerInterface::getWHero( int pos )
|
||||
|
@ -141,7 +141,7 @@ public:
|
||||
std::vector<const CGHeroInstance *> wanderingHeroes; //our heroes on the adventure map (not the garrisoned ones)
|
||||
std::vector<const CGTownInstance *> towns; //our heroes on the adventure map (not the garrisoned ones)
|
||||
std::map<const CGHeroInstance *, CGPath> paths; //maps hero => selected path in adventure map
|
||||
std::vector<const CGHeroInstance *> sleepingHeroes;
|
||||
std::vector<const CGHeroInstance *> sleepingHeroes; //if hero is in here, he's sleeping
|
||||
|
||||
struct SpellbookLastSetting
|
||||
{
|
||||
|
@ -1355,6 +1355,8 @@ void CHeroList::updateHList(const CGHeroInstance *toRemove)
|
||||
else
|
||||
select(selected);
|
||||
}
|
||||
|
||||
adventureInt->updateNextHero(NULL);
|
||||
}
|
||||
|
||||
void CHeroList::updateMove(const CGHeroInstance* which) //draws move points bar
|
||||
|
Loading…
Reference in New Issue
Block a user