mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-26 22:57:00 +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);
|
setHeroSleeping(h, newSleep);
|
||||||
updateSleepWake(h);
|
updateSleepWake(h);
|
||||||
if (newSleep)
|
if (newSleep)
|
||||||
|
{
|
||||||
fnextHero();
|
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()
|
void CAdvMapInt::fmoveHero()
|
||||||
@ -1134,19 +1140,10 @@ void CAdvMapInt::fsystemOptions()
|
|||||||
|
|
||||||
void CAdvMapInt::fnextHero()
|
void CAdvMapInt::fnextHero()
|
||||||
{
|
{
|
||||||
if(!LOCPLINT->wanderingHeroes.size()) //no wandering heroes
|
int next = getNextHeroIndex(heroList.selected);
|
||||||
|
if (next < 0)
|
||||||
return;
|
return;
|
||||||
|
heroList.select(next);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CAdvMapInt::fendTurn()
|
void CAdvMapInt::fendTurn()
|
||||||
@ -1155,7 +1152,7 @@ void CAdvMapInt::fendTurn()
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
for (int i = 0; i < LOCPLINT->wanderingHeroes.size(); i++)
|
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);
|
LOCPLINT->showYesNoDialog(CGI->generaltexth->allTexts[55], std::vector<SComponent*>(), boost::bind(&CAdvMapInt::endingTurn, this), 0, false);
|
||||||
return;
|
return;
|
||||||
@ -1175,6 +1172,54 @@ void CAdvMapInt::updateSleepWake(const CGHeroInstance *h)
|
|||||||
sleepWake.update();
|
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()
|
void CAdvMapInt::activate()
|
||||||
{
|
{
|
||||||
if(isActive())
|
if(isActive())
|
||||||
@ -1279,6 +1324,7 @@ void CAdvMapInt::setHeroSleeping(const CGHeroInstance *hero, bool sleep)
|
|||||||
LOCPLINT->sleepingHeroes += hero;
|
LOCPLINT->sleepingHeroes += hero;
|
||||||
else
|
else
|
||||||
LOCPLINT->sleepingHeroes -= hero;
|
LOCPLINT->sleepingHeroes -= hero;
|
||||||
|
updateNextHero(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CAdvMapInt::show(SDL_Surface *to)
|
void CAdvMapInt::show(SDL_Surface *to)
|
||||||
@ -1548,18 +1594,15 @@ void CAdvMapInt::select(const CArmedInstance *sel, bool centerView /*= true*/)
|
|||||||
terrain.currentPath = NULL;
|
terrain.currentPath = NULL;
|
||||||
if(sel->ID==TOWNI_TYPE)
|
if(sel->ID==TOWNI_TYPE)
|
||||||
{
|
{
|
||||||
updateSleepWake(NULL);
|
|
||||||
|
|
||||||
int pos = vstd::findPos(LOCPLINT->towns,sel);
|
int pos = vstd::findPos(LOCPLINT->towns,sel);
|
||||||
townList.selected = pos;
|
townList.selected = pos;
|
||||||
townList.fixPos();
|
townList.fixPos();
|
||||||
|
updateSleepWake(NULL);
|
||||||
|
updateMoveHero(NULL);
|
||||||
}
|
}
|
||||||
else //hero selected
|
else //hero selected
|
||||||
{
|
{
|
||||||
const CGHeroInstance *h = static_cast<const CGHeroInstance*>(sel);
|
const CGHeroInstance *h = static_cast<const CGHeroInstance*>(sel);
|
||||||
|
|
||||||
updateSleepWake(h);
|
|
||||||
|
|
||||||
if(LOCPLINT->getWHero(heroList.selected) != h)
|
if(LOCPLINT->getWHero(heroList.selected) != h)
|
||||||
{
|
{
|
||||||
heroList.selected = heroList.getPosOfHero(h);
|
heroList.selected = heroList.getPosOfHero(h);
|
||||||
@ -1567,6 +1610,9 @@ void CAdvMapInt::select(const CArmedInstance *sel, bool centerView /*= true*/)
|
|||||||
}
|
}
|
||||||
|
|
||||||
terrain.currentPath = LOCPLINT->getAndVerifyPath(h);
|
terrain.currentPath = LOCPLINT->getAndVerifyPath(h);
|
||||||
|
|
||||||
|
updateSleepWake(h);
|
||||||
|
updateMoveHero(h);
|
||||||
}
|
}
|
||||||
townList.draw(screen);
|
townList.draw(screen);
|
||||||
heroList.draw(screen);
|
heroList.draw(screen);
|
||||||
@ -1725,7 +1771,9 @@ void CAdvMapInt::tileLClicked(const int3 &mp)
|
|||||||
{
|
{
|
||||||
CGPath &path = LOCPLINT->paths[currentHero];
|
CGPath &path = LOCPLINT->paths[currentHero];
|
||||||
terrain.currentPath = &path;
|
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);
|
LOCPLINT->eraseCurrentPathOf(currentHero);
|
||||||
else
|
else
|
||||||
return;
|
return;
|
||||||
|
@ -235,6 +235,7 @@ public:
|
|||||||
|
|
||||||
bool isHeroSleeping(const CGHeroInstance *hero);
|
bool isHeroSleeping(const CGHeroInstance *hero);
|
||||||
void setHeroSleeping(const CGHeroInstance *hero, bool sleep);
|
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 setPlayer(int Player);
|
||||||
void startHotSeatWait(int Player);
|
void startHotSeatWait(int Player);
|
||||||
@ -248,7 +249,10 @@ public:
|
|||||||
const CGHeroInstance * curHero() const;
|
const CGHeroInstance * curHero() const;
|
||||||
const CGTownInstance * curTown() 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
|
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;
|
extern CAdvMapInt *adventureInt;
|
||||||
|
@ -488,6 +488,7 @@ void CPlayerInterface::heroInGarrisonChange(const CGTownInstance *town)
|
|||||||
CGI->mh->printObject(town->visitingHero);
|
CGI->mh->printObject(town->visitingHero);
|
||||||
wanderingHeroes.push_back(town->visitingHero);
|
wanderingHeroes.push_back(town->visitingHero);
|
||||||
}
|
}
|
||||||
|
adventureInt->updateNextHero(NULL);
|
||||||
|
|
||||||
if(CCastleInterface *c = castleInt)
|
if(CCastleInterface *c = castleInt)
|
||||||
{
|
{
|
||||||
@ -1142,6 +1143,7 @@ bool CPlayerInterface::moveHero( const CGHeroInstance *h, CGPath path )
|
|||||||
//but no authentic button click/sound ;-)
|
//but no authentic button click/sound ;-)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int i = 1;
|
||||||
//evil...
|
//evil...
|
||||||
eventsM.unlock();
|
eventsM.unlock();
|
||||||
pim->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));
|
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
|
//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)
|
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();
|
cb->getGsMutex().lock_shared();
|
||||||
pim->lock();
|
pim->lock();
|
||||||
eventsM.lock();
|
eventsM.lock();
|
||||||
|
|
||||||
|
if (adventureInt)
|
||||||
|
{
|
||||||
|
// (i == 0) means hero went through all the path
|
||||||
|
adventureInt->updateMoveHero(h, (i != 0));
|
||||||
|
adventureInt->updateNextHero(h);
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1336,6 +1345,8 @@ void CPlayerInterface::recreateHeroTownList()
|
|||||||
std::vector<const CGTownInstance*> townInfo = cb->getTownsInfo();
|
std::vector<const CGTownInstance*> townInfo = cb->getTownsInfo();
|
||||||
for(size_t i = 0; i < townInfo.size(); i++)
|
for(size_t i = 0; i < townInfo.size(); i++)
|
||||||
towns.push_back(townInfo[i]);
|
towns.push_back(townInfo[i]);
|
||||||
|
|
||||||
|
adventureInt->updateNextHero(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
const CGHeroInstance * CPlayerInterface::getWHero( int pos )
|
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 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::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::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
|
struct SpellbookLastSetting
|
||||||
{
|
{
|
||||||
|
@ -1355,6 +1355,8 @@ void CHeroList::updateHList(const CGHeroInstance *toRemove)
|
|||||||
else
|
else
|
||||||
select(selected);
|
select(selected);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
adventureInt->updateNextHero(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHeroList::updateMove(const CGHeroInstance* which) //draws move points bar
|
void CHeroList::updateMove(const CGHeroInstance* which) //draws move points bar
|
||||||
|
Loading…
Reference in New Issue
Block a user