1
0
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:
yupsi 2011-10-04 19:43:49 +00:00
parent 8c2dd9fdce
commit 583aca8912
5 changed files with 88 additions and 23 deletions

View File

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

View File

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

View File

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

View File

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

View File

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