1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-11-25 22:42:04 +02:00

fix segmentation fault; update townlist on adventuremap

This commit is contained in:
Laserlicht
2023-10-15 15:53:19 +02:00
committed by GitHub
parent 3b853bff08
commit 4528f42cdf
5 changed files with 27 additions and 23 deletions

View File

@@ -274,4 +274,6 @@ void PlayerLocalState::swapOwnedTowns(int pos1, int pos2)
{ {
assert(ownedTowns[pos1] && ownedTowns[pos2]); assert(ownedTowns[pos1] && ownedTowns[pos2]);
std::swap(ownedTowns[pos1], ownedTowns[pos2]); std::swap(ownedTowns[pos1], ownedTowns[pos2]);
adventureInt->onTownOrderChanged();
} }

View File

@@ -325,6 +325,11 @@ void AdventureMapInterface::onSelectionChanged(const CArmedInstance *sel)
widget->getTownList()->redraw(); widget->getTownList()->redraw();
} }
void AdventureMapInterface::onTownOrderChanged()
{
widget->getTownList()->updateWidget();
}
void AdventureMapInterface::onMapTilesChanged(boost::optional<std::unordered_set<int3>> positions) void AdventureMapInterface::onMapTilesChanged(boost::optional<std::unordered_set<int3>> positions)
{ {
if (positions) if (positions)

View File

@@ -146,6 +146,9 @@ public:
/// Called when currently selected object changes /// Called when currently selected object changes
void onSelectionChanged(const CArmedInstance *sel); 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 /// Called when map audio should be paused, e.g. on combat or town screen access
void onAudioPaused(); void onAudioPaused();

View File

@@ -326,9 +326,11 @@ std::shared_ptr<CIntObject> CTownList::createItem(size_t index)
CTownList::CTownItem::CTownItem(CTownList *parent, const CGTownInstance *Town): CTownList::CTownItem::CTownItem(CTownList *parent, const CGTownInstance *Town):
CListItem(parent), CListItem(parent),
parentList(parent), parentList(parent)
town(Town)
{ {
const std::vector<const CGTownInstance *> towns = LOCPLINT->localState->getOwnedTowns();
townPos = std::distance(towns.begin(), std::find(towns.begin(), towns.end(), Town));
OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE); OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
picture = std::make_shared<CAnimImage>(AnimationPath::builtin("ITPA"), 0); picture = std::make_shared<CAnimImage>(AnimationPath::builtin("ITPA"), 0);
pos = picture->pos; pos = picture->pos;
@@ -344,6 +346,7 @@ std::shared_ptr<CIntObject> CTownList::CTownItem::genSelection()
void CTownList::CTownItem::update() 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)]; size_t iconIndex = town->town->clientInfo.icons[town->hasFort()][town->builded >= CGI->settings()->getInteger(EGameSettings::TOWNS_BUILDINGS_PER_TURN_CAP)];
picture->setFrame(iconIndex + 2); picture->setFrame(iconIndex + 2);
@@ -353,17 +356,17 @@ void CTownList::CTownItem::update()
void CTownList::CTownItem::select(bool on) void CTownList::CTownItem::select(bool on)
{ {
if(on) if(on)
LOCPLINT->localState->setSelection(town); LOCPLINT->localState->setSelection(LOCPLINT->localState->getOwnedTowns()[townPos]);
} }
void CTownList::CTownItem::open() void CTownList::CTownItem::open()
{ {
LOCPLINT->openTownWindow(town); LOCPLINT->openTownWindow(LOCPLINT->localState->getOwnedTowns()[townPos]);
} }
void CTownList::CTownItem::showTooltip() 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) 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) if(!on)
return; return;
if(!town) if(!LOCPLINT->localState->getOwnedTowns()[townPos])
return; return;
const std::vector<const CGTownInstance *> towns = LOCPLINT->localState->getOwnedTowns(); const std::vector<const CGTownInstance *> towns = LOCPLINT->localState->getOwnedTowns();
@@ -379,13 +382,12 @@ void CTownList::CTownItem::gesture(bool on, const Point & initialPosition, const
if(towns.size() < 2) if(towns.size() < 2)
return; return;
int listPos = std::distance(towns.begin(), std::find(towns.begin(), towns.end(), town)); int townUpperPos = (townPos < 1) ? -1 : townPos - 1;
int townUpperPos = (listPos < 1) ? -1 : listPos - 1; int townLowerPos = (townPos > towns.size() - 2) ? -1 : townPos + 1;
int townLowerPos = (listPos > towns.size() - 2) ? -1 : listPos + 1;
std::vector<RadialMenuConfig> menuElements = { std::vector<RadialMenuConfig> menuElements = {
{ RadialMenuConfig::ITEM_ALT_NW, townUpperPos > -1, "altUp", "vcmi.radialWheel.townUp", [this, listPos, townUpperPos](){LOCPLINT->localState->swapOwnedTowns(listPos, townUpperPos); 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, listPos, townLowerPos](){ LOCPLINT->localState->swapOwnedTowns(listPos, townLowerPos); parentList->updateWidget(); } }, { RadialMenuConfig::ITEM_ALT_SW, townLowerPos > -1, "altDown", "vcmi.radialWheel.townDown", [this, townLowerPos](){ LOCPLINT->localState->swapOwnedTowns(townPos, townLowerPos); parentList->updateWidget(); } },
}; };
GH.windows().createAndPushWindow<RadialMenu>(pos.center(), menuElements, true); GH.windows().createAndPushWindow<RadialMenu>(pos.center(), menuElements, true);
@@ -393,7 +395,7 @@ void CTownList::CTownItem::gesture(bool on, const Point & initialPosition, const
std::string CTownList::CTownItem::getHoverText() 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) CTownList::CTownList(int visibleItemsCount, Rect widgetPosition, Point firstItemOffset, Point itemOffsetDelta, size_t initialItemsCount)
@@ -425,15 +427,7 @@ void CTownList::updateWidget()
if (!item) if (!item)
continue; continue;
if (item->town == towns[i])
{
item->update();
}
else
{
listBox->reset(); listBox->reset();
break;
}
} }
if (LOCPLINT->localState->getCurrentTown()) if (LOCPLINT->localState->getCurrentTown())

View File

@@ -152,7 +152,7 @@ class CTownList : public CList
std::shared_ptr<CAnimImage> picture; std::shared_ptr<CAnimImage> picture;
CTownList *parentList; CTownList *parentList;
public: public:
const CGTownInstance * const town; int townPos;
CTownItem(CTownList *parent, const CGTownInstance * town); CTownItem(CTownList *parent, const CGTownInstance * town);