mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-02-21 14:09:39 +00:00
Merge remote-tracking branch 'lazydev/master'
This commit is contained in:
commit
4c28f3211b
24 changed files with 344 additions and 183 deletions
|
@ -59,7 +59,7 @@ struct Arguments
|
||||||
std::string outname;
|
std::string outname;
|
||||||
|
|
||||||
std::vector<std::string> types;
|
std::vector<std::string> types;
|
||||||
|
|
||||||
ESMData data;
|
ESMData data;
|
||||||
ESM::ESMReader reader;
|
ESM::ESMReader reader;
|
||||||
ESM::ESMWriter writer;
|
ESM::ESMWriter writer;
|
||||||
|
@ -74,7 +74,7 @@ bool parseOptions (int argc, char** argv, Arguments &info)
|
||||||
("version,v", "print version information and quit.")
|
("version,v", "print version information and quit.")
|
||||||
("raw,r", "Show an unformatted list of all records and subrecords.")
|
("raw,r", "Show an unformatted list of all records and subrecords.")
|
||||||
// The intention is that this option would interact better
|
// 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> >(),
|
("type,t", bpo::value< std::vector<std::string> >(),
|
||||||
"Show only records of this type (four character record code). May "
|
"Show only records of this type (four character record code). May "
|
||||||
"be specified multiple times. Only affects dump mode.")
|
"be specified multiple times. Only affects dump mode.")
|
||||||
|
@ -262,7 +262,7 @@ void printRaw(ESM::ESMReader &esm)
|
||||||
int load(Arguments& info)
|
int load(Arguments& info)
|
||||||
{
|
{
|
||||||
ESM::ESMReader& esm = info.reader;
|
ESM::ESMReader& esm = info.reader;
|
||||||
esm.setEncoding(info.encoding);
|
esm.setEncoding(ToUTF8::CalculateEncoding(info.encoding));
|
||||||
|
|
||||||
std::string filename = info.filename;
|
std::string filename = info.filename;
|
||||||
std::cout << "Loading file: " << filename << std::endl;
|
std::cout << "Loading file: " << filename << std::endl;
|
||||||
|
@ -321,7 +321,7 @@ int load(Arguments& info)
|
||||||
if (info.types.size() > 0)
|
if (info.types.size() > 0)
|
||||||
{
|
{
|
||||||
std::vector<std::string>::iterator match;
|
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());
|
n.toString());
|
||||||
if (match == info.types.end()) interested = false;
|
if (match == info.types.end()) interested = false;
|
||||||
}
|
}
|
||||||
|
@ -425,7 +425,7 @@ int clone(Arguments& info)
|
||||||
if (++i % 3 == 0)
|
if (++i % 3 == 0)
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i % 3 != 0)
|
if (i % 3 != 0)
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
|
|
||||||
|
@ -450,7 +450,7 @@ int clone(Arguments& info)
|
||||||
for (Records::iterator it = records.begin(); it != records.end() && i > 0; ++it)
|
for (Records::iterator it = records.begin(); it != records.end() && i > 0; ++it)
|
||||||
{
|
{
|
||||||
EsmTool::RecordBase *record = *it;
|
EsmTool::RecordBase *record = *it;
|
||||||
|
|
||||||
name.val = record->getType().val;
|
name.val = record->getType().val;
|
||||||
|
|
||||||
esm.startRecord(name.toString(), record->getFlags());
|
esm.startRecord(name.toString(), record->getFlags());
|
||||||
|
@ -485,7 +485,7 @@ int clone(Arguments& info)
|
||||||
std::cerr << "\r" << perc << "%";
|
std::cerr << "\r" << perc << "%";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << "\rDone!" << std::endl;
|
std::cout << "\rDone!" << std::endl;
|
||||||
|
|
||||||
esm.close();
|
esm.close();
|
||||||
|
@ -513,7 +513,7 @@ int comp(Arguments& info)
|
||||||
|
|
||||||
fileOne.encoding = info.encoding;
|
fileOne.encoding = info.encoding;
|
||||||
fileTwo.encoding = info.encoding;
|
fileTwo.encoding = info.encoding;
|
||||||
|
|
||||||
fileOne.filename = info.filename;
|
fileOne.filename = info.filename;
|
||||||
fileTwo.filename = info.outname;
|
fileTwo.filename = info.outname;
|
||||||
|
|
||||||
|
@ -534,9 +534,9 @@ int comp(Arguments& info)
|
||||||
std::cout << "Not equal, different amount of records." << std::endl;
|
std::cout << "Not equal, different amount of records." << std::endl;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -272,7 +272,7 @@ void DataFilesModel::addMasters(const QString &path)
|
||||||
foreach (const QString &path, dir.entryList()) {
|
foreach (const QString &path, dir.entryList()) {
|
||||||
try {
|
try {
|
||||||
ESM::ESMReader fileReader;
|
ESM::ESMReader fileReader;
|
||||||
fileReader.setEncoding(mEncoding.toStdString());
|
fileReader.setEncoding(ToUTF8::CalculateEncoding(mEncoding.toStdString()));
|
||||||
fileReader.open(dir.absoluteFilePath(path).toStdString());
|
fileReader.open(dir.absoluteFilePath(path).toStdString());
|
||||||
|
|
||||||
ESM::ESMReader::MasterList mlist = fileReader.getMasters();
|
ESM::ESMReader::MasterList mlist = fileReader.getMasters();
|
||||||
|
@ -335,7 +335,7 @@ void DataFilesModel::addPlugins(const QString &path)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
ESM::ESMReader fileReader;
|
ESM::ESMReader fileReader;
|
||||||
fileReader.setEncoding(mEncoding.toStdString());
|
fileReader.setEncoding(ToUTF8::CalculateEncoding(mEncoding.toStdString()));
|
||||||
fileReader.open(dir.absoluteFilePath(path).toStdString());
|
fileReader.open(dir.absoluteFilePath(path).toStdString());
|
||||||
|
|
||||||
ESM::ESMReader::MasterList mlist = fileReader.getMasters();
|
ESM::ESMReader::MasterList mlist = fileReader.getMasters();
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
#include <components/bsa/bsa_archive.hpp>
|
#include <components/bsa/bsa_archive.hpp>
|
||||||
#include <components/files/configurationmanager.hpp>
|
#include <components/files/configurationmanager.hpp>
|
||||||
|
#include <components/translation/translation.hpp>
|
||||||
#include <components/nifoverrides/nifoverrides.hpp>
|
#include <components/nifoverrides/nifoverrides.hpp>
|
||||||
|
|
||||||
#include <components/nifbullet/bullet_nif_loader.hpp>
|
#include <components/nifbullet/bullet_nif_loader.hpp>
|
||||||
|
@ -334,12 +335,16 @@ void OMW::Engine::go()
|
||||||
mEnvironment.setWorld (new MWWorld::World (*mOgre, mFileCollections, mMaster,
|
mEnvironment.setWorld (new MWWorld::World (*mOgre, mFileCollections, mMaster,
|
||||||
mResDir, mCfgMgr.getCachePath(), mNewGame, mEncoding, mFallbackMap));
|
mResDir, mCfgMgr.getCachePath(), mNewGame, mEncoding, mFallbackMap));
|
||||||
|
|
||||||
|
//Load translation data
|
||||||
|
std::auto_ptr<TranslationData::Storage> translationDataStorage(new TranslationData::Storage(mEncoding));
|
||||||
|
translationDataStorage->loadTranslationData(mFileCollections, mMaster);
|
||||||
|
|
||||||
// Create window manager - this manages all the MW-specific GUI windows
|
// Create window manager - this manages all the MW-specific GUI windows
|
||||||
MWScript::registerExtensions (mExtensions);
|
MWScript::registerExtensions (mExtensions);
|
||||||
|
|
||||||
mEnvironment.setWindowManager (new MWGui::WindowManager(
|
mEnvironment.setWindowManager (new MWGui::WindowManager(
|
||||||
mExtensions, mFpsLevel, mNewGame, mOgre, mCfgMgr.getLogPath().string() + std::string("/"),
|
mExtensions, mFpsLevel, mNewGame, mOgre, mCfgMgr.getLogPath().string() + std::string("/"),
|
||||||
mCfgMgr.getCachePath ().string(), mScriptConsoleMode));
|
mCfgMgr.getCachePath ().string(), mScriptConsoleMode, translationDataStorage.release()));
|
||||||
|
|
||||||
// Create sound system
|
// Create sound system
|
||||||
mEnvironment.setSoundManager (new MWSound::SoundManager(mUseSound));
|
mEnvironment.setSoundManager (new MWSound::SoundManager(mUseSound));
|
||||||
|
@ -487,7 +492,7 @@ void OMW::Engine::showFPS(int level)
|
||||||
mFpsLevel = level;
|
mFpsLevel = level;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OMW::Engine::setEncoding(const std::string& encoding)
|
void OMW::Engine::setEncoding(const ToUTF8::FromType& encoding)
|
||||||
{
|
{
|
||||||
mEncoding = encoding;
|
mEncoding = encoding;
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,7 +59,7 @@ namespace OMW
|
||||||
class Engine : private Ogre::FrameListener
|
class Engine : private Ogre::FrameListener
|
||||||
{
|
{
|
||||||
MWBase::Environment mEnvironment;
|
MWBase::Environment mEnvironment;
|
||||||
std::string mEncoding;
|
ToUTF8::FromType mEncoding;
|
||||||
Files::PathContainer mDataDirs;
|
Files::PathContainer mDataDirs;
|
||||||
boost::filesystem::path mResDir;
|
boost::filesystem::path mResDir;
|
||||||
OEngine::Render::OgreRenderer *mOgre;
|
OEngine::Render::OgreRenderer *mOgre;
|
||||||
|
@ -154,7 +154,7 @@ namespace OMW
|
||||||
void setCompileAll (bool all);
|
void setCompileAll (bool all);
|
||||||
|
|
||||||
/// Font encoding
|
/// Font encoding
|
||||||
void setEncoding(const std::string& encoding);
|
void setEncoding(const ToUTF8::FromType& encoding);
|
||||||
|
|
||||||
void setAnimationVerbose(bool animverbose);
|
void setAnimationVerbose(bool animverbose);
|
||||||
|
|
||||||
|
|
|
@ -181,21 +181,8 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat
|
||||||
|
|
||||||
// Font encoding settings
|
// Font encoding settings
|
||||||
std::string encoding(variables["encoding"].as<std::string>());
|
std::string encoding(variables["encoding"].as<std::string>());
|
||||||
if (encoding == "win1250")
|
std::cout << ToUTF8::EncodingUsingMessage(encoding) << std::endl;
|
||||||
{
|
engine.setEncoding(ToUTF8::CalculateEncoding(encoding));
|
||||||
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");
|
|
||||||
}
|
|
||||||
|
|
||||||
// directory settings
|
// directory settings
|
||||||
engine.enableFSStrict(variables["fs-strict"].as<bool>());
|
engine.enableFSStrict(variables["fs-strict"].as<bool>());
|
||||||
|
|
|
@ -204,33 +204,10 @@ namespace MWClass
|
||||||
|
|
||||||
std::string text;
|
std::string text;
|
||||||
|
|
||||||
const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
|
|
||||||
|
|
||||||
if (ref->mRef.mTeleport)
|
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#{sTo}";
|
||||||
text += "\n"+dest;
|
text += "\n" + getDestination(*ref);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ref->mRef.mLockLevel > 0)
|
if (ref->mRef.mLockLevel > 0)
|
||||||
|
@ -246,6 +223,37 @@ namespace MWClass
|
||||||
return info;
|
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
|
MWWorld::Ptr
|
||||||
Door::copyToCellImpl(const MWWorld::Ptr &ptr, MWWorld::CellStore &cell) const
|
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;
|
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.
|
///< @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;
|
virtual void lock (const MWWorld::Ptr& ptr, int lockLevel) const;
|
||||||
///< Lock object
|
///< Lock object
|
||||||
|
|
||||||
|
|
|
@ -319,7 +319,7 @@ void HUD::setCellName(const std::string& cellName)
|
||||||
mCellNameTimer = 5.0f;
|
mCellNameTimer = 5.0f;
|
||||||
mCellName = cellName;
|
mCellName = cellName;
|
||||||
|
|
||||||
mCellNameBox->setCaption(mCellName);
|
mCellNameBox->setCaptionWithReplacing("#{sCell=" + mCellName + "}");
|
||||||
mCellNameBox->setVisible(mMapVisible);
|
mCellNameBox->setVisible(mMapVisible);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -299,7 +299,7 @@ MapWindow::~MapWindow()
|
||||||
|
|
||||||
void MapWindow::setCellName(const std::string& cellName)
|
void MapWindow::setCellName(const std::string& cellName)
|
||||||
{
|
{
|
||||||
setTitle(cellName);
|
setTitle("#{sCell=" + cellName + "}");
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapWindow::addVisitedLocation(const std::string& name, int x, int y)
|
void MapWindow::addVisitedLocation(const std::string& name, int x, int y)
|
||||||
|
|
|
@ -55,7 +55,8 @@ using namespace MWGui;
|
||||||
|
|
||||||
WindowManager::WindowManager(
|
WindowManager::WindowManager(
|
||||||
const Compiler::Extensions& extensions, int fpsLevel, bool newGame, OEngine::Render::OgreRenderer *mOgre,
|
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)
|
: mGuiManager(NULL)
|
||||||
, mHud(NULL)
|
, mHud(NULL)
|
||||||
, mMap(NULL)
|
, mMap(NULL)
|
||||||
|
@ -104,6 +105,7 @@ WindowManager::WindowManager(
|
||||||
, mCrosshairEnabled(Settings::Manager::getBool ("crosshair", "HUD"))
|
, mCrosshairEnabled(Settings::Manager::getBool ("crosshair", "HUD"))
|
||||||
, mSubtitlesEnabled(Settings::Manager::getBool ("subtitles", "GUI"))
|
, mSubtitlesEnabled(Settings::Manager::getBool ("subtitles", "GUI"))
|
||||||
, mHudEnabled(true)
|
, mHudEnabled(true)
|
||||||
|
, mTranslationDataStorage(pTranslationDataStorage)
|
||||||
{
|
{
|
||||||
|
|
||||||
// Set up the GUI system
|
// Set up the GUI system
|
||||||
|
@ -612,7 +614,7 @@ void WindowManager::changeCell(MWWorld::Ptr::CellStore* cell)
|
||||||
if (cell->mCell->mName != "")
|
if (cell->mCell->mName != "")
|
||||||
{
|
{
|
||||||
name = 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
|
else
|
||||||
{
|
{
|
||||||
|
@ -722,13 +724,25 @@ void WindowManager::setDragDrop(bool dragDrop)
|
||||||
|
|
||||||
void WindowManager::onRetrieveTag(const MyGUI::UString& _tag, MyGUI::UString& _result)
|
void WindowManager::onRetrieveTag(const MyGUI::UString& _tag, MyGUI::UString& _result)
|
||||||
{
|
{
|
||||||
const ESM::GameSetting *setting =
|
std::string tag(_tag);
|
||||||
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find(_tag);
|
|
||||||
|
|
||||||
if (setting && setting->mType == ESM::VT_String)
|
std::string tokenToFind = "sCell=";
|
||||||
_result = setting->getString();
|
size_t tokenLength = tokenToFind.length();
|
||||||
|
|
||||||
|
if (tag.substr(0, tokenLength) == tokenToFind)
|
||||||
|
{
|
||||||
|
_result = mTranslationDataStorage->translateCellName(tag.substr(tokenLength));
|
||||||
|
}
|
||||||
else
|
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)
|
void WindowManager::processChangedSettings(const Settings::CategorySettingVector& changed)
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include <components/esm/loadclas.hpp>
|
#include <components/esm/loadclas.hpp>
|
||||||
|
#include <components/translation/translation.hpp>
|
||||||
|
|
||||||
#include "../mwbase/windowmanager.hpp"
|
#include "../mwbase/windowmanager.hpp"
|
||||||
|
|
||||||
|
@ -76,7 +77,8 @@ namespace MWGui
|
||||||
|
|
||||||
WindowManager(const Compiler::Extensions& extensions, int fpsLevel, bool newGame,
|
WindowManager(const Compiler::Extensions& extensions, int fpsLevel, bool newGame,
|
||||||
OEngine::Render::OgreRenderer *mOgre, const std::string& logpath,
|
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();
|
virtual ~WindowManager();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -250,6 +252,7 @@ namespace MWGui
|
||||||
SpellCreationDialog* mSpellCreationDialog;
|
SpellCreationDialog* mSpellCreationDialog;
|
||||||
EnchantingDialog* mEnchantingDialog;
|
EnchantingDialog* mEnchantingDialog;
|
||||||
TrainingWindow* mTrainingWindow;
|
TrainingWindow* mTrainingWindow;
|
||||||
|
std::auto_ptr<TranslationData::Storage> mTranslationDataStorage;
|
||||||
|
|
||||||
CharacterCreation* mCharGen;
|
CharacterCreation* mCharGen;
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
#include <components/esm/records.hpp>
|
#include <components/esm/records.hpp>
|
||||||
#include "store.hpp"
|
#include "store.hpp"
|
||||||
|
|
||||||
namespace MWWorld
|
namespace MWWorld
|
||||||
{
|
{
|
||||||
class ESMStore
|
class ESMStore
|
||||||
{
|
{
|
||||||
|
@ -158,7 +158,7 @@ namespace MWWorld
|
||||||
std::ostringstream id;
|
std::ostringstream id;
|
||||||
id << "$dynamic" << mDynamicCount++;
|
id << "$dynamic" << mDynamicCount++;
|
||||||
record.mId = id.str();
|
record.mId = id.str();
|
||||||
|
|
||||||
T *ptr = store.insert(record);
|
T *ptr = store.insert(record);
|
||||||
for (iterator it = mStores.begin(); it != mStores.end(); ++it) {
|
for (iterator it = mStores.begin(); it != mStores.end(); ++it) {
|
||||||
if (it->second == &store) {
|
if (it->second == &store) {
|
||||||
|
@ -179,7 +179,7 @@ namespace MWWorld
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
inline const ESM::NPC *ESMStore::insert<ESM::NPC>(const ESM::NPC &npc) {
|
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);
|
return mNpcs.insert(npc);
|
||||||
} else if (mNpcs.search(npc.mId) != 0) {
|
} else if (mNpcs.search(npc.mId) != 0) {
|
||||||
std::ostringstream msg;
|
std::ostringstream msg;
|
||||||
|
@ -191,7 +191,7 @@ namespace MWWorld
|
||||||
std::ostringstream id;
|
std::ostringstream id;
|
||||||
id << "$dynamic" << mDynamicCount++;
|
id << "$dynamic" << mDynamicCount++;
|
||||||
record.mId = id.str();
|
record.mId = id.str();
|
||||||
|
|
||||||
ESM::NPC *ptr = mNpcs.insert(record);
|
ESM::NPC *ptr = mNpcs.insert(record);
|
||||||
mIds[ptr->mId] = ESM::REC_NPC_;
|
mIds[ptr->mId] = ESM::REC_NPC_;
|
||||||
return ptr;
|
return ptr;
|
||||||
|
|
|
@ -1,62 +1,12 @@
|
||||||
#ifndef OPENMW_MWWORLD_RECORDCMP_H
|
#ifndef OPENMW_MWWORLD_RECORDCMP_H
|
||||||
#define OPENMW_MWWORLD_RECORDCMP_H
|
#define OPENMW_MWWORLD_RECORDCMP_H
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
#include <components/esm/records.hpp>
|
#include <components/esm/records.hpp>
|
||||||
|
|
||||||
namespace MWWorld
|
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
|
struct RecordCmp
|
||||||
{
|
{
|
||||||
template <class T>
|
template <class T>
|
||||||
|
@ -67,17 +17,17 @@ namespace MWWorld
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
inline bool RecordCmp::operator()<ESM::Dialogue>(const ESM::Dialogue &x, const ESM::Dialogue &y) const {
|
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 <>
|
template <>
|
||||||
inline bool RecordCmp::operator()<ESM::Cell>(const ESM::Cell &x, const ESM::Cell &y) const {
|
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 <>
|
template <>
|
||||||
inline bool RecordCmp::operator()<ESM::Pathgrid>(const ESM::Pathgrid &x, const ESM::Pathgrid &y) const {
|
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
|
} // end namespace
|
||||||
|
|
|
@ -105,12 +105,12 @@ namespace MWWorld
|
||||||
|
|
||||||
const T *search(const std::string &id) const {
|
const T *search(const std::string &id) const {
|
||||||
T item;
|
T item;
|
||||||
item.mId = StringUtils::lowerCase(id);
|
item.mId = Misc::StringUtils::lowerCase(id);
|
||||||
|
|
||||||
typename std::vector<T>::const_iterator it =
|
typename std::vector<T>::const_iterator it =
|
||||||
std::lower_bound(mStatic.begin(), mStatic.end(), item, RecordCmp());
|
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);
|
return &(*it);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,7 +134,7 @@ namespace MWWorld
|
||||||
|
|
||||||
void load(ESM::ESMReader &esm, const std::string &id) {
|
void load(ESM::ESMReader &esm, const std::string &id) {
|
||||||
mStatic.push_back(T());
|
mStatic.push_back(T());
|
||||||
mStatic.back().mId = StringUtils::lowerCase(id);
|
mStatic.back().mId = Misc::StringUtils::lowerCase(id);
|
||||||
mStatic.back().load(esm);
|
mStatic.back().load(esm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -169,7 +169,7 @@ namespace MWWorld
|
||||||
}
|
}
|
||||||
|
|
||||||
T *insert(const T &item) {
|
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 =
|
std::pair<typename Dynamic::iterator, bool> result =
|
||||||
mDynamic.insert(std::pair<std::string, T>(id, item));
|
mDynamic.insert(std::pair<std::string, T>(id, item));
|
||||||
T *ptr = &result.first->second;
|
T *ptr = &result.first->second;
|
||||||
|
@ -182,7 +182,7 @@ namespace MWWorld
|
||||||
}
|
}
|
||||||
|
|
||||||
bool erase(const std::string &id) {
|
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);
|
typename Dynamic::iterator it = mDynamic.find(key);
|
||||||
if (it == mDynamic.end()) {
|
if (it == mDynamic.end()) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -213,7 +213,7 @@ namespace MWWorld
|
||||||
inline void Store<ESM::Script>::load(ESM::ESMReader &esm, const std::string &id) {
|
inline void Store<ESM::Script>::load(ESM::ESMReader &esm, const std::string &id) {
|
||||||
mStatic.push_back(ESM::Script());
|
mStatic.push_back(ESM::Script());
|
||||||
mStatic.back().load(esm);
|
mStatic.back().load(esm);
|
||||||
StringUtils::toLower(mStatic.back().mId);
|
Misc::StringUtils::toLower(mStatic.back().mId);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
|
@ -385,12 +385,12 @@ namespace MWWorld
|
||||||
|
|
||||||
const ESM::Cell *search(const std::string &id) const {
|
const ESM::Cell *search(const std::string &id) const {
|
||||||
ESM::Cell cell;
|
ESM::Cell cell;
|
||||||
cell.mName = StringUtils::lowerCase(id);
|
cell.mName = Misc::StringUtils::lowerCase(id);
|
||||||
|
|
||||||
std::vector<ESM::Cell>::const_iterator it =
|
std::vector<ESM::Cell>::const_iterator it =
|
||||||
std::lower_bound(mInt.begin(), mInt.end(), cell, RecordCmp());
|
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);
|
return &(*it);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -490,7 +490,7 @@ namespace MWWorld
|
||||||
const ESM::Cell *searchExtByName(const std::string &id) const {
|
const ESM::Cell *searchExtByName(const std::string &id) const {
|
||||||
std::vector<ESM::Cell *>::const_iterator it = mSharedExt.begin();
|
std::vector<ESM::Cell *>::const_iterator it = mSharedExt.begin();
|
||||||
for (; it != mSharedExt.end(); ++it) {
|
for (; it != mSharedExt.end(); ++it) {
|
||||||
if (StringUtils::ciEqual((*it)->mName, id)) {
|
if (Misc::StringUtils::ciEqual((*it)->mName, id)) {
|
||||||
return *it;
|
return *it;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -501,7 +501,7 @@ namespace MWWorld
|
||||||
const ESM::Cell *searchExtByRegion(const std::string &id) const {
|
const ESM::Cell *searchExtByRegion(const std::string &id) const {
|
||||||
std::vector<ESM::Cell *>::const_iterator it = mSharedExt.begin();
|
std::vector<ESM::Cell *>::const_iterator it = mSharedExt.begin();
|
||||||
for (; it != mSharedExt.end(); ++it) {
|
for (; it != mSharedExt.end(); ++it) {
|
||||||
if (StringUtils::ciEqual((*it)->mRegion, id)) {
|
if (Misc::StringUtils::ciEqual((*it)->mRegion, id)) {
|
||||||
return *it;
|
return *it;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -541,7 +541,7 @@ namespace MWWorld
|
||||||
ptr = &result.first->second;
|
ptr = &result.first->second;
|
||||||
mSharedExt.push_back(ptr);
|
mSharedExt.push_back(ptr);
|
||||||
} else {
|
} else {
|
||||||
std::string key = StringUtils::lowerCase(cell.mName);
|
std::string key = Misc::StringUtils::lowerCase(cell.mName);
|
||||||
|
|
||||||
// duplicate insertions are avoided by search(ESM::Cell &)
|
// duplicate insertions are avoided by search(ESM::Cell &)
|
||||||
std::pair<DynamicInt::iterator, bool> result =
|
std::pair<DynamicInt::iterator, bool> result =
|
||||||
|
@ -561,7 +561,7 @@ namespace MWWorld
|
||||||
}
|
}
|
||||||
|
|
||||||
bool erase(const std::string &id) {
|
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);
|
DynamicInt::iterator it = mDynamicInt.find(key);
|
||||||
|
|
||||||
if (it == mDynamicInt.end()) {
|
if (it == mDynamicInt.end()) {
|
||||||
|
@ -691,7 +691,7 @@ namespace MWWorld
|
||||||
pg.mCell = name;
|
pg.mCell = name;
|
||||||
|
|
||||||
iterator it = std::lower_bound(mIntBegin, mIntEnd, pg, RecordCmp());
|
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 &(*it);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -11,6 +11,8 @@
|
||||||
#include "../mwrender/sky.hpp"
|
#include "../mwrender/sky.hpp"
|
||||||
#include "../mwrender/player.hpp"
|
#include "../mwrender/player.hpp"
|
||||||
|
|
||||||
|
#include "../mwclass/door.hpp"
|
||||||
|
|
||||||
#include "player.hpp"
|
#include "player.hpp"
|
||||||
#include "manualref.hpp"
|
#include "manualref.hpp"
|
||||||
#include "cellfunctors.hpp"
|
#include "cellfunctors.hpp"
|
||||||
|
@ -168,7 +170,7 @@ namespace MWWorld
|
||||||
World::World (OEngine::Render::OgreRenderer& renderer,
|
World::World (OEngine::Render::OgreRenderer& renderer,
|
||||||
const Files::Collections& fileCollections,
|
const Files::Collections& fileCollections,
|
||||||
const std::string& master, const boost::filesystem::path& resDir, const boost::filesystem::path& cacheDir, bool newGame,
|
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),
|
: mPlayer (0), mLocalScripts (mStore), mGlobalVariables (0),
|
||||||
mSky (true), mCells (mStore, mEsm),
|
mSky (true), mCells (mStore, mEsm),
|
||||||
mNumFacing(0)
|
mNumFacing(0)
|
||||||
|
@ -237,7 +239,7 @@ namespace MWWorld
|
||||||
MWWorld::Store<ESM::Region>::iterator it = regions.begin();
|
MWWorld::Store<ESM::Region>::iterator it = regions.begin();
|
||||||
for (; it != regions.end(); ++it)
|
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);
|
return mStore.get<ESM::Cell>().searchExtByRegion(it->mId);
|
||||||
}
|
}
|
||||||
|
@ -848,7 +850,7 @@ namespace MWWorld
|
||||||
{
|
{
|
||||||
bool update = false;
|
bool update = false;
|
||||||
|
|
||||||
if (StringUtils::ciEqual(record.mId, "player"))
|
if (Misc::StringUtils::ciEqual(record.mId, "player"))
|
||||||
{
|
{
|
||||||
static const char *sRaces[] =
|
static const char *sRaces[] =
|
||||||
{
|
{
|
||||||
|
@ -859,7 +861,7 @@ namespace MWWorld
|
||||||
int i=0;
|
int i=0;
|
||||||
|
|
||||||
for (; sRaces[i]; ++i)
|
for (; sRaces[i]; ++i)
|
||||||
if (StringUtils::ciEqual (sRaces[i], record.mRace))
|
if (Misc::StringUtils::ciEqual (sRaces[i], record.mRace))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
mGlobalVariables->setInt ("pcrace", sRaces[i] ? i+1 : 0);
|
mGlobalVariables->setInt ("pcrace", sRaces[i] ? i+1 : 0);
|
||||||
|
@ -868,9 +870,9 @@ namespace MWWorld
|
||||||
mPlayer->getPlayer().get<ESM::NPC>()->mBase;
|
mPlayer->getPlayer().get<ESM::NPC>()->mBase;
|
||||||
|
|
||||||
update = record.isMale() != player->isMale() ||
|
update = record.isMale() != player->isMale() ||
|
||||||
!StringUtils::ciEqual(record.mRace, player->mRace) ||
|
!Misc::StringUtils::ciEqual(record.mRace, player->mRace) ||
|
||||||
!StringUtils::ciEqual(record.mHead, player->mHead) ||
|
!Misc::StringUtils::ciEqual(record.mHead, player->mHead) ||
|
||||||
!StringUtils::ciEqual(record.mHair, player->mHair);
|
!Misc::StringUtils::ciEqual(record.mHair, player->mHair);
|
||||||
}
|
}
|
||||||
const ESM::NPC *ret = mStore.insert(record);
|
const ESM::NPC *ret = mStore.insert(record);
|
||||||
if (update) {
|
if (update) {
|
||||||
|
@ -1123,28 +1125,7 @@ namespace MWWorld
|
||||||
if (ref.mRef.mTeleport)
|
if (ref.mRef.mTeleport)
|
||||||
{
|
{
|
||||||
World::DoorMarker newMarker;
|
World::DoorMarker newMarker;
|
||||||
|
newMarker.name = MWClass::Door::getDestination(ref);
|
||||||
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;
|
|
||||||
|
|
||||||
ESM::Position pos = ref.mData.getPosition ();
|
ESM::Position pos = ref.mData.getPosition ();
|
||||||
|
|
||||||
|
|
|
@ -95,7 +95,7 @@ namespace MWWorld
|
||||||
World (OEngine::Render::OgreRenderer& renderer,
|
World (OEngine::Render::OgreRenderer& renderer,
|
||||||
const Files::Collections& fileCollections,
|
const Files::Collections& fileCollections,
|
||||||
const std::string& master, const boost::filesystem::path& resDir, const boost::filesystem::path& cacheDir, bool newGame,
|
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();
|
virtual ~World();
|
||||||
|
|
||||||
|
@ -232,7 +232,7 @@ namespace MWWorld
|
||||||
virtual void rotateObject (const Ptr& ptr,float x,float y,float z, bool adjust = false);
|
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);
|
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)
|
virtual void indexToPosition (int cellX, int cellY, float &x, float &y, bool centre = false)
|
||||||
const;
|
const;
|
||||||
|
@ -327,7 +327,7 @@ namespace MWWorld
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void renderPlayer();
|
virtual void renderPlayer();
|
||||||
|
|
||||||
virtual void setupExternalRendering (MWRender::ExternalRendering& rendering);
|
virtual void setupExternalRendering (MWRender::ExternalRendering& rendering);
|
||||||
|
|
||||||
virtual int canRest();
|
virtual int canRest();
|
||||||
|
|
|
@ -62,6 +62,10 @@ add_component_dir (interpreter
|
||||||
miscopcodes opcodes runtime scriptopcodes spatialopcodes types defines
|
miscopcodes opcodes runtime scriptopcodes spatialopcodes types defines
|
||||||
)
|
)
|
||||||
|
|
||||||
|
add_component_dir (translation
|
||||||
|
translation
|
||||||
|
)
|
||||||
|
|
||||||
include_directories(${BULLET_INCLUDE_DIRS})
|
include_directories(${BULLET_INCLUDE_DIRS})
|
||||||
|
|
||||||
add_library(components STATIC ${COMPONENT_FILES})
|
add_library(components STATIC ${COMPONENT_FILES})
|
||||||
|
|
|
@ -347,21 +347,9 @@ void ESMReader::fail(const std::string &msg)
|
||||||
throw std::runtime_error(ss.str());
|
throw std::runtime_error(ss.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ESMReader::setEncoding(const std::string& encoding)
|
void ESMReader::setEncoding(const ToUTF8::FromType& encoding)
|
||||||
{
|
{
|
||||||
if (encoding == "win1250")
|
mEncoding = encoding;
|
||||||
{
|
|
||||||
mEncoding = ToUTF8::WINDOWS_1250;
|
|
||||||
}
|
|
||||||
else if (encoding == "win1251")
|
|
||||||
{
|
|
||||||
mEncoding = ToUTF8::WINDOWS_1251;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Default Latin encoding
|
|
||||||
mEncoding = ToUTF8::WINDOWS_1252;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -234,7 +234,7 @@ public:
|
||||||
void fail(const std::string &msg);
|
void fail(const std::string &msg);
|
||||||
|
|
||||||
/// Sets font encoding for ESM strings
|
/// Sets font encoding for ESM strings
|
||||||
void setEncoding(const std::string& encoding);
|
void setEncoding(const ToUTF8::FromType& encoding);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ogre::DataStreamPtr mEsm;
|
Ogre::DataStreamPtr mEsm;
|
||||||
|
|
|
@ -1,8 +1,58 @@
|
||||||
#ifndef MISC_STRINGOPS_H
|
#ifndef MISC_STRINGOPS_H
|
||||||
#define MISC_STRINGOPS_H
|
#define MISC_STRINGOPS_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
namespace Misc
|
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
|
/// Returns true if str1 begins with substring str2
|
||||||
bool begins(const char* str1, const char* str2);
|
bool begins(const char* str1, const char* str2);
|
||||||
|
|
|
@ -357,3 +357,23 @@ std::string ToUTF8::getLegacyEnc(ToUTF8::FromType to)
|
||||||
// Return a string
|
// Return a string
|
||||||
return std::string(&output[0], outlen);
|
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.
|
// page.
|
||||||
std::string getUtf8(FromType from);
|
std::string getUtf8(FromType from);
|
||||||
std::string getLegacyEnc(FromType to);
|
std::string getLegacyEnc(FromType to);
|
||||||
|
|
||||||
|
FromType CalculateEncoding(const std::string& encodingName);
|
||||||
|
std::string EncodingUsingMessage(const std::string& encodingName);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
109
components/translation/translation.cpp
Normal file
109
components/translation/translation.cpp
Normal file
|
@ -0,0 +1,109 @@
|
||||||
|
#include "translation.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
|
||||||
|
{
|
||||||
|
std::map<std::string, std::string>::const_iterator 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
|
||||||
|
std::map<std::string, std::string>::const_iterator phraseFormsIterator =
|
||||||
|
mPhraseForms.find(phrase);
|
||||||
|
|
||||||
|
if (phraseFormsIterator != mPhraseForms.end())
|
||||||
|
result = phraseFormsIterator->second;
|
||||||
|
else
|
||||||
|
result = phrase;
|
||||||
|
|
||||||
|
|
||||||
|
//seeking for the topic ID
|
||||||
|
std::map<std::string, std::string>::const_iterator topicIDIterator =
|
||||||
|
mTopicIDs.find(result);
|
||||||
|
|
||||||
|
if (topicIDIterator != mTopicIDs.end())
|
||||||
|
result = topicIDIterator->second;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
36
components/translation/translation.hpp
Normal file
36
components/translation/translation.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 a new issue