diff --git a/apps/openmw/mwgui/savegamedialog.cpp b/apps/openmw/mwgui/savegamedialog.cpp index 967bb23919..4957789ffd 100644 --- a/apps/openmw/mwgui/savegamedialog.cpp +++ b/apps/openmw/mwgui/savegamedialog.cpp @@ -198,12 +198,11 @@ namespace MWGui << MyGUI::TextIterator::toTagsString(MyGUI::UString(className)) << ")"; const MyGUI::UString playerDesc = MyGUI::LanguageManager::getInstance().replaceTags(title.str()); - mCharacterSelection->addItem(playerDesc, signature.mPlayerName); + mCharacterSelection->addItem(playerDesc, &*it); if (mCurrentCharacter == &*it || (!mCurrentCharacter && !mSaving - && Misc::StringUtils::ciEqual( - directory, Files::pathToUnicodeString(it->begin()->mPath.parent_path().filename())))) + && Misc::StringUtils::ciEqual(directory, Files::pathToUnicodeString(it->getPath().filename())))) { mCurrentCharacter = &*it; selectedIndex = mCharacterSelection->getItemCount() - 1; @@ -211,6 +210,11 @@ namespace MWGui } } + if (selectedIndex == MyGUI::ITEM_NONE && !mSaving && mCharacterSelection->getItemCount() != 0) + { + selectedIndex = 0; + mCurrentCharacter = *mCharacterSelection->getItemDataAt(0); + } mCharacterSelection->setIndexSelected(selectedIndex); if (selectedIndex == MyGUI::ITEM_NONE) mCharacterSelection->setCaptionWithReplacing("#{OMWEngine:SelectCharacter}"); @@ -322,16 +326,7 @@ namespace MWGui void SaveGameDialog::onCharacterSelected(MyGUI::ComboBox* sender, size_t pos) { - MWBase::StateManager* mgr = MWBase::Environment::get().getStateManager(); - - unsigned int i = 0; - const MWState::Character* character = nullptr; - for (MWBase::StateManager::CharacterIterator it = mgr->characterBegin(); it != mgr->characterEnd(); ++it, ++i) - { - if (i == pos) - character = &*it; - } - assert(character && "Can't find selected character"); + const MWState::Character* character = *mCharacterSelection->getItemDataAt(pos); mCurrentCharacter = character; mCurrentSlot = nullptr; @@ -402,7 +397,7 @@ namespace MWGui mSaveNameEdit->setCaption(sender->getItemNameAt(pos)); mCurrentSlot = nullptr; - unsigned int i = 0; + size_t i = 0; for (MWState::Character::SlotIterator it = mCurrentCharacter->begin(); it != mCurrentCharacter->end(); ++it, ++i) { @@ -416,8 +411,9 @@ namespace MWGui const size_t profileIndex = mCharacterSelection->getIndexSelected(); const std::string& slotPlayerName = mCurrentSlot->mProfile.mPlayerName; - const std::string& profilePlayerName = *mCharacterSelection->getItemDataAt(profileIndex); - if (slotPlayerName != profilePlayerName) + const ESM::SavedGame& profileSavedGame + = (*mCharacterSelection->getItemDataAt(profileIndex))->getSignature(); + if (slotPlayerName != profileSavedGame.mPlayerName) text << slotPlayerName << "\n"; text << "#{OMWEngine:Level} " << mCurrentSlot->mProfile.mPlayerLevel << "\n"; diff --git a/apps/openmw/mwstate/character.cpp b/apps/openmw/mwstate/character.cpp index 3c02311458..22d7e7ba1e 100644 --- a/apps/openmw/mwstate/character.cpp +++ b/apps/openmw/mwstate/character.cpp @@ -18,14 +18,25 @@ bool MWState::operator<(const Slot& left, const Slot& right) return left.mTimeStamp < right.mTimeStamp; } -std::string MWState::getFirstGameFile(const std::vector& contentFiles) +bool MWState::operator<(const Character& left, const Character& right) +{ + if (left.mSlots.empty() && right.mSlots.empty()) + return left.mPath < right.mPath; + else if (left.mSlots.empty()) + return false; + else if (right.mSlots.empty()) + return true; + return right.mSlots.back() < left.mSlots.back(); +} + +std::string_view MWState::getFirstGameFile(const std::vector& contentFiles) { for (const std::string& c : contentFiles) { if (Misc::StringUtils::ciEndsWith(c, ".esm") || Misc::StringUtils::ciEndsWith(c, ".omwgame")) return c; } - return ""; + return {}; } void MWState::Character::addSlot(const std::filesystem::path& path, const std::string& game) diff --git a/apps/openmw/mwstate/character.hpp b/apps/openmw/mwstate/character.hpp index 3c68d9f490..4e51301bba 100644 --- a/apps/openmw/mwstate/character.hpp +++ b/apps/openmw/mwstate/character.hpp @@ -2,6 +2,7 @@ #define GAME_STATE_CHARACTER_H #include +#include #include @@ -14,9 +15,7 @@ namespace MWState std::filesystem::file_time_type mTimeStamp; }; - bool operator<(const Slot& left, const Slot& right); - - std::string getFirstGameFile(const std::vector& contentFiles); + std::string_view getFirstGameFile(const std::vector& contentFiles); class Character { @@ -63,7 +62,12 @@ namespace MWState ///< Return signature information for this character. /// /// \attention This function must not be called if there are no slots. + + friend bool operator<(const Character& left, const Character& right); }; + + bool operator<(const Slot& left, const Slot& right); + bool operator<(const Character& left, const Character& right); } #endif diff --git a/apps/openmw/mwstate/charactermanager.cpp b/apps/openmw/mwstate/charactermanager.cpp index 32f0fe0aef..6d2583776b 100644 --- a/apps/openmw/mwstate/charactermanager.cpp +++ b/apps/openmw/mwstate/charactermanager.cpp @@ -18,10 +18,8 @@ MWState::CharacterManager::CharacterManager(std::filesystem::path saves, const s } else { - for (std::filesystem::directory_iterator iter(mPath); iter != std::filesystem::directory_iterator(); ++iter) + for (const std::filesystem::path& characterDir : std::filesystem::directory_iterator(mPath)) { - std::filesystem::path characterDir = *iter; - if (std::filesystem::is_directory(characterDir)) { Character character(characterDir, mGame); @@ -30,6 +28,7 @@ MWState::CharacterManager::CharacterManager(std::filesystem::path saves, const s mCharacters.push_back(character); } } + mCharacters.sort(); } }