mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-03-03 13:49:40 +00:00
comparestring
This commit is contained in:
parent
98103e15eb
commit
69d9d22579
7 changed files with 18 additions and 723 deletions
|
@ -45,8 +45,8 @@ namespace
|
||||||
|
|
||||||
//helper function
|
//helper function
|
||||||
std::string::size_type find_str_ci(const std::string& str, const std::string& substr,size_t pos)
|
std::string::size_type find_str_ci(const std::string& str, const std::string& substr,size_t pos)
|
||||||
{
|
{
|
||||||
return Misc::toLower(str).find(Misc::toLower(substr),pos);
|
return Misc::StringUtils::toLower(const_cast<std::string &>(str)).find(Misc::StringUtils::toLower(const_cast<std::string &>(substr)).c_str(),pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,13 +70,13 @@ namespace MWDialogue
|
||||||
MWWorld::Store<ESM::Dialogue>::iterator it = dialogs.begin();
|
MWWorld::Store<ESM::Dialogue>::iterator it = dialogs.begin();
|
||||||
for (; it != dialogs.end(); ++it)
|
for (; it != dialogs.end(); ++it)
|
||||||
{
|
{
|
||||||
mDialogueMap[Misc::toLower(it->mId)] = *it;
|
mDialogueMap[Misc::StringUtils::toLower(const_cast<std::string &>(it->mId))] = *it;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DialogueManager::addTopic (const std::string& topic)
|
void DialogueManager::addTopic (const std::string& topic)
|
||||||
{
|
{
|
||||||
mKnownTopics[Misc::toLower(topic)] = true;
|
mKnownTopics[Misc::StringUtils::toLower(const_cast<std::string &>(topic))] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DialogueManager::parseText (const std::string& text)
|
void DialogueManager::parseText (const std::string& text)
|
||||||
|
@ -274,10 +274,10 @@ namespace MWDialogue
|
||||||
{
|
{
|
||||||
if (filter.search (*iter))
|
if (filter.search (*iter))
|
||||||
{
|
{
|
||||||
mActorKnownTopics.push_back (Misc::toLower (iter->mId));
|
mActorKnownTopics.push_back ( Misc::StringUtils::toLower(const_cast<std::string &>(iter->mId)));
|
||||||
|
|
||||||
//does the player know the topic?
|
//does the player know the topic?
|
||||||
if (mKnownTopics.find (Misc::toLower (iter->mId)) != mKnownTopics.end())
|
if (mKnownTopics.find ( Misc::StringUtils::toLower(const_cast<std::string &>(iter->mId))) != mKnownTopics.end())
|
||||||
{
|
{
|
||||||
keywordList.push_back (iter->mId);
|
keywordList.push_back (iter->mId);
|
||||||
}
|
}
|
||||||
|
@ -335,7 +335,7 @@ namespace MWDialogue
|
||||||
win->setServices (windowServices);
|
win->setServices (windowServices);
|
||||||
|
|
||||||
// sort again, because the previous sort was case-sensitive
|
// sort again, because the previous sort was case-sensitive
|
||||||
keywordList.sort(Misc::stringCompareNoCase);
|
keywordList.sort(Misc::StringUtils::ciEqual);
|
||||||
win->setKeywords(keywordList);
|
win->setKeywords(keywordList);
|
||||||
|
|
||||||
mChoice = choice;
|
mChoice = choice;
|
||||||
|
@ -415,7 +415,7 @@ namespace MWDialogue
|
||||||
{
|
{
|
||||||
MWGui::DialogueWindow* win = MWBase::Environment::get().getWindowManager()->getDialogueWindow();
|
MWGui::DialogueWindow* win = MWBase::Environment::get().getWindowManager()->getDialogueWindow();
|
||||||
win->askQuestion(question);
|
win->askQuestion(question);
|
||||||
mChoiceMap[Misc::toLower(question)] = choice;
|
mChoiceMap[Misc::StringUtils::toLower(const_cast<std::string &>(question))] = choice;
|
||||||
mIsInChoice = true;
|
mIsInChoice = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -271,7 +271,7 @@ namespace MWGui
|
||||||
for (MWWorld::ContainerStoreIterator it = invStore.begin();
|
for (MWWorld::ContainerStoreIterator it = invStore.begin();
|
||||||
it != invStore.end(); ++it)
|
it != invStore.end(); ++it)
|
||||||
{
|
{
|
||||||
if (Misc::toLower(it->getCellRef().mRefID) == "gold_001")
|
if (Misc::StringUtils::toLower(it->getCellRef().mRefID) == "gold_001")
|
||||||
return it->getRefData().getCount();
|
return it->getRefData().getCount();
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -72,7 +72,7 @@ namespace MWScript
|
||||||
Interpreter::Type_Integer sum = 0;
|
Interpreter::Type_Integer sum = 0;
|
||||||
|
|
||||||
for (MWWorld::ContainerStoreIterator iter (store.begin()); iter!=store.end(); ++iter)
|
for (MWWorld::ContainerStoreIterator iter (store.begin()); iter!=store.end(); ++iter)
|
||||||
if (Misc::toLower(iter->getCellRef().mRefID) == Misc::toLower(item))
|
if (Misc::StringUtils::toLower(iter->getCellRef().mRefID) == Misc::StringUtils::toLower(item))
|
||||||
sum += iter->getRefData().getCount();
|
sum += iter->getRefData().getCount();
|
||||||
|
|
||||||
runtime.push (sum);
|
runtime.push (sum);
|
||||||
|
@ -105,7 +105,7 @@ namespace MWScript
|
||||||
for (MWWorld::ContainerStoreIterator iter (store.begin()); iter!=store.end() && count;
|
for (MWWorld::ContainerStoreIterator iter (store.begin()); iter!=store.end() && count;
|
||||||
++iter)
|
++iter)
|
||||||
{
|
{
|
||||||
if (Misc::toLower(iter->getCellRef().mRefID) == Misc::toLower(item))
|
if (Misc::StringUtils::toLower(iter->getCellRef().mRefID) == Misc::StringUtils::toLower(item))
|
||||||
{
|
{
|
||||||
itemName = MWWorld::Class::get(*iter).getName(*iter);
|
itemName = MWWorld::Class::get(*iter).getName(*iter);
|
||||||
|
|
||||||
|
@ -163,7 +163,7 @@ namespace MWScript
|
||||||
MWWorld::ContainerStoreIterator it = invStore.begin();
|
MWWorld::ContainerStoreIterator it = invStore.begin();
|
||||||
for (; it != invStore.end(); ++it)
|
for (; it != invStore.end(); ++it)
|
||||||
{
|
{
|
||||||
if (toLower(it->getCellRef().mRefID) == toLower(item))
|
if (Misc::StringUtils::toLower(it->getCellRef().mRefID) == Misc::StringUtils::toLower(item))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (it == invStore.end())
|
if (it == invStore.end())
|
||||||
|
@ -263,7 +263,7 @@ namespace MWScript
|
||||||
for (int slot = 0; slot < MWWorld::InventoryStore::Slots; ++slot)
|
for (int slot = 0; slot < MWWorld::InventoryStore::Slots; ++slot)
|
||||||
{
|
{
|
||||||
MWWorld::ContainerStoreIterator it = invStore.getSlot (slot);
|
MWWorld::ContainerStoreIterator it = invStore.getSlot (slot);
|
||||||
if (it != invStore.end() && toLower(it->getCellRef().mRefID) == toLower(item))
|
if (it != invStore.end() && Misc::StringUtils::toLower(it->getCellRef().mRefID) == Misc::StringUtils::toLower(item))
|
||||||
{
|
{
|
||||||
runtime.push(1);
|
runtime.push(1);
|
||||||
return;
|
return;
|
||||||
|
@ -281,8 +281,9 @@ namespace MWScript
|
||||||
virtual void execute(Interpreter::Runtime &runtime)
|
virtual void execute(Interpreter::Runtime &runtime)
|
||||||
{
|
{
|
||||||
MWWorld::Ptr ptr = R()(runtime);
|
MWWorld::Ptr ptr = R()(runtime);
|
||||||
|
|
||||||
std::string creatureName = toLower (runtime.getStringLiteral (runtime[0].mInteger));
|
const std::string &name = runtime.getStringLiteral (runtime[0].mInteger);
|
||||||
|
std::string creatureName = Misc::StringUtils::toLower (const_cast<std::string &>(name));
|
||||||
runtime.pop();
|
runtime.pop();
|
||||||
|
|
||||||
MWWorld::InventoryStore& invStore = MWWorld::Class::get(ptr).getInventoryStore (ptr);
|
MWWorld::InventoryStore& invStore = MWWorld::Class::get(ptr).getInventoryStore (ptr);
|
||||||
|
@ -290,7 +291,7 @@ namespace MWScript
|
||||||
it != invStore.end(); ++it)
|
it != invStore.end(); ++it)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (toLower(it->getCellRef().mSoul) == toLower(creatureName))
|
if (Misc::StringUtils::toLower(it->getCellRef().mSoul) == Misc::StringUtils::toLower(creatureName))
|
||||||
{
|
{
|
||||||
runtime.push(1);
|
runtime.push(1);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -621,7 +621,7 @@ namespace MWWorld
|
||||||
{
|
{
|
||||||
if (isPlayer)
|
if (isPlayer)
|
||||||
if (!newCell.isExterior())
|
if (!newCell.isExterior())
|
||||||
changeToInteriorCell(Misc::toLower(newCell.mCell->mName), pos);
|
changeToInteriorCell(Misc::StringUtils::toLower(const_cast<std::string &> (newCell.mCell->mName)), pos);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int cellX = newCell.mCell->getGridX();
|
int cellX = newCell.mCell->getGridX();
|
||||||
|
|
|
@ -1,674 +0,0 @@
|
||||||
#ifndef _GAME_ESM_RECLISTS_H
|
|
||||||
#define _GAME_ESM_RECLISTS_H
|
|
||||||
|
|
||||||
#include "components/esm/records.hpp"
|
|
||||||
#include <map>
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
#include <algorithm>
|
|
||||||
#include <cctype>
|
|
||||||
#include <cassert>
|
|
||||||
#include <stdexcept>
|
|
||||||
#include <iterator>
|
|
||||||
#include <boost/algorithm/string.hpp>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
using namespace boost::algorithm;
|
|
||||||
|
|
||||||
namespace ESMS
|
|
||||||
{
|
|
||||||
using namespace ESM;
|
|
||||||
|
|
||||||
struct RecList
|
|
||||||
{
|
|
||||||
virtual ~RecList() {}
|
|
||||||
|
|
||||||
virtual void load(ESMReader &esm, const std::string &id) = 0;
|
|
||||||
virtual int getSize() = 0;
|
|
||||||
virtual void listIdentifier (std::vector<std::string>& identifier) const = 0;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef std::map<int,RecList*> RecListList;
|
|
||||||
|
|
||||||
template <typename X>
|
|
||||||
struct RecListT : RecList
|
|
||||||
{
|
|
||||||
virtual ~RecListT() {}
|
|
||||||
|
|
||||||
typedef std::map<std::string,X> MapType;
|
|
||||||
|
|
||||||
MapType list;
|
|
||||||
|
|
||||||
// Load one object of this type
|
|
||||||
void load(ESMReader &esm, const std::string &id)
|
|
||||||
{
|
|
||||||
std::string id2 = Misc::toLower (id);
|
|
||||||
list[id2].load(esm);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find the given object ID, or return NULL if not found.
|
|
||||||
const X* search(const std::string &id) const
|
|
||||||
{
|
|
||||||
std::string id2 = Misc::toLower (id);
|
|
||||||
|
|
||||||
typename MapType::const_iterator iter = list.find (id2);
|
|
||||||
|
|
||||||
if (iter == list.end())
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
return &iter->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find the given object ID (throws an exception if not found)
|
|
||||||
const X* find(const std::string &id) const
|
|
||||||
{
|
|
||||||
const X *object = search (id);
|
|
||||||
|
|
||||||
if (!object)
|
|
||||||
throw std::runtime_error ("object " + id + " not found");
|
|
||||||
|
|
||||||
return object;
|
|
||||||
}
|
|
||||||
|
|
||||||
int getSize() { return list.size(); }
|
|
||||||
|
|
||||||
virtual void listIdentifier (std::vector<std::string>& identifier) const
|
|
||||||
{
|
|
||||||
for (typename MapType::const_iterator iter (list.begin()); iter!=list.end(); ++iter)
|
|
||||||
identifier.push_back (iter->first);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Same as RecListT, but does not case-smash the IDs
|
|
||||||
// Note that lookups (search or find) are still case insensitive
|
|
||||||
template <typename X>
|
|
||||||
struct RecListCaseT : RecList
|
|
||||||
{
|
|
||||||
virtual ~RecListCaseT() {}
|
|
||||||
|
|
||||||
typedef std::map<std::string,X> MapType;
|
|
||||||
|
|
||||||
MapType list;
|
|
||||||
|
|
||||||
// Load one object of this type
|
|
||||||
void load(ESMReader &esm, const std::string &id)
|
|
||||||
{
|
|
||||||
//std::string id2 = Misc::toLower (id);
|
|
||||||
|
|
||||||
list[id].load(esm);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find the given object ID, or return NULL if not found.
|
|
||||||
const X* search(const std::string &id) const
|
|
||||||
{
|
|
||||||
std::string id2 = Misc::toLower (id);
|
|
||||||
|
|
||||||
for (typename MapType::const_iterator iter = list.begin();
|
|
||||||
iter != list.end(); ++iter)
|
|
||||||
{
|
|
||||||
if (Misc::toLower(iter->first) == id2)
|
|
||||||
return &iter->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// non-const version
|
|
||||||
X* search(const std::string &id)
|
|
||||||
{
|
|
||||||
std::string id2 = Misc::toLower (id);
|
|
||||||
|
|
||||||
for (typename MapType::iterator iter = list.begin();
|
|
||||||
iter != list.end(); ++iter)
|
|
||||||
{
|
|
||||||
if (Misc::toLower(iter->first) == id2)
|
|
||||||
return &iter->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find the given object ID (throws an exception if not found)
|
|
||||||
const X* find(const std::string &id) const
|
|
||||||
{
|
|
||||||
const X *object = search (id);
|
|
||||||
|
|
||||||
if (!object)
|
|
||||||
throw std::runtime_error ("object " + id + " not found");
|
|
||||||
|
|
||||||
return object;
|
|
||||||
}
|
|
||||||
|
|
||||||
int getSize() { return list.size(); }
|
|
||||||
|
|
||||||
virtual void listIdentifier (std::vector<std::string>& identifier) const
|
|
||||||
{
|
|
||||||
for (typename MapType::const_iterator iter (list.begin()); iter!=list.end(); ++iter)
|
|
||||||
identifier.push_back (iter->first);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Modified version of RecListT for records, that need to store their own ID
|
|
||||||
template <typename X>
|
|
||||||
struct RecListWithIDT : RecList
|
|
||||||
{
|
|
||||||
virtual ~RecListWithIDT() {}
|
|
||||||
|
|
||||||
typedef std::map<std::string,X> MapType;
|
|
||||||
|
|
||||||
MapType list;
|
|
||||||
|
|
||||||
// Load one object of this type
|
|
||||||
void load(ESMReader &esm, const std::string &id)
|
|
||||||
{
|
|
||||||
std::string id2 = Misc::toLower (id);
|
|
||||||
list[id2].mId = id2;
|
|
||||||
list[id2].load(esm);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find the given object ID, or return NULL if not found.
|
|
||||||
const X* search(const std::string &id) const
|
|
||||||
{
|
|
||||||
std::string id2 = Misc::toLower (id);
|
|
||||||
|
|
||||||
typename MapType::const_iterator iter = list.find (id2);
|
|
||||||
|
|
||||||
if (iter == list.end())
|
|
||||||
return NULL;
|
|
||||||
return &iter->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find the given object ID (throws an exception if not found)
|
|
||||||
const X* find(const std::string &id) const
|
|
||||||
{
|
|
||||||
const X *object = search (id);
|
|
||||||
|
|
||||||
if (!object)
|
|
||||||
throw std::runtime_error ("object " + id + " not found");
|
|
||||||
|
|
||||||
return object;
|
|
||||||
}
|
|
||||||
|
|
||||||
int getSize() { return list.size(); }
|
|
||||||
|
|
||||||
virtual void listIdentifier (std::vector<std::string>& identifier) const
|
|
||||||
{
|
|
||||||
for (typename MapType::const_iterator iter (list.begin()); iter!=list.end(); ++iter)
|
|
||||||
identifier.push_back (iter->first);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// The only difference to the above is a slight change to the load()
|
|
||||||
// function. We might merge these together later, and store the id
|
|
||||||
// in all the structs.
|
|
||||||
template <typename X>
|
|
||||||
struct RecIDListT : RecList
|
|
||||||
{
|
|
||||||
virtual ~RecIDListT() {}
|
|
||||||
|
|
||||||
typedef std::map<std::string,X> MapType;
|
|
||||||
|
|
||||||
MapType list;
|
|
||||||
|
|
||||||
void load(ESMReader &esm, const std::string &id)
|
|
||||||
{
|
|
||||||
std::string id2 = Misc::toLower (id);
|
|
||||||
X& ref = list[id2];
|
|
||||||
|
|
||||||
ref.mId = id;
|
|
||||||
ref.load(esm);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find the given object ID, or return NULL if not found.
|
|
||||||
const X* search(const std::string &id) const
|
|
||||||
{
|
|
||||||
std::string id2 = Misc::toLower (id);
|
|
||||||
|
|
||||||
typename MapType::const_iterator iter = list.find (id2);
|
|
||||||
|
|
||||||
if (iter == list.end())
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
return &iter->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find the given object ID (throws an exception if not found)
|
|
||||||
const X* find(const std::string &id) const
|
|
||||||
{
|
|
||||||
const X *object = search (id);
|
|
||||||
|
|
||||||
if (!object)
|
|
||||||
throw std::runtime_error ("object " + id + " not found");
|
|
||||||
|
|
||||||
return object;
|
|
||||||
}
|
|
||||||
|
|
||||||
int getSize() { return list.size(); }
|
|
||||||
|
|
||||||
virtual void listIdentifier (std::vector<std::string>& identifier) const
|
|
||||||
{
|
|
||||||
for (typename MapType::const_iterator iter (list.begin()); iter!=list.end(); ++iter)
|
|
||||||
identifier.push_back (iter->first);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Land textures are indexed by an integer number
|
|
||||||
*/
|
|
||||||
struct LTexList : RecList
|
|
||||||
{
|
|
||||||
virtual ~LTexList() {}
|
|
||||||
|
|
||||||
// TODO: For multiple ESM/ESP files we need one list per file.
|
|
||||||
std::vector<LandTexture> ltex;
|
|
||||||
|
|
||||||
LTexList()
|
|
||||||
{
|
|
||||||
// More than enough to hold Morrowind.esm.
|
|
||||||
ltex.reserve(128);
|
|
||||||
}
|
|
||||||
|
|
||||||
const LandTexture* search(size_t index) const
|
|
||||||
{
|
|
||||||
assert(index < ltex.size());
|
|
||||||
return <ex.at(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
int getSize() { return ltex.size(); }
|
|
||||||
int getSize() const { return ltex.size(); }
|
|
||||||
|
|
||||||
virtual void listIdentifier (std::vector<std::string>& identifier) const {}
|
|
||||||
|
|
||||||
void load(ESMReader &esm, const std::string &id)
|
|
||||||
{
|
|
||||||
LandTexture lt;
|
|
||||||
lt.load(esm);
|
|
||||||
lt.mId = id;
|
|
||||||
|
|
||||||
// Make sure we have room for the structure
|
|
||||||
if(lt.mIndex + 1 > (int)ltex.size())
|
|
||||||
ltex.resize(lt.mIndex+1);
|
|
||||||
|
|
||||||
// Store it
|
|
||||||
ltex[lt.mIndex] = lt;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Landscapes are indexed by the X,Y coordinates of the exterior
|
|
||||||
cell they belong to.
|
|
||||||
*/
|
|
||||||
struct LandList : RecList
|
|
||||||
{
|
|
||||||
virtual ~LandList()
|
|
||||||
{
|
|
||||||
for ( LandMap::iterator itr = lands.begin(); itr != lands.end(); ++itr )
|
|
||||||
{
|
|
||||||
delete itr->second;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Map containing all landscapes
|
|
||||||
typedef std::pair<int, int> LandCoord;
|
|
||||||
typedef std::map<LandCoord, Land*> LandMap;
|
|
||||||
LandMap lands;
|
|
||||||
|
|
||||||
int count;
|
|
||||||
LandList() : count(0) {}
|
|
||||||
int getSize() { return count; }
|
|
||||||
|
|
||||||
virtual void listIdentifier (std::vector<std::string>& identifier) const {}
|
|
||||||
|
|
||||||
// Find land for the given coordinates. Return null if no mData.
|
|
||||||
Land *search(int x, int y) const
|
|
||||||
{
|
|
||||||
LandMap::const_iterator itr = lands.find(std::make_pair (x, y));
|
|
||||||
if ( itr == lands.end() )
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return itr->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
void load(ESMReader &esm, const std::string &id)
|
|
||||||
{
|
|
||||||
count++;
|
|
||||||
|
|
||||||
// Create the structure and load it. This actually skips the
|
|
||||||
// landscape data and remembers the file position for later.
|
|
||||||
Land *land = new Land();
|
|
||||||
land->load(esm);
|
|
||||||
|
|
||||||
// Store the structure
|
|
||||||
lands[std::make_pair (land->mX, land->mY)] = land;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ciLessBoost : std::binary_function<std::string, std::string, bool>
|
|
||||||
{
|
|
||||||
bool operator() (const std::string & s1, const std::string & s2) const {
|
|
||||||
//case insensitive version of is_less
|
|
||||||
return lexicographical_compare(s1, s2, is_iless());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// Cells aren't simply indexed by name. Exterior cells are treated
|
|
||||||
// separately.
|
|
||||||
// TODO: case handling (cell names are case-insensitive, but they are also showen to the
|
|
||||||
// player, so we can't simply smash case.
|
|
||||||
struct CellList : RecList
|
|
||||||
{
|
|
||||||
// Total cell count. Used for statistics.
|
|
||||||
int count;
|
|
||||||
CellList() : count(0) {}
|
|
||||||
int getSize() { return count; }
|
|
||||||
|
|
||||||
// List of interior cells. Indexed by cell name.
|
|
||||||
typedef std::map<std::string,ESM::Cell*, ciLessBoost> IntCells;
|
|
||||||
IntCells intCells;
|
|
||||||
|
|
||||||
// List of exterior cells. Indexed as extCells[mX][mY].
|
|
||||||
typedef std::map<std::pair<int, int>, ESM::Cell*> ExtCells;
|
|
||||||
ExtCells extCells;
|
|
||||||
|
|
||||||
virtual void listIdentifier (std::vector<std::string>& identifier) const
|
|
||||||
{
|
|
||||||
for (IntCells::const_iterator iter (intCells.begin()); iter!=intCells.end(); ++iter)
|
|
||||||
identifier.push_back (iter->first);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual ~CellList()
|
|
||||||
{
|
|
||||||
for (IntCells::iterator it = intCells.begin(); it!=intCells.end(); ++it)
|
|
||||||
delete it->second;
|
|
||||||
|
|
||||||
for (ExtCells::iterator it = extCells.begin(); it!=extCells.end(); ++it)
|
|
||||||
delete it->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
const ESM::Cell* searchInt(const std::string &id) const
|
|
||||||
{
|
|
||||||
IntCells::const_iterator iter = intCells.find(id);
|
|
||||||
|
|
||||||
if (iter!=intCells.end())
|
|
||||||
return iter->second;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
const ESM::Cell* findInt(const std::string &id) const
|
|
||||||
{
|
|
||||||
const ESM::Cell *cell = searchInt (id);
|
|
||||||
|
|
||||||
if (!cell)
|
|
||||||
throw std::runtime_error ("Interior cell not found - " + id);
|
|
||||||
|
|
||||||
return cell;
|
|
||||||
}
|
|
||||||
|
|
||||||
const ESM::Cell *searchExt (int x, int y) const
|
|
||||||
{
|
|
||||||
ExtCells::const_iterator it = extCells.find (std::make_pair (x, y));
|
|
||||||
|
|
||||||
if (it==extCells.end())
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return it->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
const ESM::Cell *findExt (int x, int y) const
|
|
||||||
{
|
|
||||||
const ESM::Cell *cell = searchExt (x, y);
|
|
||||||
|
|
||||||
if (!cell)
|
|
||||||
throw std::runtime_error ("Exterior cell not found");
|
|
||||||
|
|
||||||
return cell;
|
|
||||||
}
|
|
||||||
const ESM::Cell *searchExtByName (const std::string& id) const
|
|
||||||
{
|
|
||||||
for (ExtCells::const_iterator iter = extCells.begin(); iter!=extCells.end(); ++iter)
|
|
||||||
{
|
|
||||||
if (Misc::toLower (iter->second->mName) == Misc::toLower (id))
|
|
||||||
return iter->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
const ESM::Cell *searchExtByRegion (const std::string& id) const
|
|
||||||
{
|
|
||||||
std::string id2 = Misc::toLower (id);
|
|
||||||
|
|
||||||
for (ExtCells::const_iterator iter = extCells.begin(); iter!=extCells.end(); ++iter)
|
|
||||||
if (Misc::toLower (iter->second->mRegion)==id)
|
|
||||||
return iter->second;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void load(ESMReader &esm, const std::string &id)
|
|
||||||
{
|
|
||||||
count++;
|
|
||||||
|
|
||||||
// All cells have a name record, even nameless exterior cells.
|
|
||||||
ESM::Cell *cell = new ESM::Cell;
|
|
||||||
cell->mName = id;
|
|
||||||
|
|
||||||
// The cell itself takes care of all the hairy details
|
|
||||||
cell->load(esm);
|
|
||||||
|
|
||||||
if(cell->mData.mFlags & ESM::Cell::Interior)
|
|
||||||
{
|
|
||||||
// Store interior cell by name
|
|
||||||
intCells[id] = cell;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Store exterior cells by grid position
|
|
||||||
extCells[std::make_pair (cell->mData.mX, cell->mData.mY)] = cell;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct PathgridList : RecList
|
|
||||||
{
|
|
||||||
int count;
|
|
||||||
|
|
||||||
// List of grids for interior cells. Indexed by cell name.
|
|
||||||
typedef std::map<std::string,ESM::Pathgrid*, ciLessBoost> IntGrids;
|
|
||||||
IntGrids intGrids;
|
|
||||||
|
|
||||||
// List of grids for exterior cells. Indexed as extCells[mX][mY].
|
|
||||||
typedef std::map<std::pair<int, int>, ESM::Pathgrid*> ExtGrids;
|
|
||||||
ExtGrids extGrids;
|
|
||||||
|
|
||||||
PathgridList() : count(0) {}
|
|
||||||
|
|
||||||
virtual ~PathgridList()
|
|
||||||
{
|
|
||||||
for (IntGrids::iterator it = intGrids.begin(); it!=intGrids.end(); ++it)
|
|
||||||
delete it->second;
|
|
||||||
|
|
||||||
for (ExtGrids::iterator it = extGrids.begin(); it!=extGrids.end(); ++it)
|
|
||||||
delete it->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
int getSize() { return count; }
|
|
||||||
|
|
||||||
virtual void listIdentifier (std::vector<std::string>& identifier) const
|
|
||||||
{
|
|
||||||
// do nothing
|
|
||||||
}
|
|
||||||
|
|
||||||
void load(ESMReader &esm, const std::string &id)
|
|
||||||
{
|
|
||||||
count++;
|
|
||||||
ESM::Pathgrid *grid = new ESM::Pathgrid;
|
|
||||||
grid->load(esm);
|
|
||||||
if (grid->mData.mX == 0 && grid->mData.mY == 0)
|
|
||||||
{
|
|
||||||
intGrids[grid->mCell] = grid;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
extGrids[std::make_pair(grid->mData.mX, grid->mData.mY)] = grid;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Pathgrid *find(int cellX, int cellY, const std::string &cellName) const
|
|
||||||
{
|
|
||||||
Pathgrid *result = search(cellX, cellY, cellName);
|
|
||||||
if (!result)
|
|
||||||
{
|
|
||||||
throw std::runtime_error("no pathgrid found for cell " + cellName);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
Pathgrid *search(int cellX, int cellY, const std::string &cellName) const
|
|
||||||
{
|
|
||||||
Pathgrid *result = NULL;
|
|
||||||
if (cellX == 0 && cellY == 0) // possibly interior
|
|
||||||
{
|
|
||||||
IntGrids::const_iterator it = intGrids.find(cellName);
|
|
||||||
if (it != intGrids.end())
|
|
||||||
result = it->second;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ExtGrids::const_iterator it = extGrids.find(std::make_pair(cellX, cellY));
|
|
||||||
if (it != extGrids.end())
|
|
||||||
result = it->second;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
Pathgrid *search(const ESM::Cell &cell) const
|
|
||||||
{
|
|
||||||
int cellX, cellY;
|
|
||||||
if (cell.mData.mFlags & ESM::Cell::Interior)
|
|
||||||
{
|
|
||||||
cellX = cellY = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
cellX = cell.mData.mX;
|
|
||||||
cellY = cell.mData.mY;
|
|
||||||
}
|
|
||||||
return search(cellX, cellY, cell.mName);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename X>
|
|
||||||
struct ScriptListT : RecList
|
|
||||||
{
|
|
||||||
virtual ~ScriptListT() {}
|
|
||||||
|
|
||||||
typedef std::map<std::string,X> MapType;
|
|
||||||
|
|
||||||
MapType list;
|
|
||||||
|
|
||||||
// Load one object of this type
|
|
||||||
void load(ESMReader &esm, const std::string &id)
|
|
||||||
{
|
|
||||||
X ref;
|
|
||||||
ref.load (esm);
|
|
||||||
|
|
||||||
std::string realId = Misc::toLower (ref.mData.mName.toString());
|
|
||||||
|
|
||||||
std::swap (list[realId], ref);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find the given object ID, or return NULL if not found.
|
|
||||||
const X* search(const std::string &id) const
|
|
||||||
{
|
|
||||||
std::string id2 = Misc::toLower (id);
|
|
||||||
|
|
||||||
typename MapType::const_iterator iter = list.find (id2);
|
|
||||||
|
|
||||||
if (iter == list.end())
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
return &iter->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find the given object ID (throws an exception if not found)
|
|
||||||
const X* find(const std::string &id) const
|
|
||||||
{
|
|
||||||
const X *object = search (id);
|
|
||||||
|
|
||||||
if (!object)
|
|
||||||
throw std::runtime_error ("object " + id + " not found");
|
|
||||||
|
|
||||||
return object;
|
|
||||||
}
|
|
||||||
|
|
||||||
int getSize() { return list.size(); }
|
|
||||||
|
|
||||||
virtual void listIdentifier (std::vector<std::string>& identifier) const
|
|
||||||
{
|
|
||||||
for (typename MapType::const_iterator iter (list.begin()); iter!=list.end(); ++iter)
|
|
||||||
identifier.push_back (iter->first);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename X>
|
|
||||||
struct IndexListT
|
|
||||||
{
|
|
||||||
virtual ~IndexListT() {}
|
|
||||||
|
|
||||||
typedef std::map<int, X> MapType;
|
|
||||||
|
|
||||||
MapType list;
|
|
||||||
|
|
||||||
void load(ESMReader &esm)
|
|
||||||
{
|
|
||||||
X ref;
|
|
||||||
ref.load (esm);
|
|
||||||
int index = ref.mIndex;
|
|
||||||
list[index] = ref;
|
|
||||||
}
|
|
||||||
|
|
||||||
int getSize()
|
|
||||||
{
|
|
||||||
return list.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void listIdentifier (std::vector<std::string>& identifier) const {}
|
|
||||||
|
|
||||||
// Find the given object ID, or return NULL if not found.
|
|
||||||
const X* search (int id) const
|
|
||||||
{
|
|
||||||
typename MapType::const_iterator iter = list.find (id);
|
|
||||||
|
|
||||||
if (iter == list.end())
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
return &iter->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find the given object ID (throws an exception if not found)
|
|
||||||
const X* find (int id) const
|
|
||||||
{
|
|
||||||
const X *object = search (id);
|
|
||||||
|
|
||||||
if (!object)
|
|
||||||
{
|
|
||||||
std::ostringstream error;
|
|
||||||
error << "object " << id << " not found";
|
|
||||||
throw std::runtime_error (error.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
return object;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/* We need special lists for:
|
|
||||||
|
|
||||||
Path grids
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
#endif
|
|
|
@ -67,30 +67,4 @@ bool iends(const char* str1, const char* str2)
|
||||||
return strcasecmp(str2, str1+len1-len2) == 0;
|
return strcasecmp(str2, str1+len1-len2) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string toLower (const std::string& name)
|
|
||||||
{
|
|
||||||
std::string lowerCase;
|
|
||||||
|
|
||||||
std::transform (name.begin(), name.end(), std::back_inserter (lowerCase),
|
|
||||||
(int(*)(int)) std::tolower);
|
|
||||||
|
|
||||||
return lowerCase;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool stringCompareNoCase (std::string first, std::string second)
|
|
||||||
{
|
|
||||||
unsigned int i=0;
|
|
||||||
while ( (i<first.length()) && (i<second.length()) )
|
|
||||||
{
|
|
||||||
if (tolower(first[i])<tolower(second[i])) return true;
|
|
||||||
else if (tolower(first[i])>tolower(second[i])) return false;
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
if (first.length()<second.length())
|
|
||||||
return true;
|
|
||||||
else
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,12 +66,6 @@ bool ibegins(const char* str1, const char* str2);
|
||||||
/// Case insensitive, returns true if str1 ends with substring str2
|
/// Case insensitive, returns true if str1 ends with substring str2
|
||||||
bool iends(const char* str1, const char* str2);
|
bool iends(const char* str1, const char* str2);
|
||||||
|
|
||||||
///
|
|
||||||
std::string toLower (const std::string& name);
|
|
||||||
|
|
||||||
/// Case fold compare
|
|
||||||
bool stringCompareNoCase (std::string first, std::string second);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue