1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-02-19 17:09:40 +00:00

Preserve record ordering in Store

This fixes the default head/hair used for some races in the chargen UI.
This commit is contained in:
scrawl 2014-12-23 15:28:02 +01:00
parent 9b33eca368
commit b8fa73dfa9
2 changed files with 32 additions and 50 deletions

View file

@ -345,8 +345,7 @@ namespace MWGui
const MWWorld::Store<ESM::Race> &races =
MWBase::Environment::get().getWorld()->getStore().get<ESM::Race>();
int index = 0;
std::map<std::string, std::string> items; // ID, name
MWWorld::Store<ESM::Race>::iterator it = races.begin();
for (; it != races.end(); ++it)
{
@ -354,8 +353,14 @@ namespace MWGui
if (!playable) // Only display playable races
continue;
mRaceList->addItem(it->mName, it->mId);
if (Misc::StringUtils::ciEqual(it->mId, mCurrentRaceId))
items[it->mId] = it->mName;
}
int index = 0;
for (std::map<std::string, std::string>::const_iterator it = items.begin(); it != items.end(); ++it)
{
mRaceList->addItem(it->second, it->first);
if (Misc::StringUtils::ciEqual(it->first, mCurrentRaceId))
mRaceList->setIndexSelected(index);
++index;
}

View file

@ -99,7 +99,9 @@ namespace MWWorld
class Store : public StoreBase
{
std::map<std::string, T> mStatic;
std::vector<T *> mShared;
std::vector<T *> mShared; // Preserves the record order as it came from the content files (this
// is relevant for the spell autocalc code and selection order
// for heads/hairs in the character creation)
std::map<std::string, T> mDynamic;
typedef std::map<std::string, T> Dynamic;
@ -137,8 +139,9 @@ namespace MWWorld
// setUp needs to be called again after
virtual void clearDynamic()
{
// remove the dynamic part of mShared
mShared.erase(mShared.begin() + mStatic.size(), mShared.end());
mDynamic.clear();
mShared.clear();
}
const T *search(const std::string &id) const {
@ -203,18 +206,18 @@ namespace MWWorld
void load(ESM::ESMReader &esm, const std::string &id) {
std::string idLower = Misc::StringUtils::lowerCase(id);
mStatic[idLower] = T();
mStatic[idLower].mId = idLower;
mStatic[idLower].load(esm);
std::pair<typename Static::iterator, bool> inserted = mStatic.insert(std::make_pair(idLower, T()));
if (inserted.second)
mShared.push_back(&inserted.first->second);
inserted.first->second.mId = idLower;
inserted.first->second.load(esm);
}
void setUp() {
mShared.clear();
mShared.reserve(mStatic.size());
typename std::map<std::string, T>::iterator it = mStatic.begin();
for (; it != mStatic.end(); ++it) {
mShared.push_back(&(it->second));
}
// remove the dynamic part of mShared
mShared.erase(mShared.begin() + mStatic.size(), mShared.end());
}
iterator begin() const {
@ -356,10 +359,9 @@ namespace MWWorld
std::map<std::string, ESM::Dialogue>::iterator it = mStatic.find(idLower);
if (it == mStatic.end()) {
it = mStatic.insert( std::make_pair( idLower, ESM::Dialogue() ) ).first;
it->second.mId = id; // don't smash case here, as this line is printed... I think
it->second.mId = id; // don't smash case here, as this line is printed
}
//I am not sure is it need to load the dialog from a plugin if it was already loaded from prevois plugins
it->second.load(esm);
}
@ -368,7 +370,10 @@ namespace MWWorld
ESM::Script scpt;
scpt.load(esm);
Misc::StringUtils::toLower(scpt.mId);
mStatic[scpt.mId] = scpt;
std::pair<typename Static::iterator, bool> inserted = mStatic.insert(std::make_pair(scpt.mId, scpt));
if (inserted.second)
mShared.push_back(&inserted.first->second);
}
template <>
@ -376,7 +381,10 @@ namespace MWWorld
ESM::StartScript s;
s.load(esm);
s.mId = Misc::StringUtils::toLower(s.mScript);
mStatic[s.mId] = s;
std::pair<typename Static::iterator, bool> inserted = mStatic.insert(std::make_pair(s.mId, s));
if (inserted.second)
mShared.push_back(&inserted.first->second);
}
template <>
@ -1067,37 +1075,6 @@ namespace MWWorld
}
};
// Specialisation for ESM::Spell to preserve record order as it was in the content files.
// The NPC spell autocalc code heavily depends on this order.
// We could also do this in the base class, but it's usually not a good idea to depend on record order.
template<>
inline void Store<ESM::Spell>::clearDynamic()
{
// remove the dynamic part of mShared
mShared.erase(mShared.begin() + mStatic.size(), mShared.end());
mDynamic.clear();
}
template<>
inline void Store<ESM::Spell>::load(ESM::ESMReader &esm, const std::string &id) {
std::string idLower = Misc::StringUtils::lowerCase(id);
std::pair<Static::iterator, bool> inserted = mStatic.insert(std::make_pair(idLower, ESM::Spell()));
if (inserted.second)
mShared.push_back(&mStatic[idLower]);
inserted.first->second.mId = idLower;
inserted.first->second.load(esm);
}
template<>
inline void Store<ESM::Spell>::setUp()
{
// remove the dynamic part of mShared
mShared.erase(mShared.begin() + mStatic.size(), mShared.end());
}
template<>
inline void Store<ESM::Dialogue>::setUp()
{