Merge branch 'askloadnotreallyrecent' into 'master'

Replicate recent save loading prompt behavior (bug #7617)

Closes #7617

See merge request OpenMW/openmw!3710
pull/3233/head
psi29a 12 months ago
commit 60d1262d61

@ -100,6 +100,7 @@
Bug #7604: Goblins Grunt becomes idle once injured Bug #7604: Goblins Grunt becomes idle once injured
Bug #7609: ForceGreeting should not open dialogue for werewolves Bug #7609: ForceGreeting should not open dialogue for werewolves
Bug #7611: Beast races' idle animations slide after turning or jumping in place Bug #7611: Beast races' idle animations slide after turning or jumping in place
Bug #7617: The death prompt asks the player if they wanted to load the character's last created save
Bug #7619: Long map notes may get cut off Bug #7619: Long map notes may get cut off
Bug #7630: Charm can be cast on creatures Bug #7630: Charm can be cast on creatures
Bug #7631: Cannot trade with/talk to Creeper or Mudcrab Merchant when they're fleeing Bug #7631: Cannot trade with/talk to Creeper or Mudcrab Merchant when they're fleeing

@ -64,6 +64,7 @@ void MWState::StateManager::cleanup(bool force)
mState = State_NoGame; mState = State_NoGame;
mCharacterManager.setCurrentCharacter(nullptr); mCharacterManager.setCurrentCharacter(nullptr);
mTimePlayed = 0; mTimePlayed = 0;
mLastSavegame.clear();
MWMechanics::CreatureStats::cleanup(); MWMechanics::CreatureStats::cleanup();
} }
@ -119,14 +120,27 @@ void MWState::StateManager::askLoadRecent()
if (!mAskLoadRecent) if (!mAskLoadRecent)
{ {
const MWState::Character* character = getCurrentCharacter(); if (mLastSavegame.empty()) // no saves
if (!character || character->begin() == character->end()) // no saves
{ {
MWBase::Environment::get().getWindowManager()->pushGuiMode(MWGui::GM_MainMenu); MWBase::Environment::get().getWindowManager()->pushGuiMode(MWGui::GM_MainMenu);
} }
else else
{ {
MWState::Slot lastSave = *character->begin(); std::string saveName = Files::pathToUnicodeString(mLastSavegame.filename());
// Assume the last saved game belongs to the current character's slot list.
const Character* character = getCurrentCharacter();
if (character)
{
for (const auto& slot : *character)
{
if (slot.mPath == mLastSavegame)
{
saveName = slot.mProfile.mDescription;
break;
}
}
}
std::vector<std::string> buttons; std::vector<std::string> buttons;
buttons.emplace_back("#{Interface:Yes}"); buttons.emplace_back("#{Interface:Yes}");
buttons.emplace_back("#{Interface:No}"); buttons.emplace_back("#{Interface:No}");
@ -134,7 +148,7 @@ void MWState::StateManager::askLoadRecent()
= MWBase::Environment::get().getL10nManager()->getMessage("OMWEngine", "AskLoadLastSave"); = MWBase::Environment::get().getL10nManager()->getMessage("OMWEngine", "AskLoadLastSave");
std::string_view tag = "%s"; std::string_view tag = "%s";
size_t pos = message.find(tag); size_t pos = message.find(tag);
message.replace(pos, tag.length(), lastSave.mProfile.mDescription); message.replace(pos, tag.length(), saveName);
MWBase::Environment::get().getWindowManager()->interactiveMessageBox(message, buttons); MWBase::Environment::get().getWindowManager()->interactiveMessageBox(message, buttons);
mAskLoadRecent = true; mAskLoadRecent = true;
} }
@ -322,6 +336,7 @@ void MWState::StateManager::saveGame(std::string_view description, const Slot* s
throw std::runtime_error("Write operation failed (file stream)"); throw std::runtime_error("Write operation failed (file stream)");
Settings::saves().mCharacter.set(Files::pathToUnicodeString(slot->mPath.parent_path().filename())); Settings::saves().mCharacter.set(Files::pathToUnicodeString(slot->mPath.parent_path().filename()));
mLastSavegame = slot->mPath;
const auto finish = std::chrono::steady_clock::now(); const auto finish = std::chrono::steady_clock::now();
@ -561,6 +576,7 @@ void MWState::StateManager::loadGame(const Character* character, const std::file
if (character) if (character)
Settings::saves().mCharacter.set(Files::pathToUnicodeString(character->getPath().filename())); Settings::saves().mCharacter.set(Files::pathToUnicodeString(character->getPath().filename()));
mLastSavegame = filepath;
MWBase::Environment::get().getWindowManager()->setNewGame(false); MWBase::Environment::get().getWindowManager()->setNewGame(false);
MWBase::Environment::get().getWorld()->saveLoaded(); MWBase::Environment::get().getWorld()->saveLoaded();
@ -639,7 +655,15 @@ void MWState::StateManager::quickLoad()
void MWState::StateManager::deleteGame(const MWState::Character* character, const MWState::Slot* slot) void MWState::StateManager::deleteGame(const MWState::Character* character, const MWState::Slot* slot)
{ {
const std::filesystem::path savePath = slot->mPath;
mCharacterManager.deleteSlot(character, slot); mCharacterManager.deleteSlot(character, slot);
if (mLastSavegame == savePath)
{
if (character->begin() != character->end())
mLastSavegame = character->begin()->mPath;
else
mLastSavegame.clear();
}
} }
MWState::Character* MWState::StateManager::getCurrentCharacter() MWState::Character* MWState::StateManager::getCurrentCharacter()
@ -670,9 +694,9 @@ void MWState::StateManager::update(float duration)
{ {
mAskLoadRecent = false; mAskLoadRecent = false;
// Load last saved game for current character // Load last saved game for current character
// loadGame resets the game state along with mLastSavegame so we want to preserve it
MWState::Slot lastSave = *curCharacter->begin(); const std::filesystem::path filePath = std::move(mLastSavegame);
loadGame(curCharacter, lastSave.mPath); loadGame(curCharacter, filePath);
} }
else if (iButton == 1) else if (iButton == 1)
{ {

@ -17,6 +17,7 @@ namespace MWState
State mState; State mState;
CharacterManager mCharacterManager; CharacterManager mCharacterManager;
double mTimePlayed; double mTimePlayed;
std::filesystem::path mLastSavegame;
private: private:
void cleanup(bool force = false); void cleanup(bool force = false);

Loading…
Cancel
Save