1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-04-01 12:06:41 +00:00

Merge remote-tracking branch 'refs/remotes/master/master' into NonTableFields

This commit is contained in:
Marek Kochanowicz 2014-07-12 20:14:35 +02:00
commit 4b4a72c3b6
69 changed files with 1415 additions and 526 deletions

View file

@ -19,13 +19,13 @@ opencs_hdrs_noqt (model/doc
opencs_units (model/world opencs_units (model/world
idtable idtableproxymodel regionmap data commanddispatcher idtable idtableproxymodel regionmap data commanddispatcher
nestedtablemodel idtablebase resourcetable nestedtablemodel
) )
opencs_units_noqt (model/world opencs_units_noqt (model/world
universalid record commands columnbase scriptcontext cell refidcollection universalid record commands columnbase scriptcontext cell refidcollection
refidadapter refiddata refidadapterimp ref collectionbase refcollection columns infocollection tablemimedata cellcoordinates cellselection refidadapter refiddata refidadapterimp ref collectionbase refcollection columns infocollection tablemimedata cellcoordinates cellselection resources resourcesmanager
) )
opencs_hdrs_noqt (model/world opencs_hdrs_noqt (model/world

View file

@ -35,6 +35,8 @@ CS::Editor::Editor (OgreInit::OgreInit& ogreInit)
Bsa::registerResources (Files::Collections (config.first, !mFsStrict), config.second, true, Bsa::registerResources (Files::Collections (config.first, !mFsStrict), config.second, true,
mFsStrict); mFsStrict);
mDocumentManager.listResources();
mNewGame.setLocalData (mLocal); mNewGame.setLocalData (mLocal);
mFileDialog.setLocalData (mLocal); mFileDialog.setLocalData (mLocal);

View file

@ -2205,9 +2205,9 @@ void CSMDoc::Document::createBase()
CSMDoc::Document::Document (const Files::ConfigurationManager& configuration, CSMDoc::Document::Document (const Files::ConfigurationManager& configuration,
const std::vector< boost::filesystem::path >& files, bool new_, const std::vector< boost::filesystem::path >& files, bool new_,
const boost::filesystem::path& savePath, const boost::filesystem::path& resDir, const boost::filesystem::path& savePath, const boost::filesystem::path& resDir,
ToUTF8::FromType encoding) ToUTF8::FromType encoding, const CSMWorld::ResourcesManager& resourcesManager)
: mSavePath (savePath), mContentFiles (files), mNew (new_), mData (encoding), mTools (mData), : mSavePath (savePath), mContentFiles (files), mNew (new_), mData (encoding, resourcesManager),
mResDir(resDir), mTools (mData), mResDir(resDir),
mProjectPath ((configuration.getUserDataPath() / "projects") / mProjectPath ((configuration.getUserDataPath() / "projects") /
(savePath.filename().string() + ".project")), (savePath.filename().string() + ".project")),
mSaving (*this, mProjectPath, encoding) mSaving (*this, mProjectPath, encoding)

View file

@ -31,6 +31,11 @@ namespace Files
class ConfigurationManager; class ConfigurationManager;
} }
namespace CSMWorld
{
class ResourcesManager;
}
namespace CSMDoc namespace CSMDoc
{ {
class Document : public QObject class Document : public QObject
@ -73,7 +78,7 @@ namespace CSMDoc
Document (const Files::ConfigurationManager& configuration, Document (const Files::ConfigurationManager& configuration,
const std::vector< boost::filesystem::path >& files, bool new_, const std::vector< boost::filesystem::path >& files, bool new_,
const boost::filesystem::path& savePath, const boost::filesystem::path& resDir, const boost::filesystem::path& savePath, const boost::filesystem::path& resDir,
ToUTF8::FromType encoding); ToUTF8::FromType encoding, const CSMWorld::ResourcesManager& resourcesManager);
~Document(); ~Document();

View file

@ -52,7 +52,7 @@ CSMDoc::DocumentManager::~DocumentManager()
void CSMDoc::DocumentManager::addDocument (const std::vector<boost::filesystem::path>& files, const boost::filesystem::path& savePath, void CSMDoc::DocumentManager::addDocument (const std::vector<boost::filesystem::path>& files, const boost::filesystem::path& savePath,
bool new_) bool new_)
{ {
Document *document = new Document (mConfiguration, files, new_, savePath, mResDir, mEncoding); Document *document = new Document (mConfiguration, files, new_, savePath, mResDir, mEncoding, mResourcesManager);
mDocuments.push_back (document); mDocuments.push_back (document);
@ -85,6 +85,11 @@ void CSMDoc::DocumentManager::setEncoding (ToUTF8::FromType encoding)
mEncoding = encoding; mEncoding = encoding;
} }
void CSMDoc::DocumentManager::listResources()
{
mResourcesManager.listResources();
}
void CSMDoc::DocumentManager::documentLoaded (Document *document) void CSMDoc::DocumentManager::documentLoaded (Document *document)
{ {
emit documentAdded (document); emit documentAdded (document);

View file

@ -11,6 +11,8 @@
#include <components/to_utf8/to_utf8.hpp> #include <components/to_utf8/to_utf8.hpp>
#include "../world/resourcesmanager.hpp"
#include "loader.hpp" #include "loader.hpp"
namespace Files namespace Files
@ -31,6 +33,7 @@ namespace CSMDoc
QThread mLoaderThread; QThread mLoaderThread;
Loader mLoader; Loader mLoader;
ToUTF8::FromType mEncoding; ToUTF8::FromType mEncoding;
CSMWorld::ResourcesManager mResourcesManager;
DocumentManager (const DocumentManager&); DocumentManager (const DocumentManager&);
DocumentManager& operator= (const DocumentManager&); DocumentManager& operator= (const DocumentManager&);
@ -50,6 +53,9 @@ namespace CSMDoc
void setEncoding (ToUTF8::FromType encoding); void setEncoding (ToUTF8::FromType encoding);
/// Ask OGRE for a list of available resources.
void listResources();
private: private:
boost::filesystem::path mResDir; boost::filesystem::path mResDir;

View file

@ -59,6 +59,12 @@ CSMDoc::Saving::Saving (Document& document, const boost::filesystem::path& proje
appendStage (new WriteCollectionStage<CSMWorld::IdCollection<ESM::Spell> > appendStage (new WriteCollectionStage<CSMWorld::IdCollection<ESM::Spell> >
(mDocument.getData().getSpells(), mState)); (mDocument.getData().getSpells(), mState));
appendStage (new WriteCollectionStage<CSMWorld::IdCollection<ESM::Enchantment> >
(mDocument.getData().getEnchantments(), mState));
appendStage (new WriteCollectionStage<CSMWorld::IdCollection<ESM::BodyPart> >
(mDocument.getData().getBodyParts(), mState));
appendStage (new WriteDialogueCollectionStage (mDocument, mState, false)); appendStage (new WriteDialogueCollectionStage (mDocument, mState, false));
appendStage (new WriteDialogueCollectionStage (mDocument, mState, true)); appendStage (new WriteDialogueCollectionStage (mDocument, mState, true));

View file

@ -7,7 +7,7 @@ CSMFilter::AndNode::AndNode (const std::vector<boost::shared_ptr<Node> >& nodes)
: NAryNode (nodes, "and") : NAryNode (nodes, "and")
{} {}
bool CSMFilter::AndNode::test (const CSMWorld::IdTable& table, int row, bool CSMFilter::AndNode::test (const CSMWorld::IdTableBase& table, int row,
const std::map<int, int>& columns) const const std::map<int, int>& columns) const
{ {
int size = getSize(); int size = getSize();

View file

@ -11,7 +11,7 @@ namespace CSMFilter
AndNode (const std::vector<boost::shared_ptr<Node> >& nodes); AndNode (const std::vector<boost::shared_ptr<Node> >& nodes);
virtual bool test (const CSMWorld::IdTable& table, int row, virtual bool test (const CSMWorld::IdTableBase& table, int row,
const std::map<int, int>& columns) const; const std::map<int, int>& columns) const;
///< \return Can the specified table row pass through to filter? ///< \return Can the specified table row pass through to filter?
/// \param columns column ID to column index mapping /// \param columns column ID to column index mapping

View file

@ -3,7 +3,7 @@
CSMFilter::BooleanNode::BooleanNode (bool true_) : mTrue (true_) {} CSMFilter::BooleanNode::BooleanNode (bool true_) : mTrue (true_) {}
bool CSMFilter::BooleanNode::test (const CSMWorld::IdTable& table, int row, bool CSMFilter::BooleanNode::test (const CSMWorld::IdTableBase& table, int row,
const std::map<int, int>& columns) const const std::map<int, int>& columns) const
{ {
return mTrue; return mTrue;

View file

@ -13,7 +13,7 @@ namespace CSMFilter
BooleanNode (bool true_); BooleanNode (bool true_);
virtual bool test (const CSMWorld::IdTable& table, int row, virtual bool test (const CSMWorld::IdTableBase& table, int row,
const std::map<int, int>& columns) const; const std::map<int, int>& columns) const;
///< \return Can the specified table row pass through to filter? ///< \return Can the specified table row pass through to filter?
/// \param columns column ID to column index mapping /// \param columns column ID to column index mapping

View file

@ -11,7 +11,7 @@
namespace CSMWorld namespace CSMWorld
{ {
class IdTable; class IdTableBase;
} }
namespace CSMFilter namespace CSMFilter
@ -32,7 +32,7 @@ namespace CSMFilter
virtual ~Node(); virtual ~Node();
virtual bool test (const CSMWorld::IdTable& table, int row, virtual bool test (const CSMWorld::IdTableBase& table, int row,
const std::map<int, int>& columns) const = 0; const std::map<int, int>& columns) const = 0;
///< \return Can the specified table row pass through to filter? ///< \return Can the specified table row pass through to filter?
/// \param columns column ID to column index mapping /// \param columns column ID to column index mapping

View file

@ -3,7 +3,7 @@
CSMFilter::NotNode::NotNode (boost::shared_ptr<Node> child) : UnaryNode (child, "not") {} CSMFilter::NotNode::NotNode (boost::shared_ptr<Node> child) : UnaryNode (child, "not") {}
bool CSMFilter::NotNode::test (const CSMWorld::IdTable& table, int row, bool CSMFilter::NotNode::test (const CSMWorld::IdTableBase& table, int row,
const std::map<int, int>& columns) const const std::map<int, int>& columns) const
{ {
return !getChild().test (table, row, columns); return !getChild().test (table, row, columns);

View file

@ -11,7 +11,7 @@ namespace CSMFilter
NotNode (boost::shared_ptr<Node> child); NotNode (boost::shared_ptr<Node> child);
virtual bool test (const CSMWorld::IdTable& table, int row, virtual bool test (const CSMWorld::IdTableBase& table, int row,
const std::map<int, int>& columns) const; const std::map<int, int>& columns) const;
///< \return Can the specified table row pass through to filter? ///< \return Can the specified table row pass through to filter?
/// \param columns column ID to column index mapping /// \param columns column ID to column index mapping

View file

@ -7,7 +7,7 @@ CSMFilter::OrNode::OrNode (const std::vector<boost::shared_ptr<Node> >& nodes)
: NAryNode (nodes, "or") : NAryNode (nodes, "or")
{} {}
bool CSMFilter::OrNode::test (const CSMWorld::IdTable& table, int row, bool CSMFilter::OrNode::test (const CSMWorld::IdTableBase& table, int row,
const std::map<int, int>& columns) const const std::map<int, int>& columns) const
{ {
int size = getSize(); int size = getSize();

View file

@ -11,7 +11,7 @@ namespace CSMFilter
OrNode (const std::vector<boost::shared_ptr<Node> >& nodes); OrNode (const std::vector<boost::shared_ptr<Node> >& nodes);
virtual bool test (const CSMWorld::IdTable& table, int row, virtual bool test (const CSMWorld::IdTableBase& table, int row,
const std::map<int, int>& columns) const; const std::map<int, int>& columns) const;
///< \return Can the specified table row pass through to filter? ///< \return Can the specified table row pass through to filter?
/// \param columns column ID to column index mapping /// \param columns column ID to column index mapping

View file

@ -550,7 +550,12 @@ bool CSMFilter::Parser::parse (const std::string& filter, bool allowPredefined)
if (allowPredefined) if (allowPredefined)
token = getNextToken(); token = getNextToken();
if (!allowPredefined || token==Token (Token::Type_OneShot)) if (allowPredefined && token==Token (Token::Type_EOS))
{
mFilter.reset();
return true;
}
else if (!allowPredefined || token==Token (Token::Type_OneShot))
{ {
boost::shared_ptr<Node> node = parseImp (true, token!=Token (Token::Type_OneShot)); boost::shared_ptr<Node> node = parseImp (true, token!=Token (Token::Type_OneShot));

View file

@ -7,13 +7,13 @@
#include <QRegExp> #include <QRegExp>
#include "../world/columns.hpp" #include "../world/columns.hpp"
#include "../world/idtable.hpp" #include "../world/idtablebase.hpp"
CSMFilter::TextNode::TextNode (int columnId, const std::string& text) CSMFilter::TextNode::TextNode (int columnId, const std::string& text)
: mColumnId (columnId), mText (text) : mColumnId (columnId), mText (text)
{} {}
bool CSMFilter::TextNode::test (const CSMWorld::IdTable& table, int row, bool CSMFilter::TextNode::test (const CSMWorld::IdTableBase& table, int row,
const std::map<int, int>& columns) const const std::map<int, int>& columns) const
{ {
const std::map<int, int>::const_iterator iter = columns.find (mColumnId); const std::map<int, int>::const_iterator iter = columns.find (mColumnId);

View file

@ -14,7 +14,7 @@ namespace CSMFilter
TextNode (int columnId, const std::string& text); TextNode (int columnId, const std::string& text);
virtual bool test (const CSMWorld::IdTable& table, int row, virtual bool test (const CSMWorld::IdTableBase& table, int row,
const std::map<int, int>& columns) const; const std::map<int, int>& columns) const;
///< \return Can the specified table row pass through to filter? ///< \return Can the specified table row pass through to filter?
/// \param columns column ID to column index mapping /// \param columns column ID to column index mapping

View file

@ -5,13 +5,13 @@
#include <stdexcept> #include <stdexcept>
#include "../world/columns.hpp" #include "../world/columns.hpp"
#include "../world/idtable.hpp" #include "../world/idtablebase.hpp"
CSMFilter::ValueNode::ValueNode (int columnId, Type lowerType, Type upperType, CSMFilter::ValueNode::ValueNode (int columnId, Type lowerType, Type upperType,
double lower, double upper) double lower, double upper)
: mColumnId (columnId), mLowerType (lowerType), mUpperType (upperType), mLower (lower), mUpper (upper){} : mColumnId (columnId), mLowerType (lowerType), mUpperType (upperType), mLower (lower), mUpper (upper){}
bool CSMFilter::ValueNode::test (const CSMWorld::IdTable& table, int row, bool CSMFilter::ValueNode::test (const CSMWorld::IdTableBase& table, int row,
const std::map<int, int>& columns) const const std::map<int, int>& columns) const
{ {
const std::map<int, int>::const_iterator iter = columns.find (mColumnId); const std::map<int, int>::const_iterator iter = columns.find (mColumnId);

View file

@ -27,7 +27,7 @@ namespace CSMFilter
ValueNode (int columnId, Type lowerType, Type upperType, double lower, double upper); ValueNode (int columnId, Type lowerType, Type upperType, double lower, double upper);
virtual bool test (const CSMWorld::IdTable& table, int row, virtual bool test (const CSMWorld::IdTableBase& table, int row,
const std::map<int, int>& columns) const; const std::map<int, int>& columns) const;
///< \return Can the specified table row pass through to filter? ///< \return Can the specified table row pass through to filter?
/// \param columns column ID to column index mapping /// \param columns column ID to column index mapping

View file

@ -90,10 +90,20 @@ namespace CSMWorld
Display_RefRecordType, Display_RefRecordType,
Display_DialogueType, Display_DialogueType,
Display_QuestStatusType, Display_QuestStatusType,
Display_Gender,
//Those are top level columns that nest other columns //Those are top level columns that nest other columns
Display_NestedItemList Display_NestedItemList,
Display_EnchantmentType,
Display_BodyPartType,
Display_MeshType,
Display_Gender,
Display_Mesh,
Display_Icon,
Display_Music,
Display_SoundRes,
Display_Texture,
Display_Video,
Display_Colour
}; };
int mColumnId; int mColumnId;

View file

@ -463,14 +463,21 @@ namespace CSMWorld
struct FlagColumn : public Column<ESXRecordT> struct FlagColumn : public Column<ESXRecordT>
{ {
int mMask; int mMask;
bool mInverted;
FlagColumn (int columnId, int mask) FlagColumn (int columnId, int mask, bool inverted = false)
: Column<ESXRecordT> (columnId, ColumnBase::Display_Boolean), mMask (mask) : Column<ESXRecordT> (columnId, ColumnBase::Display_Boolean), mMask (mask),
mInverted (inverted)
{} {}
virtual QVariant get (const Record<ESXRecordT>& record) const virtual QVariant get (const Record<ESXRecordT>& record) const
{ {
return (record.get().mData.mFlags & mMask)!=0; bool flag = (record.get().mData.mFlags & mMask)!=0;
if (mInverted)
flag = !flag;
return flag;
} }
virtual void set (Record<ESXRecordT>& record, const QVariant& data) virtual void set (Record<ESXRecordT>& record, const QVariant& data)
@ -479,7 +486,7 @@ namespace CSMWorld
int flags = record2.mData.mFlags & ~mMask; int flags = record2.mData.mFlags & ~mMask;
if (data.toInt()) if ((data.toInt()!=0)!=mInverted)
flags |= mMask; flags |= mMask;
record2.mData.mFlags = flags; record2.mData.mFlags = flags;
@ -597,7 +604,7 @@ namespace CSMWorld
struct SoundFileColumn : public Column<ESXRecordT> struct SoundFileColumn : public Column<ESXRecordT>
{ {
SoundFileColumn() SoundFileColumn()
: Column<ESXRecordT> (Columns::ColumnId_SoundFile, ColumnBase::Display_Sound) : Column<ESXRecordT> (Columns::ColumnId_SoundFile, ColumnBase::Display_SoundRes)
{} {}
virtual QVariant get (const Record<ESXRecordT>& record) const virtual QVariant get (const Record<ESXRecordT>& record) const
@ -627,7 +634,7 @@ namespace CSMWorld
{ {
/// \todo Replace Display_Integer with something that displays the colour value more directly. /// \todo Replace Display_Integer with something that displays the colour value more directly.
MapColourColumn() MapColourColumn()
: Column<ESXRecordT> (Columns::ColumnId_MapColour, ColumnBase::Display_Integer) : Column<ESXRecordT> (Columns::ColumnId_MapColour, ColumnBase::Display_Colour)
{} {}
virtual QVariant get (const Record<ESXRecordT>& record) const virtual QVariant get (const Record<ESXRecordT>& record) const
@ -1682,6 +1689,187 @@ namespace CSMWorld
return true; return true;
} }
}; };
template<typename ESXRecordT>
struct EnchantmentTypeColumn : public Column<ESXRecordT>
{
EnchantmentTypeColumn()
: Column<ESXRecordT> (Columns::ColumnId_EnchantmentType, ColumnBase::Display_EnchantmentType)
{}
virtual QVariant get (const Record<ESXRecordT>& record) const
{
return static_cast<int> (record.get().mData.mType);
}
virtual void set (Record<ESXRecordT>& record, const QVariant& data)
{
ESXRecordT record2 = record.get();
record2.mData.mType = data.toInt();
record.setModified (record2);
}
virtual bool isEditable() const
{
return true;
}
};
template<typename ESXRecordT>
struct ChargesColumn2 : public Column<ESXRecordT>
{
ChargesColumn2() : Column<ESXRecordT> (Columns::ColumnId_Charges, ColumnBase::Display_Integer) {}
virtual QVariant get (const Record<ESXRecordT>& record) const
{
return record.get().mData.mCharge;
}
virtual void set (Record<ESXRecordT>& record, const QVariant& data)
{
ESXRecordT record2 = record.get();
record2.mData.mCharge = data.toInt();
record.setModified (record2);
}
virtual bool isEditable() const
{
return true;
}
};
template<typename ESXRecordT>
struct AutoCalcColumn : public Column<ESXRecordT>
{
AutoCalcColumn() : Column<ESXRecordT> (Columns::ColumnId_AutoCalc, ColumnBase::Display_Boolean)
{}
virtual QVariant get (const Record<ESXRecordT>& record) const
{
return record.get().mData.mAutocalc!=0;
}
virtual void set (Record<ESXRecordT>& record, const QVariant& data)
{
ESXRecordT record2 = record.get();
record2.mData.mAutocalc = data.toInt();
record.setModified (record2);
}
virtual bool isEditable() const
{
return true;
}
};
template<typename ESXRecordT>
struct ModelColumn : public Column<ESXRecordT>
{
ModelColumn() : Column<ESXRecordT> (Columns::ColumnId_Model, ColumnBase::Display_String) {}
virtual QVariant get (const Record<ESXRecordT>& record) const
{
return QString::fromUtf8 (record.get().mModel.c_str());
}
virtual void set (Record<ESXRecordT>& record, const QVariant& data)
{
ESXRecordT record2 = record.get();
record2.mModel = data.toString().toUtf8().constData();
record.setModified (record2);
}
virtual bool isEditable() const
{
return true;
}
};
template<typename ESXRecordT>
struct VampireColumn : public Column<ESXRecordT>
{
VampireColumn() : Column<ESXRecordT> (Columns::ColumnId_Vampire, ColumnBase::Display_Boolean)
{}
virtual QVariant get (const Record<ESXRecordT>& record) const
{
return record.get().mData.mVampire!=0;
}
virtual void set (Record<ESXRecordT>& record, const QVariant& data)
{
ESXRecordT record2 = record.get();
record2.mData.mVampire = data.toInt();
record.setModified (record2);
}
virtual bool isEditable() const
{
return true;
}
};
template<typename ESXRecordT>
struct BodyPartTypeColumn : public Column<ESXRecordT>
{
BodyPartTypeColumn()
: Column<ESXRecordT> (Columns::ColumnId_BodyPartType, ColumnBase::Display_BodyPartType)
{}
virtual QVariant get (const Record<ESXRecordT>& record) const
{
return static_cast<int> (record.get().mData.mPart);
}
virtual void set (Record<ESXRecordT>& record, const QVariant& data)
{
ESXRecordT record2 = record.get();
record2.mData.mPart = data.toInt();
record.setModified (record2);
}
virtual bool isEditable() const
{
return true;
}
};
template<typename ESXRecordT>
struct MeshTypeColumn : public Column<ESXRecordT>
{
MeshTypeColumn()
: Column<ESXRecordT> (Columns::ColumnId_MeshType, ColumnBase::Display_MeshType)
{}
virtual QVariant get (const Record<ESXRecordT>& record) const
{
return static_cast<int> (record.get().mData.mType);
}
virtual void set (Record<ESXRecordT>& record, const QVariant& data)
{
ESXRecordT record2 = record.get();
record2.mData.mType = data.toInt();
record.setModified (record2);
}
virtual bool isEditable() const
{
return true;
}
};
} }
#endif #endif

View file

@ -176,6 +176,13 @@ namespace CSMWorld
{ ColumnId_ReferenceableId, "Referenceable ID" }, { ColumnId_ReferenceableId, "Referenceable ID" },
{ ColumnId_InventoryItemId, "ID"}, { ColumnId_InventoryItemId, "ID"},
{ ColumnId_ItemCount, "Count"}, { ColumnId_ItemCount, "Count"},
{ ColumnId_CombatState, "Combat" },
{ ColumnId_MagicState, "Magic" },
{ ColumnId_StealthState, "Stealth" },
{ ColumnId_EnchantmentType, "Enchantment Type" },
{ ColumnId_Vampire, "Vampire" },
{ ColumnId_BodyPartType, "Bodypart Type" },
{ ColumnId_MeshType, "Mesh Type" },
{ ColumnId_UseValue1, "Use value 1" }, { ColumnId_UseValue1, "Use value 1" },
{ ColumnId_UseValue2, "Use value 2" }, { ColumnId_UseValue2, "Use value 2" },
@ -301,6 +308,22 @@ namespace
"Male", "Female", 0 "Male", "Female", 0
}; };
static const char *sEnchantmentTypes[] =
{
"Cast Once", "When Strikes", "When Used", "Constant Effect", 0
};
static const char *sBodyPartTypes[] =
{
"Head", "Hair", "Neck", "Chest", "Groin", "Hand", "Wrist", "Forearm", "Upper Arm",
"Foot", "Ankle", "Knee", "Upper Leg", "Clavicle", "Tail", 0
};
static const char *sMeshTypes[] =
{
"Skin", "Clothing", "Armour", 0
};
const char **getEnumNames (CSMWorld::Columns::ColumnId column) const char **getEnumNames (CSMWorld::Columns::ColumnId column)
{ {
switch (column) switch (column)
@ -318,6 +341,9 @@ namespace
case CSMWorld::Columns::ColumnId_DialogueType: return sDialogueTypeEnums; case CSMWorld::Columns::ColumnId_DialogueType: return sDialogueTypeEnums;
case CSMWorld::Columns::ColumnId_QuestStatusType: return sQuestStatusTypes; case CSMWorld::Columns::ColumnId_QuestStatusType: return sQuestStatusTypes;
case CSMWorld::Columns::ColumnId_Gender: return sGenderEnums; case CSMWorld::Columns::ColumnId_Gender: return sGenderEnums;
case CSMWorld::Columns::ColumnId_EnchantmentType: return sEnchantmentTypes;
case CSMWorld::Columns::ColumnId_BodyPartType: return sBodyPartTypes;
case CSMWorld::Columns::ColumnId_MeshType: return sMeshTypes;
default: return 0; default: return 0;
} }

View file

@ -172,6 +172,13 @@ namespace CSMWorld
ColumnId_ContainerContent = 157, ColumnId_ContainerContent = 157,
ColumnId_ItemCount = 158, ColumnId_ItemCount = 158,
ColumnId_InventoryItemId = 159, ColumnId_InventoryItemId = 159,
ColumnId_CombatState = 160,
ColumnId_MagicState = 161,
ColumnId_StealthState = 162,
ColumnId_EnchantmentType = 163,
ColumnId_Vampire = 164,
ColumnId_BodyPartType = 165,
ColumnId_MeshType = 166,
// Allocated to a separate value range, so we don't get a collision should we ever need // Allocated to a separate value range, so we don't get a collision should we ever need
// to extend the number of use values. // to extend the number of use values.

View file

@ -15,6 +15,8 @@
#include "columnimp.hpp" #include "columnimp.hpp"
#include "regionmap.hpp" #include "regionmap.hpp"
#include "columns.hpp" #include "columns.hpp"
#include "resourcesmanager.hpp"
#include "resourcetable.hpp"
void CSMWorld::Data::addModel (QAbstractItemModel *model, UniversalId::Type type, bool update) void CSMWorld::Data::addModel (QAbstractItemModel *model, UniversalId::Type type, bool update)
{ {
@ -56,8 +58,9 @@ int CSMWorld::Data::count (RecordBase::State state, const CollectionBase& collec
return number; return number;
} }
CSMWorld::Data::Data (ToUTF8::FromType encoding) CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourcesManager)
: mEncoder (encoding), mRefs (mCells), mReader (0), mDialogue (0) : mEncoder (encoding), mRefs (mCells), mResourcesManager (resourcesManager), mReader (0),
mDialogue (0)
{ {
mGlobals.addColumn (new StringIdColumn<ESM::Global>); mGlobals.addColumn (new StringIdColumn<ESM::Global>);
mGlobals.addColumn (new RecordStateColumn<ESM::Global>); mGlobals.addColumn (new RecordStateColumn<ESM::Global>);
@ -198,6 +201,25 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding)
mCells.addColumn (new FlagColumn<Cell> (Columns::ColumnId_InteriorSky, ESM::Cell::QuasiEx)); mCells.addColumn (new FlagColumn<Cell> (Columns::ColumnId_InteriorSky, ESM::Cell::QuasiEx));
mCells.addColumn (new RegionColumn<Cell>); mCells.addColumn (new RegionColumn<Cell>);
mEnchantments.addColumn (new StringIdColumn<ESM::Enchantment>);
mEnchantments.addColumn (new RecordStateColumn<ESM::Enchantment>);
mEnchantments.addColumn (new FixedRecordTypeColumn<ESM::Enchantment> (UniversalId::Type_Enchantment));
mEnchantments.addColumn (new EnchantmentTypeColumn<ESM::Enchantment>);
mEnchantments.addColumn (new CostColumn<ESM::Enchantment>);
mEnchantments.addColumn (new ChargesColumn2<ESM::Enchantment>);
mEnchantments.addColumn (new AutoCalcColumn<ESM::Enchantment>);
mBodyParts.addColumn (new StringIdColumn<ESM::BodyPart>);
mBodyParts.addColumn (new RecordStateColumn<ESM::BodyPart>);
mBodyParts.addColumn (new FixedRecordTypeColumn<ESM::BodyPart> (UniversalId::Type_BodyPart));
mBodyParts.addColumn (new BodyPartTypeColumn<ESM::BodyPart>);
mBodyParts.addColumn (new VampireColumn<ESM::BodyPart>);
mBodyParts.addColumn (new FlagColumn<ESM::BodyPart> (Columns::ColumnId_Female, ESM::BodyPart::BPF_Female));
mBodyParts.addColumn (new FlagColumn<ESM::BodyPart> (Columns::ColumnId_Playable, ESM::BodyPart::BPF_NotPlayable, true));
mBodyParts.addColumn (new MeshTypeColumn<ESM::BodyPart>);
mBodyParts.addColumn (new ModelColumn<ESM::BodyPart>);
mBodyParts.addColumn (new RaceColumn<ESM::BodyPart>);
mRefs.addColumn (new StringIdColumn<CellRef> (true)); mRefs.addColumn (new StringIdColumn<CellRef> (true));
mRefs.addColumn (new RecordStateColumn<CellRef>); mRefs.addColumn (new RecordStateColumn<CellRef>);
mRefs.addColumn (new FixedRecordTypeColumn<CellRef> (UniversalId::Type_Reference)); mRefs.addColumn (new FixedRecordTypeColumn<CellRef> (UniversalId::Type_Reference));
@ -252,10 +274,24 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding)
addModel (new IdTable (&mTopicInfos, IdTable::Feature_ReorderWithinTopic), UniversalId::Type_TopicInfo); addModel (new IdTable (&mTopicInfos, IdTable::Feature_ReorderWithinTopic), UniversalId::Type_TopicInfo);
addModel (new IdTable (&mJournalInfos, IdTable::Feature_ReorderWithinTopic), UniversalId::Type_JournalInfo); addModel (new IdTable (&mJournalInfos, IdTable::Feature_ReorderWithinTopic), UniversalId::Type_JournalInfo);
addModel (new IdTable (&mCells, IdTable::Feature_ViewId), UniversalId::Type_Cell); addModel (new IdTable (&mCells, IdTable::Feature_ViewId), UniversalId::Type_Cell);
addModel (new IdTable (&mEnchantments), UniversalId::Type_Enchantment);
addModel (new IdTable (&mBodyParts), UniversalId::Type_BodyPart);
addModel (new IdTable (&mReferenceables, IdTable::Feature_Preview), addModel (new IdTable (&mReferenceables, IdTable::Feature_Preview),
UniversalId::Type_Referenceable); UniversalId::Type_Referenceable);
addModel (new IdTable (&mRefs, IdTable::Feature_ViewCell | IdTable::Feature_Preview), UniversalId::Type_Reference); addModel (new IdTable (&mRefs, IdTable::Feature_ViewCell | IdTable::Feature_Preview), UniversalId::Type_Reference);
addModel (new IdTable (&mFilters), UniversalId::Type_Filter); addModel (new IdTable (&mFilters), UniversalId::Type_Filter);
addModel (new ResourceTable (&mResourcesManager.get (UniversalId::Type_Mesh)),
UniversalId::Type_Mesh);
addModel (new ResourceTable (&mResourcesManager.get (UniversalId::Type_Icon)),
UniversalId::Type_Icon);
addModel (new ResourceTable (&mResourcesManager.get (UniversalId::Type_Music)),
UniversalId::Type_Music);
addModel (new ResourceTable (&mResourcesManager.get (UniversalId::Type_SoundRes)),
UniversalId::Type_SoundRes);
addModel (new ResourceTable (&mResourcesManager.get (UniversalId::Type_Texture)),
UniversalId::Type_Texture);
addModel (new ResourceTable (&mResourcesManager.get (UniversalId::Type_Video)),
UniversalId::Type_Video);
} }
CSMWorld::Data::~Data() CSMWorld::Data::~Data()
@ -457,6 +493,31 @@ CSMWorld::IdCollection<CSMFilter::Filter>& CSMWorld::Data::getFilters()
return mFilters; return mFilters;
} }
const CSMWorld::IdCollection<ESM::Enchantment>& CSMWorld::Data::getEnchantments() const
{
return mEnchantments;
}
CSMWorld::IdCollection<ESM::Enchantment>& CSMWorld::Data::getEnchantments()
{
return mEnchantments;
}
const CSMWorld::IdCollection<ESM::BodyPart>& CSMWorld::Data::getBodyParts() const
{
return mBodyParts;
}
CSMWorld::IdCollection<ESM::BodyPart>& CSMWorld::Data::getBodyParts()
{
return mBodyParts;
}
const CSMWorld::Resources& CSMWorld::Data::getResources (const UniversalId& id) const
{
return mResourcesManager.get (UniversalId::getParentType (id.getType()));
}
QAbstractItemModel *CSMWorld::Data::getTableModel (const CSMWorld::UniversalId& id) QAbstractItemModel *CSMWorld::Data::getTableModel (const CSMWorld::UniversalId& id)
{ {
std::map<UniversalId::Type, QAbstractItemModel *>::iterator iter = mModelIndex.find (id.getType()); std::map<UniversalId::Type, QAbstractItemModel *>::iterator iter = mModelIndex.find (id.getType());
@ -534,6 +595,8 @@ bool CSMWorld::Data::continueLoading (CSMDoc::Stage::Messages& messages)
case ESM::REC_REGN: mRegions.load (*mReader, mBase); break; case ESM::REC_REGN: mRegions.load (*mReader, mBase); break;
case ESM::REC_BSGN: mBirthsigns.load (*mReader, mBase); break; case ESM::REC_BSGN: mBirthsigns.load (*mReader, mBase); break;
case ESM::REC_SPEL: mSpells.load (*mReader, mBase); break; case ESM::REC_SPEL: mSpells.load (*mReader, mBase); break;
case ESM::REC_ENCH: mEnchantments.load (*mReader, mBase); break;
case ESM::REC_BODY: mBodyParts.load (*mReader, mBase); break;
case ESM::REC_CELL: case ESM::REC_CELL:
{ {
@ -668,6 +731,8 @@ bool CSMWorld::Data::hasId (const std::string& id) const
getTopics().searchId (id)!=-1 || getTopics().searchId (id)!=-1 ||
getJournals().searchId (id)!=-1 || getJournals().searchId (id)!=-1 ||
getCells().searchId (id)!=-1 || getCells().searchId (id)!=-1 ||
getEnchantments().searchId (id)!=-1 ||
getBodyParts().searchId (id)!=-1 ||
getReferenceables().searchId (id)!=-1; getReferenceables().searchId (id)!=-1;
} }
@ -686,6 +751,8 @@ int CSMWorld::Data::count (RecordBase::State state) const
count (state, mBirthsigns) + count (state, mBirthsigns) +
count (state, mSpells) + count (state, mSpells) +
count (state, mCells) + count (state, mCells) +
count (state, mEnchantments) +
count (state, mBodyParts) +
count (state, mReferenceables); count (state, mReferenceables);
} }
@ -726,6 +793,8 @@ std::vector<std::string> CSMWorld::Data::getIds (bool listDeleted) const
appendIds (ids, mTopics, listDeleted); appendIds (ids, mTopics, listDeleted);
appendIds (ids, mJournals, listDeleted); appendIds (ids, mJournals, listDeleted);
appendIds (ids, mCells, listDeleted); appendIds (ids, mCells, listDeleted);
appendIds (ids, mEnchantments, listDeleted);
appendIds (ids, mBodyParts, listDeleted);
appendIds (ids, mReferenceables, listDeleted); appendIds (ids, mReferenceables, listDeleted);
std::sort (ids.begin(), ids.end()); std::sort (ids.begin(), ids.end());

View file

@ -21,6 +21,8 @@
#include <components/esm/loadbsgn.hpp> #include <components/esm/loadbsgn.hpp>
#include <components/esm/loadspel.hpp> #include <components/esm/loadspel.hpp>
#include <components/esm/loaddial.hpp> #include <components/esm/loaddial.hpp>
#include <components/esm/loadench.hpp>
#include <components/esm/loadbody.hpp>
#include <components/to_utf8/to_utf8.hpp> #include <components/to_utf8/to_utf8.hpp>
@ -45,6 +47,9 @@ namespace ESM
namespace CSMWorld namespace CSMWorld
{ {
class ResourcesManager;
class Resources;
class Data : public QObject class Data : public QObject
{ {
Q_OBJECT Q_OBJECT
@ -63,12 +68,15 @@ namespace CSMWorld
IdCollection<ESM::Spell> mSpells; IdCollection<ESM::Spell> mSpells;
IdCollection<ESM::Dialogue> mTopics; IdCollection<ESM::Dialogue> mTopics;
IdCollection<ESM::Dialogue> mJournals; IdCollection<ESM::Dialogue> mJournals;
IdCollection<ESM::Enchantment> mEnchantments;
IdCollection<ESM::BodyPart> mBodyParts;
InfoCollection mTopicInfos; InfoCollection mTopicInfos;
InfoCollection mJournalInfos; InfoCollection mJournalInfos;
IdCollection<Cell> mCells; IdCollection<Cell> mCells;
RefIdCollection mReferenceables; RefIdCollection mReferenceables;
RefCollection mRefs; RefCollection mRefs;
IdCollection<CSMFilter::Filter> mFilters; IdCollection<CSMFilter::Filter> mFilters;
const ResourcesManager& mResourcesManager;
std::vector<QAbstractItemModel *> mModels; std::vector<QAbstractItemModel *> mModels;
std::map<UniversalId::Type, QAbstractItemModel *> mModelIndex; std::map<UniversalId::Type, QAbstractItemModel *> mModelIndex;
std::string mAuthor; std::string mAuthor;
@ -94,7 +102,7 @@ namespace CSMWorld
public: public:
Data (ToUTF8::FromType encoding); Data (ToUTF8::FromType encoding, const ResourcesManager& resourcesManager);
virtual ~Data(); virtual ~Data();
@ -174,6 +182,17 @@ namespace CSMWorld
IdCollection<CSMFilter::Filter>& getFilters(); IdCollection<CSMFilter::Filter>& getFilters();
const IdCollection<ESM::Enchantment>& getEnchantments() const;
IdCollection<ESM::Enchantment>& getEnchantments();
const IdCollection<ESM::BodyPart>& getBodyParts() const;
IdCollection<ESM::BodyPart>& getBodyParts();
/// Throws an exception, if \a id does not match a resources list.
const Resources& getResources (const UniversalId& id) const;
QAbstractItemModel *getTableModel (const UniversalId& id); QAbstractItemModel *getTableModel (const UniversalId& id);
///< If no table model is available for \a id, an exception is thrown. ///< If no table model is available for \a id, an exception is thrown.
/// ///

View file

@ -15,7 +15,10 @@ namespace CSMWorld
void load (ESM::ESMReader& reader, bool base); void load (ESM::ESMReader& reader, bool base);
void load (const ESXRecordT& record, bool base); /// \param index Index at which the record can be found.
/// Special values: -2 index unknown, -1 record does not exist yet and therefore
/// does not have an index
void load (const ESXRecordT& record, bool base, int index = -2);
bool tryDelete (const std::string& id); bool tryDelete (const std::string& id);
///< Try deleting \a id. If the id does not exist or can't be deleted the call is ignored. ///< Try deleting \a id. If the id does not exist or can't be deleted the call is ignored.
@ -56,17 +59,28 @@ namespace CSMWorld
else else
{ {
ESXRecordT record; ESXRecordT record;
IdAccessorT().getId (record) = id;
int index = this->searchId (id);
if (index==-1)
IdAccessorT().getId (record) = id;
else
{
record = this->getRecord (index).get();
}
record.load (reader); record.load (reader);
load (record, base); load (record, base, index);
} }
} }
template<typename ESXRecordT, typename IdAccessorT> template<typename ESXRecordT, typename IdAccessorT>
void IdCollection<ESXRecordT, IdAccessorT>::load (const ESXRecordT& record, bool base) void IdCollection<ESXRecordT, IdAccessorT>::load (const ESXRecordT& record, bool base,
int index)
{ {
int index = this->searchId (IdAccessorT().getId (record)); if (index==-2)
index = this->searchId (IdAccessorT().getId (record));
if (index==-1) if (index==-1)
{ {

View file

@ -7,7 +7,7 @@
#include "columnbase.hpp" #include "columnbase.hpp"
CSMWorld::IdTable::IdTable (CollectionBase *idCollection, unsigned int features) CSMWorld::IdTable::IdTable (CollectionBase *idCollection, unsigned int features)
: mIdCollection (idCollection), mFeatures (features) : IdTableBase (features), mIdCollection (idCollection)
{} {}
CSMWorld::IdTable::~IdTable() CSMWorld::IdTable::~IdTable()
@ -283,17 +283,12 @@ void CSMWorld::IdTable::reorderRows (int baseIndex, const std::vector<int>& newO
index (baseIndex+newOrder.size()-1, mIdCollection->getColumns()-1)); index (baseIndex+newOrder.size()-1, mIdCollection->getColumns()-1));
} }
unsigned int CSMWorld::IdTable::getFeatures() const
{
return mFeatures;
}
std::pair<CSMWorld::UniversalId, std::string> CSMWorld::IdTable::view (int row) const std::pair<CSMWorld::UniversalId, std::string> CSMWorld::IdTable::view (int row) const
{ {
std::string id; std::string id;
std::string hint; std::string hint;
if (mFeatures & Feature_ViewCell) if (getFeatures() & Feature_ViewCell)
{ {
int cellColumn = mIdCollection->searchColumnIndex (Columns::ColumnId_Cell); int cellColumn = mIdCollection->searchColumnIndex (Columns::ColumnId_Cell);
int idColumn = mIdCollection->searchColumnIndex (Columns::ColumnId_Id); int idColumn = mIdCollection->searchColumnIndex (Columns::ColumnId_Id);
@ -304,7 +299,7 @@ std::pair<CSMWorld::UniversalId, std::string> CSMWorld::IdTable::view (int row)
hint = "r:" + std::string (mIdCollection->getData (row, idColumn).toString().toUtf8().constData()); hint = "r:" + std::string (mIdCollection->getData (row, idColumn).toString().toUtf8().constData());
} }
} }
else if (mFeatures & Feature_ViewId) else if (getFeatures() & Feature_ViewId)
{ {
int column = mIdCollection->searchColumnIndex (Columns::ColumnId_Id); int column = mIdCollection->searchColumnIndex (Columns::ColumnId_Id);
@ -325,6 +320,11 @@ std::pair<CSMWorld::UniversalId, std::string> CSMWorld::IdTable::view (int row)
} }
///For top level data/columns ///For top level data/columns
bool CSMWorld::IdTable::isDeleted (const std::string& id) const
{
return getRecord (id).isDeleted();
}
int CSMWorld::IdTable::getColumnId(int column) const int CSMWorld::IdTable::getColumnId(int column) const
{ {
return mIdCollection->getColumn(column).getId(); return mIdCollection->getColumn(column).getId();

View file

@ -3,8 +3,7 @@
#include <vector> #include <vector>
#include <QAbstractItemModel> #include "idtablebase.hpp"
#include "universalid.hpp" #include "universalid.hpp"
#include "columns.hpp" #include "columns.hpp"
@ -22,34 +21,13 @@ namespace CSMWorld
class CollectionBase; class CollectionBase;
class RecordBase; class RecordBase;
class IdTable : public QAbstractItemModel class IdTable : public IdTableBase
{ {
Q_OBJECT Q_OBJECT
public:
enum Features
{
Feature_ReorderWithinTopic = 1,
/// Use ID column to generate view request (ID is transformed into
/// worldspace and original ID is passed as hint with c: prefix).
Feature_ViewId = 2,
/// Use cell column to generate view request (cell ID is transformed
/// into worldspace and record ID is passed as hint with r: prefix).
Feature_ViewCell = 4,
Feature_View = Feature_ViewId | Feature_ViewCell,
Feature_Preview = 8
};
private: private:
CollectionBase *mIdCollection; CollectionBase *mIdCollection;
unsigned int mFeatures;
bool mPreview;
// not implemented // not implemented
IdTable (const IdTable&); IdTable (const IdTable&);
@ -96,17 +74,17 @@ namespace CSMWorld
const std::string& destination, const std::string& destination,
UniversalId::Type type = UniversalId::Type_None); UniversalId::Type type = UniversalId::Type_None);
QModelIndex getModelIndex (const std::string& id, int column) const; virtual QModelIndex getModelIndex (const std::string& id, int column) const;
void setRecord (const std::string& id, const RecordBase& record); void setRecord (const std::string& id, const RecordBase& record);
///< Add record or overwrite existing recrod. ///< Add record or overwrite existing recrod.
const RecordBase& getRecord (const std::string& id) const; const RecordBase& getRecord (const std::string& id) const;
int searchColumnIndex (Columns::ColumnId id) const; virtual int searchColumnIndex (Columns::ColumnId id) const;
///< Return index of column with the given \a id. If no such column exists, -1 is returned. ///< Return index of column with the given \a id. If no such column exists, -1 is returned.
int findColumnIndex (Columns::ColumnId id) const; virtual int findColumnIndex (Columns::ColumnId id) const;
///< Return index of column with the given \a id. If no such column exists, an exception is ///< Return index of column with the given \a id. If no such column exists, an exception is
/// thrown. /// thrown.
@ -114,12 +92,13 @@ namespace CSMWorld
///< Reorder the rows [baseIndex, baseIndex+newOrder.size()) according to the indices ///< Reorder the rows [baseIndex, baseIndex+newOrder.size()) according to the indices
/// given in \a newOrder (baseIndex+newOrder[0] specifies the new index of row baseIndex). /// given in \a newOrder (baseIndex+newOrder[0] specifies the new index of row baseIndex).
unsigned int getFeatures() const; virtual std::pair<UniversalId, std::string> view (int row) const;
std::pair<UniversalId, std::string> view (int row) const;
///< Return the UniversalId and the hint for viewing \a row. If viewing is not ///< Return the UniversalId and the hint for viewing \a row. If viewing is not
/// supported by this table, return (UniversalId::Type_None, ""). /// supported by this table, return (UniversalId::Type_None, "").
/// Is \a id flagged as deleted?
virtual bool isDeleted (const std::string& id) const;
int getColumnId(int column) const; int getColumnId(int column) const;
}; };
} }

View file

@ -0,0 +1,9 @@
#include "idtablebase.hpp"
CSMWorld::IdTableBase::IdTableBase (unsigned int features) : mFeatures (features) {}
unsigned int CSMWorld::IdTableBase::getFeatures() const
{
return mFeatures;
}

View file

@ -0,0 +1,67 @@
#ifndef CSM_WOLRD_IDTABLEBASE_H
#define CSM_WOLRD_IDTABLEBASE_H
#include <QAbstractItemModel>
#include "columns.hpp"
namespace CSMWorld
{
class UniversalId;
class IdTableBase : public QAbstractItemModel
{
Q_OBJECT
public:
enum Features
{
Feature_ReorderWithinTopic = 1,
/// Use ID column to generate view request (ID is transformed into
/// worldspace and original ID is passed as hint with c: prefix).
Feature_ViewId = 2,
/// Use cell column to generate view request (cell ID is transformed
/// into worldspace and record ID is passed as hint with r: prefix).
Feature_ViewCell = 4,
Feature_View = Feature_ViewId | Feature_ViewCell,
Feature_Preview = 8,
/// Table can not be modified through ordinary means.
Feature_Constant = 16
};
private:
unsigned int mFeatures;
public:
IdTableBase (unsigned int features);
virtual QModelIndex getModelIndex (const std::string& id, int column) const = 0;
/// Return index of column with the given \a id. If no such column exists, -1 is
/// returned.
virtual int searchColumnIndex (Columns::ColumnId id) const = 0;
/// Return index of column with the given \a id. If no such column exists, an
/// exception is thrown.
virtual int findColumnIndex (Columns::ColumnId id) const = 0;
/// Return the UniversalId and the hint for viewing \a row. If viewing is not
/// supported by this table, return (UniversalId::Type_None, "").
virtual std::pair<UniversalId, std::string> view (int row) const = 0;
/// Is \a id flagged as deleted?
virtual bool isDeleted (const std::string& id) const = 0;
unsigned int getFeatures() const;
};
}
#endif

View file

@ -3,7 +3,7 @@
#include <vector> #include <vector>
#include "idtable.hpp" #include "idtablebase.hpp"
void CSMWorld::IdTableProxyModel::updateColumnMap() void CSMWorld::IdTableProxyModel::updateColumnMap()
{ {
@ -13,7 +13,7 @@ void CSMWorld::IdTableProxyModel::updateColumnMap()
{ {
std::vector<int> columns = mFilter->getReferencedColumns(); std::vector<int> columns = mFilter->getReferencedColumns();
const IdTable& table = dynamic_cast<const IdTable&> (*sourceModel()); const IdTableBase& table = dynamic_cast<const IdTableBase&> (*sourceModel());
for (std::vector<int>::const_iterator iter (columns.begin()); iter!=columns.end(); ++iter) for (std::vector<int>::const_iterator iter (columns.begin()); iter!=columns.end(); ++iter)
mColumnMap.insert (std::make_pair (*iter, mColumnMap.insert (std::make_pair (*iter,
@ -28,7 +28,7 @@ bool CSMWorld::IdTableProxyModel::filterAcceptsRow (int sourceRow, const QModelI
return true; return true;
return mFilter->test ( return mFilter->test (
dynamic_cast<IdTable&> (*sourceModel()), sourceRow, mColumnMap); dynamic_cast<IdTableBase&> (*sourceModel()), sourceRow, mColumnMap);
} }
CSMWorld::IdTableProxyModel::IdTableProxyModel (QObject *parent) CSMWorld::IdTableProxyModel::IdTableProxyModel (QObject *parent)
@ -39,7 +39,7 @@ CSMWorld::IdTableProxyModel::IdTableProxyModel (QObject *parent)
QModelIndex CSMWorld::IdTableProxyModel::getModelIndex (const std::string& id, int column) const QModelIndex CSMWorld::IdTableProxyModel::getModelIndex (const std::string& id, int column) const
{ {
return mapFromSource (dynamic_cast<IdTable&> (*sourceModel()).getModelIndex (id, column)); return mapFromSource (dynamic_cast<IdTableBase&> (*sourceModel()).getModelIndex (id, column));
} }
void CSMWorld::IdTableProxyModel::setFilter (const boost::shared_ptr<CSMFilter::Node>& filter) void CSMWorld::IdTableProxyModel::setFilter (const boost::shared_ptr<CSMFilter::Node>& filter)

View file

@ -361,6 +361,15 @@ QVariant CSMWorld::CreatureRefIdAdapter::getData (const RefIdColumn *column, con
if (column==mColumns.mOriginal) if (column==mColumns.mOriginal)
return QString::fromUtf8 (record.get().mOriginal.c_str()); return QString::fromUtf8 (record.get().mOriginal.c_str());
if (column==mColumns.mCombat)
return static_cast<int> (record.get().mData.mCombat);
if (column==mColumns.mMagic)
return static_cast<int> (record.get().mData.mMagic);
if (column==mColumns.mStealth)
return static_cast<int> (record.get().mData.mStealth);
std::map<const RefIdColumn *, unsigned int>::const_iterator iter = std::map<const RefIdColumn *, unsigned int>::const_iterator iter =
mColumns.mFlags.find (column); mColumns.mFlags.find (column);
@ -384,6 +393,12 @@ void CSMWorld::CreatureRefIdAdapter::setData (const RefIdColumn *column, RefIdDa
record.get().mScale = value.toFloat(); record.get().mScale = value.toFloat();
else if (column==mColumns.mOriginal) else if (column==mColumns.mOriginal)
record.get().mOriginal = value.toString().toUtf8().constData(); record.get().mOriginal = value.toString().toUtf8().constData();
else if (column==mColumns.mCombat)
record.get().mData.mCombat = value.toInt();
else if (column==mColumns.mMagic)
record.get().mData.mMagic = value.toInt();
else if (column==mColumns.mStealth)
record.get().mData.mStealth = value.toInt();
else else
{ {
std::map<const RefIdColumn *, unsigned int>::const_iterator iter = std::map<const RefIdColumn *, unsigned int>::const_iterator iter =

View file

@ -646,6 +646,9 @@ namespace CSMWorld
const RefIdColumn *mSoul; const RefIdColumn *mSoul;
const RefIdColumn *mScale; const RefIdColumn *mScale;
const RefIdColumn *mOriginal; const RefIdColumn *mOriginal;
const RefIdColumn *mCombat;
const RefIdColumn *mMagic;
const RefIdColumn *mStealth;
CreatureColumns (const ActorColumns& actorColumns); CreatureColumns (const ActorColumns& actorColumns);
}; };

View file

@ -53,7 +53,7 @@ CSMWorld::RefIdCollection::RefIdCollection()
ModelColumns modelColumns (baseColumns); ModelColumns modelColumns (baseColumns);
mColumns.push_back (RefIdColumn (Columns::ColumnId_Model, ColumnBase::Display_String)); mColumns.push_back (RefIdColumn (Columns::ColumnId_Model, ColumnBase::Display_Mesh));
modelColumns.mModel = &mColumns.back(); modelColumns.mModel = &mColumns.back();
NameColumns nameColumns (modelColumns); NameColumns nameColumns (modelColumns);
@ -65,7 +65,7 @@ CSMWorld::RefIdCollection::RefIdCollection()
InventoryColumns inventoryColumns (nameColumns); InventoryColumns inventoryColumns (nameColumns);
mColumns.push_back (RefIdColumn (Columns::ColumnId_Icon, ColumnBase::Display_String)); mColumns.push_back (RefIdColumn (Columns::ColumnId_Icon, ColumnBase::Display_Icon));
inventoryColumns.mIcon = &mColumns.back(); inventoryColumns.mIcon = &mColumns.back();
mColumns.push_back (RefIdColumn (Columns::ColumnId_Weight, ColumnBase::Display_Float)); mColumns.push_back (RefIdColumn (Columns::ColumnId_Weight, ColumnBase::Display_Float));
inventoryColumns.mWeight = &mColumns.back(); inventoryColumns.mWeight = &mColumns.back();
@ -183,6 +183,15 @@ CSMWorld::RefIdCollection::RefIdCollection()
creatureColumns.mScale = &mColumns.back(); creatureColumns.mScale = &mColumns.back();
mColumns.push_back (RefIdColumn (Columns::ColumnId_OriginalCreature, ColumnBase::Display_String)); mColumns.push_back (RefIdColumn (Columns::ColumnId_OriginalCreature, ColumnBase::Display_String));
creatureColumns.mOriginal = &mColumns.back(); creatureColumns.mOriginal = &mColumns.back();
mColumns.push_back (
RefIdColumn (Columns::ColumnId_CombatState, ColumnBase::Display_Integer));
creatureColumns.mCombat = &mColumns.back();
mColumns.push_back (
RefIdColumn (Columns::ColumnId_MagicState, ColumnBase::Display_Integer));
creatureColumns.mMagic = &mColumns.back();
mColumns.push_back (
RefIdColumn (Columns::ColumnId_StealthState, ColumnBase::Display_Integer));
creatureColumns.mStealth = &mColumns.back();
static const struct static const struct
{ {

View file

@ -0,0 +1,103 @@
#include "resources.hpp"
#include <sstream>
#include <stdexcept>
#include <OgreResourceGroupManager.h>
#include <components/misc/stringops.hpp>
CSMWorld::Resources::Resources (const std::string& baseDirectory, UniversalId::Type type,
const char * const *extensions)
: mBaseDirectory (baseDirectory), mType (type)
{
int baseSize = mBaseDirectory.size();
Ogre::StringVector resourcesGroups =
Ogre::ResourceGroupManager::getSingleton().getResourceGroups();
for (Ogre::StringVector::iterator iter (resourcesGroups.begin());
iter!=resourcesGroups.end(); ++iter)
{
if (*iter=="General" || *iter=="Internal" || *iter=="Autodetect")
continue;
Ogre::StringVectorPtr resources =
Ogre::ResourceGroupManager::getSingleton().listResourceNames (*iter);
for (Ogre::StringVector::const_iterator iter (resources->begin());
iter!=resources->end(); ++iter)
{
if (static_cast<int> (iter->size())<baseSize+1 ||
iter->substr (0, baseSize)!=mBaseDirectory ||
((*iter)[baseSize]!='/' && (*iter)[baseSize]!='\\'))
continue;
if (extensions)
{
std::string::size_type index = iter->find_last_of ('.');
if (index==std::string::npos)
continue;
std::string extension = iter->substr (index+1);
int i = 0;
for (; extensions[i]; ++i)
if (extensions[i]==extension)
break;
if (!extensions[i])
continue;
}
std::string file = iter->substr (baseSize+1);
mFiles.push_back (file);
mIndex.insert (std::make_pair (file, static_cast<int> (mFiles.size())-1));
}
}
}
int CSMWorld::Resources::getSize() const
{
return mFiles.size();
}
std::string CSMWorld::Resources::getId (int index) const
{
return mFiles.at (index);
}
int CSMWorld::Resources::getIndex (const std::string& id) const
{
int index = searchId (id);
if (index==-1)
{
std::ostringstream stream;
stream << "Invalid resource: " << mBaseDirectory << '/' << id;
throw std::runtime_error (stream.str().c_str());
}
return index;
}
int CSMWorld::Resources::searchId (const std::string& id) const
{
std::string id2 = Misc::StringUtils::lowerCase (id);
std::map<std::string, int>::const_iterator iter = mIndex.find (id2);
if (iter==mIndex.end())
return -1;
return iter->second;
}
CSMWorld::UniversalId::Type CSMWorld::Resources::getType() const
{
return mType;
}

View file

@ -0,0 +1,37 @@
#ifndef CSM_WOLRD_RESOURCES_H
#define CSM_WOLRD_RESOURCES_H
#include <string>
#include <map>
#include <vector>
#include "universalid.hpp"
namespace CSMWorld
{
class Resources
{
std::map<std::string, int> mIndex;
std::vector<std::string> mFiles;
std::string mBaseDirectory;
UniversalId::Type mType;
public:
/// \param type Type of resources in this table.
Resources (const std::string& baseDirectory, UniversalId::Type type,
const char * const *extensions = 0);
int getSize() const;
std::string getId (int index) const;
int getIndex (const std::string& id) const;
int searchId (const std::string& id) const;
UniversalId::Type getType() const;
};
}
#endif

View file

@ -0,0 +1,31 @@
#include "resourcesmanager.hpp"
#include <stdexcept>
void CSMWorld::ResourcesManager::addResources (const Resources& resources)
{
mResources.insert (std::make_pair (resources.getType(), resources));
}
void CSMWorld::ResourcesManager::listResources()
{
static const char * const sMeshTypes[] = { "nif", 0 };
addResources (Resources ("meshes", UniversalId::Type_Mesh, sMeshTypes));
addResources (Resources ("icons", UniversalId::Type_Icon));
addResources (Resources ("music", UniversalId::Type_Music));
addResources (Resources ("sound", UniversalId::Type_SoundRes));
addResources (Resources ("textures", UniversalId::Type_Texture));
addResources (Resources ("videos", UniversalId::Type_Video));
}
const CSMWorld::Resources& CSMWorld::ResourcesManager::get (UniversalId::Type type) const
{
std::map<UniversalId::Type, Resources>::const_iterator iter = mResources.find (type);
if (iter==mResources.end())
throw std::logic_error ("Unknown resource type");
return iter->second;
}

View file

@ -0,0 +1,28 @@
#ifndef CSM_WOLRD_RESOURCESMANAGER_H
#define CSM_WOLRD_RESOURCESMANAGER_H
#include <map>
#include "universalid.hpp"
#include "resources.hpp"
namespace CSMWorld
{
class ResourcesManager
{
std::map<UniversalId::Type, Resources> mResources;
private:
void addResources (const Resources& resources);
public:
/// Ask OGRE for a list of available resources.
void listResources();
const Resources& get (UniversalId::Type type) const;
};
}
#endif

View file

@ -0,0 +1,146 @@
#include "resourcetable.hpp"
#include <stdexcept>
#include "resources.hpp"
#include "columnbase.hpp"
#include "universalid.hpp"
CSMWorld::ResourceTable::ResourceTable (const Resources *resources, unsigned int features)
: IdTableBase (features | Feature_Constant), mResources (resources)
{}
CSMWorld::ResourceTable::~ResourceTable() {}
int CSMWorld::ResourceTable::rowCount (const QModelIndex & parent) const
{
if (parent.isValid())
return 0;
return mResources->getSize();
}
int CSMWorld::ResourceTable::columnCount (const QModelIndex & parent) const
{
if (parent.isValid())
return 0;
return 2; // ID, type
}
QVariant CSMWorld::ResourceTable::data (const QModelIndex & index, int role) const
{
if (role!=Qt::DisplayRole)
return QVariant();
if (index.column()==0)
return QString::fromUtf8 (mResources->getId (index.row()).c_str());
if (index.column()==1)
return static_cast<int> (mResources->getType());
throw std::logic_error ("Invalid column in resource table");
}
QVariant CSMWorld::ResourceTable::headerData (int section, Qt::Orientation orientation,
int role ) const
{
if (orientation==Qt::Vertical)
return QVariant();
if (role==ColumnBase::Role_Flags)
return ColumnBase::Flag_Table;
switch (section)
{
case 0:
if (role==Qt::DisplayRole)
return Columns::getName (Columns::ColumnId_Id).c_str();
if (role==ColumnBase::Role_Display)
return ColumnBase::Display_String;
break;
case 1:
if (role==Qt::DisplayRole)
return Columns::getName (Columns::ColumnId_RecordType).c_str();
if (role==ColumnBase::Role_Display)
return ColumnBase::Display_Integer;
break;
}
return QVariant();
}
bool CSMWorld::ResourceTable::setData ( const QModelIndex &index, const QVariant &value,
int role)
{
return false;
}
Qt::ItemFlags CSMWorld::ResourceTable::flags (const QModelIndex & index) const
{
return Qt::ItemIsSelectable | Qt::ItemIsEnabled;;
}
QModelIndex CSMWorld::ResourceTable::index (int row, int column, const QModelIndex& parent)
const
{
if (parent.isValid())
return QModelIndex();
if (row<0 || row>=mResources->getSize())
return QModelIndex();
if (column<0 || column>1)
return QModelIndex();
return createIndex (row, column);
}
QModelIndex CSMWorld::ResourceTable::parent (const QModelIndex& index) const
{
return QModelIndex();
}
QModelIndex CSMWorld::ResourceTable::getModelIndex (const std::string& id, int column) const
{
return index (mResources->getIndex (id), column);
}
int CSMWorld::ResourceTable::searchColumnIndex (Columns::ColumnId id) const
{
if (id==Columns::ColumnId_Id)
return 0;
if (id==Columns::ColumnId_RecordType)
return 1;
return -1;
}
int CSMWorld::ResourceTable::findColumnIndex (Columns::ColumnId id) const
{
int index = searchColumnIndex (id);
if (index==-1)
throw std::logic_error ("invalid column index");
return index;
}
std::pair<CSMWorld::UniversalId, std::string> CSMWorld::ResourceTable::view (int row) const
{
return std::make_pair (UniversalId::Type_None, "");
}
bool CSMWorld::ResourceTable::isDeleted (const std::string& id) const
{
return false;
}

View file

@ -0,0 +1,57 @@
#ifndef CSM_WOLRD_RESOURCETABLE_H
#define CSM_WOLRD_RESOURCETABLE_H
#include "idtablebase.hpp"
namespace CSMWorld
{
class Resources;
class ResourceTable : public IdTableBase
{
const Resources *mResources;
public:
/// \note The feature Feature_Constant will be added implicitly.
ResourceTable (const Resources *resources, unsigned int features = 0);
virtual ~ResourceTable();
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 QModelIndex index (int row, int column, const QModelIndex& parent = QModelIndex())
const;
virtual QModelIndex parent (const QModelIndex& index) const;
virtual QModelIndex getModelIndex (const std::string& id, int column) const;
/// Return index of column with the given \a id. If no such column exists, -1 is
/// returned.
virtual int searchColumnIndex (Columns::ColumnId id) const;
/// Return index of column with the given \a id. If no such column exists, an
/// exception is thrown.
virtual int findColumnIndex (Columns::ColumnId id) const;
/// Return the UniversalId and the hint for viewing \a row. If viewing is not
/// supported by this table, return (UniversalId::Type_None, "").
virtual std::pair<UniversalId, std::string> view (int row) const;
/// Is \a id flagged as deleted?
virtual bool isDeleted (const std::string& id) const;
};
}
#endif

View file

@ -37,7 +37,7 @@ std::string CSMWorld::TableMimeData::getIcon() const
if (mUniversalId.empty()) if (mUniversalId.empty())
{ {
qDebug()<<"TableMimeData object does not hold any records!"; //because throwing in the event loop tends to be problematic qDebug()<<"TableMimeData object does not hold any records!"; //because throwing in the event loop tends to be problematic
throw("TableMimeData object does not hold any records!"); throw std::runtime_error ("TableMimeData object does not hold any records!");
} }
std::string tmpIcon; std::string tmpIcon;
@ -179,7 +179,7 @@ CSMWorld::UniversalId CSMWorld::TableMimeData::returnMatching (CSMWorld::Univers
} }
} }
throw ("TableMimeData object does not hold object of the seeked type"); throw std::runtime_error ("TableMimeData object does not hold object of the seeked type");
} }
CSMWorld::UniversalId CSMWorld::TableMimeData::returnMatching (CSMWorld::ColumnBase::Display type) const CSMWorld::UniversalId CSMWorld::TableMimeData::returnMatching (CSMWorld::ColumnBase::Display type) const
@ -201,7 +201,7 @@ CSMWorld::UniversalId CSMWorld::TableMimeData::returnMatching (CSMWorld::ColumnB
} }
} }
throw ("TableMimeData object does not hold object of the seeked type"); throw std::runtime_error ("TableMimeData object does not hold object of the seeked type");
} }
bool CSMWorld::TableMimeData::fromDocument (const CSMDoc::Document& document) const bool CSMWorld::TableMimeData::fromDocument (const CSMDoc::Document& document) const
@ -209,327 +209,82 @@ bool CSMWorld::TableMimeData::fromDocument (const CSMDoc::Document& document) co
return &document == &mDocument; return &document == &mDocument;
} }
CSMWorld::UniversalId::Type CSMWorld::TableMimeData::convertEnums (CSMWorld::ColumnBase::Display type) namespace
{ {
switch (type) struct Mapping
{ {
case CSMWorld::ColumnBase::Display_Race: CSMWorld::UniversalId::Type mUniversalIdType;
return CSMWorld::UniversalId::Type_Race; CSMWorld::ColumnBase::Display mDisplayType;
};
case CSMWorld::ColumnBase::Display_Skill: const Mapping mapping[] =
return CSMWorld::UniversalId::Type_Skill; {
{ CSMWorld::UniversalId::Type_Race, CSMWorld::ColumnBase::Display_Race },
{ CSMWorld::UniversalId::Type_Skill, CSMWorld::ColumnBase::Display_Skill },
case CSMWorld::ColumnBase::Display_Class: { CSMWorld::UniversalId::Type_Class, CSMWorld::ColumnBase::Display_Class },
return CSMWorld::UniversalId::Type_Class; { CSMWorld::UniversalId::Type_Class, CSMWorld::ColumnBase::Display_Class },
{ CSMWorld::UniversalId::Type_Faction, CSMWorld::ColumnBase::Display_Faction },
{ CSMWorld::UniversalId::Type_Sound, CSMWorld::ColumnBase::Display_Sound },
case CSMWorld::ColumnBase::Display_Faction: { CSMWorld::UniversalId::Type_Region, CSMWorld::ColumnBase::Display_Region },
return CSMWorld::UniversalId::Type_Faction; { CSMWorld::UniversalId::Type_Birthsign, CSMWorld::ColumnBase::Display_Birthsign },
{ CSMWorld::UniversalId::Type_Spell, CSMWorld::ColumnBase::Display_Spell },
{ CSMWorld::UniversalId::Type_Cell, CSMWorld::ColumnBase::Display_Cell },
case CSMWorld::ColumnBase::Display_Sound: { CSMWorld::UniversalId::Type_Referenceable, CSMWorld::ColumnBase::Display_Referenceable },
return CSMWorld::UniversalId::Type_Sound; { CSMWorld::UniversalId::Type_Activator, CSMWorld::ColumnBase::Display_Activator },
{ CSMWorld::UniversalId::Type_Potion, CSMWorld::ColumnBase::Display_Potion },
{ CSMWorld::UniversalId::Type_Apparatus, CSMWorld::ColumnBase::Display_Apparatus },
case CSMWorld::ColumnBase::Display_Region: { CSMWorld::UniversalId::Type_Armor, CSMWorld::ColumnBase::Display_Armor },
return CSMWorld::UniversalId::Type_Region; { CSMWorld::UniversalId::Type_Book, CSMWorld::ColumnBase::Display_Book },
{ CSMWorld::UniversalId::Type_Clothing, CSMWorld::ColumnBase::Display_Clothing },
{ CSMWorld::UniversalId::Type_Container, CSMWorld::ColumnBase::Display_Container },
case CSMWorld::ColumnBase::Display_Birthsign: { CSMWorld::UniversalId::Type_Creature, CSMWorld::ColumnBase::Display_Creature },
return CSMWorld::UniversalId::Type_Birthsign; { CSMWorld::UniversalId::Type_Door, CSMWorld::ColumnBase::Display_Door },
{ CSMWorld::UniversalId::Type_Ingredient, CSMWorld::ColumnBase::Display_Ingredient },
{ CSMWorld::UniversalId::Type_CreatureLevelledList, CSMWorld::ColumnBase::Display_CreatureLevelledList },
case CSMWorld::ColumnBase::Display_Spell: { CSMWorld::UniversalId::Type_ItemLevelledList, CSMWorld::ColumnBase::Display_ItemLevelledList },
return CSMWorld::UniversalId::Type_Spell; { CSMWorld::UniversalId::Type_Light, CSMWorld::ColumnBase::Display_Light },
{ CSMWorld::UniversalId::Type_Lockpick, CSMWorld::ColumnBase::Display_Lockpick },
{ CSMWorld::UniversalId::Type_Miscellaneous, CSMWorld::ColumnBase::Display_Miscellaneous },
case CSMWorld::ColumnBase::Display_Cell: { CSMWorld::UniversalId::Type_Npc, CSMWorld::ColumnBase::Display_Npc },
return CSMWorld::UniversalId::Type_Cell; { CSMWorld::UniversalId::Type_Probe, CSMWorld::ColumnBase::Display_Probe },
{ CSMWorld::UniversalId::Type_Repair, CSMWorld::ColumnBase::Display_Repair },
{ CSMWorld::UniversalId::Type_Static, CSMWorld::ColumnBase::Display_Static },
case CSMWorld::ColumnBase::Display_Referenceable: { CSMWorld::UniversalId::Type_Weapon, CSMWorld::ColumnBase::Display_Weapon },
return CSMWorld::UniversalId::Type_Referenceable; { CSMWorld::UniversalId::Type_Reference, CSMWorld::ColumnBase::Display_Reference },
{ CSMWorld::UniversalId::Type_Filter, CSMWorld::ColumnBase::Display_Filter },
{ CSMWorld::UniversalId::Type_Topic, CSMWorld::ColumnBase::Display_Topic },
case CSMWorld::ColumnBase::Display_Activator: { CSMWorld::UniversalId::Type_Journal, CSMWorld::ColumnBase::Display_Journal },
return CSMWorld::UniversalId::Type_Activator; { CSMWorld::UniversalId::Type_TopicInfo, CSMWorld::ColumnBase::Display_TopicInfo },
{ CSMWorld::UniversalId::Type_JournalInfo, CSMWorld::ColumnBase::Display_JournalInfo },
{ CSMWorld::UniversalId::Type_Scene, CSMWorld::ColumnBase::Display_Scene },
case CSMWorld::ColumnBase::Display_Potion: { CSMWorld::UniversalId::Type_Script, CSMWorld::ColumnBase::Display_Script },
return CSMWorld::UniversalId::Type_Potion; { CSMWorld::UniversalId::Type_Mesh, CSMWorld::ColumnBase::Display_Mesh },
{ CSMWorld::UniversalId::Type_Icon, CSMWorld::ColumnBase::Display_Icon },
{ CSMWorld::UniversalId::Type_Music, CSMWorld::ColumnBase::Display_Music },
case CSMWorld::ColumnBase::Display_Apparatus: { CSMWorld::UniversalId::Type_SoundRes, CSMWorld::ColumnBase::Display_SoundRes },
return CSMWorld::UniversalId::Type_Apparatus; { CSMWorld::UniversalId::Type_Texture, CSMWorld::ColumnBase::Display_Texture },
{ CSMWorld::UniversalId::Type_Video, CSMWorld::ColumnBase::Display_Video },
case CSMWorld::ColumnBase::Display_Armor: { CSMWorld::UniversalId::Type_None, CSMWorld::ColumnBase::Display_None } // end marker
return CSMWorld::UniversalId::Type_Armor; };
case CSMWorld::ColumnBase::Display_Book:
return CSMWorld::UniversalId::Type_Book;
case CSMWorld::ColumnBase::Display_Clothing:
return CSMWorld::UniversalId::Type_Clothing;
case CSMWorld::ColumnBase::Display_Container:
return CSMWorld::UniversalId::Type_Container;
case CSMWorld::ColumnBase::Display_Creature:
return CSMWorld::UniversalId::Type_Creature;
case CSMWorld::ColumnBase::Display_Door:
return CSMWorld::UniversalId::Type_Door;
case CSMWorld::ColumnBase::Display_Ingredient:
return CSMWorld::UniversalId::Type_Ingredient;
case CSMWorld::ColumnBase::Display_CreatureLevelledList:
return CSMWorld::UniversalId::Type_CreatureLevelledList;
case CSMWorld::ColumnBase::Display_ItemLevelledList:
return CSMWorld::UniversalId::Type_ItemLevelledList;
case CSMWorld::ColumnBase::Display_Light:
return CSMWorld::UniversalId::Type_Light;
case CSMWorld::ColumnBase::Display_Lockpick:
return CSMWorld::UniversalId::Type_Lockpick;
case CSMWorld::ColumnBase::Display_Miscellaneous:
return CSMWorld::UniversalId::Type_Miscellaneous;
case CSMWorld::ColumnBase::Display_Npc:
return CSMWorld::UniversalId::Type_Npc;
case CSMWorld::ColumnBase::Display_Probe:
return CSMWorld::UniversalId::Type_Probe;
case CSMWorld::ColumnBase::Display_Repair:
return CSMWorld::UniversalId::Type_Repair;
case CSMWorld::ColumnBase::Display_Static:
return CSMWorld::UniversalId::Type_Static;
case CSMWorld::ColumnBase::Display_Weapon:
return CSMWorld::UniversalId::Type_Weapon;
case CSMWorld::ColumnBase::Display_Reference:
return CSMWorld::UniversalId::Type_Reference;
case CSMWorld::ColumnBase::Display_Filter:
return CSMWorld::UniversalId::Type_Filter;
case CSMWorld::ColumnBase::Display_Topic:
return CSMWorld::UniversalId::Type_Topic;
case CSMWorld::ColumnBase::Display_Journal:
return CSMWorld::UniversalId::Type_Journal;
case CSMWorld::ColumnBase::Display_TopicInfo:
return CSMWorld::UniversalId::Type_TopicInfo;
case CSMWorld::ColumnBase::Display_JournalInfo:
return CSMWorld::UniversalId::Type_JournalInfo;
case CSMWorld::ColumnBase::Display_Scene:
return CSMWorld::UniversalId::Type_Scene;
case CSMWorld::ColumnBase::Display_Script:
return CSMWorld::UniversalId::Type_Script;
default:
return CSMWorld::UniversalId::Type_None;
}
} }
CSMWorld::ColumnBase::Display CSMWorld::TableMimeData::convertEnums (CSMWorld::UniversalId::Type type) CSMWorld::UniversalId::Type CSMWorld::TableMimeData::convertEnums (ColumnBase::Display type)
{ {
switch (type) for (int i=0; mapping[i].mUniversalIdType!=CSMWorld::UniversalId::Type_None; ++i)
{ if (mapping[i].mDisplayType==type)
case CSMWorld::UniversalId::Type_Race: return mapping[i].mUniversalIdType;
return CSMWorld::ColumnBase::Display_Race;
return CSMWorld::UniversalId::Type_None;
}
case CSMWorld::UniversalId::Type_Skill: CSMWorld::ColumnBase::Display CSMWorld::TableMimeData::convertEnums (UniversalId::Type type)
return CSMWorld::ColumnBase::Display_Skill; {
for (int i=0; mapping[i].mUniversalIdType!=CSMWorld::UniversalId::Type_None; ++i)
if (mapping[i].mUniversalIdType==type)
return mapping[i].mDisplayType;
return CSMWorld::ColumnBase::Display_None;
case CSMWorld::UniversalId::Type_Class:
return CSMWorld::ColumnBase::Display_Class;
case CSMWorld::UniversalId::Type_Faction:
return CSMWorld::ColumnBase::Display_Faction;
case CSMWorld::UniversalId::Type_Sound:
return CSMWorld::ColumnBase::Display_Sound;
case CSMWorld::UniversalId::Type_Region:
return CSMWorld::ColumnBase::Display_Region;
case CSMWorld::UniversalId::Type_Birthsign:
return CSMWorld::ColumnBase::Display_Birthsign;
case CSMWorld::UniversalId::Type_Spell:
return CSMWorld::ColumnBase::Display_Spell;
case CSMWorld::UniversalId::Type_Cell:
return CSMWorld::ColumnBase::Display_Cell;
case CSMWorld::UniversalId::Type_Referenceable:
return CSMWorld::ColumnBase::Display_Referenceable;
case CSMWorld::UniversalId::Type_Activator:
return CSMWorld::ColumnBase::Display_Activator;
case CSMWorld::UniversalId::Type_Potion:
return CSMWorld::ColumnBase::Display_Potion;
case CSMWorld::UniversalId::Type_Apparatus:
return CSMWorld::ColumnBase::Display_Apparatus;
case CSMWorld::UniversalId::Type_Armor:
return CSMWorld::ColumnBase::Display_Armor;
case CSMWorld::UniversalId::Type_Book:
return CSMWorld::ColumnBase::Display_Book;
case CSMWorld::UniversalId::Type_Clothing:
return CSMWorld::ColumnBase::Display_Clothing;
case CSMWorld::UniversalId::Type_Container:
return CSMWorld::ColumnBase::Display_Container;
case CSMWorld::UniversalId::Type_Creature:
return CSMWorld::ColumnBase::Display_Creature;
case CSMWorld::UniversalId::Type_Door:
return CSMWorld::ColumnBase::Display_Door;
case CSMWorld::UniversalId::Type_Ingredient:
return CSMWorld::ColumnBase::Display_Ingredient;
case CSMWorld::UniversalId::Type_CreatureLevelledList:
return CSMWorld::ColumnBase::Display_CreatureLevelledList;
case CSMWorld::UniversalId::Type_ItemLevelledList:
return CSMWorld::ColumnBase::Display_ItemLevelledList;
case CSMWorld::UniversalId::Type_Light:
return CSMWorld::ColumnBase::Display_Light;
case CSMWorld::UniversalId::Type_Lockpick:
return CSMWorld::ColumnBase::Display_Lockpick;
case CSMWorld::UniversalId::Type_Miscellaneous:
return CSMWorld::ColumnBase::Display_Miscellaneous;
case CSMWorld::UniversalId::Type_Npc:
return CSMWorld::ColumnBase::Display_Npc;
case CSMWorld::UniversalId::Type_Probe:
return CSMWorld::ColumnBase::Display_Probe;
case CSMWorld::UniversalId::Type_Repair:
return CSMWorld::ColumnBase::Display_Repair;
case CSMWorld::UniversalId::Type_Static:
return CSMWorld::ColumnBase::Display_Static;
case CSMWorld::UniversalId::Type_Weapon:
return CSMWorld::ColumnBase::Display_Weapon;
case CSMWorld::UniversalId::Type_Reference:
return CSMWorld::ColumnBase::Display_Reference;
case CSMWorld::UniversalId::Type_Filter:
return CSMWorld::ColumnBase::Display_Filter;
case CSMWorld::UniversalId::Type_Topic:
return CSMWorld::ColumnBase::Display_Topic;
case CSMWorld::UniversalId::Type_Journal:
return CSMWorld::ColumnBase::Display_Journal;
case CSMWorld::UniversalId::Type_TopicInfo:
return CSMWorld::ColumnBase::Display_TopicInfo;
case CSMWorld::UniversalId::Type_JournalInfo:
return CSMWorld::ColumnBase::Display_JournalInfo;
case CSMWorld::UniversalId::Type_Scene:
return CSMWorld::ColumnBase::Display_Scene;
case CSMWorld::UniversalId::Type_Script:
return CSMWorld::ColumnBase::Display_Script;
default:
return CSMWorld::ColumnBase::Display_None;
}
} }
const CSMDoc::Document* CSMWorld::TableMimeData::getDocumentPtr() const const CSMDoc::Document* CSMWorld::TableMimeData::getDocumentPtr() const

View file

@ -35,6 +35,8 @@ namespace
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_TopicInfos, "Topic Infos", 0 }, { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_TopicInfos, "Topic Infos", 0 },
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_JournalInfos, "Journal Infos", 0 }, { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_JournalInfos, "Journal Infos", 0 },
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Cells, "Cells", 0 }, { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Cells, "Cells", 0 },
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Enchantments, "Enchantments", 0 },
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_BodyParts, "Body Parts", 0 },
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Referenceables, { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Referenceables,
"Referenceables", 0 }, "Referenceables", 0 },
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_References, { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_References,
@ -42,6 +44,12 @@ namespace
{ CSMWorld::UniversalId::Class_NonRecord, CSMWorld::UniversalId::Type_RegionMap, { CSMWorld::UniversalId::Class_NonRecord, CSMWorld::UniversalId::Type_RegionMap,
"Region Map", 0 }, "Region Map", 0 },
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Filters, "Filters", 0 }, { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Filters, "Filters", 0 },
{ CSMWorld::UniversalId::Class_ResourceList, CSMWorld::UniversalId::Type_Meshes, "Meshes", 0 },
{ CSMWorld::UniversalId::Class_ResourceList, CSMWorld::UniversalId::Type_Icons, "Icons", 0 },
{ CSMWorld::UniversalId::Class_ResourceList, CSMWorld::UniversalId::Type_Musics, "Musics", 0 },
{ CSMWorld::UniversalId::Class_ResourceList, CSMWorld::UniversalId::Type_SoundsRes, "Sound Files", 0 },
{ CSMWorld::UniversalId::Class_ResourceList, CSMWorld::UniversalId::Type_Textures, "Textures", 0 },
{ CSMWorld::UniversalId::Class_ResourceList, CSMWorld::UniversalId::Type_Videos, "Videos", 0 },
{ CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, 0, 0 } // end marker { CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, 0, 0 } // end marker
}; };
@ -92,8 +100,15 @@ namespace
{ CSMWorld::UniversalId::Class_SubRecord, CSMWorld::UniversalId::Type_Reference, "Reference", 0 }, { CSMWorld::UniversalId::Class_SubRecord, CSMWorld::UniversalId::Type_Reference, "Reference", 0 },
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Filter, "Filter", ":./filter.png" }, { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Filter, "Filter", ":./filter.png" },
{ CSMWorld::UniversalId::Class_Collection, CSMWorld::UniversalId::Type_Scene, "Scene", 0 }, { CSMWorld::UniversalId::Class_Collection, CSMWorld::UniversalId::Type_Scene, "Scene", 0 },
{ CSMWorld::UniversalId::Class_Collection, CSMWorld::UniversalId::Type_Preview, "Preview", 0 }, { CSMWorld::UniversalId::Class_Collection, CSMWorld::UniversalId::Type_Preview, "Preview", 0 },
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Enchantment, "Enchantment", 0 },
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_BodyPart, "Body Part", 0 },
{ CSMWorld::UniversalId::Class_Resource, CSMWorld::UniversalId::Type_Mesh, "Mesh", 0 },
{ CSMWorld::UniversalId::Class_Resource, CSMWorld::UniversalId::Type_Icon, "Icon", 0 },
{ CSMWorld::UniversalId::Class_Resource, CSMWorld::UniversalId::Type_Music, "Music", 0 },
{ CSMWorld::UniversalId::Class_Resource, CSMWorld::UniversalId::Type_SoundRes, "Sound File", 0 },
{ CSMWorld::UniversalId::Class_Resource, CSMWorld::UniversalId::Type_Texture, "Texture", 0 },
{ CSMWorld::UniversalId::Class_Resource, CSMWorld::UniversalId::Type_Video, "Video", 0 },
{ CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, 0, 0 } // end marker { CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, 0, 0 } // end marker
}; };
@ -328,7 +343,8 @@ CSMWorld::UniversalId::Type CSMWorld::UniversalId::getParentType (Type type)
if (sIdArg[i].mClass==Class_RefRecord) if (sIdArg[i].mClass==Class_RefRecord)
return Type_Referenceables; return Type_Referenceables;
if (sIdArg[i].mClass==Class_SubRecord || sIdArg[i].mClass==Class_Record) if (sIdArg[i].mClass==Class_SubRecord || sIdArg[i].mClass==Class_Record ||
sIdArg[i].mClass==Class_Resource)
{ {
if (type==Type_Cell_Missing) if (type==Type_Cell_Missing)
return Type_Cells; return Type_Cells;

View file

@ -22,7 +22,10 @@ namespace CSMWorld
Class_RecordList, Class_RecordList,
Class_Collection, // multiple types of records combined Class_Collection, // multiple types of records combined
Class_Transient, // not part of the world data or the project data Class_Transient, // not part of the world data or the project data
Class_NonRecord // record like data that is not part of the world Class_NonRecord, // record like data that is not part of the world
Class_Resource, ///< \attention Resource IDs are unique only within the
/// respective collection
Class_ResourceList
}; };
enum ArgumentType enum ArgumentType
@ -100,10 +103,26 @@ namespace CSMWorld
Type_JournalInfo, Type_JournalInfo,
Type_Scene, Type_Scene,
Type_Preview, Type_Preview,
Type_LoadErrorLog Type_LoadErrorLog,
Type_Enchantments,
Type_Enchantment,
Type_BodyParts,
Type_BodyPart,
Type_Meshes,
Type_Mesh,
Type_Icons,
Type_Icon,
Type_Musics,
Type_Music,
Type_SoundsRes,
Type_SoundRes,
Type_Textures,
Type_Texture,
Type_Videos,
Type_Video
}; };
enum { NumberOfTypes = Type_LoadErrorLog+1 }; enum { NumberOfTypes = Type_BodyPart+1 };
private: private:

View file

@ -146,6 +146,10 @@ void CSVDoc::View::setupMechanicsMenu()
QAction *spells = new QAction (tr ("Spells"), this); QAction *spells = new QAction (tr ("Spells"), this);
connect (spells, SIGNAL (triggered()), this, SLOT (addSpellsSubView())); connect (spells, SIGNAL (triggered()), this, SLOT (addSpellsSubView()));
mechanics->addAction (spells); mechanics->addAction (spells);
QAction *enchantments = new QAction (tr ("Enchantments"), this);
connect (enchantments, SIGNAL (triggered()), this, SLOT (addEnchantmentsSubView()));
mechanics->addAction (enchantments);
} }
void CSVDoc::View::setupCharacterMenu() void CSVDoc::View::setupCharacterMenu()
@ -187,6 +191,10 @@ void CSVDoc::View::setupCharacterMenu()
QAction *journalInfos = new QAction (tr ("Journal Infos"), this); QAction *journalInfos = new QAction (tr ("Journal Infos"), this);
connect (journalInfos, SIGNAL (triggered()), this, SLOT (addJournalInfosSubView())); connect (journalInfos, SIGNAL (triggered()), this, SLOT (addJournalInfosSubView()));
characters->addAction (journalInfos); characters->addAction (journalInfos);
QAction *bodyParts = new QAction (tr ("Body Parts"), this);
connect (bodyParts, SIGNAL (triggered()), this, SLOT (addBodyPartsSubView()));
characters->addAction (bodyParts);
} }
void CSVDoc::View::setupAssetsMenu() void CSVDoc::View::setupAssetsMenu()
@ -196,6 +204,32 @@ void CSVDoc::View::setupAssetsMenu()
QAction *sounds = new QAction (tr ("Sounds"), this); QAction *sounds = new QAction (tr ("Sounds"), this);
connect (sounds, SIGNAL (triggered()), this, SLOT (addSoundsSubView())); connect (sounds, SIGNAL (triggered()), this, SLOT (addSoundsSubView()));
assets->addAction (sounds); assets->addAction (sounds);
assets->addSeparator(); // resources follow here
QAction *meshes = new QAction (tr ("Meshes"), this);
connect (meshes, SIGNAL (triggered()), this, SLOT (addMeshesSubView()));
assets->addAction (meshes);
QAction *icons = new QAction (tr ("Icons"), this);
connect (icons, SIGNAL (triggered()), this, SLOT (addIconsSubView()));
assets->addAction (icons);
QAction *musics = new QAction (tr ("Music"), this);
connect (musics, SIGNAL (triggered()), this, SLOT (addMusicsSubView()));
assets->addAction (musics);
QAction *soundsRes = new QAction (tr ("Sound Files"), this);
connect (soundsRes, SIGNAL (triggered()), this, SLOT (addSoundsResSubView()));
assets->addAction (soundsRes);
QAction *textures = new QAction (tr ("Textures"), this);
connect (textures, SIGNAL (triggered()), this, SLOT (addTexturesSubView()));
assets->addAction (textures);
QAction *videos = new QAction (tr ("Videos"), this);
connect (videos, SIGNAL (triggered()), this, SLOT (addVideosSubView()));
assets->addAction (videos);
} }
void CSVDoc::View::setupUi() void CSVDoc::View::setupUi()
@ -469,6 +503,46 @@ void CSVDoc::View::addJournalInfosSubView()
addSubView (CSMWorld::UniversalId::Type_JournalInfos); addSubView (CSMWorld::UniversalId::Type_JournalInfos);
} }
void CSVDoc::View::addEnchantmentsSubView()
{
addSubView (CSMWorld::UniversalId::Type_Enchantments);
}
void CSVDoc::View::addBodyPartsSubView()
{
addSubView (CSMWorld::UniversalId::Type_BodyParts);
}
void CSVDoc::View::addMeshesSubView()
{
addSubView (CSMWorld::UniversalId::Type_Meshes);
}
void CSVDoc::View::addIconsSubView()
{
addSubView (CSMWorld::UniversalId::Type_Icons);
}
void CSVDoc::View::addMusicsSubView()
{
addSubView (CSMWorld::UniversalId::Type_Musics);
}
void CSVDoc::View::addSoundsResSubView()
{
addSubView (CSMWorld::UniversalId::Type_SoundsRes);
}
void CSVDoc::View::addTexturesSubView()
{
addSubView (CSMWorld::UniversalId::Type_Textures);
}
void CSVDoc::View::addVideosSubView()
{
addSubView (CSMWorld::UniversalId::Type_Videos);
}
void CSVDoc::View::abortOperation (int type) void CSVDoc::View::abortOperation (int type)
{ {
mDocument->abortOperation (type); mDocument->abortOperation (type);

View file

@ -178,6 +178,22 @@ namespace CSVDoc
void addJournalInfosSubView(); void addJournalInfosSubView();
void addEnchantmentsSubView();
void addBodyPartsSubView();
void addMeshesSubView();
void addIconsSubView();
void addMusicsSubView();
void addSoundsResSubView();
void addTexturesSubView();
void addVideosSubView();
void toggleShowStatusBar (bool show); void toggleShowStatusBar (bool show);
void loadErrorLog(); void loadErrorLog();

View file

@ -78,6 +78,9 @@ CSVDoc::ViewManager::ViewManager (CSMDoc::DocumentManager& documentManager)
{ CSMWorld::ColumnBase::Display_WeaponType, CSMWorld::Columns::ColumnId_WeaponType, false }, { CSMWorld::ColumnBase::Display_WeaponType, CSMWorld::Columns::ColumnId_WeaponType, false },
{ CSMWorld::ColumnBase::Display_DialogueType, CSMWorld::Columns::ColumnId_DialogueType, false }, { CSMWorld::ColumnBase::Display_DialogueType, CSMWorld::Columns::ColumnId_DialogueType, false },
{ CSMWorld::ColumnBase::Display_QuestStatusType, CSMWorld::Columns::ColumnId_QuestStatusType, false }, { CSMWorld::ColumnBase::Display_QuestStatusType, CSMWorld::Columns::ColumnId_QuestStatusType, false },
{ CSMWorld::ColumnBase::Display_EnchantmentType, CSMWorld::Columns::ColumnId_EnchantmentType, false },
{ CSMWorld::ColumnBase::Display_BodyPartType, CSMWorld::Columns::ColumnId_BodyPartType, false },
{ CSMWorld::ColumnBase::Display_MeshType, CSMWorld::Columns::ColumnId_MeshType, false },
{ CSMWorld::ColumnBase::Display_Gender, CSMWorld::Columns::ColumnId_Gender, true } { CSMWorld::ColumnBase::Display_Gender, CSMWorld::Columns::ColumnId_Gender, true }
}; };

View file

@ -15,13 +15,18 @@ bool CSVRender::PagedWorldspaceWidget::adjustCells()
bool modified = false; bool modified = false;
bool setCamera = false; bool setCamera = false;
const CSMWorld::IdCollection<CSMWorld::Cell>& cells = mDocument.getData().getCells();
{ {
// remove // remove
std::map<CSMWorld::CellCoordinates, Cell *>::iterator iter (mCells.begin()); std::map<CSMWorld::CellCoordinates, Cell *>::iterator iter (mCells.begin());
while (iter!=mCells.end()) while (iter!=mCells.end())
{ {
if (!mSelection.has (iter->first)) int index = cells.searchId (iter->first.getId (mWorldspace));
if (!mSelection.has (iter->first) || index==-1 ||
cells.getRecord (index).mState==CSMWorld::RecordBase::State_Deleted)
{ {
delete iter->second; delete iter->second;
mCells.erase (iter++); mCells.erase (iter++);
@ -39,7 +44,10 @@ bool CSVRender::PagedWorldspaceWidget::adjustCells()
for (CSMWorld::CellSelection::Iterator iter (mSelection.begin()); iter!=mSelection.end(); for (CSMWorld::CellSelection::Iterator iter (mSelection.begin()); iter!=mSelection.end();
++iter) ++iter)
{ {
if (mCells.find (*iter)==mCells.end()) int index = cells.searchId (iter->getId (mWorldspace));
if (index!=0 && cells.getRecord (index).mState!=CSMWorld::RecordBase::State_Deleted &&
mCells.find (*iter)==mCells.end())
{ {
if (setCamera) if (setCamera)
{ {
@ -49,7 +57,7 @@ bool CSVRender::PagedWorldspaceWidget::adjustCells()
mCells.insert (std::make_pair (*iter, mCells.insert (std::make_pair (*iter,
new Cell (mDocument.getData(), getSceneManager(), new Cell (mDocument.getData(), getSceneManager(),
iter->getId ("std::default")))); iter->getId (mWorldspace))));
modified = true; modified = true;
} }
@ -121,11 +129,19 @@ void CSVRender::PagedWorldspaceWidget::referenceAdded (const QModelIndex& parent
flagAsModified(); flagAsModified();
} }
CSVRender::PagedWorldspaceWidget::PagedWorldspaceWidget (QWidget* parent, CSMDoc::Document& document) CSVRender::PagedWorldspaceWidget::PagedWorldspaceWidget (QWidget* parent, CSMDoc::Document& document)
: WorldspaceWidget (document, parent), mDocument (document) : WorldspaceWidget (document, parent), mDocument (document), mWorldspace ("std::default")
{} {
QAbstractItemModel *cells =
document.getData().getTableModel (CSMWorld::UniversalId::Type_Cells);
connect (cells, SIGNAL (dataChanged (const QModelIndex&, const QModelIndex&)),
this, SLOT (cellDataChanged (const QModelIndex&, const QModelIndex&)));
connect (cells, SIGNAL (rowsRemoved (const QModelIndex&, int, int)),
this, SLOT (cellRemoved (const QModelIndex&, int, int)));
connect (cells, SIGNAL (rowsInserted (const QModelIndex&, int, int)),
this, SLOT (cellAdded (const QModelIndex&, int, int)));
}
CSVRender::PagedWorldspaceWidget::~PagedWorldspaceWidget() CSVRender::PagedWorldspaceWidget::~PagedWorldspaceWidget()
{ {
@ -219,4 +235,27 @@ CSVRender::WorldspaceWidget::dropRequirments CSVRender::PagedWorldspaceWidget::g
default: default:
return ignored; return ignored;
} }
}
void CSVRender::PagedWorldspaceWidget::cellDataChanged (const QModelIndex& topLeft,
const QModelIndex& bottomRight)
{
/// \todo check if no selected cell is affected and do not update, if that is the case
if (adjustCells())
flagAsModified();
}
void CSVRender::PagedWorldspaceWidget::cellRemoved (const QModelIndex& parent, int start,
int end)
{
if (adjustCells())
flagAsModified();
}
void CSVRender::PagedWorldspaceWidget::cellAdded (const QModelIndex& index, int start,
int end)
{
/// \todo check if no selected cell is affected and do not update, if that is the case
if (adjustCells())
flagAsModified();
} }

View file

@ -17,6 +17,7 @@ namespace CSVRender
CSMDoc::Document& mDocument; CSMDoc::Document& mDocument;
CSMWorld::CellSelection mSelection; CSMWorld::CellSelection mSelection;
std::map<CSMWorld::CellCoordinates, Cell *> mCells; std::map<CSMWorld::CellCoordinates, Cell *> mCells;
std::string mWorldspace;
private: private:
@ -60,6 +61,15 @@ namespace CSVRender
signals: signals:
void cellSelectionChanged (const CSMWorld::CellSelection& selection); void cellSelectionChanged (const CSMWorld::CellSelection& selection);
private slots:
virtual void cellDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight);
virtual void cellRemoved (const QModelIndex& parent, int start, int end);
virtual void cellAdded (const QModelIndex& index, int start, int end);
}; };
} }

View file

@ -39,6 +39,8 @@ void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager)
CSMWorld::UniversalId::Type_Regions, CSMWorld::UniversalId::Type_Regions,
CSMWorld::UniversalId::Type_Birthsigns, CSMWorld::UniversalId::Type_Birthsigns,
CSMWorld::UniversalId::Type_Spells, CSMWorld::UniversalId::Type_Spells,
CSMWorld::UniversalId::Type_Enchantments,
CSMWorld::UniversalId::Type_BodyParts,
CSMWorld::UniversalId::Type_None // end marker CSMWorld::UniversalId::Type_None // end marker
}; };
@ -68,6 +70,21 @@ void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager)
manager.add (CSMWorld::UniversalId::Type_JournalInfos, manager.add (CSMWorld::UniversalId::Type_JournalInfos,
new CSVDoc::SubViewFactoryWithCreator<TableSubView, CreatorFactory<InfoCreator> > (false)); new CSVDoc::SubViewFactoryWithCreator<TableSubView, CreatorFactory<InfoCreator> > (false));
// Subviews for resources tables
manager.add (CSMWorld::UniversalId::Type_Meshes,
new CSVDoc::SubViewFactoryWithCreator<TableSubView, NullCreatorFactory>);
manager.add (CSMWorld::UniversalId::Type_Icons,
new CSVDoc::SubViewFactoryWithCreator<TableSubView, NullCreatorFactory>);
manager.add (CSMWorld::UniversalId::Type_Musics,
new CSVDoc::SubViewFactoryWithCreator<TableSubView, NullCreatorFactory>);
manager.add (CSMWorld::UniversalId::Type_SoundsRes,
new CSVDoc::SubViewFactoryWithCreator<TableSubView, NullCreatorFactory>);
manager.add (CSMWorld::UniversalId::Type_Textures,
new CSVDoc::SubViewFactoryWithCreator<TableSubView, NullCreatorFactory>);
manager.add (CSMWorld::UniversalId::Type_Videos,
new CSVDoc::SubViewFactoryWithCreator<TableSubView, NullCreatorFactory>);
// Subviews for editing/viewing individual records // Subviews for editing/viewing individual records
manager.add (CSMWorld::UniversalId::Type_Script, new CSVDoc::SubViewFactory<ScriptSubView>); manager.add (CSMWorld::UniversalId::Type_Script, new CSVDoc::SubViewFactory<ScriptSubView>);
@ -92,6 +109,8 @@ void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager)
CSMWorld::UniversalId::Type_Filter, CSMWorld::UniversalId::Type_Filter,
CSMWorld::UniversalId::Type_Sound, CSMWorld::UniversalId::Type_Sound,
CSMWorld::UniversalId::Type_Faction, CSMWorld::UniversalId::Type_Faction,
CSMWorld::UniversalId::Type_Enchantment,
CSMWorld::UniversalId::Type_BodyPart,
CSMWorld::UniversalId::Type_None // end marker CSMWorld::UniversalId::Type_None // end marker
}; };

View file

@ -14,6 +14,7 @@
#include "../../model/world/data.hpp" #include "../../model/world/data.hpp"
#include "../../model/world/commands.hpp" #include "../../model/world/commands.hpp"
#include "../../model/world/idtableproxymodel.hpp" #include "../../model/world/idtableproxymodel.hpp"
#include "../../model/world/idtablebase.hpp"
#include "../../model/world/idtable.hpp" #include "../../model/world/idtable.hpp"
#include "../../model/world/record.hpp" #include "../../model/world/record.hpp"
#include "../../model/world/columns.hpp" #include "../../model/world/columns.hpp"
@ -53,7 +54,7 @@ void CSVWorld::Table::contextMenuEvent (QContextMenuEvent *event)
/// \todo add menu items for select all and clear selection /// \todo add menu items for select all and clear selection
if (!mEditLock) if (!mEditLock && !(mModel->getFeatures() & CSMWorld::IdTableBase::Feature_Constant))
{ {
if (selectedRows.size()==1) if (selectedRows.size()==1)
{ {
@ -82,7 +83,7 @@ void CSVWorld::Table::contextMenuEvent (QContextMenuEvent *event)
menu.addAction (mExtendedDeleteAction); menu.addAction (mExtendedDeleteAction);
} }
if (mModel->getFeatures() & CSMWorld::IdTable::Feature_ReorderWithinTopic) if (mModel->getFeatures() & CSMWorld::IdTableBase::Feature_ReorderWithinTopic)
{ {
/// \todo allow reordering of multiple rows /// \todo allow reordering of multiple rows
if (selectedRows.size()==1) if (selectedRows.size()==1)
@ -119,7 +120,7 @@ void CSVWorld::Table::contextMenuEvent (QContextMenuEvent *event)
row = mProxyModel->mapToSource (mProxyModel->index (row, 0)).row(); row = mProxyModel->mapToSource (mProxyModel->index (row, 0)).row();
if (mModel->getFeatures() & CSMWorld::IdTable::Feature_View) if (mModel->getFeatures() & CSMWorld::IdTableBase::Feature_View)
{ {
CSMWorld::UniversalId id = mModel->view (row).first; CSMWorld::UniversalId id = mModel->view (row).first;
@ -131,7 +132,7 @@ void CSVWorld::Table::contextMenuEvent (QContextMenuEvent *event)
menu.addAction (mViewAction); menu.addAction (mViewAction);
} }
if (mModel->getFeatures() & CSMWorld::IdTable::Feature_Preview) if (mModel->getFeatures() & CSMWorld::IdTableBase::Feature_Preview)
{ {
QModelIndex index = mModel->index (row, QModelIndex index = mModel->index (row,
mModel->findColumnIndex (CSMWorld::Columns::ColumnId_Modification)); mModel->findColumnIndex (CSMWorld::Columns::ColumnId_Modification));
@ -152,7 +153,7 @@ CSVWorld::Table::Table (const CSMWorld::UniversalId& id,
: mCreateAction (0), mCloneAction(0), mRecordStatusDisplay (0), : mCreateAction (0), mCloneAction(0), mRecordStatusDisplay (0),
DragRecordTable(document) DragRecordTable(document)
{ {
mModel = &dynamic_cast<CSMWorld::IdTable&> (*mDocument.getData().getTableModel (id)); mModel = &dynamic_cast<CSMWorld::IdTableBase&> (*mDocument.getData().getTableModel (id));
mProxyModel = new CSMWorld::IdTableProxyModel (this); mProxyModel = new CSMWorld::IdTableProxyModel (this);
mProxyModel->setSourceModel (mModel); mProxyModel->setSourceModel (mModel);
@ -275,7 +276,7 @@ CSMWorld::UniversalId CSVWorld::Table::getUniversalId (int row) const
void CSVWorld::Table::editRecord() void CSVWorld::Table::editRecord()
{ {
if (!mEditLock) if (!mEditLock || (mModel->getFeatures() & CSMWorld::IdTableBase::Feature_Constant))
{ {
QModelIndexList selectedRows = selectionModel()->selectedRows(); QModelIndexList selectedRows = selectionModel()->selectedRows();
@ -286,11 +287,11 @@ void CSVWorld::Table::editRecord()
void CSVWorld::Table::cloneRecord() void CSVWorld::Table::cloneRecord()
{ {
if (!mEditLock) if (!mEditLock || (mModel->getFeatures() & CSMWorld::IdTableBase::Feature_Constant))
{ {
QModelIndexList selectedRows = selectionModel()->selectedRows(); QModelIndexList selectedRows = selectionModel()->selectedRows();
const CSMWorld::UniversalId& toClone = getUniversalId(selectedRows.begin()->row()); const CSMWorld::UniversalId& toClone = getUniversalId(selectedRows.begin()->row());
if (selectedRows.size()==1 && !mModel->getRecord(toClone.getId()).isDeleted()) if (selectedRows.size()==1 && !mModel->isDeleted (toClone.getId()))
{ {
emit cloneRequest (toClone); emit cloneRequest (toClone);
} }
@ -299,7 +300,7 @@ void CSVWorld::Table::cloneRecord()
void CSVWorld::Table::moveUpRecord() void CSVWorld::Table::moveUpRecord()
{ {
if (mEditLock) if (mEditLock || (mModel->getFeatures() & CSMWorld::IdTableBase::Feature_Constant))
return; return;
QModelIndexList selectedRows = selectionModel()->selectedRows(); QModelIndexList selectedRows = selectionModel()->selectedRows();
@ -324,14 +325,15 @@ void CSVWorld::Table::moveUpRecord()
for (int i=1; i<row2-row; ++i) for (int i=1; i<row2-row; ++i)
newOrder[i] = i; newOrder[i] = i;
mDocument.getUndoStack().push (new CSMWorld::ReorderRowsCommand (*mModel, row, newOrder)); mDocument.getUndoStack().push (new CSMWorld::ReorderRowsCommand (
dynamic_cast<CSMWorld::IdTable&> (*mModel), row, newOrder));
} }
} }
} }
void CSVWorld::Table::moveDownRecord() void CSVWorld::Table::moveDownRecord()
{ {
if (mEditLock) if (mEditLock || (mModel->getFeatures() & CSMWorld::IdTableBase::Feature_Constant))
return; return;
QModelIndexList selectedRows = selectionModel()->selectedRows(); QModelIndexList selectedRows = selectionModel()->selectedRows();
@ -356,7 +358,8 @@ void CSVWorld::Table::moveDownRecord()
for (int i=1; i<row2-row; ++i) for (int i=1; i<row2-row; ++i)
newOrder[i] = i; newOrder[i] = i;
mDocument.getUndoStack().push (new CSMWorld::ReorderRowsCommand (*mModel, row, newOrder)); mDocument.getUndoStack().push (new CSMWorld::ReorderRowsCommand (
dynamic_cast<CSMWorld::IdTable&> (*mModel), row, newOrder));
} }
} }
} }
@ -422,21 +425,27 @@ void CSVWorld::Table::tableSizeUpdate()
{ {
int rows = mProxyModel->rowCount(); int rows = mProxyModel->rowCount();
for (int i=0; i<rows; ++i) int columnIndex = mModel->searchColumnIndex (CSMWorld::Columns::ColumnId_Modification);
if (columnIndex!=-1)
{ {
QModelIndex index = mProxyModel->mapToSource (mProxyModel->index (i, 0)); for (int i=0; i<rows; ++i)
int columnIndex = mModel->findColumnIndex (CSMWorld::Columns::ColumnId_Modification);
int state = mModel->data (mModel->index (index.row(), columnIndex)).toInt();
switch (state)
{ {
case CSMWorld::RecordBase::State_BaseOnly: ++size; break; QModelIndex index = mProxyModel->mapToSource (mProxyModel->index (i, 0));
case CSMWorld::RecordBase::State_Modified: ++size; ++modified; break;
case CSMWorld::RecordBase::State_ModifiedOnly: ++size; ++modified; break; int state = mModel->data (mModel->index (index.row(), columnIndex)).toInt();
case CSMWorld::RecordBase:: State_Deleted: ++deleted; ++modified; break;
switch (state)
{
case CSMWorld::RecordBase::State_BaseOnly: ++size; break;
case CSMWorld::RecordBase::State_Modified: ++size; ++modified; break;
case CSMWorld::RecordBase::State_ModifiedOnly: ++size; ++modified; break;
case CSMWorld::RecordBase:: State_Deleted: ++deleted; ++modified; break;
}
} }
} }
else
size = rows;
} }
tableSizeChanged (size, deleted, modified); tableSizeChanged (size, deleted, modified);

View file

@ -23,7 +23,7 @@ namespace CSMWorld
class Data; class Data;
class UniversalId; class UniversalId;
class IdTableProxyModel; class IdTableProxyModel;
class IdTable; class IdTableBase;
class CommandDispatcher; class CommandDispatcher;
} }
@ -49,7 +49,7 @@ namespace CSVWorld
QAction *mExtendedDeleteAction; QAction *mExtendedDeleteAction;
QAction *mExtendedRevertAction; QAction *mExtendedRevertAction;
CSMWorld::IdTableProxyModel *mProxyModel; CSMWorld::IdTableProxyModel *mProxyModel;
CSMWorld::IdTable *mModel; CSMWorld::IdTableBase *mModel;
int mRecordStatusDisplay; int mRecordStatusDisplay;
CSMWorld::CommandDispatcher *mDispatcher; CSMWorld::CommandDispatcher *mDispatcher;

View file

@ -143,50 +143,55 @@ QWidget *CSVWorld::CommandDelegate::createEditor (QWidget *parent, const QStyleO
} }
} }
if (display != CSMWorld::ColumnBase::Display_None) switch (display)
{ {
if (variant.type() == QVariant::Color) case CSMWorld::ColumnBase::Display_Colour:
{
return new QLineEdit(parent); return new QLineEdit(parent);
}
if (display == CSMWorld::ColumnBase::Display_Integer) case CSMWorld::ColumnBase::Display_Integer:
{
return new QSpinBox(parent); return new QSpinBox(parent);
}
if (display == CSMWorld::ColumnBase::Display_Var) case CSMWorld::ColumnBase::Display_Var:
{
return new QLineEdit(parent); return new QLineEdit(parent);
}
if (display == CSMWorld::ColumnBase::Display_Float) case CSMWorld::ColumnBase::Display_Float:
{
return new QDoubleSpinBox(parent); return new QDoubleSpinBox(parent);
}
if (display == CSMWorld::ColumnBase::Display_LongString) case CSMWorld::ColumnBase::Display_LongString:
{
return new QTextEdit(parent); return new QTextEdit(parent);
}
if (display == CSMWorld::ColumnBase::Display_String || case CSMWorld::ColumnBase::Display_Boolean:
display == CSMWorld::ColumnBase::Display_Skill ||
display == CSMWorld::ColumnBase::Display_Script ||
display == CSMWorld::ColumnBase::Display_Race ||
display == CSMWorld::ColumnBase::Display_Class ||
display == CSMWorld::ColumnBase::Display_Faction ||
display == CSMWorld::ColumnBase::Display_Miscellaneous ||
display == CSMWorld::ColumnBase::Display_Sound ||
display == CSMWorld::ColumnBase::Display_Region)
{
return new DropLineEdit(parent);
}
if (display == CSMWorld::ColumnBase::Display_Boolean)
{
return new QCheckBox(parent); return new QCheckBox(parent);
}
case CSMWorld::ColumnBase::Display_String:
case CSMWorld::ColumnBase::Display_Skill:
case CSMWorld::ColumnBase::Display_Script:
case CSMWorld::ColumnBase::Display_Race:
case CSMWorld::ColumnBase::Display_Class:
case CSMWorld::ColumnBase::Display_Faction:
case CSMWorld::ColumnBase::Display_Miscellaneous:
case CSMWorld::ColumnBase::Display_Mesh:
case CSMWorld::ColumnBase::Display_Icon:
case CSMWorld::ColumnBase::Display_Music:
case CSMWorld::ColumnBase::Display_SoundRes:
case CSMWorld::ColumnBase::Display_Texture:
case CSMWorld::ColumnBase::Display_Video:
case CSMWorld::ColumnBase::Display_Sound:
return new DropLineEdit(parent);
default:
return QStyledItemDelegate::createEditor (parent, option, index);
} }
return QStyledItemDelegate::createEditor (parent, option, index);
} }
void CSVWorld::CommandDelegate::setEditLock (bool locked) void CSVWorld::CommandDelegate::setEditLock (bool locked)
{ {
mEditLock = locked; mEditLock = locked;

View file

@ -322,6 +322,15 @@ namespace MWGui
if (_sender == mFullscreenButton) if (_sender == mFullscreenButton)
{ {
// check if this resolution is supported in fullscreen // check if this resolution is supported in fullscreen
if (mResolutionList->getIndexSelected() != MyGUI::ITEM_NONE)
{
std::string resStr = mResolutionList->getItemNameAt(mResolutionList->getIndexSelected());
int resX, resY;
parseResolution (resX, resY, resStr);
Settings::Manager::setInt("resolution x", "Video", resX);
Settings::Manager::setInt("resolution y", "Video", resY);
}
bool supported = false; bool supported = false;
for (unsigned int i=0; i<mResolutionList->getItemCount(); ++i) for (unsigned int i=0; i<mResolutionList->getItemCount(); ++i)
{ {

View file

@ -419,11 +419,11 @@ namespace MWGui
std::string effectIDStr = ESM::MagicEffect::effectIdToString(mEffectParams.mEffectID); std::string effectIDStr = ESM::MagicEffect::effectIdToString(mEffectParams.mEffectID);
std::string spellLine = MWBase::Environment::get().getWindowManager()->getGameSettingString(effectIDStr, ""); std::string spellLine = MWBase::Environment::get().getWindowManager()->getGameSettingString(effectIDStr, "");
if (magicEffect->mData.mFlags & ESM::MagicEffect::TargetSkill) if (magicEffect->mData.mFlags & ESM::MagicEffect::TargetSkill && mEffectParams.mSkill != -1)
{ {
spellLine += " " + MWBase::Environment::get().getWindowManager()->getGameSettingString(ESM::Skill::sSkillNameIds[mEffectParams.mSkill], ""); spellLine += " " + MWBase::Environment::get().getWindowManager()->getGameSettingString(ESM::Skill::sSkillNameIds[mEffectParams.mSkill], "");
} }
if (magicEffect->mData.mFlags & ESM::MagicEffect::TargetAttribute) if (magicEffect->mData.mFlags & ESM::MagicEffect::TargetAttribute && mEffectParams.mAttribute != -1)
{ {
spellLine += " " + MWBase::Environment::get().getWindowManager()->getGameSettingString(ESM::Attribute::sGmstAttributeIds[mEffectParams.mAttribute], ""); spellLine += " " + MWBase::Environment::get().getWindowManager()->getGameSettingString(ESM::Attribute::sGmstAttributeIds[mEffectParams.mAttribute], "");
} }

View file

@ -64,6 +64,8 @@ void TerrainGrid::loadCell(int x, int y)
element.mChunk = new Terrain::Chunk(mCache.getUVBuffer(), bounds, positions, normals, colours); element.mChunk = new Terrain::Chunk(mCache.getUVBuffer(), bounds, positions, normals, colours);
element.mChunk->setIndexBuffer(mCache.getIndexBuffer(0)); element.mChunk->setIndexBuffer(mCache.getIndexBuffer(0));
element.mChunk->setVisibilityFlags(mVisibilityFlags);
element.mChunk->setCastShadows(true);
std::vector<Ogre::PixelBox> blendmaps; std::vector<Ogre::PixelBox> blendmaps;
std::vector<Terrain::LayerInfo> layerList; std::vector<Terrain::LayerInfo> layerList;

View file

@ -403,5 +403,7 @@ op 0x200024a: OnMurder, explicit
op 0x200024b: ToggleMenus op 0x200024b: ToggleMenus
op 0x200024c: Face op 0x200024c: Face
op 0x200024d: Face, explicit op 0x200024d: Face, explicit
op 0x200024e: GetStat (dummy function)
op 0x200024f: GetStat (dummy function), explicit
opcodes 0x200024e-0x3ffffff unused opcodes 0x2000250-0x3ffffff unused

View file

@ -5,6 +5,7 @@
#include <components/esm/locals.hpp> #include <components/esm/locals.hpp>
#include <components/compiler/locals.hpp> #include <components/compiler/locals.hpp>
#include <components/compiler/exception.hpp>
#include "../mwbase/environment.hpp" #include "../mwbase/environment.hpp"
#include "../mwbase/scriptmanager.hpp" #include "../mwbase/scriptmanager.hpp"
@ -75,65 +76,77 @@ namespace MWScript
void Locals::write (ESM::Locals& locals, const std::string& script) const void Locals::write (ESM::Locals& locals, const std::string& script) const
{ {
const Compiler::Locals& declarations = try
MWBase::Environment::get().getScriptManager()->getLocals(script);
for (int i=0; i<3; ++i)
{ {
char type = 0; const Compiler::Locals& declarations =
MWBase::Environment::get().getScriptManager()->getLocals(script);
switch (i) for (int i=0; i<3; ++i)
{ {
case 0: type = 's'; break; char type = 0;
case 1: type = 'l'; break;
case 2: type = 'f'; break;
}
const std::vector<std::string>& names = declarations.get (type);
for (int i2=0; i2<static_cast<int> (names.size()); ++i2)
{
ESM::Variant value;
switch (i) switch (i)
{ {
case 0: value.setType (ESM::VT_Int); value.setInteger (mShorts.at (i2)); break; case 0: type = 's'; break;
case 1: value.setType (ESM::VT_Int); value.setInteger (mLongs.at (i2)); break; case 1: type = 'l'; break;
case 2: value.setType (ESM::VT_Float); value.setFloat (mFloats.at (i2)); break; case 2: type = 'f'; break;
} }
locals.mVariables.push_back (std::make_pair (names[i2], value)); const std::vector<std::string>& names = declarations.get (type);
for (int i2=0; i2<static_cast<int> (names.size()); ++i2)
{
ESM::Variant value;
switch (i)
{
case 0: value.setType (ESM::VT_Int); value.setInteger (mShorts.at (i2)); break;
case 1: value.setType (ESM::VT_Int); value.setInteger (mLongs.at (i2)); break;
case 2: value.setType (ESM::VT_Float); value.setFloat (mFloats.at (i2)); break;
}
locals.mVariables.push_back (std::make_pair (names[i2], value));
}
} }
} }
catch (const Compiler::SourceException&)
{
}
} }
void Locals::read (const ESM::Locals& locals, const std::string& script) void Locals::read (const ESM::Locals& locals, const std::string& script)
{ {
const Compiler::Locals& declarations = try
MWBase::Environment::get().getScriptManager()->getLocals(script);
for (std::vector<std::pair<std::string, ESM::Variant> >::const_iterator iter
= locals.mVariables.begin(); iter!=locals.mVariables.end(); ++iter)
{ {
char type = declarations.getType (iter->first); const Compiler::Locals& declarations =
char index = declarations.getIndex (iter->first); MWBase::Environment::get().getScriptManager()->getLocals(script);
try for (std::vector<std::pair<std::string, ESM::Variant> >::const_iterator iter
= locals.mVariables.begin(); iter!=locals.mVariables.end(); ++iter)
{ {
switch (type) char type = declarations.getType (iter->first);
{ char index = declarations.getIndex (iter->first);
case 's': mShorts.at (index) = iter->second.getInteger(); break;
case 'l': mLongs.at (index) = iter->second.getInteger(); break;
case 'f': mFloats.at (index) = iter->second.getFloat(); break;
// silently ignore locals that don't exist anymore try
{
switch (type)
{
case 's': mShorts.at (index) = iter->second.getInteger(); break;
case 'l': mLongs.at (index) = iter->second.getInteger(); break;
case 'f': mFloats.at (index) = iter->second.getFloat(); break;
// silently ignore locals that don't exist anymore
}
}
catch (...)
{
// ignore type changes
/// \todo write to log
} }
} }
catch (...) }
{ catch (const Compiler::SourceException&)
// ignore type changes {
/// \todo write to log
}
} }
} }
} }

View file

@ -24,6 +24,7 @@
#include "../mwworld/player.hpp" #include "../mwworld/player.hpp"
#include "../mwworld/containerstore.hpp" #include "../mwworld/containerstore.hpp"
#include "../mwworld/esmstore.hpp" #include "../mwworld/esmstore.hpp"
#include "../mwworld/cellstore.hpp"
#include "../mwmechanics/npcstats.hpp" #include "../mwmechanics/npcstats.hpp"
#include "../mwmechanics/creaturestats.hpp" #include "../mwmechanics/creaturestats.hpp"
@ -886,7 +887,8 @@ namespace MWScript
{ {
MWWorld::CellStore* cell = ptr.getCell(); MWWorld::CellStore* cell = ptr.getCell();
msg << "Cell: " << MWBase::Environment::get().getWorld()->getCellName(cell) << std::endl; msg << "Cell: " << MWBase::Environment::get().getWorld()->getCellName(cell) << std::endl;
if (cell->getCell()->isExterior())
msg << "Grid: " << cell->getCell()->getGridX() << " " << cell->getCell()->getGridY() << std::endl;
Ogre::Vector3 pos (ptr.getRefData().getPosition().pos); Ogre::Vector3 pos (ptr.getRefData().getPosition().pos);
msg << "Coordinates: " << pos << std::endl; msg << "Coordinates: " << pos << std::endl;
} }

View file

@ -260,7 +260,7 @@ namespace MWScript
MWMechanics::DynamicStat<float> stat (ptr.getClass().getCreatureStats (ptr) MWMechanics::DynamicStat<float> stat (ptr.getClass().getCreatureStats (ptr)
.getDynamic (mIndex)); .getDynamic (mIndex));
stat.setCurrent (diff + current); stat.setCurrent (diff + current, true);
ptr.getClass().getCreatureStats (ptr).setDynamic (mIndex, stat); ptr.getClass().getCreatureStats (ptr).setDynamic (mIndex, stat);
} }
@ -1165,6 +1165,17 @@ namespace MWScript
} }
}; };
template <class R>
class OpGetStat : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
// dummy
runtime.push(0);
}
};
void installOpcodes (Interpreter::Interpreter& interpreter) void installOpcodes (Interpreter::Interpreter& interpreter)
{ {
for (int i=0; i<Compiler::Stats::numberOfAttributes; ++i) for (int i=0; i<Compiler::Stats::numberOfAttributes; ++i)
@ -1307,6 +1318,8 @@ namespace MWScript
interpreter.installSegment5 (Compiler::Stats::opcodeUndoWerewolfExplicit, new OpSetWerewolf<ExplicitRef, false>); interpreter.installSegment5 (Compiler::Stats::opcodeUndoWerewolfExplicit, new OpSetWerewolf<ExplicitRef, false>);
interpreter.installSegment5 (Compiler::Stats::opcodeSetWerewolfAcrobatics, new OpSetWerewolfAcrobatics<ImplicitRef>); interpreter.installSegment5 (Compiler::Stats::opcodeSetWerewolfAcrobatics, new OpSetWerewolfAcrobatics<ImplicitRef>);
interpreter.installSegment5 (Compiler::Stats::opcodeSetWerewolfAcrobaticsExplicit, new OpSetWerewolfAcrobatics<ExplicitRef>); interpreter.installSegment5 (Compiler::Stats::opcodeSetWerewolfAcrobaticsExplicit, new OpSetWerewolfAcrobatics<ExplicitRef>);
interpreter.installSegment5 (Compiler::Stats::opcodeGetStat, new OpGetStat<ImplicitRef>);
interpreter.installSegment5 (Compiler::Stats::opcodeGetStatExplicit, new OpGetStat<ExplicitRef>);
} }
} }
} }

View file

@ -23,11 +23,14 @@ void Store<ESM::Cell>::handleMovedCellRefs(ESM::ESMReader& esm, ESM::Cell* cell)
// We should not need to test for duplicates, as this part of the code is pre-cell merge. // We should not need to test for duplicates, as this part of the code is pre-cell merge.
cell->mMovedRefs.push_back(cMRef); cell->mMovedRefs.push_back(cMRef);
// But there may be duplicates here! // But there may be duplicates here!
ESM::CellRefTracker::iterator iter = std::find(cellAlt->mLeasedRefs.begin(), cellAlt->mLeasedRefs.end(), ref.mRefNum); if (!deleted)
if (iter == cellAlt->mLeasedRefs.end()) {
cellAlt->mLeasedRefs.push_back(ref); ESM::CellRefTracker::iterator iter = std::find(cellAlt->mLeasedRefs.begin(), cellAlt->mLeasedRefs.end(), ref.mRefNum);
else if (iter == cellAlt->mLeasedRefs.end())
*iter = ref; cellAlt->mLeasedRefs.push_back(ref);
else
*iter = ref;
}
} }
} }
@ -90,6 +93,8 @@ void Store<ESM::Cell>::load(ESM::ESMReader &esm, const std::string &id)
wipecell->mLeasedRefs.erase(it_lease); wipecell->mLeasedRefs.erase(it_lease);
*itold = *it; *itold = *it;
} }
else
oldcell->mMovedRefs.push_back(*it);
} }
// We don't need to merge mLeasedRefs of cell / oldcell. This list is filled when another cell moves a // We don't need to merge mLeasedRefs of cell / oldcell. This list is filled when another cell moves a

View file

@ -431,6 +431,8 @@ namespace Compiler
extensions.registerInstruction("setlevel", "l", opcodeSetLevel, opcodeSetLevelExplicit); extensions.registerInstruction("setlevel", "l", opcodeSetLevel, opcodeSetLevelExplicit);
extensions.registerFunction("getlevel", 'l', "", opcodeGetLevel, opcodeGetLevelExplicit); extensions.registerFunction("getlevel", 'l', "", opcodeGetLevel, opcodeGetLevelExplicit);
extensions.registerFunction("getstat", 'l', "c", opcodeGetStat, opcodeGetStatExplicit);
extensions.registerFunction ("getdeadcount", 'l', "c", opcodeGetDeadCount); extensions.registerFunction ("getdeadcount", 'l', "c", opcodeGetDeadCount);
extensions.registerFunction ("getpcfacrep", 'l', "/c", opcodeGetPCFacRep, opcodeGetPCFacRepExplicit); extensions.registerFunction ("getpcfacrep", 'l', "/c", opcodeGetPCFacRep, opcodeGetPCFacRepExplicit);

View file

@ -410,6 +410,9 @@ namespace Compiler
const int opcodeRemoveEffectsExplicit = 0x200022e; const int opcodeRemoveEffectsExplicit = 0x200022e;
const int opcodeResurrect = 0x200022f; const int opcodeResurrect = 0x200022f;
const int opcodeResurrectExplicit = 0x2000230; const int opcodeResurrectExplicit = 0x2000230;
const int opcodeGetStat = 0x200024e;
const int opcodeGetStatExplicit = 0x200024f;
} }
namespace Transformation namespace Transformation

View file

@ -22,4 +22,14 @@ void BodyPart::save(ESMWriter &esm) const
esm.writeHNT("BYDT", mData, 4); esm.writeHNT("BYDT", mData, 4);
} }
void BodyPart::blank()
{
mData.mPart = 0;
mData.mVampire = 0;
mData.mFlags = 0;
mData.mType = 0;
mModel.clear();
mRace.clear();
}
} }

View file

@ -60,6 +60,9 @@ struct BodyPart
void load(ESMReader &esm); void load(ESMReader &esm);
void save(ESMWriter &esm) const; void save(ESMWriter &esm) const;
void blank();
///< Set record to default state (does not touch the ID).
}; };
} }
#endif #endif

View file

@ -20,4 +20,13 @@ void Enchantment::save(ESMWriter &esm) const
mEffects.save(esm); mEffects.save(esm);
} }
void Enchantment::blank()
{
mData.mType = 0;
mData.mCost = 0;
mData.mCharge = 0;
mData.mAutocalc = 0;
mEffects.mList.clear();
}
} }

View file

@ -42,6 +42,9 @@ struct Enchantment
void load(ESMReader &esm); void load(ESMReader &esm);
void save(ESMWriter &esm) const; void save(ESMWriter &esm) const;
void blank();
///< Set record to default state (does not touch the ID).
}; };
} }
#endif #endif

View file

@ -267,10 +267,11 @@ namespace sh
MaterialInstance* Factory::searchInstance (const std::string& name) MaterialInstance* Factory::searchInstance (const std::string& name)
{ {
if (mMaterials.find(name) != mMaterials.end()) MaterialMap::iterator it = mMaterials.find(name);
return &mMaterials.find(name)->second; if (it != mMaterials.end())
return &(it->second);
return NULL; else
return NULL;
} }
MaterialInstance* Factory::findInstance (const std::string& name) MaterialInstance* Factory::findInstance (const std::string& name)
@ -434,8 +435,9 @@ namespace sh
std::string Factory::retrieveTextureAlias (const std::string& name) std::string Factory::retrieveTextureAlias (const std::string& name)
{ {
if (mTextureAliases.find(name) != mTextureAliases.end()) TextureAliasMap::iterator it = mTextureAliases.find(name);
return mTextureAliases[name]; if (it != mTextureAliases.end())
return it->second;
else else
return ""; return "";
} }