From 4528f42cdfa256d204418b0dc6f3a89916b76f33 Mon Sep 17 00:00:00 2001 From: Laserlicht <13953785+Laserlicht@users.noreply.github.com> Date: Sun, 15 Oct 2023 15:53:19 +0200 Subject: [PATCH] fix segmentation fault; update townlist on adventuremap --- client/PlayerLocalState.cpp | 2 + client/adventureMap/AdventureMapInterface.cpp | 5 +++ client/adventureMap/AdventureMapInterface.h | 3 ++ client/adventureMap/CList.cpp | 38 ++++++++----------- client/adventureMap/CList.h | 2 +- 5 files changed, 27 insertions(+), 23 deletions(-) diff --git a/client/PlayerLocalState.cpp b/client/PlayerLocalState.cpp index 9630231e2..3f9c62643 100644 --- a/client/PlayerLocalState.cpp +++ b/client/PlayerLocalState.cpp @@ -274,4 +274,6 @@ void PlayerLocalState::swapOwnedTowns(int pos1, int pos2) { assert(ownedTowns[pos1] && ownedTowns[pos2]); std::swap(ownedTowns[pos1], ownedTowns[pos2]); + + adventureInt->onTownOrderChanged(); } diff --git a/client/adventureMap/AdventureMapInterface.cpp b/client/adventureMap/AdventureMapInterface.cpp index 376401437..afa9179f8 100644 --- a/client/adventureMap/AdventureMapInterface.cpp +++ b/client/adventureMap/AdventureMapInterface.cpp @@ -325,6 +325,11 @@ void AdventureMapInterface::onSelectionChanged(const CArmedInstance *sel) widget->getTownList()->redraw(); } +void AdventureMapInterface::onTownOrderChanged() +{ + widget->getTownList()->updateWidget(); +} + void AdventureMapInterface::onMapTilesChanged(boost::optional> positions) { if (positions) diff --git a/client/adventureMap/AdventureMapInterface.h b/client/adventureMap/AdventureMapInterface.h index 8140d7c82..bd3ec828f 100644 --- a/client/adventureMap/AdventureMapInterface.h +++ b/client/adventureMap/AdventureMapInterface.h @@ -146,6 +146,9 @@ public: /// Called when currently selected object changes void onSelectionChanged(const CArmedInstance *sel); + /// Called when town order changes + void onTownOrderChanged(); + /// Called when map audio should be paused, e.g. on combat or town screen access void onAudioPaused(); diff --git a/client/adventureMap/CList.cpp b/client/adventureMap/CList.cpp index a78dee13f..3216b6c1b 100644 --- a/client/adventureMap/CList.cpp +++ b/client/adventureMap/CList.cpp @@ -326,9 +326,11 @@ std::shared_ptr CTownList::createItem(size_t index) CTownList::CTownItem::CTownItem(CTownList *parent, const CGTownInstance *Town): CListItem(parent), - parentList(parent), - town(Town) + parentList(parent) { + const std::vector towns = LOCPLINT->localState->getOwnedTowns(); + townPos = std::distance(towns.begin(), std::find(towns.begin(), towns.end(), Town)); + OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE); picture = std::make_shared(AnimationPath::builtin("ITPA"), 0); pos = picture->pos; @@ -344,6 +346,7 @@ std::shared_ptr CTownList::CTownItem::genSelection() void CTownList::CTownItem::update() { + const CGTownInstance * town = LOCPLINT->localState->getOwnedTowns()[townPos]; size_t iconIndex = town->town->clientInfo.icons[town->hasFort()][town->builded >= CGI->settings()->getInteger(EGameSettings::TOWNS_BUILDINGS_PER_TURN_CAP)]; picture->setFrame(iconIndex + 2); @@ -353,17 +356,17 @@ void CTownList::CTownItem::update() void CTownList::CTownItem::select(bool on) { if(on) - LOCPLINT->localState->setSelection(town); + LOCPLINT->localState->setSelection(LOCPLINT->localState->getOwnedTowns()[townPos]); } void CTownList::CTownItem::open() { - LOCPLINT->openTownWindow(town); + LOCPLINT->openTownWindow(LOCPLINT->localState->getOwnedTowns()[townPos]); } void CTownList::CTownItem::showTooltip() { - CRClickPopup::createAndPush(town, GH.getCursorPosition()); + CRClickPopup::createAndPush(LOCPLINT->localState->getOwnedTowns()[townPos], GH.getCursorPosition()); } void CTownList::CTownItem::gesture(bool on, const Point & initialPosition, const Point & finalPosition) @@ -371,7 +374,7 @@ void CTownList::CTownItem::gesture(bool on, const Point & initialPosition, const if(!on) return; - if(!town) + if(!LOCPLINT->localState->getOwnedTowns()[townPos]) return; const std::vector towns = LOCPLINT->localState->getOwnedTowns(); @@ -379,13 +382,12 @@ void CTownList::CTownItem::gesture(bool on, const Point & initialPosition, const if(towns.size() < 2) return; - int listPos = std::distance(towns.begin(), std::find(towns.begin(), towns.end(), town)); - int townUpperPos = (listPos < 1) ? -1 : listPos - 1; - int townLowerPos = (listPos > towns.size() - 2) ? -1 : listPos + 1; + int townUpperPos = (townPos < 1) ? -1 : townPos - 1; + int townLowerPos = (townPos > towns.size() - 2) ? -1 : townPos + 1; std::vector menuElements = { - { RadialMenuConfig::ITEM_ALT_NW, townUpperPos > -1, "altUp", "vcmi.radialWheel.townUp", [this, listPos, townUpperPos](){LOCPLINT->localState->swapOwnedTowns(listPos, townUpperPos); parentList->updateWidget(); } }, - { RadialMenuConfig::ITEM_ALT_SW, townLowerPos > -1, "altDown", "vcmi.radialWheel.townDown", [this, listPos, townLowerPos](){ LOCPLINT->localState->swapOwnedTowns(listPos, townLowerPos); parentList->updateWidget(); } }, + { RadialMenuConfig::ITEM_ALT_NW, townUpperPos > -1, "altUp", "vcmi.radialWheel.townUp", [this, townUpperPos](){LOCPLINT->localState->swapOwnedTowns(townPos, townUpperPos); parentList->updateWidget(); } }, + { RadialMenuConfig::ITEM_ALT_SW, townLowerPos > -1, "altDown", "vcmi.radialWheel.townDown", [this, townLowerPos](){ LOCPLINT->localState->swapOwnedTowns(townPos, townLowerPos); parentList->updateWidget(); } }, }; GH.windows().createAndPushWindow(pos.center(), menuElements, true); @@ -393,7 +395,7 @@ void CTownList::CTownItem::gesture(bool on, const Point & initialPosition, const std::string CTownList::CTownItem::getHoverText() { - return town->getObjectName(); + return LOCPLINT->localState->getOwnedTowns()[townPos]->getObjectName(); } CTownList::CTownList(int visibleItemsCount, Rect widgetPosition, Point firstItemOffset, Point itemOffsetDelta, size_t initialItemsCount) @@ -420,20 +422,12 @@ void CTownList::updateWidget() for (size_t i = 0; i < towns.size(); ++i) { - auto item = std::dynamic_pointer_cast(listBox->getItem(i)); + auto item = std::dynamic_pointer_cast(listBox->getItem(i)); if (!item) continue; - if (item->town == towns[i]) - { - item->update(); - } - else - { - listBox->reset(); - break; - } + listBox->reset(); } if (LOCPLINT->localState->getCurrentTown()) diff --git a/client/adventureMap/CList.h b/client/adventureMap/CList.h index e56736f9f..6433d8c47 100644 --- a/client/adventureMap/CList.h +++ b/client/adventureMap/CList.h @@ -152,7 +152,7 @@ class CTownList : public CList std::shared_ptr picture; CTownList *parentList; public: - const CGTownInstance * const town; + int townPos; CTownItem(CTownList *parent, const CGTownInstance * town);