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...")
set(OPENMW_VERSION_MAJOR 0)
set(OPENMW_VERSION_MINOR 33)
set(OPENMW_VERSION_RELEASE 1)
set(OPENMW_VERSION_MINOR 34)
set(OPENMW_VERSION_RELEASE 0)
set(OPENMW_VERSION_COMMITHASH "")
set(OPENMW_VERSION_TAGHASH "")

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

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

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

@ -1,6 +1,8 @@
#include "editor.hpp"
#include <openengine/bullet/BulletShapeLoader.h>
#include <QApplication>
#include <QLocalServer>
#include <QLocalSocket>
@ -21,8 +23,8 @@
CS::Editor::Editor (OgreInit::OgreInit& ogreInit)
: mUserSettings (mCfgMgr), mOverlaySystem (0), mDocumentManager (mCfgMgr),
mViewManager (mDocumentManager), mPhysicsManager (0),
mIpcServerName ("org.openmw.OpenCS"), mServer(NULL), mClientSocket(NULL)
mViewManager (mDocumentManager),
mIpcServerName ("org.openmw.OpenCS"), mServer(NULL), mClientSocket(NULL), mPid(""), mLock()
{
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());
mOverlaySystem.reset (new CSVRender::OverlaySystem);
mPhysicsManager.reset (new CSVWorld::PhysicsManager);
Bsa::registerResources (Files::Collections (config.first, !mFsStrict), config.second, true,
mFsStrict);
@ -70,7 +71,15 @@ CS::Editor::Editor (OgreInit::OgreInit& ogreInit)
}
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)
{
@ -233,7 +242,53 @@ void CS::Editor::showSettings()
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))
{
@ -242,6 +297,7 @@ bool CS::Editor::makeIPCServer()
}
mServer->close();
mServer = NULL;
return false;
}

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

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

@ -9,6 +9,8 @@
#include <components/files/configurationmanager.hpp>
#endif
#include "../../view/world/physicssystem.hpp"
void CSMDoc::Document::addGmsts()
{
static const char *gmstFloats[] =
@ -2253,7 +2255,7 @@ CSMDoc::Document::Document (const Files::ConfigurationManager& configuration,
mProjectPath ((configuration.getUserDataPath() / "projects") /
(savePath.filename().string() + ".project")),
mSaving (*this, mProjectPath, encoding),
mRunner (mProjectPath)
mRunner (mProjectPath), mPhysics(boost::shared_ptr<CSVWorld::PhysicsSystem>())
{
if (mContentFiles.empty())
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 (reportMessage (const CSMWorld::UniversalId&, const std::string&, int)),
this, SLOT (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&, const std::string&, int)));
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,
int type)
const std::string& hint, int type)
{
/// \todo find a better way to get these messages to the user.
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);
}
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 <boost/shared_ptr.hpp>
#include <boost/filesystem/path.hpp>
#include <QUndoStack>
@ -39,6 +40,11 @@ namespace CSMWorld
class ResourcesManager;
}
namespace CSVWorld
{
class PhysicsSystem;
}
namespace CSMDoc
{
class Document : public QObject
@ -57,6 +63,7 @@ namespace CSMDoc
boost::filesystem::path mResDir;
Blacklist mBlacklist;
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
// 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();
boost::shared_ptr<CSVWorld::PhysicsSystem> getPhysics();
signals:
void stateChanged (int state, CSMDoc::Document *document);
@ -140,7 +149,7 @@ namespace CSMDoc
void modificationStateChanged (bool clean);
void reportMessage (const CSMWorld::UniversalId& id, const std::string& message,
int type);
const std::string& hint, int type);
void operationDone (int type, bool failed);

@ -52,7 +52,7 @@ void CSMDoc::Loader::load()
{
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
if (document->getData().continueLoading (messages))
{
@ -65,11 +65,11 @@ void CSMDoc::Loader::load()
CSMWorld::UniversalId log (CSMWorld::UniversalId::Type_LoadErrorLog, 0);
{ // silence a g++ warning
for (CSMDoc::Stage::Messages::const_iterator iter (messages.begin());
for (CSMDoc::Messages::Iterator iter (messages.begin());
iter!=messages.end(); ++iter)
{
document->getReport (log)->add (iter->first, iter->second);
emit loadMessage (document, iter->second);
document->getReport (log)->add (iter->mId, iter->mMessage);
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()
{
Stage::Messages messages;
Messages messages;
while (mCurrentStage!=mStages.end())
{
@ -101,7 +101,7 @@ void CSMDoc::Operation::executeStage()
}
catch (const std::exception& e)
{
emit reportMessage (CSMWorld::UniversalId(), e.what(), mType);
emit reportMessage (CSMWorld::UniversalId(), e.what(), "", mType);
abort();
}
@ -112,8 +112,8 @@ void CSMDoc::Operation::executeStage()
emit progress (mCurrentStepTotal, mTotalSteps ? mTotalSteps : 1, mType);
for (Stage::Messages::const_iterator iter (messages.begin()); iter!=messages.end(); ++iter)
emit reportMessage (iter->first, iter->second, mType);
for (Messages::Iterator iter (messages.begin()); iter!=messages.end(); ++iter)
emit reportMessage (iter->mId, iter->mMessage, iter->mHint, mType);
if (mCurrentStage==mStages.end())
exit();

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

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

@ -17,7 +17,7 @@ int CSMTools::BirthsignCheckStage::setup()
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);

@ -21,7 +21,7 @@ namespace CSMTools
virtual int setup();
///< \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.
};
}

@ -14,7 +14,7 @@ int CSMTools::BodyPartCheckStage::setup()
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);

@ -27,7 +27,7 @@ namespace CSMTools
virtual int setup();
///< \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.
};
}

@ -18,7 +18,7 @@ int CSMTools::ClassCheckStage::setup()
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);

@ -21,7 +21,7 @@ namespace CSMTools
virtual int setup();
///< \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.
};
}

@ -18,7 +18,7 @@ int CSMTools::FactionCheckStage::setup()
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);

@ -21,7 +21,7 @@ namespace CSMTools
virtual int setup();
///< \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.
};
}

@ -15,10 +15,9 @@ int CSMTools::MandatoryIdStage::setup()
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 ||
mIdCollection.getRecord (mIds.at (stage)).isDeleted())
messages.push_back (std::make_pair (mCollectionId,
"Missing mandatory record: " + mIds.at (stage)));
messages.add (mCollectionId, "Missing mandatory record: " + mIds.at (stage));
}

@ -30,7 +30,7 @@ namespace CSMTools
virtual int setup();
///< \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.
};
}

@ -7,7 +7,7 @@
#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);
@ -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
}
void CSMTools::RaceCheckStage::performFinal (Messages& messages)
void CSMTools::RaceCheckStage::performFinal (CSMDoc::Messages& messages)
{
CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Races);
@ -64,7 +64,7 @@ int CSMTools::RaceCheckStage::setup()
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())
performFinal (messages);

@ -15,9 +15,9 @@ namespace CSMTools
const CSMWorld::IdCollection<ESM::Race>& mRaces;
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:
@ -26,7 +26,7 @@ namespace CSMTools
virtual int setup();
///< \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.
};
}

@ -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.
const int bookSize(mReferencables.getBooks().getSize());
@ -232,7 +232,7 @@ int CSMTools::ReferenceableCheckStage::setup()
void CSMTools::ReferenceableCheckStage::bookCheck(
int stage,
const CSMWorld::RefIdDataContainer< ESM::Book >& records,
Messages& messages)
CSMDoc::Messages& messages)
{
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
@ -250,7 +250,7 @@ void CSMTools::ReferenceableCheckStage::bookCheck(
void CSMTools::ReferenceableCheckStage::activatorCheck(
int stage,
const CSMWorld::RefIdDataContainer< ESM::Activator >& records,
Messages& messages)
CSMDoc::Messages& messages)
{
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
@ -270,7 +270,7 @@ void CSMTools::ReferenceableCheckStage::activatorCheck(
void CSMTools::ReferenceableCheckStage::potionCheck(
int stage,
const CSMWorld::RefIdDataContainer< ESM::Potion >& records,
Messages& messages)
CSMDoc::Messages& messages)
{
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
@ -290,7 +290,7 @@ void CSMTools::ReferenceableCheckStage::potionCheck(
void CSMTools::ReferenceableCheckStage::apparatusCheck(
int stage,
const CSMWorld::RefIdDataContainer< ESM::Apparatus >& records,
Messages& messages)
CSMDoc::Messages& messages)
{
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
@ -310,7 +310,7 @@ void CSMTools::ReferenceableCheckStage::apparatusCheck(
void CSMTools::ReferenceableCheckStage::armorCheck(
int stage,
const CSMWorld::RefIdDataContainer< ESM::Armor >& records,
Messages& messages)
CSMDoc::Messages& messages)
{
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
@ -336,7 +336,7 @@ void CSMTools::ReferenceableCheckStage::armorCheck(
void CSMTools::ReferenceableCheckStage::clothingCheck(
int stage,
const CSMWorld::RefIdDataContainer< ESM::Clothing >& records,
Messages& messages)
CSMDoc::Messages& messages)
{
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
@ -353,7 +353,7 @@ void CSMTools::ReferenceableCheckStage::clothingCheck(
void CSMTools::ReferenceableCheckStage::containerCheck(
int stage,
const CSMWorld::RefIdDataContainer< ESM::Container >& records,
Messages& messages)
CSMDoc::Messages& messages)
{
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
@ -381,7 +381,7 @@ void CSMTools::ReferenceableCheckStage::containerCheck(
void CSMTools::ReferenceableCheckStage::creatureCheck (
int stage, const CSMWorld::RefIdDataContainer< ESM::Creature >& records,
Messages& messages)
CSMDoc::Messages& messages)
{
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
@ -448,7 +448,7 @@ void CSMTools::ReferenceableCheckStage::creatureCheck (
void CSMTools::ReferenceableCheckStage::doorCheck(
int stage, const CSMWorld::RefIdDataContainer< ESM::Door >& records,
Messages& messages)
CSMDoc::Messages& messages)
{
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
@ -469,7 +469,7 @@ void CSMTools::ReferenceableCheckStage::doorCheck(
void CSMTools::ReferenceableCheckStage::ingredientCheck(
int stage,
const CSMWorld::RefIdDataContainer< ESM::Ingredient >& records,
Messages& messages)
CSMDoc::Messages& messages)
{
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
@ -487,7 +487,7 @@ void CSMTools::ReferenceableCheckStage::ingredientCheck(
void CSMTools::ReferenceableCheckStage::creaturesLevListCheck(
int stage,
const CSMWorld::RefIdDataContainer< ESM::CreatureLevList >& records,
Messages& messages)
CSMDoc::Messages& messages)
{
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
@ -505,7 +505,7 @@ void CSMTools::ReferenceableCheckStage::creaturesLevListCheck(
void CSMTools::ReferenceableCheckStage::itemLevelledListCheck(
int stage,
const CSMWorld::RefIdDataContainer< ESM::ItemLevList >& records,
Messages& messages)
CSMDoc::Messages& messages)
{
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
@ -522,7 +522,7 @@ void CSMTools::ReferenceableCheckStage::itemLevelledListCheck(
void CSMTools::ReferenceableCheckStage::lightCheck(
int stage, const CSMWorld::RefIdDataContainer< ESM::Light >& records,
Messages& messages)
CSMDoc::Messages& messages)
{
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
@ -547,7 +547,7 @@ void CSMTools::ReferenceableCheckStage::lightCheck(
void CSMTools::ReferenceableCheckStage::lockpickCheck(
int stage,
const CSMWorld::RefIdDataContainer< ESM::Lockpick >& records,
Messages& messages)
CSMDoc::Messages& messages)
{
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
@ -567,7 +567,7 @@ void CSMTools::ReferenceableCheckStage::lockpickCheck(
void CSMTools::ReferenceableCheckStage::miscCheck(
int stage,
const CSMWorld::RefIdDataContainer< ESM::Miscellaneous >& records,
Messages& messages)
CSMDoc::Messages& messages)
{
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
@ -584,7 +584,7 @@ void CSMTools::ReferenceableCheckStage::miscCheck(
void CSMTools::ReferenceableCheckStage::npcCheck (
int stage, const CSMWorld::RefIdDataContainer< ESM::NPC >& records,
Messages& messages)
CSMDoc::Messages& messages)
{
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
@ -701,7 +701,7 @@ void CSMTools::ReferenceableCheckStage::npcCheck (
void CSMTools::ReferenceableCheckStage::weaponCheck(
int stage, const CSMWorld::RefIdDataContainer< ESM::Weapon >& records,
Messages& messages)
CSMDoc::Messages& messages)
{
const CSMWorld::RecordBase& baseRecord = records.getRecord (stage);
@ -778,7 +778,7 @@ void CSMTools::ReferenceableCheckStage::weaponCheck(
void CSMTools::ReferenceableCheckStage::probeCheck(
int stage,
const CSMWorld::RefIdDataContainer< ESM::Probe >& records,
Messages& messages)
CSMDoc::Messages& messages)
{
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
@ -796,7 +796,7 @@ void CSMTools::ReferenceableCheckStage::probeCheck(
void CSMTools::ReferenceableCheckStage::repairCheck (
int stage, const CSMWorld::RefIdDataContainer< ESM::Repair >& records,
Messages& messages)
CSMDoc::Messages& messages)
{
const CSMWorld::RecordBase& baseRecord = records.getRecord (stage);
@ -812,7 +812,7 @@ void CSMTools::ReferenceableCheckStage::repairCheck (
void CSMTools::ReferenceableCheckStage::staticCheck (
int stage, const CSMWorld::RefIdDataContainer< ESM::Static >& records,
Messages& messages)
CSMDoc::Messages& messages)
{
const CSMWorld::RecordBase& baseRecord = records.getRecord (stage);
@ -828,7 +828,7 @@ void CSMTools::ReferenceableCheckStage::staticCheck (
//final check
void CSMTools::ReferenceableCheckStage::finalCheck (Messages& messages)
void CSMTools::ReferenceableCheckStage::finalCheck (CSMDoc::Messages& messages)
{
if (!mPlayerPresent)
messages.push_back (std::make_pair (CSMWorld::UniversalId::Type_Referenceables,
@ -839,7 +839,7 @@ void CSMTools::ReferenceableCheckStage::finalCheck (Messages& messages)
//Templates begins here
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())
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 (
const Item& someItem, Messages& messages, const std::string& someID)
const Item& someItem, CSMDoc::Messages& messages, const std::string& someID)
{
if (someItem.mName.empty())
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 (
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)
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 (
const Tool& someTool, Messages& messages, const std::string& someID)
const Tool& someTool, CSMDoc::Messages& messages, const std::string& someID)
{
if (someTool.mData.mQuality <= 0)
messages.push_back (std::make_pair (someID, someTool.mId + " has non-positive quality"));
}
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)
{

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

@ -17,7 +17,7 @@ int CSMTools::RegionCheckStage::setup()
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);

@ -21,7 +21,7 @@ namespace CSMTools
virtual int setup();
///< \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.
};
}

@ -16,7 +16,7 @@ int CSMTools::ReportModel::columnCount (const QModelIndex & parent) const
if (parent.isValid())
return 0;
return 2;
return 3;
}
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)
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
@ -38,7 +41,13 @@ QVariant CSMTools::ReportModel::headerData (int section, Qt::Orientation orienta
if (orientation==Qt::Vertical)
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)
@ -51,11 +60,12 @@ bool CSMTools::ReportModel::removeRows (int row, int count, const QModelIndex& p
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());
mRows.push_back (std::make_pair (id, message));
mRows.push_back (std::make_pair (id, std::make_pair (message, hint)));
endInsertRows();
}
@ -64,3 +74,8 @@ const CSMWorld::UniversalId& CSMTools::ReportModel::getUniversalId (int row) con
{
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
std::vector<std::pair<CSMWorld::UniversalId, std::string> > mRows;
std::vector<std::pair<CSMWorld::UniversalId, std::pair<std::string, std::string> > > mRows;
public:
@ -28,9 +28,12 @@ namespace CSMTools
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;
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
<< " (" << 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)
@ -58,7 +62,7 @@ int CSMTools::ScriptCheckStage::setup()
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);

@ -23,7 +23,7 @@ namespace CSMTools
CSMWorld::ScriptContext mContext;
std::string mId;
std::string mFile;
Messages *mMessages;
CSMDoc::Messages *mMessages;
virtual void report (const std::string& message, const Compiler::TokenLoc& loc, Type type);
///< Report error to the user.
@ -38,7 +38,7 @@ namespace CSMTools
virtual int setup();
///< \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.
};
}

@ -16,7 +16,7 @@ int CSMTools::SkillCheckStage::setup()
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);

@ -21,7 +21,7 @@ namespace CSMTools
virtual int setup();
///< \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.
};
}

@ -16,7 +16,7 @@ int CSMTools::SoundCheckStage::setup()
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);

@ -21,7 +21,7 @@ namespace CSMTools
virtual int setup();
///< \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.
};
}

@ -17,7 +17,7 @@ int CSMTools::SpellCheckStage::setup()
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);

@ -21,7 +21,7 @@ namespace CSMTools
virtual int setup();
///< \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.
};
}

@ -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 (done (int, bool)), this, SIGNAL (done (int, bool)));
connect (mVerifier,
SIGNAL (reportMessage (const CSMWorld::UniversalId&, const std::string&, int)),
this, SLOT (verifierMessage (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&, const std::string&, int)));
std::vector<std::string> mandatoryIds; // I want C++11, damn it!
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,
int type)
const std::string& hint, int type)
{
std::map<int, int>::iterator iter = mActiveReports.find (type);
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:
void verifierMessage (const CSMWorld::UniversalId& id, const std::string& message,
int type);
const std::string& hint, int type);
signals:

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

@ -671,16 +671,24 @@ int CSMWorld::Data::startLoading (const boost::filesystem::path& path, bool base
return mReader->getRecordCount();
}
bool CSMWorld::Data::continueLoading (CSMDoc::Stage::Messages& messages)
bool CSMWorld::Data::continueLoading (CSMDoc::Messages& messages)
{
if (!mReader)
throw std::logic_error ("can't continue loading, because no load has been started");
if (!mReader->hasMoreRecs())
{
// Don't delete the Reader yet. Some record types store a reference to the Reader to handle on-demand loading
boost::shared_ptr<ESM::ESMReader> ptr(mReader);
mReaders.push_back(ptr);
if (mBase)
{
// 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;
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_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:
{
@ -775,8 +794,8 @@ bool CSMWorld::Data::continueLoading (CSMDoc::Stage::Messages& messages)
}
else
{
messages.push_back (std::make_pair (UniversalId::Type_None,
"Trying to delete dialogue record " + id + " which does not exist"));
messages.add (UniversalId::Type_None,
"Trying to delete dialogue record " + id + " which does not exist");
}
}
else
@ -792,8 +811,8 @@ bool CSMWorld::Data::continueLoading (CSMDoc::Stage::Messages& messages)
{
if (!mDialogue)
{
messages.push_back (std::make_pair (UniversalId::Type_None,
"Found info record not following a dialogue record"));
messages.add (UniversalId::Type_None,
"Found info record not following a dialogue record");
mReader->skipRecord();
break;
@ -836,8 +855,7 @@ bool CSMWorld::Data::continueLoading (CSMDoc::Stage::Messages& messages)
if (unhandledRecord)
{
messages.push_back (std::make_pair (UniversalId::Type_None,
"Unsupported record type: " + n.toString()));
messages.add (UniversalId::Type_None, "Unsupported record type: " + n.toString());
mReader->skipRecord();
}

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

@ -15,12 +15,15 @@ namespace CSMWorld
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.
/// Special values: -2 index unknown, -1 record does not exist yet and therefore
/// 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);
///< 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>
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");
@ -64,6 +67,8 @@ namespace CSMWorld
record.mState = RecordBase::State_Deleted;
this->setRecord (index, record);
}
return -1;
}
else
{
@ -88,12 +93,12 @@ namespace CSMWorld
index = newIndex;
}
load (record, base, index);
return load (record, base, index);
}
}
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)
{
if (index==-2)
@ -106,6 +111,7 @@ namespace CSMWorld
record2.mState = base ? RecordBase::State_BaseOnly : RecordBase::State_ModifiedOnly;
(base ? record2.mBase : record2.mModified) = record;
index = this->getSize();
this->appendRecord (record2);
}
else
@ -120,6 +126,8 @@ namespace CSMWorld
this->setRecord (index, record2);
}
return index;
}
template<typename ESXRecordT, typename IdAccessorT>

@ -11,7 +11,7 @@
#include "record.hpp"
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);
@ -36,8 +36,7 @@ void CSMWorld::RefCollection::load (ESM::ESMReader& reader, int cellIndex, bool
CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Cell,
mCells.getId (cellIndex));
messages.push_back (std::make_pair (id,
"Attempt to delete a non-existing reference"));
messages.add (id, "Attempt to delete a non-existing reference");
continue;
}

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

@ -3,6 +3,7 @@
#include <sstream>
#include <stdexcept>
#include <algorithm>
#include <OgreResourceGroupManager.h>
@ -55,7 +56,9 @@ CSMWorld::Resources::Resources (const std::string& baseDirectory, UniversalId::T
std::string file = iter->substr (baseSize+1);
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::replace (id2.begin(), id2.end(), '\\', '/');
std::map<std::string, int>::const_iterator iter = mIndex.find (id2);
if (iter==mIndex.end())

@ -16,7 +16,6 @@
#include "../../model/world/idtable.hpp"
#include "../world/subviews.hpp"
#include "../world/physicsmanager.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>);
connect (mOperations, SIGNAL (abortOperation (int)), this, SLOT (abortOperation (int)));
CSVWorld::PhysicsManager::instance()->setupPhysics(document);
}
CSVDoc::View::~View()

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

@ -60,7 +60,7 @@ bool CSVRender::Cell::addObjects (int start, int end)
}
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)
{
mCellNode = sceneManager->getRootSceneNode()->createChildSceneNode();

@ -5,6 +5,8 @@
#include <map>
#include <memory>
#include <boost/shared_ptr.hpp>
#include <OgreVector3.h>
#include <components/terrain/terraingrid.hpp>
@ -38,7 +40,7 @@ namespace CSVRender
Ogre::SceneNode *mCellNode;
std::map<std::string, Object *> mObjects;
std::auto_ptr<Terrain::TerrainGrid> mTerrain;
CSVWorld::PhysicsSystem *mPhysics;
boost::shared_ptr<CSVWorld::PhysicsSystem> mPhysics;
Ogre::SceneManager *mSceneMgr;
int mX;
int mY;
@ -56,7 +58,7 @@ namespace CSVRender
public:
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();

@ -56,7 +56,7 @@ namespace CSVRender
//
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)
, mGrabbedSceneNode(""), mOrigObjPos(Ogre::Vector3()), mOrigMousePos(Ogre::Vector3())
, mCurrentMousePos(Ogre::Vector3()), mOffset(0.0f)

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

@ -132,7 +132,7 @@ const CSMWorld::CellRef& CSVRender::Object::getReference() const
}
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)
: mData (data), mBase (0), mForceBaseToZero (forceBaseToZero), mPhysics(physics)
{
@ -156,7 +156,8 @@ CSVRender::Object::~Object()
{
clear();
mPhysics->removeObject(mBase->getName());
if(mPhysics) // preview may not have physics enabled
mPhysics->removeObject(mBase->getName());
if (mBase)
mBase->getCreator()->destroySceneNode (mBase);

@ -1,6 +1,8 @@
#ifndef OPENCS_VIEW_OBJECT_H
#define OPENCS_VIEW_OBJECT_H
#include <boost/shared_ptr.hpp>
#include <components/nifogre/ogrenifloader.hpp>
class QModelIndex;
@ -31,7 +33,7 @@ namespace CSVRender
Ogre::SceneNode *mBase;
NifOgre::ObjectScenePtr mObject;
bool mForceBaseToZero;
CSVWorld::PhysicsSystem *mPhysics;
boost::shared_ptr<CSVWorld::PhysicsSystem> mPhysics;
/// Not implemented
Object (const Object&);
@ -58,7 +60,8 @@ namespace CSVRender
Object (const CSMWorld::Data& data, Ogre::SceneNode *cellNode,
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
/// it at 0, 0, 0 instead.

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

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

@ -10,7 +10,7 @@
CSVRender::PreviewWidget::PreviewWidget (CSMWorld::Data& data,
const std::string& id, bool referenceable, QWidget *parent)
: 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);

@ -49,7 +49,7 @@ CSVRender::UnpagedWorldspaceWidget::UnpagedWorldspaceWidget (const std::string&
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,
@ -91,7 +91,7 @@ bool CSVRender::UnpagedWorldspaceWidget::handleDrop (const std::vector<CSMWorld:
return false;
mCellId = data.begin()->getId();
mCell.reset (new Cell (getDocument().getData(), getSceneManager(), mCellId, getPhysics()));
mCell.reset (new Cell (getDocument().getData(), getSceneManager(), mCellId, getDocument().getPhysics()));
update();
emit cellChanged(*data.begin());
@ -153,6 +153,14 @@ void CSVRender::UnpagedWorldspaceWidget::referenceAdded (const QModelIndex& pare
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()
{
Ogre::Vector3 position = getCamera()->getPosition();

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

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

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

@ -1,31 +1,15 @@
#include "reportsubview.hpp"
#include <QTableView>
#include <QHeaderView>
#include "../../model/tools/reportmodel.hpp"
#include "../../view/world/idtypedelegate.hpp"
#include "reporttable.hpp"
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));
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);
setWidget (mTable = new ReportTable (document, id, this));
mTable->setItemDelegateForColumn (0, mIdTypeDelegate);
connect (mTable, SIGNAL (doubleClicked (const QModelIndex&)), this, SLOT (show (const QModelIndex&)));
connect (mTable, SIGNAL (editRequest (const CSMWorld::UniversalId&, const std::string&)),
SIGNAL (focusId (const CSMWorld::UniversalId&, const std::string&)));
}
void CSVTools::ReportSubView::setEditLock (bool locked)
@ -33,13 +17,7 @@ void CSVTools::ReportSubView::setEditLock (bool locked)
// ignored. We don't change document state anyway.
}
void CSVTools::ReportSubView::updateUserSetting
(const QString &name, const QStringList &list)
{
mIdTypeDelegate->updateUserSetting (name, list);
}
void CSVTools::ReportSubView::show (const QModelIndex& index)
void CSVTools::ReportSubView::updateUserSetting (const QString &name, const QStringList &list)
{
focusId (mModel->getUniversalId (index.row()), "");
mTable->updateUserSetting (name, list);
}

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

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

@ -56,7 +56,7 @@ namespace CSVWidget
/// \attention After the last button has been added, setSelection must be called at
/// least once to finalise the layout.
void addButton (unsigned int id,
const QString& name, const QString& tooltip = "");
const QString& name, const QString& tooltip = "", bool disabled = false);
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);
}
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()
{
if (mEditor->isChangeLocked())

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

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

@ -40,11 +40,11 @@ add_openmw_dir (mwgui
merchantrepair repair soulgemdialog companionwindow bookpage journalviewmodel journalbooks
itemmodel containeritemmodel inventoryitemmodel sortfilteritemmodel itemview
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
dialoguemanagerimp journalimp journalentry quest topic filter selectwrapper hypertextparser keywordsearch
dialoguemanagerimp journalimp journalentry quest topic filter selectwrapper hypertextparser keywordsearch scripttest
)
add_openmw_dir (mwscript

@ -40,6 +40,7 @@
#include "mwdialogue/dialoguemanagerimp.hpp"
#include "mwdialogue/journalimp.hpp"
#include "mwdialogue/scripttest.hpp"
#include "mwmechanics/mechanicsmanagerimp.hpp"
@ -79,8 +80,7 @@ bool OMW::Engine::frameRenderingQueued (const Ogre::FrameEvent& evt)
{
try
{
float frametime = std::min(evt.timeSinceLastFrame, 0.2f);
float frametime = evt.timeSinceLastFrame;
mEnvironment.setFrameDuration (frametime);
// update input
@ -175,6 +175,7 @@ OMW::Engine::Engine(Files::ConfigurationManager& configurationManager)
, mSkipMenu (false)
, mUseSound (true)
, mCompileAll (false)
, mCompileAllDialogue (false)
, mWarningsMode (1)
, mScriptContext (0)
, mFSStrict (false)
@ -426,7 +427,6 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings)
if (mCompileAll)
{
std::pair<int, int> result = MWBase::Environment::get().getScriptManager()->compileAll();
if (result.first)
std::cout
<< "compiled " << result.second << " of " << result.first << " scripts ("
@ -434,6 +434,16 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings)
<< "%)"
<< 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.
@ -478,9 +488,15 @@ void OMW::Engine::go()
}
// Start the main rendering loop
Ogre::Timer timer;
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
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
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());
}
@ -530,6 +554,11 @@ void OMW::Engine::setCompileAll (bool all)
mCompileAll = all;
}
void OMW::Engine::setCompileAllDialogue (bool all)
{
mCompileAllDialogue = all;
}
void OMW::Engine::setSoundUsage(bool soundUsage)
{
mUseSound = soundUsage;

@ -76,6 +76,7 @@ namespace OMW
bool mSkipMenu;
bool mUseSound;
bool mCompileAll;
bool mCompileAllDialogue;
int mWarningsMode;
std::string mFocusName;
std::map<std::string,std::string> mFallbackMap;
@ -178,6 +179,9 @@ namespace OMW
/// Compile all scripts (excludign dialogue scripts) at startup?
void setCompileAll (bool all);
/// Compile all dialogue scripts at startup?
void setCompileAllDialogue (bool all);
/// Font 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)
->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)
->default_value(false), "enable console-only script functionality")
@ -264,6 +267,7 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat
// scripts
engine.setCompileAll(variables["script-all"].as<bool>());
engine.setCompileAllDialogue(variables["script-all-dialogue"].as<bool>());
engine.setScriptsVerbosity(variables["script-verbose"].as<bool>());
engine.setScriptConsoleMode (variables["script-console"].as<bool>());
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
/**ie AiFollow is active and the target is the actor**/
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
/** ie AiCombat is active and the target is the actor **/
@ -204,6 +205,8 @@ namespace MWBase
/// Resurrects the player if necessary
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
* but do not keep it updated (the sound will not move with
* the object and will not stop when the object is deleted. */
Play_LoopNoEnv = Play_Loop | Play_NoEnv
Play_RemoveAtDistance = 1<<3, /* (3D only) If the listener gets further than 2000 units away
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 {
Play_TypeSfx = 1<<3, /* Normal SFX sound */
Play_TypeVoice = 1<<4, /* Voice sound */
Play_TypeFoot = 1<<5, /* Footstep sound */
Play_TypeMusic = 1<<6, /* Music track */
Play_TypeMovie = 1<<7, /* Movie audio track */
Play_TypeSfx = 1<<4, /* Normal SFX sound */
Play_TypeVoice = 1<<5, /* Voice sound */
Play_TypeFoot = 1<<6, /* Footstep sound */
Play_TypeMusic = 1<<7, /* Music track */
Play_TypeMovie = 1<<8, /* Movie audio track */
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;
/// 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
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
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
virtual void setBlindness(const int percent) = 0;
@ -342,6 +342,11 @@ namespace MWBase
virtual void setWerewolfOverlay(bool set) = 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 Book;
struct EffectList;
struct CreatureLevList;
struct ItemLevList;
}
namespace MWRender
@ -279,8 +281,10 @@ namespace MWBase
///< Attempt to fix position so that the Ptr is no longer inside collision geometry.
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
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.
/// \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 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 void togglePOV() = 0;
virtual bool isFirstPerson() const = 0;
virtual void togglePreviewMode(bool enable) = 0;
virtual bool toggleVanityMode(bool enable) = 0;
virtual void allowVanityMode(bool allow) = 0;

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

@ -119,7 +119,12 @@ namespace MWClass
// spells
for (std::vector<std::string>::const_iterator iter (ref->mBase->mSpells.mList.begin());
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
if (ref->mBase->mFlags & ESM::Creature::Weapon)
@ -346,10 +351,11 @@ namespace MWClass
setOnPcHitMe = MWBase::Environment::get().getMechanicsManager()->actorAttacked(ptr, attacker);
}
if(!object.isEmpty())
getCreatureStats(ptr).setLastHitAttemptObject(object.getClass().getId(object));
if(!successful)
{
// TODO: Handle HitAttemptOnMe script function
// Missed
MWBase::Environment::get().getSoundManager()->playSound3D(ptr, "miss", 1.0f, 1.0f);
return;
@ -672,20 +678,25 @@ namespace MWClass
if(type >= 0)
{
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();
while(sound != store.end())
{
if(type == sound->mType && !sound->mCreature.empty() &&
Misc::StringUtils::ciEqual(ptrid.substr(0, sound->mCreature.size()),
sound->mCreature))
if (type == sound->mType && !sound->mCreature.empty() && (Misc::StringUtils::ciEqual(ourId, sound->mCreature)))
sounds.push_back(&*sound);
if (type == sound->mType && sound->mCreature.empty())
fallbacksounds.push_back(&*sound);
++sound;
}
if(!sounds.empty())
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 "";
@ -879,4 +890,16 @@ namespace MWClass
MWWorld::ContainerStore& store = getContainerStore(ptr);
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 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())
{
std::string faction = ref->mBase->mFaction;
Misc::StringUtils::toLower(faction);
if(ref->mBase->mNpdtType != ESM::NPC::NPC_WITH_AUTOCALCULATED_STATS)
if (const ESM::Faction* fact = MWBase::Environment::get().getWorld()->getStore().get<ESM::Faction>().search(faction))
{
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
{
data->mNpcStats.setFactionRank(faction, (int)ref->mBase->mNpdt12.mRank);
}
std::cerr << "Warning: ignoring nonexistent faction '" << faction << "' on NPC '" << ref->mBase->mId << "'" << std::endl;
}
// creature stats
@ -361,7 +365,10 @@ namespace MWClass
for (std::vector<std::string>::const_iterator iter (race->mPowers.mList.begin());
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())
@ -385,7 +392,15 @@ namespace MWClass
// spells
for (std::vector<std::string>::const_iterator iter (ref->mBase->mSpells.mList.begin());
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
data->mInventoryStore.fill(ref->mBase->mInventory, getId(ptr), "",
@ -654,10 +669,11 @@ namespace MWClass
setOnPcHitMe = MWBase::Environment::get().getMechanicsManager()->actorAttacked(ptr, attacker);
}
if(!object.isEmpty())
getCreatureStats(ptr).setLastHitAttemptObject(object.getClass().getId(object));
if(!successful)
{
// TODO: Handle HitAttemptOnMe script function
// Missed
sndMgr->playSound3D(ptr, "miss", 1.0f, 1.0f);
return;
@ -969,6 +985,9 @@ namespace MWClass
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 GMST& gmst = getGmst();
const MWMechanics::MagicEffects &mageffects = npcdata->mNpcStats.getMagicEffects();
@ -999,37 +1018,6 @@ namespace MWClass
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
{
ensureCustomData (ptr);
@ -1275,6 +1263,7 @@ namespace MWClass
// 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
// only for biped creatures?
if(name == "moan")
return "";
if(name == "roar")
@ -1389,4 +1378,10 @@ namespace MWClass
MWWorld::ContainerStore& store = getContainerStore(ptr);
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;
///< 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;
///< Return desired movement.
@ -188,6 +185,8 @@ namespace MWClass
virtual void respawn (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
{
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)
, mTemporaryDispositionChange(0.f)
, mPermanentDispositionChange(0.f), mScriptVerbose (scriptVerbose)
@ -227,7 +227,7 @@ namespace MWDialogue
success = false;
}
if (!success && mScriptVerbose)
if (!success)
{
std::cerr
<< "compiling failed (dialogue script)" << std::endl

@ -603,6 +603,17 @@ const ESM::DialInfo* MWDialogue::Filter::search (const ESM::Dialogue& dialogue,
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,
bool fallbackToInfoRefusal, bool searchAll, bool invertDisposition) const
{

@ -55,7 +55,11 @@ namespace MWDialogue
std::vector<const ESM::DialInfo *> list (const ESM::Dialogue& dialogue,
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;
///< 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)
targetView->update();
MWBase::Environment::get().getWindowManager()->getInventoryWindow()->updateItemView();
// We need to update the view since an other item could be auto-equipped.
mSourceView->update();
}

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

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

@ -193,6 +193,9 @@ namespace MWGui
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);
paper->setNeedMouseFocus(false);
@ -207,8 +210,25 @@ namespace MWGui
continue;
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())
brBeforeLastTag = false;
brBeforeLastTag = true;
else
{
// 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:
{
pag.setIgnoreLeadingEmptyLines(false);
const BookTextParser::Attributes & attr = parser.getAttributes();
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())
{
std::string face = attr.at("face");
if (face != "Magic Cards")
mTextStyle.mFont = face;
mTextStyle.mFont = face;
}
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
// unfortunately, getLineInfo method won't be available until 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();
for (unsigned int i = lastLine; i < lines.size(); ++i)
{
if (lines[i].width == 0)
ret += lineHeight;
else
{
mPaginator.setIgnoreLeadingEmptyLines(false);
break;
}
}
#endif
return ret;

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

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

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

Loading…
Cancel
Save