mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2024-12-29 03:19:44 +00:00
Cell names localization fix
This commit is contained in:
parent
1cf019a007
commit
74ae479780
@ -59,7 +59,7 @@ struct Arguments
|
||||
std::string outname;
|
||||
|
||||
std::vector<std::string> types;
|
||||
|
||||
|
||||
ESMData data;
|
||||
ESM::ESMReader reader;
|
||||
ESM::ESMWriter writer;
|
||||
@ -74,7 +74,7 @@ bool parseOptions (int argc, char** argv, Arguments &info)
|
||||
("version,v", "print version information and quit.")
|
||||
("raw,r", "Show an unformatted list of all records and subrecords.")
|
||||
// The intention is that this option would interact better
|
||||
// with other modes including clone, dump, and raw.
|
||||
// with other modes including clone, dump, and raw.
|
||||
("type,t", bpo::value< std::vector<std::string> >(),
|
||||
"Show only records of this type (four character record code). May "
|
||||
"be specified multiple times. Only affects dump mode.")
|
||||
@ -262,7 +262,7 @@ void printRaw(ESM::ESMReader &esm)
|
||||
int load(Arguments& info)
|
||||
{
|
||||
ESM::ESMReader& esm = info.reader;
|
||||
esm.setEncoding(info.encoding);
|
||||
esm.setEncoding(ToUTF8::CalculateEncoding(info.encoding));
|
||||
|
||||
std::string filename = info.filename;
|
||||
std::cout << "Loading file: " << filename << std::endl;
|
||||
@ -321,7 +321,7 @@ int load(Arguments& info)
|
||||
if (info.types.size() > 0)
|
||||
{
|
||||
std::vector<std::string>::iterator match;
|
||||
match = std::find(info.types.begin(), info.types.end(),
|
||||
match = std::find(info.types.begin(), info.types.end(),
|
||||
n.toString());
|
||||
if (match == info.types.end()) interested = false;
|
||||
}
|
||||
@ -425,7 +425,7 @@ int clone(Arguments& info)
|
||||
if (++i % 3 == 0)
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
|
||||
if (i % 3 != 0)
|
||||
std::cout << std::endl;
|
||||
|
||||
@ -450,7 +450,7 @@ int clone(Arguments& info)
|
||||
for (Records::iterator it = records.begin(); it != records.end() && i > 0; ++it)
|
||||
{
|
||||
EsmTool::RecordBase *record = *it;
|
||||
|
||||
|
||||
name.val = record->getType().val;
|
||||
|
||||
esm.startRecord(name.toString(), record->getFlags());
|
||||
@ -485,7 +485,7 @@ int clone(Arguments& info)
|
||||
std::cerr << "\r" << perc << "%";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::cout << "\rDone!" << std::endl;
|
||||
|
||||
esm.close();
|
||||
@ -513,7 +513,7 @@ int comp(Arguments& info)
|
||||
|
||||
fileOne.encoding = info.encoding;
|
||||
fileTwo.encoding = info.encoding;
|
||||
|
||||
|
||||
fileOne.filename = info.filename;
|
||||
fileTwo.filename = info.outname;
|
||||
|
||||
@ -534,9 +534,9 @@ int comp(Arguments& info)
|
||||
std::cout << "Not equal, different amount of records." << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -272,7 +272,7 @@ void DataFilesModel::addMasters(const QString &path)
|
||||
foreach (const QString &path, dir.entryList()) {
|
||||
try {
|
||||
ESM::ESMReader fileReader;
|
||||
fileReader.setEncoding(mEncoding.toStdString());
|
||||
fileReader.setEncoding(ToUTF8::CalculateEncoding(mEncoding.toStdString()));
|
||||
fileReader.open(dir.absoluteFilePath(path).toStdString());
|
||||
|
||||
ESM::ESMReader::MasterList mlist = fileReader.getMasters();
|
||||
@ -335,7 +335,7 @@ void DataFilesModel::addPlugins(const QString &path)
|
||||
|
||||
try {
|
||||
ESM::ESMReader fileReader;
|
||||
fileReader.setEncoding(mEncoding.toStdString());
|
||||
fileReader.setEncoding(ToUTF8::CalculateEncoding(mEncoding.toStdString()));
|
||||
fileReader.open(dir.absoluteFilePath(path).toStdString());
|
||||
|
||||
ESM::ESMReader::MasterList mlist = fileReader.getMasters();
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
#include <components/bsa/bsa_archive.hpp>
|
||||
#include <components/files/configurationmanager.hpp>
|
||||
#include <components/translation_data/translation_data.hpp>
|
||||
#include <components/nifoverrides/nifoverrides.hpp>
|
||||
|
||||
#include <components/nifbullet/bullet_nif_loader.hpp>
|
||||
@ -334,12 +335,16 @@ void OMW::Engine::go()
|
||||
mEnvironment.setWorld (new MWWorld::World (*mOgre, mFileCollections, mMaster,
|
||||
mResDir, mCfgMgr.getCachePath(), mNewGame, mEncoding, mFallbackMap));
|
||||
|
||||
//Load translation data
|
||||
std::unique_ptr<TranslationData::Storage> translationDataStorage(new TranslationData::Storage(mEncoding));
|
||||
translationDataStorage->loadTranslationData(mFileCollections, mMaster);
|
||||
|
||||
// Create window manager - this manages all the MW-specific GUI windows
|
||||
MWScript::registerExtensions (mExtensions);
|
||||
|
||||
mEnvironment.setWindowManager (new MWGui::WindowManager(
|
||||
mExtensions, mFpsLevel, mNewGame, mOgre, mCfgMgr.getLogPath().string() + std::string("/"),
|
||||
mCfgMgr.getCachePath ().string(), mScriptConsoleMode));
|
||||
mCfgMgr.getCachePath ().string(), mScriptConsoleMode, translationDataStorage.release()));
|
||||
|
||||
// Create sound system
|
||||
mEnvironment.setSoundManager (new MWSound::SoundManager(mUseSound));
|
||||
@ -487,7 +492,7 @@ void OMW::Engine::showFPS(int level)
|
||||
mFpsLevel = level;
|
||||
}
|
||||
|
||||
void OMW::Engine::setEncoding(const std::string& encoding)
|
||||
void OMW::Engine::setEncoding(const ToUTF8::FromType& encoding)
|
||||
{
|
||||
mEncoding = encoding;
|
||||
}
|
||||
|
@ -59,7 +59,7 @@ namespace OMW
|
||||
class Engine : private Ogre::FrameListener
|
||||
{
|
||||
MWBase::Environment mEnvironment;
|
||||
std::string mEncoding;
|
||||
ToUTF8::FromType mEncoding;
|
||||
Files::PathContainer mDataDirs;
|
||||
boost::filesystem::path mResDir;
|
||||
OEngine::Render::OgreRenderer *mOgre;
|
||||
@ -154,7 +154,7 @@ namespace OMW
|
||||
void setCompileAll (bool all);
|
||||
|
||||
/// Font encoding
|
||||
void setEncoding(const std::string& encoding);
|
||||
void setEncoding(const ToUTF8::FromType& encoding);
|
||||
|
||||
void setAnimationVerbose(bool animverbose);
|
||||
|
||||
|
@ -181,21 +181,8 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat
|
||||
|
||||
// Font encoding settings
|
||||
std::string encoding(variables["encoding"].as<std::string>());
|
||||
if (encoding == "win1250")
|
||||
{
|
||||
std::cout << "Using Central and Eastern European font encoding." << std::endl;
|
||||
engine.setEncoding(encoding);
|
||||
}
|
||||
else if (encoding == "win1251")
|
||||
{
|
||||
std::cout << "Using Cyrillic font encoding." << std::endl;
|
||||
engine.setEncoding(encoding);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Using default (English) font encoding." << std::endl;
|
||||
engine.setEncoding("win1252");
|
||||
}
|
||||
std::cout << ToUTF8::EncodingUsingMessage(encoding) << std::endl;
|
||||
engine.setEncoding(ToUTF8::CalculateEncoding(encoding));
|
||||
|
||||
// directory settings
|
||||
engine.enableFSStrict(variables["fs-strict"].as<bool>());
|
||||
|
@ -204,33 +204,10 @@ namespace MWClass
|
||||
|
||||
std::string text;
|
||||
|
||||
const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
|
||||
|
||||
if (ref->mRef.mTeleport)
|
||||
{
|
||||
std::string dest;
|
||||
if (ref->mRef.mDestCell != "")
|
||||
{
|
||||
// door leads to an interior, use interior name as tooltip
|
||||
dest = ref->mRef.mDestCell;
|
||||
}
|
||||
else
|
||||
{
|
||||
// door leads to exterior, use cell name (if any), otherwise translated region name
|
||||
int x,y;
|
||||
MWBase::Environment::get().getWorld()->positionToIndex (ref->mRef.mDoorDest.pos[0], ref->mRef.mDoorDest.pos[1], x, y);
|
||||
const ESM::Cell* cell = store.get<ESM::Cell>().find(x,y);
|
||||
if (cell->mName != "")
|
||||
dest = cell->mName;
|
||||
else
|
||||
{
|
||||
const ESM::Region* region =
|
||||
store.get<ESM::Region>().find(cell->mRegion);
|
||||
dest = region->mName;
|
||||
}
|
||||
}
|
||||
text += "\n#{sTo}";
|
||||
text += "\n"+dest;
|
||||
text += "\n" + getDestination(*ref);
|
||||
}
|
||||
|
||||
if (ref->mRef.mLockLevel > 0)
|
||||
@ -246,6 +223,37 @@ namespace MWClass
|
||||
return info;
|
||||
}
|
||||
|
||||
std::string Door::getDestination (const MWWorld::LiveCellRef<ESM::Door>& door)
|
||||
{
|
||||
const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
|
||||
|
||||
std::string dest;
|
||||
if (door.mRef.mDestCell != "")
|
||||
{
|
||||
// door leads to an interior, use interior name as tooltip
|
||||
dest = door.mRef.mDestCell;
|
||||
}
|
||||
else
|
||||
{
|
||||
// door leads to exterior, use cell name (if any), otherwise translated region name
|
||||
int x,y;
|
||||
MWBase::Environment::get().getWorld()->positionToIndex (door.mRef.mDoorDest.pos[0], door.mRef.mDoorDest.pos[1], x, y);
|
||||
const ESM::Cell* cell = store.get<ESM::Cell>().find(x,y);
|
||||
if (cell->mName != "")
|
||||
dest = cell->mName;
|
||||
else
|
||||
{
|
||||
const ESM::Region* region =
|
||||
store.get<ESM::Region>().find(cell->mRegion);
|
||||
|
||||
//name as is, not a token
|
||||
return region->mName;
|
||||
}
|
||||
}
|
||||
|
||||
return "#{sCell=" + dest + "}";
|
||||
}
|
||||
|
||||
MWWorld::Ptr
|
||||
Door::copyToCellImpl(const MWWorld::Ptr &ptr, MWWorld::CellStore &cell) const
|
||||
{
|
||||
|
@ -31,6 +31,9 @@ namespace MWClass
|
||||
virtual MWGui::ToolTipInfo getToolTipInfo (const MWWorld::Ptr& ptr) const;
|
||||
///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip.
|
||||
|
||||
static std::string getDestination (const MWWorld::LiveCellRef<ESM::Door>& door);
|
||||
///< @return destination cell name or token
|
||||
|
||||
virtual void lock (const MWWorld::Ptr& ptr, int lockLevel) const;
|
||||
///< Lock object
|
||||
|
||||
|
@ -319,7 +319,7 @@ void HUD::setCellName(const std::string& cellName)
|
||||
mCellNameTimer = 5.0f;
|
||||
mCellName = cellName;
|
||||
|
||||
mCellNameBox->setCaption(mCellName);
|
||||
mCellNameBox->setCaptionWithReplacing("#{sCell=" + mCellName + "}");
|
||||
mCellNameBox->setVisible(mMapVisible);
|
||||
}
|
||||
}
|
||||
|
@ -299,7 +299,7 @@ MapWindow::~MapWindow()
|
||||
|
||||
void MapWindow::setCellName(const std::string& cellName)
|
||||
{
|
||||
setTitle(cellName);
|
||||
setTitle("#{sCell=" + cellName + "}");
|
||||
}
|
||||
|
||||
void MapWindow::addVisitedLocation(const std::string& name, int x, int y)
|
||||
|
@ -55,7 +55,8 @@ using namespace MWGui;
|
||||
|
||||
WindowManager::WindowManager(
|
||||
const Compiler::Extensions& extensions, int fpsLevel, bool newGame, OEngine::Render::OgreRenderer *mOgre,
|
||||
const std::string& logpath, const std::string& cacheDir, bool consoleOnlyScripts)
|
||||
const std::string& logpath, const std::string& cacheDir, bool consoleOnlyScripts,
|
||||
TranslationData::Storage* pTranslationDataStorage)
|
||||
: mGuiManager(NULL)
|
||||
, mHud(NULL)
|
||||
, mMap(NULL)
|
||||
@ -104,6 +105,7 @@ WindowManager::WindowManager(
|
||||
, mCrosshairEnabled(Settings::Manager::getBool ("crosshair", "HUD"))
|
||||
, mSubtitlesEnabled(Settings::Manager::getBool ("subtitles", "GUI"))
|
||||
, mHudEnabled(true)
|
||||
, mTranslationDataStorage(pTranslationDataStorage)
|
||||
{
|
||||
|
||||
// Set up the GUI system
|
||||
@ -612,7 +614,7 @@ void WindowManager::changeCell(MWWorld::Ptr::CellStore* cell)
|
||||
if (cell->mCell->mName != "")
|
||||
{
|
||||
name = cell->mCell->mName;
|
||||
mMap->addVisitedLocation (name, cell->mCell->getGridX (), cell->mCell->getGridY ());
|
||||
mMap->addVisitedLocation ("#{sCell=" + name + "}", cell->mCell->getGridX (), cell->mCell->getGridY ());
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -722,13 +724,25 @@ void WindowManager::setDragDrop(bool dragDrop)
|
||||
|
||||
void WindowManager::onRetrieveTag(const MyGUI::UString& _tag, MyGUI::UString& _result)
|
||||
{
|
||||
const ESM::GameSetting *setting =
|
||||
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find(_tag);
|
||||
std::string tag(_tag);
|
||||
|
||||
if (setting && setting->mType == ESM::VT_String)
|
||||
_result = setting->getString();
|
||||
std::string tokenToFind = "sCell=";
|
||||
size_t tokenLength = tokenToFind.length();
|
||||
|
||||
if (tag.substr(0, tokenLength) == tokenToFind)
|
||||
{
|
||||
_result = mTranslationDataStorage->translateCellName(tag.substr(tokenLength));
|
||||
}
|
||||
else
|
||||
_result = _tag;
|
||||
{
|
||||
const ESM::GameSetting *setting =
|
||||
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find(tag);
|
||||
|
||||
if (setting && setting->mType == ESM::VT_String)
|
||||
_result = setting->getString();
|
||||
else
|
||||
_result = tag;
|
||||
}
|
||||
}
|
||||
|
||||
void WindowManager::processChangedSettings(const Settings::CategorySettingVector& changed)
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include <string>
|
||||
|
||||
#include <components/esm/loadclas.hpp>
|
||||
#include <components/translation_data/translation_data.hpp>
|
||||
|
||||
#include "../mwbase/windowmanager.hpp"
|
||||
|
||||
@ -76,7 +77,8 @@ namespace MWGui
|
||||
|
||||
WindowManager(const Compiler::Extensions& extensions, int fpsLevel, bool newGame,
|
||||
OEngine::Render::OgreRenderer *mOgre, const std::string& logpath,
|
||||
const std::string& cacheDir, bool consoleOnlyScripts);
|
||||
const std::string& cacheDir, bool consoleOnlyScripts,
|
||||
TranslationData::Storage* pTranslationDataStorage);
|
||||
virtual ~WindowManager();
|
||||
|
||||
/**
|
||||
@ -250,6 +252,7 @@ namespace MWGui
|
||||
SpellCreationDialog* mSpellCreationDialog;
|
||||
EnchantingDialog* mEnchantingDialog;
|
||||
TrainingWindow* mTrainingWindow;
|
||||
std::unique_ptr<TranslationData::Storage> mTranslationDataStorage;
|
||||
|
||||
CharacterCreation* mCharGen;
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
#include <components/esm/records.hpp>
|
||||
#include "store.hpp"
|
||||
|
||||
namespace MWWorld
|
||||
namespace MWWorld
|
||||
{
|
||||
class ESMStore
|
||||
{
|
||||
@ -158,7 +158,7 @@ namespace MWWorld
|
||||
std::ostringstream id;
|
||||
id << "$dynamic" << mDynamicCount++;
|
||||
record.mId = id.str();
|
||||
|
||||
|
||||
T *ptr = store.insert(record);
|
||||
for (iterator it = mStores.begin(); it != mStores.end(); ++it) {
|
||||
if (it->second == &store) {
|
||||
@ -179,7 +179,7 @@ namespace MWWorld
|
||||
|
||||
template <>
|
||||
inline const ESM::NPC *ESMStore::insert<ESM::NPC>(const ESM::NPC &npc) {
|
||||
if (StringUtils::ciEqual(npc.mId, "player")) {
|
||||
if (Misc::StringUtils::ciEqual(npc.mId, "player")) {
|
||||
return mNpcs.insert(npc);
|
||||
} else if (mNpcs.search(npc.mId) != 0) {
|
||||
std::ostringstream msg;
|
||||
@ -191,7 +191,7 @@ namespace MWWorld
|
||||
std::ostringstream id;
|
||||
id << "$dynamic" << mDynamicCount++;
|
||||
record.mId = id.str();
|
||||
|
||||
|
||||
ESM::NPC *ptr = mNpcs.insert(record);
|
||||
mIds[ptr->mId] = ESM::REC_NPC_;
|
||||
return ptr;
|
||||
|
@ -1,62 +1,12 @@
|
||||
#ifndef OPENMW_MWWORLD_RECORDCMP_H
|
||||
#define OPENMW_MWWORLD_RECORDCMP_H
|
||||
|
||||
#include <string>
|
||||
#include <cctype>
|
||||
#include <algorithm>
|
||||
|
||||
#include <components/esm/records.hpp>
|
||||
|
||||
namespace MWWorld
|
||||
{
|
||||
/// \todo move this to another location
|
||||
class StringUtils
|
||||
{
|
||||
struct ci
|
||||
{
|
||||
bool operator()(int x, int y) const {
|
||||
return std::tolower(x) < std::tolower(y);
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
static bool ciLess(const std::string &x, const std::string &y) {
|
||||
return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end(), ci());
|
||||
}
|
||||
|
||||
static bool ciEqual(const std::string &x, const std::string &y) {
|
||||
if (x.size() != y.size()) {
|
||||
return false;
|
||||
}
|
||||
std::string::const_iterator xit = x.begin();
|
||||
std::string::const_iterator yit = y.begin();
|
||||
for (; xit != x.end(); ++xit, ++yit) {
|
||||
if (std::tolower(*xit) != std::tolower(*yit)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Transforms input string to lower case w/o copy
|
||||
static std::string &toLower(std::string &inout) {
|
||||
std::transform(
|
||||
inout.begin(),
|
||||
inout.end(),
|
||||
inout.begin(),
|
||||
(int (*)(int)) std::tolower
|
||||
);
|
||||
return inout;
|
||||
}
|
||||
|
||||
/// Returns lower case copy of input string
|
||||
static std::string lowerCase(const std::string &in)
|
||||
{
|
||||
std::string out = in;
|
||||
return toLower(out);
|
||||
}
|
||||
};
|
||||
|
||||
struct RecordCmp
|
||||
{
|
||||
template <class T>
|
||||
@ -67,17 +17,17 @@ namespace MWWorld
|
||||
|
||||
template <>
|
||||
inline bool RecordCmp::operator()<ESM::Dialogue>(const ESM::Dialogue &x, const ESM::Dialogue &y) const {
|
||||
return StringUtils::ciLess(x.mId, y.mId);
|
||||
return Misc::StringUtils::ciLess(x.mId, y.mId);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline bool RecordCmp::operator()<ESM::Cell>(const ESM::Cell &x, const ESM::Cell &y) const {
|
||||
return StringUtils::ciLess(x.mName, y.mName);
|
||||
return Misc::StringUtils::ciLess(x.mName, y.mName);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline bool RecordCmp::operator()<ESM::Pathgrid>(const ESM::Pathgrid &x, const ESM::Pathgrid &y) const {
|
||||
return StringUtils::ciLess(x.mCell, y.mCell);
|
||||
return Misc::StringUtils::ciLess(x.mCell, y.mCell);
|
||||
}
|
||||
|
||||
} // end namespace
|
||||
|
@ -105,12 +105,12 @@ namespace MWWorld
|
||||
|
||||
const T *search(const std::string &id) const {
|
||||
T item;
|
||||
item.mId = StringUtils::lowerCase(id);
|
||||
item.mId = Misc::StringUtils::lowerCase(id);
|
||||
|
||||
typename std::vector<T>::const_iterator it =
|
||||
std::lower_bound(mStatic.begin(), mStatic.end(), item, RecordCmp());
|
||||
|
||||
if (it != mStatic.end() && StringUtils::ciEqual(it->mId, id)) {
|
||||
if (it != mStatic.end() && Misc::StringUtils::ciEqual(it->mId, id)) {
|
||||
return &(*it);
|
||||
}
|
||||
|
||||
@ -134,7 +134,7 @@ namespace MWWorld
|
||||
|
||||
void load(ESM::ESMReader &esm, const std::string &id) {
|
||||
mStatic.push_back(T());
|
||||
mStatic.back().mId = StringUtils::lowerCase(id);
|
||||
mStatic.back().mId = Misc::StringUtils::lowerCase(id);
|
||||
mStatic.back().load(esm);
|
||||
}
|
||||
|
||||
@ -169,7 +169,7 @@ namespace MWWorld
|
||||
}
|
||||
|
||||
T *insert(const T &item) {
|
||||
std::string id = StringUtils::lowerCase(item.mId);
|
||||
std::string id = Misc::StringUtils::lowerCase(item.mId);
|
||||
std::pair<typename Dynamic::iterator, bool> result =
|
||||
mDynamic.insert(std::pair<std::string, T>(id, item));
|
||||
T *ptr = &result.first->second;
|
||||
@ -182,7 +182,7 @@ namespace MWWorld
|
||||
}
|
||||
|
||||
bool erase(const std::string &id) {
|
||||
std::string key = StringUtils::lowerCase(id);
|
||||
std::string key = Misc::StringUtils::lowerCase(id);
|
||||
typename Dynamic::iterator it = mDynamic.find(key);
|
||||
if (it == mDynamic.end()) {
|
||||
return false;
|
||||
@ -213,7 +213,7 @@ namespace MWWorld
|
||||
inline void Store<ESM::Script>::load(ESM::ESMReader &esm, const std::string &id) {
|
||||
mStatic.push_back(ESM::Script());
|
||||
mStatic.back().load(esm);
|
||||
StringUtils::toLower(mStatic.back().mId);
|
||||
Misc::StringUtils::toLower(mStatic.back().mId);
|
||||
}
|
||||
|
||||
template <>
|
||||
@ -385,12 +385,12 @@ namespace MWWorld
|
||||
|
||||
const ESM::Cell *search(const std::string &id) const {
|
||||
ESM::Cell cell;
|
||||
cell.mName = StringUtils::lowerCase(id);
|
||||
cell.mName = Misc::StringUtils::lowerCase(id);
|
||||
|
||||
std::vector<ESM::Cell>::const_iterator it =
|
||||
std::lower_bound(mInt.begin(), mInt.end(), cell, RecordCmp());
|
||||
|
||||
if (it != mInt.end() && StringUtils::ciEqual(it->mName, id)) {
|
||||
if (it != mInt.end() && Misc::StringUtils::ciEqual(it->mName, id)) {
|
||||
return &(*it);
|
||||
}
|
||||
|
||||
@ -490,7 +490,7 @@ namespace MWWorld
|
||||
const ESM::Cell *searchExtByName(const std::string &id) const {
|
||||
std::vector<ESM::Cell *>::const_iterator it = mSharedExt.begin();
|
||||
for (; it != mSharedExt.end(); ++it) {
|
||||
if (StringUtils::ciEqual((*it)->mName, id)) {
|
||||
if (Misc::StringUtils::ciEqual((*it)->mName, id)) {
|
||||
return *it;
|
||||
}
|
||||
}
|
||||
@ -501,7 +501,7 @@ namespace MWWorld
|
||||
const ESM::Cell *searchExtByRegion(const std::string &id) const {
|
||||
std::vector<ESM::Cell *>::const_iterator it = mSharedExt.begin();
|
||||
for (; it != mSharedExt.end(); ++it) {
|
||||
if (StringUtils::ciEqual((*it)->mRegion, id)) {
|
||||
if (Misc::StringUtils::ciEqual((*it)->mRegion, id)) {
|
||||
return *it;
|
||||
}
|
||||
}
|
||||
@ -541,7 +541,7 @@ namespace MWWorld
|
||||
ptr = &result.first->second;
|
||||
mSharedExt.push_back(ptr);
|
||||
} else {
|
||||
std::string key = StringUtils::lowerCase(cell.mName);
|
||||
std::string key = Misc::StringUtils::lowerCase(cell.mName);
|
||||
|
||||
// duplicate insertions are avoided by search(ESM::Cell &)
|
||||
std::pair<DynamicInt::iterator, bool> result =
|
||||
@ -561,7 +561,7 @@ namespace MWWorld
|
||||
}
|
||||
|
||||
bool erase(const std::string &id) {
|
||||
std::string key = StringUtils::lowerCase(id);
|
||||
std::string key = Misc::StringUtils::lowerCase(id);
|
||||
DynamicInt::iterator it = mDynamicInt.find(key);
|
||||
|
||||
if (it == mDynamicInt.end()) {
|
||||
@ -691,7 +691,7 @@ namespace MWWorld
|
||||
pg.mCell = name;
|
||||
|
||||
iterator it = std::lower_bound(mIntBegin, mIntEnd, pg, RecordCmp());
|
||||
if (it != mIntEnd && StringUtils::ciEqual(it->mCell, name)) {
|
||||
if (it != mIntEnd && Misc::StringUtils::ciEqual(it->mCell, name)) {
|
||||
return &(*it);
|
||||
}
|
||||
return 0;
|
||||
|
@ -11,6 +11,8 @@
|
||||
#include "../mwrender/sky.hpp"
|
||||
#include "../mwrender/player.hpp"
|
||||
|
||||
#include "../mwclass/door.hpp"
|
||||
|
||||
#include "player.hpp"
|
||||
#include "manualref.hpp"
|
||||
#include "cellfunctors.hpp"
|
||||
@ -168,7 +170,7 @@ namespace MWWorld
|
||||
World::World (OEngine::Render::OgreRenderer& renderer,
|
||||
const Files::Collections& fileCollections,
|
||||
const std::string& master, const boost::filesystem::path& resDir, const boost::filesystem::path& cacheDir, bool newGame,
|
||||
const std::string& encoding, std::map<std::string,std::string> fallbackMap)
|
||||
const ToUTF8::FromType& encoding, std::map<std::string,std::string> fallbackMap)
|
||||
: mPlayer (0), mLocalScripts (mStore), mGlobalVariables (0),
|
||||
mSky (true), mCells (mStore, mEsm),
|
||||
mNumFacing(0)
|
||||
@ -237,7 +239,7 @@ namespace MWWorld
|
||||
MWWorld::Store<ESM::Region>::iterator it = regions.begin();
|
||||
for (; it != regions.end(); ++it)
|
||||
{
|
||||
if (MWWorld::StringUtils::ciEqual(cellName, it->mName))
|
||||
if (Misc::StringUtils::ciEqual(cellName, it->mName))
|
||||
{
|
||||
return mStore.get<ESM::Cell>().searchExtByRegion(it->mId);
|
||||
}
|
||||
@ -805,7 +807,7 @@ namespace MWWorld
|
||||
{
|
||||
bool update = false;
|
||||
|
||||
if (StringUtils::ciEqual(record.mId, "player"))
|
||||
if (Misc::StringUtils::ciEqual(record.mId, "player"))
|
||||
{
|
||||
static const char *sRaces[] =
|
||||
{
|
||||
@ -816,7 +818,7 @@ namespace MWWorld
|
||||
int i=0;
|
||||
|
||||
for (; sRaces[i]; ++i)
|
||||
if (StringUtils::ciEqual (sRaces[i], record.mRace))
|
||||
if (Misc::StringUtils::ciEqual (sRaces[i], record.mRace))
|
||||
break;
|
||||
|
||||
mGlobalVariables->setInt ("pcrace", sRaces[i] ? i+1 : 0);
|
||||
@ -825,9 +827,9 @@ namespace MWWorld
|
||||
mPlayer->getPlayer().get<ESM::NPC>()->mBase;
|
||||
|
||||
update = record.isMale() != player->isMale() ||
|
||||
!StringUtils::ciEqual(record.mRace, player->mRace) ||
|
||||
!StringUtils::ciEqual(record.mHead, player->mHead) ||
|
||||
!StringUtils::ciEqual(record.mHair, player->mHair);
|
||||
!Misc::StringUtils::ciEqual(record.mRace, player->mRace) ||
|
||||
!Misc::StringUtils::ciEqual(record.mHead, player->mHead) ||
|
||||
!Misc::StringUtils::ciEqual(record.mHair, player->mHair);
|
||||
}
|
||||
const ESM::NPC *ret = mStore.insert(record);
|
||||
if (update) {
|
||||
@ -1080,28 +1082,7 @@ namespace MWWorld
|
||||
if (ref.mRef.mTeleport)
|
||||
{
|
||||
World::DoorMarker newMarker;
|
||||
|
||||
std::string dest;
|
||||
if (ref.mRef.mDestCell != "")
|
||||
{
|
||||
// door leads to an interior, use interior name
|
||||
dest = ref.mRef.mDestCell;
|
||||
}
|
||||
else
|
||||
{
|
||||
// door leads to exterior, use cell name (if any), otherwise translated region name
|
||||
int x,y;
|
||||
positionToIndex (ref.mRef.mDoorDest.pos[0], ref.mRef.mDoorDest.pos[1], x, y);
|
||||
const ESM::Cell* cell = mStore.get<ESM::Cell>().find(x,y);
|
||||
if (cell->mName != "")
|
||||
dest = cell->mName;
|
||||
else
|
||||
{
|
||||
dest = mStore.get<ESM::Region>().find(cell->mRegion)->mName;
|
||||
}
|
||||
}
|
||||
|
||||
newMarker.name = dest;
|
||||
newMarker.name = MWClass::Door::getDestination(ref);
|
||||
|
||||
ESM::Position pos = ref.mData.getPosition ();
|
||||
|
||||
|
@ -95,7 +95,7 @@ namespace MWWorld
|
||||
World (OEngine::Render::OgreRenderer& renderer,
|
||||
const Files::Collections& fileCollections,
|
||||
const std::string& master, const boost::filesystem::path& resDir, const boost::filesystem::path& cacheDir, bool newGame,
|
||||
const std::string& encoding, std::map<std::string,std::string> fallbackMap);
|
||||
const ToUTF8::FromType& encoding, std::map<std::string,std::string> fallbackMap);
|
||||
|
||||
virtual ~World();
|
||||
|
||||
@ -228,7 +228,7 @@ namespace MWWorld
|
||||
virtual void rotateObject (const Ptr& ptr,float x,float y,float z, bool adjust = false);
|
||||
|
||||
virtual void safePlaceObject(const MWWorld::Ptr& ptr,MWWorld::CellStore &Cell,ESM::Position pos);
|
||||
///< place an object in a "safe" location (ie not in the void, etc). Makes a copy of the Ptr.
|
||||
///< place an object in a "safe" location (ie not in the void, etc). Makes a copy of the Ptr.
|
||||
|
||||
virtual void indexToPosition (int cellX, int cellY, float &x, float &y, bool centre = false)
|
||||
const;
|
||||
@ -323,7 +323,7 @@ namespace MWWorld
|
||||
}
|
||||
|
||||
virtual void renderPlayer();
|
||||
|
||||
|
||||
virtual void setupExternalRendering (MWRender::ExternalRendering& rendering);
|
||||
|
||||
virtual int canRest();
|
||||
|
@ -62,6 +62,10 @@ add_component_dir (interpreter
|
||||
miscopcodes opcodes runtime scriptopcodes spatialopcodes types
|
||||
)
|
||||
|
||||
add_component_dir (translation_data
|
||||
translation_data
|
||||
)
|
||||
|
||||
include_directories(${BULLET_INCLUDE_DIRS})
|
||||
|
||||
add_library(components STATIC ${COMPONENT_FILES})
|
||||
|
@ -347,21 +347,9 @@ void ESMReader::fail(const std::string &msg)
|
||||
throw std::runtime_error(ss.str());
|
||||
}
|
||||
|
||||
void ESMReader::setEncoding(const std::string& encoding)
|
||||
void ESMReader::setEncoding(const ToUTF8::FromType& encoding)
|
||||
{
|
||||
if (encoding == "win1250")
|
||||
{
|
||||
mEncoding = ToUTF8::WINDOWS_1250;
|
||||
}
|
||||
else if (encoding == "win1251")
|
||||
{
|
||||
mEncoding = ToUTF8::WINDOWS_1251;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Default Latin encoding
|
||||
mEncoding = ToUTF8::WINDOWS_1252;
|
||||
}
|
||||
mEncoding = encoding;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -234,7 +234,7 @@ public:
|
||||
void fail(const std::string &msg);
|
||||
|
||||
/// Sets font encoding for ESM strings
|
||||
void setEncoding(const std::string& encoding);
|
||||
void setEncoding(const ToUTF8::FromType& encoding);
|
||||
|
||||
private:
|
||||
Ogre::DataStreamPtr mEsm;
|
||||
|
@ -1,8 +1,58 @@
|
||||
#ifndef MISC_STRINGOPS_H
|
||||
#define MISC_STRINGOPS_H
|
||||
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
|
||||
namespace Misc
|
||||
{
|
||||
class StringUtils
|
||||
{
|
||||
struct ci
|
||||
{
|
||||
bool operator()(int x, int y) const {
|
||||
return std::tolower(x) < std::tolower(y);
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
static bool ciLess(const std::string &x, const std::string &y) {
|
||||
return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end(), ci());
|
||||
}
|
||||
|
||||
static bool ciEqual(const std::string &x, const std::string &y) {
|
||||
if (x.size() != y.size()) {
|
||||
return false;
|
||||
}
|
||||
std::string::const_iterator xit = x.begin();
|
||||
std::string::const_iterator yit = y.begin();
|
||||
for (; xit != x.end(); ++xit, ++yit) {
|
||||
if (std::tolower(*xit) != std::tolower(*yit)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Transforms input string to lower case w/o copy
|
||||
static std::string &toLower(std::string &inout) {
|
||||
std::transform(
|
||||
inout.begin(),
|
||||
inout.end(),
|
||||
inout.begin(),
|
||||
(int (*)(int)) std::tolower
|
||||
);
|
||||
return inout;
|
||||
}
|
||||
|
||||
/// Returns lower case copy of input string
|
||||
static std::string lowerCase(const std::string &in)
|
||||
{
|
||||
std::string out = in;
|
||||
return toLower(out);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/// Returns true if str1 begins with substring str2
|
||||
bool begins(const char* str1, const char* str2);
|
||||
|
@ -357,3 +357,23 @@ std::string ToUTF8::getLegacyEnc(ToUTF8::FromType to)
|
||||
// Return a string
|
||||
return std::string(&output[0], outlen);
|
||||
}
|
||||
|
||||
ToUTF8::FromType ToUTF8::CalculateEncoding(const std::string& encodingName)
|
||||
{
|
||||
if (encodingName == "win1250")
|
||||
return ToUTF8::WINDOWS_1250;
|
||||
else if (encodingName == "win1251")
|
||||
return ToUTF8::WINDOWS_1251;
|
||||
else
|
||||
return ToUTF8::WINDOWS_1252;
|
||||
}
|
||||
|
||||
std::string ToUTF8::EncodingUsingMessage(const std::string& encodingName)
|
||||
{
|
||||
if (encodingName == "win1250")
|
||||
return "Using Central and Eastern European font encoding.";
|
||||
else if (encodingName == "win1251")
|
||||
return "Using Cyrillic font encoding.";
|
||||
else
|
||||
return "Using default (English) font encoding.";
|
||||
}
|
||||
|
@ -22,6 +22,9 @@ namespace ToUTF8
|
||||
// page.
|
||||
std::string getUtf8(FromType from);
|
||||
std::string getLegacyEnc(FromType to);
|
||||
|
||||
FromType CalculateEncoding(const std::string& encodingName);
|
||||
std::string EncodingUsingMessage(const std::string& encodingName);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
104
components/translation_data/translation_data.cpp
Normal file
104
components/translation_data/translation_data.cpp
Normal file
@ -0,0 +1,104 @@
|
||||
#include "translation_data.hpp"
|
||||
#include <components/misc/stringops.hpp>
|
||||
|
||||
#include <fstream>
|
||||
|
||||
namespace TranslationData
|
||||
{
|
||||
void Storage::loadTranslationData(const Files::Collections& dataFileCollections,
|
||||
const std::string& esmFileName)
|
||||
{
|
||||
std::string esmNameNoExtension(Misc::StringUtils::lowerCase(esmFileName));
|
||||
//changing the extension
|
||||
size_t dotPos = esmNameNoExtension.rfind('.');
|
||||
if (dotPos != std::string::npos)
|
||||
esmNameNoExtension.resize(dotPos);
|
||||
|
||||
loadData(mCellNamesTranslations, esmNameNoExtension, ".cel", dataFileCollections);
|
||||
loadData(mPhraseForms, esmNameNoExtension, ".top", dataFileCollections);
|
||||
loadData(mTopicIDs, esmNameNoExtension, ".mrk", dataFileCollections);
|
||||
}
|
||||
|
||||
void Storage::loadData(ContainerType& container,
|
||||
const std::string& fileNameNoExtension,
|
||||
const std::string& extension,
|
||||
const Files::Collections& dataFileCollections)
|
||||
{
|
||||
std::string path;
|
||||
try
|
||||
{
|
||||
path = dataFileCollections.getCollection(extension).getPath(fileNameNoExtension + extension).string();
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
//no file
|
||||
return;
|
||||
}
|
||||
|
||||
std::ifstream stream(path);
|
||||
if (stream.is_open())
|
||||
{
|
||||
loadDataFromStream(container, stream);
|
||||
stream.close();
|
||||
}
|
||||
}
|
||||
|
||||
void Storage::loadDataFromStream(ContainerType& container, std::istream& stream)
|
||||
{
|
||||
std::string line;
|
||||
while (!stream.eof())
|
||||
{
|
||||
std::getline( stream, line );
|
||||
if (!line.empty() && *line.rbegin() == '\r')
|
||||
line.resize(line.size() - 1);
|
||||
|
||||
if (!line.empty())
|
||||
{
|
||||
char* buffer = ToUTF8::getBuffer(line.size() + 1);
|
||||
//buffer has at least line.size() + 1 bytes, so it must be safe
|
||||
strcpy(buffer, line.c_str());
|
||||
line = ToUTF8::getUtf8(mEncoding);
|
||||
|
||||
size_t tab_pos = line.find('\t');
|
||||
if (tab_pos != std::string::npos && tab_pos > 0 && tab_pos < line.size() - 1)
|
||||
{
|
||||
std::string key = line.substr(0, tab_pos);
|
||||
std::string value = line.substr(tab_pos + 1);
|
||||
|
||||
if (!key.empty() && !value.empty())
|
||||
container.insert(std::make_pair(key, value));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string Storage::translateCellName(const std::string& cellName) const
|
||||
{
|
||||
auto entry = mCellNamesTranslations.find(cellName);
|
||||
|
||||
if (entry == mCellNamesTranslations.end())
|
||||
return cellName;
|
||||
|
||||
return entry->second;
|
||||
}
|
||||
|
||||
std::string Storage::topicID(const std::string& phrase) const
|
||||
{
|
||||
std::string result;
|
||||
|
||||
//seeking for the standard phrase form
|
||||
auto phraseFormsIterator = mPhraseForms.find(phrase);
|
||||
if (phraseFormsIterator != mPhraseForms.end())
|
||||
result = phraseFormsIterator->second;
|
||||
else
|
||||
result = phrase;
|
||||
|
||||
|
||||
//seeking for the topic ID
|
||||
auto topicIDIterator = mTopicIDs.find(result);
|
||||
if (topicIDIterator != mTopicIDs.end())
|
||||
result = topicIDIterator->second;
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
36
components/translation_data/translation_data.hpp
Normal file
36
components/translation_data/translation_data.hpp
Normal file
@ -0,0 +1,36 @@
|
||||
#ifndef COMPONENTS_TRANSLATION_DATA_H
|
||||
#define COMPONENTS_TRANSLATION_DATA_H
|
||||
|
||||
#include <components/to_utf8/to_utf8.hpp>
|
||||
#include <components/files/collections.hpp>
|
||||
|
||||
namespace TranslationData
|
||||
{
|
||||
class Storage
|
||||
{
|
||||
public:
|
||||
Storage(const ToUTF8::FromType& encoding) : mEncoding(encoding) {}
|
||||
|
||||
void loadTranslationData(const Files::Collections& dataFileCollections,
|
||||
const std::string& esmFileName);
|
||||
|
||||
std::string translateCellName(const std::string& cellName) const;
|
||||
std::string topicID(const std::string& phrase) const;
|
||||
|
||||
private:
|
||||
typedef std::map<std::string, std::string> ContainerType;
|
||||
|
||||
void loadData(ContainerType& container,
|
||||
const std::string& fileNameNoExtension,
|
||||
const std::string& extension,
|
||||
const Files::Collections& dataFileCollections);
|
||||
|
||||
void loadDataFromStream(ContainerType& container, std::istream& stream);
|
||||
|
||||
|
||||
ToUTF8::FromType mEncoding;
|
||||
std::map<std::string, std::string> mCellNamesTranslations, mTopicIDs, mPhraseForms;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user