mirror of
https://github.com/vcmi/vcmi.git
synced 2025-02-15 13:33:36 +02:00
Moved selection logic to player state
This commit is contained in:
parent
e8718a46cc
commit
bb08a0afc8
@ -405,6 +405,7 @@ void CPlayerInterface::heroKilled(const CGHeroInstance* hero)
|
||||
{
|
||||
EVENT_HANDLER_CALLED_BY_CLIENT;
|
||||
LOG_TRACE_PARAMS(logGlobal, "Hero %s killed handler for player %s", hero->getNameTranslated() % playerID);
|
||||
|
||||
localState->removeWanderingHero(hero);
|
||||
adventureInt->onHeroChanged(hero);
|
||||
localState->erasePath(hero);
|
||||
@ -2084,12 +2085,3 @@ void CPlayerInterface::showWorldViewEx(const std::vector<ObjectPosInfo>& objectP
|
||||
EVENT_HANDLER_CALLED_BY_CLIENT;
|
||||
adventureInt->openWorldView(objectPositions, showTerrain );
|
||||
}
|
||||
|
||||
void CPlayerInterface::setSelection(const CArmedInstance *sel, bool centerView)
|
||||
{
|
||||
if (sel == localState->getCurrentArmy())
|
||||
return;
|
||||
|
||||
localState->setSelection(sel);
|
||||
adventureInt->onSelectionChanged(sel, centerView);
|
||||
}
|
||||
|
@ -207,9 +207,6 @@ public: // public interface for use by client via LOCPLINT access
|
||||
void showShipyardDialogOrProblemPopup(const IShipyard *obj); //obj may be town or shipyard;
|
||||
void proposeLoadingGame();
|
||||
|
||||
/// Changes currently selected object
|
||||
void setSelection(const CArmedInstance *sel, bool centerView = true);
|
||||
|
||||
///returns true if all events are processed internally
|
||||
bool capturedAllEvents();
|
||||
|
||||
|
@ -107,6 +107,41 @@ const CGHeroInstance * PlayerLocalState::getCurrentHero() const
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const CGHeroInstance * PlayerLocalState::getNextWanderingHero(const CGHeroInstance * currentHero)
|
||||
{
|
||||
bool currentHeroFound = false;
|
||||
const CGHeroInstance * firstSuitable = nullptr;
|
||||
const CGHeroInstance * nextSuitable = nullptr;
|
||||
|
||||
for(const auto * hero : getWanderingHeroes())
|
||||
{
|
||||
if (hero == currentHero)
|
||||
{
|
||||
currentHeroFound = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isHeroSleeping(hero))
|
||||
continue;
|
||||
|
||||
if (hero->movement == 0)
|
||||
continue;
|
||||
|
||||
if (!firstSuitable)
|
||||
firstSuitable = hero;
|
||||
|
||||
if (!nextSuitable && currentHeroFound)
|
||||
nextSuitable = hero;
|
||||
}
|
||||
|
||||
// if we found suitable hero after currently selected hero -> return this hero
|
||||
if (nextSuitable)
|
||||
return nextSuitable;
|
||||
|
||||
// othervice -> loop over and return first suitable hero in the list (or null if none)
|
||||
return firstSuitable;
|
||||
}
|
||||
|
||||
const CGTownInstance * PlayerLocalState::getCurrentTown() const
|
||||
{
|
||||
if(currentSelection && currentSelection->ID == Obj::TOWN)
|
||||
@ -125,7 +160,13 @@ const CArmedInstance * PlayerLocalState::getCurrentArmy() const
|
||||
|
||||
void PlayerLocalState::setSelection(const CArmedInstance * selection)
|
||||
{
|
||||
if (currentSelection == selection)
|
||||
return;
|
||||
|
||||
currentSelection = selection;
|
||||
|
||||
if (selection)
|
||||
adventureInt->onSelectionChanged(selection);
|
||||
}
|
||||
|
||||
bool PlayerLocalState::isHeroSleeping(const CGHeroInstance * hero) const
|
||||
@ -174,8 +215,21 @@ void PlayerLocalState::removeWanderingHero(const CGHeroInstance * hero)
|
||||
{
|
||||
assert(hero);
|
||||
assert(vstd::contains(wanderingHeroes, hero));
|
||||
|
||||
if (hero == currentSelection)
|
||||
{
|
||||
auto const * nextHero = getNextWanderingHero(hero);
|
||||
setSelection(nextHero);
|
||||
}
|
||||
|
||||
vstd::erase(wanderingHeroes, hero);
|
||||
vstd::erase(sleepingHeroes, hero);
|
||||
|
||||
if (currentSelection == nullptr && !wanderingHeroes.empty())
|
||||
setSelection(wanderingHeroes.front());
|
||||
|
||||
if (currentSelection == nullptr && !ownedTowns.empty())
|
||||
setSelection(ownedTowns.front());
|
||||
}
|
||||
|
||||
const std::vector<const CGTownInstance *> & PlayerLocalState::getOwnedTowns()
|
||||
@ -202,4 +256,13 @@ void PlayerLocalState::removeOwnedTown(const CGTownInstance * town)
|
||||
assert(town);
|
||||
assert(vstd::contains(ownedTowns, town));
|
||||
vstd::erase(ownedTowns, town);
|
||||
|
||||
if (town == currentSelection)
|
||||
setSelection(nullptr);
|
||||
|
||||
if (currentSelection == nullptr && !wanderingHeroes.empty())
|
||||
setSelection(wanderingHeroes.front());
|
||||
|
||||
if (currentSelection == nullptr && !ownedTowns.empty())
|
||||
setSelection(ownedTowns.front());
|
||||
}
|
||||
|
@ -69,6 +69,7 @@ public:
|
||||
|
||||
const std::vector<const CGHeroInstance *> & getWanderingHeroes();
|
||||
const CGHeroInstance * getWanderingHero(size_t index);
|
||||
const CGHeroInstance * getNextWanderingHero(const CGHeroInstance * hero);
|
||||
void addWanderingHero(const CGHeroInstance * hero);
|
||||
void removeWanderingHero(const CGHeroInstance * hero);
|
||||
|
||||
@ -88,7 +89,7 @@ public:
|
||||
const CArmedInstance * getCurrentArmy() const;
|
||||
|
||||
/// Changes currently selected object
|
||||
void setSelection(const CArmedInstance * selection);
|
||||
void setSelection(const CArmedInstance *sel);
|
||||
|
||||
template<typename Handler>
|
||||
void serialize(Handler & h, int version)
|
||||
|
@ -287,9 +287,14 @@ void CAdventureMapInterface::fsleepWake()
|
||||
if (!h)
|
||||
return;
|
||||
bool newSleep = !LOCPLINT->localState->isHeroSleeping(h);
|
||||
setHeroSleeping(h, newSleep);
|
||||
|
||||
updateButtons();
|
||||
if (newSleep)
|
||||
LOCPLINT->localState->setHeroAsleep(h);
|
||||
else
|
||||
LOCPLINT->localState->setHeroAwaken(h);
|
||||
|
||||
onHeroChanged(h);
|
||||
|
||||
if (newSleep)
|
||||
fnextHero();
|
||||
|
||||
@ -328,10 +333,14 @@ void CAdventureMapInterface::fsystemOptions()
|
||||
|
||||
void CAdventureMapInterface::fnextHero()
|
||||
{
|
||||
const auto * nextHero = getNextHero(LOCPLINT->localState->getCurrentHero());
|
||||
const auto * currHero = LOCPLINT->localState->getCurrentHero();
|
||||
const auto * nextHero = LOCPLINT->localState->getNextWanderingHero(currHero);
|
||||
|
||||
if (nextHero)
|
||||
LOCPLINT->setSelection(nextHero, true);
|
||||
{
|
||||
LOCPLINT->localState->setSelection(nextHero);
|
||||
centerOnObject(nextHero);
|
||||
}
|
||||
}
|
||||
|
||||
void CAdventureMapInterface::fendTurn()
|
||||
@ -376,7 +385,7 @@ void CAdventureMapInterface::updateButtons()
|
||||
spellbook->block(!hero);
|
||||
moveHero->block(!hero || !LOCPLINT->localState->hasPath(hero) || hero->movement == 0);
|
||||
|
||||
const auto * nextSuitableHero = getNextHero(hero);
|
||||
const auto * nextSuitableHero = LOCPLINT->localState->getNextWanderingHero(hero);
|
||||
nextHero->block(nextSuitableHero == nullptr);
|
||||
|
||||
if(hero)
|
||||
@ -388,41 +397,6 @@ void CAdventureMapInterface::updateButtons()
|
||||
}
|
||||
}
|
||||
|
||||
const CGHeroInstance * CAdventureMapInterface::getNextHero(const CGHeroInstance * currentHero)
|
||||
{
|
||||
bool currentHeroFound = false;
|
||||
const CGHeroInstance * firstSuitable = nullptr;
|
||||
const CGHeroInstance * nextSuitable = nullptr;
|
||||
|
||||
for(const auto * hero : LOCPLINT->localState->getWanderingHeroes())
|
||||
{
|
||||
if (hero == currentHero)
|
||||
{
|
||||
currentHeroFound = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (LOCPLINT->localState->isHeroSleeping(hero))
|
||||
continue;
|
||||
|
||||
if (hero->movement == 0)
|
||||
continue;
|
||||
|
||||
if (!firstSuitable)
|
||||
firstSuitable = hero;
|
||||
|
||||
if (!nextSuitable && currentHeroFound)
|
||||
nextSuitable = hero;
|
||||
}
|
||||
|
||||
// if we found suitable hero after currently selected hero -> return this hero
|
||||
if (nextSuitable)
|
||||
return nextSuitable;
|
||||
|
||||
// othervice -> loop over and return first suitable hero in the list (or null if none)
|
||||
return firstSuitable;
|
||||
}
|
||||
|
||||
void CAdventureMapInterface::onHeroChanged(const CGHeroInstance *h)
|
||||
{
|
||||
heroList->update(h);
|
||||
@ -522,16 +496,6 @@ void CAdventureMapInterface::showAll(SDL_Surface * to)
|
||||
LOCPLINT->cingconsole->show(to);
|
||||
}
|
||||
|
||||
void CAdventureMapInterface::setHeroSleeping(const CGHeroInstance *hero, bool sleep)
|
||||
{
|
||||
if (sleep)
|
||||
LOCPLINT->localState->setHeroAsleep(hero);
|
||||
else
|
||||
LOCPLINT->localState->setHeroAwaken(hero);
|
||||
|
||||
onHeroChanged(hero);
|
||||
}
|
||||
|
||||
void CAdventureMapInterface::show(SDL_Surface * to)
|
||||
{
|
||||
// if(state != EGameState::MAKING_TURN)
|
||||
@ -818,13 +782,15 @@ std::optional<Point> CAdventureMapInterface::keyToMoveDirection(const SDL_Keycod
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
void CAdventureMapInterface::onSelectionChanged(const CArmedInstance *sel, bool centerView)
|
||||
void CAdventureMapInterface::onSelectionChanged(const CArmedInstance *sel)
|
||||
{
|
||||
assert(sel);
|
||||
|
||||
infoBar->popAll();
|
||||
mapAudio->onSelectionChanged(sel);
|
||||
if(centerView)
|
||||
bool centerView = !settings["session"]["autoSkip"].Bool();
|
||||
|
||||
if (centerView)
|
||||
centerOnObject(sel);
|
||||
|
||||
if(sel->ID==Obj::TOWN)
|
||||
@ -944,20 +910,18 @@ void CAdventureMapInterface::onPlayerTurnStarted(PlayerColor playerID)
|
||||
}
|
||||
}
|
||||
|
||||
bool centerView = !settings["session"]["autoSkip"].Bool();
|
||||
|
||||
//select first hero if available.
|
||||
if (heroToSelect != nullptr)
|
||||
{
|
||||
LOCPLINT->setSelection(heroToSelect, centerView);
|
||||
LOCPLINT->localState->setSelection(heroToSelect);
|
||||
}
|
||||
else if (LOCPLINT->localState->getOwnedTowns().size())
|
||||
{
|
||||
LOCPLINT->setSelection(LOCPLINT->localState->getOwnedTown(0), centerView);
|
||||
LOCPLINT->localState->setSelection(LOCPLINT->localState->getOwnedTown(0));
|
||||
}
|
||||
else
|
||||
{
|
||||
LOCPLINT->setSelection(LOCPLINT->localState->getWanderingHero(0), centerView);
|
||||
LOCPLINT->localState->setSelection(LOCPLINT->localState->getWanderingHero(0));
|
||||
}
|
||||
|
||||
//show new day animation and sound on infobar
|
||||
@ -1044,7 +1008,7 @@ void CAdventureMapInterface::onTileLeftClicked(const int3 &mapPos)
|
||||
if(LOCPLINT->localState->getCurrentArmy() == topBlocking) //selected town clicked
|
||||
LOCPLINT->openTownWindow(static_cast<const CGTownInstance*>(topBlocking));
|
||||
else if(canSelect)
|
||||
LOCPLINT->setSelection(static_cast<const CArmedInstance*>(topBlocking), false);
|
||||
LOCPLINT->localState->setSelection(static_cast<const CArmedInstance*>(topBlocking));
|
||||
}
|
||||
else if(const CGHeroInstance * currentHero = LOCPLINT->localState->getCurrentHero()) //hero is selected
|
||||
{
|
||||
@ -1058,7 +1022,7 @@ void CAdventureMapInterface::onTileLeftClicked(const int3 &mapPos)
|
||||
}
|
||||
else if(canSelect && pn->turns == 255 ) //selectable object at inaccessible tile
|
||||
{
|
||||
LOCPLINT->setSelection(static_cast<const CArmedInstance*>(topBlocking), false);
|
||||
LOCPLINT->localState->setSelection(static_cast<const CArmedInstance*>(topBlocking));
|
||||
return;
|
||||
}
|
||||
else //still here? we need to move hero if we clicked end of already selected path or calculate a new path otherwise
|
||||
|
@ -132,8 +132,6 @@ private:
|
||||
|
||||
std::optional<Point> keyToMoveDirection(const SDL_Keycode & key);
|
||||
|
||||
void setHeroSleeping(const CGHeroInstance *hero, bool sleep);
|
||||
const CGHeroInstance * getNextHero(const CGHeroInstance * currentHero); //for Next Hero button - cycles awake heroes with movement only
|
||||
void endingTurn();
|
||||
|
||||
/// exits currently opened world view mode and returns to normal map
|
||||
@ -176,8 +174,8 @@ public:
|
||||
/// Called by PlayerInterface when town state changed and town list must be updated
|
||||
void onTownChanged(const CGTownInstance * town);
|
||||
|
||||
/// Changes currently selected object
|
||||
void onSelectionChanged(const CArmedInstance *sel, bool centerView = true);
|
||||
/// Called when currently selected object changes
|
||||
void onSelectionChanged(const CArmedInstance *sel);
|
||||
|
||||
/// Called when map audio should be paused, e.g. on combat or town screen access
|
||||
void onAudioPaused();
|
||||
|
@ -204,8 +204,8 @@ std::shared_ptr<CIntObject> CHeroList::CHeroItem::genSelection()
|
||||
|
||||
void CHeroList::CHeroItem::select(bool on)
|
||||
{
|
||||
if(on && LOCPLINT->localState->getCurrentHero() != hero)
|
||||
LOCPLINT->setSelection(hero);
|
||||
if(on)
|
||||
LOCPLINT->localState->setSelection(hero);
|
||||
}
|
||||
|
||||
void CHeroList::CHeroItem::open()
|
||||
@ -293,8 +293,8 @@ void CTownList::CTownItem::update()
|
||||
|
||||
void CTownList::CTownItem::select(bool on)
|
||||
{
|
||||
if (on && LOCPLINT->localState->getCurrentTown() != town)
|
||||
LOCPLINT->setSelection(town, true);
|
||||
if(on)
|
||||
LOCPLINT->localState->setSelection(town);
|
||||
}
|
||||
|
||||
void CTownList::CTownItem::open()
|
||||
|
@ -1230,9 +1230,9 @@ void CCastleInterface::close()
|
||||
if(town->tempOwner == LOCPLINT->playerID) //we may have opened window for an allied town
|
||||
{
|
||||
if(town->visitingHero && town->visitingHero->tempOwner == LOCPLINT->playerID)
|
||||
LOCPLINT->setSelection(town->visitingHero);
|
||||
LOCPLINT->localState->setSelection(town->visitingHero);
|
||||
else
|
||||
LOCPLINT->setSelection(town);
|
||||
LOCPLINT->localState->setSelection(town);
|
||||
}
|
||||
CWindowObject::close();
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user