Use descriptive names for save files and character folders (Fixes #1449)

deque
scrawl 11 years ago
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…
Cancel
Save