diff --git a/client/CPlayerInterface.cpp b/client/CPlayerInterface.cpp index 487e5eb11..02317294a 100644 --- a/client/CPlayerInterface.cpp +++ b/client/CPlayerInterface.cpp @@ -515,7 +515,8 @@ void CPlayerInterface::heroInGarrisonChange(const CGTownInstance *town) if(town->visitingHero) //hero leaves garrison { - if(town->visitingHero->tempOwner == playerID) + // This method also gets called on hero recruitment -> wandering heroes already contains new hero + if(town->visitingHero->tempOwner == playerID && !vstd::contains(localState->getWanderingHeroes(), town->visitingHero)) localState->addWanderingHero(town->visitingHero); } adventureInt->onHeroChanged(nullptr); @@ -1255,8 +1256,8 @@ void CPlayerInterface::moveHero( const CGHeroInstance *h, const CGPath& path ) setMovementStatus(true); - if (adventureInt) - adventureInt->onHeroWokeUp(h); + if (localState->isHeroSleeping(h)) + localState->setHeroAwaken(h); boost::thread moveHeroTask(std::bind(&CPlayerInterface::doMoveHero,this,h,path)); } diff --git a/client/adventureMap/CAdventureMapInterface.cpp b/client/adventureMap/CAdventureMapInterface.cpp index 2dd82600b..bf0899ad1 100644 --- a/client/adventureMap/CAdventureMapInterface.cpp +++ b/client/adventureMap/CAdventureMapInterface.cpp @@ -70,11 +70,6 @@ CAdventureMapInterface::CAdventureMapInterface(): pos.w = GH.screenDimensions().x; pos.h = GH.screenDimensions().y; strongInterest = true; // handle all mouse move events to prevent dead mouse move space in fullscreen mode - townList->onSelect = [this](){ - const CGTownInstance * selectedTown = LOCPLINT->localState->getOwnedTown(townList->getSelectedIndex()); - assert(selectedTown); - LOCPLINT->setSelection(selectedTown); - }; bg = IImage::createFromFile(ADVOPT.mainGraphic); if(!ADVOPT.worldViewGraphic.empty()) @@ -293,15 +288,10 @@ void CAdventureMapInterface::fsleepWake() return; bool newSleep = !LOCPLINT->localState->isHeroSleeping(h); 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 - } + updateButtons(); + if (newSleep) + fnextHero(); // redraw to update the image of sleep/wake button panelMain->redraw(); @@ -378,20 +368,24 @@ void CAdventureMapInterface::fendTurn() endingTurn(); } -void CAdventureMapInterface::updateSleepWake(const CGHeroInstance *h) +void CAdventureMapInterface::updateButtons() { - sleepWake->block(!h); - if (!h) - return; - bool state = LOCPLINT->localState->isHeroSleeping(h); - sleepWake->setIndex(state ? 1 : 0, true); - sleepWake->assignedKeys.clear(); - sleepWake->assignedKeys.insert(state ? SDLK_w : SDLK_z); -} + const auto * hero = LOCPLINT->localState->getCurrentHero(); -void CAdventureMapInterface::updateSpellbook(const CGHeroInstance *h) -{ - spellbook->block(!h); + sleepWake->block(!hero); + spellbook->block(!hero); + moveHero->block(!hero || !LOCPLINT->localState->hasPath(hero) || hero->movement == 0); + + const auto * nextSuitableHero = getNextHero(hero); + nextHero->block(nextSuitableHero == nullptr); + + if(hero) + { + bool state = LOCPLINT->localState->isHeroSleeping(hero); + sleepWake->setIndex(state ? 1 : 0, true); + sleepWake->assignedKeys = {state ? SDLK_w : SDLK_z}; + sleepWake->redraw(); + } } const CGHeroInstance * CAdventureMapInterface::getNextHero(const CGHeroInstance * currentHero) @@ -400,7 +394,7 @@ const CGHeroInstance * CAdventureMapInterface::getNextHero(const CGHeroInstance const CGHeroInstance * firstSuitable = nullptr; const CGHeroInstance * nextSuitable = nullptr; - for (auto const * hero : LOCPLINT->localState->getWanderingHeroes()) + for(const auto * hero : LOCPLINT->localState->getWanderingHeroes()) { if (hero == currentHero) { @@ -436,23 +430,7 @@ void CAdventureMapInterface::onHeroChanged(const CGHeroInstance *h) if (h == LOCPLINT->localState->getCurrentHero()) infoBar->showSelection(); - const auto * nextSuitableHero = getNextHero(h); - if (nextSuitableHero == nullptr) - { - nextHero->block(true); - return; - } - - nextHero->block(false); - - if(!LOCPLINT->localState->getCurrentHero()) - { - moveHero->block(true); - return; - } - - bool hasPath = LOCPLINT->localState->hasPath(h); - moveHero->block(!hasPath || h->movement == 0); + updateButtons(); } void CAdventureMapInterface::onTownChanged(const CGTownInstance * town) @@ -526,8 +504,8 @@ void CAdventureMapInterface::showAll(SDL_Surface * to) { bg->draw(to, 0, 0); - if(state != EGameState::MAKING_TURN) - return; +// if(state != EGameState::MAKING_TURN) +// return; heroList->showAll(to); townList->showAll(to); @@ -544,18 +522,6 @@ void CAdventureMapInterface::showAll(SDL_Surface * to) LOCPLINT->cingconsole->show(to); } -void CAdventureMapInterface::onHeroWokeUp(const CGHeroInstance * hero) -{ - if (!LOCPLINT->localState->isHeroSleeping(hero)) - return; - - sleepWake->clickLeft(true, false); - sleepWake->clickLeft(false, true); - //could've just called - //fsleepWake(); - //but no authentic button click/sound ;-) -} - void CAdventureMapInterface::setHeroSleeping(const CGHeroInstance *hero, bool sleep) { if (sleep) @@ -568,8 +534,8 @@ void CAdventureMapInterface::setHeroSleeping(const CGHeroInstance *hero, bool sl void CAdventureMapInterface::show(SDL_Surface * to) { - if(state != EGameState::MAKING_TURN) - return; +// if(state != EGameState::MAKING_TURN) +// return; handleMapScrollingUpdate(); @@ -652,6 +618,8 @@ void CAdventureMapInterface::handleMapScrollingUpdate() if(scrollDelta.y == 0) CCS->curh->set(Cursor::Map::POINTER); } + + scrollingCursorSet = scrollDelta != Point(0,0); } void CAdventureMapInterface::centerOnTile(int3 on) @@ -866,10 +834,7 @@ void CAdventureMapInterface::onSelectionChanged(const CArmedInstance *sel, bool infoBar->showTownSelection(town); townList->select(town); heroList->select(nullptr); - - updateSleepWake(nullptr); onHeroChanged(nullptr); - updateSpellbook(nullptr); } else //hero selected { @@ -880,11 +845,9 @@ void CAdventureMapInterface::onSelectionChanged(const CArmedInstance *sel, bool townList->select(nullptr); LOCPLINT->localState->verifyPath(hero); - - updateSleepWake(hero); onHeroChanged(hero); - updateSpellbook(hero); } + updateButtons(); townList->redraw(); heroList->redraw(); } @@ -1128,10 +1091,11 @@ void CAdventureMapInterface::onTileLeftClicked(const int3 &mapPos) void CAdventureMapInterface::onTileHovered(const int3 &mapPos) { - if(state == EGameState::MAKING_TURN) + if(state != EGameState::MAKING_TURN) return; - if(!LOCPLINT->localState->getCurrentArmy()) //may occur just at the start of game (fake move before full intiialization) + //may occur just at the start of game (fake move before full intiialization) + if(!LOCPLINT->localState->getCurrentArmy()) return; if(!LOCPLINT->cb->isVisible(mapPos)) diff --git a/client/adventureMap/CAdventureMapInterface.h b/client/adventureMap/CAdventureMapInterface.h index 21fdb6e32..e93a95e8f 100644 --- a/client/adventureMap/CAdventureMapInterface.h +++ b/client/adventureMap/CAdventureMapInterface.h @@ -120,9 +120,9 @@ private: void adjustActiveness(bool aiTurnStart); //should be called every time at AI/human turn transition; blocks GUI during AI turn const IShipyard * ourInaccessibleShipyard(const CGObjectInstance *obj) const; //checks if obj is our ashipyard and cursor is 0,0 -> returns shipyard or nullptr else - //button updates - void updateSleepWake(const CGHeroInstance *h); - void updateSpellbook(const CGHeroInstance *h); + + // update locked state of buttons + void updateButtons(); void handleMapScrollingUpdate(); @@ -138,6 +138,8 @@ private: /// exits currently opened world view mode and returns to normal map void exitWorldView(); + void leaveCastingMode(const int3 & castTarget); + void abortCastingMode(); protected: // CIntObject interface implementation @@ -165,9 +167,6 @@ public: /// Called by PlayerInterface when interface should be switched to specified player without starting turn void onCurrentPlayerChanged(PlayerColor playerID); - /// Called by PlayerInterface when hero is forced to wake up, e.g. on moving sleeping hero - void onHeroWokeUp(const CGHeroInstance * hero); - /// Called by PlayerInterface when specific map tile changed and must be updated on minimap void onMapTilesChanged( boost::optional > positions); @@ -206,9 +205,8 @@ public: /// called by MapView whenever tile is clicked void onTileRightClicked(const int3 & mapPos); + /// called by spell window when spell to cast has been selected void enterCastingMode(const CSpell * sp); - void leaveCastingMode(const int3 & castTarget); - void abortCastingMode(); /// returns area of screen covered by terrain (main game area) Rect terrainAreaPixels() const; diff --git a/client/adventureMap/CList.cpp b/client/adventureMap/CList.cpp index 27effa6c9..b01f0f646 100644 --- a/client/adventureMap/CList.cpp +++ b/client/adventureMap/CList.cpp @@ -294,7 +294,7 @@ void CTownList::CTownItem::update() void CTownList::CTownItem::select(bool on) { if (on && LOCPLINT->localState->getCurrentTown() != town) - LOCPLINT->localState->setSelection(town); + LOCPLINT->setSelection(town, true); } void CTownList::CTownItem::open()