Conflicts:
	apps/openmw/mwdialogue/dialoguemanagerimp.cpp
	apps/openmw/mwworld/worldimp.cpp
	components/esm_store/reclists.hpp
	components/misc/stringops.hpp
actorid
eduard 12 years ago
commit c85400b809

1
.gitignore vendored

@ -14,3 +14,4 @@ Makefile
makefile makefile
data data
*.kdev4 *.kdev4
CMakeLists.txt.user

4
.gitmodules vendored

@ -1,3 +1 @@
[submodule "extern/shiny"]
path = extern/shiny
url = git://github.com/scrawl/shiny.git

@ -15,7 +15,7 @@ include (OpenMWMacros)
# Version # Version
set (OPENMW_VERSION_MAJOR 0) set (OPENMW_VERSION_MAJOR 0)
set (OPENMW_VERSION_MINOR 19) set (OPENMW_VERSION_MINOR 20)
set (OPENMW_VERSION_RELEASE 0) set (OPENMW_VERSION_RELEASE 0)
set (OPENMW_VERSION "${OPENMW_VERSION_MAJOR}.${OPENMW_VERSION_MINOR}.${OPENMW_VERSION_RELEASE}") set (OPENMW_VERSION "${OPENMW_VERSION_MAJOR}.${OPENMW_VERSION_MINOR}.${OPENMW_VERSION_RELEASE}")
@ -26,11 +26,13 @@ configure_file ("${OpenMW_SOURCE_DIR}/Docs/mainpage.hpp.cmake" "${OpenMW_SOURCE_
option(MYGUI_STATIC "Link static build of Mygui into the binaries" FALSE) option(MYGUI_STATIC "Link static build of Mygui into the binaries" FALSE)
option(OGRE_STATIC "Link static build of Ogre and Ogre Plugins into the binaries" FALSE) option(OGRE_STATIC "Link static build of Ogre and Ogre Plugins into the binaries" FALSE)
option(BOOST_STATIC "Link static build of Boost into the binaries" FALSE)
# Apps and tools # Apps and tools
option(BUILD_ESMTOOL "build ESM inspector" ON) option(BUILD_ESMTOOL "build ESM inspector" ON)
option(BUILD_LAUNCHER "build Launcher" ON) option(BUILD_LAUNCHER "build Launcher" ON)
option(BUILD_MWINIIMPORTER "build MWiniImporter" ON) option(BUILD_MWINIIMPORTER "build MWiniImporter" ON)
option(BUILD_OPENCS "build OpenMW Construction Set" ON)
option(BUILD_WITH_CODE_COVERAGE "Enable code coverage with gconv" OFF) option(BUILD_WITH_CODE_COVERAGE "Enable code coverage with gconv" OFF)
option(BUILD_UNITTESTS "Enable Unittests with Google C++ Unittest ang GMock frameworks" OFF) option(BUILD_UNITTESTS "Enable Unittests with Google C++ Unittest ang GMock frameworks" OFF)
@ -167,9 +169,9 @@ if (WIN32)
set(PLATFORM_INCLUDE_DIR "platform") set(PLATFORM_INCLUDE_DIR "platform")
add_definitions(-DBOOST_ALL_NO_LIB) add_definitions(-DBOOST_ALL_NO_LIB)
else (WIN32) else (WIN32)
set(PLATFORM_INCLUDE_DIR "") set(PLATFORM_INCLUDE_DIR "")
find_path (UUID_INCLUDE_DIR uuid/uuid.h) find_path (UUID_INCLUDE_DIR uuid/uuid.h)
include_directories(${UUID_INCLUDE_DIR}) include_directories(${UUID_INCLUDE_DIR})
endif (WIN32) endif (WIN32)
if (MSVC10) if (MSVC10)
set(PLATFORM_INCLUDE_DIR "") set(PLATFORM_INCLUDE_DIR "")
@ -183,7 +185,7 @@ endif (APPLE)
# Fix for not visible pthreads functions for linker with glibc 2.15 # Fix for not visible pthreads functions for linker with glibc 2.15
if (UNIX AND NOT APPLE) if (UNIX AND NOT APPLE)
find_package (Threads) find_package (Threads)
endif() endif()
# find boost without components so we can use Boost_VERSION # find boost without components so we can use Boost_VERSION
@ -196,6 +198,10 @@ if (Boost_VERSION LESS 104900)
set(BOOST_COMPONENTS ${BOOST_COMPONENTS} wave) set(BOOST_COMPONENTS ${BOOST_COMPONENTS} wave)
endif() endif()
IF(BOOST_STATIC)
set(Boost_USE_STATIC_LIBS ON)
endif()
find_package(OGRE REQUIRED) find_package(OGRE REQUIRED)
find_package(MyGUI REQUIRED) find_package(MyGUI REQUIRED)
find_package(Boost REQUIRED COMPONENTS ${BOOST_COMPONENTS}) find_package(Boost REQUIRED COMPONENTS ${BOOST_COMPONENTS})
@ -356,7 +362,7 @@ if(DPKG_PROGRAM)
SET(CPACK_DEBIAN_PACKAGE_NAME "openmw") SET(CPACK_DEBIAN_PACKAGE_NAME "openmw")
SET(CPACK_DEBIAN_PACKAGE_VERSION "${VERSION_STRING}") SET(CPACK_DEBIAN_PACKAGE_VERSION "${VERSION_STRING}")
SET(CPACK_PACKAGE_EXECUTABLES "openmw;OpenMW esmtool;Esmtool omwlauncher;OMWLauncher mwiniimporter;MWiniImporter") SET(CPACK_PACKAGE_EXECUTABLES "openmw;OpenMW esmtool;Esmtool omwlauncher;OMWLauncher mwiniimporter;MWiniImporter")
SET(CPACK_DEBIAN_PACKAGE_DEPENDS "libboost-filesystem1.46.1 (>= 1.46.1), libboost-program-options1.46.1 (>= 1.46.1), libboost-system1.46.1 (>= 1.46.1), libboost-thread1.46.1 (>= 1.46.1), libc6 (>= 2.11.2), libfreetype6 (>= 2.2.1), libgcc1 (>= 1:4.1.1), libmpg123-0 (>= 1.12.1), libois-1.3.0 (>= 1.3.0), libopenal1 (>= 1:1.12.854), libsndfile1 (>= 1.0.23), libstdc++6 (>= 4.4.5), libuuid1 (>= 2.17.2), libqtgui4 (>= 4.7.0)") SET(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6 (>= 2.11.2), libfreetype6 (>= 2.2.1), libgcc1 (>= 1:4.1.1), libmpg123-0 (>= 1.12.1), libois-1.3.0 (>= 1.3.0), libopenal1 (>= 1:1.12.854), libsndfile1 (>= 1.0.23), libstdc++6 (>= 4.4.5), libuuid1 (>= 2.17.2), libqtgui4 (>= 4.7.0)")
SET(CPACK_DEBIAN_PACKAGE_SECTION "Games") SET(CPACK_DEBIAN_PACKAGE_SECTION "Games")
@ -462,6 +468,10 @@ if (BUILD_MWINIIMPORTER)
add_subdirectory( apps/mwiniimporter ) add_subdirectory( apps/mwiniimporter )
endif() endif()
if (BUILD_OPENCS)
add_subdirectory (apps/opencs)
endif()
# UnitTests # UnitTests
if (BUILD_UNITTESTS) if (BUILD_UNITTESTS)
add_subdirectory( apps/openmw_test_suite ) add_subdirectory( apps/openmw_test_suite )

@ -262,7 +262,7 @@ void printRaw(ESM::ESMReader &esm)
int load(Arguments& info) int load(Arguments& info)
{ {
ESM::ESMReader& esm = info.reader; ESM::ESMReader& esm = info.reader;
esm.setEncoding(info.encoding); esm.setEncoding(ToUTF8::calculateEncoding(info.encoding));
std::string filename = info.filename; std::string filename = info.filename;
std::cout << "Loading file: " << filename << std::endl; std::cout << "Loading file: " << filename << std::endl;

@ -738,7 +738,6 @@ void Record<ESM::GameSetting>::print()
default: default:
std::cout << "unknown type"; std::cout << "unknown type";
} }
std::cout << "\n Dirty: " << mData.mDirty << std::endl;
} }
template<> template<>
@ -1213,7 +1212,7 @@ void Record<ESM::Region>::print()
template<> template<>
void Record<ESM::Script>::print() void Record<ESM::Script>::print()
{ {
std::cout << " Name: " << mData.mData.mName.toString() << std::endl; std::cout << " Name: " << mData.mId << std::endl;
std::cout << " Num Shorts: " << mData.mData.mNumShorts << std::endl; std::cout << " Num Shorts: " << mData.mData.mNumShorts << std::endl;
std::cout << " Num Longs: " << mData.mData.mNumLongs << std::endl; std::cout << " Num Longs: " << mData.mData.mNumLongs << std::endl;
@ -1329,13 +1328,4 @@ void Record<ESM::Weapon>::print()
<< (int)mData.mData.mThrust[1] << std::endl; << (int)mData.mData.mThrust[1] << std::endl;
} }
template<>
void Record<ESM::CellRef>::print()
{
std::cout << " Refnum: " << mData.mRefnum << std::endl;
std::cout << " ID: '" << mData.mRefID << "'\n";
std::cout << " Owner: '" << mData.mOwner << "'\n";
std::cout << " INTV: " << mData.mIntv << " NAM9: " << mData.mIntv << std::endl;
}
} // end namespace } // end namespace

@ -2,6 +2,8 @@
#include <QFileInfo> #include <QFileInfo>
#include <QDir> #include <QDir>
#include <stdexcept>
#include <components/esm/esmreader.hpp> #include <components/esm/esmreader.hpp>
#include "esm/esmfile.hpp" #include "esm/esmfile.hpp"
@ -270,7 +272,7 @@ void DataFilesModel::addMasters(const QString &path)
foreach (const QString &path, dir.entryList()) { foreach (const QString &path, dir.entryList()) {
try { try {
ESM::ESMReader fileReader; ESM::ESMReader fileReader;
fileReader.setEncoding(mEncoding.toStdString()); fileReader.setEncoding(ToUTF8::calculateEncoding(mEncoding.toStdString()));
fileReader.open(dir.absoluteFilePath(path).toStdString()); fileReader.open(dir.absoluteFilePath(path).toStdString());
ESM::ESMReader::MasterList mlist = fileReader.getMasters(); ESM::ESMReader::MasterList mlist = fileReader.getMasters();
@ -333,7 +335,7 @@ void DataFilesModel::addPlugins(const QString &path)
try { try {
ESM::ESMReader fileReader; ESM::ESMReader fileReader;
fileReader.setEncoding(mEncoding.toStdString()); fileReader.setEncoding(ToUTF8::calculateEncoding(mEncoding.toStdString()));
fileReader.open(dir.absoluteFilePath(path).toStdString()); fileReader.open(dir.absoluteFilePath(path).toStdString());
ESM::ESMReader::MasterList mlist = fileReader.getMasters(); ESM::ESMReader::MasterList mlist = fileReader.getMasters();

@ -0,0 +1,76 @@
set (OPENCS_SRC
main.cpp editor.cpp
model/doc/documentmanager.cpp model/doc/document.cpp
model/world/universalid.cpp model/world/idcollection.cpp model/world/data.cpp model/world/idtable.cpp
model/world/commands.cpp model/world/idtableproxymodel.cpp model/world/record.cpp
model/world/columnbase.cpp
model/tools/tools.cpp model/tools/operation.cpp model/tools/stage.cpp model/tools/verifier.cpp
model/tools/mandatoryid.cpp model/tools/reportmodel.cpp
view/doc/viewmanager.cpp view/doc/view.cpp view/doc/operations.cpp view/doc/operation.cpp view/doc/subviewfactory.cpp
view/doc/subview.cpp
view/world/table.cpp view/world/tablesubview.cpp view/world/subviews.cpp view/world/util.cpp
view/world/dialoguesubview.cpp
view/tools/reportsubview.cpp view/tools/subviews.cpp
)
set (OPENCS_HDR
editor.hpp
model/doc/documentmanager.hpp model/doc/document.hpp model/doc/state.hpp
model/world/universalid.hpp model/world/record.hpp model/world/idcollection.hpp model/world/data.hpp
model/world/idtable.hpp model/world/columns.hpp model/world/idtableproxymodel.hpp
model/world/commands.hpp model/world/columnbase.hpp
model/tools/tools.hpp model/tools/operation.hpp model/tools/stage.hpp model/tools/verifier.hpp
model/tools/mandatoryid.hpp model/tools/reportmodel.hpp
view/doc/viewmanager.hpp view/doc/view.hpp view/doc/operations.hpp view/doc/operation.hpp view/doc/subviewfactory.hpp
view/doc/subview.hpp view/doc/subviewfactoryimp.hpp
view/world/table.hpp view/world/tablesubview.hpp view/world/subviews.hpp view/world/util.hpp
view/world/dialoguesubview.hpp
view/tools/reportsubview.hpp view/tools/subviews.hpp
)
set (OPENCS_US
)
set (OPENCS_RES
)
source_group (opencs FILES ${OPENCS_SRC} ${OPENCS_HDR})
if(WIN32)
set(QT_USE_QTMAIN TRUE)
endif(WIN32)
find_package(Qt4 COMPONENTS QtCore QtGui QtXml QtXmlPatterns REQUIRED)
include(${QT_USE_FILE})
qt4_wrap_ui(OPENCS_UI_HDR ${OPENCS_UI})
qt4_wrap_cpp(OPENCS_MOC_SRC ${OPENCS_HDR})
qt4_add_resources(OPENCS_RES_SRC ${OPENCS_RES})
include_directories(${CMAKE_CURRENT_BINARY_DIR})
add_executable(opencs
${OPENCS_SRC}
${OPENCS_UI_HDR}
${OPENCS_MOC_SRC}
${OPENCS_RES_SRC}
)
target_link_libraries(opencs
${Boost_LIBRARIES}
${QT_LIBRARIES}
components
)

@ -0,0 +1,49 @@
#include "editor.hpp"
#include <sstream>
#include <QtGui/QApplication>
#include "model/doc/document.hpp"
#include "model/world/data.hpp"
CS::Editor::Editor() : mViewManager (mDocumentManager), mNewDocumentIndex (0)
{
connect (&mViewManager, SIGNAL (newDocumentRequest ()), this, SLOT (createDocument ()));
}
void CS::Editor::createDocument()
{
std::ostringstream stream;
stream << "NewDocument" << (++mNewDocumentIndex);
CSMDoc::Document *document = mDocumentManager.addDocument (stream.str());
static const char *sGlobals[] =
{
"Day", "DaysPassed", "GameHour", "Month", "PCRace", "PCVampire", "PCWerewolf", "PCYear", 0
};
for (int i=0; sGlobals[i]; ++i)
{
ESM::Global record;
record.mId = sGlobals[i];
record.mValue = i==0 ? 1 : 0;
record.mType = ESM::VT_Float;
document->getData().getGlobals().add (record);
}
document->getData().merge(); /// \todo remove once proper ESX loading is implemented
mViewManager.addView (document);
}
int CS::Editor::run()
{
/// \todo Instead of creating an empty document, open a small welcome dialogue window with buttons for new/load/recent projects
createDocument();
return QApplication::exec();
}

@ -0,0 +1,37 @@
#ifndef CS_EDITOR_H
#define CS_EDITOR_H
#include <QObject>
#include "model/doc/documentmanager.hpp"
#include "view/doc/viewmanager.hpp"
namespace CS
{
class Editor : public QObject
{
Q_OBJECT
int mNewDocumentIndex; ///< \todo remove when the proper new document dialogue is implemented.
CSMDoc::DocumentManager mDocumentManager;
CSVDoc::ViewManager mViewManager;
// not implemented
Editor (const Editor&);
Editor& operator= (const Editor&);
public:
Editor();
int run();
///< \return error status
public slots:
void createDocument();
};
}
#endif

@ -0,0 +1,39 @@
#include "editor.hpp"
#include <exception>
#include <iostream>
#include <QtGui/QApplication>
class Application : public QApplication
{
private:
bool notify (QObject *receiver, QEvent *event)
{
try
{
return QApplication::notify (receiver, event);
}
catch (const std::exception& exception)
{
std::cerr << "An exception has been caught: " << exception.what() << std::endl;
}
return false;
}
public:
Application (int& argc, char *argv[]) : QApplication (argc, argv) {}
};
int main(int argc, char *argv[])
{
Application mApplication (argc, argv);
CS::Editor editor;
return editor.run();
}

@ -0,0 +1,114 @@
#include "document.hpp"
CSMDoc::Document::Document (const std::string& name)
: mTools (mData)
{
mName = name; ///< \todo replace with ESX list
connect (&mUndoStack, SIGNAL (cleanChanged (bool)), this, SLOT (modificationStateChanged (bool)));
connect (&mTools, SIGNAL (progress (int, int, int)), this, SLOT (progress (int, int, int)));
connect (&mTools, SIGNAL (done (int)), this, SLOT (operationDone (int)));
// dummy implementation -> remove when proper save is implemented.
mSaveCount = 0;
connect (&mSaveTimer, SIGNAL(timeout()), this, SLOT (saving()));
}
QUndoStack& CSMDoc::Document::getUndoStack()
{
return mUndoStack;
}
int CSMDoc::Document::getState() const
{
int state = 0;
if (!mUndoStack.isClean())
state |= State_Modified;
if (mSaveCount)
state |= State_Locked | State_Saving | State_Operation;
if (int operations = mTools.getRunningOperations())
state |= State_Locked | State_Operation | operations;
return state;
}
const std::string& CSMDoc::Document::getName() const
{
return mName;
}
void CSMDoc::Document::save()
{
mSaveCount = 1;
mSaveTimer.start (500);
emit stateChanged (getState(), this);
emit progress (1, 16, State_Saving, 1, this);
}
CSMWorld::UniversalId CSMDoc::Document::verify()
{
CSMWorld::UniversalId id = mTools.runVerifier();
emit stateChanged (getState(), this);
return id;
}
void CSMDoc::Document::abortOperation (int type)
{
mTools.abortOperation (type);
if (type==State_Saving)
{
mSaveTimer.stop();
emit stateChanged (getState(), this);
}
}
void CSMDoc::Document::modificationStateChanged (bool clean)
{
emit stateChanged (getState(), this);
}
void CSMDoc::Document::operationDone (int type)
{
emit stateChanged (getState(), this);
}
void CSMDoc::Document::saving()
{
++mSaveCount;
emit progress (mSaveCount, 16, State_Saving, 1, this);
if (mSaveCount>15)
{
mSaveCount = 0;
mSaveTimer.stop();
mUndoStack.setClean();
emit stateChanged (getState(), this);
}
}
const CSMWorld::Data& CSMDoc::Document::getData() const
{
return mData;
}
CSMWorld::Data& CSMDoc::Document::getData()
{
return mData;
}
CSMTools::ReportModel *CSMDoc::Document::getReport (const CSMWorld::UniversalId& id)
{
return mTools.getReport (id);
}
void CSMDoc::Document::progress (int current, int max, int type)
{
emit progress (current, max, type, 1, this);
}

@ -0,0 +1,87 @@
#ifndef CSM_DOC_DOCUMENT_H
#define CSM_DOC_DOCUMENT_H
#include <string>
#include <QUndoStack>
#include <QObject>
#include <QTimer>
#include "../world/data.hpp"
#include "../tools/tools.hpp"
#include "state.hpp"
class QAbstractItemModel;
namespace CSMDoc
{
class Document : public QObject
{
Q_OBJECT
private:
std::string mName; ///< \todo replace name with ESX list
CSMWorld::Data mData;
CSMTools::Tools mTools;
// 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.
QUndoStack mUndoStack;
int mSaveCount; ///< dummy implementation -> remove when proper save is implemented.
QTimer mSaveTimer; ///< dummy implementation -> remove when proper save is implemented.
// not implemented
Document (const Document&);
Document& operator= (const Document&);
public:
Document (const std::string& name);
///< \todo replace name with ESX list
QUndoStack& getUndoStack();
int getState() const;
const std::string& getName() const;
///< \todo replace with ESX list
void save();
CSMWorld::UniversalId verify();
void abortOperation (int type);
const CSMWorld::Data& getData() const;
CSMWorld::Data& getData();
CSMTools::ReportModel *getReport (const CSMWorld::UniversalId& id);
///< The ownership of the returned report is not transferred.
signals:
void stateChanged (int state, CSMDoc::Document *document);
void progress (int current, int max, int type, int threads, CSMDoc::Document *document);
private slots:
void modificationStateChanged (bool clean);
void operationDone (int type);
void saving();
///< dummy implementation -> remove when proper save is implemented.
public slots:
void progress (int current, int max, int type);
};
}
#endif

@ -0,0 +1,37 @@
#include "documentmanager.hpp"
#include <algorithm>
#include <stdexcept>
#include "document.hpp"
CSMDoc::DocumentManager::DocumentManager() {}
CSMDoc::DocumentManager::~DocumentManager()
{
for (std::vector<Document *>::iterator iter (mDocuments.begin()); iter!=mDocuments.end(); ++iter)
delete *iter;
}
CSMDoc::Document *CSMDoc::DocumentManager::addDocument (const std::string& name)
{
Document *document = new Document (name);
mDocuments.push_back (document);
return document;
}
bool CSMDoc::DocumentManager::removeDocument (Document *document)
{
std::vector<Document *>::iterator iter = std::find (mDocuments.begin(), mDocuments.end(), document);
if (iter==mDocuments.end())
throw std::runtime_error ("removing invalid document");
mDocuments.erase (iter);
delete document;
return mDocuments.empty();
}

@ -0,0 +1,32 @@
#ifndef CSM_DOC_DOCUMENTMGR_H
#define CSM_DOC_DOCUMENTMGR_H
#include <vector>
#include <string>
namespace CSMDoc
{
class Document;
class DocumentManager
{
std::vector<Document *> mDocuments;
DocumentManager (const DocumentManager&);
DocumentManager& operator= (const DocumentManager&);
public:
DocumentManager();
~DocumentManager();
Document *addDocument (const std::string& name);
///< The ownership of the returned document is not transferred to the caller.
bool removeDocument (Document *document);
///< \return last document removed?
};
}
#endif

@ -0,0 +1,19 @@
#ifndef CSM_DOC_STATE_H
#define CSM_DOC_STATE_H
namespace CSMDoc
{
enum State
{
State_Modified = 1,
State_Locked = 2,
State_Operation = 4,
State_Saving = 8,
State_Verifying = 16,
State_Compiling = 32, // not implemented yet
State_Searching = 64 // not implemented yet
};
}
#endif

@ -0,0 +1,21 @@
#include "mandatoryid.hpp"
#include "../world/idcollection.hpp"
CSMTools::MandatoryIdStage::MandatoryIdStage (const CSMWorld::IdCollectionBase& idCollection,
const CSMWorld::UniversalId& collectionId, const std::vector<std::string>& ids)
: mIdCollection (idCollection), mCollectionId (collectionId), mIds (ids)
{}
int CSMTools::MandatoryIdStage::setup()
{
return mIds.size();
}
void CSMTools::MandatoryIdStage::perform (int stage, std::vector<std::string>& messages)
{
if (mIdCollection.searchId (mIds.at (stage))==-1 ||
mIdCollection.getRecord (mIds.at (stage)).isDeleted())
messages.push_back (mCollectionId.toString() + "|Missing mandatory record: " + mIds.at (stage));
}

@ -0,0 +1,38 @@
#ifndef CSM_TOOLS_MANDATORYID_H
#define CSM_TOOLS_MANDATORYID_H
#include <string>
#include <vector>
#include "../world/universalid.hpp"
#include "stage.hpp"
namespace CSMWorld
{
class IdCollectionBase;
}
namespace CSMTools
{
/// \brief Verify stage: make sure that records with specific IDs exist.
class MandatoryIdStage : public Stage
{
const CSMWorld::IdCollectionBase& mIdCollection;
CSMWorld::UniversalId mCollectionId;
std::vector<std::string> mIds;
public:
MandatoryIdStage (const CSMWorld::IdCollectionBase& idCollection, const CSMWorld::UniversalId& collectionId,
const std::vector<std::string>& ids);
virtual int setup();
///< \return number of steps
virtual void perform (int stage, std::vector<std::string>& messages);
///< Messages resulting from this tage will be appended to \a messages.
};
}
#endif

@ -0,0 +1,84 @@
#include "operation.hpp"
#include <string>
#include <vector>
#include <QTimer>
#include "../doc/state.hpp"
#include "stage.hpp"
void CSMTools::Operation::prepareStages()
{
mCurrentStage = mStages.begin();
mCurrentStep = 0;
mCurrentStepTotal = 0;
mTotalSteps = 0;
for (std::vector<std::pair<Stage *, int> >::iterator iter (mStages.begin()); iter!=mStages.end(); ++iter)
{
iter->second = iter->first->setup();
mTotalSteps += iter->second;
}
}
CSMTools::Operation::Operation (int type) : mType (type) {}
CSMTools::Operation::~Operation()
{
for (std::vector<std::pair<Stage *, int> >::iterator iter (mStages.begin()); iter!=mStages.end(); ++iter)
delete iter->first;
}
void CSMTools::Operation::run()
{
prepareStages();
QTimer timer;
timer.connect (&timer, SIGNAL (timeout()), this, SLOT (verify()));
timer.start (0);
exec();
}
void CSMTools::Operation::appendStage (Stage *stage)
{
mStages.push_back (std::make_pair (stage, 0));
}
void CSMTools::Operation::abort()
{
exit();
}
void CSMTools::Operation::verify()
{
std::vector<std::string> messages;
while (mCurrentStage!=mStages.end())
{
if (mCurrentStep>=mCurrentStage->second)
{
mCurrentStep = 0;
++mCurrentStage;
}
else
{
mCurrentStage->first->perform (mCurrentStep++, messages);
++mCurrentStepTotal;
break;
}
}
emit progress (mCurrentStepTotal, mTotalSteps ? mTotalSteps : 1, mType);
for (std::vector<std::string>::const_iterator iter (messages.begin()); iter!=messages.end(); ++iter)
emit reportMessage (iter->c_str(), mType);
if (mCurrentStage==mStages.end())
exit();
}

@ -0,0 +1,54 @@
#ifndef CSM_TOOLS_OPERATION_H
#define CSM_TOOLS_OPERATION_H
#include <vector>
#include <QThread>
namespace CSMTools
{
class Stage;
class Operation : public QThread
{
Q_OBJECT
int mType;
std::vector<std::pair<Stage *, int> > mStages; // stage, number of steps
std::vector<std::pair<Stage *, int> >::iterator mCurrentStage;
int mCurrentStep;
int mCurrentStepTotal;
int mTotalSteps;
void prepareStages();
public:
Operation (int type);
virtual ~Operation();
virtual void run();
void appendStage (Stage *stage);
///< The ownership of \a stage is transferred to *this.
///
/// \attention Do no call this function while this Operation is running.
signals:
void progress (int current, int max, int type);
void reportMessage (const QString& message, int type);
public slots:
void abort();
private slots:
void verify();
};
}
#endif

@ -0,0 +1,71 @@
#include "reportmodel.hpp"
#include <stdexcept>
int CSMTools::ReportModel::rowCount (const QModelIndex & parent) const
{
if (parent.isValid())
return 0;
return mRows.size();
}
int CSMTools::ReportModel::columnCount (const QModelIndex & parent) const
{
if (parent.isValid())
return 0;
return 2;
}
QVariant CSMTools::ReportModel::data (const QModelIndex & index, int role) const
{
if (role!=Qt::DisplayRole)
return QVariant();
if (index.column()==0)
return static_cast<int> (mRows.at (index.row()).first.getType());
else
return mRows.at (index.row()).second.c_str();
}
QVariant CSMTools::ReportModel::headerData (int section, Qt::Orientation orientation, int role) const
{
if (role!=Qt::DisplayRole)
return QVariant();
if (orientation==Qt::Vertical)
return QVariant();
return tr (section==0 ? "Type" : "Description");
}
bool CSMTools::ReportModel::removeRows (int row, int count, const QModelIndex& parent)
{
if (parent.isValid())
return false;
mRows.erase (mRows.begin()+row, mRows.begin()+row+count);
return true;
}
void CSMTools::ReportModel::add (const std::string& row)
{
std::string::size_type index = row.find ('|');
if (index==std::string::npos)
throw std::logic_error ("invalid report message");
beginInsertRows (QModelIndex(), mRows.size(), mRows.size());
mRows.push_back (std::make_pair (row.substr (0, index), row.substr (index+1)));
endInsertRows();
}
const CSMWorld::UniversalId& CSMTools::ReportModel::getUniversalId (int row) const
{
return mRows.at (row).first;
}

@ -0,0 +1,37 @@
#ifndef CSM_TOOLS_REPORTMODEL_H
#define CSM_TOOLS_REPORTMODEL_H
#include <vector>
#include <string>
#include <QAbstractTableModel>
#include "../world/universalid.hpp"
namespace CSMTools
{
class ReportModel : public QAbstractTableModel
{
Q_OBJECT
std::vector<std::pair<CSMWorld::UniversalId, std::string> > mRows;
public:
virtual int rowCount (const QModelIndex & parent = QModelIndex()) const;
virtual int columnCount (const QModelIndex & parent = QModelIndex()) const;
virtual QVariant data (const QModelIndex & index, int role = Qt::DisplayRole) const;
virtual QVariant headerData (int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
virtual bool removeRows (int row, int count, const QModelIndex& parent = QModelIndex());
void add (const std::string& row);
const CSMWorld::UniversalId& getUniversalId (int row) const;
};
}
#endif

@ -0,0 +1,4 @@
#include "stage.hpp"
CSMTools::Stage::~Stage() {}

@ -0,0 +1,24 @@
#ifndef CSM_TOOLS_STAGE_H
#define CSM_TOOLS_STAGE_H
#include <vector>
#include <string>
namespace CSMTools
{
class Stage
{
public:
virtual ~Stage();
virtual int setup() = 0;
///< \return number of steps
virtual void perform (int stage, std::vector<std::string>& messages) = 0;
///< Messages resulting from this tage will be appended to \a messages.
};
}
#endif

@ -0,0 +1,123 @@
#include "tools.hpp"
#include <QThreadPool>
#include "verifier.hpp"
#include "../doc/state.hpp"
#include "../world/data.hpp"
#include "../world/universalid.hpp"
#include "reportmodel.hpp"
#include "mandatoryid.hpp"
CSMTools::Operation *CSMTools::Tools::get (int type)
{
switch (type)
{
case CSMDoc::State_Verifying: return mVerifier;
}
return 0;
}
const CSMTools::Operation *CSMTools::Tools::get (int type) const
{
return const_cast<Tools *> (this)->get (type);
}
CSMTools::Verifier *CSMTools::Tools::getVerifier()
{
if (!mVerifier)
{
mVerifier = new Verifier;
connect (mVerifier, SIGNAL (progress (int, int, int)), this, SIGNAL (progress (int, int, int)));
connect (mVerifier, SIGNAL (finished()), this, SLOT (verifierDone()));
connect (mVerifier, SIGNAL (reportMessage (const QString&, int)),
this, SLOT (verifierMessage (const QString&, int)));
std::vector<std::string> mandatoryIds; // I want C++11, damn it!
mandatoryIds.push_back ("Day");
mandatoryIds.push_back ("DaysPassed");
mandatoryIds.push_back ("GameHour");
mandatoryIds.push_back ("Month");
mandatoryIds.push_back ("PCRace");
mandatoryIds.push_back ("PCVampire");
mandatoryIds.push_back ("PCWerewolf");
mandatoryIds.push_back ("PCYear");
mVerifier->appendStage (new MandatoryIdStage (mData.getGlobals(),
CSMWorld::UniversalId (CSMWorld::UniversalId::Type_Globals), mandatoryIds));
}
return mVerifier;
}
CSMTools::Tools::Tools (CSMWorld::Data& data) : mData (data), mVerifier (0), mNextReportNumber (0)
{
for (std::map<int, ReportModel *>::iterator iter (mReports.begin()); iter!=mReports.end(); ++iter)
delete iter->second;
}
CSMTools::Tools::~Tools()
{
delete mVerifier;
}
CSMWorld::UniversalId CSMTools::Tools::runVerifier()
{
mReports.insert (std::make_pair (mNextReportNumber++, new ReportModel));
mActiveReports[CSMDoc::State_Verifying] = mNextReportNumber-1;
getVerifier()->start();
return CSMWorld::UniversalId (CSMWorld::UniversalId::Type_VerificationResults, mNextReportNumber-1);
}
void CSMTools::Tools::abortOperation (int type)
{
if (Operation *operation = get (type))
operation->abort();
}
int CSMTools::Tools::getRunningOperations() const
{
static const int sOperations[] =
{
CSMDoc::State_Verifying,
-1
};
int result = 0;
for (int i=0; sOperations[i]!=-1; ++i)
if (const Operation *operation = get (sOperations[i]))
if (operation->isRunning())
result |= sOperations[i];
return result;
}
CSMTools::ReportModel *CSMTools::Tools::getReport (const CSMWorld::UniversalId& id)
{
if (id.getType()!=CSMWorld::UniversalId::Type_VerificationResults)
throw std::logic_error ("invalid request for report model: " + id.toString());
return mReports.at (id.getIndex());
}
void CSMTools::Tools::verifierDone()
{
emit done (CSMDoc::State_Verifying);
}
void CSMTools::Tools::verifierMessage (const QString& message, int type)
{
std::map<int, int>::iterator iter = mActiveReports.find (type);
if (iter!=mActiveReports.end())
mReports[iter->second]->add (message.toStdString());
}

@ -0,0 +1,73 @@
#ifndef CSM_TOOLS_TOOLS_H
#define CSM_TOOLS_TOOLS_H
#include <QObject>
#include <map>
namespace CSMWorld
{
class Data;
class UniversalId;
}
namespace CSMTools
{
class Verifier;
class Operation;
class ReportModel;
class Tools : public QObject
{
Q_OBJECT
CSMWorld::Data& mData;
Verifier *mVerifier;
std::map<int, ReportModel *> mReports;
int mNextReportNumber;
std::map<int, int> mActiveReports; // type, report number
// not implemented
Tools (const Tools&);
Tools& operator= (const Tools&);
Verifier *getVerifier();
Operation *get (int type);
///< Returns a 0-pointer, if operation hasn't been used yet.
const Operation *get (int type) const;
///< Returns a 0-pointer, if operation hasn't been used yet.
public:
Tools (CSMWorld::Data& data);
virtual ~Tools();
CSMWorld::UniversalId runVerifier();
///< \return ID of the report for this verification run
void abortOperation (int type);
///< \attention The operation is not aborted immediately.
int getRunningOperations() const;
ReportModel *getReport (const CSMWorld::UniversalId& id);
///< The ownership of the returned report is not transferred.
private slots:
void verifierDone();
void verifierMessage (const QString& message, int type);
signals:
void progress (int current, int max, int type);
void done (int type);
};
}
#endif

@ -0,0 +1,7 @@
#include "verifier.hpp"
#include "../doc/state.hpp"
CSMTools::Verifier::Verifier() : Operation (CSMDoc::State_Verifying)
{}

@ -0,0 +1,17 @@
#ifndef CSM_TOOLS_VERIFIER_H
#define CSM_TOOLS_VERIFIER_H
#include "operation.hpp"
namespace CSMTools
{
class Verifier : public Operation
{
public:
Verifier();
};
}
#endif

@ -0,0 +1,13 @@
#include "columnbase.hpp"
CSMWorld::ColumnBase::ColumnBase (const std::string& title, int flags)
: mTitle (title), mFlags (flags)
{}
CSMWorld::ColumnBase::~ColumnBase() {}
bool CSMWorld::ColumnBase::isUserEditable() const
{
return isEditable();
}

@ -0,0 +1,57 @@
#ifndef CSM_WOLRD_COLUMNBASE_H
#define CSM_WOLRD_COLUMNBASE_H
#include <string>
#include <Qt>
#include <QVariant>
#include "record.hpp"
namespace CSMWorld
{
struct ColumnBase
{
enum Roles
{
Role_Flags = Qt::UserRole
};
enum Flags
{
Flag_Table = 1, // column should be displayed in table view
Flag_Dialogue = 2 // column should be displayed in dialogue view
};
std::string mTitle;
int mFlags;
ColumnBase (const std::string& title, int flag);
virtual ~ColumnBase();
virtual bool isEditable() const = 0;
virtual bool isUserEditable() const;
///< Can this column be edited directly by the user?
};
template<typename ESXRecordT>
struct Column : public ColumnBase
{
std::string mTitle;
int mFlags;
Column (const std::string& title, int flags = Flag_Table | Flag_Dialogue)
: ColumnBase (title, flags) {}
virtual QVariant get (const Record<ESXRecordT>& record) const = 0;
virtual void set (Record<ESXRecordT>& record, const QVariant& data)
{
throw std::logic_error ("Column " + mTitle + " is not editable");
}
};
}
#endif

@ -0,0 +1,95 @@
#ifndef CSM_WOLRD_COLUMNS_H
#define CSM_WOLRD_COLUMNS_H
#include "idcollection.hpp"
namespace CSMWorld
{
template<typename ESXRecordT>
struct FloatValueColumn : public Column<ESXRecordT>
{
FloatValueColumn() : Column<ESXRecordT> ("Value") {}
virtual QVariant get (const Record<ESXRecordT>& record) const
{
return record.get().mValue;
}
virtual void set (Record<ESXRecordT>& record, const QVariant& data)
{
ESXRecordT base = record.getBase();
base.mValue = data.toFloat();
record.setModified (base);
}
virtual bool isEditable() const
{
return true;
}
};
template<typename ESXRecordT>
struct StringIdColumn : public Column<ESXRecordT>
{
StringIdColumn() : Column<ESXRecordT> ("ID") {}
virtual QVariant get (const Record<ESXRecordT>& record) const
{
return record.get().mId.c_str();
}
virtual bool isEditable() const
{
return false;
}
};
template<typename ESXRecordT>
struct RecordStateColumn : public Column<ESXRecordT>
{
RecordStateColumn() : Column<ESXRecordT> ("*") {}
virtual QVariant get (const Record<ESXRecordT>& record) const
{
if (record.mState==Record<ESXRecordT>::State_Erased)
return static_cast<int> (Record<ESXRecordT>::State_Deleted);
return static_cast<int> (record.mState);
}
virtual void set (Record<ESXRecordT>& record, const QVariant& data)
{
record.mState = static_cast<RecordBase::State> (data.toInt());
}
virtual bool isEditable() const
{
return true;
}
virtual bool isUserEditable() const
{
return false;
}
};
template<typename ESXRecordT>
struct FixedRecordTypeColumn : public Column<ESXRecordT>
{
int mType;
FixedRecordTypeColumn (int type) : Column<ESXRecordT> ("Type", 0), mType (type) {}
virtual QVariant get (const Record<ESXRecordT>& record) const
{
return mType;
}
virtual bool isEditable() const
{
return false;
}
};
}
#endif

@ -0,0 +1,108 @@
#include "commands.hpp"
#include <QAbstractTableModel>
#include "idtableproxymodel.hpp"
#include "idtable.hpp"
CSMWorld::ModifyCommand::ModifyCommand (QAbstractItemModel& model, const QModelIndex& index,
const QVariant& new_, QUndoCommand *parent)
: QUndoCommand (parent), mModel (model), mIndex (index), mNew (new_)
{
mOld = mModel.data (mIndex, Qt::EditRole);
setText ("Modify " + mModel.headerData (mIndex.column(), Qt::Horizontal, Qt::DisplayRole).toString());
}
void CSMWorld::ModifyCommand::redo()
{
mModel.setData (mIndex, mNew);
}
void CSMWorld::ModifyCommand::undo()
{
mModel.setData (mIndex, mOld);
}
CSMWorld::CreateCommand::CreateCommand (IdTableProxyModel& model, const std::string& id, QUndoCommand *parent)
: QUndoCommand (parent), mModel (model), mId (id)
{
setText (("Create record " + id).c_str());
}
void CSMWorld::CreateCommand::redo()
{
mModel.addRecord (mId);
}
void CSMWorld::CreateCommand::undo()
{
mModel.removeRow (mModel.getModelIndex (mId, 0).row());
}
CSMWorld::RevertCommand::RevertCommand (IdTable& model, const std::string& id, QUndoCommand *parent)
: QUndoCommand (parent), mModel (model), mId (id), mOld (0)
{
setText (("Revert record " + id).c_str());
mOld = model.getRecord (id).clone();
}
CSMWorld::RevertCommand::~RevertCommand()
{
delete mOld;
}
void CSMWorld::RevertCommand::redo()
{
QModelIndex index = mModel.getModelIndex (mId, 1);
RecordBase::State state = static_cast<RecordBase::State> (mModel.data (index).toInt());
if (state==RecordBase::State_ModifiedOnly)
{
mModel.removeRows (index.row(), 1);
}
else
{
mModel.setData (index, static_cast<int> (RecordBase::State_BaseOnly));
}
}
void CSMWorld::RevertCommand::undo()
{
mModel.setRecord (*mOld);
}
CSMWorld::DeleteCommand::DeleteCommand (IdTable& model, const std::string& id, QUndoCommand *parent)
: QUndoCommand (parent), mModel (model), mId (id), mOld (0)
{
setText (("Delete record " + id).c_str());
mOld = model.getRecord (id).clone();
}
CSMWorld::DeleteCommand::~DeleteCommand()
{
delete mOld;
}
void CSMWorld::DeleteCommand::redo()
{
QModelIndex index = mModel.getModelIndex (mId, 1);
RecordBase::State state = static_cast<RecordBase::State> (mModel.data (index).toInt());
if (state==RecordBase::State_ModifiedOnly)
{
mModel.removeRows (index.row(), 1);
}
else
{
mModel.setData (index, static_cast<int> (RecordBase::State_Deleted));
}
}
void CSMWorld::DeleteCommand::undo()
{
mModel.setRecord (*mOld);
}

@ -0,0 +1,95 @@
#ifndef CSM_WOLRD_COMMANDS_H
#define CSM_WOLRD_COMMANDS_H
#include "record.hpp"
#include <string>
#include <QVariant>
#include <QUndoCommand>
#include <QModelIndex>
class QModelIndex;
class QAbstractItemModel;
namespace CSMWorld
{
class IdTableProxyModel;
class IdTable;
class RecordBase;
class ModifyCommand : public QUndoCommand
{
QAbstractItemModel& mModel;
QModelIndex mIndex;
QVariant mNew;
QVariant mOld;
public:
ModifyCommand (QAbstractItemModel& model, const QModelIndex& index, const QVariant& new_,
QUndoCommand *parent = 0);
virtual void redo();
virtual void undo();
};
class CreateCommand : public QUndoCommand
{
IdTableProxyModel& mModel;
std::string mId;
public:
CreateCommand (IdTableProxyModel& model, const std::string& id, QUndoCommand *parent = 0);
virtual void redo();
virtual void undo();
};
class RevertCommand : public QUndoCommand
{
IdTable& mModel;
std::string mId;
RecordBase *mOld;
// not implemented
RevertCommand (const RevertCommand&);
RevertCommand& operator= (const RevertCommand&);
public:
RevertCommand (IdTable& model, const std::string& id, QUndoCommand *parent = 0);
virtual ~RevertCommand();
virtual void redo();
virtual void undo();
};
class DeleteCommand : public QUndoCommand
{
IdTable& mModel;
std::string mId;
RecordBase *mOld;
// not implemented
DeleteCommand (const DeleteCommand&);
DeleteCommand& operator= (const DeleteCommand&);
public:
DeleteCommand (IdTable& model, const std::string& id, QUndoCommand *parent = 0);
virtual ~DeleteCommand();
virtual void redo();
virtual void undo();
};
}
#endif

@ -0,0 +1,55 @@
#include "data.hpp"
#include <stdexcept>
#include <QAbstractTableModel>
#include <components/esm/loadglob.hpp>
#include "idtable.hpp"
#include "columns.hpp"
CSMWorld::Data::Data()
{
mGlobals.addColumn (new StringIdColumn<ESM::Global>);
mGlobals.addColumn (new RecordStateColumn<ESM::Global>);
mGlobals.addColumn (new FixedRecordTypeColumn<ESM::Global> (UniversalId::Type_Global));
mGlobals.addColumn (new FloatValueColumn<ESM::Global>);
mModels.insert (std::make_pair (
UniversalId (UniversalId::Type_Globals),
new IdTable (&mGlobals)
));
}
CSMWorld::Data::~Data()
{
for (std::map<UniversalId, QAbstractTableModel *>::iterator iter (mModels.begin()); iter!=mModels.end(); ++iter)
delete iter->second;
}
const CSMWorld::IdCollection<ESM::Global>& CSMWorld::Data::getGlobals() const
{
return mGlobals;
}
CSMWorld::IdCollection<ESM::Global>& CSMWorld::Data::getGlobals()
{
return mGlobals;
}
QAbstractTableModel *CSMWorld::Data::getTableModel (const UniversalId& id)
{
std::map<UniversalId, QAbstractTableModel *>::iterator iter = mModels.find (id);
if (iter==mModels.end())
throw std::logic_error ("No table model available for " + id.toString());
return iter->second;
}
void CSMWorld::Data::merge()
{
mGlobals.merge();
}

@ -0,0 +1,42 @@
#ifndef CSM_WOLRD_IDLIST_H
#define CSM_WOLRD_IDLIST_H
#include <map>
#include <components/esm/loadglob.hpp>
#include "idcollection.hpp"
#include "universalid.hpp"
class QAbstractTableModel;
namespace CSMWorld
{
class Data
{
IdCollection<ESM::Global> mGlobals;
std::map<UniversalId, QAbstractTableModel *> mModels;
// not implemented
Data (const Data&);
Data& operator= (const Data&);
public:
Data();
~Data();
const IdCollection<ESM::Global>& getGlobals() const;
IdCollection<ESM::Global>& getGlobals();
QAbstractTableModel *getTableModel (const UniversalId& id);
///< If no table model is available for \æ id, an exception is thrown.
void merge();
///< Merge modified into base.
};
}
#endif

@ -0,0 +1,6 @@
#include "idcollection.hpp"
CSMWorld::IdCollectionBase::IdCollectionBase() {}
CSMWorld::IdCollectionBase::~IdCollectionBase() {}

@ -0,0 +1,325 @@
#ifndef CSM_WOLRD_IDCOLLECTION_H
#define CSM_WOLRD_IDCOLLECTION_H
#include <vector>
#include <map>
#include <string>
#include <algorithm>
#include <cctype>
#include <stdexcept>
#include <functional>
#include <QVariant>
#include "columnbase.hpp"
namespace CSMWorld
{
class IdCollectionBase
{
// not implemented
IdCollectionBase (const IdCollectionBase&);
IdCollectionBase& operator= (const IdCollectionBase&);
public:
IdCollectionBase();
virtual ~IdCollectionBase();
virtual int getSize() const = 0;
virtual std::string getId (int index) const = 0;
virtual int getIndex (const std::string& id) const = 0;
virtual int getColumns() const = 0;
virtual const ColumnBase& getColumn (int column) const = 0;
virtual QVariant getData (int index, int column) const = 0;
virtual void setData (int index, int column, const QVariant& data) = 0;
virtual void merge() = 0;
///< Merge modified into base.
virtual void purge() = 0;
///< Remove records that are flagged as erased.
virtual void removeRows (int index, int count) = 0;
virtual void appendBlankRecord (const std::string& id) = 0;
virtual int searchId (const std::string& id) const = 0;
////< Search record with \a id.
/// \return index of record (if found) or -1 (not found)
virtual void replace (int index, const RecordBase& record) = 0;
///< If the record type does not match, an exception is thrown.
///
/// \attention \a record must not change the ID.
virtual void appendRecord (const RecordBase& record) = 0;
///< If the record type does not match, an exception is thrown.
virtual std::string getId (const RecordBase& record) const = 0;
///< Return ID for \a record.
///
/// \attention Throw san exception, if the type of \a record does not match.
virtual const RecordBase& getRecord (const std::string& id) const = 0;
};
///< \brief Collection of ID-based records
template<typename ESXRecordT>
class IdCollection : public IdCollectionBase
{
std::vector<Record<ESXRecordT> > mRecords;
std::map<std::string, int> mIndex;
std::vector<Column<ESXRecordT> *> mColumns;
// not implemented
IdCollection (const IdCollection&);
IdCollection& operator= (const IdCollection&);
public:
IdCollection();
virtual ~IdCollection();
void add (const ESXRecordT& record);
///< Add a new record (modified)
virtual int getSize() const;
virtual std::string getId (int index) const;
virtual int getIndex (const std::string& id) const;
virtual int getColumns() const;
virtual QVariant getData (int index, int column) const;
virtual void setData (int index, int column, const QVariant& data);
virtual const ColumnBase& getColumn (int column) const;
virtual void merge();
///< Merge modified into base.
virtual void purge();
///< Remove records that are flagged as erased.
virtual void removeRows (int index, int count) ;
virtual void appendBlankRecord (const std::string& id);
virtual int searchId (const std::string& id) const;
////< Search record with \a id.
/// \return index of record (if found) or -1 (not found)
virtual void replace (int index, const RecordBase& record);
///< If the record type does not match, an exception is thrown.
///
/// \attention \a record must not change the ID.
virtual void appendRecord (const RecordBase& record);
///< If the record type does not match, an exception is thrown.
virtual std::string getId (const RecordBase& record) const;
///< Return ID for \a record.
///
/// \attention Throw san exception, if the type of \a record does not match.
virtual const RecordBase& getRecord (const std::string& id) const;
void addColumn (Column<ESXRecordT> *column);
};
template<typename ESXRecordT>
IdCollection<ESXRecordT>::IdCollection()
{}
template<typename ESXRecordT>
IdCollection<ESXRecordT>::~IdCollection()
{
for (typename std::vector<Column<ESXRecordT> *>::iterator iter (mColumns.begin()); iter!=mColumns.end(); ++iter)
delete *iter;
}
template<typename ESXRecordT>
void IdCollection<ESXRecordT>::add (const ESXRecordT& record)
{
std::string id;
std::transform (record.mId.begin(), record.mId.end(), std::back_inserter (id),
(int(*)(int)) std::tolower);
std::map<std::string, int>::iterator iter = mIndex.find (id);
if (iter==mIndex.end())
{
Record<ESXRecordT> record2;
record2.mState = Record<ESXRecordT>::State_ModifiedOnly;
record2.mModified = record;
mRecords.push_back (record2);
mIndex.insert (std::make_pair (id, mRecords.size()-1));
}
else
{
mRecords[iter->second].setModified (record);
}
}
template<typename ESXRecordT>
int IdCollection<ESXRecordT>::getSize() const
{
return mRecords.size();
}
template<typename ESXRecordT>
std::string IdCollection<ESXRecordT>::getId (int index) const
{
return mRecords.at (index).get().mId;
}
template<typename ESXRecordT>
int IdCollection<ESXRecordT>::getIndex (const std::string& id) const
{
int index = searchId (id);
if (index==-1)
throw std::runtime_error ("invalid ID: " + id);
return index;
}
template<typename ESXRecordT>
int IdCollection<ESXRecordT>::getColumns() const
{
return mColumns.size();
}
template<typename ESXRecordT>
QVariant IdCollection<ESXRecordT>::getData (int index, int column) const
{
return mColumns.at (column)->get (mRecords.at (index));
}
template<typename ESXRecordT>
void IdCollection<ESXRecordT>::setData (int index, int column, const QVariant& data)
{
return mColumns.at (column)->set (mRecords.at (index), data);
}
template<typename ESXRecordT>
const ColumnBase& IdCollection<ESXRecordT>::getColumn (int column) const
{
return *mColumns.at (column);
}
template<typename ESXRecordT>
void IdCollection<ESXRecordT>::addColumn (Column<ESXRecordT> *column)
{
mColumns.push_back (column);
}
template<typename ESXRecordT>
void IdCollection<ESXRecordT>::merge()
{
for (typename std::vector<Record<ESXRecordT> >::iterator iter (mRecords.begin()); iter!=mRecords.end(); ++iter)
iter->merge();
purge();
}
template<typename ESXRecordT>
void IdCollection<ESXRecordT>::purge()
{
mRecords.erase (std::remove_if (mRecords.begin(), mRecords.end(),
std::mem_fun_ref (&Record<ESXRecordT>::isErased) // I want lambda :(
), mRecords.end());
}
template<typename ESXRecordT>
void IdCollection<ESXRecordT>::removeRows (int index, int count)
{
mRecords.erase (mRecords.begin()+index, mRecords.begin()+index+count);
typename std::map<std::string, int>::iterator iter = mIndex.begin();
while (iter!=mIndex.end())
{
if (iter->second>=index)
{
if (iter->second>=index+count)
{
iter->second -= count;
}
else
{
mIndex.erase (iter++);
}
}
++iter;
}
}
template<typename ESXRecordT>
void IdCollection<ESXRecordT>::appendBlankRecord (const std::string& id)
{
ESXRecordT record;
record.mId = id;
record.blank();
add (record);
}
template<typename ESXRecordT>
int IdCollection<ESXRecordT>::searchId (const std::string& id) const
{
std::string id2;
std::transform (id.begin(), id.end(), std::back_inserter (id2),
(int(*)(int)) std::tolower);
std::map<std::string, int>::const_iterator iter = mIndex.find (id2);
if (iter==mIndex.end())
return -1;
return iter->second;
}
template<typename ESXRecordT>
void IdCollection<ESXRecordT>::replace (int index, const RecordBase& record)
{
mRecords.at (index) = dynamic_cast<const Record<ESXRecordT>&> (record);
}
template<typename ESXRecordT>
void IdCollection<ESXRecordT>::appendRecord (const RecordBase& record)
{
mRecords.push_back (dynamic_cast<const Record<ESXRecordT>&> (record));
mIndex.insert (std::make_pair (getId (record), mRecords.size()-1));
}
template<typename ESXRecordT>
std::string IdCollection<ESXRecordT>::getId (const RecordBase& record) const
{
const Record<ESXRecordT>& record2 = dynamic_cast<const Record<ESXRecordT>&> (record);
return (record2.isModified() ? record2.mModified : record2.mBase).mId;
}
template<typename ESXRecordT>
const RecordBase& IdCollection<ESXRecordT>::getRecord (const std::string& id) const
{
int index = getIndex (id);
return mRecords.at (index);
}
}
#endif

@ -0,0 +1,137 @@
#include "idtable.hpp"
#include "idcollection.hpp"
CSMWorld::IdTable::IdTable (IdCollectionBase *idCollection) : mIdCollection (idCollection)
{
}
CSMWorld::IdTable::~IdTable()
{
}
int CSMWorld::IdTable::rowCount (const QModelIndex & parent) const
{
if (parent.isValid())
return 0;
return mIdCollection->getSize();
}
int CSMWorld::IdTable::columnCount (const QModelIndex & parent) const
{
if (parent.isValid())
return 0;
return mIdCollection->getColumns();
}
QVariant CSMWorld::IdTable::data (const QModelIndex & index, int role) const
{
if (role!=Qt::DisplayRole && role!=Qt::EditRole)
return QVariant();
if (role==Qt::EditRole && !mIdCollection->getColumn (index.column()).isEditable())
return QVariant();
return mIdCollection->getData (index.row(), index.column());
}
QVariant CSMWorld::IdTable::headerData (int section, Qt::Orientation orientation, int role) const
{
if (orientation==Qt::Vertical)
return QVariant();
if (role==Qt::DisplayRole)
return tr (mIdCollection->getColumn (section).mTitle.c_str());
if (role==ColumnBase::Role_Flags)
return mIdCollection->getColumn (section).mFlags;
return QVariant();
}
bool CSMWorld::IdTable::setData ( const QModelIndex &index, const QVariant &value, int role)
{
if (mIdCollection->getColumn (index.column()).isEditable() && role==Qt::EditRole)
{
mIdCollection->setData (index.row(), index.column(), value);
emit dataChanged (CSMWorld::IdTable::index (index.row(), 0),
CSMWorld::IdTable::index (index.row(), mIdCollection->getColumns()-1));
return true;
}
return false;
}
Qt::ItemFlags CSMWorld::IdTable::flags (const QModelIndex & index) const
{
Qt::ItemFlags flags = Qt::ItemIsSelectable | Qt::ItemIsEnabled;
if (mIdCollection->getColumn (index.column()).isUserEditable())
flags |= Qt::ItemIsEditable;
return flags;
}
bool CSMWorld::IdTable::removeRows (int row, int count, const QModelIndex& parent)
{
if (parent.isValid())
return false;
beginRemoveRows (parent, row, row+count-1);
mIdCollection->removeRows (row, count);
endRemoveRows();
return true;
}
void CSMWorld::IdTable::addRecord (const std::string& id)
{
int index = mIdCollection->getSize();
beginInsertRows (QModelIndex(), index, index);
mIdCollection->appendBlankRecord (id);
endInsertRows();
}
QModelIndex CSMWorld::IdTable::getModelIndex (const std::string& id, int column) const
{
return index (mIdCollection->getIndex (id), column);
}
void CSMWorld::IdTable::setRecord (const RecordBase& record)
{
int index = mIdCollection->searchId (mIdCollection->getId (record));
if (index==-1)
{
int index = mIdCollection->getSize();
beginInsertRows (QModelIndex(), index, index);
mIdCollection->appendRecord (record);
endInsertRows();
}
else
{
mIdCollection->replace (index, record);
emit dataChanged (CSMWorld::IdTable::index (index, 0),
CSMWorld::IdTable::index (index, mIdCollection->getColumns()-1));
}
}
const CSMWorld::RecordBase& CSMWorld::IdTable::getRecord (const std::string& id) const
{
return mIdCollection->getRecord (id);
}

@ -0,0 +1,53 @@
#ifndef CSM_WOLRD_IDTABLE_H
#define CSM_WOLRD_IDTABLE_H
#include <QAbstractTableModel>
namespace CSMWorld
{
class IdCollectionBase;
class RecordBase;
class IdTable : public QAbstractTableModel
{
Q_OBJECT
IdCollectionBase *mIdCollection;
// not implemented
IdTable (const IdTable&);
IdTable& operator= (const IdTable&);
public:
IdTable (IdCollectionBase *idCollection);
///< The ownership of \a idCollection is not transferred.
virtual ~IdTable();
virtual int rowCount (const QModelIndex & parent = QModelIndex()) const;
virtual int columnCount (const QModelIndex & parent = QModelIndex()) const;
virtual QVariant data (const QModelIndex & index, int role = Qt::DisplayRole) const;
virtual QVariant headerData (int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
virtual bool setData ( const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
virtual Qt::ItemFlags flags (const QModelIndex & index) const;
virtual bool removeRows (int row, int count, const QModelIndex& parent = QModelIndex());
void addRecord (const std::string& id);
QModelIndex getModelIndex (const std::string& id, int column) const;
void setRecord (const RecordBase& record);
///< Add record or overwrite existing recrod.
const RecordBase& getRecord (const std::string& id) const;
};
}
#endif

@ -0,0 +1,18 @@
#include "idtableproxymodel.hpp"
#include "idtable.hpp"
CSMWorld::IdTableProxyModel::IdTableProxyModel (QObject *parent)
: QSortFilterProxyModel (parent)
{}
void CSMWorld::IdTableProxyModel::addRecord (const std::string& id)
{
dynamic_cast<IdTable&> (*sourceModel()).addRecord (id);
}
QModelIndex CSMWorld::IdTableProxyModel::getModelIndex (const std::string& id, int column) const
{
return mapFromSource (dynamic_cast<IdTable&> (*sourceModel()).getModelIndex (id, column));
}

@ -0,0 +1,24 @@
#ifndef CSM_WOLRD_IDTABLEPROXYMODEL_H
#define CSM_WOLRD_IDTABLEPROXYMODEL_H
#include <QSortFilterProxyModel>
#include <string>
namespace CSMWorld
{
class IdTableProxyModel : public QSortFilterProxyModel
{
Q_OBJECT
public:
IdTableProxyModel (QObject *parent = 0);
virtual void addRecord (const std::string& id);
virtual QModelIndex getModelIndex (const std::string& id, int column) const;
};
}
#endif

@ -0,0 +1,21 @@
#include "record.hpp"
CSMWorld::RecordBase::~RecordBase() {}
bool CSMWorld::RecordBase::RecordBase::isDeleted() const
{
return mState==State_Deleted || mState==State_Erased;
}
bool CSMWorld::RecordBase::RecordBase::isErased() const
{
return mState==State_Erased;
}
bool CSMWorld::RecordBase::RecordBase::isModified() const
{
return mState==State_Modified || mState==State_ModifiedOnly;
}

@ -0,0 +1,104 @@
#ifndef CSM_WOLRD_RECORD_H
#define CSM_WOLRD_RECORD_H
#include <stdexcept>
namespace CSMWorld
{
struct RecordBase
{
enum State
{
State_BaseOnly = 0, // defined in base only
State_Modified = 1, // exists in base, but has been modified
State_ModifiedOnly = 2, // newly created in modified
State_Deleted = 3, // exists in base, but has been deleted
State_Erased = 4 // does not exist at all (we mostly treat that the same way as deleted)
};
State mState;
virtual ~RecordBase();
virtual RecordBase *clone() const = 0;
bool isDeleted() const;
bool isErased() const;
bool isModified() const;
};
template <typename ESXRecordT>
struct Record : public RecordBase
{
ESXRecordT mBase;
ESXRecordT mModified;
virtual RecordBase *clone() const;
const ESXRecordT& get() const;
///< Throws an exception, if the record is deleted.
const ESXRecordT& getBase() const;
///< Throws an exception, if the record is deleted. Returns modified, if there is no base.
void setModified (const ESXRecordT& modified);
///< Throws an exception, if the record is deleted.
void merge();
///< Merge modified into base.
};
template <typename ESXRecordT>
RecordBase *Record<ESXRecordT>::clone() const
{
return new Record<ESXRecordT> (*this);
}
template <typename ESXRecordT>
const ESXRecordT& Record<ESXRecordT>::get() const
{
if (mState==State_Erased)
throw std::logic_error ("attempt to access a deleted record");
return mState==State_BaseOnly ? mBase : mModified;
}
template <typename ESXRecordT>
const ESXRecordT& Record<ESXRecordT>::getBase() const
{
if (mState==State_Erased)
throw std::logic_error ("attempt to access a deleted record");
return mState==State_ModifiedOnly ? mModified : mBase;
}
template <typename ESXRecordT>
void Record<ESXRecordT>::setModified (const ESXRecordT& modified)
{
if (mState==State_Erased)
throw std::logic_error ("attempt to modify a deleted record");
mModified = modified;
if (mState!=State_ModifiedOnly)
mState = mBase==mModified ? State_BaseOnly : State_Modified;
}
template <typename ESXRecordT>
void Record<ESXRecordT>::merge()
{
if (isModified())
{
mBase = mModified;
mState = State_BaseOnly;
}
else if (mState==State_Deleted)
{
mState = State_Erased;
}
}
}
#endif

@ -0,0 +1,237 @@
#include "universalid.hpp"
#include <ostream>
#include <stdexcept>
#include <sstream>
namespace
{
struct TypeData
{
CSMWorld::UniversalId::Class mClass;
CSMWorld::UniversalId::Type mType;
const char *mName;
};
static const TypeData sNoArg[] =
{
{ CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, "empty" },
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Globals, "Global Variables" },
{ CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, 0 } // end marker
};
static const TypeData sIdArg[] =
{
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Global, "Global Variable" },
{ CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, 0 } // end marker
};
static const TypeData sIndexArg[] =
{
{ CSMWorld::UniversalId::Class_Transient, CSMWorld::UniversalId::Type_VerificationResults, "Verification Results" },
{ CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, 0 } // end marker
};
}
CSMWorld::UniversalId::UniversalId (const std::string& universalId)
{
std::string::size_type index = universalId.find (':');
if (index==std::string::npos)
{
std::string type = universalId.substr (0, index);
if (index==std::string::npos)
{
for (int i=0; sNoArg[i].mName; ++i)
if (type==sNoArg[i].mName)
{
mArgumentType = ArgumentType_None;
mType = sNoArg[i].mType;
mClass = sNoArg[i].mClass;
return;
}
}
else
{
for (int i=0; sIdArg[i].mName; ++i)
if (type==sIdArg[i].mName)
{
mArgumentType = ArgumentType_Id;
mType = sIdArg[i].mType;
mClass = sIdArg[i].mClass;
mId = universalId.substr (0, index);
return;
}
for (int i=0; sIndexArg[i].mName; ++i)
if (type==sIndexArg[i].mName)
{
mArgumentType = ArgumentType_Index;
mType = sIndexArg[i].mType;
mClass = sIndexArg[i].mClass;
std::istringstream stream (universalId.substr (0, index));
if (stream >> mIndex)
return;
break;
}
}
}
throw std::runtime_error ("invalid UniversalId: " + universalId);
}
CSMWorld::UniversalId::UniversalId (Type type) : mArgumentType (ArgumentType_None), mType (type), mIndex (0)
{
for (int i=0; sNoArg[i].mName; ++i)
if (type==sNoArg[i].mType)
{
mClass = sNoArg[i].mClass;
return;
}
throw std::logic_error ("invalid argument-less UniversalId type");
}
CSMWorld::UniversalId::UniversalId (Type type, const std::string& id)
: mArgumentType (ArgumentType_Id), mType (type), mId (id), mIndex (0)
{
for (int i=0; sIdArg[i].mName; ++i)
if (type==sIdArg[i].mType)
{
mClass = sIdArg[i].mClass;
return;
}
throw std::logic_error ("invalid ID argument UniversalId type");
}
CSMWorld::UniversalId::UniversalId (Type type, int index)
: mArgumentType (ArgumentType_Index), mType (type), mIndex (index)
{
for (int i=0; sIndexArg[i].mName; ++i)
if (type==sIndexArg[i].mType)
{
mClass = sIndexArg[i].mClass;
return;
}
throw std::logic_error ("invalid index argument UniversalId type");
}
CSMWorld::UniversalId::Class CSMWorld::UniversalId::getClass() const
{
return mClass;
}
CSMWorld::UniversalId::ArgumentType CSMWorld::UniversalId::getArgumentType() const
{
return mArgumentType;
}
CSMWorld::UniversalId::Type CSMWorld::UniversalId::getType() const
{
return mType;
}
const std::string& CSMWorld::UniversalId::getId() const
{
if (mArgumentType!=ArgumentType_Id)
throw std::logic_error ("invalid access to ID of non-ID UniversalId");
return mId;
}
int CSMWorld::UniversalId::getIndex() const
{
if (mArgumentType!=ArgumentType_Index)
throw std::logic_error ("invalid access to index of non-index UniversalId");
return mIndex;
}
bool CSMWorld::UniversalId::isEqual (const UniversalId& universalId) const
{
if (mClass!=universalId.mClass || mArgumentType!=universalId.mArgumentType || mType!=universalId.mType)
return false;
switch (mArgumentType)
{
case ArgumentType_Id: return mId==universalId.mId;
case ArgumentType_Index: return mIndex==universalId.mIndex;
default: return true;
}
}
bool CSMWorld::UniversalId::isLess (const UniversalId& universalId) const
{
if (mType<universalId.mType)
return true;
if (mType>universalId.mType)
return false;
switch (mArgumentType)
{
case ArgumentType_Id: return mId<universalId.mId;
case ArgumentType_Index: return mIndex<universalId.mIndex;
default: return false;
}
}
std::string CSMWorld::UniversalId::getTypeName() const
{
const TypeData *typeData = mArgumentType==ArgumentType_None ? sNoArg :
(mArgumentType==ArgumentType_Id ? sIdArg : sIndexArg);
for (int i=0; typeData[i].mName; ++i)
if (typeData[i].mType==mType)
return typeData[i].mName;
throw std::logic_error ("failed to retrieve UniversalId type name");
}
std::string CSMWorld::UniversalId::toString() const
{
std::ostringstream stream;
stream << getTypeName();
switch (mArgumentType)
{
case ArgumentType_None: break;
case ArgumentType_Id: stream << ": " << mId; break;
case ArgumentType_Index: stream << ": " << mIndex; break;
}
return stream.str();
}
bool CSMWorld::operator== (const CSMWorld::UniversalId& left, const CSMWorld::UniversalId& right)
{
return left.isEqual (right);
}
bool CSMWorld::operator!= (const CSMWorld::UniversalId& left, const CSMWorld::UniversalId& right)
{
return !left.isEqual (right);
}
bool CSMWorld::operator< (const UniversalId& left, const UniversalId& right)
{
return left.isLess (right);
}
std::ostream& CSMWorld::operator< (std::ostream& stream, const CSMWorld::UniversalId& universalId)
{
return stream << universalId.toString();
}

@ -0,0 +1,96 @@
#ifndef CSM_WOLRD_UNIVERSALID_H
#define CSM_WOLRD_UNIVERSALID_H
#include <string>
#include <iosfwd>
#include <QMetaType>
namespace CSMWorld
{
class UniversalId
{
public:
enum Class
{
Class_None = 0,
Class_Record,
Class_SubRecord,
Class_RecordList,
Class_Collection, // multiple types of records combined
Class_Transient, // not part of the world data or the project data
Class_NonRecord // record like data that is not part of the world
};
enum ArgumentType
{
ArgumentType_None,
ArgumentType_Id,
ArgumentType_Index
};
enum Type
{
Type_None,
Type_Globals,
Type_Global,
Type_VerificationResults
};
private:
Class mClass;
ArgumentType mArgumentType;
Type mType;
std::string mId;
int mIndex;
public:
UniversalId (const std::string& universalId);
UniversalId (Type type = Type_None);
///< Using a type for a non-argument-less UniversalId will throw an exception.
UniversalId (Type type, const std::string& id);
///< Using a type for a non-ID-argument UniversalId will throw an exception.
UniversalId (Type type, int index);
///< Using a type for a non-index-argument UniversalId will throw an exception.
Class getClass() const;
ArgumentType getArgumentType() const;
Type getType() const;
const std::string& getId() const;
///< Calling this function for a non-ID type will throw an exception.
int getIndex() const;
///< Calling this function for a non-index type will throw an exception.
bool isEqual (const UniversalId& universalId) const;
bool isLess (const UniversalId& universalId) const;
std::string getTypeName() const;
std::string toString() const;
};
bool operator== (const UniversalId& left, const UniversalId& right);
bool operator!= (const UniversalId& left, const UniversalId& right);
bool operator< (const UniversalId& left, const UniversalId& right);
std::ostream& operator< (std::ostream& stream, const UniversalId& universalId);
}
Q_DECLARE_METATYPE (CSMWorld::UniversalId)
#endif

@ -0,0 +1,54 @@
#include "operation.hpp"
#include <sstream>
#include "../../model/doc/document.hpp"
void CSVDoc::Operation::updateLabel (int threads)
{
if (threads==-1 || ((threads==0)!=mStalling))
{
std::string name ("unknown operation");
switch (mType)
{
case CSMDoc::State_Saving: name = "saving"; break;
case CSMDoc::State_Verifying: name = "verifying"; break;
}
std::ostringstream stream;
if ((mStalling = (threads<=0)))
{
stream << name << " (waiting for a free worker thread)";
}
else
{
stream << name << " (%p%)";
}
setFormat (stream.str().c_str());
}
}
CSVDoc::Operation::Operation (int type) : mType (type), mStalling (false)
{
/// \todo Add a cancel button or a pop up menu with a cancel item
updateLabel();
/// \todo assign different progress bar colours to allow the user to distinguish easily between operation types
}
void CSVDoc::Operation::setProgress (int current, int max, int threads)
{
updateLabel (threads);
setRange (0, max);
setValue (current);
}
int CSVDoc::Operation::getType() const
{
return mType;
}

@ -0,0 +1,31 @@
#ifndef CSV_DOC_OPERATION_H
#define CSV_DOC_OPERATION_H
#include <QProgressBar>
namespace CSVDoc
{
class Operation : public QProgressBar
{
Q_OBJECT
int mType;
bool mStalling;
// not implemented
Operation (const Operation&);
Operation& operator= (const Operation&);
void updateLabel (int threads = -1);
public:
Operation (int type);
void setProgress (int current, int max, int threads);
int getType() const;
};
}
#endif

@ -0,0 +1,47 @@
#include "operations.hpp"
#include <QVBoxLayout>
#include "operation.hpp"
CSVDoc::Operations::Operations()
{
/// \todo make widget height fixed (exactly the height required to display all operations)
setFeatures (QDockWidget::NoDockWidgetFeatures);
QWidget *widget = new QWidget;
setWidget (widget);
mLayout = new QVBoxLayout;
widget->setLayout (mLayout);
}
void CSVDoc::Operations::setProgress (int current, int max, int type, int threads)
{
for (std::vector<Operation *>::iterator iter (mOperations.begin()); iter!=mOperations.end(); ++iter)
if ((*iter)->getType()==type)
{
(*iter)->setProgress (current, max, threads);
return;
}
Operation *operation = new Operation (type);
mLayout->addWidget (operation);
mOperations.push_back (operation);
operation->setProgress (current, max, threads);
}
void CSVDoc::Operations::quitOperation (int type)
{
for (std::vector<Operation *>::iterator iter (mOperations.begin()); iter!=mOperations.end(); ++iter)
if ((*iter)->getType()==type)
{
delete *iter;
mOperations.erase (iter);
break;
}
}

@ -0,0 +1,37 @@
#ifndef CSV_DOC_OPERATIONS_H
#define CSV_DOC_OPERATIONS_H
#include <vector>
#include <QDockWidget>
class QVBoxLayout;
namespace CSVDoc
{
class Operation;
class Operations : public QDockWidget
{
Q_OBJECT
QVBoxLayout *mLayout;
std::vector<Operation *> mOperations;
// not implemented
Operations (const Operations&);
Operations& operator= (const Operations&);
public:
Operations();
void setProgress (int current, int max, int type, int threads);
///< Implicitly starts the operation, if it is not running already.
void quitOperation (int type);
///< Calling this function for an operation that is not running is a no-op.
};
}
#endif

@ -0,0 +1,18 @@
#include "subview.hpp"
CSVDoc::SubView::SubView (const CSMWorld::UniversalId& id) : mUniversalId (id)
{
/// \todo add a button to the title bar that clones this sub view
setWindowTitle (mUniversalId.toString().c_str());
/// \todo remove (for testing only)
setMinimumWidth (100);
setMinimumHeight (60);
}
CSMWorld::UniversalId CSVDoc::SubView::getUniversalId() const
{
return mUniversalId;
}

@ -0,0 +1,45 @@
#ifndef CSV_DOC_SUBVIEW_H
#define CSV_DOC_SUBVIEW_H
#include "../../model/doc/document.hpp"
#include "../../model/world/universalid.hpp"
#include "subviewfactory.hpp"
#include <QDockWidget>
class QUndoStack;
namespace CSMWorld
{
class Data;
}
namespace CSVDoc
{
class SubView : public QDockWidget
{
Q_OBJECT
CSMWorld::UniversalId mUniversalId;
// not implemented
SubView (const SubView&);
SubView& operator= (SubView&);
public:
SubView (const CSMWorld::UniversalId& id);
CSMWorld::UniversalId getUniversalId() const;
virtual void setEditLock (bool locked) = 0;
signals:
void focusId (const CSMWorld::UniversalId& universalId);
};
}
#endif

@ -0,0 +1,38 @@
#include "subviewfactory.hpp"
#include <cassert>
#include <stdexcept>
CSVDoc::SubViewFactoryBase::SubViewFactoryBase() {}
CSVDoc::SubViewFactoryBase::~SubViewFactoryBase() {}
CSVDoc::SubViewFactoryManager::SubViewFactoryManager() {}
CSVDoc::SubViewFactoryManager::~SubViewFactoryManager()
{
for (std::map<CSMWorld::UniversalId::Type, SubViewFactoryBase *>::iterator iter (mSubViewFactories.begin());
iter!=mSubViewFactories.end(); ++iter)
delete iter->second;
}
void CSVDoc::SubViewFactoryManager::add (const CSMWorld::UniversalId::Type& id, SubViewFactoryBase *factory)
{
assert (mSubViewFactories.find (id)==mSubViewFactories.end());
mSubViewFactories.insert (std::make_pair (id, factory));
}
CSVDoc::SubView *CSVDoc::SubViewFactoryManager::makeSubView (const CSMWorld::UniversalId& id,
CSMDoc::Document& document)
{
std::map<CSMWorld::UniversalId::Type, SubViewFactoryBase *>::iterator iter = mSubViewFactories.find (id.getType());
if (iter==mSubViewFactories.end())
throw std::runtime_error ("Failed to create a sub view for: " + id.toString());
return iter->second->makeSubView (id, document);
}

@ -0,0 +1,55 @@
#ifndef CSV_DOC_SUBVIEWFACTORY_H
#define CSV_DOC_SUBVIEWFACTORY_H
#include <map>
#include "../../model/world/universalid.hpp"
namespace CSMDoc
{
class Document;
}
namespace CSVDoc
{
class SubView;
class SubViewFactoryBase
{
// not implemented
SubViewFactoryBase (const SubViewFactoryBase&);
SubViewFactoryBase& operator= (const SubViewFactoryBase&);
public:
SubViewFactoryBase();
virtual ~SubViewFactoryBase();
virtual SubView *makeSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document) = 0;
///< The ownership of the returned sub view is not transferred.
};
class SubViewFactoryManager
{
std::map<CSMWorld::UniversalId::Type, SubViewFactoryBase *> mSubViewFactories;
// not implemented
SubViewFactoryManager (const SubViewFactoryManager&);
SubViewFactoryManager& operator= (const SubViewFactoryManager&);
public:
SubViewFactoryManager();
~SubViewFactoryManager();
void add (const CSMWorld::UniversalId::Type& id, SubViewFactoryBase *factory);
///< The ownership of \a factory is transferred to this.
SubView *makeSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document);
///< The ownership of the returned sub view is not transferred.
};
}
#endif

@ -0,0 +1,50 @@
#ifndef CSV_DOC_SUBVIEWFACTORYIMP_H
#define CSV_DOC_SUBVIEWFACTORYIMP_H
#include "../../model/doc/document.hpp"
#include "subviewfactory.hpp"
namespace CSVDoc
{
template<class SubViewT>
class SubViewFactory : public SubViewFactoryBase
{
public:
virtual CSVDoc::SubView *makeSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document);
};
template<class SubViewT>
CSVDoc::SubView *SubViewFactory<SubViewT>::makeSubView (const CSMWorld::UniversalId& id,
CSMDoc::Document& document)
{
return new SubViewT (id, document);
}
template<class SubViewT>
class SubViewFactoryWithCreateFlag : public SubViewFactoryBase
{
bool mCreateAndDelete;
public:
SubViewFactoryWithCreateFlag (bool createAndDelete);
virtual CSVDoc::SubView *makeSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document);
};
template<class SubViewT>
SubViewFactoryWithCreateFlag<SubViewT>::SubViewFactoryWithCreateFlag (bool createAndDelete)
: mCreateAndDelete (createAndDelete)
{}
template<class SubViewT>
CSVDoc::SubView *SubViewFactoryWithCreateFlag<SubViewT>::makeSubView (const CSMWorld::UniversalId& id,
CSMDoc::Document& document)
{
return new SubViewT (id, document, mCreateAndDelete);
}
}
#endif

@ -0,0 +1,216 @@
#include "view.hpp"
#include <sstream>
#include <stdexcept>
#include <QCloseEvent>
#include <QMenuBar>
#include <QMdiArea>
#include "../../model/doc/document.hpp"
#include "../world/subviews.hpp"
#include "../tools/subviews.hpp"
#include "viewmanager.hpp"
#include "operations.hpp"
#include "subview.hpp"
void CSVDoc::View::closeEvent (QCloseEvent *event)
{
if (!mViewManager.closeRequest (this))
event->ignore();
}
void CSVDoc::View::setupFileMenu()
{
QMenu *file = menuBar()->addMenu (tr ("&File"));
QAction *new_ = new QAction (tr ("New"), this);
connect (new_, SIGNAL (triggered()), this, SIGNAL (newDocumentRequest()));
file->addAction (new_);
mSave = new QAction (tr ("&Save"), this);
connect (mSave, SIGNAL (triggered()), this, SLOT (save()));
file->addAction (mSave);
}
void CSVDoc::View::setupEditMenu()
{
QMenu *edit = menuBar()->addMenu (tr ("&Edit"));
mUndo = mDocument->getUndoStack().createUndoAction (this, tr("&Undo"));
mUndo->setShortcuts (QKeySequence::Undo);
edit->addAction (mUndo);
mRedo= mDocument->getUndoStack().createRedoAction (this, tr("&Redo"));
mRedo->setShortcuts (QKeySequence::Redo);
edit->addAction (mRedo);
}
void CSVDoc::View::setupViewMenu()
{
QMenu *view = menuBar()->addMenu (tr ("&View"));
QAction *newWindow = new QAction (tr ("&New View"), this);
connect (newWindow, SIGNAL (triggered()), this, SLOT (newView()));
view->addAction (newWindow);
}
void CSVDoc::View::setupWorldMenu()
{
QMenu *world = menuBar()->addMenu (tr ("&World"));
QAction *globals = new QAction (tr ("Globals"), this);
connect (globals, SIGNAL (triggered()), this, SLOT (addGlobalsSubView()));
world->addAction (globals);
mVerify = new QAction (tr ("&Verify"), this);
connect (mVerify, SIGNAL (triggered()), this, SLOT (verify()));
world->addAction (mVerify);
}
void CSVDoc::View::setupUi()
{
setupFileMenu();
setupEditMenu();
setupViewMenu();
setupWorldMenu();
}
void CSVDoc::View::updateTitle()
{
std::ostringstream stream;
stream << mDocument->getName();
if (mDocument->getState() & CSMDoc::State_Modified)
stream << " *";
if (mViewTotal>1)
stream << " [" << (mViewIndex+1) << "/" << mViewTotal << "]";
setWindowTitle (stream.str().c_str());
}
void CSVDoc::View::updateActions()
{
bool editing = !(mDocument->getState() & CSMDoc::State_Locked);
for (std::vector<QAction *>::iterator iter (mEditingActions.begin()); iter!=mEditingActions.end(); ++iter)
(*iter)->setEnabled (editing);
mUndo->setEnabled (editing & mDocument->getUndoStack().canUndo());
mRedo->setEnabled (editing & mDocument->getUndoStack().canRedo());
mSave->setEnabled (!(mDocument->getState() & CSMDoc::State_Saving));
mVerify->setEnabled (!(mDocument->getState() & CSMDoc::State_Verifying));
}
CSVDoc::View::View (ViewManager& viewManager, CSMDoc::Document *document, int totalViews)
: mViewManager (viewManager), mDocument (document), mViewIndex (totalViews-1), mViewTotal (totalViews)
{
setDockOptions (QMainWindow::AllowNestedDocks);
resize (300, 300); /// \todo get default size from settings and set reasonable minimal size
mOperations = new Operations;
addDockWidget (Qt::BottomDockWidgetArea, mOperations);
updateTitle();
setupUi();
CSVWorld::addSubViewFactories (mSubViewFactory);
CSVTools::addSubViewFactories (mSubViewFactory);
}
CSVDoc::View::~View()
{
}
const CSMDoc::Document *CSVDoc::View::getDocument() const
{
return mDocument;
}
CSMDoc::Document *CSVDoc::View::getDocument()
{
return mDocument;
}
void CSVDoc::View::setIndex (int viewIndex, int totalViews)
{
mViewIndex = viewIndex;
mViewTotal = totalViews;
updateTitle();
}
void CSVDoc::View::updateDocumentState()
{
updateTitle();
updateActions();
static const int operations[] =
{
CSMDoc::State_Saving, CSMDoc::State_Verifying,
-1 // end marker
};
int state = mDocument->getState() ;
for (int i=0; operations[i]!=-1; ++i)
if (!(state & operations[i]))
mOperations->quitOperation (operations[i]);
QList<CSVDoc::SubView *> subViews = findChildren<CSVDoc::SubView *>();
for (QList<CSVDoc::SubView *>::iterator iter (subViews.begin()); iter!=subViews.end(); ++iter)
(*iter)->setEditLock (state & CSMDoc::State_Locked);
}
void CSVDoc::View::updateProgress (int current, int max, int type, int threads)
{
mOperations->setProgress (current, max, type, threads);
}
void CSVDoc::View::addSubView (const CSMWorld::UniversalId& id)
{
/// \todo add an user setting for limiting the number of sub views per top level view. Automatically open a new top level view if this
/// number is exceeded
/// \todo if the sub view limit setting is one, the sub view title bar should be hidden and the text in the main title bar adjusted
/// accordingly
/// \todo add an user setting to reuse sub views (on a per document basis or on a per top level view basis)
SubView *view = mSubViewFactory.makeSubView (id, *mDocument);
addDockWidget (Qt::TopDockWidgetArea, view);
connect (view, SIGNAL (focusId (const CSMWorld::UniversalId&)), this,
SLOT (addSubView (const CSMWorld::UniversalId&)));
view->show();
}
void CSVDoc::View::newView()
{
mViewManager.addView (mDocument);
}
void CSVDoc::View::save()
{
mDocument->save();
}
void CSVDoc::View::verify()
{
addSubView (mDocument->verify());
}
void CSVDoc::View::addGlobalsSubView()
{
addSubView (CSMWorld::UniversalId::Type_Globals);
}

@ -0,0 +1,103 @@
#ifndef CSV_DOC_VIEW_H
#define CSV_DOC_VIEW_H
#include <vector>
#include <map>
#include <QMainWindow>
#include "subviewfactory.hpp"
class QAction;
namespace CSMDoc
{
class Document;
}
namespace CSMWorld
{
class UniversalId;
}
namespace CSVDoc
{
class ViewManager;
class Operations;
class View : public QMainWindow
{
Q_OBJECT
ViewManager& mViewManager;
CSMDoc::Document *mDocument;
int mViewIndex;
int mViewTotal;
QAction *mUndo;
QAction *mRedo;
QAction *mSave;
QAction *mVerify;
std::vector<QAction *> mEditingActions;
Operations *mOperations;
SubViewFactoryManager mSubViewFactory;
// not implemented
View (const View&);
View& operator= (const View&);
private:
void closeEvent (QCloseEvent *event);
void setupFileMenu();
void setupEditMenu();
void setupViewMenu();
void setupWorldMenu();
void setupUi();
void updateTitle();
void updateActions();
public:
View (ViewManager& viewManager, CSMDoc::Document *document, int totalViews);
///< The ownership of \a document is not transferred to *this.
virtual ~View();
const CSMDoc::Document *getDocument() const;
CSMDoc::Document *getDocument();
void setIndex (int viewIndex, int totalViews);
void updateDocumentState();
void updateProgress (int current, int max, int type, int threads);
signals:
void newDocumentRequest();
public slots:
void addSubView (const CSMWorld::UniversalId& id);
private slots:
void newView();
void save();
void verify();
void addGlobalsSubView();
};
}
#endif

@ -0,0 +1,112 @@
#include "viewmanager.hpp"
#include <map>
#include "../../model/doc/documentmanager.hpp"
#include "../../model/doc/document.hpp"
#include "view.hpp"
void CSVDoc::ViewManager::updateIndices()
{
std::map<CSMDoc::Document *, std::pair<int, int> > documents;
for (std::vector<View *>::const_iterator iter (mViews.begin()); iter!=mViews.end(); ++iter)
{
std::map<CSMDoc::Document *, std::pair<int, int> >::iterator document = documents.find ((*iter)->getDocument());
if (document==documents.end())
document =
documents.insert (
std::make_pair ((*iter)->getDocument(), std::make_pair (0, countViews ((*iter)->getDocument())))).
first;
(*iter)->setIndex (document->second.first++, document->second.second);
}
}
CSVDoc::ViewManager::ViewManager (CSMDoc::DocumentManager& documentManager)
: mDocumentManager (documentManager)
{
}
CSVDoc::ViewManager::~ViewManager()
{
for (std::vector<View *>::iterator iter (mViews.begin()); iter!=mViews.end(); ++iter)
delete *iter;
}
CSVDoc::View *CSVDoc::ViewManager::addView (CSMDoc::Document *document)
{
if (countViews (document)==0)
{
// new document
connect (document, SIGNAL (stateChanged (int, CSMDoc::Document *)),
this, SLOT (documentStateChanged (int, CSMDoc::Document *)));
connect (document, SIGNAL (progress (int, int, int, int, CSMDoc::Document *)),
this, SLOT (progress (int, int, int, int, CSMDoc::Document *)));
}
View *view = new View (*this, document, countViews (document)+1);
mViews.push_back (view);
view->show();
connect (view, SIGNAL (newDocumentRequest ()), this, SIGNAL (newDocumentRequest()));
updateIndices();
return view;
}
int CSVDoc::ViewManager::countViews (const CSMDoc::Document *document) const
{
int count = 0;
for (std::vector<View *>::const_iterator iter (mViews.begin()); iter!=mViews.end(); ++iter)
if ((*iter)->getDocument()==document)
++count;
return count;
}
bool CSVDoc::ViewManager::closeRequest (View *view)
{
std::vector<View *>::iterator iter = std::find (mViews.begin(), mViews.end(), view);
if (iter!=mViews.end())
{
bool last = countViews (view->getDocument())<=1;
/// \todo check if save is in progress -> warn user about possible data loss
/// \todo check if document has not been saved -> return false and start close dialogue
mViews.erase (iter);
view->deleteLater();
if (last)
mDocumentManager.removeDocument (view->getDocument());
else
updateIndices();
}
return true;
}
void CSVDoc::ViewManager::documentStateChanged (int state, CSMDoc::Document *document)
{
for (std::vector<View *>::const_iterator iter (mViews.begin()); iter!=mViews.end(); ++iter)
if ((*iter)->getDocument()==document)
(*iter)->updateDocumentState();
}
void CSVDoc::ViewManager::progress (int current, int max, int type, int threads, CSMDoc::Document *document)
{
for (std::vector<View *>::const_iterator iter (mViews.begin()); iter!=mViews.end(); ++iter)
if ((*iter)->getDocument()==document)
(*iter)->updateProgress (current, max, type, threads);
}

@ -0,0 +1,58 @@
#ifndef CSV_DOC_VIEWMANAGER_H
#define CSV_DOC_VIEWMANAGER_H
#include <vector>
#include <QObject>
namespace CSMDoc
{
class Document;
class DocumentManager;
}
namespace CSVDoc
{
class View;
class ViewManager : public QObject
{
Q_OBJECT
CSMDoc::DocumentManager& mDocumentManager;
std::vector<View *> mViews;
// not implemented
ViewManager (const ViewManager&);
ViewManager& operator= (const ViewManager&);
void updateIndices();
public:
ViewManager (CSMDoc::DocumentManager& documentManager);
virtual ~ViewManager();
View *addView (CSMDoc::Document *document);
///< The ownership of the returned view is not transferred.
int countViews (const CSMDoc::Document *document) const;
///< Return number of views for \a document.
bool closeRequest (View *view);
signals:
void newDocumentRequest();
private slots:
void documentStateChanged (int state, CSMDoc::Document *document);
void progress (int current, int max, int type, int threads, CSMDoc::Document *document);
};
}
#endif

@ -0,0 +1,32 @@
#include "reportsubview.hpp"
#include <QTableView>
#include <QHeaderView>
#include "../../model/tools/reportmodel.hpp"
CSVTools::ReportSubView::ReportSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document)
: CSVDoc::SubView (id), mModel (document.getReport (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);
connect (mTable, SIGNAL (doubleClicked (const QModelIndex&)), this, SLOT (show (const QModelIndex&)));
}
void CSVTools::ReportSubView::setEditLock (bool locked)
{
// ignored. We don't change document state anyway.
}
void CSVTools::ReportSubView::show (const QModelIndex& index)
{
focusId (mModel->getUniversalId (index.row()));
}

@ -0,0 +1,42 @@
#ifndef CSV_TOOLS_REPORTSUBVIEW_H
#define CSV_TOOLS_REPORTSUBVIEW_H
#include "../doc/subview.hpp"
class QTableView;
class QModelIndex;
namespace CSMDoc
{
class Document;
}
namespace CSMTools
{
class ReportModel;
}
namespace CSVTools
{
class Table;
class ReportSubView : public CSVDoc::SubView
{
Q_OBJECT
CSMTools::ReportModel *mModel;
QTableView *mTable;
public:
ReportSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document);
virtual void setEditLock (bool locked);
private slots:
void show (const QModelIndex& index);
};
}
#endif

@ -0,0 +1,12 @@
#include "subviews.hpp"
#include "../doc/subviewfactoryimp.hpp"
#include "reportsubview.hpp"
void CSVTools::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager)
{
manager.add (CSMWorld::UniversalId::Type_VerificationResults,
new CSVDoc::SubViewFactory<ReportSubView>);
}

@ -0,0 +1,14 @@
#ifndef CSV_TOOLS_SUBVIEWS_H
#define CSV_TOOLS_SUBVIEWS_H
namespace CSVDoc
{
class SubViewFactoryManager;
}
namespace CSVTools
{
void addSubViewFactories (CSVDoc::SubViewFactoryManager& manager);
}
#endif

@ -0,0 +1,14 @@
#include "dialoguesubview.hpp"
CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document,
bool createAndDelete)
: SubView (id)
{
}
void CSVWorld::DialogueSubView::setEditLock (bool locked)
{
}

@ -0,0 +1,24 @@
#ifndef CSV_WORLD_DIALOGUESUBVIEW_H
#define CSV_WORLD_DIALOGUESUBVIEW_H
#include "../doc/subview.hpp"
namespace CSMDoc
{
class Document;
}
namespace CSVWorld
{
class DialogueSubView : public CSVDoc::SubView
{
public:
DialogueSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document, bool createAndDelete);
virtual void setEditLock (bool locked);
};
}
#endif

@ -0,0 +1,16 @@
#include "subviews.hpp"
#include "../doc/subviewfactoryimp.hpp"
#include "tablesubview.hpp"
#include "dialoguesubview.hpp"
void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager)
{
manager.add (CSMWorld::UniversalId::Type_Globals,
new CSVDoc::SubViewFactoryWithCreateFlag<TableSubView> (true));
manager.add (CSMWorld::UniversalId::Type_Global,
new CSVDoc::SubViewFactoryWithCreateFlag<DialogueSubView> (true));
}

@ -0,0 +1,14 @@
#ifndef CSV_WORLD_SUBVIEWS_H
#define CSV_WORLD_SUBVIEWS_H
namespace CSVDoc
{
class SubViewFactoryManager;
}
namespace CSVWorld
{
void addSubViewFactories (CSVDoc::SubViewFactoryManager& manager);
}
#endif

@ -0,0 +1,199 @@
#include "table.hpp"
#include <QHeaderView>
#include <QAction>
#include <QMenu>
#include <QContextMenuEvent>
#include "../../model/world/data.hpp"
#include "../../model/world/commands.hpp"
#include "../../model/world/idtableproxymodel.hpp"
#include "../../model/world/idtable.hpp"
#include "../../model/world/record.hpp"
#include "util.hpp"
void CSVWorld::Table::contextMenuEvent (QContextMenuEvent *event)
{
QModelIndexList selectedRows = selectionModel()->selectedRows();
QMenu menu (this);
/// \todo add menu items for select all and clear selection
if (!mEditLock)
{
if (mCreateAction)
menu.addAction (mCreateAction);
if (listRevertableSelectedIds().size()>0)
menu.addAction (mRevertAction);
if (listDeletableSelectedIds().size()>0)
menu.addAction (mDeleteAction);
}
menu.exec (event->globalPos());
}
std::vector<std::string> CSVWorld::Table::listRevertableSelectedIds() const
{
QModelIndexList selectedRows = selectionModel()->selectedRows();
std::vector<std::string> revertableIds;
for (QModelIndexList::const_iterator iter (selectedRows.begin()); iter!=selectedRows.end(); ++iter)
{
std::string id = mProxyModel->data (*iter).toString().toStdString();
CSMWorld::RecordBase::State state =
static_cast<CSMWorld::RecordBase::State> (mModel->data (mModel->getModelIndex (id, 1)).toInt());
if (state!=CSMWorld::RecordBase::State_BaseOnly)
revertableIds.push_back (id);
}
return revertableIds;
}
std::vector<std::string> CSVWorld::Table::listDeletableSelectedIds() const
{
QModelIndexList selectedRows = selectionModel()->selectedRows();
std::vector<std::string> deletableIds;
for (QModelIndexList::const_iterator iter (selectedRows.begin()); iter!=selectedRows.end(); ++iter)
{
std::string id = mProxyModel->data (*iter).toString().toStdString();
CSMWorld::RecordBase::State state =
static_cast<CSMWorld::RecordBase::State> (mModel->data (mModel->getModelIndex (id, 1)).toInt());
if (state!=CSMWorld::RecordBase::State_Deleted)
deletableIds.push_back (id);
}
return deletableIds;
}
CSVWorld::Table::Table (const CSMWorld::UniversalId& id, CSMWorld::Data& data, QUndoStack& undoStack,
bool createAndDelete)
: mUndoStack (undoStack), mCreateAction (0), mEditLock (false)
{
mModel = &dynamic_cast<CSMWorld::IdTable&> (*data.getTableModel (id));
mProxyModel = new CSMWorld::IdTableProxyModel (this);
mProxyModel->setSourceModel (mModel);
setModel (mProxyModel);
horizontalHeader()->setResizeMode (QHeaderView::Interactive);
verticalHeader()->hide();
setSortingEnabled (true);
setSelectionBehavior (QAbstractItemView::SelectRows);
setSelectionMode (QAbstractItemView::ExtendedSelection);
int columns = mModel->columnCount();
for (int i=0; i<columns; ++i)
{
int flags = mModel->headerData (i, Qt::Horizontal, CSMWorld::ColumnBase::Role_Flags).toInt();
if (flags & CSMWorld::ColumnBase::Flag_Table)
{
CommandDelegate *delegate = new CommandDelegate (undoStack, this);
mDelegates.push_back (delegate);
setItemDelegateForColumn (i, delegate);
}
else
hideColumn (i);
}
/// \todo make initial layout fill the whole width of the table
if (createAndDelete)
{
mCreateAction = new QAction (tr ("Add Record"), this);
connect (mCreateAction, SIGNAL (triggered()), this, SLOT (createRecord()));
addAction (mCreateAction);
}
mRevertAction = new QAction (tr ("Revert Record"), this);
connect (mRevertAction, SIGNAL (triggered()), this, SLOT (revertRecord()));
addAction (mRevertAction);
mDeleteAction = new QAction (tr ("Delete Record"), this);
connect (mDeleteAction, SIGNAL (triggered()), this, SLOT (deleteRecord()));
addAction (mDeleteAction);
}
void CSVWorld::Table::setEditLock (bool locked)
{
for (std::vector<CommandDelegate *>::iterator iter (mDelegates.begin()); iter!=mDelegates.end(); ++iter)
(*iter)->setEditLock (locked);
mEditLock = locked;
}
CSMWorld::UniversalId CSVWorld::Table::getUniversalId (int row) const
{
return CSMWorld::UniversalId (
static_cast<CSMWorld::UniversalId::Type> (mProxyModel->data (mProxyModel->index (row, 2)).toInt()),
mProxyModel->data (mProxyModel->index (row, 0)).toString().toStdString());
}
#include <sstream> /// \todo remove
void CSVWorld::Table::createRecord()
{
if (!mEditLock)
{
/// \todo ask the user for an ID instead.
static int index = 0;
std::ostringstream stream;
stream << "id" << index++;
mUndoStack.push (new CSMWorld::CreateCommand (*mProxyModel, stream.str()));
}
}
void CSVWorld::Table::revertRecord()
{
if (!mEditLock)
{
std::vector<std::string> revertableIds = listRevertableSelectedIds();
if (revertableIds.size()>0)
{
if (revertableIds.size()>1)
mUndoStack.beginMacro (tr ("Revert multiple records"));
for (std::vector<std::string>::const_iterator iter (revertableIds.begin()); iter!=revertableIds.end(); ++iter)
mUndoStack.push (new CSMWorld::RevertCommand (*mModel, *iter));
if (revertableIds.size()>1)
mUndoStack.endMacro();
}
}
}
void CSVWorld::Table::deleteRecord()
{
if (!mEditLock)
{
std::vector<std::string> deletableIds = listDeletableSelectedIds();
if (deletableIds.size()>0)
{
if (deletableIds.size()>1)
mUndoStack.beginMacro (tr ("Delete multiple records"));
for (std::vector<std::string>::const_iterator iter (deletableIds.begin()); iter!=deletableIds.end(); ++iter)
mUndoStack.push (new CSMWorld::DeleteCommand (*mModel, *iter));
if (deletableIds.size()>1)
mUndoStack.endMacro();
}
}
}

@ -0,0 +1,65 @@
#ifndef CSV_WORLD_TABLE_H
#define CSV_WORLD_TABLE_H
#include <vector>
#include <string>
#include <QTableView>
class QUndoStack;
class QAction;
namespace CSMWorld
{
class Data;
class UniversalId;
class IdTableProxyModel;
class IdTable;
}
namespace CSVWorld
{
class CommandDelegate;
///< Table widget
class Table : public QTableView
{
Q_OBJECT
std::vector<CommandDelegate *> mDelegates;
QUndoStack& mUndoStack;
QAction *mCreateAction;
QAction *mRevertAction;
QAction *mDeleteAction;
CSMWorld::IdTableProxyModel *mProxyModel;
CSMWorld::IdTable *mModel;
bool mEditLock;
private:
void contextMenuEvent (QContextMenuEvent *event);
std::vector<std::string> listRevertableSelectedIds() const;
std::vector<std::string> listDeletableSelectedIds() const;
public:
Table (const CSMWorld::UniversalId& id, CSMWorld::Data& data, QUndoStack& undoStack, bool createAndDelete);
///< \param createAndDelete Allow creation and deletion of records.
void setEditLock (bool locked);
CSMWorld::UniversalId getUniversalId (int row) const;
private slots:
void createRecord();
void revertRecord();
void deleteRecord();
};
}
#endif

@ -0,0 +1,25 @@
#include "tablesubview.hpp"
#include "../../model/doc/document.hpp"
#include "table.hpp"
CSVWorld::TableSubView::TableSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document,
bool createAndDelete)
: SubView (id)
{
setWidget (mTable = new Table (id, document.getData(), document.getUndoStack(), createAndDelete));
connect (mTable, SIGNAL (doubleClicked (const QModelIndex&)), this, SLOT (rowActivated (const QModelIndex&)));
}
void CSVWorld::TableSubView::setEditLock (bool locked)
{
mTable->setEditLock (locked);
}
void CSVWorld::TableSubView::rowActivated (const QModelIndex& index)
{
focusId (mTable->getUniversalId (index.row()));
}

@ -0,0 +1,35 @@
#ifndef CSV_WORLD_TABLESUBVIEW_H
#define CSV_WORLD_TABLESUBVIEW_H
#include "../doc/subview.hpp"
class QModelIndex;
namespace CSMDoc
{
class Document;
}
namespace CSVWorld
{
class Table;
class TableSubView : public CSVDoc::SubView
{
Q_OBJECT
Table *mTable;
public:
TableSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document, bool createAndDelete);
virtual void setEditLock (bool locked);
private slots:
void rowActivated (const QModelIndex& index);
};
}
#endif

@ -0,0 +1,57 @@
#include "util.hpp"
#include <QUndoStack>
#include "../../model/world/commands.hpp"
CSVWorld::NastyTableModelHack::NastyTableModelHack (QAbstractItemModel& model)
: mModel (model)
{}
int CSVWorld::NastyTableModelHack::rowCount (const QModelIndex & parent) const
{
return mModel.rowCount (parent);
}
int CSVWorld::NastyTableModelHack::columnCount (const QModelIndex & parent) const
{
return mModel.columnCount (parent);
}
QVariant CSVWorld::NastyTableModelHack::data (const QModelIndex & index, int role) const
{
return mModel.data (index, role);
}
bool CSVWorld::NastyTableModelHack::setData ( const QModelIndex &index, const QVariant &value, int role)
{
mData = value;
return true;
}
QVariant CSVWorld::NastyTableModelHack::getData() const
{
return mData;
}
CSVWorld::CommandDelegate::CommandDelegate (QUndoStack& undoStack, QObject *parent)
: QStyledItemDelegate (parent), mUndoStack (undoStack), mEditLock (false)
{}
void CSVWorld::CommandDelegate::setModelData (QWidget *editor, QAbstractItemModel *model,
const QModelIndex& index) const
{
if (!mEditLock)
{
NastyTableModelHack hack (*model);
QStyledItemDelegate::setModelData (editor, &hack, index);
mUndoStack.push (new CSMWorld::ModifyCommand (*model, index, hack.getData()));
}
///< \todo provide some kind of feedback to the user, indicating that editing is currently not possible.
}
void CSVWorld::CommandDelegate::setEditLock (bool locked)
{
mEditLock = locked;
}

@ -0,0 +1,50 @@
#ifndef CSV_WORLD_UTIL_H
#define CSV_WORLD_UTIL_H
#include <QAbstractTableModel>
#include <QStyledItemDelegate>
class QUndoStack;
namespace CSVWorld
{
///< \brief Getting the data out of an editor widget
///
/// Really, Qt? Really?
class NastyTableModelHack : public QAbstractTableModel
{
QAbstractItemModel& mModel;
QVariant mData;
public:
NastyTableModelHack (QAbstractItemModel& model);
int rowCount (const QModelIndex & parent = QModelIndex()) const;
int columnCount (const QModelIndex & parent = QModelIndex()) const;
QVariant data (const QModelIndex & index, int role = Qt::DisplayRole) const;
bool setData (const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
QVariant getData() const;
};
///< \brief Use commands instead of manipulating the model directly
class CommandDelegate : public QStyledItemDelegate
{
QUndoStack& mUndoStack;
bool mEditLock;
public:
CommandDelegate (QUndoStack& undoStack, QObject *parent);
void setModelData (QWidget *editor, QAbstractItemModel *model, const QModelIndex& index) const;
void setEditLock (bool locked);
};
}
#endif

@ -34,7 +34,7 @@ add_openmw_dir (mwgui
) )
add_openmw_dir (mwdialogue add_openmw_dir (mwdialogue
dialoguemanagerimp journalimp journalentry quest topic dialoguemanagerimp journalimp journalentry quest topic filter selectwrapper
) )
add_openmw_dir (mwscript add_openmw_dir (mwscript
@ -53,6 +53,7 @@ add_openmw_dir (mwworld
containerstore actiontalk actiontake manualref player cellfunctors failedaction containerstore actiontalk actiontake manualref player cellfunctors failedaction
cells localscripts customdata weather inventorystore ptr actionopen actionread cells localscripts customdata weather inventorystore ptr actionopen actionread
actionequip timestamp actionalchemy cellstore actionapply actioneat actionequip timestamp actionalchemy cellstore actionapply actioneat
esmstore store recordcmp
) )
add_openmw_dir (mwclass add_openmw_dir (mwclass
@ -62,7 +63,7 @@ add_openmw_dir (mwclass
add_openmw_dir (mwmechanics add_openmw_dir (mwmechanics
mechanicsmanagerimp stat creaturestats magiceffects movement actors drawstate spells mechanicsmanagerimp stat creaturestats magiceffects movement actors drawstate spells
activespells npcstats aipackage aisequence alchemy activespells npcstats aipackage aisequence alchemy aiwander aitravel aifollow aiescort aiactivate
) )
add_openmw_dir (mwbase add_openmw_dir (mwbase

@ -8,6 +8,7 @@
#include <components/bsa/bsa_archive.hpp> #include <components/bsa/bsa_archive.hpp>
#include <components/files/configurationmanager.hpp> #include <components/files/configurationmanager.hpp>
#include <components/translation/translation.hpp>
#include <components/nifoverrides/nifoverrides.hpp> #include <components/nifoverrides/nifoverrides.hpp>
#include <components/nifbullet/bullet_nif_loader.hpp> #include <components/nifbullet/bullet_nif_loader.hpp>
@ -20,6 +21,7 @@
#include "mwscript/scriptmanagerimp.hpp" #include "mwscript/scriptmanagerimp.hpp"
#include "mwscript/extensions.hpp" #include "mwscript/extensions.hpp"
#include "mwscript/interpretercontext.hpp"
#include "mwsound/soundmanagerimp.hpp" #include "mwsound/soundmanagerimp.hpp"
@ -101,7 +103,7 @@ bool OMW::Engine::frameRenderingQueued (const Ogre::FrameEvent& evt)
MWBase::Environment::get().getWorld()->doPhysics (movement, mEnvironment.getFrameDuration()); MWBase::Environment::get().getWorld()->doPhysics (movement, mEnvironment.getFrameDuration());
// update world // update world
MWBase::Environment::get().getWorld()->update (evt.timeSinceLastFrame); MWBase::Environment::get().getWorld()->update (evt.timeSinceLastFrame, MWBase::Environment::get().getWindowManager()->isGuiMode());
// update GUI // update GUI
Ogre::RenderWindow* window = mOgre->getWindow(); Ogre::RenderWindow* window = mOgre->getWindow();
@ -333,12 +335,15 @@ void OMW::Engine::go()
mEnvironment.setWorld (new MWWorld::World (*mOgre, mFileCollections, mMaster, mEnvironment.setWorld (new MWWorld::World (*mOgre, mFileCollections, mMaster,
mResDir, mCfgMgr.getCachePath(), mNewGame, mEncoding, mFallbackMap)); mResDir, mCfgMgr.getCachePath(), mNewGame, mEncoding, mFallbackMap));
//Load translation data
mTranslationDataStorage.loadTranslationData(mFileCollections, mMaster);
// Create window manager - this manages all the MW-specific GUI windows // Create window manager - this manages all the MW-specific GUI windows
MWScript::registerExtensions (mExtensions); MWScript::registerExtensions (mExtensions);
mEnvironment.setWindowManager (new MWGui::WindowManager( mEnvironment.setWindowManager (new MWGui::WindowManager(
mExtensions, mFpsLevel, mNewGame, mOgre, mCfgMgr.getLogPath().string() + std::string("/"), mExtensions, mFpsLevel, mNewGame, mOgre, mCfgMgr.getLogPath().string() + std::string("/"),
mCfgMgr.getCachePath ().string(), mScriptConsoleMode)); mCfgMgr.getCachePath ().string(), mScriptConsoleMode, mTranslationDataStorage));
// Create sound system // Create sound system
mEnvironment.setSoundManager (new MWSound::SoundManager(mUseSound)); mEnvironment.setSoundManager (new MWSound::SoundManager(mUseSound));
@ -355,7 +360,7 @@ void OMW::Engine::go()
// Create dialog system // Create dialog system
mEnvironment.setJournal (new MWDialogue::Journal); mEnvironment.setJournal (new MWDialogue::Journal);
mEnvironment.setDialogueManager (new MWDialogue::DialogueManager (mExtensions)); mEnvironment.setDialogueManager (new MWDialogue::DialogueManager (mExtensions, mVerboseScripts));
// Sets up the input system // Sets up the input system
mEnvironment.setInputManager (new MWInput::InputManager (*mOgre, mEnvironment.setInputManager (new MWInput::InputManager (*mOgre,
@ -486,9 +491,10 @@ void OMW::Engine::showFPS(int level)
mFpsLevel = level; mFpsLevel = level;
} }
void OMW::Engine::setEncoding(const std::string& encoding) void OMW::Engine::setEncoding(const ToUTF8::FromType& encoding)
{ {
mEncoding = encoding; mEncoding = encoding;
mTranslationDataStorage.setEncoding (encoding);
} }
void OMW::Engine::setFallbackValues(std::map<std::string,std::string> fallbackMap) void OMW::Engine::setFallbackValues(std::map<std::string,std::string> fallbackMap)

@ -5,6 +5,7 @@
#include <components/compiler/extensions.hpp> #include <components/compiler/extensions.hpp>
#include <components/files/collections.hpp> #include <components/files/collections.hpp>
#include <components/translation/translation.hpp>
#include "mwbase/environment.hpp" #include "mwbase/environment.hpp"
@ -59,7 +60,7 @@ namespace OMW
class Engine : private Ogre::FrameListener class Engine : private Ogre::FrameListener
{ {
MWBase::Environment mEnvironment; MWBase::Environment mEnvironment;
std::string mEncoding; ToUTF8::FromType mEncoding;
Files::PathContainer mDataDirs; Files::PathContainer mDataDirs;
boost::filesystem::path mResDir; boost::filesystem::path mResDir;
OEngine::Render::OgreRenderer *mOgre; OEngine::Render::OgreRenderer *mOgre;
@ -79,9 +80,9 @@ namespace OMW
Compiler::Extensions mExtensions; Compiler::Extensions mExtensions;
Compiler::Context *mScriptContext; Compiler::Context *mScriptContext;
Files::Collections mFileCollections; Files::Collections mFileCollections;
bool mFSStrict; bool mFSStrict;
Translation::Storage mTranslationDataStorage;
// not implemented // not implemented
Engine (const Engine&); Engine (const Engine&);
@ -154,7 +155,7 @@ namespace OMW
void setCompileAll (bool all); void setCompileAll (bool all);
/// Font encoding /// Font encoding
void setEncoding(const std::string& encoding); void setEncoding(const ToUTF8::FromType& encoding);
void setAnimationVerbose(bool animverbose); void setAnimationVerbose(bool animverbose);

@ -131,9 +131,7 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat
->default_value(false), "enable console-only script functionality") ->default_value(false), "enable console-only script functionality")
("script-run", bpo::value<std::string>()->default_value(""), ("script-run", bpo::value<std::string>()->default_value(""),
"select a file that is executed in the console on startup\n\n" "select a file containing a list of console commands that is executed on startup")
"Note: The file contains a list of script lines, but not a complete scripts. "
"That means no begin/end and no variable declarations.")
("new-game", bpo::value<bool>()->implicit_value(true) ("new-game", bpo::value<bool>()->implicit_value(true)
->default_value(false), "activate char gen/new game mechanics") ->default_value(false), "activate char gen/new game mechanics")
@ -183,21 +181,8 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat
// Font encoding settings // Font encoding settings
std::string encoding(variables["encoding"].as<std::string>()); std::string encoding(variables["encoding"].as<std::string>());
if (encoding == "win1250") std::cout << ToUTF8::encodingUsingMessage(encoding) << std::endl;
{ engine.setEncoding(ToUTF8::calculateEncoding(encoding));
std::cout << "Using Central and Eastern European font encoding." << std::endl;
engine.setEncoding(encoding);
}
else if (encoding == "win1251")
{
std::cout << "Using Cyrillic font encoding." << std::endl;
engine.setEncoding(encoding);
}
else
{
std::cout << "Using default (English) font encoding." << std::endl;
engine.setEncoding("win1252");
}
// directory settings // directory settings
engine.enableFSStrict(variables["fs-strict"].as<bool>()); engine.enableFSStrict(variables["fs-strict"].as<bool>());

@ -33,13 +33,17 @@ namespace MWBase
virtual void goodbye() = 0; virtual void goodbye() = 0;
///get the faction of the actor you are talking with virtual MWWorld::Ptr getActor() const = 0;
virtual std::string getFaction() const = 0; ///< Return the actor the player is currently talking to.
//calbacks for the GUI //calbacks for the GUI
virtual void keywordSelected (const std::string& keyword) = 0; virtual void keywordSelected (const std::string& keyword) = 0;
virtual void goodbyeSelected() = 0; virtual void goodbyeSelected() = 0;
virtual void questionAnswered (const std::string& answer) = 0; virtual void questionAnswered (const std::string& answer) = 0;
virtual void persuade (int type) = 0;
virtual int getTemporaryDispositionChange () const = 0;
virtual void applyTemporaryDispositionChange (int delta) = 0;
}; };
} }

@ -62,7 +62,7 @@ namespace MWBase
virtual void setPlayerName (const std::string& name) = 0; virtual void setPlayerName (const std::string& name) = 0;
///< Set player name. ///< Set player name.
virtual void setPlayerRace (const std::string& id, bool male) = 0; virtual void setPlayerRace (const std::string& id, bool male, const std::string &head, const std::string &hair) = 0;
///< Set player race. ///< Set player race.
virtual void setPlayerBirthsign (const std::string& id) = 0; virtual void setPlayerBirthsign (const std::string& id) = 0;
@ -77,8 +77,27 @@ namespace MWBase
virtual void restoreDynamicStats() = 0; virtual void restoreDynamicStats() = 0;
///< If the player is sleeping, this should be called every hour. ///< If the player is sleeping, this should be called every hour.
virtual int getBarterOffer(const MWWorld::Ptr& ptr,int basePrice, bool buying) = 0;
///< This is used by every service to determine the price of objects given the trading skills of the player and NPC.
virtual int getDerivedDisposition(const MWWorld::Ptr& ptr) = 0;
///< Calculate the diposition of an NPC toward the player.
virtual int countDeaths (const std::string& id) const = 0; virtual int countDeaths (const std::string& id) const = 0;
///< Return the number of deaths for actors with the given ID. ///< Return the number of deaths for actors with the given ID.
enum PersuasionType
{
PT_Admire,
PT_Intimidate,
PT_Taunt,
PT_Bribe10,
PT_Bribe100,
PT_Bribe1000
};
virtual void getPersuasionDispositionChange (const MWWorld::Ptr& npc, PersuasionType type,
float currentTemporaryDispositionDelta, bool& success, float& tempChange, float& permChange) = 0;
///< Perform a persuasion action on NPC
}; };
} }

@ -29,11 +29,7 @@ namespace ESM
struct Class; struct Class;
struct Potion; struct Potion;
struct Spell; struct Spell;
} struct NPC;
namespace ESMS
{
struct ESMStore;
} }
namespace MWRender namespace MWRender
@ -48,6 +44,7 @@ namespace MWWorld
class LocalScripts; class LocalScripts;
class Ptr; class Ptr;
class TimeStamp; class TimeStamp;
class ESMStore;
} }
namespace MWBase namespace MWBase
@ -68,7 +65,8 @@ namespace MWBase
Render_CollisionDebug, Render_CollisionDebug,
Render_Wireframe, Render_Wireframe,
Render_Pathgrid, Render_Pathgrid,
Render_Compositors Render_Compositors,
Render_BoundingBoxes
}; };
struct DoorMarker struct DoorMarker
@ -104,7 +102,7 @@ namespace MWBase
virtual MWWorld::Player& getPlayer() = 0; virtual MWWorld::Player& getPlayer() = 0;
virtual const ESMS::ESMStore& getStore() const = 0; virtual const MWWorld::ESMStore& getStore() const = 0;
virtual ESM::ESMReader& getEsmReader() = 0; virtual ESM::ESMReader& getEsmReader() = 0;
@ -136,6 +134,10 @@ namespace MWBase
virtual char getGlobalVariableType (const std::string& name) const = 0; virtual char getGlobalVariableType (const std::string& name) const = 0;
///< Return ' ', if there is no global variable with this name. ///< Return ' ', if there is no global variable with this name.
virtual std::vector<std::string> getGlobals () const = 0;
virtual std::string getCurrentCellName() const = 0;
virtual MWWorld::Ptr getPtr (const std::string& name, bool activeOnly) = 0; virtual MWWorld::Ptr getPtr (const std::string& name, bool activeOnly) = 0;
///< Return a pointer to a liveCellRef with the given name. ///< Return a pointer to a liveCellRef with the given name.
/// \param activeOnly do non search inactive cells. /// \param activeOnly do non search inactive cells.
@ -234,24 +236,28 @@ namespace MWBase
///< Toggle a render mode. ///< Toggle a render mode.
///< \return Resulting mode ///< \return Resulting mode
virtual std::pair<std::string, const ESM::Potion *> createRecord (const ESM::Potion& record) virtual const ESM::Potion *createRecord (const ESM::Potion& record)
= 0; = 0;
///< Create a new recrod (of type potion) in the ESM store. ///< Create a new recrod (of type potion) in the ESM store.
/// \return ID, pointer to created record /// \return pointer to created record
virtual std::pair<std::string, const ESM::Spell *> createRecord (const ESM::Spell& record) virtual const ESM::Spell *createRecord (const ESM::Spell& record)
= 0; = 0;
///< Create a new recrod (of type spell) in the ESM store. ///< Create a new recrod (of type spell) in the ESM store.
/// \return ID, pointer to created record /// \return pointer to created record
virtual std::pair<std::string, const ESM::Class *> createRecord (const ESM::Class& record) virtual const ESM::Class *createRecord (const ESM::Class& record)
= 0; = 0;
///< Create a new recrod (of type class) in the ESM store. ///< Create a new recrod (of type class) in the ESM store.
/// \return ID, pointer to created record /// \return pointer to created record
virtual const ESM::Cell *createRecord (const ESM::Cell& record) = 0; virtual const ESM::Cell *createRecord (const ESM::Cell& record) = 0;
///< Create a new recrod (of type cell) in the ESM store. ///< Create a new recrod (of type cell) in the ESM store.
/// \return ID, pointer to created record /// \return pointer to created record
virtual const ESM::NPC *createRecord(const ESM::NPC &record) = 0;
///< Create a new recrod (of type npc) in the ESM store.
/// \return pointer to created record
virtual void playAnimationGroup (const MWWorld::Ptr& ptr, const std::string& groupName, virtual void playAnimationGroup (const MWWorld::Ptr& ptr, const std::string& groupName,
int mode, int number = 1) = 0; int mode, int number = 1) = 0;
@ -265,7 +271,7 @@ namespace MWBase
///< Skip the animation for the given MW-reference for one frame. Calls to this function for ///< Skip the animation for the given MW-reference for one frame. Calls to this function for
/// references that are currently not in the rendered scene should be ignored. /// references that are currently not in the rendered scene should be ignored.
virtual void update (float duration) = 0; virtual void update (float duration, bool paused) = 0;
virtual bool placeObject(const MWWorld::Ptr& object, float cursorX, float cursorY) = 0; virtual bool placeObject(const MWWorld::Ptr& object, float cursorX, float cursorY) = 0;
///< place an object into the gameworld at the specified cursor position ///< place an object into the gameworld at the specified cursor position

@ -30,18 +30,17 @@ namespace MWClass
void Activator::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const void Activator::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
{ {
const std::string model = getModel(ptr); const std::string model = getModel(ptr);
if(!model.empty()) { if(!model.empty())
physics.insertObjectPhysics(ptr, model); physics.addObject(ptr);
}
} }
std::string Activator::getModel(const MWWorld::Ptr &ptr) const std::string Activator::getModel(const MWWorld::Ptr &ptr) const
{ {
MWWorld::LiveCellRef<ESM::Activator> *ref = MWWorld::LiveCellRef<ESM::Activator> *ref =
ptr.get<ESM::Activator>(); ptr.get<ESM::Activator>();
assert(ref->base != NULL); assert(ref->mBase != NULL);
const std::string &model = ref->base->mModel; const std::string &model = ref->mBase->mModel;
if (!model.empty()) { if (!model.empty()) {
return "meshes\\" + model; return "meshes\\" + model;
} }
@ -53,7 +52,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Activator> *ref = MWWorld::LiveCellRef<ESM::Activator> *ref =
ptr.get<ESM::Activator>(); ptr.get<ESM::Activator>();
return ref->base->mName; return ref->mBase->mName;
} }
std::string Activator::getScript (const MWWorld::Ptr& ptr) const std::string Activator::getScript (const MWWorld::Ptr& ptr) const
@ -61,7 +60,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Activator> *ref = MWWorld::LiveCellRef<ESM::Activator> *ref =
ptr.get<ESM::Activator>(); ptr.get<ESM::Activator>();
return ref->base->mScript; return ref->mBase->mScript;
} }
void Activator::registerSelf() void Activator::registerSelf()
@ -76,7 +75,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Activator> *ref = MWWorld::LiveCellRef<ESM::Activator> *ref =
ptr.get<ESM::Activator>(); ptr.get<ESM::Activator>();
return (ref->base->mName != ""); return (ref->mBase->mName != "");
} }
MWGui::ToolTipInfo Activator::getToolTipInfo (const MWWorld::Ptr& ptr) const MWGui::ToolTipInfo Activator::getToolTipInfo (const MWWorld::Ptr& ptr) const
@ -85,11 +84,11 @@ namespace MWClass
ptr.get<ESM::Activator>(); ptr.get<ESM::Activator>();
MWGui::ToolTipInfo info; MWGui::ToolTipInfo info;
info.caption = ref->base->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount()); info.caption = ref->mBase->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
std::string text; std::string text;
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) if (MWBase::Environment::get().getWindowManager()->getFullHelp())
text += MWGui::ToolTips::getMiscString(ref->base->mScript, "Script"); text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
info.text = text; info.text = text;
return info; return info;
@ -101,6 +100,6 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Activator> *ref = MWWorld::LiveCellRef<ESM::Activator> *ref =
ptr.get<ESM::Activator>(); ptr.get<ESM::Activator>();
return MWWorld::Ptr(&cell.activators.insert(*ref), &cell); return MWWorld::Ptr(&cell.mActivators.insert(*ref), &cell);
} }
} }

@ -33,18 +33,17 @@ namespace MWClass
void Apparatus::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const void Apparatus::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
{ {
const std::string model = getModel(ptr); const std::string model = getModel(ptr);
if(!model.empty()) { if(!model.empty())
physics.insertObjectPhysics(ptr, model); physics.addObject(ptr);
}
} }
std::string Apparatus::getModel(const MWWorld::Ptr &ptr) const std::string Apparatus::getModel(const MWWorld::Ptr &ptr) const
{ {
MWWorld::LiveCellRef<ESM::Apparatus> *ref = MWWorld::LiveCellRef<ESM::Apparatus> *ref =
ptr.get<ESM::Apparatus>(); ptr.get<ESM::Apparatus>();
assert(ref->base != NULL); assert(ref->mBase != NULL);
const std::string &model = ref->base->mModel; const std::string &model = ref->mBase->mModel;
if (!model.empty()) { if (!model.empty()) {
return "meshes\\" + model; return "meshes\\" + model;
} }
@ -56,7 +55,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Apparatus> *ref = MWWorld::LiveCellRef<ESM::Apparatus> *ref =
ptr.get<ESM::Apparatus>(); ptr.get<ESM::Apparatus>();
return ref->base->mName; return ref->mBase->mName;
} }
boost::shared_ptr<MWWorld::Action> Apparatus::activate (const MWWorld::Ptr& ptr, boost::shared_ptr<MWWorld::Action> Apparatus::activate (const MWWorld::Ptr& ptr,
@ -75,7 +74,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Apparatus> *ref = MWWorld::LiveCellRef<ESM::Apparatus> *ref =
ptr.get<ESM::Apparatus>(); ptr.get<ESM::Apparatus>();
return ref->base->mScript; return ref->mBase->mScript;
} }
int Apparatus::getValue (const MWWorld::Ptr& ptr) const int Apparatus::getValue (const MWWorld::Ptr& ptr) const
@ -83,7 +82,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Apparatus> *ref = MWWorld::LiveCellRef<ESM::Apparatus> *ref =
ptr.get<ESM::Apparatus>(); ptr.get<ESM::Apparatus>();
return ref->base->mData.mValue; return ref->mBase->mData.mValue;
} }
void Apparatus::registerSelf() void Apparatus::registerSelf()
@ -108,7 +107,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Apparatus> *ref = MWWorld::LiveCellRef<ESM::Apparatus> *ref =
ptr.get<ESM::Apparatus>(); ptr.get<ESM::Apparatus>();
return ref->base->mIcon; return ref->mBase->mIcon;
} }
bool Apparatus::hasToolTip (const MWWorld::Ptr& ptr) const bool Apparatus::hasToolTip (const MWWorld::Ptr& ptr) const
@ -116,7 +115,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Apparatus> *ref = MWWorld::LiveCellRef<ESM::Apparatus> *ref =
ptr.get<ESM::Apparatus>(); ptr.get<ESM::Apparatus>();
return (ref->base->mName != ""); return (ref->mBase->mName != "");
} }
MWGui::ToolTipInfo Apparatus::getToolTipInfo (const MWWorld::Ptr& ptr) const MWGui::ToolTipInfo Apparatus::getToolTipInfo (const MWWorld::Ptr& ptr) const
@ -125,17 +124,17 @@ namespace MWClass
ptr.get<ESM::Apparatus>(); ptr.get<ESM::Apparatus>();
MWGui::ToolTipInfo info; MWGui::ToolTipInfo info;
info.caption = ref->base->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount()); info.caption = ref->mBase->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
info.icon = ref->base->mIcon; info.icon = ref->mBase->mIcon;
std::string text; std::string text;
text += "\n#{sQuality}: " + MWGui::ToolTips::toString(ref->base->mData.mQuality); text += "\n#{sQuality}: " + MWGui::ToolTips::toString(ref->mBase->mData.mQuality);
text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->base->mData.mWeight); text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight);
text += MWGui::ToolTips::getValueString(ref->base->mData.mValue, "#{sValue}"); text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}");
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
text += MWGui::ToolTips::getMiscString(ref->ref.mOwner, "Owner"); text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner");
text += MWGui::ToolTips::getMiscString(ref->base->mScript, "Script"); text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
} }
info.text = text; info.text = text;
@ -154,6 +153,6 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Apparatus> *ref = MWWorld::LiveCellRef<ESM::Apparatus> *ref =
ptr.get<ESM::Apparatus>(); ptr.get<ESM::Apparatus>();
return MWWorld::Ptr(&cell.appas.insert(*ref), &cell); return MWWorld::Ptr(&cell.mAppas.insert(*ref), &cell);
} }
} }

@ -36,18 +36,17 @@ namespace MWClass
void Armor::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const void Armor::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
{ {
const std::string model = getModel(ptr); const std::string model = getModel(ptr);
if(!model.empty()) { if(!model.empty())
physics.insertObjectPhysics(ptr, model); physics.addObject(ptr);
}
} }
std::string Armor::getModel(const MWWorld::Ptr &ptr) const std::string Armor::getModel(const MWWorld::Ptr &ptr) const
{ {
MWWorld::LiveCellRef<ESM::Armor> *ref = MWWorld::LiveCellRef<ESM::Armor> *ref =
ptr.get<ESM::Armor>(); ptr.get<ESM::Armor>();
assert(ref->base != NULL); assert(ref->mBase != NULL);
const std::string &model = ref->base->mModel; const std::string &model = ref->mBase->mModel;
if (!model.empty()) { if (!model.empty()) {
return "meshes\\" + model; return "meshes\\" + model;
} }
@ -59,7 +58,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Armor> *ref = MWWorld::LiveCellRef<ESM::Armor> *ref =
ptr.get<ESM::Armor>(); ptr.get<ESM::Armor>();
return ref->base->mName; return ref->mBase->mName;
} }
boost::shared_ptr<MWWorld::Action> Armor::activate (const MWWorld::Ptr& ptr, boost::shared_ptr<MWWorld::Action> Armor::activate (const MWWorld::Ptr& ptr,
@ -82,7 +81,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Armor> *ref = MWWorld::LiveCellRef<ESM::Armor> *ref =
ptr.get<ESM::Armor>(); ptr.get<ESM::Armor>();
return ref->base->mData.mHealth; return ref->mBase->mData.mHealth;
} }
std::string Armor::getScript (const MWWorld::Ptr& ptr) const std::string Armor::getScript (const MWWorld::Ptr& ptr) const
@ -90,7 +89,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Armor> *ref = MWWorld::LiveCellRef<ESM::Armor> *ref =
ptr.get<ESM::Armor>(); ptr.get<ESM::Armor>();
return ref->base->mScript; return ref->mBase->mScript;
} }
std::pair<std::vector<int>, bool> Armor::getEquipmentSlots (const MWWorld::Ptr& ptr) const std::pair<std::vector<int>, bool> Armor::getEquipmentSlots (const MWWorld::Ptr& ptr) const
@ -118,7 +117,7 @@ namespace MWClass
}; };
for (int i=0; i<size; ++i) for (int i=0; i<size; ++i)
if (sMapping[i][0]==ref->base->mData.mType) if (sMapping[i][0]==ref->mBase->mData.mType)
{ {
slots.push_back (int (sMapping[i][1])); slots.push_back (int (sMapping[i][1]));
break; break;
@ -134,7 +133,7 @@ namespace MWClass
std::string typeGmst; std::string typeGmst;
switch (ref->base->mData.mType) switch (ref->mBase->mData.mType)
{ {
case ESM::Armor::Helmet: typeGmst = "iHelmWeight"; break; case ESM::Armor::Helmet: typeGmst = "iHelmWeight"; break;
case ESM::Armor::Cuirass: typeGmst = "iCuirassWeight"; break; case ESM::Armor::Cuirass: typeGmst = "iCuirassWeight"; break;
@ -152,14 +151,17 @@ namespace MWClass
if (typeGmst.empty()) if (typeGmst.empty())
return -1; return -1;
float iWeight = MWBase::Environment::get().getWorld()->getStore().gameSettings.find (typeGmst)->getInt(); const MWWorld::Store<ESM::GameSetting> &gmst =
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
float iWeight = gmst.find (typeGmst)->getInt();
if (iWeight * MWBase::Environment::get().getWorld()->getStore().gameSettings.find ("fLightMaxMod")->getFloat()>= if (iWeight * gmst.find ("fLightMaxMod")->getFloat()>=
ref->base->mData.mWeight) ref->mBase->mData.mWeight)
return ESM::Skill::LightArmor; return ESM::Skill::LightArmor;
if (iWeight * MWBase::Environment::get().getWorld()->getStore().gameSettings.find ("fMedMaxMod")->getFloat()>= if (iWeight * gmst.find ("fMedMaxMod")->getFloat()>=
ref->base->mData.mWeight) ref->mBase->mData.mWeight)
return ESM::Skill::MediumArmor; return ESM::Skill::MediumArmor;
return ESM::Skill::HeavyArmor; return ESM::Skill::HeavyArmor;
@ -170,7 +172,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Armor> *ref = MWWorld::LiveCellRef<ESM::Armor> *ref =
ptr.get<ESM::Armor>(); ptr.get<ESM::Armor>();
return ref->base->mData.mValue; return ref->mBase->mData.mValue;
} }
void Armor::registerSelf() void Armor::registerSelf()
@ -207,7 +209,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Armor> *ref = MWWorld::LiveCellRef<ESM::Armor> *ref =
ptr.get<ESM::Armor>(); ptr.get<ESM::Armor>();
return ref->base->mIcon; return ref->mBase->mIcon;
} }
bool Armor::hasToolTip (const MWWorld::Ptr& ptr) const bool Armor::hasToolTip (const MWWorld::Ptr& ptr) const
@ -215,7 +217,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Armor> *ref = MWWorld::LiveCellRef<ESM::Armor> *ref =
ptr.get<ESM::Armor>(); ptr.get<ESM::Armor>();
return (ref->base->mName != ""); return (ref->mBase->mName != "");
} }
MWGui::ToolTipInfo Armor::getToolTipInfo (const MWWorld::Ptr& ptr) const MWGui::ToolTipInfo Armor::getToolTipInfo (const MWWorld::Ptr& ptr) const
@ -224,8 +226,8 @@ namespace MWClass
ptr.get<ESM::Armor>(); ptr.get<ESM::Armor>();
MWGui::ToolTipInfo info; MWGui::ToolTipInfo info;
info.caption = ref->base->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount()); info.caption = ref->mBase->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
info.icon = ref->base->mIcon; info.icon = ref->mBase->mIcon;
std::string text; std::string text;
@ -239,20 +241,20 @@ namespace MWClass
else else
typeText = "#{sHeavy}"; typeText = "#{sHeavy}";
text += "\n#{sArmorRating}: " + MWGui::ToolTips::toString(ref->base->mData.mArmor); text += "\n#{sArmorRating}: " + MWGui::ToolTips::toString(ref->mBase->mData.mArmor);
/// \todo store the current armor health somewhere /// \todo store the current armor health somewhere
text += "\n#{sCondition}: " + MWGui::ToolTips::toString(ref->base->mData.mHealth); text += "\n#{sCondition}: " + MWGui::ToolTips::toString(ref->mBase->mData.mHealth);
text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->base->mData.mWeight) + " (" + typeText + ")"; text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight) + " (" + typeText + ")";
text += MWGui::ToolTips::getValueString(ref->base->mData.mValue, "#{sValue}"); text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}");
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
text += MWGui::ToolTips::getMiscString(ref->ref.mOwner, "Owner"); text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner");
text += MWGui::ToolTips::getMiscString(ref->base->mScript, "Script"); text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
} }
info.enchant = ref->base->mEnchant; info.enchant = ref->mBase->mEnchant;
info.text = text; info.text = text;
@ -264,7 +266,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Armor> *ref = MWWorld::LiveCellRef<ESM::Armor> *ref =
ptr.get<ESM::Armor>(); ptr.get<ESM::Armor>();
return ref->base->mEnchant; return ref->mBase->mEnchant;
} }
boost::shared_ptr<MWWorld::Action> Armor::use (const MWWorld::Ptr& ptr) const boost::shared_ptr<MWWorld::Action> Armor::use (const MWWorld::Ptr& ptr) const
@ -282,6 +284,6 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Armor> *ref = MWWorld::LiveCellRef<ESM::Armor> *ref =
ptr.get<ESM::Armor>(); ptr.get<ESM::Armor>();
return MWWorld::Ptr(&cell.armors.insert(*ref), &cell); return MWWorld::Ptr(&cell.mArmors.insert(*ref), &cell);
} }
} }

@ -32,18 +32,17 @@ namespace MWClass
void Book::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const void Book::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
{ {
const std::string model = getModel(ptr); const std::string model = getModel(ptr);
if(!model.empty()) { if(!model.empty())
physics.insertObjectPhysics(ptr, model); physics.addObject(ptr);
}
} }
std::string Book::getModel(const MWWorld::Ptr &ptr) const std::string Book::getModel(const MWWorld::Ptr &ptr) const
{ {
MWWorld::LiveCellRef<ESM::Book> *ref = MWWorld::LiveCellRef<ESM::Book> *ref =
ptr.get<ESM::Book>(); ptr.get<ESM::Book>();
assert(ref->base != NULL); assert(ref->mBase != NULL);
const std::string &model = ref->base->mModel; const std::string &model = ref->mBase->mModel;
if (!model.empty()) { if (!model.empty()) {
return "meshes\\" + model; return "meshes\\" + model;
} }
@ -55,7 +54,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Book> *ref = MWWorld::LiveCellRef<ESM::Book> *ref =
ptr.get<ESM::Book>(); ptr.get<ESM::Book>();
return ref->base->mName; return ref->mBase->mName;
} }
boost::shared_ptr<MWWorld::Action> Book::activate (const MWWorld::Ptr& ptr, boost::shared_ptr<MWWorld::Action> Book::activate (const MWWorld::Ptr& ptr,
@ -70,7 +69,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Book> *ref = MWWorld::LiveCellRef<ESM::Book> *ref =
ptr.get<ESM::Book>(); ptr.get<ESM::Book>();
return ref->base->mScript; return ref->mBase->mScript;
} }
int Book::getValue (const MWWorld::Ptr& ptr) const int Book::getValue (const MWWorld::Ptr& ptr) const
@ -78,7 +77,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Book> *ref = MWWorld::LiveCellRef<ESM::Book> *ref =
ptr.get<ESM::Book>(); ptr.get<ESM::Book>();
return ref->base->mData.mValue; return ref->mBase->mData.mValue;
} }
void Book::registerSelf() void Book::registerSelf()
@ -103,7 +102,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Book> *ref = MWWorld::LiveCellRef<ESM::Book> *ref =
ptr.get<ESM::Book>(); ptr.get<ESM::Book>();
return ref->base->mIcon; return ref->mBase->mIcon;
} }
bool Book::hasToolTip (const MWWorld::Ptr& ptr) const bool Book::hasToolTip (const MWWorld::Ptr& ptr) const
@ -111,7 +110,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Book> *ref = MWWorld::LiveCellRef<ESM::Book> *ref =
ptr.get<ESM::Book>(); ptr.get<ESM::Book>();
return (ref->base->mName != ""); return (ref->mBase->mName != "");
} }
MWGui::ToolTipInfo Book::getToolTipInfo (const MWWorld::Ptr& ptr) const MWGui::ToolTipInfo Book::getToolTipInfo (const MWWorld::Ptr& ptr) const
@ -120,20 +119,20 @@ namespace MWClass
ptr.get<ESM::Book>(); ptr.get<ESM::Book>();
MWGui::ToolTipInfo info; MWGui::ToolTipInfo info;
info.caption = ref->base->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount()); info.caption = ref->mBase->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
info.icon = ref->base->mIcon; info.icon = ref->mBase->mIcon;
std::string text; std::string text;
text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->base->mData.mWeight); text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight);
text += MWGui::ToolTips::getValueString(ref->base->mData.mValue, "#{sValue}"); text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}");
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
text += MWGui::ToolTips::getMiscString(ref->ref.mOwner, "Owner"); text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner");
text += MWGui::ToolTips::getMiscString(ref->base->mScript, "Script"); text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
} }
info.enchant = ref->base->mEnchant; info.enchant = ref->mBase->mEnchant;
info.text = text; info.text = text;
@ -145,7 +144,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Book> *ref = MWWorld::LiveCellRef<ESM::Book> *ref =
ptr.get<ESM::Book>(); ptr.get<ESM::Book>();
return ref->base->mEnchant; return ref->mBase->mEnchant;
} }
boost::shared_ptr<MWWorld::Action> Book::use (const MWWorld::Ptr& ptr) const boost::shared_ptr<MWWorld::Action> Book::use (const MWWorld::Ptr& ptr) const
@ -159,6 +158,6 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Book> *ref = MWWorld::LiveCellRef<ESM::Book> *ref =
ptr.get<ESM::Book>(); ptr.get<ESM::Book>();
return MWWorld::Ptr(&cell.books.insert(*ref), &cell); return MWWorld::Ptr(&cell.mBooks.insert(*ref), &cell);
} }
} }

@ -34,18 +34,17 @@ namespace MWClass
void Clothing::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const void Clothing::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
{ {
const std::string model = getModel(ptr); const std::string model = getModel(ptr);
if(!model.empty()) { if(!model.empty())
physics.insertObjectPhysics(ptr, model); physics.addObject(ptr);
}
} }
std::string Clothing::getModel(const MWWorld::Ptr &ptr) const std::string Clothing::getModel(const MWWorld::Ptr &ptr) const
{ {
MWWorld::LiveCellRef<ESM::Clothing> *ref = MWWorld::LiveCellRef<ESM::Clothing> *ref =
ptr.get<ESM::Clothing>(); ptr.get<ESM::Clothing>();
assert(ref->base != NULL); assert(ref->mBase != NULL);
const std::string &model = ref->base->mModel; const std::string &model = ref->mBase->mModel;
if (!model.empty()) { if (!model.empty()) {
return "meshes\\" + model; return "meshes\\" + model;
} }
@ -57,7 +56,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Clothing> *ref = MWWorld::LiveCellRef<ESM::Clothing> *ref =
ptr.get<ESM::Clothing>(); ptr.get<ESM::Clothing>();
return ref->base->mName; return ref->mBase->mName;
} }
boost::shared_ptr<MWWorld::Action> Clothing::activate (const MWWorld::Ptr& ptr, boost::shared_ptr<MWWorld::Action> Clothing::activate (const MWWorld::Ptr& ptr,
@ -75,7 +74,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Clothing> *ref = MWWorld::LiveCellRef<ESM::Clothing> *ref =
ptr.get<ESM::Clothing>(); ptr.get<ESM::Clothing>();
return ref->base->mScript; return ref->mBase->mScript;
} }
std::pair<std::vector<int>, bool> Clothing::getEquipmentSlots (const MWWorld::Ptr& ptr) const std::pair<std::vector<int>, bool> Clothing::getEquipmentSlots (const MWWorld::Ptr& ptr) const
@ -85,7 +84,7 @@ namespace MWClass
std::vector<int> slots; std::vector<int> slots;
if (ref->base->mData.mType==ESM::Clothing::Ring) if (ref->mBase->mData.mType==ESM::Clothing::Ring)
{ {
slots.push_back (int (MWWorld::InventoryStore::Slot_LeftRing)); slots.push_back (int (MWWorld::InventoryStore::Slot_LeftRing));
slots.push_back (int (MWWorld::InventoryStore::Slot_RightRing)); slots.push_back (int (MWWorld::InventoryStore::Slot_RightRing));
@ -108,7 +107,7 @@ namespace MWClass
}; };
for (int i=0; i<size; ++i) for (int i=0; i<size; ++i)
if (sMapping[i][0]==ref->base->mData.mType) if (sMapping[i][0]==ref->mBase->mData.mType)
{ {
slots.push_back (int (sMapping[i][1])); slots.push_back (int (sMapping[i][1]));
break; break;
@ -123,7 +122,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Clothing> *ref = MWWorld::LiveCellRef<ESM::Clothing> *ref =
ptr.get<ESM::Clothing>(); ptr.get<ESM::Clothing>();
if (ref->base->mData.mType==ESM::Clothing::Shoes) if (ref->mBase->mData.mType==ESM::Clothing::Shoes)
return ESM::Skill::Unarmored; return ESM::Skill::Unarmored;
return -1; return -1;
@ -134,7 +133,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Clothing> *ref = MWWorld::LiveCellRef<ESM::Clothing> *ref =
ptr.get<ESM::Clothing>(); ptr.get<ESM::Clothing>();
return ref->base->mData.mValue; return ref->mBase->mData.mValue;
} }
void Clothing::registerSelf() void Clothing::registerSelf()
@ -149,7 +148,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Clothing> *ref = MWWorld::LiveCellRef<ESM::Clothing> *ref =
ptr.get<ESM::Clothing>(); ptr.get<ESM::Clothing>();
if (ref->base->mData.mType == 8) if (ref->mBase->mData.mType == 8)
{ {
return std::string("Item Ring Up"); return std::string("Item Ring Up");
} }
@ -161,7 +160,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Clothing> *ref = MWWorld::LiveCellRef<ESM::Clothing> *ref =
ptr.get<ESM::Clothing>(); ptr.get<ESM::Clothing>();
if (ref->base->mData.mType == 8) if (ref->mBase->mData.mType == 8)
{ {
return std::string("Item Ring Down"); return std::string("Item Ring Down");
} }
@ -173,7 +172,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Clothing> *ref = MWWorld::LiveCellRef<ESM::Clothing> *ref =
ptr.get<ESM::Clothing>(); ptr.get<ESM::Clothing>();
return ref->base->mIcon; return ref->mBase->mIcon;
} }
bool Clothing::hasToolTip (const MWWorld::Ptr& ptr) const bool Clothing::hasToolTip (const MWWorld::Ptr& ptr) const
@ -181,7 +180,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Clothing> *ref = MWWorld::LiveCellRef<ESM::Clothing> *ref =
ptr.get<ESM::Clothing>(); ptr.get<ESM::Clothing>();
return (ref->base->mName != ""); return (ref->mBase->mName != "");
} }
MWGui::ToolTipInfo Clothing::getToolTipInfo (const MWWorld::Ptr& ptr) const MWGui::ToolTipInfo Clothing::getToolTipInfo (const MWWorld::Ptr& ptr) const
@ -190,20 +189,20 @@ namespace MWClass
ptr.get<ESM::Clothing>(); ptr.get<ESM::Clothing>();
MWGui::ToolTipInfo info; MWGui::ToolTipInfo info;
info.caption = ref->base->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount()); info.caption = ref->mBase->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
info.icon = ref->base->mIcon; info.icon = ref->mBase->mIcon;
std::string text; std::string text;
text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->base->mData.mWeight); text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight);
text += MWGui::ToolTips::getValueString(ref->base->mData.mValue, "#{sValue}"); text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}");
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
text += MWGui::ToolTips::getMiscString(ref->ref.mOwner, "Owner"); text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner");
text += MWGui::ToolTips::getMiscString(ref->base->mScript, "Script"); text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
} }
info.enchant = ref->base->mEnchant; info.enchant = ref->mBase->mEnchant;
info.text = text; info.text = text;
@ -215,7 +214,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Clothing> *ref = MWWorld::LiveCellRef<ESM::Clothing> *ref =
ptr.get<ESM::Clothing>(); ptr.get<ESM::Clothing>();
return ref->base->mEnchant; return ref->mBase->mEnchant;
} }
boost::shared_ptr<MWWorld::Action> Clothing::use (const MWWorld::Ptr& ptr) const boost::shared_ptr<MWWorld::Action> Clothing::use (const MWWorld::Ptr& ptr) const
@ -233,6 +232,6 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Clothing> *ref = MWWorld::LiveCellRef<ESM::Clothing> *ref =
ptr.get<ESM::Clothing>(); ptr.get<ESM::Clothing>();
return MWWorld::Ptr(&cell.clothes.insert(*ref), &cell); return MWWorld::Ptr(&cell.mClothes.insert(*ref), &cell);
} }
} }

@ -65,18 +65,17 @@ namespace MWClass
void Container::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const void Container::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
{ {
const std::string model = getModel(ptr); const std::string model = getModel(ptr);
if(!model.empty()) { if(!model.empty())
physics.insertObjectPhysics(ptr, model); physics.addObject(ptr);
}
} }
std::string Container::getModel(const MWWorld::Ptr &ptr) const std::string Container::getModel(const MWWorld::Ptr &ptr) const
{ {
MWWorld::LiveCellRef<ESM::Container> *ref = MWWorld::LiveCellRef<ESM::Container> *ref =
ptr.get<ESM::Container>(); ptr.get<ESM::Container>();
assert(ref->base != NULL); assert(ref->mBase != NULL);
const std::string &model = ref->base->mModel; const std::string &model = ref->mBase->mModel;
if (!model.empty()) { if (!model.empty()) {
return "meshes\\" + model; return "meshes\\" + model;
} }
@ -149,7 +148,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Container> *ref = MWWorld::LiveCellRef<ESM::Container> *ref =
ptr.get<ESM::Container>(); ptr.get<ESM::Container>();
return ref->base->mName; return ref->mBase->mName;
} }
MWWorld::ContainerStore& Container::getContainerStore (const MWWorld::Ptr& ptr) MWWorld::ContainerStore& Container::getContainerStore (const MWWorld::Ptr& ptr)
@ -165,7 +164,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Container> *ref = MWWorld::LiveCellRef<ESM::Container> *ref =
ptr.get<ESM::Container>(); ptr.get<ESM::Container>();
return ref->base->mScript; return ref->mBase->mScript;
} }
void Container::registerSelf() void Container::registerSelf()
@ -180,7 +179,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Container> *ref = MWWorld::LiveCellRef<ESM::Container> *ref =
ptr.get<ESM::Container>(); ptr.get<ESM::Container>();
return (ref->base->mName != ""); return (ref->mBase->mName != "");
} }
MWGui::ToolTipInfo Container::getToolTipInfo (const MWWorld::Ptr& ptr) const MWGui::ToolTipInfo Container::getToolTipInfo (const MWWorld::Ptr& ptr) const
@ -189,17 +188,17 @@ namespace MWClass
ptr.get<ESM::Container>(); ptr.get<ESM::Container>();
MWGui::ToolTipInfo info; MWGui::ToolTipInfo info;
info.caption = ref->base->mName; info.caption = ref->mBase->mName;
std::string text; std::string text;
if (ref->ref.mLockLevel > 0) if (ref->mRef.mLockLevel > 0)
text += "\n#{sLockLevel}: " + MWGui::ToolTips::toString(ref->ref.mLockLevel); text += "\n#{sLockLevel}: " + MWGui::ToolTips::toString(ref->mRef.mLockLevel);
if (ref->ref.mTrap != "") if (ref->mRef.mTrap != "")
text += "\n#{sTrapped}"; text += "\n#{sTrapped}";
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
text += MWGui::ToolTips::getMiscString(ref->ref.mOwner, "Owner"); text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner");
text += MWGui::ToolTips::getMiscString(ref->base->mScript, "Script"); text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
} }
info.text = text; info.text = text;
@ -212,7 +211,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Container> *ref = MWWorld::LiveCellRef<ESM::Container> *ref =
ptr.get<ESM::Container>(); ptr.get<ESM::Container>();
return ref->base->mWeight; return ref->mBase->mWeight;
} }
float Container::getEncumbrance (const MWWorld::Ptr& ptr) const float Container::getEncumbrance (const MWWorld::Ptr& ptr) const
@ -239,6 +238,6 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Container> *ref = MWWorld::LiveCellRef<ESM::Container> *ref =
ptr.get<ESM::Container>(); ptr.get<ESM::Container>();
return MWWorld::Ptr(&cell.containers.insert(*ref), &cell); return MWWorld::Ptr(&cell.mContainers.insert(*ref), &cell);
} }
} }

@ -48,28 +48,28 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Creature> *ref = ptr.get<ESM::Creature>(); MWWorld::LiveCellRef<ESM::Creature> *ref = ptr.get<ESM::Creature>();
// creature stats // creature stats
data->mCreatureStats.getAttribute(0).set (ref->base->mData.mStrength); data->mCreatureStats.getAttribute(0).set (ref->mBase->mData.mStrength);
data->mCreatureStats.getAttribute(1).set (ref->base->mData.mIntelligence); data->mCreatureStats.getAttribute(1).set (ref->mBase->mData.mIntelligence);
data->mCreatureStats.getAttribute(2).set (ref->base->mData.mWillpower); data->mCreatureStats.getAttribute(2).set (ref->mBase->mData.mWillpower);
data->mCreatureStats.getAttribute(3).set (ref->base->mData.mAgility); data->mCreatureStats.getAttribute(3).set (ref->mBase->mData.mAgility);
data->mCreatureStats.getAttribute(4).set (ref->base->mData.mSpeed); data->mCreatureStats.getAttribute(4).set (ref->mBase->mData.mSpeed);
data->mCreatureStats.getAttribute(5).set (ref->base->mData.mEndurance); data->mCreatureStats.getAttribute(5).set (ref->mBase->mData.mEndurance);
data->mCreatureStats.getAttribute(6).set (ref->base->mData.mPersonality); data->mCreatureStats.getAttribute(6).set (ref->mBase->mData.mPersonality);
data->mCreatureStats.getAttribute(7).set (ref->base->mData.mLuck); data->mCreatureStats.getAttribute(7).set (ref->mBase->mData.mLuck);
data->mCreatureStats.setHealth (ref->base->mData.mHealth); data->mCreatureStats.setHealth (ref->mBase->mData.mHealth);
data->mCreatureStats.setMagicka (ref->base->mData.mMana); data->mCreatureStats.setMagicka (ref->mBase->mData.mMana);
data->mCreatureStats.setFatigue (ref->base->mData.mFatigue); data->mCreatureStats.setFatigue (ref->mBase->mData.mFatigue);
data->mCreatureStats.setLevel(ref->base->mData.mLevel); data->mCreatureStats.setLevel(ref->mBase->mData.mLevel);
data->mCreatureStats.setHello(ref->base->mAiData.mHello); data->mCreatureStats.setAiSetting (0, ref->mBase->mAiData.mHello);
data->mCreatureStats.setFight(ref->base->mAiData.mFight); data->mCreatureStats.setAiSetting (1, ref->mBase->mAiData.mFight);
data->mCreatureStats.setFlee(ref->base->mAiData.mFlee); data->mCreatureStats.setAiSetting (2, ref->mBase->mAiData.mFlee);
data->mCreatureStats.setAlarm(ref->base->mAiData.mAlarm); data->mCreatureStats.setAiSetting (3, ref->mBase->mAiData.mAlarm);
// spells // spells
for (std::vector<std::string>::const_iterator iter (ref->base->mSpells.mList.begin()); for (std::vector<std::string>::const_iterator iter (ref->mBase->mSpells.mList.begin());
iter!=ref->base->mSpells.mList.end(); ++iter) iter!=ref->mBase->mSpells.mList.end(); ++iter)
data->mCreatureStats.getSpells().add (*iter); data->mCreatureStats.getSpells().add (*iter);
// store // store
@ -82,7 +82,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Creature> *ref = MWWorld::LiveCellRef<ESM::Creature> *ref =
ptr.get<ESM::Creature>(); ptr.get<ESM::Creature>();
return ref->base->mId; return ref->mBase->mId;
} }
void Creature::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const void Creature::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
@ -94,9 +94,8 @@ namespace MWClass
void Creature::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const void Creature::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
{ {
const std::string model = getModel(ptr); const std::string model = getModel(ptr);
if(!model.empty()){ if(!model.empty())
physics.insertActorPhysics(ptr, model); physics.addActor(ptr);
}
MWBase::Environment::get().getMechanicsManager()->addActor (ptr); MWBase::Environment::get().getMechanicsManager()->addActor (ptr);
} }
@ -104,9 +103,9 @@ namespace MWClass
{ {
MWWorld::LiveCellRef<ESM::Creature> *ref = MWWorld::LiveCellRef<ESM::Creature> *ref =
ptr.get<ESM::Creature>(); ptr.get<ESM::Creature>();
assert (ref->base != NULL); assert (ref->mBase != NULL);
const std::string &model = ref->base->mModel; const std::string &model = ref->mBase->mModel;
if (!model.empty()) { if (!model.empty()) {
return "meshes\\" + model; return "meshes\\" + model;
} }
@ -118,7 +117,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Creature> *ref = MWWorld::LiveCellRef<ESM::Creature> *ref =
ptr.get<ESM::Creature>(); ptr.get<ESM::Creature>();
return ref->base->mName; return ref->mBase->mName;
} }
MWMechanics::CreatureStats& Creature::getCreatureStats (const MWWorld::Ptr& ptr) const MWMechanics::CreatureStats& Creature::getCreatureStats (const MWWorld::Ptr& ptr) const
@ -150,7 +149,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Creature> *ref = MWWorld::LiveCellRef<ESM::Creature> *ref =
ptr.get<ESM::Creature>(); ptr.get<ESM::Creature>();
return ref->base->mScript; return ref->mBase->mScript;
} }
bool Creature::isEssential (const MWWorld::Ptr& ptr) const bool Creature::isEssential (const MWWorld::Ptr& ptr) const
@ -158,7 +157,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Creature> *ref = MWWorld::LiveCellRef<ESM::Creature> *ref =
ptr.get<ESM::Creature>(); ptr.get<ESM::Creature>();
return ref->base->mFlags & ESM::Creature::Essential; return ref->mBase->mFlags & ESM::Creature::Essential;
} }
void Creature::registerSelf() void Creature::registerSelf()
@ -181,11 +180,11 @@ namespace MWClass
ptr.get<ESM::Creature>(); ptr.get<ESM::Creature>();
MWGui::ToolTipInfo info; MWGui::ToolTipInfo info;
info.caption = ref->base->mName; info.caption = ref->mBase->mName;
std::string text; std::string text;
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) if (MWBase::Environment::get().getWindowManager()->getFullHelp())
text += MWGui::ToolTips::getMiscString(ref->base->mScript, "Script"); text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
info.text = text; info.text = text;
return info; return info;
@ -219,6 +218,6 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Creature> *ref = MWWorld::LiveCellRef<ESM::Creature> *ref =
ptr.get<ESM::Creature>(); ptr.get<ESM::Creature>();
return MWWorld::Ptr(&cell.creatures.insert(*ref), &cell); return MWWorld::Ptr(&cell.mCreatures.insert(*ref), &cell);
} }
} }

@ -36,18 +36,17 @@ namespace MWClass
void Door::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const void Door::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
{ {
const std::string model = getModel(ptr); const std::string model = getModel(ptr);
if(!model.empty()) { if(!model.empty())
physics.insertObjectPhysics(ptr, model); physics.addObject(ptr);
}
} }
std::string Door::getModel(const MWWorld::Ptr &ptr) const std::string Door::getModel(const MWWorld::Ptr &ptr) const
{ {
MWWorld::LiveCellRef<ESM::Door> *ref = MWWorld::LiveCellRef<ESM::Door> *ref =
ptr.get<ESM::Door>(); ptr.get<ESM::Door>();
assert(ref->base != NULL); assert(ref->mBase != NULL);
const std::string &model = ref->base->mModel; const std::string &model = ref->mBase->mModel;
if (!model.empty()) { if (!model.empty()) {
return "meshes\\" + model; return "meshes\\" + model;
} }
@ -59,10 +58,10 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Door> *ref = MWWorld::LiveCellRef<ESM::Door> *ref =
ptr.get<ESM::Door>(); ptr.get<ESM::Door>();
if (ref->ref.mTeleport && !ref->ref.mDestCell.empty()) // TODO doors that lead to exteriors if (ref->mRef.mTeleport && !ref->mRef.mDestCell.empty()) // TODO doors that lead to exteriors
return ref->ref.mDestCell; return ref->mRef.mDestCell;
return ref->base->mName; return ref->mBase->mName;
} }
boost::shared_ptr<MWWorld::Action> Door::activate (const MWWorld::Ptr& ptr, boost::shared_ptr<MWWorld::Action> Door::activate (const MWWorld::Ptr& ptr,
@ -71,8 +70,8 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Door> *ref = MWWorld::LiveCellRef<ESM::Door> *ref =
ptr.get<ESM::Door>(); ptr.get<ESM::Door>();
const std::string &openSound = ref->base->mOpenSound; const std::string &openSound = ref->mBase->mOpenSound;
//const std::string &closeSound = ref->base->closeSound; //const std::string &closeSound = ref->mBase->closeSound;
const std::string lockedSound = "LockedDoor"; const std::string lockedSound = "LockedDoor";
const std::string trapActivationSound = "Disarm Trap Fail"; const std::string trapActivationSound = "Disarm Trap Fail";
@ -119,13 +118,13 @@ namespace MWClass
return action; return action;
} }
if (ref->ref.mTeleport) if (ref->mRef.mTeleport)
{ {
// teleport door // teleport door
/// \todo remove this if clause once ActionTeleport can also support other actors /// \todo remove this if clause once ActionTeleport can also support other actors
if (MWBase::Environment::get().getWorld()->getPlayer().getPlayer()==actor) if (MWBase::Environment::get().getWorld()->getPlayer().getPlayer()==actor)
{ {
boost::shared_ptr<MWWorld::Action> action(new MWWorld::ActionTeleport (ref->ref.mDestCell, ref->ref.mDoorDest)); boost::shared_ptr<MWWorld::Action> action(new MWWorld::ActionTeleport (ref->mRef.mDestCell, ref->mRef.mDoorDest));
action->setSound(openSound); action->setSound(openSound);
@ -177,7 +176,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Door> *ref = MWWorld::LiveCellRef<ESM::Door> *ref =
ptr.get<ESM::Door>(); ptr.get<ESM::Door>();
return ref->base->mScript; return ref->mBase->mScript;
} }
void Door::registerSelf() void Door::registerSelf()
@ -192,7 +191,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Door> *ref = MWWorld::LiveCellRef<ESM::Door> *ref =
ptr.get<ESM::Door>(); ptr.get<ESM::Door>();
return (ref->base->mName != ""); return (ref->mBase->mName != "");
} }
MWGui::ToolTipInfo Door::getToolTipInfo (const MWWorld::Ptr& ptr) const MWGui::ToolTipInfo Door::getToolTipInfo (const MWWorld::Ptr& ptr) const
@ -201,49 +200,58 @@ namespace MWClass
ptr.get<ESM::Door>(); ptr.get<ESM::Door>();
MWGui::ToolTipInfo info; MWGui::ToolTipInfo info;
info.caption = ref->base->mName; info.caption = ref->mBase->mName;
std::string text; std::string text;
const ESMS::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); if (ref->mRef.mTeleport)
{
text += "\n#{sTo}";
text += "\n" + getDestination(*ref);
}
if (ref->mRef.mLockLevel > 0)
text += "\n#{sLockLevel}: " + MWGui::ToolTips::toString(ref->mRef.mLockLevel);
if (ref->mRef.mTrap != "")
text += "\n#{sTrapped}";
if (MWBase::Environment::get().getWindowManager()->getFullHelp())
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
info.text = text;
return info;
}
if (ref->ref.mTeleport) std::string Door::getDestination (const MWWorld::LiveCellRef<ESM::Door>& door)
{ {
const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
std::string dest; std::string dest;
if (ref->ref.mDestCell != "") if (door.mRef.mDestCell != "")
{ {
// door leads to an interior, use interior name as tooltip // door leads to an interior, use interior name as tooltip
dest = ref->ref.mDestCell; dest = door.mRef.mDestCell;
} }
else else
{ {
// door leads to exterior, use cell name (if any), otherwise translated region name // door leads to exterior, use cell name (if any), otherwise translated region name
int x,y; int x,y;
MWBase::Environment::get().getWorld()->positionToIndex (ref->ref.mDoorDest.pos[0], ref->ref.mDoorDest.pos[1], x, y); MWBase::Environment::get().getWorld()->positionToIndex (door.mRef.mDoorDest.pos[0], door.mRef.mDoorDest.pos[1], x, y);
const ESM::Cell* cell = store.cells.findExt(x,y); const ESM::Cell* cell = store.get<ESM::Cell>().find(x,y);
if (cell->mName != "") if (cell->mName != "")
dest = cell->mName; dest = cell->mName;
else else
{ {
const ESM::Region* region = store.regions.search(cell->mRegion); const ESM::Region* region =
dest = region->mName; store.get<ESM::Region>().find(cell->mRegion);
}
//name as is, not a token
return region->mName;
} }
text += "\n#{sTo}";
text += "\n"+dest;
} }
if (ref->ref.mLockLevel > 0) return "#{sCell=" + dest + "}";
text += "\n#{sLockLevel}: " + MWGui::ToolTips::toString(ref->ref.mLockLevel);
if (ref->ref.mTrap != "")
text += "\n#{sTrapped}";
if (MWBase::Environment::get().getWindowManager()->getFullHelp())
text += MWGui::ToolTips::getMiscString(ref->base->mScript, "Script");
info.text = text;
return info;
} }
MWWorld::Ptr MWWorld::Ptr
@ -252,6 +260,6 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Door> *ref = MWWorld::LiveCellRef<ESM::Door> *ref =
ptr.get<ESM::Door>(); ptr.get<ESM::Door>();
return MWWorld::Ptr(&cell.doors.insert(*ref), &cell); return MWWorld::Ptr(&cell.mDoors.insert(*ref), &cell);
} }
} }

@ -31,6 +31,9 @@ namespace MWClass
virtual MWGui::ToolTipInfo getToolTipInfo (const MWWorld::Ptr& ptr) const; virtual MWGui::ToolTipInfo getToolTipInfo (const MWWorld::Ptr& ptr) const;
///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip. ///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip.
static std::string getDestination (const MWWorld::LiveCellRef<ESM::Door>& door);
///< @return destination cell name or token
virtual void lock (const MWWorld::Ptr& ptr, int lockLevel) const; virtual void lock (const MWWorld::Ptr& ptr, int lockLevel) const;
///< Lock object ///< Lock object

@ -25,7 +25,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Ingredient> *ref = MWWorld::LiveCellRef<ESM::Ingredient> *ref =
ptr.get<ESM::Ingredient>(); ptr.get<ESM::Ingredient>();
return ref->base->mId; return ref->mBase->mId;
} }
void Ingredient::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const void Ingredient::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
@ -41,18 +41,17 @@ namespace MWClass
void Ingredient::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const void Ingredient::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
{ {
const std::string model = getModel(ptr); const std::string model = getModel(ptr);
if(!model.empty()) { if(!model.empty())
physics.insertObjectPhysics(ptr, model); physics.addObject(ptr);
}
} }
std::string Ingredient::getModel(const MWWorld::Ptr &ptr) const std::string Ingredient::getModel(const MWWorld::Ptr &ptr) const
{ {
MWWorld::LiveCellRef<ESM::Ingredient> *ref = MWWorld::LiveCellRef<ESM::Ingredient> *ref =
ptr.get<ESM::Ingredient>(); ptr.get<ESM::Ingredient>();
assert(ref->base != NULL); assert(ref->mBase != NULL);
const std::string &model = ref->base->mModel; const std::string &model = ref->mBase->mModel;
if (!model.empty()) { if (!model.empty()) {
return "meshes\\" + model; return "meshes\\" + model;
} }
@ -64,7 +63,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Ingredient> *ref = MWWorld::LiveCellRef<ESM::Ingredient> *ref =
ptr.get<ESM::Ingredient>(); ptr.get<ESM::Ingredient>();
return ref->base->mName; return ref->mBase->mName;
} }
boost::shared_ptr<MWWorld::Action> Ingredient::activate (const MWWorld::Ptr& ptr, boost::shared_ptr<MWWorld::Action> Ingredient::activate (const MWWorld::Ptr& ptr,
@ -82,7 +81,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Ingredient> *ref = MWWorld::LiveCellRef<ESM::Ingredient> *ref =
ptr.get<ESM::Ingredient>(); ptr.get<ESM::Ingredient>();
return ref->base->mScript; return ref->mBase->mScript;
} }
int Ingredient::getValue (const MWWorld::Ptr& ptr) const int Ingredient::getValue (const MWWorld::Ptr& ptr) const
@ -90,7 +89,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Ingredient> *ref = MWWorld::LiveCellRef<ESM::Ingredient> *ref =
ptr.get<ESM::Ingredient>(); ptr.get<ESM::Ingredient>();
return ref->base->mData.mValue; return ref->mBase->mData.mValue;
} }
@ -125,7 +124,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Ingredient> *ref = MWWorld::LiveCellRef<ESM::Ingredient> *ref =
ptr.get<ESM::Ingredient>(); ptr.get<ESM::Ingredient>();
return ref->base->mIcon; return ref->mBase->mIcon;
} }
bool Ingredient::hasToolTip (const MWWorld::Ptr& ptr) const bool Ingredient::hasToolTip (const MWWorld::Ptr& ptr) const
@ -133,7 +132,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Ingredient> *ref = MWWorld::LiveCellRef<ESM::Ingredient> *ref =
ptr.get<ESM::Ingredient>(); ptr.get<ESM::Ingredient>();
return (ref->base->mName != ""); return (ref->mBase->mName != "");
} }
MWGui::ToolTipInfo Ingredient::getToolTipInfo (const MWWorld::Ptr& ptr) const MWGui::ToolTipInfo Ingredient::getToolTipInfo (const MWWorld::Ptr& ptr) const
@ -142,28 +141,28 @@ namespace MWClass
ptr.get<ESM::Ingredient>(); ptr.get<ESM::Ingredient>();
MWGui::ToolTipInfo info; MWGui::ToolTipInfo info;
info.caption = ref->base->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount()); info.caption = ref->mBase->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
info.icon = ref->base->mIcon; info.icon = ref->mBase->mIcon;
std::string text; std::string text;
text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->base->mData.mWeight); text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight);
text += MWGui::ToolTips::getValueString(ref->base->mData.mValue, "#{sValue}"); text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}");
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
text += MWGui::ToolTips::getMiscString(ref->ref.mOwner, "Owner"); text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner");
text += MWGui::ToolTips::getMiscString(ref->base->mScript, "Script"); text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
} }
MWGui::Widgets::SpellEffectList list; MWGui::Widgets::SpellEffectList list;
for (int i=0; i<4; ++i) for (int i=0; i<4; ++i)
{ {
if (ref->base->mData.mEffectID[i] < 0) if (ref->mBase->mData.mEffectID[i] < 0)
continue; continue;
MWGui::Widgets::SpellEffectParams params; MWGui::Widgets::SpellEffectParams params;
params.mEffectID = ref->base->mData.mEffectID[i]; params.mEffectID = ref->mBase->mData.mEffectID[i];
params.mAttribute = ref->base->mData.mAttributes[i]; params.mAttribute = ref->mBase->mData.mAttributes[i];
params.mSkill = ref->base->mData.mSkills[i]; params.mSkill = ref->mBase->mData.mSkills[i];
list.push_back(params); list.push_back(params);
} }
info.effects = list; info.effects = list;
@ -179,6 +178,6 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Ingredient> *ref = MWWorld::LiveCellRef<ESM::Ingredient> *ref =
ptr.get<ESM::Ingredient>(); ptr.get<ESM::Ingredient>();
return MWWorld::Ptr(&cell.ingreds.insert(*ref), &cell); return MWWorld::Ptr(&cell.mIngreds.insert(*ref), &cell);
} }
} }

@ -28,9 +28,9 @@ namespace MWClass
{ {
MWWorld::LiveCellRef<ESM::Light> *ref = MWWorld::LiveCellRef<ESM::Light> *ref =
ptr.get<ESM::Light>(); ptr.get<ESM::Light>();
assert (ref->base != NULL); assert (ref->mBase != NULL);
const std::string &model = ref->base->mModel; const std::string &model = ref->mBase->mModel;
MWRender::Objects& objects = renderingInterface.getObjects(); MWRender::Objects& objects = renderingInterface.getObjects();
objects.insertBegin(ptr, ptr.getRefData().isEnabled(), false); objects.insertBegin(ptr, ptr.getRefData().isEnabled(), false);
@ -38,11 +38,11 @@ namespace MWClass
if (!model.empty()) if (!model.empty())
objects.insertMesh(ptr, "meshes\\" + model); objects.insertMesh(ptr, "meshes\\" + model);
const int color = ref->base->mData.mColor; const int color = ref->mBase->mData.mColor;
const float r = ((color >> 0) & 0xFF) / 255.0f; const float r = ((color >> 0) & 0xFF) / 255.0f;
const float g = ((color >> 8) & 0xFF) / 255.0f; const float g = ((color >> 8) & 0xFF) / 255.0f;
const float b = ((color >> 16) & 0xFF) / 255.0f; const float b = ((color >> 16) & 0xFF) / 255.0f;
const float radius = float (ref->base->mData.mRadius); const float radius = float (ref->mBase->mData.mRadius);
objects.insertLight (ptr, r, g, b, radius); objects.insertLight (ptr, r, g, b, radius);
} }
@ -50,25 +50,24 @@ namespace MWClass
{ {
MWWorld::LiveCellRef<ESM::Light> *ref = MWWorld::LiveCellRef<ESM::Light> *ref =
ptr.get<ESM::Light>(); ptr.get<ESM::Light>();
assert (ref->base != NULL); assert (ref->mBase != NULL);
const std::string &model = ref->base->mModel; const std::string &model = ref->mBase->mModel;
if(!model.empty()) { if(!model.empty())
physics.insertObjectPhysics(ptr, "meshes\\" + model); physics.addObject(ptr);
}
if (!ref->base->mSound.empty()) { if (!ref->mBase->mSound.empty())
MWBase::Environment::get().getSoundManager()->playSound3D(ptr, ref->base->mSound, 1.0, 1.0, MWBase::SoundManager::Play_Loop); MWBase::Environment::get().getSoundManager()->playSound3D(ptr, ref->mBase->mSound, 1.0, 1.0, MWBase::SoundManager::Play_Loop);
}
} }
std::string Light::getModel(const MWWorld::Ptr &ptr) const std::string Light::getModel(const MWWorld::Ptr &ptr) const
{ {
MWWorld::LiveCellRef<ESM::Light> *ref = MWWorld::LiveCellRef<ESM::Light> *ref =
ptr.get<ESM::Light>(); ptr.get<ESM::Light>();
assert (ref->base != NULL); assert (ref->mBase != NULL);
const std::string &model = ref->base->mModel; const std::string &model = ref->mBase->mModel;
if (!model.empty()) { if (!model.empty()) {
return "meshes\\" + model; return "meshes\\" + model;
} }
@ -80,10 +79,10 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Light> *ref = MWWorld::LiveCellRef<ESM::Light> *ref =
ptr.get<ESM::Light>(); ptr.get<ESM::Light>();
if (ref->base->mModel.empty()) if (ref->mBase->mModel.empty())
return ""; return "";
return ref->base->mName; return ref->mBase->mName;
} }
boost::shared_ptr<MWWorld::Action> Light::activate (const MWWorld::Ptr& ptr, boost::shared_ptr<MWWorld::Action> Light::activate (const MWWorld::Ptr& ptr,
@ -92,7 +91,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Light> *ref = MWWorld::LiveCellRef<ESM::Light> *ref =
ptr.get<ESM::Light>(); ptr.get<ESM::Light>();
if (!(ref->base->mData.mFlags & ESM::Light::Carry)) if (!(ref->mBase->mData.mFlags & ESM::Light::Carry))
return boost::shared_ptr<MWWorld::Action> (new MWWorld::FailedAction); return boost::shared_ptr<MWWorld::Action> (new MWWorld::FailedAction);
boost::shared_ptr<MWWorld::Action> action(new MWWorld::ActionTake (ptr)); boost::shared_ptr<MWWorld::Action> action(new MWWorld::ActionTake (ptr));
@ -107,7 +106,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Light> *ref = MWWorld::LiveCellRef<ESM::Light> *ref =
ptr.get<ESM::Light>(); ptr.get<ESM::Light>();
return ref->base->mScript; return ref->mBase->mScript;
} }
std::pair<std::vector<int>, bool> Light::getEquipmentSlots (const MWWorld::Ptr& ptr) const std::pair<std::vector<int>, bool> Light::getEquipmentSlots (const MWWorld::Ptr& ptr) const
@ -117,7 +116,7 @@ namespace MWClass
std::vector<int> slots; std::vector<int> slots;
if (ref->base->mData.mFlags & ESM::Light::Carry) if (ref->mBase->mData.mFlags & ESM::Light::Carry)
slots.push_back (int (MWWorld::InventoryStore::Slot_CarriedLeft)); slots.push_back (int (MWWorld::InventoryStore::Slot_CarriedLeft));
return std::make_pair (slots, false); return std::make_pair (slots, false);
@ -128,7 +127,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Light> *ref = MWWorld::LiveCellRef<ESM::Light> *ref =
ptr.get<ESM::Light>(); ptr.get<ESM::Light>();
return ref->base->mData.mValue; return ref->mBase->mData.mValue;
} }
void Light::registerSelf() void Light::registerSelf()
@ -154,7 +153,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Light> *ref = MWWorld::LiveCellRef<ESM::Light> *ref =
ptr.get<ESM::Light>(); ptr.get<ESM::Light>();
return ref->base->mIcon; return ref->mBase->mIcon;
} }
bool Light::hasToolTip (const MWWorld::Ptr& ptr) const bool Light::hasToolTip (const MWWorld::Ptr& ptr) const
@ -162,7 +161,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Light> *ref = MWWorld::LiveCellRef<ESM::Light> *ref =
ptr.get<ESM::Light>(); ptr.get<ESM::Light>();
return (ref->base->mName != ""); return (ref->mBase->mName != "");
} }
MWGui::ToolTipInfo Light::getToolTipInfo (const MWWorld::Ptr& ptr) const MWGui::ToolTipInfo Light::getToolTipInfo (const MWWorld::Ptr& ptr) const
@ -171,17 +170,17 @@ namespace MWClass
ptr.get<ESM::Light>(); ptr.get<ESM::Light>();
MWGui::ToolTipInfo info; MWGui::ToolTipInfo info;
info.caption = ref->base->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount()); info.caption = ref->mBase->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
info.icon = ref->base->mIcon; info.icon = ref->mBase->mIcon;
std::string text; std::string text;
text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->base->mData.mWeight); text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight);
text += MWGui::ToolTips::getValueString(ref->base->mData.mValue, "#{sValue}"); text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}");
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
text += MWGui::ToolTips::getMiscString(ref->ref.mOwner, "Owner"); text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner");
text += MWGui::ToolTips::getMiscString(ref->base->mScript, "Script"); text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
} }
info.text = text; info.text = text;
@ -204,6 +203,6 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Light> *ref = MWWorld::LiveCellRef<ESM::Light> *ref =
ptr.get<ESM::Light>(); ptr.get<ESM::Light>();
return MWWorld::Ptr(&cell.lights.insert(*ref), &cell); return MWWorld::Ptr(&cell.mLights.insert(*ref), &cell);
} }
} }

@ -34,18 +34,17 @@ namespace MWClass
void Lockpick::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const void Lockpick::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
{ {
const std::string model = getModel(ptr); const std::string model = getModel(ptr);
if(!model.empty()) { if(!model.empty())
physics.insertObjectPhysics(ptr, model); physics.addObject(ptr);
}
} }
std::string Lockpick::getModel(const MWWorld::Ptr &ptr) const std::string Lockpick::getModel(const MWWorld::Ptr &ptr) const
{ {
MWWorld::LiveCellRef<ESM::Tool> *ref = MWWorld::LiveCellRef<ESM::Tool> *ref =
ptr.get<ESM::Tool>(); ptr.get<ESM::Tool>();
assert(ref->base != NULL); assert(ref->mBase != NULL);
const std::string &model = ref->base->mModel; const std::string &model = ref->mBase->mModel;
if (!model.empty()) { if (!model.empty()) {
return "meshes\\" + model; return "meshes\\" + model;
} }
@ -57,7 +56,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Tool> *ref = MWWorld::LiveCellRef<ESM::Tool> *ref =
ptr.get<ESM::Tool>(); ptr.get<ESM::Tool>();
return ref->base->mName; return ref->mBase->mName;
} }
boost::shared_ptr<MWWorld::Action> Lockpick::activate (const MWWorld::Ptr& ptr, boost::shared_ptr<MWWorld::Action> Lockpick::activate (const MWWorld::Ptr& ptr,
@ -75,7 +74,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Tool> *ref = MWWorld::LiveCellRef<ESM::Tool> *ref =
ptr.get<ESM::Tool>(); ptr.get<ESM::Tool>();
return ref->base->mScript; return ref->mBase->mScript;
} }
std::pair<std::vector<int>, bool> Lockpick::getEquipmentSlots (const MWWorld::Ptr& ptr) const std::pair<std::vector<int>, bool> Lockpick::getEquipmentSlots (const MWWorld::Ptr& ptr) const
@ -92,7 +91,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Tool> *ref = MWWorld::LiveCellRef<ESM::Tool> *ref =
ptr.get<ESM::Tool>(); ptr.get<ESM::Tool>();
return ref->base->mData.mValue; return ref->mBase->mData.mValue;
} }
void Lockpick::registerSelf() void Lockpick::registerSelf()
@ -117,7 +116,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Tool> *ref = MWWorld::LiveCellRef<ESM::Tool> *ref =
ptr.get<ESM::Tool>(); ptr.get<ESM::Tool>();
return ref->base->mIcon; return ref->mBase->mIcon;
} }
bool Lockpick::hasToolTip (const MWWorld::Ptr& ptr) const bool Lockpick::hasToolTip (const MWWorld::Ptr& ptr) const
@ -125,7 +124,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Tool> *ref = MWWorld::LiveCellRef<ESM::Tool> *ref =
ptr.get<ESM::Tool>(); ptr.get<ESM::Tool>();
return (ref->base->mName != ""); return (ref->mBase->mName != "");
} }
MWGui::ToolTipInfo Lockpick::getToolTipInfo (const MWWorld::Ptr& ptr) const MWGui::ToolTipInfo Lockpick::getToolTipInfo (const MWWorld::Ptr& ptr) const
@ -134,21 +133,21 @@ namespace MWClass
ptr.get<ESM::Tool>(); ptr.get<ESM::Tool>();
MWGui::ToolTipInfo info; MWGui::ToolTipInfo info;
info.caption = ref->base->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount()); info.caption = ref->mBase->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
info.icon = ref->base->mIcon; info.icon = ref->mBase->mIcon;
std::string text; std::string text;
/// \todo store remaining uses somewhere /// \todo store remaining uses somewhere
text += "\n#{sUses}: " + MWGui::ToolTips::toString(ref->base->mData.mUses); text += "\n#{sUses}: " + MWGui::ToolTips::toString(ref->mBase->mData.mUses);
text += "\n#{sQuality}: " + MWGui::ToolTips::toString(ref->base->mData.mQuality); text += "\n#{sQuality}: " + MWGui::ToolTips::toString(ref->mBase->mData.mQuality);
text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->base->mData.mWeight); text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight);
text += MWGui::ToolTips::getValueString(ref->base->mData.mValue, "#{sValue}"); text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}");
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
text += MWGui::ToolTips::getMiscString(ref->ref.mOwner, "Owner"); text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner");
text += MWGui::ToolTips::getMiscString(ref->base->mScript, "Script"); text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
} }
info.text = text; info.text = text;
@ -171,6 +170,6 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Tool> *ref = MWWorld::LiveCellRef<ESM::Tool> *ref =
ptr.get<ESM::Tool>(); ptr.get<ESM::Tool>();
return MWWorld::Ptr(&cell.lockpicks.insert(*ref), &cell); return MWWorld::Ptr(&cell.mLockpicks.insert(*ref), &cell);
} }
} }

@ -37,18 +37,17 @@ namespace MWClass
void Miscellaneous::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const void Miscellaneous::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
{ {
const std::string model = getModel(ptr); const std::string model = getModel(ptr);
if(!model.empty()) { if(!model.empty())
physics.insertObjectPhysics(ptr, model); physics.addObject(ptr);
}
} }
std::string Miscellaneous::getModel(const MWWorld::Ptr &ptr) const std::string Miscellaneous::getModel(const MWWorld::Ptr &ptr) const
{ {
MWWorld::LiveCellRef<ESM::Miscellaneous> *ref = MWWorld::LiveCellRef<ESM::Miscellaneous> *ref =
ptr.get<ESM::Miscellaneous>(); ptr.get<ESM::Miscellaneous>();
assert(ref->base != NULL); assert(ref->mBase != NULL);
const std::string &model = ref->base->mModel; const std::string &model = ref->mBase->mModel;
if (!model.empty()) { if (!model.empty()) {
return "meshes\\" + model; return "meshes\\" + model;
} }
@ -60,7 +59,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Miscellaneous> *ref = MWWorld::LiveCellRef<ESM::Miscellaneous> *ref =
ptr.get<ESM::Miscellaneous>(); ptr.get<ESM::Miscellaneous>();
return ref->base->mName; return ref->mBase->mName;
} }
boost::shared_ptr<MWWorld::Action> Miscellaneous::activate (const MWWorld::Ptr& ptr, boost::shared_ptr<MWWorld::Action> Miscellaneous::activate (const MWWorld::Ptr& ptr,
@ -78,7 +77,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Miscellaneous> *ref = MWWorld::LiveCellRef<ESM::Miscellaneous> *ref =
ptr.get<ESM::Miscellaneous>(); ptr.get<ESM::Miscellaneous>();
return ref->base->mScript; return ref->mBase->mScript;
} }
int Miscellaneous::getValue (const MWWorld::Ptr& ptr) const int Miscellaneous::getValue (const MWWorld::Ptr& ptr) const
@ -86,7 +85,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Miscellaneous> *ref = MWWorld::LiveCellRef<ESM::Miscellaneous> *ref =
ptr.get<ESM::Miscellaneous>(); ptr.get<ESM::Miscellaneous>();
return ref->base->mData.mValue; return ref->mBase->mData.mValue;
} }
void Miscellaneous::registerSelf() void Miscellaneous::registerSelf()
@ -101,7 +100,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Miscellaneous> *ref = MWWorld::LiveCellRef<ESM::Miscellaneous> *ref =
ptr.get<ESM::Miscellaneous>(); ptr.get<ESM::Miscellaneous>();
if (ref->base->mName == MWBase::Environment::get().getWorld()->getStore().gameSettings.find("sGold")->getString()) if (ref->mBase->mName == MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("sGold")->getString())
{ {
return std::string("Item Gold Up"); return std::string("Item Gold Up");
} }
@ -113,7 +112,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Miscellaneous> *ref = MWWorld::LiveCellRef<ESM::Miscellaneous> *ref =
ptr.get<ESM::Miscellaneous>(); ptr.get<ESM::Miscellaneous>();
if (ref->base->mName == MWBase::Environment::get().getWorld()->getStore().gameSettings.find("sGold")->getString()) if (ref->mBase->mName == MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("sGold")->getString())
{ {
return std::string("Item Gold Down"); return std::string("Item Gold Down");
} }
@ -125,7 +124,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Miscellaneous> *ref = MWWorld::LiveCellRef<ESM::Miscellaneous> *ref =
ptr.get<ESM::Miscellaneous>(); ptr.get<ESM::Miscellaneous>();
return ref->base->mIcon; return ref->mBase->mIcon;
} }
bool Miscellaneous::hasToolTip (const MWWorld::Ptr& ptr) const bool Miscellaneous::hasToolTip (const MWWorld::Ptr& ptr) const
@ -133,7 +132,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Miscellaneous> *ref = MWWorld::LiveCellRef<ESM::Miscellaneous> *ref =
ptr.get<ESM::Miscellaneous>(); ptr.get<ESM::Miscellaneous>();
return (ref->base->mName != ""); return (ref->mBase->mName != "");
} }
MWGui::ToolTipInfo Miscellaneous::getToolTipInfo (const MWWorld::Ptr& ptr) const MWGui::ToolTipInfo Miscellaneous::getToolTipInfo (const MWWorld::Ptr& ptr) const
@ -143,13 +142,13 @@ namespace MWClass
MWGui::ToolTipInfo info; MWGui::ToolTipInfo info;
const ESMS::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
int count = ptr.getRefData().getCount(); int count = ptr.getRefData().getCount();
bool isGold = (ref->base->mName == store.gameSettings.find("sGold")->getString()); bool isGold = (ref->mBase->mName == store.get<ESM::GameSetting>().find("sGold")->getString());
if (isGold && count == 1) if (isGold && count == 1)
count = ref->base->mData.mValue; count = ref->mBase->mData.mValue;
std::string countString; std::string countString;
if (!isGold) if (!isGold)
@ -157,12 +156,12 @@ namespace MWClass
else // gold displays its count also if it's 1. else // gold displays its count also if it's 1.
countString = " (" + boost::lexical_cast<std::string>(count) + ")"; countString = " (" + boost::lexical_cast<std::string>(count) + ")";
info.caption = ref->base->mName + countString; info.caption = ref->mBase->mName + countString;
info.icon = ref->base->mIcon; info.icon = ref->mBase->mIcon;
if (ref->ref.mSoul != "") if (ref->mRef.mSoul != "")
{ {
const ESM::Creature *creature = store.creatures.search(ref->ref.mSoul); const ESM::Creature *creature = store.get<ESM::Creature>().find(ref->mRef.mSoul);
info.caption += " (" + creature->mName + ")"; info.caption += " (" + creature->mName + ")";
} }
@ -170,13 +169,13 @@ namespace MWClass
if (!isGold) if (!isGold)
{ {
text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->base->mData.mWeight); text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight);
text += MWGui::ToolTips::getValueString(ref->base->mData.mValue, "#{sValue}"); text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}");
} }
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
text += MWGui::ToolTips::getMiscString(ref->ref.mOwner, "Owner"); text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner");
text += MWGui::ToolTips::getMiscString(ref->base->mScript, "Script"); text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
} }
info.text = text; info.text = text;
@ -189,10 +188,10 @@ namespace MWClass
{ {
MWWorld::Ptr newPtr; MWWorld::Ptr newPtr;
const ESMS::ESMStore &store = const MWWorld::ESMStore &store =
MWBase::Environment::get().getWorld()->getStore(); MWBase::Environment::get().getWorld()->getStore();
if (MWWorld::Class::get(ptr).getName(ptr) == store.gameSettings.find("sGold")->getString()) { if (MWWorld::Class::get(ptr).getName(ptr) == store.get<ESM::GameSetting>().find("sGold")->getString()) {
int goldAmount = ptr.getRefData().getCount(); int goldAmount = ptr.getRefData().getCount();
std::string base = "Gold_001"; std::string base = "Gold_001";
@ -210,11 +209,11 @@ namespace MWClass
MWWorld::ManualRef newRef(store, base); MWWorld::ManualRef newRef(store, base);
MWWorld::LiveCellRef<ESM::Miscellaneous> *ref = MWWorld::LiveCellRef<ESM::Miscellaneous> *ref =
newRef.getPtr().get<ESM::Miscellaneous>(); newRef.getPtr().get<ESM::Miscellaneous>();
newPtr = MWWorld::Ptr(&cell.miscItems.insert(*ref), &cell); newPtr = MWWorld::Ptr(&cell.mMiscItems.insert(*ref), &cell);
} else { } else {
MWWorld::LiveCellRef<ESM::Miscellaneous> *ref = MWWorld::LiveCellRef<ESM::Miscellaneous> *ref =
ptr.get<ESM::Miscellaneous>(); ptr.get<ESM::Miscellaneous>();
newPtr = MWWorld::Ptr(&cell.miscItems.insert(*ref), &cell); newPtr = MWWorld::Ptr(&cell.mMiscItems.insert(*ref), &cell);
} }
return newPtr; return newPtr;
} }

@ -62,39 +62,41 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::NPC> *ref = ptr.get<ESM::NPC>(); MWWorld::LiveCellRef<ESM::NPC> *ref = ptr.get<ESM::NPC>();
// NPC stats // NPC stats
if (!ref->base->mFaction.empty()) if (!ref->mBase->mFaction.empty())
{ {
std::string faction = ref->base->mFaction; std::string faction = ref->mBase->mFaction;
boost::algorithm::to_lower(faction); boost::algorithm::to_lower(faction);
if(ref->base->mNpdt52.mGold != -10) if(ref->mBase->mNpdt52.mGold != -10)
{ {
data->mNpcStats.getFactionRanks()[faction] = (int)ref->base->mNpdt52.mRank; data->mNpcStats.getFactionRanks()[faction] = (int)ref->mBase->mNpdt52.mRank;
} }
else else
{ {
data->mNpcStats.getFactionRanks()[faction] = (int)ref->base->mNpdt12.mRank; data->mNpcStats.getFactionRanks()[faction] = (int)ref->mBase->mNpdt12.mRank;
} }
} }
// creature stats // creature stats
if(ref->base->mNpdt52.mGold != -10) if(ref->mBase->mNpdt52.mGold != -10)
{ {
for (int i=0; i<27; ++i) for (int i=0; i<27; ++i)
data->mNpcStats.getSkill (i).setBase (ref->base->mNpdt52.mSkills[i]); data->mNpcStats.getSkill (i).setBase (ref->mBase->mNpdt52.mSkills[i]);
data->mCreatureStats.getAttribute(0).set (ref->base->mNpdt52.mStrength); data->mCreatureStats.getAttribute(0).set (ref->mBase->mNpdt52.mStrength);
data->mCreatureStats.getAttribute(1).set (ref->base->mNpdt52.mIntelligence); data->mCreatureStats.getAttribute(1).set (ref->mBase->mNpdt52.mIntelligence);
data->mCreatureStats.getAttribute(2).set (ref->base->mNpdt52.mWillpower); data->mCreatureStats.getAttribute(2).set (ref->mBase->mNpdt52.mWillpower);
data->mCreatureStats.getAttribute(3).set (ref->base->mNpdt52.mAgility); data->mCreatureStats.getAttribute(3).set (ref->mBase->mNpdt52.mAgility);
data->mCreatureStats.getAttribute(4).set (ref->base->mNpdt52.mSpeed); data->mCreatureStats.getAttribute(4).set (ref->mBase->mNpdt52.mSpeed);
data->mCreatureStats.getAttribute(5).set (ref->base->mNpdt52.mEndurance); data->mCreatureStats.getAttribute(5).set (ref->mBase->mNpdt52.mEndurance);
data->mCreatureStats.getAttribute(6).set (ref->base->mNpdt52.mPersonality); data->mCreatureStats.getAttribute(6).set (ref->mBase->mNpdt52.mPersonality);
data->mCreatureStats.getAttribute(7).set (ref->base->mNpdt52.mLuck); data->mCreatureStats.getAttribute(7).set (ref->mBase->mNpdt52.mLuck);
data->mCreatureStats.setHealth (ref->base->mNpdt52.mHealth); data->mCreatureStats.setHealth (ref->mBase->mNpdt52.mHealth);
data->mCreatureStats.setMagicka (ref->base->mNpdt52.mMana); data->mCreatureStats.setMagicka (ref->mBase->mNpdt52.mMana);
data->mCreatureStats.setFatigue (ref->base->mNpdt52.mFatigue); data->mCreatureStats.setFatigue (ref->mBase->mNpdt52.mFatigue);
data->mCreatureStats.setLevel(ref->base->mNpdt52.mLevel); data->mCreatureStats.setLevel(ref->mBase->mNpdt52.mLevel);
data->mNpcStats.setBaseDisposition(ref->mBase->mNpdt52.mDisposition);
data->mNpcStats.setReputation(ref->mBase->mNpdt52.mReputation);
} }
else else
{ {
@ -108,14 +110,14 @@ namespace MWClass
data->mCreatureStats.setLevel (1); data->mCreatureStats.setLevel (1);
} }
data->mCreatureStats.setHello(ref->base->mAiData.mHello); data->mCreatureStats.setAiSetting (0, ref->mBase->mAiData.mHello);
data->mCreatureStats.setFight(ref->base->mAiData.mFight); data->mCreatureStats.setAiSetting (1, ref->mBase->mAiData.mFight);
data->mCreatureStats.setFlee(ref->base->mAiData.mFlee); data->mCreatureStats.setAiSetting (2, ref->mBase->mAiData.mFlee);
data->mCreatureStats.setAlarm(ref->base->mAiData.mAlarm); data->mCreatureStats.setAiSetting (3, ref->mBase->mAiData.mAlarm);
// spells // spells
for (std::vector<std::string>::const_iterator iter (ref->base->mSpells.mList.begin()); for (std::vector<std::string>::const_iterator iter (ref->mBase->mSpells.mList.begin());
iter!=ref->base->mSpells.mList.end(); ++iter) iter!=ref->mBase->mSpells.mList.end(); ++iter)
data->mCreatureStats.getSpells().add (*iter); data->mCreatureStats.getSpells().add (*iter);
// store // store
@ -128,7 +130,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::NPC> *ref = MWWorld::LiveCellRef<ESM::NPC> *ref =
ptr.get<ESM::NPC>(); ptr.get<ESM::NPC>();
return ref->base->mId; return ref->mBase->mId;
} }
void Npc::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const void Npc::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
@ -138,7 +140,7 @@ namespace MWClass
void Npc::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const void Npc::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
{ {
physics.insertActorPhysics(ptr, getModel(ptr)); physics.addActor(ptr);
MWBase::Environment::get().getMechanicsManager()->addActor(ptr); MWBase::Environment::get().getMechanicsManager()->addActor(ptr);
} }
@ -146,9 +148,9 @@ namespace MWClass
{ {
MWWorld::LiveCellRef<ESM::NPC> *ref = MWWorld::LiveCellRef<ESM::NPC> *ref =
ptr.get<ESM::NPC>(); ptr.get<ESM::NPC>();
assert(ref->base != NULL); assert(ref->mBase != NULL);
std::string headID = ref->base->mHead; std::string headID = ref->mBase->mHead;
int end = headID.find_last_of("head_") - 4; int end = headID.find_last_of("head_") - 4;
std::string bodyRaceID = headID.substr(0, end); std::string bodyRaceID = headID.substr(0, end);
@ -170,7 +172,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::NPC> *ref = MWWorld::LiveCellRef<ESM::NPC> *ref =
ptr.get<ESM::NPC>(); ptr.get<ESM::NPC>();
return ref->base->mName; return ref->mBase->mName;
} }
MWMechanics::CreatureStats& Npc::getCreatureStats (const MWWorld::Ptr& ptr) const MWMechanics::CreatureStats& Npc::getCreatureStats (const MWWorld::Ptr& ptr) const
@ -217,7 +219,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::NPC> *ref = MWWorld::LiveCellRef<ESM::NPC> *ref =
ptr.get<ESM::NPC>(); ptr.get<ESM::NPC>();
return ref->base->mScript; return ref->mBase->mScript;
} }
void Npc::setForceStance (const MWWorld::Ptr& ptr, Stance stance, bool force) const void Npc::setForceStance (const MWWorld::Ptr& ptr, Stance stance, bool force) const
@ -325,7 +327,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::NPC> *ref = MWWorld::LiveCellRef<ESM::NPC> *ref =
ptr.get<ESM::NPC>(); ptr.get<ESM::NPC>();
return ref->base->mFlags & ESM::NPC::Essential; return ref->mBase->mFlags & ESM::NPC::Essential;
} }
void Npc::registerSelf() void Npc::registerSelf()
@ -347,11 +349,11 @@ namespace MWClass
ptr.get<ESM::NPC>(); ptr.get<ESM::NPC>();
MWGui::ToolTipInfo info; MWGui::ToolTipInfo info;
info.caption = ref->base->mName; info.caption = ref->mBase->mName;
std::string text; std::string text;
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) if (MWBase::Environment::get().getWindowManager()->getFullHelp())
text += MWGui::ToolTips::getMiscString(ref->base->mScript, "Script"); text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
info.text = text; info.text = text;
return info; return info;
@ -395,8 +397,10 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::NPC> *ref = ptr.get<ESM::NPC>(); MWWorld::LiveCellRef<ESM::NPC> *ref = ptr.get<ESM::NPC>();
const ESM::Class *class_ = MWBase::Environment::get().getWorld()->getStore().classes.find ( const ESM::Class *class_ =
ref->base->mClass); MWBase::Environment::get().getWorld()->getStore().get<ESM::Class>().find (
ref->mBase->mClass
);
stats.useSkill (skill, *class_, usageType); stats.useSkill (skill, *class_, usageType);
} }
@ -413,6 +417,6 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::NPC> *ref = MWWorld::LiveCellRef<ESM::NPC> *ref =
ptr.get<ESM::NPC>(); ptr.get<ESM::NPC>();
return MWWorld::Ptr(&cell.npcs.insert(*ref), &cell); return MWWorld::Ptr(&cell.mNpcs.insert(*ref), &cell);
} }
} }

@ -34,18 +34,17 @@ namespace MWClass
void Potion::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const void Potion::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
{ {
const std::string model = getModel(ptr); const std::string model = getModel(ptr);
if(!model.empty()) { if(!model.empty())
physics.insertObjectPhysics(ptr, model); physics.addObject(ptr);
}
} }
std::string Potion::getModel(const MWWorld::Ptr &ptr) const std::string Potion::getModel(const MWWorld::Ptr &ptr) const
{ {
MWWorld::LiveCellRef<ESM::Potion> *ref = MWWorld::LiveCellRef<ESM::Potion> *ref =
ptr.get<ESM::Potion>(); ptr.get<ESM::Potion>();
assert(ref->base != NULL); assert(ref->mBase != NULL);
const std::string &model = ref->base->mModel; const std::string &model = ref->mBase->mModel;
if (!model.empty()) { if (!model.empty()) {
return "meshes\\" + model; return "meshes\\" + model;
} }
@ -57,7 +56,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Potion> *ref = MWWorld::LiveCellRef<ESM::Potion> *ref =
ptr.get<ESM::Potion>(); ptr.get<ESM::Potion>();
return ref->base->mName; return ref->mBase->mName;
} }
boost::shared_ptr<MWWorld::Action> Potion::activate (const MWWorld::Ptr& ptr, boost::shared_ptr<MWWorld::Action> Potion::activate (const MWWorld::Ptr& ptr,
@ -76,7 +75,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Potion> *ref = MWWorld::LiveCellRef<ESM::Potion> *ref =
ptr.get<ESM::Potion>(); ptr.get<ESM::Potion>();
return ref->base->mScript; return ref->mBase->mScript;
} }
int Potion::getValue (const MWWorld::Ptr& ptr) const int Potion::getValue (const MWWorld::Ptr& ptr) const
@ -84,7 +83,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Potion> *ref = MWWorld::LiveCellRef<ESM::Potion> *ref =
ptr.get<ESM::Potion>(); ptr.get<ESM::Potion>();
return ref->base->mData.mValue; return ref->mBase->mData.mValue;
} }
void Potion::registerSelf() void Potion::registerSelf()
@ -109,7 +108,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Potion> *ref = MWWorld::LiveCellRef<ESM::Potion> *ref =
ptr.get<ESM::Potion>(); ptr.get<ESM::Potion>();
return ref->base->mIcon; return ref->mBase->mIcon;
} }
bool Potion::hasToolTip (const MWWorld::Ptr& ptr) const bool Potion::hasToolTip (const MWWorld::Ptr& ptr) const
@ -117,7 +116,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Potion> *ref = MWWorld::LiveCellRef<ESM::Potion> *ref =
ptr.get<ESM::Potion>(); ptr.get<ESM::Potion>();
return (ref->base->mName != ""); return (ref->mBase->mName != "");
} }
MWGui::ToolTipInfo Potion::getToolTipInfo (const MWWorld::Ptr& ptr) const MWGui::ToolTipInfo Potion::getToolTipInfo (const MWWorld::Ptr& ptr) const
@ -126,20 +125,20 @@ namespace MWClass
ptr.get<ESM::Potion>(); ptr.get<ESM::Potion>();
MWGui::ToolTipInfo info; MWGui::ToolTipInfo info;
info.caption = ref->base->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount()); info.caption = ref->mBase->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
info.icon = ref->base->mIcon; info.icon = ref->mBase->mIcon;
std::string text; std::string text;
text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->base->mData.mWeight); text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight);
text += MWGui::ToolTips::getValueString(ref->base->mData.mValue, "#{sValue}"); text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}");
info.effects = MWGui::Widgets::MWEffectList::effectListFromESM(&ref->base->mEffects); info.effects = MWGui::Widgets::MWEffectList::effectListFromESM(&ref->mBase->mEffects);
info.isPotion = true; info.isPotion = true;
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
text += MWGui::ToolTips::getMiscString(ref->ref.mOwner, "Owner"); text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner");
text += MWGui::ToolTips::getMiscString(ref->base->mScript, "Script"); text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
} }
info.text = text; info.text = text;
@ -157,7 +156,7 @@ namespace MWClass
MWWorld::Ptr actor = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); MWWorld::Ptr actor = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
boost::shared_ptr<MWWorld::Action> action ( boost::shared_ptr<MWWorld::Action> action (
new MWWorld::ActionApply (actor, ref->base->mId)); new MWWorld::ActionApply (actor, ref->mBase->mId));
action->setSound ("Drink"); action->setSound ("Drink");
@ -170,6 +169,6 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Potion> *ref = MWWorld::LiveCellRef<ESM::Potion> *ref =
ptr.get<ESM::Potion>(); ptr.get<ESM::Potion>();
return MWWorld::Ptr(&cell.potions.insert(*ref), &cell); return MWWorld::Ptr(&cell.mPotions.insert(*ref), &cell);
} }
} }

@ -34,18 +34,17 @@ namespace MWClass
void Probe::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const void Probe::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
{ {
const std::string model = getModel(ptr); const std::string model = getModel(ptr);
if(!model.empty()) { if(!model.empty())
physics.insertObjectPhysics(ptr, model); physics.addObject(ptr);
}
} }
std::string Probe::getModel(const MWWorld::Ptr &ptr) const std::string Probe::getModel(const MWWorld::Ptr &ptr) const
{ {
MWWorld::LiveCellRef<ESM::Probe> *ref = MWWorld::LiveCellRef<ESM::Probe> *ref =
ptr.get<ESM::Probe>(); ptr.get<ESM::Probe>();
assert(ref->base != NULL); assert(ref->mBase != NULL);
const std::string &model = ref->base->mModel; const std::string &model = ref->mBase->mModel;
if (!model.empty()) { if (!model.empty()) {
return "meshes\\" + model; return "meshes\\" + model;
} }
@ -57,7 +56,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Probe> *ref = MWWorld::LiveCellRef<ESM::Probe> *ref =
ptr.get<ESM::Probe>(); ptr.get<ESM::Probe>();
return ref->base->mName; return ref->mBase->mName;
} }
boost::shared_ptr<MWWorld::Action> Probe::activate (const MWWorld::Ptr& ptr, boost::shared_ptr<MWWorld::Action> Probe::activate (const MWWorld::Ptr& ptr,
const MWWorld::Ptr& actor) const const MWWorld::Ptr& actor) const
@ -74,7 +73,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Probe> *ref = MWWorld::LiveCellRef<ESM::Probe> *ref =
ptr.get<ESM::Probe>(); ptr.get<ESM::Probe>();
return ref->base->mScript; return ref->mBase->mScript;
} }
std::pair<std::vector<int>, bool> Probe::getEquipmentSlots (const MWWorld::Ptr& ptr) const std::pair<std::vector<int>, bool> Probe::getEquipmentSlots (const MWWorld::Ptr& ptr) const
@ -91,7 +90,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Probe> *ref = MWWorld::LiveCellRef<ESM::Probe> *ref =
ptr.get<ESM::Probe>(); ptr.get<ESM::Probe>();
return ref->base->mData.mValue; return ref->mBase->mData.mValue;
} }
void Probe::registerSelf() void Probe::registerSelf()
@ -116,7 +115,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Probe> *ref = MWWorld::LiveCellRef<ESM::Probe> *ref =
ptr.get<ESM::Probe>(); ptr.get<ESM::Probe>();
return ref->base->mIcon; return ref->mBase->mIcon;
} }
bool Probe::hasToolTip (const MWWorld::Ptr& ptr) const bool Probe::hasToolTip (const MWWorld::Ptr& ptr) const
@ -124,7 +123,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Probe> *ref = MWWorld::LiveCellRef<ESM::Probe> *ref =
ptr.get<ESM::Probe>(); ptr.get<ESM::Probe>();
return (ref->base->mName != ""); return (ref->mBase->mName != "");
} }
MWGui::ToolTipInfo Probe::getToolTipInfo (const MWWorld::Ptr& ptr) const MWGui::ToolTipInfo Probe::getToolTipInfo (const MWWorld::Ptr& ptr) const
@ -133,21 +132,21 @@ namespace MWClass
ptr.get<ESM::Probe>(); ptr.get<ESM::Probe>();
MWGui::ToolTipInfo info; MWGui::ToolTipInfo info;
info.caption = ref->base->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount()); info.caption = ref->mBase->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
info.icon = ref->base->mIcon; info.icon = ref->mBase->mIcon;
std::string text; std::string text;
/// \todo store remaining uses somewhere /// \todo store remaining uses somewhere
text += "\n#{sUses}: " + MWGui::ToolTips::toString(ref->base->mData.mUses); text += "\n#{sUses}: " + MWGui::ToolTips::toString(ref->mBase->mData.mUses);
text += "\n#{sQuality}: " + MWGui::ToolTips::toString(ref->base->mData.mQuality); text += "\n#{sQuality}: " + MWGui::ToolTips::toString(ref->mBase->mData.mQuality);
text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->base->mData.mWeight); text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight);
text += MWGui::ToolTips::getValueString(ref->base->mData.mValue, "#{sValue}"); text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}");
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
text += MWGui::ToolTips::getMiscString(ref->ref.mOwner, "Owner"); text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner");
text += MWGui::ToolTips::getMiscString(ref->base->mScript, "Script"); text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
} }
info.text = text; info.text = text;
@ -170,6 +169,6 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Probe> *ref = MWWorld::LiveCellRef<ESM::Probe> *ref =
ptr.get<ESM::Probe>(); ptr.get<ESM::Probe>();
return MWWorld::Ptr(&cell.probes.insert(*ref), &cell); return MWWorld::Ptr(&cell.mProbes.insert(*ref), &cell);
} }
} }

@ -32,18 +32,17 @@ namespace MWClass
void Repair::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const void Repair::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
{ {
const std::string model = getModel(ptr); const std::string model = getModel(ptr);
if(!model.empty()) { if(!model.empty())
physics.insertObjectPhysics(ptr, model); physics.addObject(ptr);
}
} }
std::string Repair::getModel(const MWWorld::Ptr &ptr) const std::string Repair::getModel(const MWWorld::Ptr &ptr) const
{ {
MWWorld::LiveCellRef<ESM::Repair> *ref = MWWorld::LiveCellRef<ESM::Repair> *ref =
ptr.get<ESM::Repair>(); ptr.get<ESM::Repair>();
assert(ref->base != NULL); assert(ref->mBase != NULL);
const std::string &model = ref->base->mModel; const std::string &model = ref->mBase->mModel;
if (!model.empty()) { if (!model.empty()) {
return "meshes\\" + model; return "meshes\\" + model;
} }
@ -55,7 +54,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Repair> *ref = MWWorld::LiveCellRef<ESM::Repair> *ref =
ptr.get<ESM::Repair>(); ptr.get<ESM::Repair>();
return ref->base->mName; return ref->mBase->mName;
} }
boost::shared_ptr<MWWorld::Action> Repair::activate (const MWWorld::Ptr& ptr, boost::shared_ptr<MWWorld::Action> Repair::activate (const MWWorld::Ptr& ptr,
@ -73,7 +72,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Repair> *ref = MWWorld::LiveCellRef<ESM::Repair> *ref =
ptr.get<ESM::Repair>(); ptr.get<ESM::Repair>();
return ref->base->mScript; return ref->mBase->mScript;
} }
int Repair::getValue (const MWWorld::Ptr& ptr) const int Repair::getValue (const MWWorld::Ptr& ptr) const
@ -81,7 +80,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Repair> *ref = MWWorld::LiveCellRef<ESM::Repair> *ref =
ptr.get<ESM::Repair>(); ptr.get<ESM::Repair>();
return ref->base->mData.mValue; return ref->mBase->mData.mValue;
} }
void Repair::registerSelf() void Repair::registerSelf()
@ -106,7 +105,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Repair> *ref = MWWorld::LiveCellRef<ESM::Repair> *ref =
ptr.get<ESM::Repair>(); ptr.get<ESM::Repair>();
return ref->base->mIcon; return ref->mBase->mIcon;
} }
bool Repair::hasToolTip (const MWWorld::Ptr& ptr) const bool Repair::hasToolTip (const MWWorld::Ptr& ptr) const
@ -114,7 +113,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Repair> *ref = MWWorld::LiveCellRef<ESM::Repair> *ref =
ptr.get<ESM::Repair>(); ptr.get<ESM::Repair>();
return (ref->base->mName != ""); return (ref->mBase->mName != "");
} }
MWGui::ToolTipInfo Repair::getToolTipInfo (const MWWorld::Ptr& ptr) const MWGui::ToolTipInfo Repair::getToolTipInfo (const MWWorld::Ptr& ptr) const
@ -123,21 +122,21 @@ namespace MWClass
ptr.get<ESM::Repair>(); ptr.get<ESM::Repair>();
MWGui::ToolTipInfo info; MWGui::ToolTipInfo info;
info.caption = ref->base->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount()); info.caption = ref->mBase->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
info.icon = ref->base->mIcon; info.icon = ref->mBase->mIcon;
std::string text; std::string text;
/// \todo store remaining uses somewhere /// \todo store remaining uses somewhere
text += "\n#{sUses}: " + MWGui::ToolTips::toString(ref->base->mData.mUses); text += "\n#{sUses}: " + MWGui::ToolTips::toString(ref->mBase->mData.mUses);
text += "\n#{sQuality}: " + MWGui::ToolTips::toString(ref->base->mData.mQuality); text += "\n#{sQuality}: " + MWGui::ToolTips::toString(ref->mBase->mData.mQuality);
text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->base->mData.mWeight); text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight);
text += MWGui::ToolTips::getValueString(ref->base->mData.mValue, "#{sValue}"); text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}");
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
text += MWGui::ToolTips::getMiscString(ref->ref.mOwner, "Owner"); text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner");
text += MWGui::ToolTips::getMiscString(ref->base->mScript, "Script"); text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
} }
info.text = text; info.text = text;
@ -151,6 +150,6 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Repair> *ref = MWWorld::LiveCellRef<ESM::Repair> *ref =
ptr.get<ESM::Repair>(); ptr.get<ESM::Repair>();
return MWWorld::Ptr(&cell.repairs.insert(*ref), &cell); return MWWorld::Ptr(&cell.mRepairs.insert(*ref), &cell);
} }
} }

@ -24,18 +24,17 @@ namespace MWClass
void Static::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const void Static::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
{ {
const std::string model = getModel(ptr); const std::string model = getModel(ptr);
if(!model.empty()) { if(!model.empty())
physics.insertObjectPhysics(ptr, model); physics.addObject(ptr);
}
} }
std::string Static::getModel(const MWWorld::Ptr &ptr) const std::string Static::getModel(const MWWorld::Ptr &ptr) const
{ {
MWWorld::LiveCellRef<ESM::Static> *ref = MWWorld::LiveCellRef<ESM::Static> *ref =
ptr.get<ESM::Static>(); ptr.get<ESM::Static>();
assert(ref->base != NULL); assert(ref->mBase != NULL);
const std::string &model = ref->base->mModel; const std::string &model = ref->mBase->mModel;
if (!model.empty()) { if (!model.empty()) {
return "meshes\\" + model; return "meshes\\" + model;
} }
@ -60,6 +59,6 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Static> *ref = MWWorld::LiveCellRef<ESM::Static> *ref =
ptr.get<ESM::Static>(); ptr.get<ESM::Static>();
return MWWorld::Ptr(&cell.statics.insert(*ref), &cell); return MWWorld::Ptr(&cell.mStatics.insert(*ref), &cell);
} }
} }

@ -34,18 +34,17 @@ namespace MWClass
void Weapon::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const void Weapon::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
{ {
const std::string model = getModel(ptr); const std::string model = getModel(ptr);
if(!model.empty()) { if(!model.empty())
physics.insertObjectPhysics(ptr, model); physics.addObject(ptr);
}
} }
std::string Weapon::getModel(const MWWorld::Ptr &ptr) const std::string Weapon::getModel(const MWWorld::Ptr &ptr) const
{ {
MWWorld::LiveCellRef<ESM::Weapon> *ref = MWWorld::LiveCellRef<ESM::Weapon> *ref =
ptr.get<ESM::Weapon>(); ptr.get<ESM::Weapon>();
assert(ref->base != NULL); assert(ref->mBase != NULL);
const std::string &model = ref->base->mModel; const std::string &model = ref->mBase->mModel;
if (!model.empty()) { if (!model.empty()) {
return "meshes\\" + model; return "meshes\\" + model;
} }
@ -57,7 +56,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Weapon> *ref = MWWorld::LiveCellRef<ESM::Weapon> *ref =
ptr.get<ESM::Weapon>(); ptr.get<ESM::Weapon>();
return ref->base->mName; return ref->mBase->mName;
} }
boost::shared_ptr<MWWorld::Action> Weapon::activate (const MWWorld::Ptr& ptr, boost::shared_ptr<MWWorld::Action> Weapon::activate (const MWWorld::Ptr& ptr,
@ -80,7 +79,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Weapon> *ref = MWWorld::LiveCellRef<ESM::Weapon> *ref =
ptr.get<ESM::Weapon>(); ptr.get<ESM::Weapon>();
return ref->base->mData.mHealth; return ref->mBase->mData.mHealth;
} }
std::string Weapon::getScript (const MWWorld::Ptr& ptr) const std::string Weapon::getScript (const MWWorld::Ptr& ptr) const
@ -88,7 +87,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Weapon> *ref = MWWorld::LiveCellRef<ESM::Weapon> *ref =
ptr.get<ESM::Weapon>(); ptr.get<ESM::Weapon>();
return ref->base->mScript; return ref->mBase->mScript;
} }
std::pair<std::vector<int>, bool> Weapon::getEquipmentSlots (const MWWorld::Ptr& ptr) const std::pair<std::vector<int>, bool> Weapon::getEquipmentSlots (const MWWorld::Ptr& ptr) const
@ -99,12 +98,12 @@ namespace MWClass
std::vector<int> slots; std::vector<int> slots;
bool stack = false; bool stack = false;
if (ref->base->mData.mType==ESM::Weapon::Arrow || ref->base->mData.mType==ESM::Weapon::Bolt) if (ref->mBase->mData.mType==ESM::Weapon::Arrow || ref->mBase->mData.mType==ESM::Weapon::Bolt)
{ {
slots.push_back (int (MWWorld::InventoryStore::Slot_Ammunition)); slots.push_back (int (MWWorld::InventoryStore::Slot_Ammunition));
stack = true; stack = true;
} }
else if (ref->base->mData.mType==ESM::Weapon::MarksmanThrown) else if (ref->mBase->mData.mType==ESM::Weapon::MarksmanThrown)
{ {
slots.push_back (int (MWWorld::InventoryStore::Slot_CarriedRight)); slots.push_back (int (MWWorld::InventoryStore::Slot_CarriedRight));
stack = true; stack = true;
@ -139,7 +138,7 @@ namespace MWClass
}; };
for (int i=0; i<size; ++i) for (int i=0; i<size; ++i)
if (sMapping[i][0]==ref->base->mData.mType) if (sMapping[i][0]==ref->mBase->mData.mType)
return sMapping[i][1]; return sMapping[i][1];
return -1; return -1;
@ -150,7 +149,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Weapon> *ref = MWWorld::LiveCellRef<ESM::Weapon> *ref =
ptr.get<ESM::Weapon>(); ptr.get<ESM::Weapon>();
return ref->base->mData.mValue; return ref->mBase->mData.mValue;
} }
void Weapon::registerSelf() void Weapon::registerSelf()
@ -165,7 +164,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Weapon> *ref = MWWorld::LiveCellRef<ESM::Weapon> *ref =
ptr.get<ESM::Weapon>(); ptr.get<ESM::Weapon>();
int type = ref->base->mData.mType; int type = ref->mBase->mData.mType;
// Ammo // Ammo
if (type == 12 || type == 13) if (type == 12 || type == 13)
{ {
@ -211,7 +210,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Weapon> *ref = MWWorld::LiveCellRef<ESM::Weapon> *ref =
ptr.get<ESM::Weapon>(); ptr.get<ESM::Weapon>();
int type = ref->base->mData.mType; int type = ref->mBase->mData.mType;
// Ammo // Ammo
if (type == 12 || type == 13) if (type == 12 || type == 13)
{ {
@ -257,7 +256,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Weapon> *ref = MWWorld::LiveCellRef<ESM::Weapon> *ref =
ptr.get<ESM::Weapon>(); ptr.get<ESM::Weapon>();
return ref->base->mIcon; return ref->mBase->mIcon;
} }
bool Weapon::hasToolTip (const MWWorld::Ptr& ptr) const bool Weapon::hasToolTip (const MWWorld::Ptr& ptr) const
@ -265,7 +264,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Weapon> *ref = MWWorld::LiveCellRef<ESM::Weapon> *ref =
ptr.get<ESM::Weapon>(); ptr.get<ESM::Weapon>();
return (ref->base->mName != ""); return (ref->mBase->mName != "");
} }
MWGui::ToolTipInfo Weapon::getToolTipInfo (const MWWorld::Ptr& ptr) const MWGui::ToolTipInfo Weapon::getToolTipInfo (const MWWorld::Ptr& ptr) const
@ -274,15 +273,15 @@ namespace MWClass
ptr.get<ESM::Weapon>(); ptr.get<ESM::Weapon>();
MWGui::ToolTipInfo info; MWGui::ToolTipInfo info;
info.caption = ref->base->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount()); info.caption = ref->mBase->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
info.icon = ref->base->mIcon; info.icon = ref->mBase->mIcon;
const ESMS::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
std::string text; std::string text;
// weapon type & damage. arrows / bolts don't have his info. // weapon type & damage. arrows / bolts don't have his info.
if (ref->base->mData.mType < 12) if (ref->mBase->mData.mType < 12)
{ {
text += "\n#{sType} "; text += "\n#{sType} ";
@ -300,49 +299,49 @@ namespace MWClass
mapping[ESM::Weapon::MarksmanCrossbow] = std::make_pair("sSkillMarksman", ""); mapping[ESM::Weapon::MarksmanCrossbow] = std::make_pair("sSkillMarksman", "");
mapping[ESM::Weapon::MarksmanThrown] = std::make_pair("sSkillMarksman", ""); mapping[ESM::Weapon::MarksmanThrown] = std::make_pair("sSkillMarksman", "");
std::string type = mapping[ref->base->mData.mType].first; std::string type = mapping[ref->mBase->mData.mType].first;
std::string oneOrTwoHanded = mapping[ref->base->mData.mType].second; std::string oneOrTwoHanded = mapping[ref->mBase->mData.mType].second;
text += store.gameSettings.find(type)->getString() + text += store.get<ESM::GameSetting>().find(type)->getString() +
((oneOrTwoHanded != "") ? ", " + store.gameSettings.find(oneOrTwoHanded)->getString() : ""); ((oneOrTwoHanded != "") ? ", " + store.get<ESM::GameSetting>().find(oneOrTwoHanded)->getString() : "");
// weapon damage // weapon damage
if (ref->base->mData.mType >= 9) if (ref->mBase->mData.mType >= 9)
{ {
// marksman // marksman
text += "\n#{sAttack}: " text += "\n#{sAttack}: "
+ MWGui::ToolTips::toString(static_cast<int>(ref->base->mData.mChop[0])) + MWGui::ToolTips::toString(static_cast<int>(ref->mBase->mData.mChop[0]))
+ " - " + MWGui::ToolTips::toString(static_cast<int>(ref->base->mData.mChop[1])); + " - " + MWGui::ToolTips::toString(static_cast<int>(ref->mBase->mData.mChop[1]));
} }
else else
{ {
// Chop // Chop
text += "\n#{sChop}: " text += "\n#{sChop}: "
+ MWGui::ToolTips::toString(static_cast<int>(ref->base->mData.mChop[0])) + MWGui::ToolTips::toString(static_cast<int>(ref->mBase->mData.mChop[0]))
+ " - " + MWGui::ToolTips::toString(static_cast<int>(ref->base->mData.mChop[1])); + " - " + MWGui::ToolTips::toString(static_cast<int>(ref->mBase->mData.mChop[1]));
// Slash // Slash
text += "\n#{sSlash}: " text += "\n#{sSlash}: "
+ MWGui::ToolTips::toString(static_cast<int>(ref->base->mData.mSlash[0])) + MWGui::ToolTips::toString(static_cast<int>(ref->mBase->mData.mSlash[0]))
+ " - " + MWGui::ToolTips::toString(static_cast<int>(ref->base->mData.mSlash[1])); + " - " + MWGui::ToolTips::toString(static_cast<int>(ref->mBase->mData.mSlash[1]));
// Thrust // Thrust
text += "\n#{sThrust}: " text += "\n#{sThrust}: "
+ MWGui::ToolTips::toString(static_cast<int>(ref->base->mData.mThrust[0])) + MWGui::ToolTips::toString(static_cast<int>(ref->mBase->mData.mThrust[0]))
+ " - " + MWGui::ToolTips::toString(static_cast<int>(ref->base->mData.mThrust[1])); + " - " + MWGui::ToolTips::toString(static_cast<int>(ref->mBase->mData.mThrust[1]));
} }
} }
/// \todo store the current weapon health somewhere /// \todo store the current weapon health somewhere
if (ref->base->mData.mType < 11) // thrown weapons and arrows/bolts don't have health, only quantity if (ref->mBase->mData.mType < 11) // thrown weapons and arrows/bolts don't have health, only quantity
text += "\n#{sCondition}: " + MWGui::ToolTips::toString(ref->base->mData.mHealth); text += "\n#{sCondition}: " + MWGui::ToolTips::toString(ref->mBase->mData.mHealth);
text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->base->mData.mWeight); text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight);
text += MWGui::ToolTips::getValueString(ref->base->mData.mValue, "#{sValue}"); text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}");
info.enchant = ref->base->mEnchant; info.enchant = ref->mBase->mEnchant;
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
text += MWGui::ToolTips::getMiscString(ref->ref.mOwner, "Owner"); text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner");
text += MWGui::ToolTips::getMiscString(ref->base->mScript, "Script"); text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
} }
info.text = text; info.text = text;
@ -355,7 +354,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Weapon> *ref = MWWorld::LiveCellRef<ESM::Weapon> *ref =
ptr.get<ESM::Weapon>(); ptr.get<ESM::Weapon>();
return ref->base->mEnchant; return ref->mBase->mEnchant;
} }
boost::shared_ptr<MWWorld::Action> Weapon::use (const MWWorld::Ptr& ptr) const boost::shared_ptr<MWWorld::Action> Weapon::use (const MWWorld::Ptr& ptr) const
@ -373,6 +372,6 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Weapon> *ref = MWWorld::LiveCellRef<ESM::Weapon> *ref =
ptr.get<ESM::Weapon>(); ptr.get<ESM::Weapon>();
return MWWorld::Ptr(&cell.weapons.insert(*ref), &cell); return MWWorld::Ptr(&cell.mWeapons.insert(*ref), &cell);
} }
} }

@ -6,42 +6,44 @@
#include <iterator> #include <iterator>
#include <components/esm/loaddial.hpp> #include <components/esm/loaddial.hpp>
#include <components/esm/loadinfo.hpp>
#include <components/esm_store/store.hpp> #include <components/compiler/exception.hpp>
#include <components/compiler/errorhandler.hpp>
#include <components/compiler/scanner.hpp>
#include <components/compiler/locals.hpp>
#include <components/compiler/output.hpp>
#include <components/compiler/scriptparser.hpp>
#include <components/interpreter/interpreter.hpp>
#include <components/interpreter/defines.hpp>
#include "../mwbase/environment.hpp" #include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp" #include "../mwbase/world.hpp"
#include "../mwbase/scriptmanager.hpp" #include "../mwbase/scriptmanager.hpp"
#include "../mwbase/journal.hpp"
#include "../mwbase/windowmanager.hpp" #include "../mwbase/windowmanager.hpp"
#include "../mwbase/mechanicsmanager.hpp"
#include "../mwworld/class.hpp" #include "../mwworld/class.hpp"
#include "../mwworld/refdata.hpp"
#include "../mwworld/player.hpp"
#include "../mwworld/containerstore.hpp" #include "../mwworld/containerstore.hpp"
#include "../mwworld/esmstore.hpp"
#include "../mwworld/player.hpp"
#include "../mwgui/dialogue.hpp" #include "../mwgui/dialogue.hpp"
#include <iostream>
#include <components/compiler/exception.hpp>
#include <components/compiler/errorhandler.hpp>
#include <components/compiler/scanner.hpp>
#include <components/compiler/locals.hpp>
#include <components/compiler/output.hpp>
#include <components/compiler/scriptparser.hpp>
#include <components/interpreter/interpreter.hpp>
#include "../mwscript/compilercontext.hpp" #include "../mwscript/compilercontext.hpp"
#include "../mwscript/interpretercontext.hpp" #include "../mwscript/interpretercontext.hpp"
#include "../mwscript/extensions.hpp" #include "../mwscript/extensions.hpp"
#include "../mwclass/npc.hpp" #include "../mwmechanics/creaturestats.hpp"
#include "../mwmechanics/npcstats.hpp" #include "../mwmechanics/npcstats.hpp"
#include "filter.hpp"
namespace namespace
{ {
<<<<<<< HEAD
template<typename T1, typename T2> template<typename T1, typename T2>
bool selectCompare (char comp, T1 value1, T2 value2) bool selectCompare (char comp, T1 value1, T2 value2)
{ {
@ -122,6 +124,8 @@ namespace
return false; return false;
} }
=======
>>>>>>> 92623921add0d6e16a34973dcf6f2ee1f52dbbe7
//helper function //helper function
std::string::size_type find_str_ci(const std::string& str, const std::string& substr,size_t pos) std::string::size_type find_str_ci(const std::string& str, const std::string& substr,size_t pos)
{ {
@ -131,6 +135,7 @@ namespace
namespace MWDialogue namespace MWDialogue
{ {
<<<<<<< HEAD
bool DialogueManager::functionFilter(const MWWorld::Ptr& actor, const ESM::DialInfo& info,bool choice) bool DialogueManager::functionFilter(const MWWorld::Ptr& actor, const ESM::DialInfo& info,bool choice)
@ -558,18 +563,31 @@ namespace MWDialogue
} }
DialogueManager::DialogueManager (const Compiler::Extensions& extensions) : DialogueManager::DialogueManager (const Compiler::Extensions& extensions) :
=======
DialogueManager::DialogueManager (const Compiler::Extensions& extensions, bool scriptVerbose) :
>>>>>>> 92623921add0d6e16a34973dcf6f2ee1f52dbbe7
mCompilerContext (MWScript::CompilerContext::Type_Dialgoue), mCompilerContext (MWScript::CompilerContext::Type_Dialgoue),
mErrorStream(std::cout.rdbuf()),mErrorHandler(mErrorStream) mErrorStream(std::cout.rdbuf()),mErrorHandler(mErrorStream)
, mTemporaryDispositionChange(0.f)
, mPermanentDispositionChange(0.f), mScriptVerbose (scriptVerbose)
{ {
mChoice = -1; mChoice = -1;
mIsInChoice = false; mIsInChoice = false;
mCompilerContext.setExtensions (&extensions); mCompilerContext.setExtensions (&extensions);
mDialogueMap.clear(); mDialogueMap.clear();
mActorKnownTopics.clear(); mActorKnownTopics.clear();
ESMS::RecListCaseT<ESM::Dialogue>::MapType dialogueList = MWBase::Environment::get().getWorld()->getStore().dialogs.list;
for(ESMS::RecListCaseT<ESM::Dialogue>::MapType::iterator it = dialogueList.begin(); it!=dialogueList.end();it++) const MWWorld::Store<ESM::Dialogue> &dialogs =
MWBase::Environment::get().getWorld()->getStore().get<ESM::Dialogue>();
MWWorld::Store<ESM::Dialogue>::iterator it = dialogs.begin();
for (; it != dialogs.end(); ++it)
{ {
<<<<<<< HEAD
mDialogueMap[Misc::toLower(it->first)] = it->second; mDialogueMap[Misc::toLower(it->first)] = it->second;
=======
mDialogueMap[toLower(it->mId)] = *it;
>>>>>>> 92623921add0d6e16a34973dcf6f2ee1f52dbbe7
} }
} }
@ -578,24 +596,17 @@ namespace MWDialogue
mKnownTopics[Misc::toLower(topic)] = true; mKnownTopics[Misc::toLower(topic)] = true;
} }
void DialogueManager::parseText (std::string text) void DialogueManager::parseText (const std::string& text)
{ {
std::list<std::string>::iterator it; std::list<std::string>::iterator it;
for(it = mActorKnownTopics.begin();it != mActorKnownTopics.end();++it) for(it = mActorKnownTopics.begin();it != mActorKnownTopics.end();++it)
{ {
size_t pos = find_str_ci(text,*it,0); size_t pos = find_str_ci(text,*it,0);
if(pos !=std::string::npos) if(pos !=std::string::npos)
{
if(pos==0)
{
mKnownTopics[*it] = true;
}
else if(text.substr(pos -1,1) == " ")
{ {
mKnownTopics[*it] = true; mKnownTopics[*it] = true;
} }
} }
}
updateTopics(); updateTopics();
} }
@ -606,6 +617,10 @@ namespace MWDialogue
mActor = actor; mActor = actor;
MWMechanics::CreatureStats& creatureStats = MWWorld::Class::get (actor).getCreatureStats (actor);
mTalkedTo = creatureStats.hasTalkedToPlayer();
creatureStats.talkedToPlayer();
mActorKnownTopics.clear(); mActorKnownTopics.clear();
//initialise the GUI //initialise the GUI
@ -617,41 +632,39 @@ namespace MWDialogue
updateTopics(); updateTopics();
//greeting //greeting
bool greetingFound = false; const MWWorld::Store<ESM::Dialogue> &dialogs =
//ESMS::RecListT<ESM::Dialogue>::MapType dialogueList = MWBase::Environment::get().getWorld()->getStore().dialogs.list; MWBase::Environment::get().getWorld()->getStore().get<ESM::Dialogue>();
ESMS::RecListCaseT<ESM::Dialogue>::MapType dialogueList = MWBase::Environment::get().getWorld()->getStore().dialogs.list;
for(ESMS::RecListCaseT<ESM::Dialogue>::MapType::iterator it = dialogueList.begin(); it!=dialogueList.end();it++) Filter filter (actor, mChoice, mTalkedTo);
{
ESM::Dialogue ndialogue = it->second; for (MWWorld::Store<ESM::Dialogue>::iterator it = dialogs.begin(); it != dialogs.end(); ++it)
if(ndialogue.mType == ESM::Dialogue::Greeting)
{ {
if (greetingFound) break; if(it->mType == ESM::Dialogue::Greeting)
for (std::vector<ESM::DialInfo>::const_iterator iter (it->second.mInfo.begin());
iter!=it->second.mInfo.end(); ++iter)
{ {
if (isMatching (actor, *iter) && functionFilter(mActor,*iter,true)) if (const ESM::DialInfo *info = filter.search (*it))
{ {
if (!iter->mSound.empty()) if (!info->mSound.empty())
{ {
// TODO play sound // TODO play sound
} }
std::string text = iter->mResponse; parseText (info->mResponse);
parseText(text);
win->addText(iter->mResponse); MWScript::InterpreterContext interpreterContext(&mActor.getRefData().getLocals(),mActor);
executeScript(iter->mResultScript); win->addText (Interpreter::fixDefinesDialog(info->mResponse, interpreterContext));
greetingFound = true; executeScript (info->mResultScript);
mLastTopic = it->first; mLastTopic = it->mId;
mLastDialogue = *iter; mLastDialogue = *info;
break; break;
} }
} }
} }
} }
}
bool DialogueManager::compile (const std::string& cmd,std::vector<Interpreter::Type_Code>& code) bool DialogueManager::compile (const std::string& cmd,std::vector<Interpreter::Type_Code>& code)
{ {
bool success = true;
try try
{ {
mErrorHandler.reset(); mErrorHandler.reset();
@ -673,26 +686,36 @@ namespace MWDialogue
Compiler::ScriptParser parser(mErrorHandler,mCompilerContext, locals, false); Compiler::ScriptParser parser(mErrorHandler,mCompilerContext, locals, false);
scanner.scan (parser); scanner.scan (parser);
if(mErrorHandler.isGood())
{ if (!mErrorHandler.isGood())
parser.getCode(code); success = false;
return true;
} if (success)
return false; parser.getCode (code);
} }
catch (const Compiler::SourceException& /* error */) catch (const Compiler::SourceException& /* error */)
{ {
// error has already been reported via error handler // error has already been reported via error handler
success = false;
} }
catch (const std::exception& error) catch (const std::exception& error)
{ {
printError (std::string ("An exception has been thrown: ") + error.what()); std::cerr << std::string ("Dialogue error: An exception has been thrown: ") + error.what() << std::endl;
success = false;
} }
return false; if (!success && mScriptVerbose)
{
std::cerr
<< "compiling failed (dialogue script)" << std::endl
<< cmd
<< std::endl << std::endl;
} }
void DialogueManager::executeScript(std::string script) return success;
}
void DialogueManager::executeScript (const std::string& script)
{ {
std::vector<Interpreter::Type_Code> code; std::vector<Interpreter::Type_Code> code;
if(compile(script,code)) if(compile(script,code))
@ -706,8 +729,47 @@ namespace MWDialogue
} }
catch (const std::exception& error) catch (const std::exception& error)
{ {
printError (std::string ("An exception has been thrown: ") + error.what()); std::cerr << std::string ("Dialogue error: An exception has been thrown: ") + error.what();
}
}
}
void DialogueManager::executeTopic (const std::string& topic)
{
Filter filter (mActor, mChoice, mTalkedTo);
const MWWorld::Store<ESM::Dialogue> &dialogues =
MWBase::Environment::get().getWorld()->getStore().get<ESM::Dialogue>();
const ESM::Dialogue& dialogue = *dialogues.find (topic);
if (const ESM::DialInfo *info = filter.search (dialogue))
{
parseText (info->mResponse);
MWGui::DialogueWindow* win = MWBase::Environment::get().getWindowManager()->getDialogueWindow();
if (dialogue.mType==ESM::Dialogue::Persuasion)
{
std::string modifiedTopic = "s" + topic;
modifiedTopic.erase (std::remove (modifiedTopic.begin(), modifiedTopic.end(), ' '), modifiedTopic.end());
const MWWorld::Store<ESM::GameSetting>& gmsts =
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
win->addTitle (gmsts.find (modifiedTopic)->getString());
} }
else
win->addTitle (topic);
MWScript::InterpreterContext interpreterContext(&mActor.getRefData().getLocals(),mActor);
win->addText (Interpreter::fixDefinesDialog(info->mResponse, interpreterContext));
executeScript (info->mResultScript);
mLastTopic = topic;
mLastDialogue = *info;
} }
} }
@ -717,18 +779,24 @@ namespace MWDialogue
int choice = mChoice; int choice = mChoice;
mChoice = -1; mChoice = -1;
mActorKnownTopics.clear(); mActorKnownTopics.clear();
MWGui::DialogueWindow* win = MWBase::Environment::get().getWindowManager()->getDialogueWindow();
ESMS::RecListCaseT<ESM::Dialogue>::MapType dialogueList = MWBase::Environment::get().getWorld()->getStore().dialogs.list; const MWWorld::Store<ESM::Dialogue> &dialogs =
for(ESMS::RecListCaseT<ESM::Dialogue>::MapType::iterator it = dialogueList.begin(); it!=dialogueList.end();it++) MWBase::Environment::get().getWorld()->getStore().get<ESM::Dialogue>();
Filter filter (mActor, mChoice, mTalkedTo);
for (MWWorld::Store<ESM::Dialogue>::iterator iter = dialogs.begin(); iter != dialogs.end(); ++iter)
{ {
ESM::Dialogue ndialogue = it->second; if (iter->mType == ESM::Dialogue::Topic)
if(ndialogue.mType == ESM::Dialogue::Topic)
{ {
for (std::vector<ESM::DialInfo>::const_iterator iter (it->second.mInfo.begin()); if (filter.search (*iter))
iter!=it->second.mInfo.end(); ++iter)
{ {
if (isMatching (mActor, *iter) && functionFilter(mActor,*iter,true)) mActorKnownTopics.push_back (toLower (iter->mId));
//does the player know the topic?
if (mKnownTopics.find (toLower (iter->mId)) != mKnownTopics.end())
{ {
<<<<<<< HEAD
mActorKnownTopics.push_back(Misc::toLower(it->first)); mActorKnownTopics.push_back(Misc::toLower(it->first));
//does the player know the topic? //does the player know the topic?
if(mKnownTopics.find(Misc::toLower(it->first)) != mKnownTopics.end()) if(mKnownTopics.find(Misc::toLower(it->first)) != mKnownTopics.end())
@ -736,6 +804,9 @@ namespace MWDialogue
keywordList.push_back(it->first); keywordList.push_back(it->first);
break; break;
} }
=======
keywordList.push_back (iter->mId);
>>>>>>> 92623921add0d6e16a34973dcf6f2ee1f52dbbe7
} }
} }
} }
@ -746,14 +817,14 @@ namespace MWDialogue
if (mActor.getTypeName() == typeid(ESM::NPC).name()) if (mActor.getTypeName() == typeid(ESM::NPC).name())
{ {
MWWorld::LiveCellRef<ESM::NPC>* ref = mActor.get<ESM::NPC>(); MWWorld::LiveCellRef<ESM::NPC>* ref = mActor.get<ESM::NPC>();
if (ref->base->mHasAI) if (ref->mBase->mHasAI)
services = ref->base->mAiData.mServices; services = ref->mBase->mAiData.mServices;
} }
else if (mActor.getTypeName() == typeid(ESM::Creature).name()) else if (mActor.getTypeName() == typeid(ESM::Creature).name())
{ {
MWWorld::LiveCellRef<ESM::Creature>* ref = mActor.get<ESM::Creature>(); MWWorld::LiveCellRef<ESM::Creature>* ref = mActor.get<ESM::Creature>();
if (ref->base->mHasAI) if (ref->mBase->mHasAI)
services = ref->base->mAiData.mServices; services = ref->mBase->mAiData.mServices;
} }
int windowServices = 0; int windowServices = 0;
@ -771,7 +842,7 @@ namespace MWDialogue
|| services & ESM::NPC::Misc) || services & ESM::NPC::Misc)
windowServices |= MWGui::DialogueWindow::Service_Trade; windowServices |= MWGui::DialogueWindow::Service_Trade;
if( !mActor.get<ESM::NPC>()->base->mTransport.empty()) if(mActor.getTypeName() == typeid(ESM::NPC).name() && !mActor.get<ESM::NPC>()->mBase->mTransport.empty())
windowServices |= MWGui::DialogueWindow::Service_Travel; windowServices |= MWGui::DialogueWindow::Service_Travel;
if (services & ESM::NPC::Spells) if (services & ESM::NPC::Spells)
@ -786,6 +857,8 @@ namespace MWDialogue
if (services & ESM::NPC::Enchanting) if (services & ESM::NPC::Enchanting)
windowServices |= MWGui::DialogueWindow::Service_Enchant; windowServices |= MWGui::DialogueWindow::Service_Enchant;
MWGui::DialogueWindow* win = MWBase::Environment::get().getWindowManager()->getDialogueWindow();
win->setServices (windowServices); win->setServices (windowServices);
// sort again, because the previous sort was case-sensitive // sort again, because the previous sort was case-sensitive
@ -802,29 +875,9 @@ namespace MWDialogue
if(mDialogueMap.find(keyword) != mDialogueMap.end()) if(mDialogueMap.find(keyword) != mDialogueMap.end())
{ {
ESM::Dialogue ndialogue = mDialogueMap[keyword]; ESM::Dialogue ndialogue = mDialogueMap[keyword];
if(ndialogue.mType == ESM::Dialogue::Topic) if (mDialogueMap[keyword].mType == ESM::Dialogue::Topic)
{
for (std::vector<ESM::DialInfo>::const_iterator iter = ndialogue.mInfo.begin();
iter!=ndialogue.mInfo.end(); ++iter)
{
if (isMatching (mActor, *iter) && functionFilter(mActor,*iter,true))
{ {
std::string text = iter->mResponse; executeTopic (keyword);
std::string script = iter->mResultScript;
parseText(text);
MWGui::DialogueWindow* win = MWBase::Environment::get().getWindowManager()->getDialogueWindow();
win->addTitle(keyword);
win->addText(iter->mResponse);
executeScript(script);
mLastTopic = keyword;
mLastDialogue = *iter;
break;
}
}
} }
} }
} }
@ -835,45 +888,51 @@ namespace MWDialogue
void DialogueManager::goodbyeSelected() void DialogueManager::goodbyeSelected()
{ {
MWBase::Environment::get().getWindowManager()->removeGuiMode(MWGui::GM_Dialogue); MWBase::Environment::get().getWindowManager()->removeGuiMode(MWGui::GM_Dialogue);
// Apply disposition change to NPC's base disposition
if (mActor.getTypeName() == typeid(ESM::NPC).name())
{
MWMechanics::NpcStats& npcStats = MWWorld::Class::get(mActor).getNpcStats(mActor);
npcStats.setBaseDisposition(npcStats.getBaseDisposition() + mPermanentDispositionChange);
}
mPermanentDispositionChange = 0;
mTemporaryDispositionChange = 0;
} }
void DialogueManager::questionAnswered (const std::string& answer) void DialogueManager::questionAnswered (const std::string& answer)
{ {
if(mChoiceMap.find(answer) != mChoiceMap.end()) if (mChoiceMap.find(answer) != mChoiceMap.end())
{ {
mChoice = mChoiceMap[answer]; mChoice = mChoiceMap[answer];
std::vector<ESM::DialInfo>::const_iterator iter; if (mDialogueMap.find(mLastTopic) != mDialogueMap.end())
if(mDialogueMap.find(mLastTopic) != mDialogueMap.end())
{ {
ESM::Dialogue ndialogue = mDialogueMap[mLastTopic]; if (mDialogueMap[mLastTopic].mType == ESM::Dialogue::Topic)
if(ndialogue.mType == ESM::Dialogue::Topic)
{ {
for (std::vector<ESM::DialInfo>::const_iterator iter = ndialogue.mInfo.begin(); Filter filter (mActor, mChoice, mTalkedTo);
iter!=ndialogue.mInfo.end(); ++iter)
{ if (const ESM::DialInfo *info = filter.search (mDialogueMap[mLastTopic]))
if (isMatching (mActor, *iter) && functionFilter(mActor,*iter,true))
{ {
mChoiceMap.clear(); mChoiceMap.clear();
mChoice = -1; mChoice = -1;
mIsInChoice = false; mIsInChoice = false;
MWGui::DialogueWindow* win = MWBase::Environment::get().getWindowManager()->getDialogueWindow(); std::string text = info->mResponse;
std::string text = iter->mResponse; parseText (text);
parseText(text);
win->addText(text); MWScript::InterpreterContext interpreterContext(&mActor.getRefData().getLocals(),mActor);
executeScript(iter->mResultScript); MWBase::Environment::get().getWindowManager()->getDialogueWindow()->addText (Interpreter::fixDefinesDialog(text, interpreterContext));
executeScript (info->mResultScript);
mLastTopic = mLastTopic; mLastTopic = mLastTopic;
mLastDialogue = *iter; mLastDialogue = *info;
break;
}
} }
} }
} }
updateTopics(); updateTopics();
} }
} }
void DialogueManager::printError (std::string error) void DialogueManager::printError (const std::string& error)
{ {
MWGui::DialogueWindow* win = MWBase::Environment::get().getWindowManager()->getDialogueWindow(); MWGui::DialogueWindow* win = MWBase::Environment::get().getWindowManager()->getDialogueWindow();
win->addText(error); win->addText(error);
@ -887,28 +946,60 @@ namespace MWDialogue
mIsInChoice = true; mIsInChoice = true;
} }
std::string DialogueManager::getFaction() const MWWorld::Ptr DialogueManager::getActor() const
{ {
if (mActor.getTypeName() != typeid(ESM::NPC).name()) return mActor;
return ""; }
std::string factionID(""); void DialogueManager::goodbye()
MWMechanics::NpcStats stats = MWWorld::Class::get(mActor).getNpcStats(mActor);
if(stats.getFactionRanks().empty())
{ {
std::cout << "No faction for this actor!"; MWGui::DialogueWindow* win = MWBase::Environment::get().getWindowManager()->getDialogueWindow();
win->goodbye();
} }
else
void DialogueManager::persuade(int type)
{ {
factionID = stats.getFactionRanks().begin()->first; bool success;
float temp, perm;
MWBase::Environment::get().getMechanicsManager()->getPersuasionDispositionChange(
mActor, MWBase::MechanicsManager::PersuasionType(type), mTemporaryDispositionChange,
success, temp, perm);
mTemporaryDispositionChange += temp;
mPermanentDispositionChange += perm;
// change temp disposition so that final disposition is between 0...100
int curDisp = MWBase::Environment::get().getMechanicsManager()->getDerivedDisposition(mActor);
if (curDisp + mTemporaryDispositionChange < 0)
mTemporaryDispositionChange = -curDisp;
else if (curDisp + mTemporaryDispositionChange > 100)
mTemporaryDispositionChange = 100 - curDisp;
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
MWWorld::Class::get(player).skillUsageSucceeded(player, ESM::Skill::Speechcraft, success ? 0 : 1);
std::string text;
if (type == MWBase::MechanicsManager::PT_Admire)
text = "Admire";
else if (type == MWBase::MechanicsManager::PT_Taunt)
text = "Taunt";
else if (type == MWBase::MechanicsManager::PT_Intimidate)
text = "Intimidate";
else{
text = "Bribe";
} }
return factionID;
executeTopic (text + (success ? " Success" : " Fail"));
} }
void DialogueManager::goodbye() int DialogueManager::getTemporaryDispositionChange() const
{ {
MWGui::DialogueWindow* win = MWBase::Environment::get().getWindowManager()->getDialogueWindow(); return mTemporaryDispositionChange;
}
win->goodbye(); void DialogueManager::applyTemporaryDispositionChange(int delta)
{
mTemporaryDispositionChange += delta;
} }
} }

@ -3,55 +3,54 @@
#include "../mwbase/dialoguemanager.hpp" #include "../mwbase/dialoguemanager.hpp"
#include <components/esm/loadinfo.hpp> #include <map>
#include <list>
#include <components/compiler/streamerrorhandler.hpp> #include <components/compiler/streamerrorhandler.hpp>
#include "../mwscript/compilercontext.hpp"
#include "../mwscript/interpretercontext.hpp"
#include <components/compiler/output.hpp>
#include "../mwworld/ptr.hpp" #include "../mwworld/ptr.hpp"
#include <map> #include "../mwscript/compilercontext.hpp"
namespace MWDialogue namespace MWDialogue
{ {
class DialogueManager : public MWBase::DialogueManager class DialogueManager : public MWBase::DialogueManager
{ {
bool isMatching (const MWWorld::Ptr& actor, const ESM::DialInfo::SelectStruct& select) const; std::map<std::string, ESM::Dialogue> mDialogueMap;
std::map<std::string, bool> mKnownTopics;// Those are the topics the player knows.
bool isMatching (const MWWorld::Ptr& actor, const ESM::DialInfo& info) const;
bool functionFilter(const MWWorld::Ptr& actor, const ESM::DialInfo& info,bool choice);
void parseText(std::string text);
void updateTopics();
std::map<std::string,ESM::Dialogue> mDialogueMap;
std::map<std::string,bool> mKnownTopics;// Those are the topics the player knows.
std::list<std::string> mActorKnownTopics; std::list<std::string> mActorKnownTopics;
MWScript::CompilerContext mCompilerContext; MWScript::CompilerContext mCompilerContext;
std::ostream mErrorStream; std::ostream mErrorStream;
Compiler::StreamErrorHandler mErrorHandler; Compiler::StreamErrorHandler mErrorHandler;
bool compile (const std::string& cmd,std::vector<Interpreter::Type_Code>& code);
void executeScript(std::string script);
MWWorld::Ptr mActor; MWWorld::Ptr mActor;
bool mTalkedTo;
void printError(std::string error);
int mChoice; int mChoice;
std::map<std::string,int> mChoiceMap; std::map<std::string, int> mChoiceMap;
std::string mLastTopic; std::string mLastTopic;
ESM::DialInfo mLastDialogue; ESM::DialInfo mLastDialogue;
bool mIsInChoice; bool mIsInChoice;
float mTemporaryDispositionChange;
float mPermanentDispositionChange;
bool mScriptVerbose;
void parseText (const std::string& text);
void updateTopics();
bool compile (const std::string& cmd,std::vector<Interpreter::Type_Code>& code);
void executeScript (const std::string& script);
void printError (const std::string& error);
void executeTopic (const std::string& topic);
public: public:
DialogueManager (const Compiler::Extensions& extensions); DialogueManager (const Compiler::Extensions& extensions, bool scriptVerbose);
virtual void startDialogue (const MWWorld::Ptr& actor); virtual void startDialogue (const MWWorld::Ptr& actor);
@ -61,14 +60,17 @@ namespace MWDialogue
virtual void goodbye(); virtual void goodbye();
///get the faction of the actor you are talking with virtual MWWorld::Ptr getActor() const;
virtual std::string getFaction() const; ///< Return the actor the player is currently talking to.
//calbacks for the GUI //calbacks for the GUI
virtual void keywordSelected (const std::string& keyword); virtual void keywordSelected (const std::string& keyword);
virtual void goodbyeSelected(); virtual void goodbyeSelected();
virtual void questionAnswered (const std::string& answer); virtual void questionAnswered (const std::string& answer);
virtual void persuade (int type);
virtual int getTemporaryDispositionChange () const;
virtual void applyTemporaryDispositionChange (int delta);
}; };
} }

@ -0,0 +1,570 @@
#include "filter.hpp"
#include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp"
#include "../mwbase/journal.hpp"
#include "../mwbase/mechanicsmanager.hpp"
#include "../mwworld/class.hpp"
#include "../mwworld/player.hpp"
#include "../mwworld/containerstore.hpp"
#include "../mwworld/inventorystore.hpp"
#include "../mwmechanics/npcstats.hpp"
#include "../mwmechanics/creaturestats.hpp"
#include "../mwmechanics/magiceffects.hpp"
#include "selectwrapper.hpp"
namespace
{
std::string toLower (const std::string& name)
{
std::string lowerCase;
std::transform (name.begin(), name.end(), std::back_inserter (lowerCase),
(int(*)(int)) std::tolower);
return lowerCase;
}
}
bool MWDialogue::Filter::testActor (const ESM::DialInfo& info) const
{
// actor id
if (!info.mActor.empty())
if (toLower (info.mActor)!=MWWorld::Class::get (mActor).getId (mActor))
return false;
bool isCreature = (mActor.getTypeName() != typeid (ESM::NPC).name());
// NPC race
if (!info.mRace.empty())
{
if (isCreature)
return false;
MWWorld::LiveCellRef<ESM::NPC> *cellRef = mActor.get<ESM::NPC>();
if (toLower (info.mRace)!=toLower (cellRef->mBase->mRace))
return false;
}
// NPC class
if (!info.mClass.empty())
{
if (isCreature)
return false;
MWWorld::LiveCellRef<ESM::NPC> *cellRef = mActor.get<ESM::NPC>();
if (toLower (info.mClass)!=toLower (cellRef->mBase->mClass))
return false;
}
// NPC faction
if (!info.mNpcFaction.empty())
{
if (isCreature)
return false;
MWMechanics::NpcStats& stats = MWWorld::Class::get (mActor).getNpcStats (mActor);
std::map<std::string, int>::iterator iter = stats.getFactionRanks().find (toLower (info.mNpcFaction));
if (iter==stats.getFactionRanks().end())
return false;
// check rank
if (iter->second < info.mData.mRank)
return false;
}
// Gender
if (!isCreature)
{
MWWorld::LiveCellRef<ESM::NPC>* npc = mActor.get<ESM::NPC>();
if (info.mData.mGender==(npc->mBase->mFlags & npc->mBase->Female ? 0 : 1))
return false;
}
return true;
}
bool MWDialogue::Filter::testPlayer (const ESM::DialInfo& info) const
{
const MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
// check player faction
if (!info.mPcFaction.empty())
{
MWMechanics::NpcStats& stats = MWWorld::Class::get (player).getNpcStats (player);
std::map<std::string,int>::iterator iter = stats.getFactionRanks().find (toLower (info.mPcFaction));
if(iter==stats.getFactionRanks().end())
return false;
// check rank
if (iter->second < info.mData.mPCrank)
return false;
}
// check cell
if (!info.mCell.empty())
if (toLower (player.getCell()->mCell->mName) != toLower (info.mCell))
return false;
return true;
}
bool MWDialogue::Filter::testSelectStructs (const ESM::DialInfo& info) const
{
for (std::vector<ESM::DialInfo::SelectStruct>::const_iterator iter (info.mSelects.begin());
iter != info.mSelects.end(); ++iter)
if (!testSelectStruct (*iter))
return false;
return true;
}
bool MWDialogue::Filter::testSelectStruct (const SelectWrapper& select) const
{
if (select.isNpcOnly() && mActor.getTypeName()!=typeid (ESM::NPC).name())
return select.isInverted();
switch (select.getType())
{
case SelectWrapper::Type_None: return true;
case SelectWrapper::Type_Integer: return select.selectCompare (getSelectStructInteger (select));
case SelectWrapper::Type_Numeric: return testSelectStructNumeric (select);
case SelectWrapper::Type_Boolean: return select.selectCompare (getSelectStructBoolean (select));
}
return true;
}
bool MWDialogue::Filter::testSelectStructNumeric (const SelectWrapper& select) const
{
switch (select.getFunction())
{
case SelectWrapper::Function_Global:
// internally all globals are float :(
return select.selectCompare (
MWBase::Environment::get().getWorld()->getGlobalVariable (select.getName()).mFloat);
case SelectWrapper::Function_Local:
{
std::string scriptName = MWWorld::Class::get (mActor).getScript (mActor);
if (scriptName.empty())
return false; // no script
const ESM::Script *script =
MWBase::Environment::get().getWorld()->getStore().get<ESM::Script>().find (scriptName);
std::string name = select.getName();
int i = 0;
for (; i<static_cast<int> (script->mVarNames.size()); ++i)
if (script->mVarNames[i]==name)
break;
if (i>=static_cast<int> (script->mVarNames.size()))
return false; // script does not have a variable of this name
const MWScript::Locals& locals = mActor.getRefData().getLocals();
if (i<script->mData.mNumShorts)
return select.selectCompare (static_cast<int> (locals.mShorts[i]));
i -= script->mData.mNumShorts;
if (i<script->mData.mNumLongs)
return select.selectCompare (locals.mLongs[i]);
i -= script->mData.mNumShorts;
return select.selectCompare (locals.mFloats.at (i));
}
case SelectWrapper::Function_PcHealthPercent:
{
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
float ratio = MWWorld::Class::get (player).getCreatureStats (player).getHealth().getCurrent() /
MWWorld::Class::get (player).getCreatureStats (player).getHealth().getModified();
return select.selectCompare (ratio);
}
case SelectWrapper::Function_PcDynamicStat:
{
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
float value = MWWorld::Class::get (player).getCreatureStats (player).
getDynamic (select.getArgument()).getCurrent();
return select.selectCompare (value);
}
case SelectWrapper::Function_HealthPercent:
{
float ratio = MWWorld::Class::get (mActor).getCreatureStats (mActor).getHealth().getCurrent() /
MWWorld::Class::get (mActor).getCreatureStats (mActor).getHealth().getModified();
return select.selectCompare (ratio);
}
default:
throw std::runtime_error ("unknown numeric select function");
}
}
int MWDialogue::Filter::getSelectStructInteger (const SelectWrapper& select) const
{
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
switch (select.getFunction())
{
case SelectWrapper::Function_Journal:
return MWBase::Environment::get().getJournal()->getJournalIndex (select.getName());
case SelectWrapper::Function_Item:
{
MWWorld::ContainerStore& store = MWWorld::Class::get (player).getContainerStore (player);
int sum = 0;
std::string name = select.getName();
for (MWWorld::ContainerStoreIterator iter (store.begin()); iter!=store.end(); ++iter)
if (toLower(iter->getCellRef().mRefID) == name)
sum += iter->getRefData().getCount();
return sum;
}
case SelectWrapper::Function_Dead:
return MWBase::Environment::get().getMechanicsManager()->countDeaths (select.getName());
case SelectWrapper::Function_Choice:
return mChoice;
case SelectWrapper::Function_AiSetting:
return MWWorld::Class::get (mActor).getCreatureStats (mActor).getAiSetting (select.getArgument());
case SelectWrapper::Function_PcAttribute:
return MWWorld::Class::get (player).getCreatureStats (player).
getAttribute (select.getArgument()).getModified();
case SelectWrapper::Function_PcSkill:
return static_cast<int> (MWWorld::Class::get (player).
getNpcStats (player).getSkill (select.getArgument()).getModified());
case SelectWrapper::Function_FriendlyHit:
{
int hits = MWWorld::Class::get (mActor).getCreatureStats (mActor).getFriendlyHits();
return hits>4 ? 4 : hits;
}
case SelectWrapper::Function_PcLevel:
return MWWorld::Class::get (player).getCreatureStats (player).getLevel();
case SelectWrapper::Function_PcGender:
return player.get<ESM::NPC>()->mBase->mFlags & ESM::NPC::Female ? 0 : 1;
case SelectWrapper::Function_PcClothingModifier:
{
MWWorld::InventoryStore& store = MWWorld::Class::get (player).getInventoryStore (player);
int value = 0;
for (int i=0; i<=15; ++i) // everything except thigns held in hands and amunition
{
MWWorld::ContainerStoreIterator slot = store.getSlot (i);
if (slot!=store.end())
value += MWWorld::Class::get (*slot).getValue (*slot);
}
return value;
}
case SelectWrapper::Function_PcCrimeLevel:
return MWWorld::Class::get (player).getNpcStats (player).getBounty();
case SelectWrapper::Function_RankRequirement:
{
if (MWWorld::Class::get (mActor).getNpcStats (mActor).getFactionRanks().empty())
return 0;
std::string faction =
MWWorld::Class::get (mActor).getNpcStats (mActor).getFactionRanks().begin()->first;
int rank = getFactionRank (player, faction);
if (rank>=9)
return 0; // max rank
int result = 0;
if (hasFactionRankSkillRequirements (player, faction, rank+1))
result += 1;
if (hasFactionRankReputationRequirements (player, faction, rank+1))
result += 2;
return result;
}
case SelectWrapper::Function_Level:
return MWWorld::Class::get (mActor).getCreatureStats (mActor).getLevel();
case SelectWrapper::Function_PCReputation:
return MWWorld::Class::get (player).getNpcStats (player).getReputation();
case SelectWrapper::Function_Weather:
return MWBase::Environment::get().getWorld()->getCurrentWeather();
case SelectWrapper::Function_Reputation:
return MWWorld::Class::get (mActor).getNpcStats (mActor).getReputation();
case SelectWrapper::Function_FactionRankDiff:
{
if (MWWorld::Class::get (mActor).getNpcStats (mActor).getFactionRanks().empty())
return 0;
std::pair<std::string, int> faction =
*MWWorld::Class::get (mActor).getNpcStats (mActor).getFactionRanks().begin();
int rank = getFactionRank (player, faction.first);
return rank-faction.second;
}
case SelectWrapper::Function_WerewolfKills:
return MWWorld::Class::get (player).getNpcStats (player).getWerewolfKills();
case SelectWrapper::Function_RankLow:
case SelectWrapper::Function_RankHigh:
{
bool low = select.getFunction()==SelectWrapper::Function_RankLow;
if (MWWorld::Class::get (mActor).getNpcStats (mActor).getFactionRanks().empty())
return 0;
std::string factionId =
MWWorld::Class::get (mActor).getNpcStats (mActor).getFactionRanks().begin()->first;
int value = 0;
const ESM::Faction& faction =
*MWBase::Environment::get().getWorld()->getStore().get<ESM::Faction>().find (factionId);
MWMechanics::NpcStats& playerStats = MWWorld::Class::get (player).getNpcStats (player);
for (std::vector<ESM::Faction::Reaction>::const_iterator iter (faction.mReactions.begin());
iter!=faction.mReactions.end(); ++iter)
if (playerStats.getFactionRanks().find (iter->mFaction)!=playerStats.getFactionRanks().end())
if (low ? iter->mReaction<value : iter->mReaction>value)
value = iter->mReaction;
return value;
}
default:
throw std::runtime_error ("unknown integer select function");
}
}
bool MWDialogue::Filter::getSelectStructBoolean (const SelectWrapper& select) const
{
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
switch (select.getFunction())
{
case SelectWrapper::Function_False:
return false;
case SelectWrapper::Function_Id:
return select.getName()==toLower (MWWorld::Class::get (mActor).getId (mActor));
case SelectWrapper::Function_Faction:
return toLower (mActor.get<ESM::NPC>()->mBase->mFaction)==select.getName();
case SelectWrapper::Function_Class:
return toLower (mActor.get<ESM::NPC>()->mBase->mClass)==select.getName();
case SelectWrapper::Function_Race:
return toLower (mActor.get<ESM::NPC>()->mBase->mRace)==select.getName();
case SelectWrapper::Function_Cell:
return toLower (mActor.getCell()->mCell->mName)==select.getName();
case SelectWrapper::Function_SameGender:
return (player.get<ESM::NPC>()->mBase->mFlags & ESM::NPC::Female)==
(mActor.get<ESM::NPC>()->mBase->mFlags & ESM::NPC::Female);
case SelectWrapper::Function_SameRace:
return toLower (mActor.get<ESM::NPC>()->mBase->mRace)!=
toLower (player.get<ESM::NPC>()->mBase->mRace);
case SelectWrapper::Function_SameFaction:
return MWWorld::Class::get (mActor).getNpcStats (mActor).isSameFaction (
MWWorld::Class::get (player).getNpcStats (player));
case SelectWrapper::Function_PcCommonDisease:
return MWWorld::Class::get (player).getCreatureStats (player).hasCommonDisease();
case SelectWrapper::Function_PcBlightDisease:
return MWWorld::Class::get (player).getCreatureStats (player).hasBlightDisease();
case SelectWrapper::Function_PcCorprus:
return MWWorld::Class::get (player).getCreatureStats (player).
getMagicEffects().get (132).mMagnitude!=0;
case SelectWrapper::Function_PcExpelled:
{
if (MWWorld::Class::get (mActor).getNpcStats (mActor).getFactionRanks().empty())
return false;
std::string faction =
MWWorld::Class::get (mActor).getNpcStats (mActor).getFactionRanks().begin()->first;
std::set<std::string>& expelled = MWWorld::Class::get (player).getNpcStats (player).getExpelled();
return expelled.find (faction)!=expelled.end();
}
case SelectWrapper::Function_PcVampire:
return MWWorld::Class::get (player).getNpcStats (player).isVampire();
case SelectWrapper::Function_TalkedToPc:
return mTalkedToPlayer;
case SelectWrapper::Function_Alarmed:
return MWWorld::Class::get (mActor).getCreatureStats (mActor).isAlarmed();
case SelectWrapper::Function_Detected:
return MWWorld::Class::get (mActor).hasDetected (mActor, player);
case SelectWrapper::Function_Attacked:
return MWWorld::Class::get (mActor).getCreatureStats (mActor).getAttacked();
case SelectWrapper::Function_ShouldAttack:
return MWWorld::Class::get (mActor).getCreatureStats (mActor).isHostile();
case SelectWrapper::Function_CreatureTargetted:
return MWWorld::Class::get (mActor).getCreatureStats (mActor).getCreatureTargetted();
case SelectWrapper::Function_PCWerewolf:
return MWWorld::Class::get (player).getNpcStats (player).isWerewolf();
default:
throw std::runtime_error ("unknown boolean select function");
}
}
int MWDialogue::Filter::getFactionRank (const MWWorld::Ptr& actor, const std::string& factionId) const
{
MWMechanics::NpcStats& stats = MWWorld::Class::get (actor).getNpcStats (actor);
std::map<std::string, int>::const_iterator iter = stats.getFactionRanks().find (factionId);
if (iter==stats.getFactionRanks().end())
return -1;
return iter->second;
}
bool MWDialogue::Filter::hasFactionRankSkillRequirements (const MWWorld::Ptr& actor,
const std::string& factionId, int rank) const
{
if (rank<0 || rank>=10)
throw std::runtime_error ("rank index out of range");
if (!MWWorld::Class::get (actor).getNpcStats (actor).hasSkillsForRank (factionId, rank))
return false;
const ESM::Faction& faction =
*MWBase::Environment::get().getWorld()->getStore().get<ESM::Faction>().find (factionId);
MWMechanics::CreatureStats& stats = MWWorld::Class::get (actor).getCreatureStats (actor);
return stats.getAttribute (faction.mData.mAttribute1).getBase()>=faction.mData.mRankData[rank].mAttribute1 &&
stats.getAttribute (faction.mData.mAttribute2).getBase()>=faction.mData.mRankData[rank].mAttribute2;
}
bool MWDialogue::Filter::hasFactionRankReputationRequirements (const MWWorld::Ptr& actor,
const std::string& factionId, int rank) const
{
if (rank<0 || rank>=10)
throw std::runtime_error ("rank index out of range");
MWMechanics::NpcStats& stats = MWWorld::Class::get (actor).getNpcStats (actor);
const ESM::Faction& faction =
*MWBase::Environment::get().getWorld()->getStore().get<ESM::Faction>().find (factionId);
return stats.getFactionReputation (factionId)>=faction.mData.mRankData[rank].mFactReaction;
}
MWDialogue::Filter::Filter (const MWWorld::Ptr& actor, int choice, bool talkedToPlayer)
: mActor (actor), mChoice (choice), mTalkedToPlayer (talkedToPlayer)
{}
bool MWDialogue::Filter::operator() (const ESM::DialInfo& info) const
{
return testActor (info) && testPlayer (info) && testSelectStructs (info);
}
const ESM::DialInfo *MWDialogue::Filter::search (const ESM::Dialogue& dialogue) const
{
for (std::vector<ESM::DialInfo>::const_iterator iter = dialogue.mInfo.begin();
iter!=dialogue.mInfo.end(); ++iter)
if ((*this) (*iter))
return &*iter;
return 0;
}

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

Loading…
Cancel
Save