Merge branch 'characterguide' into 'master'

Compare saves passed on the command line using file equivalence

Closes #8842

See merge request OpenMW/openmw!5034
This commit is contained in:
Alexei Kotov 2025-12-16 12:07:30 +03:00
commit 8b92f68537
4 changed files with 18 additions and 7 deletions

View File

@ -45,7 +45,7 @@ namespace MWBase
virtual void askLoadRecent() = 0; virtual void askLoadRecent() = 0;
virtual void requestNewGame() = 0; virtual void requestNewGame() = 0;
virtual void requestLoad(const std::filesystem::path& filepath) = 0; virtual void requestLoad(const MWState::Character* character, const std::filesystem::path& filepath) = 0;
virtual State getState() const = 0; virtual State getState() const = 0;

View File

@ -53,7 +53,7 @@ namespace MWLua
const MWState::Slot* slot = findSlot(character, slotName); const MWState::Slot* slot = findSlot(character, slotName);
if (!slot) if (!slot)
throw std::runtime_error("Save game slot not found: " + std::string(dir) + "/" + std::string(slotName)); throw std::runtime_error("Save game slot not found: " + std::string(dir) + "/" + std::string(slotName));
MWBase::Environment::get().getStateManager()->requestLoad(slot->mPath); MWBase::Environment::get().getStateManager()->requestLoad(character, slot->mPath);
}; };
api["deleteGame"] = [](std::string_view dir, std::string_view slotName) { api["deleteGame"] = [](std::string_view dir, std::string_view slotName) {

View File

@ -402,7 +402,7 @@ void MWState::StateManager::loadGame(const std::filesystem::path& filepath)
{ {
for (const auto& slot : character) for (const auto& slot : character)
{ {
if (slot.mPath == filepath) if (std::filesystem::equivalent(slot.mPath, filepath))
{ {
loadGame(&character, slot.mPath); loadGame(&character, slot.mPath);
return; return;
@ -697,7 +697,7 @@ void MWState::StateManager::quickLoad()
if (currentCharacter->begin() == currentCharacter->end()) if (currentCharacter->begin() == currentCharacter->end())
return; return;
// use requestLoad, otherwise we can crash by loading during the wrong part of the frame // use requestLoad, otherwise we can crash by loading during the wrong part of the frame
requestLoad(currentCharacter->begin()->mPath); requestLoad(currentCharacter, currentCharacter->begin()->mPath);
} }
} }
@ -763,7 +763,14 @@ void MWState::StateManager::update(float duration)
if (mLoadRequest) if (mLoadRequest)
{ {
MWBase::Environment::get().getWindowManager()->removeGuiMode(MWGui::GM_MainMenu); MWBase::Environment::get().getWindowManager()->removeGuiMode(MWGui::GM_MainMenu);
loadGame(*mLoadRequest); const Character* character = mLoadRequest->first;
// The character may have been deleted after the request was made
const bool validCharacter = std::ranges::find_if(mCharacterManager, [=](const Character& c) {
return &c == character;
}) != mCharacterManager.end();
if (!validCharacter)
character = getCurrentCharacter();
loadGame(character, mLoadRequest->second);
mLoadRequest = std::nullopt; mLoadRequest = std::nullopt;
} }
} }

View File

@ -3,6 +3,7 @@
#include <filesystem> #include <filesystem>
#include <map> #include <map>
#include <utility>
#include "../mwbase/statemanager.hpp" #include "../mwbase/statemanager.hpp"
@ -15,7 +16,7 @@ namespace MWState
bool mQuitRequest; bool mQuitRequest;
bool mAskLoadRecent; bool mAskLoadRecent;
bool mNewGameRequest = false; bool mNewGameRequest = false;
std::optional<std::filesystem::path> mLoadRequest; std::optional<std::pair<const Character*, std::filesystem::path>> mLoadRequest;
State mState; State mState;
CharacterManager mCharacterManager; CharacterManager mCharacterManager;
double mTimePlayed; double mTimePlayed;
@ -42,7 +43,10 @@ namespace MWState
void askLoadRecent() override; void askLoadRecent() override;
void requestNewGame() override { mNewGameRequest = true; } void requestNewGame() override { mNewGameRequest = true; }
void requestLoad(const std::filesystem::path& filepath) override { mLoadRequest = filepath; } void requestLoad(const Character* character, const std::filesystem::path& filepath) override
{
mLoadRequest.emplace(character, filepath);
}
State getState() const override; State getState() const override;