Merge pull request #1 from OpenMW/master

Update from original
moveref
dteviot 10 years ago
commit 66040e3a7b

@ -12,8 +12,8 @@ set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/)
message(STATUS "Configuring OpenMW...") message(STATUS "Configuring OpenMW...")
set(OPENMW_VERSION_MAJOR 0) set(OPENMW_VERSION_MAJOR 0)
set(OPENMW_VERSION_MINOR 33) set(OPENMW_VERSION_MINOR 34)
set(OPENMW_VERSION_RELEASE 1) set(OPENMW_VERSION_RELEASE 0)
set(OPENMW_VERSION_COMMITHASH "") set(OPENMW_VERSION_COMMITHASH "")
set(OPENMW_VERSION_TAGHASH "") set(OPENMW_VERSION_TAGHASH "")

@ -137,6 +137,7 @@ void Launcher::DataFilesPage::saveSettings(const QString &profile)
void Launcher::DataFilesPage::removeProfile(const QString &profile) void Launcher::DataFilesPage::removeProfile(const QString &profile)
{ {
mLauncherSettings.remove(QString("Profiles/") + profile); mLauncherSettings.remove(QString("Profiles/") + profile);
mLauncherSettings.remove(QString("Profiles/") + profile + QString("/content"));
} }
QAbstractItemModel *Launcher::DataFilesPage::profilesModel() const QAbstractItemModel *Launcher::DataFilesPage::profilesModel() const
@ -153,9 +154,11 @@ void Launcher::DataFilesPage::setProfile(int index, bool savePrevious)
{ {
if (index >= -1 && index < ui.profilesComboBox->count()) if (index >= -1 && index < ui.profilesComboBox->count())
{ {
QString previous = ui.profilesComboBox->itemText(ui.profilesComboBox->currentIndex()); QString previous = mPreviousProfile;
QString current = ui.profilesComboBox->itemText(index); QString current = ui.profilesComboBox->itemText(index);
mPreviousProfile = current;
setProfile (previous, current, savePrevious); setProfile (previous, current, savePrevious);
} }
} }
@ -166,9 +169,6 @@ void Launcher::DataFilesPage::setProfile (const QString &previous, const QString
if (previous == current) if (previous == current)
return; return;
if (previous.isEmpty())
return;
if (!previous.isEmpty() && savePrevious) if (!previous.isEmpty() && savePrevious)
saveSettings (previous); saveSettings (previous);
@ -206,12 +206,16 @@ void Launcher::DataFilesPage::slotProfileRenamed(const QString &previous, const
void Launcher::DataFilesPage::slotProfileChanged(int index) void Launcher::DataFilesPage::slotProfileChanged(int index)
{ {
// in case the event was triggered externally
if (ui.profilesComboBox->currentIndex() != index)
ui.profilesComboBox->setCurrentIndex(index);
setProfile (index, true); setProfile (index, true);
} }
void Launcher::DataFilesPage::on_newProfileAction_triggered() void Launcher::DataFilesPage::on_newProfileAction_triggered()
{ {
if (!mProfileDialog->exec() == QDialog::Accepted) if (mProfileDialog->exec() != QDialog::Accepted)
return; return;
QString profile = mProfileDialog->lineEdit()->text(); QString profile = mProfileDialog->lineEdit()->text();
@ -221,9 +225,10 @@ void Launcher::DataFilesPage::on_newProfileAction_triggered()
saveSettings(); saveSettings();
mSelector->clearCheckStates(); mLauncherSettings.setValue(QString("Profiles/currentprofile"), profile);
addProfile(profile, true); addProfile(profile, true);
mSelector->clearCheckStates();
mSelector->setGameFile(); mSelector->setGameFile();
@ -237,10 +242,8 @@ void Launcher::DataFilesPage::addProfile (const QString &profile, bool setAsCurr
if (profile.isEmpty()) if (profile.isEmpty())
return; return;
if (ui.profilesComboBox->findText (profile) != -1) if (ui.profilesComboBox->findText (profile) == -1)
return; ui.profilesComboBox->addItem (profile);
ui.profilesComboBox->addItem (profile);
if (setAsCurrent) if (setAsCurrent)
setProfile (ui.profilesComboBox->findText (profile), false); setProfile (ui.profilesComboBox->findText (profile), false);
@ -256,10 +259,12 @@ void Launcher::DataFilesPage::on_deleteProfileAction_triggered()
if (!showDeleteMessageBox (profile)) if (!showDeleteMessageBox (profile))
return; return;
// Remove the profile from the combobox // this should work since the Default profile can't be deleted and is always index 0
ui.profilesComboBox->removeItem (ui.profilesComboBox->findText (profile)); int next = ui.profilesComboBox->currentIndex()-1;
ui.profilesComboBox->setCurrentIndex(next);
removeProfile(profile); removeProfile(profile);
ui.profilesComboBox->removeItem(ui.profilesComboBox->findText(profile));
saveSettings(); saveSettings();

@ -67,6 +67,8 @@ namespace Launcher
Config::GameSettings &mGameSettings; Config::GameSettings &mGameSettings;
Config::LauncherSettings &mLauncherSettings; Config::LauncherSettings &mLauncherSettings;
QString mPreviousProfile;
QString mDataLocal; QString mDataLocal;
void setPluginsCheckstates(Qt::CheckState state); void setPluginsCheckstates(Qt::CheckState state);

@ -11,7 +11,7 @@ opencs_units (model/doc
) )
opencs_units_noqt (model/doc opencs_units_noqt (model/doc
stage savingstate savingstages blacklist stage savingstate savingstages blacklist messages
) )
opencs_hdrs_noqt (model/doc opencs_hdrs_noqt (model/doc
@ -68,7 +68,7 @@ opencs_units (view/world
opencs_units_noqt (view/world opencs_units_noqt (view/world
subviews enumdelegate vartypedelegate recordstatusdelegate idtypedelegate datadisplaydelegate subviews enumdelegate vartypedelegate recordstatusdelegate idtypedelegate datadisplaydelegate
scripthighlighter idvalidator dialoguecreator physicssystem physicsmanager scripthighlighter idvalidator dialoguecreator physicssystem
) )
opencs_units (view/widget opencs_units (view/widget
@ -92,7 +92,7 @@ opencs_hdrs_noqt (view/render
opencs_units (view/tools opencs_units (view/tools
reportsubview reportsubview reporttable
) )
opencs_units_noqt (view/tools opencs_units_noqt (view/tools

@ -1,6 +1,8 @@
#include "editor.hpp" #include "editor.hpp"
#include <openengine/bullet/BulletShapeLoader.h>
#include <QApplication> #include <QApplication>
#include <QLocalServer> #include <QLocalServer>
#include <QLocalSocket> #include <QLocalSocket>
@ -21,8 +23,8 @@
CS::Editor::Editor (OgreInit::OgreInit& ogreInit) CS::Editor::Editor (OgreInit::OgreInit& ogreInit)
: mUserSettings (mCfgMgr), mOverlaySystem (0), mDocumentManager (mCfgMgr), : mUserSettings (mCfgMgr), mOverlaySystem (0), mDocumentManager (mCfgMgr),
mViewManager (mDocumentManager), mPhysicsManager (0), mViewManager (mDocumentManager),
mIpcServerName ("org.openmw.OpenCS"), mServer(NULL), mClientSocket(NULL) mIpcServerName ("org.openmw.OpenCS"), mServer(NULL), mClientSocket(NULL), mPid(""), mLock()
{ {
std::pair<Files::PathContainer, std::vector<std::string> > config = readConfig(); std::pair<Files::PathContainer, std::vector<std::string> > config = readConfig();
@ -34,7 +36,6 @@ CS::Editor::Editor (OgreInit::OgreInit& ogreInit)
ogreInit.init ((mCfgMgr.getUserConfigPath() / "opencsOgre.log").string()); ogreInit.init ((mCfgMgr.getUserConfigPath() / "opencsOgre.log").string());
mOverlaySystem.reset (new CSVRender::OverlaySystem); mOverlaySystem.reset (new CSVRender::OverlaySystem);
mPhysicsManager.reset (new CSVWorld::PhysicsManager);
Bsa::registerResources (Files::Collections (config.first, !mFsStrict), config.second, true, Bsa::registerResources (Files::Collections (config.first, !mFsStrict), config.second, true,
mFsStrict); mFsStrict);
@ -70,7 +71,15 @@ CS::Editor::Editor (OgreInit::OgreInit& ogreInit)
} }
CS::Editor::~Editor () CS::Editor::~Editor ()
{} {
mPidFile.close();
if(mServer && boost::filesystem::exists(mPid))
remove(mPid.string().c_str()); // ignore any error
// cleanup global resources used by OEngine
delete OEngine::Physic::BulletShapeManager::getSingletonPtr();
}
void CS::Editor::setupDataFiles (const Files::PathContainer& dataDirs) void CS::Editor::setupDataFiles (const Files::PathContainer& dataDirs)
{ {
@ -233,7 +242,53 @@ void CS::Editor::showSettings()
bool CS::Editor::makeIPCServer() bool CS::Editor::makeIPCServer()
{ {
mServer = new QLocalServer(this); try
{
mPid = boost::filesystem::temp_directory_path();
mPid /= "opencs.pid";
bool pidExists = boost::filesystem::exists(mPid);
mPidFile.open(mPid);
mLock = boost::interprocess::file_lock(mPid.string().c_str());
if(!mLock.try_lock())
{
std::cerr << "OpenCS already running." << std::endl;
return false;
}
#ifdef _WIN32
mPidFile << GetCurrentProcessId() << std::endl;
#else
mPidFile << getpid() << std::endl;
#endif
mServer = new QLocalServer(this);
if(pidExists)
{
// hack to get the temp directory path
mServer->listen("dummy");
QString fullPath = mServer->fullServerName();
mServer->close();
fullPath.remove(QRegExp("dummy$"));
fullPath += mIpcServerName;
if(boost::filesystem::exists(fullPath.toStdString().c_str()))
{
// TODO: compare pid of the current process with that in the file
std::cout << "Detected unclean shutdown." << std::endl;
// delete the stale file
if(remove(fullPath.toStdString().c_str()))
std::cerr << "ERROR removing stale connection file" << std::endl;
}
}
}
catch(const std::exception& e)
{
std::cerr << "ERROR " << e.what() << std::endl;
return false;
}
if(mServer->listen(mIpcServerName)) if(mServer->listen(mIpcServerName))
{ {
@ -242,6 +297,7 @@ bool CS::Editor::makeIPCServer()
} }
mServer->close(); mServer->close();
mServer = NULL;
return false; return false;
} }

@ -3,6 +3,9 @@
#include <memory> #include <memory>
#include <boost/interprocess/sync/file_lock.hpp>
#include <boost/filesystem/fstream.hpp>
#include <QObject> #include <QObject>
#include <QString> #include <QString>
#include <QLocalServer> #include <QLocalServer>
@ -28,7 +31,6 @@
#include "view/settings/dialog.hpp" #include "view/settings/dialog.hpp"
#include "view/render/overlaysystem.hpp" #include "view/render/overlaysystem.hpp"
#include "view/world/physicsmanager.hpp"
namespace OgreInit namespace OgreInit
{ {
@ -45,7 +47,6 @@ namespace CS
Files::ConfigurationManager mCfgMgr; Files::ConfigurationManager mCfgMgr;
CSMSettings::UserSettings mUserSettings; CSMSettings::UserSettings mUserSettings;
std::auto_ptr<CSVRender::OverlaySystem> mOverlaySystem; std::auto_ptr<CSVRender::OverlaySystem> mOverlaySystem;
std::auto_ptr<CSVWorld::PhysicsManager> mPhysicsManager;
CSMDoc::DocumentManager mDocumentManager; CSMDoc::DocumentManager mDocumentManager;
CSVDoc::ViewManager mViewManager; CSVDoc::ViewManager mViewManager;
CSVDoc::StartupDialogue mStartup; CSVDoc::StartupDialogue mStartup;
@ -54,6 +55,9 @@ namespace CS
CSVDoc::FileDialog mFileDialog; CSVDoc::FileDialog mFileDialog;
boost::filesystem::path mLocal; boost::filesystem::path mLocal;
boost::filesystem::path mResources; boost::filesystem::path mResources;
boost::filesystem::path mPid;
boost::interprocess::file_lock mLock;
boost::filesystem::ofstream mPidFile;
bool mFsStrict; bool mFsStrict;
void setupDataFiles (const Files::PathContainer& dataDirs); void setupDataFiles (const Files::PathContainer& dataDirs);

@ -83,7 +83,7 @@ int main(int argc, char *argv[])
if(!editor.makeIPCServer()) if(!editor.makeIPCServer())
{ {
editor.connectToIPCServer(); editor.connectToIPCServer();
// return 0; return 0;
} }
shinyFactory = editor.setupGraphics(); shinyFactory = editor.setupGraphics();

@ -9,6 +9,8 @@
#include <components/files/configurationmanager.hpp> #include <components/files/configurationmanager.hpp>
#endif #endif
#include "../../view/world/physicssystem.hpp"
void CSMDoc::Document::addGmsts() void CSMDoc::Document::addGmsts()
{ {
static const char *gmstFloats[] = static const char *gmstFloats[] =
@ -2253,7 +2255,7 @@ CSMDoc::Document::Document (const Files::ConfigurationManager& configuration,
mProjectPath ((configuration.getUserDataPath() / "projects") / mProjectPath ((configuration.getUserDataPath() / "projects") /
(savePath.filename().string() + ".project")), (savePath.filename().string() + ".project")),
mSaving (*this, mProjectPath, encoding), mSaving (*this, mProjectPath, encoding),
mRunner (mProjectPath) mRunner (mProjectPath), mPhysics(boost::shared_ptr<CSVWorld::PhysicsSystem>())
{ {
if (mContentFiles.empty()) if (mContentFiles.empty())
throw std::runtime_error ("Empty content file sequence"); throw std::runtime_error ("Empty content file sequence");
@ -2299,8 +2301,8 @@ CSMDoc::Document::Document (const Files::ConfigurationManager& configuration,
connect (&mSaving, SIGNAL (done (int, bool)), this, SLOT (operationDone (int, bool))); connect (&mSaving, SIGNAL (done (int, bool)), this, SLOT (operationDone (int, bool)));
connect ( connect (
&mSaving, SIGNAL (reportMessage (const CSMWorld::UniversalId&, const std::string&, int)), &mSaving, SIGNAL (reportMessage (const CSMWorld::UniversalId&, const std::string&, const std::string&, int)),
this, SLOT (reportMessage (const CSMWorld::UniversalId&, const std::string&, int))); this, SLOT (reportMessage (const CSMWorld::UniversalId&, const std::string&, const std::string&, int)));
connect (&mRunner, SIGNAL (runStateChanged()), this, SLOT (runStateChanged())); connect (&mRunner, SIGNAL (runStateChanged()), this, SLOT (runStateChanged()));
} }
@ -2385,7 +2387,7 @@ void CSMDoc::Document::modificationStateChanged (bool clean)
} }
void CSMDoc::Document::reportMessage (const CSMWorld::UniversalId& id, const std::string& message, void CSMDoc::Document::reportMessage (const CSMWorld::UniversalId& id, const std::string& message,
int type) const std::string& hint, int type)
{ {
/// \todo find a better way to get these messages to the user. /// \todo find a better way to get these messages to the user.
std::cout << message << std::endl; std::cout << message << std::endl;
@ -2464,3 +2466,11 @@ void CSMDoc::Document::progress (int current, int max, int type)
{ {
emit progress (current, max, type, 1, this); emit progress (current, max, type, 1, this);
} }
boost::shared_ptr<CSVWorld::PhysicsSystem> CSMDoc::Document::getPhysics ()
{
if(!mPhysics)
mPhysics = boost::shared_ptr<CSVWorld::PhysicsSystem> (new CSVWorld::PhysicsSystem());
return mPhysics;
}

@ -3,6 +3,7 @@
#include <string> #include <string>
#include <boost/shared_ptr.hpp>
#include <boost/filesystem/path.hpp> #include <boost/filesystem/path.hpp>
#include <QUndoStack> #include <QUndoStack>
@ -39,6 +40,11 @@ namespace CSMWorld
class ResourcesManager; class ResourcesManager;
} }
namespace CSVWorld
{
class PhysicsSystem;
}
namespace CSMDoc namespace CSMDoc
{ {
class Document : public QObject class Document : public QObject
@ -57,6 +63,7 @@ namespace CSMDoc
boost::filesystem::path mResDir; boost::filesystem::path mResDir;
Blacklist mBlacklist; Blacklist mBlacklist;
Runner mRunner; Runner mRunner;
boost::shared_ptr<CSVWorld::PhysicsSystem> mPhysics;
// It is important that the undo stack is declared last, because on desctruction it fires a signal, that is connected to a slot, that is // It is important that the undo stack is declared last, because on desctruction it fires a signal, that is connected to a slot, that is
// using other member variables. Unfortunately this connection is cut only in the QObject destructor, which is way too late. // using other member variables. Unfortunately this connection is cut only in the QObject destructor, which is way too late.
@ -129,6 +136,8 @@ namespace CSMDoc
QTextDocument *getRunLog(); QTextDocument *getRunLog();
boost::shared_ptr<CSVWorld::PhysicsSystem> getPhysics();
signals: signals:
void stateChanged (int state, CSMDoc::Document *document); void stateChanged (int state, CSMDoc::Document *document);
@ -140,7 +149,7 @@ namespace CSMDoc
void modificationStateChanged (bool clean); void modificationStateChanged (bool clean);
void reportMessage (const CSMWorld::UniversalId& id, const std::string& message, void reportMessage (const CSMWorld::UniversalId& id, const std::string& message,
int type); const std::string& hint, int type);
void operationDone (int type, bool failed); void operationDone (int type, bool failed);

@ -52,7 +52,7 @@ void CSMDoc::Loader::load()
{ {
if (iter->second.mRecordsLeft) if (iter->second.mRecordsLeft)
{ {
CSMDoc::Stage::Messages messages; CSMDoc::Messages messages;
for (int i=0; i<batchingSize; ++i) // do not flood the system with update signals for (int i=0; i<batchingSize; ++i) // do not flood the system with update signals
if (document->getData().continueLoading (messages)) if (document->getData().continueLoading (messages))
{ {
@ -65,11 +65,11 @@ void CSMDoc::Loader::load()
CSMWorld::UniversalId log (CSMWorld::UniversalId::Type_LoadErrorLog, 0); CSMWorld::UniversalId log (CSMWorld::UniversalId::Type_LoadErrorLog, 0);
{ // silence a g++ warning { // silence a g++ warning
for (CSMDoc::Stage::Messages::const_iterator iter (messages.begin()); for (CSMDoc::Messages::Iterator iter (messages.begin());
iter!=messages.end(); ++iter) iter!=messages.end(); ++iter)
{ {
document->getReport (log)->add (iter->first, iter->second); document->getReport (log)->add (iter->mId, iter->mMessage);
emit loadMessage (document, iter->second); emit loadMessage (document, iter->mMessage);
} }
} }

@ -0,0 +1,28 @@
#include "messages.hpp"
void CSMDoc::Messages::add (const CSMWorld::UniversalId& id, const std::string& message,
const std::string& hint)
{
Message data;
data.mId = id;
data.mMessage = message;
data.mHint = hint;
mMessages.push_back (data);
}
void CSMDoc::Messages::push_back (const std::pair<CSMWorld::UniversalId, std::string>& data)
{
add (data.first, data.second);
}
CSMDoc::Messages::Iterator CSMDoc::Messages::begin() const
{
return mMessages.begin();
}
CSMDoc::Messages::Iterator CSMDoc::Messages::end() const
{
return mMessages.end();
}

@ -0,0 +1,44 @@
#ifndef CSM_DOC_MESSAGES_H
#define CSM_DOC_MESSAGES_H
#include <string>
#include <vector>
#include "../world/universalid.hpp"
namespace CSMDoc
{
class Messages
{
public:
struct Message
{
CSMWorld::UniversalId mId;
std::string mMessage;
std::string mHint;
};
typedef std::vector<Message> Collection;
typedef Collection::const_iterator Iterator;
private:
Collection mMessages;
public:
void add (const CSMWorld::UniversalId& id, const std::string& message,
const std::string& hint = "");
/// \deprecated Use add instead.
void push_back (const std::pair<CSMWorld::UniversalId, std::string>& data);
Iterator begin() const;
Iterator end() const;
};
}
#endif

@ -84,7 +84,7 @@ void CSMDoc::Operation::abort()
void CSMDoc::Operation::executeStage() void CSMDoc::Operation::executeStage()
{ {
Stage::Messages messages; Messages messages;
while (mCurrentStage!=mStages.end()) while (mCurrentStage!=mStages.end())
{ {
@ -101,7 +101,7 @@ void CSMDoc::Operation::executeStage()
} }
catch (const std::exception& e) catch (const std::exception& e)
{ {
emit reportMessage (CSMWorld::UniversalId(), e.what(), mType); emit reportMessage (CSMWorld::UniversalId(), e.what(), "", mType);
abort(); abort();
} }
@ -112,8 +112,8 @@ void CSMDoc::Operation::executeStage()
emit progress (mCurrentStepTotal, mTotalSteps ? mTotalSteps : 1, mType); emit progress (mCurrentStepTotal, mTotalSteps ? mTotalSteps : 1, mType);
for (Stage::Messages::const_iterator iter (messages.begin()); iter!=messages.end(); ++iter) for (Messages::Iterator iter (messages.begin()); iter!=messages.end(); ++iter)
emit reportMessage (iter->first, iter->second, mType); emit reportMessage (iter->mId, iter->mMessage, iter->mHint, mType);
if (mCurrentStage==mStages.end()) if (mCurrentStage==mStages.end())
exit(); exit();

@ -52,7 +52,7 @@ namespace CSMDoc
void progress (int current, int max, int type); void progress (int current, int max, int type);
void reportMessage (const CSMWorld::UniversalId& id, const std::string& message, void reportMessage (const CSMWorld::UniversalId& id, const std::string& message,
int type); const std::string& hint, int type);
void done (int type, bool failed); void done (int type, bool failed);

@ -6,14 +6,14 @@
#include "../world/universalid.hpp" #include "../world/universalid.hpp"
#include "messages.hpp"
namespace CSMDoc namespace CSMDoc
{ {
class Stage class Stage
{ {
public: public:
typedef std::vector<std::pair<CSMWorld::UniversalId, std::string> > Messages;
virtual ~Stage(); virtual ~Stage();
virtual int setup() = 0; virtual int setup() = 0;

@ -17,7 +17,7 @@ int CSMTools::BirthsignCheckStage::setup()
return mBirthsigns.getSize(); return mBirthsigns.getSize();
} }
void CSMTools::BirthsignCheckStage::perform (int stage, Messages& messages) void CSMTools::BirthsignCheckStage::perform (int stage, CSMDoc::Messages& messages)
{ {
const CSMWorld::Record<ESM::BirthSign>& record = mBirthsigns.getRecord (stage); const CSMWorld::Record<ESM::BirthSign>& record = mBirthsigns.getRecord (stage);

@ -21,7 +21,7 @@ namespace CSMTools
virtual int setup(); virtual int setup();
///< \return number of steps ///< \return number of steps
virtual void perform (int stage, Messages& messages); virtual void perform (int stage, CSMDoc::Messages& messages);
///< Messages resulting from this tage will be appended to \a messages. ///< Messages resulting from this tage will be appended to \a messages.
}; };
} }

@ -14,7 +14,7 @@ int CSMTools::BodyPartCheckStage::setup()
return mBodyParts.getSize(); return mBodyParts.getSize();
} }
void CSMTools::BodyPartCheckStage::perform ( int stage, Messages &messages ) void CSMTools::BodyPartCheckStage::perform (int stage, CSMDoc::Messages &messages)
{ {
const CSMWorld::Record<ESM::BodyPart> &record = mBodyParts.getRecord(stage); const CSMWorld::Record<ESM::BodyPart> &record = mBodyParts.getRecord(stage);

@ -27,7 +27,7 @@ namespace CSMTools
virtual int setup(); virtual int setup();
///< \return number of steps ///< \return number of steps
virtual void perform( int stage, Messages &messages ); virtual void perform( int stage, CSMDoc::Messages &messages );
///< Messages resulting from this tage will be appended to \a messages. ///< Messages resulting from this tage will be appended to \a messages.
}; };
} }

@ -18,7 +18,7 @@ int CSMTools::ClassCheckStage::setup()
return mClasses.getSize(); return mClasses.getSize();
} }
void CSMTools::ClassCheckStage::perform (int stage, Messages& messages) void CSMTools::ClassCheckStage::perform (int stage, CSMDoc::Messages& messages)
{ {
const CSMWorld::Record<ESM::Class>& record = mClasses.getRecord (stage); const CSMWorld::Record<ESM::Class>& record = mClasses.getRecord (stage);

@ -21,7 +21,7 @@ namespace CSMTools
virtual int setup(); virtual int setup();
///< \return number of steps ///< \return number of steps
virtual void perform (int stage, Messages& messages); virtual void perform (int stage, CSMDoc::Messages& messages);
///< Messages resulting from this tage will be appended to \a messages. ///< Messages resulting from this tage will be appended to \a messages.
}; };
} }

@ -18,7 +18,7 @@ int CSMTools::FactionCheckStage::setup()
return mFactions.getSize(); return mFactions.getSize();
} }
void CSMTools::FactionCheckStage::perform (int stage, Messages& messages) void CSMTools::FactionCheckStage::perform (int stage, CSMDoc::Messages& messages)
{ {
const CSMWorld::Record<ESM::Faction>& record = mFactions.getRecord (stage); const CSMWorld::Record<ESM::Faction>& record = mFactions.getRecord (stage);

@ -21,7 +21,7 @@ namespace CSMTools
virtual int setup(); virtual int setup();
///< \return number of steps ///< \return number of steps
virtual void perform (int stage, Messages& messages); virtual void perform (int stage, CSMDoc::Messages& messages);
///< Messages resulting from this tage will be appended to \a messages. ///< Messages resulting from this tage will be appended to \a messages.
}; };
} }

@ -15,10 +15,9 @@ int CSMTools::MandatoryIdStage::setup()
return mIds.size(); return mIds.size();
} }
void CSMTools::MandatoryIdStage::perform (int stage, Messages& messages) void CSMTools::MandatoryIdStage::perform (int stage, CSMDoc::Messages& messages)
{ {
if (mIdCollection.searchId (mIds.at (stage))==-1 || if (mIdCollection.searchId (mIds.at (stage))==-1 ||
mIdCollection.getRecord (mIds.at (stage)).isDeleted()) mIdCollection.getRecord (mIds.at (stage)).isDeleted())
messages.push_back (std::make_pair (mCollectionId, messages.add (mCollectionId, "Missing mandatory record: " + mIds.at (stage));
"Missing mandatory record: " + mIds.at (stage)));
} }

@ -30,7 +30,7 @@ namespace CSMTools
virtual int setup(); virtual int setup();
///< \return number of steps ///< \return number of steps
virtual void perform (int stage, Messages& messages); virtual void perform (int stage, CSMDoc::Messages& messages);
///< Messages resulting from this tage will be appended to \a messages. ///< Messages resulting from this tage will be appended to \a messages.
}; };
} }

@ -7,7 +7,7 @@
#include "../world/universalid.hpp" #include "../world/universalid.hpp"
void CSMTools::RaceCheckStage::performPerRecord (int stage, Messages& messages) void CSMTools::RaceCheckStage::performPerRecord (int stage, CSMDoc::Messages& messages)
{ {
const CSMWorld::Record<ESM::Race>& record = mRaces.getRecord (stage); const CSMWorld::Record<ESM::Race>& record = mRaces.getRecord (stage);
@ -46,7 +46,7 @@ void CSMTools::RaceCheckStage::performPerRecord (int stage, Messages& messages)
/// \todo check data members that can't be edited in the table view /// \todo check data members that can't be edited in the table view
} }
void CSMTools::RaceCheckStage::performFinal (Messages& messages) void CSMTools::RaceCheckStage::performFinal (CSMDoc::Messages& messages)
{ {
CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Races); CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Races);
@ -64,7 +64,7 @@ int CSMTools::RaceCheckStage::setup()
return mRaces.getSize()+1; return mRaces.getSize()+1;
} }
void CSMTools::RaceCheckStage::perform (int stage, Messages& messages) void CSMTools::RaceCheckStage::perform (int stage, CSMDoc::Messages& messages)
{ {
if (stage==mRaces.getSize()) if (stage==mRaces.getSize())
performFinal (messages); performFinal (messages);

@ -15,9 +15,9 @@ namespace CSMTools
const CSMWorld::IdCollection<ESM::Race>& mRaces; const CSMWorld::IdCollection<ESM::Race>& mRaces;
bool mPlayable; bool mPlayable;
void performPerRecord (int stage, Messages& messages); void performPerRecord (int stage, CSMDoc::Messages& messages);
void performFinal (Messages& messages); void performFinal (CSMDoc::Messages& messages);
public: public:
@ -26,7 +26,7 @@ namespace CSMTools
virtual int setup(); virtual int setup();
///< \return number of steps ///< \return number of steps
virtual void perform (int stage, Messages& messages); virtual void perform (int stage, CSMDoc::Messages& messages);
///< Messages resulting from this tage will be appended to \a messages. ///< Messages resulting from this tage will be appended to \a messages.
}; };
} }

@ -18,7 +18,7 @@ CSMTools::ReferenceableCheckStage::ReferenceableCheckStage(
{ {
} }
void CSMTools::ReferenceableCheckStage::perform (int stage, Messages& messages) void CSMTools::ReferenceableCheckStage::perform (int stage, CSMDoc::Messages& messages)
{ {
//Checks for books, than, when stage is above mBooksSize goes to other checks, with (stage - PrevSum) as stage. //Checks for books, than, when stage is above mBooksSize goes to other checks, with (stage - PrevSum) as stage.
const int bookSize(mReferencables.getBooks().getSize()); const int bookSize(mReferencables.getBooks().getSize());
@ -232,7 +232,7 @@ int CSMTools::ReferenceableCheckStage::setup()
void CSMTools::ReferenceableCheckStage::bookCheck( void CSMTools::ReferenceableCheckStage::bookCheck(
int stage, int stage,
const CSMWorld::RefIdDataContainer< ESM::Book >& records, const CSMWorld::RefIdDataContainer< ESM::Book >& records,
Messages& messages) CSMDoc::Messages& messages)
{ {
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage); const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
@ -250,7 +250,7 @@ void CSMTools::ReferenceableCheckStage::bookCheck(
void CSMTools::ReferenceableCheckStage::activatorCheck( void CSMTools::ReferenceableCheckStage::activatorCheck(
int stage, int stage,
const CSMWorld::RefIdDataContainer< ESM::Activator >& records, const CSMWorld::RefIdDataContainer< ESM::Activator >& records,
Messages& messages) CSMDoc::Messages& messages)
{ {
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage); const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
@ -270,7 +270,7 @@ void CSMTools::ReferenceableCheckStage::activatorCheck(
void CSMTools::ReferenceableCheckStage::potionCheck( void CSMTools::ReferenceableCheckStage::potionCheck(
int stage, int stage,
const CSMWorld::RefIdDataContainer< ESM::Potion >& records, const CSMWorld::RefIdDataContainer< ESM::Potion >& records,
Messages& messages) CSMDoc::Messages& messages)
{ {
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage); const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
@ -290,7 +290,7 @@ void CSMTools::ReferenceableCheckStage::potionCheck(
void CSMTools::ReferenceableCheckStage::apparatusCheck( void CSMTools::ReferenceableCheckStage::apparatusCheck(
int stage, int stage,
const CSMWorld::RefIdDataContainer< ESM::Apparatus >& records, const CSMWorld::RefIdDataContainer< ESM::Apparatus >& records,
Messages& messages) CSMDoc::Messages& messages)
{ {
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage); const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
@ -310,7 +310,7 @@ void CSMTools::ReferenceableCheckStage::apparatusCheck(
void CSMTools::ReferenceableCheckStage::armorCheck( void CSMTools::ReferenceableCheckStage::armorCheck(
int stage, int stage,
const CSMWorld::RefIdDataContainer< ESM::Armor >& records, const CSMWorld::RefIdDataContainer< ESM::Armor >& records,
Messages& messages) CSMDoc::Messages& messages)
{ {
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage); const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
@ -336,7 +336,7 @@ void CSMTools::ReferenceableCheckStage::armorCheck(
void CSMTools::ReferenceableCheckStage::clothingCheck( void CSMTools::ReferenceableCheckStage::clothingCheck(
int stage, int stage,
const CSMWorld::RefIdDataContainer< ESM::Clothing >& records, const CSMWorld::RefIdDataContainer< ESM::Clothing >& records,
Messages& messages) CSMDoc::Messages& messages)
{ {
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage); const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
@ -353,7 +353,7 @@ void CSMTools::ReferenceableCheckStage::clothingCheck(
void CSMTools::ReferenceableCheckStage::containerCheck( void CSMTools::ReferenceableCheckStage::containerCheck(
int stage, int stage,
const CSMWorld::RefIdDataContainer< ESM::Container >& records, const CSMWorld::RefIdDataContainer< ESM::Container >& records,
Messages& messages) CSMDoc::Messages& messages)
{ {
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage); const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
@ -381,7 +381,7 @@ void CSMTools::ReferenceableCheckStage::containerCheck(
void CSMTools::ReferenceableCheckStage::creatureCheck ( void CSMTools::ReferenceableCheckStage::creatureCheck (
int stage, const CSMWorld::RefIdDataContainer< ESM::Creature >& records, int stage, const CSMWorld::RefIdDataContainer< ESM::Creature >& records,
Messages& messages) CSMDoc::Messages& messages)
{ {
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage); const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
@ -448,7 +448,7 @@ void CSMTools::ReferenceableCheckStage::creatureCheck (
void CSMTools::ReferenceableCheckStage::doorCheck( void CSMTools::ReferenceableCheckStage::doorCheck(
int stage, const CSMWorld::RefIdDataContainer< ESM::Door >& records, int stage, const CSMWorld::RefIdDataContainer< ESM::Door >& records,
Messages& messages) CSMDoc::Messages& messages)
{ {
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage); const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
@ -469,7 +469,7 @@ void CSMTools::ReferenceableCheckStage::doorCheck(
void CSMTools::ReferenceableCheckStage::ingredientCheck( void CSMTools::ReferenceableCheckStage::ingredientCheck(
int stage, int stage,
const CSMWorld::RefIdDataContainer< ESM::Ingredient >& records, const CSMWorld::RefIdDataContainer< ESM::Ingredient >& records,
Messages& messages) CSMDoc::Messages& messages)
{ {
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage); const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
@ -487,7 +487,7 @@ void CSMTools::ReferenceableCheckStage::ingredientCheck(
void CSMTools::ReferenceableCheckStage::creaturesLevListCheck( void CSMTools::ReferenceableCheckStage::creaturesLevListCheck(
int stage, int stage,
const CSMWorld::RefIdDataContainer< ESM::CreatureLevList >& records, const CSMWorld::RefIdDataContainer< ESM::CreatureLevList >& records,
Messages& messages) CSMDoc::Messages& messages)
{ {
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage); const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
@ -505,7 +505,7 @@ void CSMTools::ReferenceableCheckStage::creaturesLevListCheck(
void CSMTools::ReferenceableCheckStage::itemLevelledListCheck( void CSMTools::ReferenceableCheckStage::itemLevelledListCheck(
int stage, int stage,
const CSMWorld::RefIdDataContainer< ESM::ItemLevList >& records, const CSMWorld::RefIdDataContainer< ESM::ItemLevList >& records,
Messages& messages) CSMDoc::Messages& messages)
{ {
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage); const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
@ -522,7 +522,7 @@ void CSMTools::ReferenceableCheckStage::itemLevelledListCheck(
void CSMTools::ReferenceableCheckStage::lightCheck( void CSMTools::ReferenceableCheckStage::lightCheck(
int stage, const CSMWorld::RefIdDataContainer< ESM::Light >& records, int stage, const CSMWorld::RefIdDataContainer< ESM::Light >& records,
Messages& messages) CSMDoc::Messages& messages)
{ {
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage); const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
@ -547,7 +547,7 @@ void CSMTools::ReferenceableCheckStage::lightCheck(
void CSMTools::ReferenceableCheckStage::lockpickCheck( void CSMTools::ReferenceableCheckStage::lockpickCheck(
int stage, int stage,
const CSMWorld::RefIdDataContainer< ESM::Lockpick >& records, const CSMWorld::RefIdDataContainer< ESM::Lockpick >& records,
Messages& messages) CSMDoc::Messages& messages)
{ {
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage); const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
@ -567,7 +567,7 @@ void CSMTools::ReferenceableCheckStage::lockpickCheck(
void CSMTools::ReferenceableCheckStage::miscCheck( void CSMTools::ReferenceableCheckStage::miscCheck(
int stage, int stage,
const CSMWorld::RefIdDataContainer< ESM::Miscellaneous >& records, const CSMWorld::RefIdDataContainer< ESM::Miscellaneous >& records,
Messages& messages) CSMDoc::Messages& messages)
{ {
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage); const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
@ -584,7 +584,7 @@ void CSMTools::ReferenceableCheckStage::miscCheck(
void CSMTools::ReferenceableCheckStage::npcCheck ( void CSMTools::ReferenceableCheckStage::npcCheck (
int stage, const CSMWorld::RefIdDataContainer< ESM::NPC >& records, int stage, const CSMWorld::RefIdDataContainer< ESM::NPC >& records,
Messages& messages) CSMDoc::Messages& messages)
{ {
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage); const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
@ -701,7 +701,7 @@ void CSMTools::ReferenceableCheckStage::npcCheck (
void CSMTools::ReferenceableCheckStage::weaponCheck( void CSMTools::ReferenceableCheckStage::weaponCheck(
int stage, const CSMWorld::RefIdDataContainer< ESM::Weapon >& records, int stage, const CSMWorld::RefIdDataContainer< ESM::Weapon >& records,
Messages& messages) CSMDoc::Messages& messages)
{ {
const CSMWorld::RecordBase& baseRecord = records.getRecord (stage); const CSMWorld::RecordBase& baseRecord = records.getRecord (stage);
@ -778,7 +778,7 @@ void CSMTools::ReferenceableCheckStage::weaponCheck(
void CSMTools::ReferenceableCheckStage::probeCheck( void CSMTools::ReferenceableCheckStage::probeCheck(
int stage, int stage,
const CSMWorld::RefIdDataContainer< ESM::Probe >& records, const CSMWorld::RefIdDataContainer< ESM::Probe >& records,
Messages& messages) CSMDoc::Messages& messages)
{ {
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage); const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
@ -796,7 +796,7 @@ void CSMTools::ReferenceableCheckStage::probeCheck(
void CSMTools::ReferenceableCheckStage::repairCheck ( void CSMTools::ReferenceableCheckStage::repairCheck (
int stage, const CSMWorld::RefIdDataContainer< ESM::Repair >& records, int stage, const CSMWorld::RefIdDataContainer< ESM::Repair >& records,
Messages& messages) CSMDoc::Messages& messages)
{ {
const CSMWorld::RecordBase& baseRecord = records.getRecord (stage); const CSMWorld::RecordBase& baseRecord = records.getRecord (stage);
@ -812,7 +812,7 @@ void CSMTools::ReferenceableCheckStage::repairCheck (
void CSMTools::ReferenceableCheckStage::staticCheck ( void CSMTools::ReferenceableCheckStage::staticCheck (
int stage, const CSMWorld::RefIdDataContainer< ESM::Static >& records, int stage, const CSMWorld::RefIdDataContainer< ESM::Static >& records,
Messages& messages) CSMDoc::Messages& messages)
{ {
const CSMWorld::RecordBase& baseRecord = records.getRecord (stage); const CSMWorld::RecordBase& baseRecord = records.getRecord (stage);
@ -828,7 +828,7 @@ void CSMTools::ReferenceableCheckStage::staticCheck (
//final check //final check
void CSMTools::ReferenceableCheckStage::finalCheck (Messages& messages) void CSMTools::ReferenceableCheckStage::finalCheck (CSMDoc::Messages& messages)
{ {
if (!mPlayerPresent) if (!mPlayerPresent)
messages.push_back (std::make_pair (CSMWorld::UniversalId::Type_Referenceables, messages.push_back (std::make_pair (CSMWorld::UniversalId::Type_Referenceables,
@ -839,7 +839,7 @@ void CSMTools::ReferenceableCheckStage::finalCheck (Messages& messages)
//Templates begins here //Templates begins here
template<typename Item> void CSMTools::ReferenceableCheckStage::inventoryItemCheck ( template<typename Item> void CSMTools::ReferenceableCheckStage::inventoryItemCheck (
const Item& someItem, Messages& messages, const std::string& someID, bool enchantable) const Item& someItem, CSMDoc::Messages& messages, const std::string& someID, bool enchantable)
{ {
if (someItem.mName.empty()) if (someItem.mName.empty())
messages.push_back (std::make_pair (someID, someItem.mId + " has an empty name")); messages.push_back (std::make_pair (someID, someItem.mId + " has an empty name"));
@ -865,7 +865,7 @@ template<typename Item> void CSMTools::ReferenceableCheckStage::inventoryItemChe
} }
template<typename Item> void CSMTools::ReferenceableCheckStage::inventoryItemCheck ( template<typename Item> void CSMTools::ReferenceableCheckStage::inventoryItemCheck (
const Item& someItem, Messages& messages, const std::string& someID) const Item& someItem, CSMDoc::Messages& messages, const std::string& someID)
{ {
if (someItem.mName.empty()) if (someItem.mName.empty())
messages.push_back (std::make_pair (someID, someItem.mId + " has an empty name")); messages.push_back (std::make_pair (someID, someItem.mId + " has an empty name"));
@ -888,7 +888,7 @@ template<typename Item> void CSMTools::ReferenceableCheckStage::inventoryItemChe
} }
template<typename Tool> void CSMTools::ReferenceableCheckStage::toolCheck ( template<typename Tool> void CSMTools::ReferenceableCheckStage::toolCheck (
const Tool& someTool, Messages& messages, const std::string& someID, bool canBeBroken) const Tool& someTool, CSMDoc::Messages& messages, const std::string& someID, bool canBeBroken)
{ {
if (someTool.mData.mQuality <= 0) if (someTool.mData.mQuality <= 0)
messages.push_back (std::make_pair (someID, someTool.mId + " has non-positive quality")); messages.push_back (std::make_pair (someID, someTool.mId + " has non-positive quality"));
@ -899,14 +899,14 @@ template<typename Tool> void CSMTools::ReferenceableCheckStage::toolCheck (
} }
template<typename Tool> void CSMTools::ReferenceableCheckStage::toolCheck ( template<typename Tool> void CSMTools::ReferenceableCheckStage::toolCheck (
const Tool& someTool, Messages& messages, const std::string& someID) const Tool& someTool, CSMDoc::Messages& messages, const std::string& someID)
{ {
if (someTool.mData.mQuality <= 0) if (someTool.mData.mQuality <= 0)
messages.push_back (std::make_pair (someID, someTool.mId + " has non-positive quality")); messages.push_back (std::make_pair (someID, someTool.mId + " has non-positive quality"));
} }
template<typename List> void CSMTools::ReferenceableCheckStage::listCheck ( template<typename List> void CSMTools::ReferenceableCheckStage::listCheck (
const List& someList, Messages& messages, const std::string& someID) const List& someList, CSMDoc::Messages& messages, const std::string& someID)
{ {
for (unsigned i = 0; i < someList.mList.size(); ++i) for (unsigned i = 0; i < someList.mList.size(); ++i)
{ {

@ -17,56 +17,56 @@ namespace CSMTools
const CSMWorld::IdCollection<ESM::Class>& classes, const CSMWorld::IdCollection<ESM::Class>& classes,
const CSMWorld::IdCollection<ESM::Faction>& factions); const CSMWorld::IdCollection<ESM::Faction>& factions);
virtual void perform(int stage, Messages& messages); virtual void perform(int stage, CSMDoc::Messages& messages);
virtual int setup(); virtual int setup();
private: private:
//CONCRETE CHECKS //CONCRETE CHECKS
void bookCheck(int stage, const CSMWorld::RefIdDataContainer< ESM::Book >& records, Messages& messages); void bookCheck(int stage, const CSMWorld::RefIdDataContainer< ESM::Book >& records, CSMDoc::Messages& messages);
void activatorCheck(int stage, const CSMWorld::RefIdDataContainer< ESM::Activator >& records, Messages& messages); void activatorCheck(int stage, const CSMWorld::RefIdDataContainer< ESM::Activator >& records, CSMDoc::Messages& messages);
void potionCheck(int stage, const CSMWorld::RefIdDataContainer<ESM::Potion>& records, Messages& messages); void potionCheck(int stage, const CSMWorld::RefIdDataContainer<ESM::Potion>& records, CSMDoc::Messages& messages);
void apparatusCheck(int stage, const CSMWorld::RefIdDataContainer<ESM::Apparatus>& records, Messages& messages); void apparatusCheck(int stage, const CSMWorld::RefIdDataContainer<ESM::Apparatus>& records, CSMDoc::Messages& messages);
void armorCheck(int stage, const CSMWorld::RefIdDataContainer<ESM::Armor>& records, Messages& messages); void armorCheck(int stage, const CSMWorld::RefIdDataContainer<ESM::Armor>& records, CSMDoc::Messages& messages);
void clothingCheck(int stage, const CSMWorld::RefIdDataContainer<ESM::Clothing>& records, Messages& messages); void clothingCheck(int stage, const CSMWorld::RefIdDataContainer<ESM::Clothing>& records, CSMDoc::Messages& messages);
void containerCheck(int stage, const CSMWorld::RefIdDataContainer<ESM::Container>& records, Messages& messages); void containerCheck(int stage, const CSMWorld::RefIdDataContainer<ESM::Container>& records, CSMDoc::Messages& messages);
void creatureCheck(int stage, const CSMWorld::RefIdDataContainer<ESM::Creature>& records, Messages& messages); void creatureCheck(int stage, const CSMWorld::RefIdDataContainer<ESM::Creature>& records, CSMDoc::Messages& messages);
void doorCheck(int stage, const CSMWorld::RefIdDataContainer<ESM::Door>& records, Messages& messages); void doorCheck(int stage, const CSMWorld::RefIdDataContainer<ESM::Door>& records, CSMDoc::Messages& messages);
void ingredientCheck(int stage, const CSMWorld::RefIdDataContainer<ESM::Ingredient>& records, Messages& messages); void ingredientCheck(int stage, const CSMWorld::RefIdDataContainer<ESM::Ingredient>& records, CSMDoc::Messages& messages);
void creaturesLevListCheck(int stage, const CSMWorld::RefIdDataContainer<ESM::CreatureLevList>& records, Messages& messages); void creaturesLevListCheck(int stage, const CSMWorld::RefIdDataContainer<ESM::CreatureLevList>& records, CSMDoc::Messages& messages);
void itemLevelledListCheck(int stage, const CSMWorld::RefIdDataContainer<ESM::ItemLevList>& records, Messages& messages); void itemLevelledListCheck(int stage, const CSMWorld::RefIdDataContainer<ESM::ItemLevList>& records, CSMDoc::Messages& messages);
void lightCheck(int stage, const CSMWorld::RefIdDataContainer<ESM::Light>& records, Messages& messages); void lightCheck(int stage, const CSMWorld::RefIdDataContainer<ESM::Light>& records, CSMDoc::Messages& messages);
void lockpickCheck(int stage, const CSMWorld::RefIdDataContainer<ESM::Lockpick>& records, Messages& messages); void lockpickCheck(int stage, const CSMWorld::RefIdDataContainer<ESM::Lockpick>& records, CSMDoc::Messages& messages);
void miscCheck(int stage, const CSMWorld::RefIdDataContainer<ESM::Miscellaneous>& records, Messages& messages); void miscCheck(int stage, const CSMWorld::RefIdDataContainer<ESM::Miscellaneous>& records, CSMDoc::Messages& messages);
void npcCheck(int stage, const CSMWorld::RefIdDataContainer<ESM::NPC>& records, Messages& messages); void npcCheck(int stage, const CSMWorld::RefIdDataContainer<ESM::NPC>& records, CSMDoc::Messages& messages);
void weaponCheck(int stage, const CSMWorld::RefIdDataContainer<ESM::Weapon>& records, Messages& messages); void weaponCheck(int stage, const CSMWorld::RefIdDataContainer<ESM::Weapon>& records, CSMDoc::Messages& messages);
void probeCheck(int stage, const CSMWorld::RefIdDataContainer<ESM::Probe>& records, Messages& messages); void probeCheck(int stage, const CSMWorld::RefIdDataContainer<ESM::Probe>& records, CSMDoc::Messages& messages);
void repairCheck(int stage, const CSMWorld::RefIdDataContainer<ESM::Repair>& records, Messages& messages); void repairCheck(int stage, const CSMWorld::RefIdDataContainer<ESM::Repair>& records, CSMDoc::Messages& messages);
void staticCheck(int stage, const CSMWorld::RefIdDataContainer<ESM::Static>& records, Messages& messages); void staticCheck(int stage, const CSMWorld::RefIdDataContainer<ESM::Static>& records, CSMDoc::Messages& messages);
//FINAL CHECK //FINAL CHECK
void finalCheck (Messages& messages); void finalCheck (CSMDoc::Messages& messages);
//TEMPLATE CHECKS //TEMPLATE CHECKS
template<typename ITEM> void inventoryItemCheck(const ITEM& someItem, template<typename ITEM> void inventoryItemCheck(const ITEM& someItem,
Messages& messages, CSMDoc::Messages& messages,
const std::string& someID, const std::string& someID,
bool enchantable); //for all enchantable items. bool enchantable); //for all enchantable items.
template<typename ITEM> void inventoryItemCheck(const ITEM& someItem, template<typename ITEM> void inventoryItemCheck(const ITEM& someItem,
Messages& messages, CSMDoc::Messages& messages,
const std::string& someID); //for non-enchantable items. const std::string& someID); //for non-enchantable items.
template<typename TOOL> void toolCheck(const TOOL& someTool, template<typename TOOL> void toolCheck(const TOOL& someTool,
Messages& messages, CSMDoc::Messages& messages,
const std::string& someID, const std::string& someID,
bool canbebroken); //for tools with uses. bool canbebroken); //for tools with uses.
template<typename TOOL> void toolCheck(const TOOL& someTool, template<typename TOOL> void toolCheck(const TOOL& someTool,
Messages& messages, CSMDoc::Messages& messages,
const std::string& someID); //for tools without uses. const std::string& someID); //for tools without uses.
template<typename LIST> void listCheck(const LIST& someList, template<typename LIST> void listCheck(const LIST& someList,
Messages& messages, CSMDoc::Messages& messages,
const std::string& someID); const std::string& someID);
const CSMWorld::RefIdData& mReferencables; const CSMWorld::RefIdData& mReferencables;

@ -17,7 +17,7 @@ int CSMTools::RegionCheckStage::setup()
return mRegions.getSize(); return mRegions.getSize();
} }
void CSMTools::RegionCheckStage::perform (int stage, Messages& messages) void CSMTools::RegionCheckStage::perform (int stage, CSMDoc::Messages& messages)
{ {
const CSMWorld::Record<ESM::Region>& record = mRegions.getRecord (stage); const CSMWorld::Record<ESM::Region>& record = mRegions.getRecord (stage);

@ -21,7 +21,7 @@ namespace CSMTools
virtual int setup(); virtual int setup();
///< \return number of steps ///< \return number of steps
virtual void perform (int stage, Messages& messages); virtual void perform (int stage, CSMDoc::Messages& messages);
///< Messages resulting from this tage will be appended to \a messages. ///< Messages resulting from this tage will be appended to \a messages.
}; };
} }

@ -16,7 +16,7 @@ int CSMTools::ReportModel::columnCount (const QModelIndex & parent) const
if (parent.isValid()) if (parent.isValid())
return 0; return 0;
return 2; return 3;
} }
QVariant CSMTools::ReportModel::data (const QModelIndex & index, int role) const QVariant CSMTools::ReportModel::data (const QModelIndex & index, int role) const
@ -26,8 +26,11 @@ QVariant CSMTools::ReportModel::data (const QModelIndex & index, int role) const
if (index.column()==0) if (index.column()==0)
return static_cast<int> (mRows.at (index.row()).first.getType()); return static_cast<int> (mRows.at (index.row()).first.getType());
else
return mRows.at (index.row()).second.c_str(); if (index.column()==1)
return QString::fromUtf8 (mRows.at (index.row()).second.first.c_str());
return QString::fromUtf8 (mRows.at (index.row()).second.second.c_str());
} }
QVariant CSMTools::ReportModel::headerData (int section, Qt::Orientation orientation, int role) const QVariant CSMTools::ReportModel::headerData (int section, Qt::Orientation orientation, int role) const
@ -38,7 +41,13 @@ QVariant CSMTools::ReportModel::headerData (int section, Qt::Orientation orienta
if (orientation==Qt::Vertical) if (orientation==Qt::Vertical)
return QVariant(); return QVariant();
return tr (section==0 ? "Type" : "Description"); if (section==0)
return "Type";
if (section==1)
return "Description";
return "Hint";
} }
bool CSMTools::ReportModel::removeRows (int row, int count, const QModelIndex& parent) bool CSMTools::ReportModel::removeRows (int row, int count, const QModelIndex& parent)
@ -51,11 +60,12 @@ bool CSMTools::ReportModel::removeRows (int row, int count, const QModelIndex& p
return true; return true;
} }
void CSMTools::ReportModel::add (const CSMWorld::UniversalId& id, const std::string& message) void CSMTools::ReportModel::add (const CSMWorld::UniversalId& id, const std::string& message,
const std::string& hint)
{ {
beginInsertRows (QModelIndex(), mRows.size(), mRows.size()); beginInsertRows (QModelIndex(), mRows.size(), mRows.size());
mRows.push_back (std::make_pair (id, message)); mRows.push_back (std::make_pair (id, std::make_pair (message, hint)));
endInsertRows(); endInsertRows();
} }
@ -64,3 +74,8 @@ const CSMWorld::UniversalId& CSMTools::ReportModel::getUniversalId (int row) con
{ {
return mRows.at (row).first; return mRows.at (row).first;
} }
std::string CSMTools::ReportModel::getHint (int row) const
{
return mRows.at (row).second.second;
}

@ -14,7 +14,7 @@ namespace CSMTools
{ {
Q_OBJECT Q_OBJECT
std::vector<std::pair<CSMWorld::UniversalId, std::string> > mRows; std::vector<std::pair<CSMWorld::UniversalId, std::pair<std::string, std::string> > > mRows;
public: public:
@ -28,9 +28,12 @@ namespace CSMTools
virtual bool removeRows (int row, int count, const QModelIndex& parent = QModelIndex()); virtual bool removeRows (int row, int count, const QModelIndex& parent = QModelIndex());
void add (const CSMWorld::UniversalId& id, const std::string& message); void add (const CSMWorld::UniversalId& id, const std::string& message,
const std::string& hint = "");
const CSMWorld::UniversalId& getUniversalId (int row) const; const CSMWorld::UniversalId& getUniversalId (int row) const;
std::string getHint (int row) const;
}; };
} }

@ -28,7 +28,11 @@ void CSMTools::ScriptCheckStage::report (const std::string& message, const Compi
<< ", line " << loc.mLine << ", column " << loc.mColumn << ", line " << loc.mLine << ", column " << loc.mColumn
<< " (" << loc.mLiteral << "): " << message; << " (" << loc.mLiteral << "): " << message;
mMessages->push_back (std::make_pair (id, stream.str())); std::ostringstream hintStream;
hintStream << "l:" << loc.mLine << " " << loc.mColumn;
mMessages->add (id, stream.str(), hintStream.str());
} }
void CSMTools::ScriptCheckStage::report (const std::string& message, Type type) void CSMTools::ScriptCheckStage::report (const std::string& message, Type type)
@ -58,7 +62,7 @@ int CSMTools::ScriptCheckStage::setup()
return mDocument.getData().getScripts().getSize(); return mDocument.getData().getScripts().getSize();
} }
void CSMTools::ScriptCheckStage::perform (int stage, Messages& messages) void CSMTools::ScriptCheckStage::perform (int stage, CSMDoc::Messages& messages)
{ {
mId = mDocument.getData().getScripts().getId (stage); mId = mDocument.getData().getScripts().getId (stage);

@ -23,7 +23,7 @@ namespace CSMTools
CSMWorld::ScriptContext mContext; CSMWorld::ScriptContext mContext;
std::string mId; std::string mId;
std::string mFile; std::string mFile;
Messages *mMessages; CSMDoc::Messages *mMessages;
virtual void report (const std::string& message, const Compiler::TokenLoc& loc, Type type); virtual void report (const std::string& message, const Compiler::TokenLoc& loc, Type type);
///< Report error to the user. ///< Report error to the user.
@ -38,7 +38,7 @@ namespace CSMTools
virtual int setup(); virtual int setup();
///< \return number of steps ///< \return number of steps
virtual void perform (int stage, Messages& messages); virtual void perform (int stage, CSMDoc::Messages& messages);
///< Messages resulting from this tage will be appended to \a messages. ///< Messages resulting from this tage will be appended to \a messages.
}; };
} }

@ -16,7 +16,7 @@ int CSMTools::SkillCheckStage::setup()
return mSkills.getSize(); return mSkills.getSize();
} }
void CSMTools::SkillCheckStage::perform (int stage, Messages& messages) void CSMTools::SkillCheckStage::perform (int stage, CSMDoc::Messages& messages)
{ {
const CSMWorld::Record<ESM::Skill>& record = mSkills.getRecord (stage); const CSMWorld::Record<ESM::Skill>& record = mSkills.getRecord (stage);

@ -21,7 +21,7 @@ namespace CSMTools
virtual int setup(); virtual int setup();
///< \return number of steps ///< \return number of steps
virtual void perform (int stage, Messages& messages); virtual void perform (int stage, CSMDoc::Messages& messages);
///< Messages resulting from this tage will be appended to \a messages. ///< Messages resulting from this tage will be appended to \a messages.
}; };
} }

@ -16,7 +16,7 @@ int CSMTools::SoundCheckStage::setup()
return mSounds.getSize(); return mSounds.getSize();
} }
void CSMTools::SoundCheckStage::perform (int stage, Messages& messages) void CSMTools::SoundCheckStage::perform (int stage, CSMDoc::Messages& messages)
{ {
const CSMWorld::Record<ESM::Sound>& record = mSounds.getRecord (stage); const CSMWorld::Record<ESM::Sound>& record = mSounds.getRecord (stage);

@ -21,7 +21,7 @@ namespace CSMTools
virtual int setup(); virtual int setup();
///< \return number of steps ///< \return number of steps
virtual void perform (int stage, Messages& messages); virtual void perform (int stage, CSMDoc::Messages& messages);
///< Messages resulting from this tage will be appended to \a messages. ///< Messages resulting from this tage will be appended to \a messages.
}; };
} }

@ -17,7 +17,7 @@ int CSMTools::SpellCheckStage::setup()
return mSpells.getSize(); return mSpells.getSize();
} }
void CSMTools::SpellCheckStage::perform (int stage, Messages& messages) void CSMTools::SpellCheckStage::perform (int stage, CSMDoc::Messages& messages)
{ {
const CSMWorld::Record<ESM::Spell>& record = mSpells.getRecord (stage); const CSMWorld::Record<ESM::Spell>& record = mSpells.getRecord (stage);

@ -21,7 +21,7 @@ namespace CSMTools
virtual int setup(); virtual int setup();
///< \return number of steps ///< \return number of steps
virtual void perform (int stage, Messages& messages); virtual void perform (int stage, CSMDoc::Messages& messages);
///< Messages resulting from this tage will be appended to \a messages. ///< Messages resulting from this tage will be appended to \a messages.
}; };
} }

@ -48,8 +48,8 @@ CSMDoc::Operation *CSMTools::Tools::getVerifier()
connect (mVerifier, SIGNAL (progress (int, int, int)), this, SIGNAL (progress (int, int, int))); connect (mVerifier, SIGNAL (progress (int, int, int)), this, SIGNAL (progress (int, int, int)));
connect (mVerifier, SIGNAL (done (int, bool)), this, SIGNAL (done (int, bool))); connect (mVerifier, SIGNAL (done (int, bool)), this, SIGNAL (done (int, bool)));
connect (mVerifier, connect (mVerifier,
SIGNAL (reportMessage (const CSMWorld::UniversalId&, const std::string&, int)), SIGNAL (reportMessage (const CSMWorld::UniversalId&, const std::string&, const std::string&, int)),
this, SLOT (verifierMessage (const CSMWorld::UniversalId&, const std::string&, int))); this, SLOT (verifierMessage (const CSMWorld::UniversalId&, const std::string&, const std::string&, int)));
std::vector<std::string> mandatoryIds; // I want C++11, damn it! std::vector<std::string> mandatoryIds; // I want C++11, damn it!
mandatoryIds.push_back ("Day"); mandatoryIds.push_back ("Day");
@ -155,11 +155,11 @@ CSMTools::ReportModel *CSMTools::Tools::getReport (const CSMWorld::UniversalId&
} }
void CSMTools::Tools::verifierMessage (const CSMWorld::UniversalId& id, const std::string& message, void CSMTools::Tools::verifierMessage (const CSMWorld::UniversalId& id, const std::string& message,
int type) const std::string& hint, int type)
{ {
std::map<int, int>::iterator iter = mActiveReports.find (type); std::map<int, int>::iterator iter = mActiveReports.find (type);
if (iter!=mActiveReports.end()) if (iter!=mActiveReports.end())
mReports[iter->second]->add (id, message); mReports[iter->second]->add (id, message, hint);
} }

@ -64,7 +64,7 @@ namespace CSMTools
private slots: private slots:
void verifierMessage (const CSMWorld::UniversalId& id, const std::string& message, void verifierMessage (const CSMWorld::UniversalId& id, const std::string& message,
int type); const std::string& hint, int type);
signals: signals:

@ -272,7 +272,7 @@ namespace CSMWorld
{ {
ESXRecordT record2 = record.get(); ESXRecordT record2 = record.get();
record2.mData.mUseValue[mIndex] = data.toInt(); record2.mData.mUseValue[mIndex] = data.toFloat();
record.setModified (record2); record.setModified (record2);
} }

@ -671,16 +671,24 @@ int CSMWorld::Data::startLoading (const boost::filesystem::path& path, bool base
return mReader->getRecordCount(); return mReader->getRecordCount();
} }
bool CSMWorld::Data::continueLoading (CSMDoc::Stage::Messages& messages) bool CSMWorld::Data::continueLoading (CSMDoc::Messages& messages)
{ {
if (!mReader) if (!mReader)
throw std::logic_error ("can't continue loading, because no load has been started"); throw std::logic_error ("can't continue loading, because no load has been started");
if (!mReader->hasMoreRecs()) if (!mReader->hasMoreRecs())
{ {
// Don't delete the Reader yet. Some record types store a reference to the Reader to handle on-demand loading if (mBase)
boost::shared_ptr<ESM::ESMReader> ptr(mReader); {
mReaders.push_back(ptr); // Don't delete the Reader yet. Some record types store a reference to the Reader to handle on-demand loading.
// We don't store non-base reader, because everything going into modified will be
// fully loaded during the initial loading process.
boost::shared_ptr<ESM::ESMReader> ptr(mReader);
mReaders.push_back(ptr);
}
else
delete mReader;
mReader = 0; mReader = 0;
mDialogue = 0; mDialogue = 0;
@ -713,7 +721,18 @@ bool CSMWorld::Data::continueLoading (CSMDoc::Stage::Messages& messages)
case ESM::REC_PGRD: mPathgrids.load (*mReader, mBase); break; case ESM::REC_PGRD: mPathgrids.load (*mReader, mBase); break;
case ESM::REC_LTEX: mLandTextures.load (*mReader, mBase); break; case ESM::REC_LTEX: mLandTextures.load (*mReader, mBase); break;
case ESM::REC_LAND: mLand.load(*mReader, mBase); break;
case ESM::REC_LAND:
{
int index = mLand.load(*mReader, mBase);
if (index!=-1 && !mBase)
mLand.getRecord (index).mModified.mLand->loadData (
ESM::Land::DATA_VHGT | ESM::Land::DATA_VNML | ESM::Land::DATA_VCLR |
ESM::Land::DATA_VTEX);
break;
}
case ESM::REC_CELL: case ESM::REC_CELL:
{ {
@ -775,8 +794,8 @@ bool CSMWorld::Data::continueLoading (CSMDoc::Stage::Messages& messages)
} }
else else
{ {
messages.push_back (std::make_pair (UniversalId::Type_None, messages.add (UniversalId::Type_None,
"Trying to delete dialogue record " + id + " which does not exist")); "Trying to delete dialogue record " + id + " which does not exist");
} }
} }
else else
@ -792,8 +811,8 @@ bool CSMWorld::Data::continueLoading (CSMDoc::Stage::Messages& messages)
{ {
if (!mDialogue) if (!mDialogue)
{ {
messages.push_back (std::make_pair (UniversalId::Type_None, messages.add (UniversalId::Type_None,
"Found info record not following a dialogue record")); "Found info record not following a dialogue record");
mReader->skipRecord(); mReader->skipRecord();
break; break;
@ -836,8 +855,7 @@ bool CSMWorld::Data::continueLoading (CSMDoc::Stage::Messages& messages)
if (unhandledRecord) if (unhandledRecord)
{ {
messages.push_back (std::make_pair (UniversalId::Type_None, messages.add (UniversalId::Type_None, "Unsupported record type: " + n.toString());
"Unsupported record type: " + n.toString()));
mReader->skipRecord(); mReader->skipRecord();
} }

@ -244,7 +244,7 @@ namespace CSMWorld
/// ///
///< \return estimated number of records ///< \return estimated number of records
bool continueLoading (CSMDoc::Stage::Messages& messages); bool continueLoading (CSMDoc::Messages& messages);
///< \return Finished? ///< \return Finished?
bool hasId (const std::string& id) const; bool hasId (const std::string& id) const;

@ -15,12 +15,15 @@ namespace CSMWorld
public: public:
void load (ESM::ESMReader& reader, bool base); /// \return Index of loaded record (-1 if no record was loaded)
int load (ESM::ESMReader& reader, bool base);
/// \param index Index at which the record can be found. /// \param index Index at which the record can be found.
/// Special values: -2 index unknown, -1 record does not exist yet and therefore /// Special values: -2 index unknown, -1 record does not exist yet and therefore
/// does not have an index /// does not have an index
void load (const ESXRecordT& record, bool base, int index = -2); ///
/// \return index
int load (const ESXRecordT& record, bool base, int index = -2);
bool tryDelete (const std::string& id); bool tryDelete (const std::string& id);
///< Try deleting \a id. If the id does not exist or can't be deleted the call is ignored. ///< Try deleting \a id. If the id does not exist or can't be deleted the call is ignored.
@ -36,7 +39,7 @@ namespace CSMWorld
} }
template<typename ESXRecordT, typename IdAccessorT> template<typename ESXRecordT, typename IdAccessorT>
void IdCollection<ESXRecordT, IdAccessorT>::load (ESM::ESMReader& reader, bool base) int IdCollection<ESXRecordT, IdAccessorT>::load (ESM::ESMReader& reader, bool base)
{ {
std::string id = reader.getHNOString ("NAME"); std::string id = reader.getHNOString ("NAME");
@ -64,6 +67,8 @@ namespace CSMWorld
record.mState = RecordBase::State_Deleted; record.mState = RecordBase::State_Deleted;
this->setRecord (index, record); this->setRecord (index, record);
} }
return -1;
} }
else else
{ {
@ -88,12 +93,12 @@ namespace CSMWorld
index = newIndex; index = newIndex;
} }
load (record, base, index); return load (record, base, index);
} }
} }
template<typename ESXRecordT, typename IdAccessorT> template<typename ESXRecordT, typename IdAccessorT>
void IdCollection<ESXRecordT, IdAccessorT>::load (const ESXRecordT& record, bool base, int IdCollection<ESXRecordT, IdAccessorT>::load (const ESXRecordT& record, bool base,
int index) int index)
{ {
if (index==-2) if (index==-2)
@ -106,6 +111,7 @@ namespace CSMWorld
record2.mState = base ? RecordBase::State_BaseOnly : RecordBase::State_ModifiedOnly; record2.mState = base ? RecordBase::State_BaseOnly : RecordBase::State_ModifiedOnly;
(base ? record2.mBase : record2.mModified) = record; (base ? record2.mBase : record2.mModified) = record;
index = this->getSize();
this->appendRecord (record2); this->appendRecord (record2);
} }
else else
@ -120,6 +126,8 @@ namespace CSMWorld
this->setRecord (index, record2); this->setRecord (index, record2);
} }
return index;
} }
template<typename ESXRecordT, typename IdAccessorT> template<typename ESXRecordT, typename IdAccessorT>

@ -11,7 +11,7 @@
#include "record.hpp" #include "record.hpp"
void CSMWorld::RefCollection::load (ESM::ESMReader& reader, int cellIndex, bool base, void CSMWorld::RefCollection::load (ESM::ESMReader& reader, int cellIndex, bool base,
std::map<ESM::RefNum, std::string>& cache, CSMDoc::Stage::Messages& messages) std::map<ESM::RefNum, std::string>& cache, CSMDoc::Messages& messages)
{ {
Record<Cell> cell = mCells.getRecord (cellIndex); Record<Cell> cell = mCells.getRecord (cellIndex);
@ -36,8 +36,7 @@ void CSMWorld::RefCollection::load (ESM::ESMReader& reader, int cellIndex, bool
CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Cell, CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Cell,
mCells.getId (cellIndex)); mCells.getId (cellIndex));
messages.push_back (std::make_pair (id, messages.add (id, "Attempt to delete a non-existing reference");
"Attempt to delete a non-existing reference"));
continue; continue;
} }

@ -28,7 +28,7 @@ namespace CSMWorld
void load (ESM::ESMReader& reader, int cellIndex, bool base, void load (ESM::ESMReader& reader, int cellIndex, bool base,
std::map<ESM::RefNum, std::string>& cache, std::map<ESM::RefNum, std::string>& cache,
CSMDoc::Stage::Messages& messages); CSMDoc::Messages& messages);
///< Load a sequence of references. ///< Load a sequence of references.
std::string getNewId(); std::string getNewId();

@ -3,6 +3,7 @@
#include <sstream> #include <sstream>
#include <stdexcept> #include <stdexcept>
#include <algorithm>
#include <OgreResourceGroupManager.h> #include <OgreResourceGroupManager.h>
@ -55,7 +56,9 @@ CSMWorld::Resources::Resources (const std::string& baseDirectory, UniversalId::T
std::string file = iter->substr (baseSize+1); std::string file = iter->substr (baseSize+1);
mFiles.push_back (file); mFiles.push_back (file);
mIndex.insert (std::make_pair (file, static_cast<int> (mFiles.size())-1)); std::replace (file.begin(), file.end(), '\\', '/');
mIndex.insert (std::make_pair (
Misc::StringUtils::lowerCase (file), static_cast<int> (mFiles.size())-1));
} }
} }
} }
@ -89,6 +92,8 @@ int CSMWorld::Resources::searchId (const std::string& id) const
{ {
std::string id2 = Misc::StringUtils::lowerCase (id); std::string id2 = Misc::StringUtils::lowerCase (id);
std::replace (id2.begin(), id2.end(), '\\', '/');
std::map<std::string, int>::const_iterator iter = mIndex.find (id2); std::map<std::string, int>::const_iterator iter = mIndex.find (id2);
if (iter==mIndex.end()) if (iter==mIndex.end())

@ -16,7 +16,6 @@
#include "../../model/world/idtable.hpp" #include "../../model/world/idtable.hpp"
#include "../world/subviews.hpp" #include "../world/subviews.hpp"
#include "../world/physicsmanager.hpp"
#include "../tools/subviews.hpp" #include "../tools/subviews.hpp"
@ -407,8 +406,6 @@ CSVDoc::View::View (ViewManager& viewManager, CSMDoc::Document *document, int to
mSubViewFactory.add (CSMWorld::UniversalId::Type_RunLog, new SubViewFactory<RunLogSubView>); mSubViewFactory.add (CSMWorld::UniversalId::Type_RunLog, new SubViewFactory<RunLogSubView>);
connect (mOperations, SIGNAL (abortOperation (int)), this, SLOT (abortOperation (int))); connect (mOperations, SIGNAL (abortOperation (int)), this, SLOT (abortOperation (int)));
CSVWorld::PhysicsManager::instance()->setupPhysics(document);
} }
CSVDoc::View::~View() CSVDoc::View::~View()

@ -16,7 +16,6 @@
#include "../world/vartypedelegate.hpp" #include "../world/vartypedelegate.hpp"
#include "../world/recordstatusdelegate.hpp" #include "../world/recordstatusdelegate.hpp"
#include "../world/idtypedelegate.hpp" #include "../world/idtypedelegate.hpp"
#include "../world/physicsmanager.hpp"
#include "../../model/settings/usersettings.hpp" #include "../../model/settings/usersettings.hpp"
@ -219,7 +218,6 @@ void CSVDoc::ViewManager::removeDocAndView (CSMDoc::Document *document)
mDocumentManager.removeDocument(document); mDocumentManager.removeDocument(document);
(*iter)->deleteLater(); (*iter)->deleteLater();
mViews.erase (iter); mViews.erase (iter);
CSVWorld::PhysicsManager::instance()->removeDocument(document);
updateIndices(); updateIndices();
return; return;

@ -60,7 +60,7 @@ bool CSVRender::Cell::addObjects (int start, int end)
} }
CSVRender::Cell::Cell (CSMWorld::Data& data, Ogre::SceneManager *sceneManager, CSVRender::Cell::Cell (CSMWorld::Data& data, Ogre::SceneManager *sceneManager,
const std::string& id, CSVWorld::PhysicsSystem *physics, const Ogre::Vector3& origin) const std::string& id, boost::shared_ptr<CSVWorld::PhysicsSystem> physics, const Ogre::Vector3& origin)
: mData (data), mId (Misc::StringUtils::lowerCase (id)), mSceneMgr(sceneManager), mPhysics(physics) : mData (data), mId (Misc::StringUtils::lowerCase (id)), mSceneMgr(sceneManager), mPhysics(physics)
{ {
mCellNode = sceneManager->getRootSceneNode()->createChildSceneNode(); mCellNode = sceneManager->getRootSceneNode()->createChildSceneNode();

@ -5,6 +5,8 @@
#include <map> #include <map>
#include <memory> #include <memory>
#include <boost/shared_ptr.hpp>
#include <OgreVector3.h> #include <OgreVector3.h>
#include <components/terrain/terraingrid.hpp> #include <components/terrain/terraingrid.hpp>
@ -38,7 +40,7 @@ namespace CSVRender
Ogre::SceneNode *mCellNode; Ogre::SceneNode *mCellNode;
std::map<std::string, Object *> mObjects; std::map<std::string, Object *> mObjects;
std::auto_ptr<Terrain::TerrainGrid> mTerrain; std::auto_ptr<Terrain::TerrainGrid> mTerrain;
CSVWorld::PhysicsSystem *mPhysics; boost::shared_ptr<CSVWorld::PhysicsSystem> mPhysics;
Ogre::SceneManager *mSceneMgr; Ogre::SceneManager *mSceneMgr;
int mX; int mX;
int mY; int mY;
@ -56,7 +58,7 @@ namespace CSVRender
public: public:
Cell (CSMWorld::Data& data, Ogre::SceneManager *sceneManager, const std::string& id, Cell (CSMWorld::Data& data, Ogre::SceneManager *sceneManager, const std::string& id,
CSVWorld::PhysicsSystem *physics, const Ogre::Vector3& origin = Ogre::Vector3 (0, 0, 0)); boost::shared_ptr<CSVWorld::PhysicsSystem> physics, const Ogre::Vector3& origin = Ogre::Vector3 (0, 0, 0));
~Cell(); ~Cell();

@ -56,7 +56,7 @@ namespace CSVRender
// //
MouseState::MouseState(WorldspaceWidget *parent) MouseState::MouseState(WorldspaceWidget *parent)
: mParent(parent), mPhysics(parent->getPhysics()), mSceneManager(parent->getSceneManager()) : mParent(parent), mPhysics(parent->mDocument.getPhysics()), mSceneManager(parent->getSceneManager())
, mCurrentObj(""), mMouseState(Mouse_Default), mOldPos(0,0), mMouseEventTimer(0), mPlane(0) , mCurrentObj(""), mMouseState(Mouse_Default), mOldPos(0,0), mMouseEventTimer(0), mPlane(0)
, mGrabbedSceneNode(""), mOrigObjPos(Ogre::Vector3()), mOrigMousePos(Ogre::Vector3()) , mGrabbedSceneNode(""), mOrigObjPos(Ogre::Vector3()), mOrigMousePos(Ogre::Vector3())
, mCurrentMousePos(Ogre::Vector3()), mOffset(0.0f) , mCurrentMousePos(Ogre::Vector3()), mOffset(0.0f)

@ -2,6 +2,7 @@
#define OPENCS_VIEW_MOUSESTATE_H #define OPENCS_VIEW_MOUSESTATE_H
#include <map> #include <map>
#include <boost/shared_ptr.hpp>
#include <QPoint> #include <QPoint>
#include <OgreVector3.h> #include <OgreVector3.h>
@ -43,7 +44,7 @@ namespace CSVRender
MouseStates mMouseState; MouseStates mMouseState;
WorldspaceWidget *mParent; WorldspaceWidget *mParent;
CSVWorld::PhysicsSystem *mPhysics; // local copy boost::shared_ptr<CSVWorld::PhysicsSystem> mPhysics;
Ogre::SceneManager *mSceneManager; // local copy Ogre::SceneManager *mSceneManager; // local copy
QPoint mOldPos; QPoint mOldPos;

@ -132,7 +132,7 @@ const CSMWorld::CellRef& CSVRender::Object::getReference() const
} }
CSVRender::Object::Object (const CSMWorld::Data& data, Ogre::SceneNode *cellNode, CSVRender::Object::Object (const CSMWorld::Data& data, Ogre::SceneNode *cellNode,
const std::string& id, bool referenceable, CSVWorld::PhysicsSystem *physics, const std::string& id, bool referenceable, boost::shared_ptr<CSVWorld::PhysicsSystem> physics,
bool forceBaseToZero) bool forceBaseToZero)
: mData (data), mBase (0), mForceBaseToZero (forceBaseToZero), mPhysics(physics) : mData (data), mBase (0), mForceBaseToZero (forceBaseToZero), mPhysics(physics)
{ {
@ -156,7 +156,8 @@ CSVRender::Object::~Object()
{ {
clear(); clear();
mPhysics->removeObject(mBase->getName()); if(mPhysics) // preview may not have physics enabled
mPhysics->removeObject(mBase->getName());
if (mBase) if (mBase)
mBase->getCreator()->destroySceneNode (mBase); mBase->getCreator()->destroySceneNode (mBase);

@ -1,6 +1,8 @@
#ifndef OPENCS_VIEW_OBJECT_H #ifndef OPENCS_VIEW_OBJECT_H
#define OPENCS_VIEW_OBJECT_H #define OPENCS_VIEW_OBJECT_H
#include <boost/shared_ptr.hpp>
#include <components/nifogre/ogrenifloader.hpp> #include <components/nifogre/ogrenifloader.hpp>
class QModelIndex; class QModelIndex;
@ -31,7 +33,7 @@ namespace CSVRender
Ogre::SceneNode *mBase; Ogre::SceneNode *mBase;
NifOgre::ObjectScenePtr mObject; NifOgre::ObjectScenePtr mObject;
bool mForceBaseToZero; bool mForceBaseToZero;
CSVWorld::PhysicsSystem *mPhysics; boost::shared_ptr<CSVWorld::PhysicsSystem> mPhysics;
/// Not implemented /// Not implemented
Object (const Object&); Object (const Object&);
@ -58,7 +60,8 @@ namespace CSVRender
Object (const CSMWorld::Data& data, Ogre::SceneNode *cellNode, Object (const CSMWorld::Data& data, Ogre::SceneNode *cellNode,
const std::string& id, bool referenceable, const std::string& id, bool referenceable,
CSVWorld::PhysicsSystem *physics = NULL, bool forceBaseToZero = false); boost::shared_ptr<CSVWorld::PhysicsSystem> physics = boost::shared_ptr<CSVWorld::PhysicsSystem> (),
bool forceBaseToZero = false);
/// \param forceBaseToZero If this is a reference ignore the coordinates and place /// \param forceBaseToZero If this is a reference ignore the coordinates and place
/// it at 0, 0, 0 instead. /// it at 0, 0, 0 instead.

@ -22,6 +22,7 @@
#include "../widget/scenetooltoggle.hpp" #include "../widget/scenetooltoggle.hpp"
#include "../widget/scenetoolmode.hpp" #include "../widget/scenetoolmode.hpp"
#include "../widget/scenetooltoggle2.hpp"
#include "editmode.hpp" #include "editmode.hpp"
#include "elements.hpp" #include "elements.hpp"
@ -111,7 +112,7 @@ bool CSVRender::PagedWorldspaceWidget::adjustCells()
mCells.find (*iter)==mCells.end()) mCells.find (*iter)==mCells.end())
{ {
Cell *cell = new Cell (mDocument.getData(), getSceneManager(), Cell *cell = new Cell (mDocument.getData(), getSceneManager(),
iter->getId (mWorldspace), getPhysics()); iter->getId (mWorldspace), mDocument.getPhysics());
mCells.insert (std::make_pair (*iter, cell)); mCells.insert (std::make_pair (*iter, cell));
float height = cell->getTerrainHeightAt(Ogre::Vector3( float height = cell->getTerrainHeightAt(Ogre::Vector3(
@ -212,6 +213,14 @@ void CSVRender::PagedWorldspaceWidget::mouseDoubleClickEvent (QMouseEvent *event
WorldspaceWidget::mouseDoubleClickEvent(event); WorldspaceWidget::mouseDoubleClickEvent(event);
} }
void CSVRender::PagedWorldspaceWidget::addVisibilitySelectorButtons (
CSVWidget::SceneToolToggle2 *tool)
{
WorldspaceWidget::addVisibilitySelectorButtons (tool);
tool->addButton (Element_Terrain, "Terrain");
tool->addButton (Element_Fog, "Fog", "", true);
}
void CSVRender::PagedWorldspaceWidget::addEditModeSelectorButtons ( void CSVRender::PagedWorldspaceWidget::addEditModeSelectorButtons (
CSVWidget::SceneToolMode *tool) CSVWidget::SceneToolMode *tool)
{ {
@ -362,8 +371,11 @@ CSVRender::PagedWorldspaceWidget::~PagedWorldspaceWidget()
delete iter->second; delete iter->second;
} }
removeRenderTargetListener(mOverlayMask); if(mOverlayMask)
delete mOverlayMask; {
removeRenderTargetListener(mOverlayMask);
delete mOverlayMask;
}
} }
void CSVRender::PagedWorldspaceWidget::useViewHint (const std::string& hint) void CSVRender::PagedWorldspaceWidget::useViewHint (const std::string& hint)

@ -83,6 +83,8 @@ namespace CSVRender
protected: protected:
virtual void addVisibilitySelectorButtons (CSVWidget::SceneToolToggle2 *tool);
virtual void addEditModeSelectorButtons (CSVWidget::SceneToolMode *tool); virtual void addEditModeSelectorButtons (CSVWidget::SceneToolMode *tool);
virtual void updateOverlay(); virtual void updateOverlay();

@ -10,7 +10,7 @@
CSVRender::PreviewWidget::PreviewWidget (CSMWorld::Data& data, CSVRender::PreviewWidget::PreviewWidget (CSMWorld::Data& data,
const std::string& id, bool referenceable, QWidget *parent) const std::string& id, bool referenceable, QWidget *parent)
: SceneWidget (parent), mData (data), : SceneWidget (parent), mData (data),
mObject (data, getSceneManager()->getRootSceneNode(), id, referenceable, NULL, true) mObject (data, getSceneManager()->getRootSceneNode(), id, referenceable, boost::shared_ptr<CSVWorld::PhysicsSystem>(), true)
{ {
setNavigation (&mOrbit); setNavigation (&mOrbit);

@ -49,7 +49,7 @@ CSVRender::UnpagedWorldspaceWidget::UnpagedWorldspaceWidget (const std::string&
update(); update();
mCell.reset (new Cell (document.getData(), getSceneManager(), mCellId, getPhysics())); mCell.reset (new Cell (document.getData(), getSceneManager(), mCellId, document.getPhysics()));
} }
void CSVRender::UnpagedWorldspaceWidget::cellDataChanged (const QModelIndex& topLeft, void CSVRender::UnpagedWorldspaceWidget::cellDataChanged (const QModelIndex& topLeft,
@ -91,7 +91,7 @@ bool CSVRender::UnpagedWorldspaceWidget::handleDrop (const std::vector<CSMWorld:
return false; return false;
mCellId = data.begin()->getId(); mCellId = data.begin()->getId();
mCell.reset (new Cell (getDocument().getData(), getSceneManager(), mCellId, getPhysics())); mCell.reset (new Cell (getDocument().getData(), getSceneManager(), mCellId, getDocument().getPhysics()));
update(); update();
emit cellChanged(*data.begin()); emit cellChanged(*data.begin());
@ -153,6 +153,14 @@ void CSVRender::UnpagedWorldspaceWidget::referenceAdded (const QModelIndex& pare
flagAsModified(); flagAsModified();
} }
void CSVRender::UnpagedWorldspaceWidget::addVisibilitySelectorButtons (
CSVWidget::SceneToolToggle2 *tool)
{
WorldspaceWidget::addVisibilitySelectorButtons (tool);
tool->addButton (Element_Terrain, "Terrain", "", true);
tool->addButton (Element_Fog, "Fog");
}
std::string CSVRender::UnpagedWorldspaceWidget::getStartupInstruction() std::string CSVRender::UnpagedWorldspaceWidget::getStartupInstruction()
{ {
Ogre::Vector3 position = getCamera()->getPosition(); Ogre::Vector3 position = getCamera()->getPosition();

@ -60,6 +60,10 @@ namespace CSVRender
virtual std::string getStartupInstruction(); virtual std::string getStartupInstruction();
protected:
virtual void addVisibilitySelectorButtons (CSVWidget::SceneToolToggle2 *tool);
private slots: private slots:
void cellDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight); void cellDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight);

@ -16,14 +16,13 @@
#include "../widget/scenetooltoggle2.hpp" #include "../widget/scenetooltoggle2.hpp"
#include "../widget/scenetoolrun.hpp" #include "../widget/scenetoolrun.hpp"
#include "../world/physicsmanager.hpp"
#include "../world/physicssystem.hpp" #include "../world/physicssystem.hpp"
#include "elements.hpp" #include "elements.hpp"
#include "editmode.hpp" #include "editmode.hpp"
CSVRender::WorldspaceWidget::WorldspaceWidget (CSMDoc::Document& document, QWidget* parent) CSVRender::WorldspaceWidget::WorldspaceWidget (CSMDoc::Document& document, QWidget* parent)
: SceneWidget (parent), mDocument(document), mSceneElements(0), mRun(0), mPhysics(0), mMouse(0), : SceneWidget (parent), mDocument(document), mSceneElements(0), mRun(0), mPhysics(boost::shared_ptr<CSVWorld::PhysicsSystem>()), mMouse(0),
mInteractionMask (0) mInteractionMask (0)
{ {
setAcceptDrops(true); setAcceptDrops(true);
@ -56,9 +55,7 @@ CSVRender::WorldspaceWidget::WorldspaceWidget (CSMDoc::Document& document, QWidg
connect (debugProfiles, SIGNAL (rowsAboutToBeRemoved (const QModelIndex&, int, int)), connect (debugProfiles, SIGNAL (rowsAboutToBeRemoved (const QModelIndex&, int, int)),
this, SLOT (debugProfileAboutToBeRemoved (const QModelIndex&, int, int))); this, SLOT (debugProfileAboutToBeRemoved (const QModelIndex&, int, int)));
// associate WorldSpaceWidgets (and their SceneManagers) with Documents mPhysics = document.getPhysics(); // create physics if one doesn't exist
// then create physics if there is a new document
mPhysics = CSVWorld::PhysicsManager::instance()->addSceneWidget(document, this);
mPhysics->addSceneManager(getSceneManager(), this); mPhysics->addSceneManager(getSceneManager(), this);
mMouse = new MouseState(this); mMouse = new MouseState(this);
} }
@ -67,7 +64,6 @@ CSVRender::WorldspaceWidget::~WorldspaceWidget ()
{ {
delete mMouse; delete mMouse;
mPhysics->removeSceneManager(getSceneManager()); mPhysics->removeSceneManager(getSceneManager());
CSVWorld::PhysicsManager::instance()->removeSceneWidget(this);
} }
void CSVRender::WorldspaceWidget::selectNavigationMode (const std::string& mode) void CSVRender::WorldspaceWidget::selectNavigationMode (const std::string& mode)
@ -263,10 +259,8 @@ void CSVRender::WorldspaceWidget::addVisibilitySelectorButtons (
CSVWidget::SceneToolToggle2 *tool) CSVWidget::SceneToolToggle2 *tool)
{ {
tool->addButton (Element_Reference, "References"); tool->addButton (Element_Reference, "References");
tool->addButton (Element_Terrain, "Terrain");
tool->addButton (Element_Water, "Water"); tool->addButton (Element_Water, "Water");
tool->addButton (Element_Pathgrid, "Pathgrid"); tool->addButton (Element_Pathgrid, "Pathgrid");
tool->addButton (Element_Fog, "Fog");
} }
void CSVRender::WorldspaceWidget::addEditModeSelectorButtons (CSVWidget::SceneToolMode *tool) void CSVRender::WorldspaceWidget::addEditModeSelectorButtons (CSVWidget::SceneToolMode *tool)
@ -370,12 +364,6 @@ void CSVRender::WorldspaceWidget::updateOverlay()
{ {
} }
CSVWorld::PhysicsSystem *CSVRender::WorldspaceWidget::getPhysics()
{
assert(mPhysics);
return mPhysics;
}
void CSVRender::WorldspaceWidget::mouseMoveEvent (QMouseEvent *event) void CSVRender::WorldspaceWidget::mouseMoveEvent (QMouseEvent *event)
{ {
if(event->buttons() & Qt::RightButton) if(event->buttons() & Qt::RightButton)

@ -1,6 +1,8 @@
#ifndef OPENCS_VIEW_WORLDSPACEWIDGET_H #ifndef OPENCS_VIEW_WORLDSPACEWIDGET_H
#define OPENCS_VIEW_WORLDSPACEWIDGET_H #define OPENCS_VIEW_WORLDSPACEWIDGET_H
#include <boost/shared_ptr.hpp>
#include "scenewidget.hpp" #include "scenewidget.hpp"
#include "mousestate.hpp" #include "mousestate.hpp"
@ -40,7 +42,7 @@ namespace CSVRender
CSVWidget::SceneToolToggle2 *mSceneElements; CSVWidget::SceneToolToggle2 *mSceneElements;
CSVWidget::SceneToolRun *mRun; CSVWidget::SceneToolRun *mRun;
CSMDoc::Document& mDocument; CSMDoc::Document& mDocument;
CSVWorld::PhysicsSystem *mPhysics; boost::shared_ptr<CSVWorld::PhysicsSystem> mPhysics;
MouseState *mMouse; MouseState *mMouse;
unsigned int mInteractionMask; unsigned int mInteractionMask;
@ -115,8 +117,6 @@ namespace CSVRender
virtual void updateOverlay(); virtual void updateOverlay();
CSVWorld::PhysicsSystem *getPhysics();
virtual void mouseMoveEvent (QMouseEvent *event); virtual void mouseMoveEvent (QMouseEvent *event);
virtual void mousePressEvent (QMouseEvent *event); virtual void mousePressEvent (QMouseEvent *event);
virtual void mouseReleaseEvent (QMouseEvent *event); virtual void mouseReleaseEvent (QMouseEvent *event);

@ -1,31 +1,15 @@
#include "reportsubview.hpp" #include "reportsubview.hpp"
#include <QTableView> #include "reporttable.hpp"
#include <QHeaderView>
#include "../../model/tools/reportmodel.hpp"
#include "../../view/world/idtypedelegate.hpp"
CSVTools::ReportSubView::ReportSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document) CSVTools::ReportSubView::ReportSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document)
: CSVDoc::SubView (id), mModel (document.getReport (id)) : CSVDoc::SubView (id)
{ {
setWidget (mTable = new QTableView (this)); setWidget (mTable = new ReportTable (document, id, this));
mTable->setModel (mModel);
mTable->horizontalHeader()->setResizeMode (QHeaderView::Interactive);
mTable->verticalHeader()->hide();
mTable->setSortingEnabled (true);
mTable->setSelectionBehavior (QAbstractItemView::SelectRows);
mTable->setSelectionMode (QAbstractItemView::ExtendedSelection);
mIdTypeDelegate = CSVWorld::IdTypeDelegateFactory().makeDelegate (
document, this);
mTable->setItemDelegateForColumn (0, mIdTypeDelegate); connect (mTable, SIGNAL (editRequest (const CSMWorld::UniversalId&, const std::string&)),
SIGNAL (focusId (const CSMWorld::UniversalId&, const std::string&)));
connect (mTable, SIGNAL (doubleClicked (const QModelIndex&)), this, SLOT (show (const QModelIndex&)));
} }
void CSVTools::ReportSubView::setEditLock (bool locked) void CSVTools::ReportSubView::setEditLock (bool locked)
@ -33,13 +17,7 @@ void CSVTools::ReportSubView::setEditLock (bool locked)
// ignored. We don't change document state anyway. // ignored. We don't change document state anyway.
} }
void CSVTools::ReportSubView::updateUserSetting void CSVTools::ReportSubView::updateUserSetting (const QString &name, const QStringList &list)
(const QString &name, const QStringList &list)
{
mIdTypeDelegate->updateUserSetting (name, list);
}
void CSVTools::ReportSubView::show (const QModelIndex& index)
{ {
focusId (mModel->getUniversalId (index.row()), ""); mTable->updateUserSetting (name, list);
} }

@ -11,27 +11,15 @@ namespace CSMDoc
class Document; class Document;
} }
namespace CSMTools
{
class ReportModel;
}
namespace CSVWorld
{
class CommandDelegate;
}
namespace CSVTools namespace CSVTools
{ {
class Table; class ReportTable;
class ReportSubView : public CSVDoc::SubView class ReportSubView : public CSVDoc::SubView
{ {
Q_OBJECT Q_OBJECT
CSMTools::ReportModel *mModel; ReportTable *mTable;
QTableView *mTable;
CSVWorld::CommandDelegate *mIdTypeDelegate;
public: public:
@ -39,12 +27,7 @@ namespace CSVTools
virtual void setEditLock (bool locked); virtual void setEditLock (bool locked);
virtual void updateUserSetting virtual void updateUserSetting (const QString &, const QStringList &);
(const QString &, const QStringList &);
private slots:
void show (const QModelIndex& index);
}; };
} }

@ -0,0 +1,136 @@
#include "reporttable.hpp"
#include <algorithm>
#include <QHeaderView>
#include <QAction>
#include <QMenu>
#include "../../model/tools/reportmodel.hpp"
#include "../../view/world/idtypedelegate.hpp"
void CSVTools::ReportTable::contextMenuEvent (QContextMenuEvent *event)
{
QModelIndexList selectedRows = selectionModel()->selectedRows();
// create context menu
QMenu menu (this);
if (!selectedRows.empty())
{
menu.addAction (mShowAction);
menu.addAction (mRemoveAction);
}
menu.exec (event->globalPos());
}
void CSVTools::ReportTable::mouseMoveEvent (QMouseEvent *event)
{
if (event->buttons() & Qt::LeftButton)
startDrag (*this);
}
void CSVTools::ReportTable::mouseDoubleClickEvent (QMouseEvent *event)
{
Qt::KeyboardModifiers modifiers =
event->modifiers() & (Qt::ShiftModifier | Qt::ControlModifier);
QModelIndex index = currentIndex();
selectionModel()->select (index,
QItemSelectionModel::Clear | QItemSelectionModel::Select | QItemSelectionModel::Rows);
switch (modifiers)
{
case 0:
event->accept();
showSelection();
break;
case Qt::ShiftModifier:
event->accept();
removeSelection();
break;
case Qt::ControlModifier:
event->accept();
showSelection();
removeSelection();
break;
}
}
CSVTools::ReportTable::ReportTable (CSMDoc::Document& document,
const CSMWorld::UniversalId& id, QWidget *parent)
: CSVWorld::DragRecordTable (document, parent), mModel (document.getReport (id))
{
horizontalHeader()->setResizeMode (QHeaderView::Interactive);
verticalHeader()->hide();
setSortingEnabled (true);
setSelectionBehavior (QAbstractItemView::SelectRows);
setSelectionMode (QAbstractItemView::ExtendedSelection);
setModel (mModel);
setColumnHidden (2, true);
mIdTypeDelegate = CSVWorld::IdTypeDelegateFactory().makeDelegate (
document, this);
setItemDelegateForColumn (0, mIdTypeDelegate);
mShowAction = new QAction (tr ("Show"), this);
connect (mShowAction, SIGNAL (triggered()), this, SLOT (showSelection()));
addAction (mShowAction);
mRemoveAction = new QAction (tr ("Remove from list"), this);
connect (mRemoveAction, SIGNAL (triggered()), this, SLOT (removeSelection()));
addAction (mRemoveAction);
}
std::vector<CSMWorld::UniversalId> CSVTools::ReportTable::getDraggedRecords() const
{
std::vector<CSMWorld::UniversalId> ids;
QModelIndexList selectedRows = selectionModel()->selectedRows();
for (QModelIndexList::const_iterator iter (selectedRows.begin()); iter!=selectedRows.end();
++iter)
{
ids.push_back (mModel->getUniversalId (iter->row()));
}
return ids;
}
void CSVTools::ReportTable::updateUserSetting (const QString& name, const QStringList& list)
{
mIdTypeDelegate->updateUserSetting (name, list);
}
void CSVTools::ReportTable::showSelection()
{
QModelIndexList selectedRows = selectionModel()->selectedRows();
for (QModelIndexList::const_iterator iter (selectedRows.begin()); iter!=selectedRows.end();
++iter)
emit editRequest (mModel->getUniversalId (iter->row()), mModel->getHint (iter->row()));
}
void CSVTools::ReportTable::removeSelection()
{
QModelIndexList selectedRows = selectionModel()->selectedRows();
std::reverse (selectedRows.begin(), selectedRows.end());
for (QModelIndexList::const_iterator iter (selectedRows.begin()); iter!=selectedRows.end();
++iter)
mModel->removeRows (iter->row(), 1);
selectionModel()->clear();
}

@ -0,0 +1,58 @@
#ifndef CSV_TOOLS_REPORTTABLE_H
#define CSV_TOOLS_REPORTTABLE_H
#include "../world/dragrecordtable.hpp"
class QAction;
namespace CSMTools
{
class ReportModel;
}
namespace CSVWorld
{
class CommandDelegate;
}
namespace CSVTools
{
class ReportTable : public CSVWorld::DragRecordTable
{
Q_OBJECT
CSMTools::ReportModel *mModel;
CSVWorld::CommandDelegate *mIdTypeDelegate;
QAction *mShowAction;
QAction *mRemoveAction;
private:
void contextMenuEvent (QContextMenuEvent *event);
void mouseMoveEvent (QMouseEvent *event);
virtual void mouseDoubleClickEvent (QMouseEvent *event);
public:
ReportTable (CSMDoc::Document& document, const CSMWorld::UniversalId& id,
QWidget *parent = 0);
virtual std::vector<CSMWorld::UniversalId> getDraggedRecords() const;
void updateUserSetting (const QString& name, const QStringList& list);
private slots:
void showSelection();
void removeSelection();
signals:
void editRequest (const CSMWorld::UniversalId& id, const std::string& hint);
};
}
#endif

@ -72,7 +72,7 @@ void CSVWidget::SceneToolToggle2::showPanel (const QPoint& position)
} }
void CSVWidget::SceneToolToggle2::addButton (unsigned int id, void CSVWidget::SceneToolToggle2::addButton (unsigned int id,
const QString& name, const QString& tooltip) const QString& name, const QString& tooltip, bool disabled)
{ {
std::ostringstream stream; std::ostringstream stream;
stream << mSingleIcon << id; stream << mSingleIcon << id;
@ -84,6 +84,9 @@ void CSVWidget::SceneToolToggle2::addButton (unsigned int id,
button->setIconSize (QSize (mIconSize, mIconSize)); button->setIconSize (QSize (mIconSize, mIconSize));
button->setFixedSize (mButtonSize, mButtonSize); button->setFixedSize (mButtonSize, mButtonSize);
if (disabled)
button->setDisabled (true);
mLayout->addWidget (button); mLayout->addWidget (button);
ButtonDesc desc; ButtonDesc desc;
@ -95,7 +98,7 @@ void CSVWidget::SceneToolToggle2::addButton (unsigned int id,
connect (button, SIGNAL (clicked()), this, SLOT (selected())); connect (button, SIGNAL (clicked()), this, SLOT (selected()));
if (mButtons.size()==1) if (mButtons.size()==1 && !disabled)
mFirst = button; mFirst = button;
} }

@ -56,7 +56,7 @@ namespace CSVWidget
/// \attention After the last button has been added, setSelection must be called at /// \attention After the last button has been added, setSelection must be called at
/// least once to finalise the layout. /// least once to finalise the layout.
void addButton (unsigned int id, void addButton (unsigned int id,
const QString& name, const QString& tooltip = ""); const QString& name, const QString& tooltip = "", bool disabled = false);
unsigned int getSelection() const; unsigned int getSelection() const;

@ -1,110 +0,0 @@
#include "physicsmanager.hpp"
#include <iostream>
#include <openengine/bullet/BulletShapeLoader.h>
#include "../render/worldspacewidget.hpp"
#include "physicssystem.hpp"
namespace CSVWorld
{
PhysicsManager *PhysicsManager::mPhysicsManagerInstance = 0;
PhysicsManager::PhysicsManager()
{
assert(!mPhysicsManagerInstance);
mPhysicsManagerInstance = this;
}
PhysicsManager::~PhysicsManager()
{
std::map<CSMDoc::Document *, CSVWorld::PhysicsSystem *>::iterator iter = mPhysics.begin();
for(; iter != mPhysics.end(); ++iter)
delete iter->second; // shouldn't be any left but just in case
}
PhysicsManager *PhysicsManager::instance()
{
assert(mPhysicsManagerInstance);
return mPhysicsManagerInstance;
}
// create a physics instance per document, called from CSVDoc::View() to get Document*
void PhysicsManager::setupPhysics(CSMDoc::Document *doc)
{
std::map<CSMDoc::Document *, std::list<CSVRender::SceneWidget *> >::iterator iter = mSceneWidgets.find(doc);
if(iter == mSceneWidgets.end())
{
mSceneWidgets[doc] = std::list<CSVRender::SceneWidget *> (); // zero elements
mPhysics[doc] = new PhysicsSystem();
}
}
// destroy physics, called from CSVDoc::ViewManager
void PhysicsManager::removeDocument(CSMDoc::Document *doc)
{
std::map<CSMDoc::Document *, CSVWorld::PhysicsSystem *>::iterator iter = mPhysics.find(doc);
if(iter != mPhysics.end())
{
delete iter->second;
mPhysics.erase(iter);
}
std::map<CSMDoc::Document *, std::list<CSVRender::SceneWidget *> >::iterator it = mSceneWidgets.find(doc);
if(it != mSceneWidgets.end())
{
mSceneWidgets.erase(it);
}
// cleanup global resources used by OEngine
if(mPhysics.empty())
{
delete OEngine::Physic::BulletShapeManager::getSingletonPtr();
}
}
// called from CSVRender::WorldspaceWidget() to get widgets' association with Document&
PhysicsSystem *PhysicsManager::addSceneWidget(CSMDoc::Document &doc, CSVRender::WorldspaceWidget *widget)
{
CSVRender::SceneWidget *sceneWidget = static_cast<CSVRender::SceneWidget *>(widget);
std::map<CSMDoc::Document *, std::list<CSVRender::SceneWidget *> >::iterator iter = mSceneWidgets.begin();
for(; iter != mSceneWidgets.end(); ++iter)
{
if((*iter).first == &doc)
{
(*iter).second.push_back(sceneWidget);
return mPhysics[(*iter).first]; // TODO: consider using shared_ptr instead
}
}
throw std::runtime_error("No physics system found for the given document.");
}
// deprecated by removeDocument() and may be deleted in future code updates
// however there may be some value in removing the deleted scene widgets from the
// list so that the list does not grow forever
void PhysicsManager::removeSceneWidget(CSVRender::WorldspaceWidget *widget)
{
CSVRender::SceneWidget *sceneWidget = static_cast<CSVRender::SceneWidget *>(widget);
std::map<CSMDoc::Document *, std::list<CSVRender::SceneWidget *> >::iterator iter = mSceneWidgets.begin();
for(; iter != mSceneWidgets.end(); ++iter)
{
std::list<CSVRender::SceneWidget *>::iterator itWidget = (*iter).second.begin();
for(; itWidget != (*iter).second.end(); ++itWidget)
{
if((*itWidget) == sceneWidget)
{
(*iter).second.erase(itWidget);
//if((*iter).second.empty()) // last one for the document
// NOTE: do not delete physics until the document itself is closed
break;
}
}
}
}
}

@ -1,54 +0,0 @@
#ifndef CSV_WORLD_PHYSICSMANAGER_H
#define CSV_WORLD_PHYSICSMANAGER_H
#include <map>
#include <list>
namespace Ogre
{
class SceneManager;
}
namespace CSMDoc
{
class Document;
}
namespace CSVRender
{
class WorldspaceWidget;
class SceneWidget;
}
namespace CSVWorld
{
class PhysicsSystem;
}
namespace CSVWorld
{
class PhysicsManager
{
static PhysicsManager *mPhysicsManagerInstance;
std::map<CSMDoc::Document *, std::list<CSVRender::SceneWidget *> > mSceneWidgets;
std::map<CSMDoc::Document *, CSVWorld::PhysicsSystem *> mPhysics;
public:
PhysicsManager();
~PhysicsManager();
static PhysicsManager *instance();
void setupPhysics(CSMDoc::Document *);
PhysicsSystem *addSceneWidget(CSMDoc::Document &doc, CSVRender::WorldspaceWidget *widget);
void removeSceneWidget(CSVRender::WorldspaceWidget *widget);
void removeDocument(CSMDoc::Document *doc);
};
}
#endif // CSV_WORLD_PHYSICSMANAGER_H

@ -47,6 +47,32 @@ void CSVWorld::ScriptSubView::setEditLock (bool locked)
mEditor->setReadOnly (locked); mEditor->setReadOnly (locked);
} }
void CSVWorld::ScriptSubView::useHint (const std::string& hint)
{
if (hint.empty())
return;
if (hint[0]=='l')
{
std::istringstream stream (hint.c_str()+1);
char ignore;
int line;
int column;
if (stream >> ignore >> line >> column)
{
QTextCursor cursor = mEditor->textCursor();
cursor.movePosition (QTextCursor::Start);
if (cursor.movePosition (QTextCursor::Down, QTextCursor::MoveAnchor, line))
cursor.movePosition (QTextCursor::Right, QTextCursor::MoveAnchor, column);
mEditor->setTextCursor (cursor);
}
}
}
void CSVWorld::ScriptSubView::textChanged() void CSVWorld::ScriptSubView::textChanged()
{ {
if (mEditor->isChangeLocked()) if (mEditor->isChangeLocked())

@ -34,6 +34,8 @@ namespace CSVWorld
virtual void setEditLock (bool locked); virtual void setEditLock (bool locked);
virtual void useHint (const std::string& hint);
public slots: public slots:
void textChanged(); void textChanged();

@ -173,6 +173,8 @@ QWidget *CSVWorld::CommandDelegate::createEditor (QWidget *parent, const QStyleO
{ {
QDoubleSpinBox *dsb = new QDoubleSpinBox(parent); QDoubleSpinBox *dsb = new QDoubleSpinBox(parent);
dsb->setRange(FLT_MIN, FLT_MAX); dsb->setRange(FLT_MIN, FLT_MAX);
dsb->setSingleStep(0.01f);
dsb->setDecimals(3);
return dsb; return dsb;
} }

@ -40,11 +40,11 @@ add_openmw_dir (mwgui
merchantrepair repair soulgemdialog companionwindow bookpage journalviewmodel journalbooks merchantrepair repair soulgemdialog companionwindow bookpage journalviewmodel journalbooks
itemmodel containeritemmodel inventoryitemmodel sortfilteritemmodel itemview itemmodel containeritemmodel inventoryitemmodel sortfilteritemmodel itemview
tradeitemmodel companionitemmodel pickpocketitemmodel controllers savegamedialog tradeitemmodel companionitemmodel pickpocketitemmodel controllers savegamedialog
recharge mode videowidget backgroundimage itemwidget screenfader debugwindow recharge mode videowidget backgroundimage itemwidget screenfader debugwindow spellmodel spellview
) )
add_openmw_dir (mwdialogue add_openmw_dir (mwdialogue
dialoguemanagerimp journalimp journalentry quest topic filter selectwrapper hypertextparser keywordsearch dialoguemanagerimp journalimp journalentry quest topic filter selectwrapper hypertextparser keywordsearch scripttest
) )
add_openmw_dir (mwscript add_openmw_dir (mwscript

@ -40,6 +40,7 @@
#include "mwdialogue/dialoguemanagerimp.hpp" #include "mwdialogue/dialoguemanagerimp.hpp"
#include "mwdialogue/journalimp.hpp" #include "mwdialogue/journalimp.hpp"
#include "mwdialogue/scripttest.hpp"
#include "mwmechanics/mechanicsmanagerimp.hpp" #include "mwmechanics/mechanicsmanagerimp.hpp"
@ -79,8 +80,7 @@ bool OMW::Engine::frameRenderingQueued (const Ogre::FrameEvent& evt)
{ {
try try
{ {
float frametime = std::min(evt.timeSinceLastFrame, 0.2f); float frametime = evt.timeSinceLastFrame;
mEnvironment.setFrameDuration (frametime); mEnvironment.setFrameDuration (frametime);
// update input // update input
@ -175,6 +175,7 @@ OMW::Engine::Engine(Files::ConfigurationManager& configurationManager)
, mSkipMenu (false) , mSkipMenu (false)
, mUseSound (true) , mUseSound (true)
, mCompileAll (false) , mCompileAll (false)
, mCompileAllDialogue (false)
, mWarningsMode (1) , mWarningsMode (1)
, mScriptContext (0) , mScriptContext (0)
, mFSStrict (false) , mFSStrict (false)
@ -426,7 +427,6 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings)
if (mCompileAll) if (mCompileAll)
{ {
std::pair<int, int> result = MWBase::Environment::get().getScriptManager()->compileAll(); std::pair<int, int> result = MWBase::Environment::get().getScriptManager()->compileAll();
if (result.first) if (result.first)
std::cout std::cout
<< "compiled " << result.second << " of " << result.first << " scripts (" << "compiled " << result.second << " of " << result.first << " scripts ("
@ -434,6 +434,16 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings)
<< "%)" << "%)"
<< std::endl; << std::endl;
} }
if (mCompileAllDialogue)
{
std::pair<int, int> result = MWDialogue::ScriptTest::compileAll(&mExtensions, mWarningsMode);
if (result.first)
std::cout
<< "compiled " << result.second << " of " << result.first << " dialogue script/actor combinations a("
<< 100*static_cast<double> (result.second)/result.first
<< "%)"
<< std::endl;
}
} }
// Initialise and enter main loop. // Initialise and enter main loop.
@ -478,9 +488,15 @@ void OMW::Engine::go()
} }
// Start the main rendering loop // Start the main rendering loop
Ogre::Timer timer;
while (!MWBase::Environment::get().getStateManager()->hasQuitRequest()) while (!MWBase::Environment::get().getStateManager()->hasQuitRequest())
Ogre::Root::getSingleton().renderOneFrame(); {
float dt = timer.getMilliseconds()/1000.f;
dt = std::min(dt, 0.2f);
timer.reset();
Ogre::Root::getSingleton().renderOneFrame(dt);
}
// Save user settings // Save user settings
settings.saveUser(settingspath); settings.saveUser(settingspath);
@ -500,6 +516,14 @@ void OMW::Engine::activate()
if (ptr.getClass().getName(ptr) == "") // objects without name presented to user can never be activated if (ptr.getClass().getName(ptr) == "") // objects without name presented to user can never be activated
return; return;
if (ptr.getClass().isActor())
{
MWMechanics::CreatureStats &stats = ptr.getClass().getCreatureStats(ptr);
if (stats.getAiSequence().isInCombat() && !stats.isDead())
return;
}
MWBase::Environment::get().getWorld()->activate(ptr, MWBase::Environment::get().getWorld()->getPlayerPtr()); MWBase::Environment::get().getWorld()->activate(ptr, MWBase::Environment::get().getWorld()->getPlayerPtr());
} }
@ -530,6 +554,11 @@ void OMW::Engine::setCompileAll (bool all)
mCompileAll = all; mCompileAll = all;
} }
void OMW::Engine::setCompileAllDialogue (bool all)
{
mCompileAllDialogue = all;
}
void OMW::Engine::setSoundUsage(bool soundUsage) void OMW::Engine::setSoundUsage(bool soundUsage)
{ {
mUseSound = soundUsage; mUseSound = soundUsage;

@ -76,6 +76,7 @@ namespace OMW
bool mSkipMenu; bool mSkipMenu;
bool mUseSound; bool mUseSound;
bool mCompileAll; bool mCompileAll;
bool mCompileAllDialogue;
int mWarningsMode; int mWarningsMode;
std::string mFocusName; std::string mFocusName;
std::map<std::string,std::string> mFallbackMap; std::map<std::string,std::string> mFallbackMap;
@ -178,6 +179,9 @@ namespace OMW
/// Compile all scripts (excludign dialogue scripts) at startup? /// Compile all scripts (excludign dialogue scripts) at startup?
void setCompileAll (bool all); void setCompileAll (bool all);
/// Compile all dialogue scripts at startup?
void setCompileAllDialogue (bool all);
/// Font encoding /// Font encoding
void setEncoding(const ToUTF8::FromType& encoding); void setEncoding(const ToUTF8::FromType& encoding);

@ -130,6 +130,9 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat
("script-all", bpo::value<bool>()->implicit_value(true) ("script-all", bpo::value<bool>()->implicit_value(true)
->default_value(false), "compile all scripts (excluding dialogue scripts) at startup") ->default_value(false), "compile all scripts (excluding dialogue scripts) at startup")
("script-all-dialogue", bpo::value<bool>()->implicit_value(true)
->default_value(false), "compile all dialogue scripts at startup")
("script-console", bpo::value<bool>()->implicit_value(true) ("script-console", bpo::value<bool>()->implicit_value(true)
->default_value(false), "enable console-only script functionality") ->default_value(false), "enable console-only script functionality")
@ -264,6 +267,7 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat
// scripts // scripts
engine.setCompileAll(variables["script-all"].as<bool>()); engine.setCompileAll(variables["script-all"].as<bool>());
engine.setCompileAllDialogue(variables["script-all-dialogue"].as<bool>());
engine.setScriptsVerbosity(variables["script-verbose"].as<bool>()); engine.setScriptsVerbosity(variables["script-verbose"].as<bool>());
engine.setScriptConsoleMode (variables["script-console"].as<bool>()); engine.setScriptConsoleMode (variables["script-console"].as<bool>());
engine.setStartupScript (variables["script-run"].as<std::string>()); engine.setStartupScript (variables["script-run"].as<std::string>());

@ -183,6 +183,7 @@ namespace MWBase
///return the list of actors which are following the given actor ///return the list of actors which are following the given actor
/**ie AiFollow is active and the target is the actor**/ /**ie AiFollow is active and the target is the actor**/
virtual std::list<MWWorld::Ptr> getActorsFollowing(const MWWorld::Ptr& actor) = 0; virtual std::list<MWWorld::Ptr> getActorsFollowing(const MWWorld::Ptr& actor) = 0;
virtual std::list<int> getActorsFollowingIndices(const MWWorld::Ptr& actor) = 0;
///Returns a list of actors who are fighting the given actor within the fAlarmDistance ///Returns a list of actors who are fighting the given actor within the fAlarmDistance
/** ie AiCombat is active and the target is the actor **/ /** ie AiCombat is active and the target is the actor **/
@ -204,6 +205,8 @@ namespace MWBase
/// Resurrects the player if necessary /// Resurrects the player if necessary
virtual void keepPlayerAlive() = 0; virtual void keepPlayerAlive() = 0;
virtual bool isReadyToBlock (const MWWorld::Ptr& ptr) const = 0;
}; };
} }

@ -42,15 +42,21 @@ namespace MWBase
Play_NoTrack = 1<<2, /* (3D only) Play the sound at the given object's position Play_NoTrack = 1<<2, /* (3D only) Play the sound at the given object's position
* but do not keep it updated (the sound will not move with * but do not keep it updated (the sound will not move with
* the object and will not stop when the object is deleted. */ * the object and will not stop when the object is deleted. */
Play_RemoveAtDistance = 1<<3, /* (3D only) If the listener gets further than 2000 units away
Play_LoopNoEnv = Play_Loop | Play_NoEnv from the sound source, the sound is removed.
This is weird stuff but apparently how vanilla works for sounds
played by the PlayLoopSound family of script functions. Perhaps we
can make this cut off a more subtle fade later, but have to
be careful to not change the overall volume of areas by too much. */
Play_LoopNoEnv = Play_Loop | Play_NoEnv,
Play_LoopRemoveAtDistance = Play_Loop | Play_RemoveAtDistance
}; };
enum PlayType { enum PlayType {
Play_TypeSfx = 1<<3, /* Normal SFX sound */ Play_TypeSfx = 1<<4, /* Normal SFX sound */
Play_TypeVoice = 1<<4, /* Voice sound */ Play_TypeVoice = 1<<5, /* Voice sound */
Play_TypeFoot = 1<<5, /* Footstep sound */ Play_TypeFoot = 1<<6, /* Footstep sound */
Play_TypeMusic = 1<<6, /* Music track */ Play_TypeMusic = 1<<7, /* Music track */
Play_TypeMovie = 1<<7, /* Movie audio track */ Play_TypeMovie = 1<<8, /* Movie audio track */
Play_TypeMask = Play_TypeSfx|Play_TypeVoice|Play_TypeFoot|Play_TypeMusic|Play_TypeMovie Play_TypeMask = Play_TypeSfx|Play_TypeVoice|Play_TypeFoot|Play_TypeMusic|Play_TypeMovie
}; };

@ -330,11 +330,11 @@ namespace MWBase
virtual void pinWindow (MWGui::GuiWindow window) = 0; virtual void pinWindow (MWGui::GuiWindow window) = 0;
/// Fade the screen in, over \a time seconds /// Fade the screen in, over \a time seconds
virtual void fadeScreenIn(const float time) = 0; virtual void fadeScreenIn(const float time, bool clearQueue=true) = 0;
/// Fade the screen out to black, over \a time seconds /// Fade the screen out to black, over \a time seconds
virtual void fadeScreenOut(const float time) = 0; virtual void fadeScreenOut(const float time, bool clearQueue=true) = 0;
/// Fade the screen to a specified percentage of black, over \a time seconds /// Fade the screen to a specified percentage of black, over \a time seconds
virtual void fadeScreenTo(const int percent, const float time) = 0; virtual void fadeScreenTo(const int percent, const float time, bool clearQueue=true) = 0;
/// Darken the screen to a specified percentage /// Darken the screen to a specified percentage
virtual void setBlindness(const int percent) = 0; virtual void setBlindness(const int percent) = 0;
@ -342,6 +342,11 @@ namespace MWBase
virtual void setWerewolfOverlay(bool set) = 0; virtual void setWerewolfOverlay(bool set) = 0;
virtual void toggleDebugWindow() = 0; virtual void toggleDebugWindow() = 0;
/// Cycle to next or previous spell
virtual void cycleSpell(bool next) = 0;
/// Cycle to next or previous weapon
virtual void cycleWeapon(bool next) = 0;
}; };
} }

@ -40,6 +40,8 @@ namespace ESM
struct Enchantment; struct Enchantment;
struct Book; struct Book;
struct EffectList; struct EffectList;
struct CreatureLevList;
struct ItemLevList;
} }
namespace MWRender namespace MWRender
@ -279,8 +281,10 @@ namespace MWBase
///< Attempt to fix position so that the Ptr is no longer inside collision geometry. ///< Attempt to fix position so that the Ptr is no longer inside collision geometry.
virtual void deleteObject (const MWWorld::Ptr& ptr) = 0; virtual void deleteObject (const MWWorld::Ptr& ptr) = 0;
virtual void undeleteObject (const MWWorld::Ptr& ptr) = 0;
virtual void moveObject (const MWWorld::Ptr& ptr, float x, float y, float z) = 0; virtual MWWorld::Ptr moveObject (const MWWorld::Ptr& ptr, float x, float y, float z) = 0;
///< @return an updated Ptr in case the Ptr's cell changes
virtual void virtual void
moveObject(const MWWorld::Ptr &ptr, MWWorld::CellStore* newCell, float x, float y, float z) = 0; moveObject(const MWWorld::Ptr &ptr, MWWorld::CellStore* newCell, float x, float y, float z) = 0;
@ -357,6 +361,14 @@ namespace MWBase
///< Create a new record (of type book) in the ESM store. ///< Create a new record (of type book) in the ESM store.
/// \return pointer to created record /// \return pointer to created record
virtual const ESM::CreatureLevList *createOverrideRecord (const ESM::CreatureLevList& record) = 0;
///< Write this record to the ESM store, allowing it to override a pre-existing record with the same ID.
/// \return pointer to created record
virtual const ESM::ItemLevList *createOverrideRecord (const ESM::ItemLevList& record) = 0;
///< Write this record to the ESM store, allowing it to override a pre-existing record with the same ID.
/// \return pointer to created record
virtual void update (float duration, bool paused) = 0; virtual void update (float duration, bool paused) = 0;
virtual MWWorld::Ptr placeObject (const MWWorld::Ptr& object, float cursorX, float cursorY, int amount) = 0; virtual MWWorld::Ptr placeObject (const MWWorld::Ptr& object, float cursorX, float cursorY, int amount) = 0;
@ -386,6 +398,7 @@ namespace MWBase
virtual bool isOnGround(const MWWorld::Ptr &ptr) const = 0; virtual bool isOnGround(const MWWorld::Ptr &ptr) const = 0;
virtual void togglePOV() = 0; virtual void togglePOV() = 0;
virtual bool isFirstPerson() const = 0;
virtual void togglePreviewMode(bool enable) = 0; virtual void togglePreviewMode(bool enable) = 0;
virtual bool toggleVanityMode(bool enable) = 0; virtual bool toggleVanityMode(bool enable) = 0;
virtual void allowVanityMode(bool allow) = 0; virtual void allowVanityMode(bool allow) = 0;

@ -7,6 +7,7 @@
#include "../mwbase/environment.hpp" #include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp" #include "../mwbase/world.hpp"
#include "../mwbase/windowmanager.hpp" #include "../mwbase/windowmanager.hpp"
#include "../mwbase/mechanicsmanager.hpp"
#include "../mwworld/ptr.hpp" #include "../mwworld/ptr.hpp"
#include "../mwworld/failedaction.hpp" #include "../mwworld/failedaction.hpp"
@ -21,7 +22,7 @@
#include "../mwgui/tooltips.hpp" #include "../mwgui/tooltips.hpp"
#include "../mwrender/objects.hpp" #include "../mwrender/actors.hpp"
#include "../mwrender/renderinginterface.hpp" #include "../mwrender/renderinginterface.hpp"
#include "../mwmechanics/npcstats.hpp" #include "../mwmechanics/npcstats.hpp"
@ -87,7 +88,8 @@ namespace MWClass
{ {
const std::string model = getModel(ptr); const std::string model = getModel(ptr);
if (!model.empty()) { if (!model.empty()) {
renderingInterface.getObjects().insertModel(ptr, model); MWRender::Actors& actors = renderingInterface.getActors();
actors.insertActivator(ptr);
} }
} }
@ -96,6 +98,7 @@ namespace MWClass
const std::string model = getModel(ptr); const std::string model = getModel(ptr);
if(!model.empty()) if(!model.empty())
physics.addObject(ptr); physics.addObject(ptr);
MWBase::Environment::get().getMechanicsManager()->add(ptr);
} }
std::string Container::getModel(const MWWorld::Ptr &ptr) const std::string Container::getModel(const MWWorld::Ptr &ptr) const

@ -119,7 +119,12 @@ namespace MWClass
// spells // spells
for (std::vector<std::string>::const_iterator iter (ref->mBase->mSpells.mList.begin()); for (std::vector<std::string>::const_iterator iter (ref->mBase->mSpells.mList.begin());
iter!=ref->mBase->mSpells.mList.end(); ++iter) iter!=ref->mBase->mSpells.mList.end(); ++iter)
data->mCreatureStats.getSpells().add (*iter); {
if (const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().get<ESM::Spell>().search(*iter))
data->mCreatureStats.getSpells().add (spell);
else /// \todo add option to make this a fatal error message pop-up, but default to warning for vanilla compatibility
std::cerr << "Warning: ignoring nonexistent spell '" << *iter << "' on creature '" << ref->mBase->mId << "'" << std::endl;
}
// inventory // inventory
if (ref->mBase->mFlags & ESM::Creature::Weapon) if (ref->mBase->mFlags & ESM::Creature::Weapon)
@ -346,10 +351,11 @@ namespace MWClass
setOnPcHitMe = MWBase::Environment::get().getMechanicsManager()->actorAttacked(ptr, attacker); setOnPcHitMe = MWBase::Environment::get().getMechanicsManager()->actorAttacked(ptr, attacker);
} }
if(!object.isEmpty())
getCreatureStats(ptr).setLastHitAttemptObject(object.getClass().getId(object));
if(!successful) if(!successful)
{ {
// TODO: Handle HitAttemptOnMe script function
// Missed // Missed
MWBase::Environment::get().getSoundManager()->playSound3D(ptr, "miss", 1.0f, 1.0f); MWBase::Environment::get().getSoundManager()->playSound3D(ptr, "miss", 1.0f, 1.0f);
return; return;
@ -672,20 +678,25 @@ namespace MWClass
if(type >= 0) if(type >= 0)
{ {
std::vector<const ESM::SoundGenerator*> sounds; std::vector<const ESM::SoundGenerator*> sounds;
sounds.reserve(8); std::vector<const ESM::SoundGenerator*> fallbacksounds;
MWWorld::LiveCellRef<ESM::Creature>* ref = ptr.get<ESM::Creature>();
const std::string& ourId = (ref->mBase->mOriginal.empty()) ? getId(ptr) : ref->mBase->mOriginal;
std::string ptrid = Creature::getId(ptr);
MWWorld::Store<ESM::SoundGenerator>::iterator sound = store.begin(); MWWorld::Store<ESM::SoundGenerator>::iterator sound = store.begin();
while(sound != store.end()) while(sound != store.end())
{ {
if(type == sound->mType && !sound->mCreature.empty() && if (type == sound->mType && !sound->mCreature.empty() && (Misc::StringUtils::ciEqual(ourId, sound->mCreature)))
Misc::StringUtils::ciEqual(ptrid.substr(0, sound->mCreature.size()),
sound->mCreature))
sounds.push_back(&*sound); sounds.push_back(&*sound);
if (type == sound->mType && sound->mCreature.empty())
fallbacksounds.push_back(&*sound);
++sound; ++sound;
} }
if(!sounds.empty()) if(!sounds.empty())
return sounds[(int)(rand()/(RAND_MAX+1.0)*sounds.size())]->mSound; return sounds[(int)(rand()/(RAND_MAX+1.0)*sounds.size())]->mSound;
if (!fallbacksounds.empty())
return fallbacksounds[(int)(rand()/(RAND_MAX+1.0)*fallbacksounds.size())]->mSound;
} }
return ""; return "";
@ -879,4 +890,16 @@ namespace MWClass
MWWorld::ContainerStore& store = getContainerStore(ptr); MWWorld::ContainerStore& store = getContainerStore(ptr);
store.restock(list, ptr, ptr.getCellRef().getRefId(), ptr.getCellRef().getFaction()); store.restock(list, ptr, ptr.getCellRef().getRefId(), ptr.getCellRef().getFaction());
} }
int Creature::getBaseFightRating(const MWWorld::Ptr &ptr) const
{
MWWorld::LiveCellRef<ESM::Creature> *ref = ptr.get<ESM::Creature>();
return ref->mBase->mAiData.mFight;
}
void Creature::adjustScale(const MWWorld::Ptr &ptr, float &scale) const
{
MWWorld::LiveCellRef<ESM::Creature> *ref = ptr.get<ESM::Creature>();
scale *= ref->mBase->mScale;
}
} }

@ -154,6 +154,10 @@ namespace MWClass
virtual void respawn (const MWWorld::Ptr& ptr) const; virtual void respawn (const MWWorld::Ptr& ptr) const;
virtual void restock (const MWWorld::Ptr &ptr) const; virtual void restock (const MWWorld::Ptr &ptr) const;
virtual int getBaseFightRating(const MWWorld::Ptr &ptr) const;
virtual void adjustScale(const MWWorld::Ptr& ptr,float& scale) const;
}; };
} }

@ -300,15 +300,19 @@ namespace MWClass
if (!ref->mBase->mFaction.empty()) if (!ref->mBase->mFaction.empty())
{ {
std::string faction = ref->mBase->mFaction; std::string faction = ref->mBase->mFaction;
Misc::StringUtils::toLower(faction); if (const ESM::Faction* fact = MWBase::Environment::get().getWorld()->getStore().get<ESM::Faction>().search(faction))
if(ref->mBase->mNpdtType != ESM::NPC::NPC_WITH_AUTOCALCULATED_STATS)
{ {
data->mNpcStats.setFactionRank(faction, (int)ref->mBase->mNpdt52.mRank); if(ref->mBase->mNpdtType != ESM::NPC::NPC_WITH_AUTOCALCULATED_STATS)
{
data->mNpcStats.setFactionRank(fact->mId, (int)ref->mBase->mNpdt52.mRank);
}
else
{
data->mNpcStats.setFactionRank(fact->mId, (int)ref->mBase->mNpdt12.mRank);
}
} }
else else
{ std::cerr << "Warning: ignoring nonexistent faction '" << faction << "' on NPC '" << ref->mBase->mId << "'" << std::endl;
data->mNpcStats.setFactionRank(faction, (int)ref->mBase->mNpdt12.mRank);
}
} }
// creature stats // creature stats
@ -361,7 +365,10 @@ namespace MWClass
for (std::vector<std::string>::const_iterator iter (race->mPowers.mList.begin()); for (std::vector<std::string>::const_iterator iter (race->mPowers.mList.begin());
iter!=race->mPowers.mList.end(); ++iter) iter!=race->mPowers.mList.end(); ++iter)
{ {
data->mNpcStats.getSpells().add (*iter); if (const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().get<ESM::Spell>().search(*iter))
data->mNpcStats.getSpells().add (spell);
else
std::cerr << "Warning: ignoring nonexistent race power '" << *iter << "' on NPC '" << ref->mBase->mId << "'" << std::endl;
} }
if (data->mNpcStats.getFactionRanks().size()) if (data->mNpcStats.getFactionRanks().size())
@ -385,7 +392,15 @@ namespace MWClass
// spells // spells
for (std::vector<std::string>::const_iterator iter (ref->mBase->mSpells.mList.begin()); for (std::vector<std::string>::const_iterator iter (ref->mBase->mSpells.mList.begin());
iter!=ref->mBase->mSpells.mList.end(); ++iter) iter!=ref->mBase->mSpells.mList.end(); ++iter)
data->mNpcStats.getSpells().add (*iter); {
if (const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().get<ESM::Spell>().search(*iter))
data->mNpcStats.getSpells().add (spell);
else
{
/// \todo add option to make this a fatal error message pop-up, but default to warning for vanilla compatibility
std::cerr << "Warning: ignoring nonexistent spell '" << *iter << "' on NPC '" << ref->mBase->mId << "'" << std::endl;
}
}
// inventory // inventory
data->mInventoryStore.fill(ref->mBase->mInventory, getId(ptr), "", data->mInventoryStore.fill(ref->mBase->mInventory, getId(ptr), "",
@ -654,10 +669,11 @@ namespace MWClass
setOnPcHitMe = MWBase::Environment::get().getMechanicsManager()->actorAttacked(ptr, attacker); setOnPcHitMe = MWBase::Environment::get().getMechanicsManager()->actorAttacked(ptr, attacker);
} }
if(!object.isEmpty())
getCreatureStats(ptr).setLastHitAttemptObject(object.getClass().getId(object));
if(!successful) if(!successful)
{ {
// TODO: Handle HitAttemptOnMe script function
// Missed // Missed
sndMgr->playSound3D(ptr, "miss", 1.0f, 1.0f); sndMgr->playSound3D(ptr, "miss", 1.0f, 1.0f);
return; return;
@ -969,6 +985,9 @@ namespace MWClass
float Npc::getJump(const MWWorld::Ptr &ptr) const float Npc::getJump(const MWWorld::Ptr &ptr) const
{ {
if(getEncumbrance(ptr) > getCapacity(ptr))
return 0.f;
const NpcCustomData *npcdata = static_cast<const NpcCustomData*>(ptr.getRefData().getCustomData()); const NpcCustomData *npcdata = static_cast<const NpcCustomData*>(ptr.getRefData().getCustomData());
const GMST& gmst = getGmst(); const GMST& gmst = getGmst();
const MWMechanics::MagicEffects &mageffects = npcdata->mNpcStats.getMagicEffects(); const MWMechanics::MagicEffects &mageffects = npcdata->mNpcStats.getMagicEffects();
@ -999,37 +1018,6 @@ namespace MWClass
return x; return x;
} }
float Npc::getFallDamage(const MWWorld::Ptr &ptr, float fallHeight) const
{
MWBase::World *world = MWBase::Environment::get().getWorld();
const MWWorld::Store<ESM::GameSetting> &store = world->getStore().get<ESM::GameSetting>();
const float fallDistanceMin = store.find("fFallDamageDistanceMin")->getFloat();
if (fallHeight >= fallDistanceMin)
{
const float acrobaticsSkill = ptr.getClass().getNpcStats (ptr).getSkill(ESM::Skill::Acrobatics).getModified();
const NpcCustomData *npcdata = static_cast<const NpcCustomData*>(ptr.getRefData().getCustomData());
const float jumpSpellBonus = npcdata->mNpcStats.getMagicEffects().get(ESM::MagicEffect::Jump).getMagnitude();
const float fallAcroBase = store.find("fFallAcroBase")->getFloat();
const float fallAcroMult = store.find("fFallAcroMult")->getFloat();
const float fallDistanceBase = store.find("fFallDistanceBase")->getFloat();
const float fallDistanceMult = store.find("fFallDistanceMult")->getFloat();
float x = fallHeight - fallDistanceMin;
x -= (1.5 * acrobaticsSkill) + jumpSpellBonus;
x = std::max(0.0f, x);
float a = fallAcroBase + fallAcroMult * (100 - acrobaticsSkill);
x = fallDistanceBase + fallDistanceMult * x;
x *= a;
return x;
}
return 0;
}
MWMechanics::Movement& Npc::getMovementSettings (const MWWorld::Ptr& ptr) const MWMechanics::Movement& Npc::getMovementSettings (const MWWorld::Ptr& ptr) const
{ {
ensureCustomData (ptr); ensureCustomData (ptr);
@ -1275,6 +1263,7 @@ namespace MWClass
// TODO: I have no idea what these are supposed to do for NPCs since they use // TODO: I have no idea what these are supposed to do for NPCs since they use
// voiced dialog for various conditions like health loss and combat taunts. Maybe // voiced dialog for various conditions like health loss and combat taunts. Maybe
// only for biped creatures? // only for biped creatures?
if(name == "moan") if(name == "moan")
return ""; return "";
if(name == "roar") if(name == "roar")
@ -1389,4 +1378,10 @@ namespace MWClass
MWWorld::ContainerStore& store = getContainerStore(ptr); MWWorld::ContainerStore& store = getContainerStore(ptr);
store.restock(list, ptr, ptr.getCellRef().getRefId(), ptr.getCellRef().getFaction()); store.restock(list, ptr, ptr.getCellRef().getRefId(), ptr.getCellRef().getFaction());
} }
int Npc::getBaseFightRating (const MWWorld::Ptr& ptr) const
{
MWWorld::LiveCellRef<ESM::NPC> *ref = ptr.get<ESM::NPC>();
return ref->mBase->mAiData.mFight;
}
} }

@ -104,9 +104,6 @@ namespace MWClass
virtual float getJump(const MWWorld::Ptr &ptr) const; virtual float getJump(const MWWorld::Ptr &ptr) const;
///< Return jump velocity (not accounting for movement) ///< Return jump velocity (not accounting for movement)
virtual float getFallDamage(const MWWorld::Ptr &ptr, float fallHeight) const;
///< Return amount of health points lost when falling
virtual MWMechanics::Movement& getMovementSettings (const MWWorld::Ptr& ptr) const; virtual MWMechanics::Movement& getMovementSettings (const MWWorld::Ptr& ptr) const;
///< Return desired movement. ///< Return desired movement.
@ -188,6 +185,8 @@ namespace MWClass
virtual void respawn (const MWWorld::Ptr& ptr) const; virtual void respawn (const MWWorld::Ptr& ptr) const;
virtual void restock (const MWWorld::Ptr& ptr) const; virtual void restock (const MWWorld::Ptr& ptr) const;
virtual int getBaseFightRating (const MWWorld::Ptr& ptr) const;
}; };
} }

@ -47,7 +47,7 @@
namespace MWDialogue namespace MWDialogue
{ {
DialogueManager::DialogueManager (const Compiler::Extensions& extensions, bool scriptVerbose, Translation::Storage& translationDataStorage) : DialogueManager::DialogueManager (const Compiler::Extensions& extensions, bool scriptVerbose, Translation::Storage& translationDataStorage) :
mCompilerContext (MWScript::CompilerContext::Type_Dialgoue), mCompilerContext (MWScript::CompilerContext::Type_Dialogue),
mErrorStream(std::cout.rdbuf()),mErrorHandler(mErrorStream) mErrorStream(std::cout.rdbuf()),mErrorHandler(mErrorStream)
, mTemporaryDispositionChange(0.f) , mTemporaryDispositionChange(0.f)
, mPermanentDispositionChange(0.f), mScriptVerbose (scriptVerbose) , mPermanentDispositionChange(0.f), mScriptVerbose (scriptVerbose)
@ -227,7 +227,7 @@ namespace MWDialogue
success = false; success = false;
} }
if (!success && mScriptVerbose) if (!success)
{ {
std::cerr std::cerr
<< "compiling failed (dialogue script)" << std::endl << "compiling failed (dialogue script)" << std::endl

@ -603,6 +603,17 @@ const ESM::DialInfo* MWDialogue::Filter::search (const ESM::Dialogue& dialogue,
return suitableInfos[0]; return suitableInfos[0];
} }
std::vector<const ESM::DialInfo *> MWDialogue::Filter::listAll (const ESM::Dialogue& dialogue) const
{
std::vector<const ESM::DialInfo *> infos;
for (ESM::Dialogue::InfoContainer::const_iterator iter = dialogue.mInfo.begin(); iter!=dialogue.mInfo.end(); ++iter)
{
if (testActor (*iter))
infos.push_back(&*iter);
}
return infos;
}
std::vector<const ESM::DialInfo *> MWDialogue::Filter::list (const ESM::Dialogue& dialogue, std::vector<const ESM::DialInfo *> MWDialogue::Filter::list (const ESM::Dialogue& dialogue,
bool fallbackToInfoRefusal, bool searchAll, bool invertDisposition) const bool fallbackToInfoRefusal, bool searchAll, bool invertDisposition) const
{ {

@ -55,7 +55,11 @@ namespace MWDialogue
std::vector<const ESM::DialInfo *> list (const ESM::Dialogue& dialogue, std::vector<const ESM::DialInfo *> list (const ESM::Dialogue& dialogue,
bool fallbackToInfoRefusal, bool searchAll, bool invertDisposition=false) const; bool fallbackToInfoRefusal, bool searchAll, bool invertDisposition=false) const;
///< \note If fallbackToInfoRefusal is used, the returned DialInfo might not be from the supplied ESM::Dialogue. ///< List all infos that could be used on the given actor, using the current runtime state of the actor.
/// \note If fallbackToInfoRefusal is used, the returned DialInfo might not be from the supplied ESM::Dialogue.
std::vector<const ESM::DialInfo *> listAll (const ESM::Dialogue& dialogue) const;
///< List all infos that could possibly be used on the given actor, ignoring runtime state filters and ignoring player filters.
const ESM::DialInfo* search (const ESM::Dialogue& dialogue, const bool fallbackToInfoRefusal) const; const ESM::DialInfo* search (const ESM::Dialogue& dialogue, const bool fallbackToInfoRefusal) const;
///< Get a matching response for the requested dialogue. ///< Get a matching response for the requested dialogue.

@ -0,0 +1,125 @@
#include "scripttest.hpp"
#include "../mwworld/manualref.hpp"
#include "../mwworld/class.hpp"
#include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp"
#include "../mwbase/scriptmanager.hpp"
#include "../mwscript/compilercontext.hpp"
#include <components/compiler/exception.hpp>
#include <components/compiler/streamerrorhandler.hpp>
#include <components/compiler/scanner.hpp>
#include <components/compiler/locals.hpp>
#include <components/compiler/output.hpp>
#include <components/compiler/scriptparser.hpp>
#include "filter.hpp"
namespace
{
void test(const MWWorld::Ptr& actor, int &compiled, int &total, const Compiler::Extensions* extensions, int warningsMode)
{
MWDialogue::Filter filter(actor, 0, false);
MWScript::CompilerContext compilerContext(MWScript::CompilerContext::Type_Dialogue);
compilerContext.setExtensions(extensions);
std::ostream errorStream(std::cout.rdbuf());
Compiler::StreamErrorHandler errorHandler(errorStream);
errorHandler.setWarningsMode (warningsMode);
const MWWorld::Store<ESM::Dialogue>& dialogues = MWBase::Environment::get().getWorld()->getStore().get<ESM::Dialogue>();
for (MWWorld::Store<ESM::Dialogue>::iterator it = dialogues.begin(); it != dialogues.end(); ++it)
{
std::vector<const ESM::DialInfo*> infos = filter.listAll(*it);
for (std::vector<const ESM::DialInfo*>::iterator it = infos.begin(); it != infos.end(); ++it)
{
const ESM::DialInfo* info = *it;
if (!info->mResultScript.empty())
{
bool success = true;
++total;
try
{
errorHandler.reset();
std::istringstream input (info->mResultScript + "\n");
Compiler::Scanner scanner (errorHandler, input, extensions);
Compiler::Locals locals;
std::string actorScript = actor.getClass().getScript(actor);
if (!actorScript.empty())
{
// grab local variables from actor's script, if available.
locals = MWBase::Environment::get().getScriptManager()->getLocals (actorScript);
}
Compiler::ScriptParser parser(errorHandler, compilerContext, locals, false);
scanner.scan (parser);
if (!errorHandler.isGood())
success = false;
++compiled;
}
catch (const Compiler::SourceException& /* error */)
{
// error has already been reported via error handler
success = false;
}
catch (const std::exception& error)
{
std::cerr << std::string ("Dialogue error: An exception has been thrown: ") + error.what() << std::endl;
success = false;
}
if (!success)
{
std::cerr
<< "compiling failed (dialogue script)" << std::endl
<< info->mResultScript
<< std::endl << std::endl;
}
}
}
}
}
}
namespace MWDialogue
{
namespace ScriptTest
{
std::pair<int, int> compileAll(const Compiler::Extensions *extensions, int warningsMode)
{
int compiled = 0, total = 0;
const MWWorld::Store<ESM::NPC>& npcs = MWBase::Environment::get().getWorld()->getStore().get<ESM::NPC>();
for (MWWorld::Store<ESM::NPC>::iterator it = npcs.begin(); it != npcs.end(); ++it)
{
MWWorld::ManualRef ref(MWBase::Environment::get().getWorld()->getStore(), it->mId);
test(ref.getPtr(), compiled, total, extensions, warningsMode);
}
const MWWorld::Store<ESM::Creature>& creatures = MWBase::Environment::get().getWorld()->getStore().get<ESM::Creature>();
for (MWWorld::Store<ESM::Creature>::iterator it = creatures.begin(); it != creatures.end(); ++it)
{
MWWorld::ManualRef ref(MWBase::Environment::get().getWorld()->getStore(), it->mId);
test(ref.getPtr(), compiled, total, extensions, warningsMode);
}
return std::make_pair(total, compiled);
}
}
}

@ -0,0 +1,20 @@
#ifndef OPENMW_MWDIALOGUE_SCRIPTTEST_H
#define OPENMW_MWDIALOGUE_SCRIPTTEST_H
#include <components/compiler/extensions.hpp>
namespace MWDialogue
{
namespace ScriptTest
{
/// Attempt to compile all dialogue scripts, use for verification purposes
/// @return A pair containing <total number of scripts, number of successfully compiled scripts>
std::pair<int, int> compileAll(const Compiler::Extensions* extensions, int warningsMode);
}
}
#endif

@ -124,6 +124,8 @@ namespace MWGui
if (targetView) if (targetView)
targetView->update(); targetView->update();
MWBase::Environment::get().getWindowManager()->getInventoryWindow()->updateItemView();
// We need to update the view since an other item could be auto-equipped. // We need to update the view since an other item could be auto-equipped.
mSourceView->update(); mSourceView->update();
} }

@ -533,9 +533,11 @@ namespace MWGui
if (mGoodbye) if (mGoodbye)
{ {
Goodbye* link = new Goodbye();
mLinks.push_back(link);
std::string goodbye = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("sGoodbye")->getString(); std::string goodbye = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("sGoodbye")->getString();
BookTypesetter::Style* questionStyle = typesetter->createHotStyle(body, linkNormal, linkHot, linkActive, BookTypesetter::Style* questionStyle = typesetter->createHotStyle(body, linkNormal, linkHot, linkActive,
TypesetBook::InteractiveId(mLinks.back())); TypesetBook::InteractiveId(link));
typesetter->lineBreak(); typesetter->lineBreak();
typesetter->write(questionStyle, to_utf8_span(goodbye.c_str())); typesetter->write(questionStyle, to_utf8_span(goodbye.c_str()));
} }
@ -654,7 +656,6 @@ namespace MWGui
void DialogueWindow::goodbye() void DialogueWindow::goodbye()
{ {
mLinks.push_back(new Goodbye());
mGoodbye = true; mGoodbye = true;
mEnabled = false; mEnabled = false;
updateHistory(); updateHistory();

@ -109,8 +109,8 @@ namespace MWGui
mCharge->setCaption(boost::lexical_cast<std::string>(mEnchanting.getGemCharge())); mCharge->setCaption(boost::lexical_cast<std::string>(mEnchanting.getGemCharge()));
std::stringstream castCost; std::stringstream castCost;
castCost << std::setprecision(1) << std::fixed << mEnchanting.getCastCost(); castCost << mEnchanting.getCastCost();
mCastCost->setCaption(boost::lexical_cast<std::string>(castCost.str())); mCastCost->setCaption(castCost.str());
mPrice->setCaption(boost::lexical_cast<std::string>(mEnchanting.getEnchantPrice())); mPrice->setCaption(boost::lexical_cast<std::string>(mEnchanting.getEnchantPrice()));

@ -193,6 +193,9 @@ namespace MWGui
MyGUI::Gui::getInstance().destroyWidget(parent->getChildAt(0)); MyGUI::Gui::getInstance().destroyWidget(parent->getChildAt(0));
} }
mTextStyle = TextStyle();
mBlockStyle = BlockStyle();
MyGUI::Widget * paper = parent->createWidget<MyGUI::Widget>("Widget", MyGUI::IntCoord(0, 0, pag.getPageWidth(), pag.getPageHeight()), MyGUI::Align::Left | MyGUI::Align::Top); MyGUI::Widget * paper = parent->createWidget<MyGUI::Widget>("Widget", MyGUI::IntCoord(0, 0, pag.getPageWidth(), pag.getPageHeight()), MyGUI::Align::Left | MyGUI::Align::Top);
paper->setNeedMouseFocus(false); paper->setNeedMouseFocus(false);
@ -207,8 +210,25 @@ namespace MWGui
continue; continue;
std::string plainText = parser.getReadyText(); std::string plainText = parser.getReadyText();
// for cases when linebreaks are used to cause a shift to the next page
// if the split text block ends in an empty line, proceeding text block(s) should have leading empty lines removed
if (pag.getIgnoreLeadingEmptyLines())
{
while (!plainText.empty())
{
if (plainText[0] == '\n')
plainText.erase(plainText.begin());
else
{
pag.setIgnoreLeadingEmptyLines(false);
break;
}
}
}
if (plainText.empty()) if (plainText.empty())
brBeforeLastTag = false; brBeforeLastTag = true;
else else
{ {
// Each block of text (between two tags / boundary and tag) will be displayed in a separate editbox widget, // Each block of text (between two tags / boundary and tag) will be displayed in a separate editbox widget,
@ -252,6 +272,8 @@ namespace MWGui
{ {
case BookTextParser::Event_ImgTag: case BookTextParser::Event_ImgTag:
{ {
pag.setIgnoreLeadingEmptyLines(false);
const BookTextParser::Attributes & attr = parser.getAttributes(); const BookTextParser::Attributes & attr = parser.getAttributes();
if (attr.find("src") == attr.end() || attr.find("width") == attr.end() || attr.find("height") == attr.end()) if (attr.find("src") == attr.end() || attr.find("width") == attr.end() || attr.find("height") == attr.end())
@ -331,9 +353,7 @@ namespace MWGui
if (attr.find("face") != attr.end()) if (attr.find("face") != attr.end())
{ {
std::string face = attr.at("face"); std::string face = attr.at("face");
mTextStyle.mFont = face;
if (face != "Magic Cards")
mTextStyle.mFont = face;
} }
if (attr.find("size") != attr.end()) if (attr.find("size") != attr.end())
{ {
@ -408,13 +428,18 @@ namespace MWGui
// first empty lines that would go to the next page should be ignored // first empty lines that would go to the next page should be ignored
// unfortunately, getLineInfo method won't be available until 3.2.2 // unfortunately, getLineInfo method won't be available until 3.2.2
#if (MYGUI_VERSION >= MYGUI_DEFINE_VERSION(3, 2, 2)) #if (MYGUI_VERSION >= MYGUI_DEFINE_VERSION(3, 2, 2))
mPaginator.setIgnoreLeadingEmptyLines(true);
const MyGUI::VectorLineInfo & lines = mEditBox->getSubWidgetText()->castType<MyGUI::EditText>()->getLineInfo(); const MyGUI::VectorLineInfo & lines = mEditBox->getSubWidgetText()->castType<MyGUI::EditText>()->getLineInfo();
for (unsigned int i = lastLine; i < lines.size(); ++i) for (unsigned int i = lastLine; i < lines.size(); ++i)
{ {
if (lines[i].width == 0) if (lines[i].width == 0)
ret += lineHeight; ret += lineHeight;
else else
{
mPaginator.setIgnoreLeadingEmptyLines(false);
break; break;
}
} }
#endif #endif
return ret; return ret;

@ -81,7 +81,8 @@ namespace MWGui
Paginator(int pageWidth, int pageHeight) Paginator(int pageWidth, int pageHeight)
: mStartTop(0), mCurrentTop(0), : mStartTop(0), mCurrentTop(0),
mPageWidth(pageWidth), mPageHeight(pageHeight) mPageWidth(pageWidth), mPageHeight(pageHeight),
mIgnoreLeadingEmptyLines(false)
{ {
} }
@ -89,10 +90,12 @@ namespace MWGui
int getCurrentTop() const { return mCurrentTop; } int getCurrentTop() const { return mCurrentTop; }
int getPageWidth() const { return mPageWidth; } int getPageWidth() const { return mPageWidth; }
int getPageHeight() const { return mPageHeight; } int getPageHeight() const { return mPageHeight; }
bool getIgnoreLeadingEmptyLines() const { return mIgnoreLeadingEmptyLines; }
Pages getPages() const { return mPages; } Pages getPages() const { return mPages; }
void setStartTop(int top) { mStartTop = top; } void setStartTop(int top) { mStartTop = top; }
void setCurrentTop(int top) { mCurrentTop = top; } void setCurrentTop(int top) { mCurrentTop = top; }
void setIgnoreLeadingEmptyLines(bool ignore) { mIgnoreLeadingEmptyLines = ignore; }
Paginator & operator<<(const Page & page) Paginator & operator<<(const Page & page)
{ {
@ -103,6 +106,7 @@ namespace MWGui
private: private:
int mStartTop, mCurrentTop; int mStartTop, mCurrentTop;
int mPageWidth, mPageHeight; int mPageWidth, mPageHeight;
bool mIgnoreLeadingEmptyLines;
Pages mPages; Pages mPages;
}; };

@ -99,14 +99,8 @@ void InventoryItemModel::update()
if (mActor.getClass().hasInventoryStore(mActor)) if (mActor.getClass().hasInventoryStore(mActor))
{ {
MWWorld::InventoryStore& store = mActor.getClass().getInventoryStore(mActor); MWWorld::InventoryStore& store = mActor.getClass().getInventoryStore(mActor);
for (int slot=0; slot<MWWorld::InventoryStore::Slots; ++slot) if (store.isEquipped(newItem.mBase))
{ newItem.mType = ItemStack::Type_Equipped;
MWWorld::ContainerStoreIterator equipped = store.getSlot(slot);
if (equipped == store.end())
continue;
if (*equipped == newItem.mBase)
newItem.mType = ItemStack::Type_Equipped;
}
} }
mItems.push_back(newItem); mItems.push_back(newItem);

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save