mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-01-05 15:55:45 +00:00
Use descriptive names for save files and character folders (Fixes #1449)
This commit is contained in:
parent
e796fa2313
commit
7721e54191
@ -54,9 +54,28 @@ void MWState::Character::addSlot (const ESM::SavedGame& profile)
|
||||
Slot slot;
|
||||
|
||||
std::ostringstream stream;
|
||||
stream << mNext++;
|
||||
|
||||
// The profile description is user-supplied, so we need to escape the path
|
||||
for (std::string::const_iterator it = profile.mDescription.begin(); it != profile.mDescription.end(); ++it)
|
||||
{
|
||||
if (std::isalnum(*it)) // Ignores multibyte characters and non alphanumeric characters
|
||||
stream << *it;
|
||||
else
|
||||
stream << "_";
|
||||
}
|
||||
|
||||
slot.mPath = mPath / stream.str();
|
||||
|
||||
// Append an index if necessary to ensure a unique file
|
||||
int i=0;
|
||||
while (boost::filesystem::exists(slot.mPath))
|
||||
{
|
||||
std::ostringstream test;
|
||||
test << stream.str();
|
||||
test << " - " << ++i;
|
||||
slot.mPath = mPath / test.str();
|
||||
}
|
||||
|
||||
slot.mProfile = profile;
|
||||
slot.mTimeStamp = std::time (0);
|
||||
|
||||
@ -64,7 +83,7 @@ void MWState::Character::addSlot (const ESM::SavedGame& profile)
|
||||
}
|
||||
|
||||
MWState::Character::Character (const boost::filesystem::path& saves, const std::string& game)
|
||||
: mPath (saves), mNext (0)
|
||||
: mPath (saves)
|
||||
{
|
||||
if (!boost::filesystem::is_directory (mPath))
|
||||
{
|
||||
@ -82,13 +101,6 @@ MWState::Character::Character (const boost::filesystem::path& saves, const std::
|
||||
addSlot (slotPath, game);
|
||||
}
|
||||
catch (...) {} // ignoring bad saved game files for now
|
||||
|
||||
std::istringstream stream (slotPath.filename().string());
|
||||
|
||||
int index = 0;
|
||||
|
||||
if ((stream >> index) && index>=mNext)
|
||||
mNext = index+1;
|
||||
}
|
||||
|
||||
std::sort (mSlots.begin(), mSlots.end());
|
||||
|
@ -26,7 +26,6 @@ namespace MWState
|
||||
|
||||
boost::filesystem::path mPath;
|
||||
std::vector<Slot> mSlots;
|
||||
int mNext;
|
||||
|
||||
void addSlot (const boost::filesystem::path& path, const std::string& game);
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
MWState::CharacterManager::CharacterManager (const boost::filesystem::path& saves,
|
||||
const std::string& game)
|
||||
: mPath (saves), mNext (0), mCurrent (0), mGame (game)
|
||||
: mPath (saves), mCurrent (0), mGame (game)
|
||||
{
|
||||
if (!boost::filesystem::is_directory (mPath))
|
||||
{
|
||||
@ -28,21 +28,14 @@ MWState::CharacterManager::CharacterManager (const boost::filesystem::path& save
|
||||
if (character.begin()!=character.end())
|
||||
mCharacters.push_back (character);
|
||||
}
|
||||
|
||||
std::istringstream stream (characterDir.filename().string());
|
||||
|
||||
int index = 0;
|
||||
|
||||
if ((stream >> index) && index>=mNext)
|
||||
mNext = index+1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MWState::Character *MWState::CharacterManager::getCurrentCharacter (bool create)
|
||||
MWState::Character *MWState::CharacterManager::getCurrentCharacter (bool create, const std::string& name)
|
||||
{
|
||||
if (!mCurrent && create)
|
||||
createCharacter();
|
||||
createCharacter(name);
|
||||
|
||||
return mCurrent;
|
||||
}
|
||||
@ -63,13 +56,31 @@ void MWState::CharacterManager::deleteSlot(const MWState::Character *character,
|
||||
}
|
||||
}
|
||||
|
||||
void MWState::CharacterManager::createCharacter()
|
||||
void MWState::CharacterManager::createCharacter(const std::string& name)
|
||||
{
|
||||
std::ostringstream stream;
|
||||
stream << mNext++;
|
||||
|
||||
// The character name is user-supplied, so we need to escape the path
|
||||
for (std::string::const_iterator it = name.begin(); it != name.end(); ++it)
|
||||
{
|
||||
if (std::isalnum(*it)) // Ignores multibyte characters and non alphanumeric characters
|
||||
stream << *it;
|
||||
else
|
||||
stream << "_";
|
||||
}
|
||||
|
||||
boost::filesystem::path path = mPath / stream.str();
|
||||
|
||||
// Append an index if necessary to ensure a unique directory
|
||||
int i=0;
|
||||
while (boost::filesystem::exists(path))
|
||||
{
|
||||
std::ostringstream test;
|
||||
test << stream.str();
|
||||
test << " - " << ++i;
|
||||
path = mPath / test.str();
|
||||
}
|
||||
|
||||
mCharacters.push_back (Character (path, mGame));
|
||||
|
||||
mCurrent = &mCharacters.back();
|
||||
|
@ -10,7 +10,6 @@ namespace MWState
|
||||
class CharacterManager
|
||||
{
|
||||
boost::filesystem::path mPath;
|
||||
int mNext;
|
||||
|
||||
// Uses std::list, so that mCurrent stays valid when characters are deleted
|
||||
std::list<Character> mCharacters;
|
||||
@ -32,13 +31,15 @@ namespace MWState
|
||||
|
||||
CharacterManager (const boost::filesystem::path& saves, const std::string& game);
|
||||
|
||||
Character *getCurrentCharacter (bool create = true);
|
||||
Character *getCurrentCharacter (bool create, const std::string& name);
|
||||
///< \param create Create a new character, if there is no current character.
|
||||
/// \param name The character name to use in case a new character is created.
|
||||
|
||||
void deleteSlot(const MWState::Character *character, const MWState::Slot *slot);
|
||||
|
||||
void createCharacter();
|
||||
void createCharacter(const std::string& name);
|
||||
///< Create new character within saved game management
|
||||
/// \param name Name for the character (does not need to be unique)
|
||||
|
||||
void setCurrentCharacter (const Character *character);
|
||||
|
||||
|
@ -184,9 +184,9 @@ void MWState::StateManager::saveGame (const std::string& description, const Slot
|
||||
encoded->read(&profile.mScreenshot[0], encoded->size());
|
||||
|
||||
if (!slot)
|
||||
slot = mCharacterManager.getCurrentCharacter()->createSlot (profile);
|
||||
slot = getCurrentCharacter()->createSlot (profile);
|
||||
else
|
||||
slot = mCharacterManager.getCurrentCharacter()->updateSlot (slot, profile);
|
||||
slot = getCurrentCharacter()->updateSlot (slot, profile);
|
||||
|
||||
boost::filesystem::ofstream stream (slot->mPath, std::ios::binary);
|
||||
|
||||
@ -252,7 +252,7 @@ void MWState::StateManager::saveGame (const std::string& description, const Slot
|
||||
|
||||
// If no file was written, clean up the slot
|
||||
if (slot && !boost::filesystem::exists(slot->mPath))
|
||||
mCharacterManager.getCurrentCharacter()->deleteSlot(slot);
|
||||
getCurrentCharacter()->deleteSlot(slot);
|
||||
}
|
||||
}
|
||||
|
||||
@ -419,7 +419,10 @@ void MWState::StateManager::deleteGame(const MWState::Character *character, cons
|
||||
|
||||
MWState::Character *MWState::StateManager::getCurrentCharacter (bool create)
|
||||
{
|
||||
return mCharacterManager.getCurrentCharacter (create);
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
||||
std::string name = player.getClass().getName(player);
|
||||
|
||||
return mCharacterManager.getCurrentCharacter (create, name);
|
||||
}
|
||||
|
||||
MWState::StateManager::CharacterIterator MWState::StateManager::characterBegin()
|
||||
@ -440,11 +443,12 @@ void MWState::StateManager::update (float duration)
|
||||
if (mAskLoadRecent)
|
||||
{
|
||||
int iButton = MWBase::Environment::get().getWindowManager()->readPressedButton();
|
||||
if(iButton==0)
|
||||
MWState::Character *curCharacter = getCurrentCharacter(false);
|
||||
if(iButton==0 && curCharacter)
|
||||
{
|
||||
mAskLoadRecent = false;
|
||||
//Load last saved game for current character
|
||||
MWState::Character *curCharacter = getCurrentCharacter();
|
||||
|
||||
MWState::Slot lastSave = *curCharacter->begin();
|
||||
loadGame(curCharacter, &lastSave);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user