1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-02-01 18:45:31 +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
idtable idtableproxymodel regionmap data commanddispatcher
nestedtablemodel
idtablebase resourcetable nestedtablemodel
)
opencs_units_noqt (model/world
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

View file

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

View file

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

View file

@ -31,6 +31,11 @@ namespace Files
class ConfigurationManager;
}
namespace CSMWorld
{
class ResourcesManager;
}
namespace CSMDoc
{
class Document : public QObject
@ -73,7 +78,7 @@ namespace CSMDoc
Document (const Files::ConfigurationManager& configuration,
const std::vector< boost::filesystem::path >& files, bool new_,
const boost::filesystem::path& savePath, const boost::filesystem::path& resDir,
ToUTF8::FromType encoding);
ToUTF8::FromType encoding, const CSMWorld::ResourcesManager& resourcesManager);
~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,
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);
@ -85,6 +85,11 @@ void CSMDoc::DocumentManager::setEncoding (ToUTF8::FromType encoding)
mEncoding = encoding;
}
void CSMDoc::DocumentManager::listResources()
{
mResourcesManager.listResources();
}
void CSMDoc::DocumentManager::documentLoaded (Document *document)
{
emit documentAdded (document);

View file

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

View file

@ -7,7 +7,7 @@ CSMFilter::AndNode::AndNode (const std::vector<boost::shared_ptr<Node> >& nodes)
: 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
{
int size = getSize();

View file

@ -11,7 +11,7 @@ namespace CSMFilter
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;
///< \return Can the specified table row pass through to filter?
/// \param columns column ID to column index mapping

View file

@ -3,7 +3,7 @@
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
{
return mTrue;

View file

@ -13,7 +13,7 @@ namespace CSMFilter
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;
///< \return Can the specified table row pass through to filter?
/// \param columns column ID to column index mapping

View file

@ -11,7 +11,7 @@
namespace CSMWorld
{
class IdTable;
class IdTableBase;
}
namespace CSMFilter
@ -32,7 +32,7 @@ namespace CSMFilter
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;
///< \return Can the specified table row pass through to filter?
/// \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") {}
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
{
return !getChild().test (table, row, columns);

View file

@ -11,7 +11,7 @@ namespace CSMFilter
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;
///< \return Can the specified table row pass through to filter?
/// \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")
{}
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
{
int size = getSize();

View file

@ -11,7 +11,7 @@ namespace CSMFilter
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;
///< \return Can the specified table row pass through to filter?
/// \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)
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));

View file

@ -7,13 +7,13 @@
#include <QRegExp>
#include "../world/columns.hpp"
#include "../world/idtable.hpp"
#include "../world/idtablebase.hpp"
CSMFilter::TextNode::TextNode (int columnId, const std::string& 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>::const_iterator iter = columns.find (mColumnId);

View file

@ -14,7 +14,7 @@ namespace CSMFilter
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;
///< \return Can the specified table row pass through to filter?
/// \param columns column ID to column index mapping

View file

@ -5,13 +5,13 @@
#include <stdexcept>
#include "../world/columns.hpp"
#include "../world/idtable.hpp"
#include "../world/idtablebase.hpp"
CSMFilter::ValueNode::ValueNode (int columnId, Type lowerType, Type upperType,
double lower, double 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>::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);
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;
///< \return Can the specified table row pass through to filter?
/// \param columns column ID to column index mapping

View file

@ -90,10 +90,20 @@ namespace CSMWorld
Display_RefRecordType,
Display_DialogueType,
Display_QuestStatusType,
Display_Gender,
//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;

View file

@ -463,14 +463,21 @@ namespace CSMWorld
struct FlagColumn : public Column<ESXRecordT>
{
int mMask;
bool mInverted;
FlagColumn (int columnId, int mask)
: Column<ESXRecordT> (columnId, ColumnBase::Display_Boolean), mMask (mask)
FlagColumn (int columnId, int mask, bool inverted = false)
: Column<ESXRecordT> (columnId, ColumnBase::Display_Boolean), mMask (mask),
mInverted (inverted)
{}
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)
@ -479,7 +486,7 @@ namespace CSMWorld
int flags = record2.mData.mFlags & ~mMask;
if (data.toInt())
if ((data.toInt()!=0)!=mInverted)
flags |= mMask;
record2.mData.mFlags = flags;
@ -597,7 +604,7 @@ namespace CSMWorld
struct SoundFileColumn : public Column<ESXRecordT>
{
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
@ -627,7 +634,7 @@ namespace CSMWorld
{
/// \todo Replace Display_Integer with something that displays the colour value more directly.
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
@ -1682,6 +1689,187 @@ namespace CSMWorld
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

View file

@ -176,6 +176,13 @@ namespace CSMWorld
{ ColumnId_ReferenceableId, "Referenceable ID" },
{ ColumnId_InventoryItemId, "ID"},
{ 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_UseValue2, "Use value 2" },
@ -301,6 +308,22 @@ namespace
"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)
{
switch (column)
@ -318,6 +341,9 @@ namespace
case CSMWorld::Columns::ColumnId_DialogueType: return sDialogueTypeEnums;
case CSMWorld::Columns::ColumnId_QuestStatusType: return sQuestStatusTypes;
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;
}

View file

@ -172,6 +172,13 @@ namespace CSMWorld
ColumnId_ContainerContent = 157,
ColumnId_ItemCount = 158,
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
// to extend the number of use values.

View file

@ -15,6 +15,8 @@
#include "columnimp.hpp"
#include "regionmap.hpp"
#include "columns.hpp"
#include "resourcesmanager.hpp"
#include "resourcetable.hpp"
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;
}
CSMWorld::Data::Data (ToUTF8::FromType encoding)
: mEncoder (encoding), mRefs (mCells), mReader (0), mDialogue (0)
CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourcesManager)
: mEncoder (encoding), mRefs (mCells), mResourcesManager (resourcesManager), mReader (0),
mDialogue (0)
{
mGlobals.addColumn (new StringIdColumn<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 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 RecordStateColumn<CellRef>);
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 (&mJournalInfos, IdTable::Feature_ReorderWithinTopic), UniversalId::Type_JournalInfo);
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),
UniversalId::Type_Referenceable);
addModel (new IdTable (&mRefs, IdTable::Feature_ViewCell | IdTable::Feature_Preview), UniversalId::Type_Reference);
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()
@ -457,6 +493,31 @@ CSMWorld::IdCollection<CSMFilter::Filter>& CSMWorld::Data::getFilters()
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)
{
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_BSGN: mBirthsigns.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:
{
@ -668,6 +731,8 @@ bool CSMWorld::Data::hasId (const std::string& id) const
getTopics().searchId (id)!=-1 ||
getJournals().searchId (id)!=-1 ||
getCells().searchId (id)!=-1 ||
getEnchantments().searchId (id)!=-1 ||
getBodyParts().searchId (id)!=-1 ||
getReferenceables().searchId (id)!=-1;
}
@ -686,6 +751,8 @@ int CSMWorld::Data::count (RecordBase::State state) const
count (state, mBirthsigns) +
count (state, mSpells) +
count (state, mCells) +
count (state, mEnchantments) +
count (state, mBodyParts) +
count (state, mReferenceables);
}
@ -726,6 +793,8 @@ std::vector<std::string> CSMWorld::Data::getIds (bool listDeleted) const
appendIds (ids, mTopics, listDeleted);
appendIds (ids, mJournals, listDeleted);
appendIds (ids, mCells, listDeleted);
appendIds (ids, mEnchantments, listDeleted);
appendIds (ids, mBodyParts, listDeleted);
appendIds (ids, mReferenceables, listDeleted);
std::sort (ids.begin(), ids.end());

View file

@ -21,6 +21,8 @@
#include <components/esm/loadbsgn.hpp>
#include <components/esm/loadspel.hpp>
#include <components/esm/loaddial.hpp>
#include <components/esm/loadench.hpp>
#include <components/esm/loadbody.hpp>
#include <components/to_utf8/to_utf8.hpp>
@ -45,6 +47,9 @@ namespace ESM
namespace CSMWorld
{
class ResourcesManager;
class Resources;
class Data : public QObject
{
Q_OBJECT
@ -63,12 +68,15 @@ namespace CSMWorld
IdCollection<ESM::Spell> mSpells;
IdCollection<ESM::Dialogue> mTopics;
IdCollection<ESM::Dialogue> mJournals;
IdCollection<ESM::Enchantment> mEnchantments;
IdCollection<ESM::BodyPart> mBodyParts;
InfoCollection mTopicInfos;
InfoCollection mJournalInfos;
IdCollection<Cell> mCells;
RefIdCollection mReferenceables;
RefCollection mRefs;
IdCollection<CSMFilter::Filter> mFilters;
const ResourcesManager& mResourcesManager;
std::vector<QAbstractItemModel *> mModels;
std::map<UniversalId::Type, QAbstractItemModel *> mModelIndex;
std::string mAuthor;
@ -94,7 +102,7 @@ namespace CSMWorld
public:
Data (ToUTF8::FromType encoding);
Data (ToUTF8::FromType encoding, const ResourcesManager& resourcesManager);
virtual ~Data();
@ -174,6 +182,17 @@ namespace CSMWorld
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);
///< 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 (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);
///< 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
{
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);
load (record, base);
load (record, base, index);
}
}
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)
{

View file

@ -7,7 +7,7 @@
#include "columnbase.hpp"
CSMWorld::IdTable::IdTable (CollectionBase *idCollection, unsigned int features)
: mIdCollection (idCollection), mFeatures (features)
: IdTableBase (features), mIdCollection (idCollection)
{}
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));
}
unsigned int CSMWorld::IdTable::getFeatures() const
{
return mFeatures;
}
std::pair<CSMWorld::UniversalId, std::string> CSMWorld::IdTable::view (int row) const
{
std::string id;
std::string hint;
if (mFeatures & Feature_ViewCell)
if (getFeatures() & Feature_ViewCell)
{
int cellColumn = mIdCollection->searchColumnIndex (Columns::ColumnId_Cell);
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());
}
}
else if (mFeatures & Feature_ViewId)
else if (getFeatures() & Feature_ViewId)
{
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
bool CSMWorld::IdTable::isDeleted (const std::string& id) const
{
return getRecord (id).isDeleted();
}
int CSMWorld::IdTable::getColumnId(int column) const
{
return mIdCollection->getColumn(column).getId();

View file

@ -3,8 +3,7 @@
#include <vector>
#include <QAbstractItemModel>
#include "idtablebase.hpp"
#include "universalid.hpp"
#include "columns.hpp"
@ -22,34 +21,13 @@ namespace CSMWorld
class CollectionBase;
class RecordBase;
class IdTable : public QAbstractItemModel
class IdTable : public IdTableBase
{
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:
CollectionBase *mIdCollection;
unsigned int mFeatures;
bool mPreview;
// not implemented
IdTable (const IdTable&);
@ -96,17 +74,17 @@ namespace CSMWorld
const std::string& destination,
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);
///< Add record or overwrite existing recrod.
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.
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
/// thrown.
@ -114,12 +92,13 @@ namespace CSMWorld
///< 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).
unsigned int getFeatures() const;
std::pair<UniversalId, std::string> view (int row) const;
virtual std::pair<UniversalId, std::string> view (int row) const;
///< Return the UniversalId and the hint for viewing \a row. If viewing is not
/// 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;
};
}

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 "idtable.hpp"
#include "idtablebase.hpp"
void CSMWorld::IdTableProxyModel::updateColumnMap()
{
@ -13,7 +13,7 @@ void CSMWorld::IdTableProxyModel::updateColumnMap()
{
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)
mColumnMap.insert (std::make_pair (*iter,
@ -28,7 +28,7 @@ bool CSMWorld::IdTableProxyModel::filterAcceptsRow (int sourceRow, const QModelI
return true;
return mFilter->test (
dynamic_cast<IdTable&> (*sourceModel()), sourceRow, mColumnMap);
dynamic_cast<IdTableBase&> (*sourceModel()), sourceRow, mColumnMap);
}
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
{
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)

View file

@ -361,6 +361,15 @@ QVariant CSMWorld::CreatureRefIdAdapter::getData (const RefIdColumn *column, con
if (column==mColumns.mOriginal)
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 =
mColumns.mFlags.find (column);
@ -384,6 +393,12 @@ void CSMWorld::CreatureRefIdAdapter::setData (const RefIdColumn *column, RefIdDa
record.get().mScale = value.toFloat();
else if (column==mColumns.mOriginal)
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
{
std::map<const RefIdColumn *, unsigned int>::const_iterator iter =

View file

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

View file

@ -53,7 +53,7 @@ CSMWorld::RefIdCollection::RefIdCollection()
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();
NameColumns nameColumns (modelColumns);
@ -65,7 +65,7 @@ CSMWorld::RefIdCollection::RefIdCollection()
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();
mColumns.push_back (RefIdColumn (Columns::ColumnId_Weight, ColumnBase::Display_Float));
inventoryColumns.mWeight = &mColumns.back();
@ -183,6 +183,15 @@ CSMWorld::RefIdCollection::RefIdCollection()
creatureColumns.mScale = &mColumns.back();
mColumns.push_back (RefIdColumn (Columns::ColumnId_OriginalCreature, ColumnBase::Display_String));
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
{

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())
{
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;
@ -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
@ -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
@ -209,327 +209,82 @@ bool CSMWorld::TableMimeData::fromDocument (const CSMDoc::Document& document) co
return &document == &mDocument;
}
CSMWorld::UniversalId::Type CSMWorld::TableMimeData::convertEnums (CSMWorld::ColumnBase::Display type)
namespace
{
switch (type)
struct Mapping
{
case CSMWorld::ColumnBase::Display_Race:
return CSMWorld::UniversalId::Type_Race;
case CSMWorld::ColumnBase::Display_Skill:
return CSMWorld::UniversalId::Type_Skill;
case CSMWorld::ColumnBase::Display_Class:
return CSMWorld::UniversalId::Type_Class;
case CSMWorld::ColumnBase::Display_Faction:
return CSMWorld::UniversalId::Type_Faction;
case CSMWorld::ColumnBase::Display_Sound:
return CSMWorld::UniversalId::Type_Sound;
case CSMWorld::ColumnBase::Display_Region:
return CSMWorld::UniversalId::Type_Region;
case CSMWorld::ColumnBase::Display_Birthsign:
return CSMWorld::UniversalId::Type_Birthsign;
case CSMWorld::ColumnBase::Display_Spell:
return CSMWorld::UniversalId::Type_Spell;
case CSMWorld::ColumnBase::Display_Cell:
return CSMWorld::UniversalId::Type_Cell;
case CSMWorld::ColumnBase::Display_Referenceable:
return CSMWorld::UniversalId::Type_Referenceable;
case CSMWorld::ColumnBase::Display_Activator:
return CSMWorld::UniversalId::Type_Activator;
case CSMWorld::ColumnBase::Display_Potion:
return CSMWorld::UniversalId::Type_Potion;
case CSMWorld::ColumnBase::Display_Apparatus:
return CSMWorld::UniversalId::Type_Apparatus;
case CSMWorld::ColumnBase::Display_Armor:
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::UniversalId::Type mUniversalIdType;
CSMWorld::ColumnBase::Display mDisplayType;
};
const Mapping mapping[] =
{
{ CSMWorld::UniversalId::Type_Race, CSMWorld::ColumnBase::Display_Race },
{ CSMWorld::UniversalId::Type_Skill, CSMWorld::ColumnBase::Display_Skill },
{ CSMWorld::UniversalId::Type_Class, CSMWorld::ColumnBase::Display_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 },
{ CSMWorld::UniversalId::Type_Region, CSMWorld::ColumnBase::Display_Region },
{ CSMWorld::UniversalId::Type_Birthsign, CSMWorld::ColumnBase::Display_Birthsign },
{ CSMWorld::UniversalId::Type_Spell, CSMWorld::ColumnBase::Display_Spell },
{ CSMWorld::UniversalId::Type_Cell, CSMWorld::ColumnBase::Display_Cell },
{ CSMWorld::UniversalId::Type_Referenceable, CSMWorld::ColumnBase::Display_Referenceable },
{ CSMWorld::UniversalId::Type_Activator, CSMWorld::ColumnBase::Display_Activator },
{ CSMWorld::UniversalId::Type_Potion, CSMWorld::ColumnBase::Display_Potion },
{ CSMWorld::UniversalId::Type_Apparatus, CSMWorld::ColumnBase::Display_Apparatus },
{ CSMWorld::UniversalId::Type_Armor, CSMWorld::ColumnBase::Display_Armor },
{ CSMWorld::UniversalId::Type_Book, CSMWorld::ColumnBase::Display_Book },
{ CSMWorld::UniversalId::Type_Clothing, CSMWorld::ColumnBase::Display_Clothing },
{ CSMWorld::UniversalId::Type_Container, CSMWorld::ColumnBase::Display_Container },
{ CSMWorld::UniversalId::Type_Creature, CSMWorld::ColumnBase::Display_Creature },
{ CSMWorld::UniversalId::Type_Door, CSMWorld::ColumnBase::Display_Door },
{ CSMWorld::UniversalId::Type_Ingredient, CSMWorld::ColumnBase::Display_Ingredient },
{ CSMWorld::UniversalId::Type_CreatureLevelledList, CSMWorld::ColumnBase::Display_CreatureLevelledList },
{ CSMWorld::UniversalId::Type_ItemLevelledList, CSMWorld::ColumnBase::Display_ItemLevelledList },
{ CSMWorld::UniversalId::Type_Light, CSMWorld::ColumnBase::Display_Light },
{ CSMWorld::UniversalId::Type_Lockpick, CSMWorld::ColumnBase::Display_Lockpick },
{ CSMWorld::UniversalId::Type_Miscellaneous, CSMWorld::ColumnBase::Display_Miscellaneous },
{ CSMWorld::UniversalId::Type_Npc, CSMWorld::ColumnBase::Display_Npc },
{ CSMWorld::UniversalId::Type_Probe, CSMWorld::ColumnBase::Display_Probe },
{ CSMWorld::UniversalId::Type_Repair, CSMWorld::ColumnBase::Display_Repair },
{ CSMWorld::UniversalId::Type_Static, CSMWorld::ColumnBase::Display_Static },
{ CSMWorld::UniversalId::Type_Weapon, CSMWorld::ColumnBase::Display_Weapon },
{ CSMWorld::UniversalId::Type_Reference, CSMWorld::ColumnBase::Display_Reference },
{ CSMWorld::UniversalId::Type_Filter, CSMWorld::ColumnBase::Display_Filter },
{ CSMWorld::UniversalId::Type_Topic, CSMWorld::ColumnBase::Display_Topic },
{ CSMWorld::UniversalId::Type_Journal, CSMWorld::ColumnBase::Display_Journal },
{ CSMWorld::UniversalId::Type_TopicInfo, CSMWorld::ColumnBase::Display_TopicInfo },
{ CSMWorld::UniversalId::Type_JournalInfo, CSMWorld::ColumnBase::Display_JournalInfo },
{ CSMWorld::UniversalId::Type_Scene, CSMWorld::ColumnBase::Display_Scene },
{ CSMWorld::UniversalId::Type_Script, CSMWorld::ColumnBase::Display_Script },
{ CSMWorld::UniversalId::Type_Mesh, CSMWorld::ColumnBase::Display_Mesh },
{ CSMWorld::UniversalId::Type_Icon, CSMWorld::ColumnBase::Display_Icon },
{ CSMWorld::UniversalId::Type_Music, CSMWorld::ColumnBase::Display_Music },
{ CSMWorld::UniversalId::Type_SoundRes, CSMWorld::ColumnBase::Display_SoundRes },
{ CSMWorld::UniversalId::Type_Texture, CSMWorld::ColumnBase::Display_Texture },
{ CSMWorld::UniversalId::Type_Video, CSMWorld::ColumnBase::Display_Video },
{ CSMWorld::UniversalId::Type_None, CSMWorld::ColumnBase::Display_None } // end marker
};
}
CSMWorld::ColumnBase::Display CSMWorld::TableMimeData::convertEnums (CSMWorld::UniversalId::Type type)
CSMWorld::UniversalId::Type CSMWorld::TableMimeData::convertEnums (ColumnBase::Display type)
{
switch (type)
{
case CSMWorld::UniversalId::Type_Race:
return CSMWorld::ColumnBase::Display_Race;
for (int i=0; mapping[i].mUniversalIdType!=CSMWorld::UniversalId::Type_None; ++i)
if (mapping[i].mDisplayType==type)
return mapping[i].mUniversalIdType;
return CSMWorld::UniversalId::Type_None;
}
case CSMWorld::UniversalId::Type_Skill:
return CSMWorld::ColumnBase::Display_Skill;
CSMWorld::ColumnBase::Display CSMWorld::TableMimeData::convertEnums (UniversalId::Type type)
{
for (int i=0; mapping[i].mUniversalIdType!=CSMWorld::UniversalId::Type_None; ++i)
if (mapping[i].mUniversalIdType==type)
return mapping[i].mDisplayType;
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;
}
return CSMWorld::ColumnBase::Display_None;
}
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_JournalInfos, "Journal Infos", 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,
"Referenceables", 0 },
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_References,
@ -42,6 +44,12 @@ namespace
{ CSMWorld::UniversalId::Class_NonRecord, CSMWorld::UniversalId::Type_RegionMap,
"Region Map", 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
};
@ -92,8 +100,15 @@ namespace
{ CSMWorld::UniversalId::Class_SubRecord, CSMWorld::UniversalId::Type_Reference, "Reference", 0 },
{ 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_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
};
@ -328,7 +343,8 @@ CSMWorld::UniversalId::Type CSMWorld::UniversalId::getParentType (Type type)
if (sIdArg[i].mClass==Class_RefRecord)
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)
return Type_Cells;

View file

@ -22,7 +22,10 @@ namespace CSMWorld
Class_RecordList,
Class_Collection, // multiple types of records combined
Class_Transient, // not part of the world data or the project data
Class_NonRecord // record like data that is not part of the world
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
@ -100,10 +103,26 @@ namespace CSMWorld
Type_JournalInfo,
Type_Scene,
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:

View file

@ -146,6 +146,10 @@ void CSVDoc::View::setupMechanicsMenu()
QAction *spells = new QAction (tr ("Spells"), this);
connect (spells, SIGNAL (triggered()), this, SLOT (addSpellsSubView()));
mechanics->addAction (spells);
QAction *enchantments = new QAction (tr ("Enchantments"), this);
connect (enchantments, SIGNAL (triggered()), this, SLOT (addEnchantmentsSubView()));
mechanics->addAction (enchantments);
}
void CSVDoc::View::setupCharacterMenu()
@ -187,6 +191,10 @@ void CSVDoc::View::setupCharacterMenu()
QAction *journalInfos = new QAction (tr ("Journal Infos"), this);
connect (journalInfos, SIGNAL (triggered()), this, SLOT (addJournalInfosSubView()));
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()
@ -196,6 +204,32 @@ void CSVDoc::View::setupAssetsMenu()
QAction *sounds = new QAction (tr ("Sounds"), this);
connect (sounds, SIGNAL (triggered()), this, SLOT (addSoundsSubView()));
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()
@ -469,6 +503,46 @@ void CSVDoc::View::addJournalInfosSubView()
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)
{
mDocument->abortOperation (type);

View file

@ -178,6 +178,22 @@ namespace CSVDoc
void addJournalInfosSubView();
void addEnchantmentsSubView();
void addBodyPartsSubView();
void addMeshesSubView();
void addIconsSubView();
void addMusicsSubView();
void addSoundsResSubView();
void addTexturesSubView();
void addVideosSubView();
void toggleShowStatusBar (bool show);
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_DialogueType, CSMWorld::Columns::ColumnId_DialogueType, 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 }
};

View file

@ -15,13 +15,18 @@ bool CSVRender::PagedWorldspaceWidget::adjustCells()
bool modified = false;
bool setCamera = false;
const CSMWorld::IdCollection<CSMWorld::Cell>& cells = mDocument.getData().getCells();
{
// remove
std::map<CSMWorld::CellCoordinates, Cell *>::iterator iter (mCells.begin());
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;
mCells.erase (iter++);
@ -39,7 +44,10 @@ bool CSVRender::PagedWorldspaceWidget::adjustCells()
for (CSMWorld::CellSelection::Iterator iter (mSelection.begin()); iter!=mSelection.end();
++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)
{
@ -49,7 +57,7 @@ bool CSVRender::PagedWorldspaceWidget::adjustCells()
mCells.insert (std::make_pair (*iter,
new Cell (mDocument.getData(), getSceneManager(),
iter->getId ("std::default"))));
iter->getId (mWorldspace))));
modified = true;
}
@ -121,11 +129,19 @@ void CSVRender::PagedWorldspaceWidget::referenceAdded (const QModelIndex& parent
flagAsModified();
}
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()
{
@ -219,4 +235,27 @@ CSVRender::WorldspaceWidget::dropRequirments CSVRender::PagedWorldspaceWidget::g
default:
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;
CSMWorld::CellSelection mSelection;
std::map<CSMWorld::CellCoordinates, Cell *> mCells;
std::string mWorldspace;
private:
@ -60,6 +61,15 @@ namespace CSVRender
signals:
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_Birthsigns,
CSMWorld::UniversalId::Type_Spells,
CSMWorld::UniversalId::Type_Enchantments,
CSMWorld::UniversalId::Type_BodyParts,
CSMWorld::UniversalId::Type_None // end marker
};
@ -68,6 +70,21 @@ void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager)
manager.add (CSMWorld::UniversalId::Type_JournalInfos,
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
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_Sound,
CSMWorld::UniversalId::Type_Faction,
CSMWorld::UniversalId::Type_Enchantment,
CSMWorld::UniversalId::Type_BodyPart,
CSMWorld::UniversalId::Type_None // end marker
};

View file

@ -14,6 +14,7 @@
#include "../../model/world/data.hpp"
#include "../../model/world/commands.hpp"
#include "../../model/world/idtableproxymodel.hpp"
#include "../../model/world/idtablebase.hpp"
#include "../../model/world/idtable.hpp"
#include "../../model/world/record.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
if (!mEditLock)
if (!mEditLock && !(mModel->getFeatures() & CSMWorld::IdTableBase::Feature_Constant))
{
if (selectedRows.size()==1)
{
@ -82,7 +83,7 @@ void CSVWorld::Table::contextMenuEvent (QContextMenuEvent *event)
menu.addAction (mExtendedDeleteAction);
}
if (mModel->getFeatures() & CSMWorld::IdTable::Feature_ReorderWithinTopic)
if (mModel->getFeatures() & CSMWorld::IdTableBase::Feature_ReorderWithinTopic)
{
/// \todo allow reordering of multiple rows
if (selectedRows.size()==1)
@ -119,7 +120,7 @@ void CSVWorld::Table::contextMenuEvent (QContextMenuEvent *event)
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;
@ -131,7 +132,7 @@ void CSVWorld::Table::contextMenuEvent (QContextMenuEvent *event)
menu.addAction (mViewAction);
}
if (mModel->getFeatures() & CSMWorld::IdTable::Feature_Preview)
if (mModel->getFeatures() & CSMWorld::IdTableBase::Feature_Preview)
{
QModelIndex index = mModel->index (row,
mModel->findColumnIndex (CSMWorld::Columns::ColumnId_Modification));
@ -152,7 +153,7 @@ CSVWorld::Table::Table (const CSMWorld::UniversalId& id,
: mCreateAction (0), mCloneAction(0), mRecordStatusDisplay (0),
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->setSourceModel (mModel);
@ -275,7 +276,7 @@ CSMWorld::UniversalId CSVWorld::Table::getUniversalId (int row) const
void CSVWorld::Table::editRecord()
{
if (!mEditLock)
if (!mEditLock || (mModel->getFeatures() & CSMWorld::IdTableBase::Feature_Constant))
{
QModelIndexList selectedRows = selectionModel()->selectedRows();
@ -286,11 +287,11 @@ void CSVWorld::Table::editRecord()
void CSVWorld::Table::cloneRecord()
{
if (!mEditLock)
if (!mEditLock || (mModel->getFeatures() & CSMWorld::IdTableBase::Feature_Constant))
{
QModelIndexList selectedRows = selectionModel()->selectedRows();
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);
}
@ -299,7 +300,7 @@ void CSVWorld::Table::cloneRecord()
void CSVWorld::Table::moveUpRecord()
{
if (mEditLock)
if (mEditLock || (mModel->getFeatures() & CSMWorld::IdTableBase::Feature_Constant))
return;
QModelIndexList selectedRows = selectionModel()->selectedRows();
@ -324,14 +325,15 @@ void CSVWorld::Table::moveUpRecord()
for (int i=1; i<row2-row; ++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()
{
if (mEditLock)
if (mEditLock || (mModel->getFeatures() & CSMWorld::IdTableBase::Feature_Constant))
return;
QModelIndexList selectedRows = selectionModel()->selectedRows();
@ -356,7 +358,8 @@ void CSVWorld::Table::moveDownRecord()
for (int i=1; i<row2-row; ++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();
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));
int columnIndex = mModel->findColumnIndex (CSMWorld::Columns::ColumnId_Modification);
int state = mModel->data (mModel->index (index.row(), columnIndex)).toInt();
switch (state)
for (int i=0; i<rows; ++i)
{
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;
QModelIndex index = mProxyModel->mapToSource (mProxyModel->index (i, 0));
int state = mModel->data (mModel->index (index.row(), columnIndex)).toInt();
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);

View file

@ -23,7 +23,7 @@ namespace CSMWorld
class Data;
class UniversalId;
class IdTableProxyModel;
class IdTable;
class IdTableBase;
class CommandDispatcher;
}
@ -49,7 +49,7 @@ namespace CSVWorld
QAction *mExtendedDeleteAction;
QAction *mExtendedRevertAction;
CSMWorld::IdTableProxyModel *mProxyModel;
CSMWorld::IdTable *mModel;
CSMWorld::IdTableBase *mModel;
int mRecordStatusDisplay;
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);
}
if (display == CSMWorld::ColumnBase::Display_Integer)
{
case CSMWorld::ColumnBase::Display_Integer:
return new QSpinBox(parent);
}
if (display == CSMWorld::ColumnBase::Display_Var)
{
case CSMWorld::ColumnBase::Display_Var:
return new QLineEdit(parent);
}
if (display == CSMWorld::ColumnBase::Display_Float)
{
case CSMWorld::ColumnBase::Display_Float:
return new QDoubleSpinBox(parent);
}
if (display == CSMWorld::ColumnBase::Display_LongString)
{
case CSMWorld::ColumnBase::Display_LongString:
return new QTextEdit(parent);
}
if (display == CSMWorld::ColumnBase::Display_String ||
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)
{
case CSMWorld::ColumnBase::Display_Boolean:
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)
{
mEditLock = locked;

View file

@ -322,6 +322,15 @@ namespace MWGui
if (_sender == mFullscreenButton)
{
// 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;
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 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], "");
}
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], "");
}

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->setIndexBuffer(mCache.getIndexBuffer(0));
element.mChunk->setVisibilityFlags(mVisibilityFlags);
element.mChunk->setCastShadows(true);
std::vector<Ogre::PixelBox> blendmaps;
std::vector<Terrain::LayerInfo> layerList;

View file

@ -403,5 +403,7 @@ op 0x200024a: OnMurder, explicit
op 0x200024b: ToggleMenus
op 0x200024c: Face
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/compiler/locals.hpp>
#include <components/compiler/exception.hpp>
#include "../mwbase/environment.hpp"
#include "../mwbase/scriptmanager.hpp"
@ -75,65 +76,77 @@ namespace MWScript
void Locals::write (ESM::Locals& locals, const std::string& script) const
{
const Compiler::Locals& declarations =
MWBase::Environment::get().getScriptManager()->getLocals(script);
for (int i=0; i<3; ++i)
try
{
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;
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;
char type = 0;
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;
case 0: type = 's'; break;
case 1: type = 'l'; 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)
{
const Compiler::Locals& declarations =
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)
try
{
char type = declarations.getType (iter->first);
char index = declarations.getIndex (iter->first);
const Compiler::Locals& declarations =
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)
{
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;
char type = declarations.getType (iter->first);
char index = declarations.getIndex (iter->first);
// 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 (...)
{
// ignore type changes
/// \todo write to log
}
}
catch (const Compiler::SourceException&)
{
}
}
}

View file

@ -24,6 +24,7 @@
#include "../mwworld/player.hpp"
#include "../mwworld/containerstore.hpp"
#include "../mwworld/esmstore.hpp"
#include "../mwworld/cellstore.hpp"
#include "../mwmechanics/npcstats.hpp"
#include "../mwmechanics/creaturestats.hpp"
@ -886,7 +887,8 @@ namespace MWScript
{
MWWorld::CellStore* cell = ptr.getCell();
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);
msg << "Coordinates: " << pos << std::endl;
}

View file

@ -260,7 +260,7 @@ namespace MWScript
MWMechanics::DynamicStat<float> stat (ptr.getClass().getCreatureStats (ptr)
.getDynamic (mIndex));
stat.setCurrent (diff + current);
stat.setCurrent (diff + current, true);
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)
{
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::opcodeSetWerewolfAcrobatics, new OpSetWerewolfAcrobatics<ImplicitRef>);
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.
cell->mMovedRefs.push_back(cMRef);
// But there may be duplicates here!
ESM::CellRefTracker::iterator iter = std::find(cellAlt->mLeasedRefs.begin(), cellAlt->mLeasedRefs.end(), ref.mRefNum);
if (iter == cellAlt->mLeasedRefs.end())
cellAlt->mLeasedRefs.push_back(ref);
else
*iter = ref;
if (!deleted)
{
ESM::CellRefTracker::iterator iter = std::find(cellAlt->mLeasedRefs.begin(), cellAlt->mLeasedRefs.end(), ref.mRefNum);
if (iter == cellAlt->mLeasedRefs.end())
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);
*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

View file

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

View file

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

View file

@ -22,4 +22,14 @@ void BodyPart::save(ESMWriter &esm) const
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 save(ESMWriter &esm) const;
void blank();
///< Set record to default state (does not touch the ID).
};
}
#endif

View file

@ -20,4 +20,13 @@ void Enchantment::save(ESMWriter &esm) const
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 save(ESMWriter &esm) const;
void blank();
///< Set record to default state (does not touch the ID).
};
}
#endif

View file

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