From 518cb0e3b7a181462bb7044ae966a9bcf18659c1 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 16 Apr 2013 12:12:04 +0200 Subject: [PATCH 01/44] added another abstraction layer to ID access in IdCollection --- apps/opencs/model/world/idcollection.hpp | 123 +++++++++++++---------- 1 file changed, 72 insertions(+), 51 deletions(-) diff --git a/apps/opencs/model/world/idcollection.hpp b/apps/opencs/model/world/idcollection.hpp index 4afe9cbaa..7052b300e 100644 --- a/apps/opencs/model/world/idcollection.hpp +++ b/apps/opencs/model/world/idcollection.hpp @@ -79,8 +79,29 @@ namespace CSMWorld virtual void load (ESM::ESMReader& reader, bool base) = 0; }; - ///< \brief Collection of ID-based records + ///< \brief Access to ID field in records template + struct IdAccessor + { + std::string& getId (ESXRecordT& record); + + const std::string getId (const ESXRecordT& record) const; + }; + + template + std::string& IdAccessor::getId (ESXRecordT& record) + { + return record.mId; + } + + template + const std::string IdAccessor::getId (const ESXRecordT& record) const + { + return record.mId; + } + + ///< \brief Collection of ID-based records + template > class IdCollection : public IdCollectionBase { std::vector > mRecords; @@ -150,21 +171,21 @@ namespace CSMWorld void addColumn (Column *column); }; - template - IdCollection::IdCollection() + template + IdCollection::IdCollection() {} - template - IdCollection::~IdCollection() + template + IdCollection::~IdCollection() { for (typename std::vector *>::iterator iter (mColumns.begin()); iter!=mColumns.end(); ++iter) delete *iter; } - template - void IdCollection::add (const ESXRecordT& record) + template + void IdCollection::add (const ESXRecordT& record) { - std::string id = Misc::StringUtils::lowerCase(record.mId); + std::string id = Misc::StringUtils::lowerCase (IdAccessorT().getId (record)); std::map::iterator iter = mIndex.find (id); @@ -183,20 +204,20 @@ namespace CSMWorld } } - template - int IdCollection::getSize() const + template + int IdCollection::getSize() const { return mRecords.size(); } - template - std::string IdCollection::getId (int index) const + template + std::string IdCollection::getId (int index) const { - return mRecords.at (index).get().mId; + return IdAccessorT().getId (mRecords.at (index).get()); } - template - int IdCollection::getIndex (const std::string& id) const + template + int IdCollection::getIndex (const std::string& id) const { int index = searchId (id); @@ -206,38 +227,38 @@ namespace CSMWorld return index; } - template - int IdCollection::getColumns() const + template + int IdCollection::getColumns() const { return mColumns.size(); } - template - QVariant IdCollection::getData (int index, int column) const + template + QVariant IdCollection::getData (int index, int column) const { return mColumns.at (column)->get (mRecords.at (index)); } - template - void IdCollection::setData (int index, int column, const QVariant& data) + template + void IdCollection::setData (int index, int column, const QVariant& data) { return mColumns.at (column)->set (mRecords.at (index), data); } - template - const ColumnBase& IdCollection::getColumn (int column) const + template + const ColumnBase& IdCollection::getColumn (int column) const { return *mColumns.at (column); } - template - void IdCollection::addColumn (Column *column) + template + void IdCollection::addColumn (Column *column) { mColumns.push_back (column); } - template - void IdCollection::merge() + template + void IdCollection::merge() { for (typename std::vector >::iterator iter (mRecords.begin()); iter!=mRecords.end(); ++iter) iter->merge(); @@ -245,16 +266,16 @@ namespace CSMWorld purge(); } - template - void IdCollection::purge() + template + void IdCollection::purge() { mRecords.erase (std::remove_if (mRecords.begin(), mRecords.end(), std::mem_fun_ref (&Record::isErased) // I want lambda :( ), mRecords.end()); } - template - void IdCollection::removeRows (int index, int count) + template + void IdCollection::removeRows (int index, int count) { mRecords.erase (mRecords.begin()+index, mRecords.begin()+index+count); @@ -278,17 +299,17 @@ namespace CSMWorld } } - template - void IdCollection::appendBlankRecord (const std::string& id) + template + void IdCollection::appendBlankRecord (const std::string& id) { ESXRecordT record; - record.mId = id; + IdAccessorT().getId (record) = id; record.blank(); add (record); } - template - int IdCollection::searchId (const std::string& id) const + template + int IdCollection::searchId (const std::string& id) const { std::string id2 = Misc::StringUtils::lowerCase(id); @@ -300,28 +321,28 @@ namespace CSMWorld return iter->second; } - template - void IdCollection::replace (int index, const RecordBase& record) + template + void IdCollection::replace (int index, const RecordBase& record) { mRecords.at (index) = dynamic_cast&> (record); } - template - void IdCollection::appendRecord (const RecordBase& record) + template + void IdCollection::appendRecord (const RecordBase& record) { mRecords.push_back (dynamic_cast&> (record)); mIndex.insert (std::make_pair (Misc::StringUtils::lowerCase (getId (record)), mRecords.size()-1)); } - template - std::string IdCollection::getId (const RecordBase& record) const + template + std::string IdCollection::getId (const RecordBase& record) const { const Record& record2 = dynamic_cast&> (record); - return (record2.isModified() ? record2.mModified : record2.mBase).mId; + return IdAccessorT().getId (record2.isModified() ? record2.mModified : record2.mBase); } - template - void IdCollection::load (ESM::ESMReader& reader, bool base) + template + void IdCollection::load (ESM::ESMReader& reader, bool base) { std::string id = reader.getHNOString ("NAME"); @@ -351,10 +372,10 @@ namespace CSMWorld else { ESXRecordT record; - record.mId = id; + IdAccessorT().getId (record) = id; record.load (reader); - int index = searchId (record.mId); + int index = searchId (IdAccessorT().getId (record)); if (index==-1) { @@ -378,15 +399,15 @@ namespace CSMWorld } } - template - const Record& IdCollection::getRecord (const std::string& id) const + template + const Record& IdCollection::getRecord (const std::string& id) const { int index = getIndex (id); return mRecords.at (index); } - template - const Record& IdCollection::getRecord (int index) const + template + const Record& IdCollection::getRecord (int index) const { return mRecords.at (index); } From afe7b3c64c4adafd112b4d151d8866ffefb4a725 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 23 Apr 2013 10:56:55 +0200 Subject: [PATCH 02/44] added additional type argument to IdCollection::appendBlankRecord --- apps/opencs/model/world/idcollection.hpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/apps/opencs/model/world/idcollection.hpp b/apps/opencs/model/world/idcollection.hpp index 7052b300e..45b4961aa 100644 --- a/apps/opencs/model/world/idcollection.hpp +++ b/apps/opencs/model/world/idcollection.hpp @@ -16,6 +16,7 @@ #include #include "columnbase.hpp" +#include "universalid.hpp" namespace CSMWorld { @@ -53,7 +54,9 @@ namespace CSMWorld virtual void removeRows (int index, int count) = 0; - virtual void appendBlankRecord (const std::string& id) = 0; + virtual void appendBlankRecord (const std::string& id, + UniversalId::Type type = UniversalId::Type_None) = 0; + ///< \param type Will be ignored, unless the collection supports multiple record types virtual int searchId (const std::string& id) const = 0; ////< Search record with \a id. @@ -143,7 +146,9 @@ namespace CSMWorld virtual void removeRows (int index, int count) ; - virtual void appendBlankRecord (const std::string& id); + virtual void appendBlankRecord (const std::string& id, + UniversalId::Type type = UniversalId::Type_None); + ///< \param type Will be ignored, unless the collection supports multiple record types virtual int searchId (const std::string& id) const; ////< Search record with \a id. @@ -300,7 +305,8 @@ namespace CSMWorld } template - void IdCollection::appendBlankRecord (const std::string& id) + void IdCollection::appendBlankRecord (const std::string& id, + UniversalId::Type type) { ESXRecordT record; IdAccessorT().getId (record) = id; From 808718d96708d9833e7a8fe959de1e8823802039 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 23 Apr 2013 11:21:21 +0200 Subject: [PATCH 03/44] added referenceable record types to UniversalId --- apps/opencs/model/world/universalid.cpp | 26 +++++++++++++++++++++++++ apps/opencs/model/world/universalid.hpp | 25 +++++++++++++++++++++++- 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/apps/opencs/model/world/universalid.cpp b/apps/opencs/model/world/universalid.cpp index c0241bc38..bd1632e3e 100644 --- a/apps/opencs/model/world/universalid.cpp +++ b/apps/opencs/model/world/universalid.cpp @@ -29,6 +29,8 @@ namespace { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Birthsigns, "Birthsigns" }, { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Spells, "Spells" }, { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Cells, "Cells" }, + { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Referenceables, + "Referenceables" }, { CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, 0 } // end marker }; @@ -47,6 +49,30 @@ namespace { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Birthsign, "Birthsign" }, { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Spell, "Spell" }, { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Cell, "Cell" }, + { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Referenceable, "Referenceables" }, + { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Activator, "Activator" }, + { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Potion, "Potion" }, + { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Apparatus, "Apparatus" }, + { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Armor, "Armor" }, + { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Book, "Book" }, + { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Clothing, "Clothing" }, + { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Container, "Container" }, + { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Creature, "Creature" }, + { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Door, "Door" }, + { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Ingredient, "Ingredient" }, + { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_CreatureLevelledList, + "Creature Levelled List" }, + { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_ItemLevelledList, + "Item Levelled List" }, + { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Light, "Light" }, + { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Lockpick, "Lockpick" }, + { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Miscellaneous, + "Miscellaneous" }, + { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Npc, "NPC" }, + { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Probe, "Probe" }, + { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Repair, "Repair" }, + { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Static, "Static" }, + { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Weapon, "Weapon" }, { CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, 0 } // end marker }; diff --git a/apps/opencs/model/world/universalid.hpp b/apps/opencs/model/world/universalid.hpp index 9b52aded1..2c4b14eaf 100644 --- a/apps/opencs/model/world/universalid.hpp +++ b/apps/opencs/model/world/universalid.hpp @@ -57,7 +57,30 @@ namespace CSMWorld Type_Spells, Type_Spell, Type_Cells, - Type_Cell + Type_Cell, + Type_Referenceables, + Type_Referenceable, + Type_Activator, + Type_Potion, + Type_Apparatus, + Type_Armor, + Type_Book, + Type_Clothing, + Type_Container, + Type_Creature, + Type_Door, + Type_Ingredient, + Type_CreatureLevelledList, + Type_ItemLevelledList, + Type_Light, + Type_Lockpick, + Type_Miscellaneous, + Type_Npc, + Type_Probe, + Type_Repair, + Type_Static, + Type_Weapon + }; private: From a17d17c19105557c88ff2cdcaca19df103f6fba6 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 23 Apr 2013 11:22:07 +0200 Subject: [PATCH 04/44] added additional type argument to IdCollection::load --- apps/opencs/model/world/idcollection.hpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/apps/opencs/model/world/idcollection.hpp b/apps/opencs/model/world/idcollection.hpp index 45b4961aa..7761929f3 100644 --- a/apps/opencs/model/world/idcollection.hpp +++ b/apps/opencs/model/world/idcollection.hpp @@ -79,7 +79,9 @@ namespace CSMWorld virtual const RecordBase& getRecord (int index) const = 0; - virtual void load (ESM::ESMReader& reader, bool base) = 0; + virtual void load (ESM::ESMReader& reader, bool base, + UniversalId::Type type = UniversalId::Type_None) = 0; + ///< \param type Will be ignored, unless the collection supports multiple record types }; ///< \brief Access to ID field in records @@ -171,7 +173,9 @@ namespace CSMWorld virtual const Record& getRecord (int index) const; - virtual void load (ESM::ESMReader& reader, bool base); + virtual void load (ESM::ESMReader& reader, bool base, + UniversalId::Type type = UniversalId::Type_None); + ///< \param type Will be ignored, unless the collection supports multiple record types void addColumn (Column *column); }; @@ -348,7 +352,8 @@ namespace CSMWorld } template - void IdCollection::load (ESM::ESMReader& reader, bool base) + void IdCollection::load (ESM::ESMReader& reader, bool base, + UniversalId::Type type) { std::string id = reader.getHNOString ("NAME"); From e7bf1d230ccf6ec08e01b5ef813d0b98adbc2dc9 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 27 Apr 2013 16:22:04 +0200 Subject: [PATCH 05/44] fixed an indexing problem in IdCollection --- apps/opencs/model/world/idcollection.hpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/apps/opencs/model/world/idcollection.hpp b/apps/opencs/model/world/idcollection.hpp index 7761929f3..e65f11cef 100644 --- a/apps/opencs/model/world/idcollection.hpp +++ b/apps/opencs/model/world/idcollection.hpp @@ -278,9 +278,15 @@ namespace CSMWorld template void IdCollection::purge() { - mRecords.erase (std::remove_if (mRecords.begin(), mRecords.end(), - std::mem_fun_ref (&Record::isErased) // I want lambda :( - ), mRecords.end()); + int i = 0; + + while (i (mRecords.size())) + { + if (mRecords[i].isErased()) + removeRows (i, 1); + else + ++i; + } } template From 236751ec451495f2b1161ef0d5324f15a6a3e39c Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 29 Apr 2013 17:52:01 +0200 Subject: [PATCH 06/44] some IdCollection and IdTable cleanup --- apps/opencs/model/world/commands.cpp | 4 +-- apps/opencs/model/world/idcollection.hpp | 44 +++++++++++++----------- apps/opencs/model/world/idtable.cpp | 8 ++--- apps/opencs/model/world/idtable.hpp | 2 +- 4 files changed, 30 insertions(+), 28 deletions(-) diff --git a/apps/opencs/model/world/commands.cpp b/apps/opencs/model/world/commands.cpp index 1f8660bdd..eaded5b70 100644 --- a/apps/opencs/model/world/commands.cpp +++ b/apps/opencs/model/world/commands.cpp @@ -71,7 +71,7 @@ void CSMWorld::RevertCommand::redo() void CSMWorld::RevertCommand::undo() { - mModel.setRecord (*mOld); + mModel.setRecord (mId, *mOld); } CSMWorld::DeleteCommand::DeleteCommand (IdTable& model, const std::string& id, QUndoCommand *parent) @@ -104,5 +104,5 @@ void CSMWorld::DeleteCommand::redo() void CSMWorld::DeleteCommand::undo() { - mModel.setRecord (*mOld); + mModel.setRecord (mId, *mOld); } \ No newline at end of file diff --git a/apps/opencs/model/world/idcollection.hpp b/apps/opencs/model/world/idcollection.hpp index e65f11cef..9ace34a09 100644 --- a/apps/opencs/model/world/idcollection.hpp +++ b/apps/opencs/model/world/idcollection.hpp @@ -66,15 +66,12 @@ namespace CSMWorld ///< If the record type does not match, an exception is thrown. /// /// \attention \a record must not change the ID. + ///< \param type Will be ignored, unless the collection supports multiple record types - virtual void appendRecord (const RecordBase& record) = 0; + virtual void appendRecord (const RecordBase& record, + UniversalId::Type type = UniversalId::Type_None) = 0; ///< If the record type does not match, an exception is thrown. - virtual std::string getId (const RecordBase& record) const = 0; - ///< Return ID for \a record. - /// - /// \attention Throws an exception, if the type of \a record does not match. - virtual const RecordBase& getRecord (const std::string& id) const = 0; virtual const RecordBase& getRecord (int index) const = 0; @@ -82,6 +79,9 @@ namespace CSMWorld virtual void load (ESM::ESMReader& reader, bool base, UniversalId::Type type = UniversalId::Type_None) = 0; ///< \param type Will be ignored, unless the collection supports multiple record types + + virtual int getAppendIndex (UniversalId::Type type = UniversalId::Type_None) const = 0; + ///< \param type Will be ignored, unless the collection supports multiple record types }; ///< \brief Access to ID field in records @@ -161,13 +161,10 @@ namespace CSMWorld /// /// \attention \a record must not change the ID. - virtual void appendRecord (const RecordBase& record); + virtual void appendRecord (const RecordBase& record, + UniversalId::Type type = UniversalId::Type_None); ///< If the record type does not match, an exception is thrown. - - virtual std::string getId (const RecordBase& record) const; - ///< Return ID for \a record. - /// - /// \attention Throw san exception, if the type of \a record does not match. + ///< \param type Will be ignored, unless the collection supports multiple record types virtual const Record& getRecord (const std::string& id) const; @@ -177,6 +174,9 @@ namespace CSMWorld UniversalId::Type type = UniversalId::Type_None); ///< \param type Will be ignored, unless the collection supports multiple record types + virtual int getAppendIndex (UniversalId::Type type = UniversalId::Type_None) const; + ///< \param type Will be ignored, unless the collection supports multiple record types + void addColumn (Column *column); }; @@ -344,17 +344,13 @@ namespace CSMWorld } template - void IdCollection::appendRecord (const RecordBase& record) + void IdCollection::appendRecord (const RecordBase& record, + UniversalId::Type type) { mRecords.push_back (dynamic_cast&> (record)); - mIndex.insert (std::make_pair (Misc::StringUtils::lowerCase (getId (record)), mRecords.size()-1)); - } - - template - std::string IdCollection::getId (const RecordBase& record) const - { - const Record& record2 = dynamic_cast&> (record); - return IdAccessorT().getId (record2.isModified() ? record2.mModified : record2.mBase); + mIndex.insert (std::make_pair (Misc::StringUtils::lowerCase (IdAccessorT().getId ( + dynamic_cast (record))), + mRecords.size()-1)); } template @@ -416,6 +412,12 @@ namespace CSMWorld } } + template + int IdCollection::getAppendIndex (UniversalId::Type type) const + { + return static_cast (mRecords.size()); + } + template const Record& IdCollection::getRecord (const std::string& id) const { diff --git a/apps/opencs/model/world/idtable.cpp b/apps/opencs/model/world/idtable.cpp index 79e33584b..386ca8702 100644 --- a/apps/opencs/model/world/idtable.cpp +++ b/apps/opencs/model/world/idtable.cpp @@ -117,7 +117,7 @@ QModelIndex CSMWorld::IdTable::parent (const QModelIndex& index) const void CSMWorld::IdTable::addRecord (const std::string& id) { - int index = mIdCollection->getSize(); + int index = mIdCollection->getAppendIndex(); beginInsertRows (QModelIndex(), index, index); @@ -131,13 +131,13 @@ QModelIndex CSMWorld::IdTable::getModelIndex (const std::string& id, int column) return index (mIdCollection->getIndex (id), column); } -void CSMWorld::IdTable::setRecord (const RecordBase& record) +void CSMWorld::IdTable::setRecord (const std::string& id, const RecordBase& record) { - int index = mIdCollection->searchId (mIdCollection->getId (record)); + int index = mIdCollection->searchId (id); if (index==-1) { - int index = mIdCollection->getSize(); + int index = mIdCollection->getAppendIndex(); beginInsertRows (QModelIndex(), index, index); diff --git a/apps/opencs/model/world/idtable.hpp b/apps/opencs/model/world/idtable.hpp index 80476c524..de0dde56e 100644 --- a/apps/opencs/model/world/idtable.hpp +++ b/apps/opencs/model/world/idtable.hpp @@ -48,7 +48,7 @@ namespace CSMWorld QModelIndex getModelIndex (const std::string& id, int column) const; - void setRecord (const RecordBase& record); + void setRecord (const std::string& id, const RecordBase& record); ///< Add record or overwrite existing recrod. const RecordBase& getRecord (const std::string& id) const; From f8a331f1738a58667db2af0f81dd0a6c3ed0d30f Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Wed, 1 May 2013 16:49:34 +0200 Subject: [PATCH 07/44] fixed a bad cast --- apps/opencs/model/world/idcollection.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/opencs/model/world/idcollection.hpp b/apps/opencs/model/world/idcollection.hpp index 9ace34a09..93390c97b 100644 --- a/apps/opencs/model/world/idcollection.hpp +++ b/apps/opencs/model/world/idcollection.hpp @@ -349,7 +349,7 @@ namespace CSMWorld { mRecords.push_back (dynamic_cast&> (record)); mIndex.insert (std::make_pair (Misc::StringUtils::lowerCase (IdAccessorT().getId ( - dynamic_cast (record))), + dynamic_cast&> (record).get())), mRecords.size()-1)); } From 1b84aeb5b9e67493a3fe0f0984695ba6ccbbeb20 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 2 May 2013 14:30:39 +0200 Subject: [PATCH 08/44] fixed a problem with editing records that do not exist in base --- apps/opencs/model/world/record.hpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/opencs/model/world/record.hpp b/apps/opencs/model/world/record.hpp index c8f728e7d..4d95b5c91 100644 --- a/apps/opencs/model/world/record.hpp +++ b/apps/opencs/model/world/record.hpp @@ -81,7 +81,9 @@ namespace CSMWorld throw std::logic_error ("attempt to modify a deleted record"); mModified = modified; - mState = State_Modified; + + if (mState!=State_ModifiedOnly) + mState = State_Modified; } template From 13e7abd7df0a3e54349a4c8d7e9b4fa2bc447bc3 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 3 May 2013 12:52:45 +0200 Subject: [PATCH 09/44] added assign function to Record class --- apps/opencs/model/world/record.hpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/apps/opencs/model/world/record.hpp b/apps/opencs/model/world/record.hpp index 4d95b5c91..853ed1559 100644 --- a/apps/opencs/model/world/record.hpp +++ b/apps/opencs/model/world/record.hpp @@ -22,6 +22,9 @@ namespace CSMWorld virtual RecordBase *clone() const = 0; + virtual void assign (const RecordBase& record) = 0; + ///< Will throw an exception if the types don't match. + bool isDeleted() const; bool isErased() const; @@ -37,6 +40,8 @@ namespace CSMWorld virtual RecordBase *clone() const; + virtual void assign (const RecordBase& record); + const ESXRecordT& get() const; ///< Throws an exception, if the record is deleted. @@ -56,6 +61,12 @@ namespace CSMWorld return new Record (*this); } + template + void Record::assign (const RecordBase& record) + { + *this = dynamic_cast& > (record); + } + template const ESXRecordT& Record::get() const { From b21dae8d75d7d5f6d625455401d786b102b4dd28 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 6 May 2013 14:10:43 +0200 Subject: [PATCH 10/44] added blank function to all referencable record structs --- components/esm/aipackage.cpp | 6 ++++ components/esm/aipackage.hpp | 3 ++ components/esm/loadacti.cpp | 7 +++++ components/esm/loadacti.hpp | 3 ++ components/esm/loadalch.cpp | 12 ++++++++ components/esm/loadalch.hpp | 4 +++ components/esm/loadappa.cpp | 12 ++++++++ components/esm/loadappa.hpp | 3 ++ components/esm/loadarmo.cpp | 15 ++++++++++ components/esm/loadarmo.hpp | 3 ++ components/esm/loadbook.cpp | 14 +++++++++ components/esm/loadbook.hpp | 3 ++ components/esm/loadclot.cpp | 20 +++++++++++-- components/esm/loadclot.hpp | 3 ++ components/esm/loadcont.cpp | 9 ++++++ components/esm/loadcont.hpp | 3 ++ components/esm/loadcrea.cpp | 24 +++++++++++++++ components/esm/loadcrea.hpp | 3 ++ components/esm/loaddoor.cpp | 8 +++++ components/esm/loaddoor.hpp | 3 ++ components/esm/loadingr.cpp | 18 ++++++++++- components/esm/loadingr.hpp | 3 ++ components/esm/loadlevlist.cpp | 8 ++++- components/esm/loadlevlist.hpp | 5 +++- components/esm/loadligh.cpp | 14 +++++++++ components/esm/loadligh.hpp | 3 ++ components/esm/loadlock.cpp | 14 +++++++-- components/esm/loadlock.hpp | 3 ++ components/esm/loadmisc.cpp | 10 +++++++ components/esm/loadmisc.hpp | 3 ++ components/esm/loadnpc.cpp | 55 ++++++++++++++++++++++++++++++++-- components/esm/loadnpc.hpp | 15 ++++------ components/esm/loadprob.cpp | 13 +++++++- components/esm/loadprob.hpp | 3 ++ components/esm/loadrepa.cpp | 12 +++++++- components/esm/loadrepa.hpp | 3 ++ components/esm/loadstat.cpp | 4 +++ components/esm/loadstat.hpp | 3 ++ components/esm/loadweap.cpp | 20 +++++++++++++ components/esm/loadweap.hpp | 3 ++ 40 files changed, 347 insertions(+), 23 deletions(-) diff --git a/components/esm/aipackage.cpp b/components/esm/aipackage.cpp index 1e6220c3a..1440dbd13 100644 --- a/components/esm/aipackage.cpp +++ b/components/esm/aipackage.cpp @@ -5,6 +5,12 @@ namespace ESM { + void AIData::blank() + { + mHello = mU1 = mFight = mFlee = mAlarm = mU2 = mU3 = mU4 = 0; + mServices = 0; + } + void AIPackageList::load(ESMReader &esm) { while (esm.hasMoreSubs()) { diff --git a/components/esm/aipackage.hpp b/components/esm/aipackage.hpp index 3128fe0c6..38499b2dd 100644 --- a/components/esm/aipackage.hpp +++ b/components/esm/aipackage.hpp @@ -19,6 +19,9 @@ namespace ESM // These are probabilities char mHello, mU1, mFight, mFlee, mAlarm, mU2, mU3, mU4; int mServices; // See the Services enum + + void blank(); + ///< Set record to default state (does not touch the ID). }; // 12 bytes struct AIWander diff --git a/components/esm/loadacti.cpp b/components/esm/loadacti.cpp index 0e214e2b6..fd022af7e 100644 --- a/components/esm/loadacti.cpp +++ b/components/esm/loadacti.cpp @@ -17,4 +17,11 @@ void Activator::save(ESMWriter &esm) esm.writeHNCString("FNAM", mName); esm.writeHNOCString("SCRI", mScript); } + + void Activator::blank() + { + mName.clear(); + mScript.clear(); + mModel.clear(); + } } diff --git a/components/esm/loadacti.hpp b/components/esm/loadacti.hpp index 8cb335feb..a62990590 100644 --- a/components/esm/loadacti.hpp +++ b/components/esm/loadacti.hpp @@ -15,6 +15,9 @@ struct Activator void load(ESMReader &esm); void save(ESMWriter &esm); + + void blank(); + ///< Set record to default state (does not touch the ID). }; } diff --git a/components/esm/loadalch.cpp b/components/esm/loadalch.cpp index a4b1bb718..dbb69c066 100644 --- a/components/esm/loadalch.cpp +++ b/components/esm/loadalch.cpp @@ -23,4 +23,16 @@ void Potion::save(ESMWriter &esm) esm.writeHNT("ALDT", mData, 12); mEffects.save(esm); } + + void Potion::blank() + { + mData.mWeight = 0; + mData.mValue = 0; + mData.mAutoCalc = 0; + mName.clear(); + mModel.clear(); + mIcon.clear(); + mScript.clear(); + mEffects.mList.clear(); + } } diff --git a/components/esm/loadalch.hpp b/components/esm/loadalch.hpp index 1e571ac40..3ede85342 100644 --- a/components/esm/loadalch.hpp +++ b/components/esm/loadalch.hpp @@ -30,6 +30,10 @@ struct Potion void load(ESMReader &esm); void save(ESMWriter &esm); + + void blank(); + ///< Set record to default state (does not touch the ID). + }; } #endif diff --git a/components/esm/loadappa.cpp b/components/esm/loadappa.cpp index 643fefda5..4b8d2b763 100644 --- a/components/esm/loadappa.cpp +++ b/components/esm/loadappa.cpp @@ -36,4 +36,16 @@ void Apparatus::save(ESMWriter &esm) esm.writeHNOCString("SCRI", mScript); esm.writeHNCString("ITEX", mIcon); } + + void Apparatus::blank() + { + mData.mType = 0; + mData.mQuality = 0; + mData.mWeight = 0; + mData.mValue = 0; + mModel.clear(); + mIcon.clear(); + mScript.clear(); + mName.clear(); + } } diff --git a/components/esm/loadappa.hpp b/components/esm/loadappa.hpp index 486a559f8..ed9d335be 100644 --- a/components/esm/loadappa.hpp +++ b/components/esm/loadappa.hpp @@ -36,6 +36,9 @@ struct Apparatus void load(ESMReader &esm); void save(ESMWriter &esm); + + void blank(); + ///< Set record to default state (does not touch the ID). }; } #endif diff --git a/components/esm/loadarmo.cpp b/components/esm/loadarmo.cpp index 613346533..e64c8705d 100644 --- a/components/esm/loadarmo.cpp +++ b/components/esm/loadarmo.cpp @@ -50,4 +50,19 @@ void Armor::save(ESMWriter &esm) esm.writeHNOCString("ENAM", mEnchant); } + void Armor::blank() + { + mData.mType = 0; + mData.mWeight = 0; + mData.mValue = 0; + mData.mHealth = 0; + mData.mEnchant = 0; + mData.mArmor = 0; + mParts.mParts.clear(); + mName.clear(); + mModel.clear(); + mIcon.clear(); + mScript.clear(); + mEnchant.clear(); + } } diff --git a/components/esm/loadarmo.hpp b/components/esm/loadarmo.hpp index c18b4486d..eaef42be8 100644 --- a/components/esm/loadarmo.hpp +++ b/components/esm/loadarmo.hpp @@ -90,6 +90,9 @@ struct Armor void load(ESMReader &esm); void save(ESMWriter &esm); + + void blank(); + ///< Set record to default state (does not touch the ID). }; } #endif diff --git a/components/esm/loadbook.cpp b/components/esm/loadbook.cpp index 8ed2f122a..3a70ac786 100644 --- a/components/esm/loadbook.cpp +++ b/components/esm/loadbook.cpp @@ -27,4 +27,18 @@ void Book::save(ESMWriter &esm) esm.writeHNOCString("ENAM", mEnchant); } + void Book::blank() + { + mData.mWeight = 0; + mData.mValue = 0; + mData.mIsScroll = 0; + mData.mSkillID = 0; + mData.mEnchant = 0; + mName.clear(); + mModel.clear(); + mIcon.clear(); + mScript.clear(); + mEnchant.clear(); + mText.clear(); + } } diff --git a/components/esm/loadbook.hpp b/components/esm/loadbook.hpp index 22201abed..68042e246 100644 --- a/components/esm/loadbook.hpp +++ b/components/esm/loadbook.hpp @@ -26,6 +26,9 @@ struct Book void load(ESMReader &esm); void save(ESMWriter &esm); + + void blank(); + ///< Set record to default state (does not touch the ID). }; } #endif diff --git a/components/esm/loadclot.cpp b/components/esm/loadclot.cpp index a37fbe8a4..10b00970f 100644 --- a/components/esm/loadclot.cpp +++ b/components/esm/loadclot.cpp @@ -16,7 +16,7 @@ void Clothing::load(ESMReader &esm) mIcon = esm.getHNOString("ITEX"); mParts.load(esm); - + mEnchant = esm.getHNOString("ENAM"); } @@ -28,10 +28,24 @@ void Clothing::save(ESMWriter &esm) esm.writeHNOCString("SCRI", mScript); esm.writeHNOCString("ITEX", mIcon); - + mParts.save(esm); - + esm.writeHNOCString("ENAM", mEnchant); } + void Clothing::blank() + { + mData.mType = 0; + mData.mWeight = 0; + mData.mValue = 0; + mData.mEnchant = 0; + mParts.mParts.clear(); + mName.clear(); + mModel.clear(); + mIcon.clear(); + mIcon.clear(); + mEnchant.clear(); + mScript.clear(); + } } diff --git a/components/esm/loadclot.hpp b/components/esm/loadclot.hpp index 623983ccf..816d03cb2 100644 --- a/components/esm/loadclot.hpp +++ b/components/esm/loadclot.hpp @@ -46,6 +46,9 @@ struct Clothing void load(ESMReader &esm); void save(ESMWriter &esm); + + void blank(); + ///< Set record to default state (does not touch the ID). }; } #endif diff --git a/components/esm/loadcont.cpp b/components/esm/loadcont.cpp index e6ba91e7c..853c8bd50 100644 --- a/components/esm/loadcont.cpp +++ b/components/esm/loadcont.cpp @@ -53,4 +53,13 @@ void Container::save(ESMWriter &esm) mInventory.save(esm); } + void Container::blank() + { + mName.clear(); + mModel.clear(); + mScript.clear(); + mWeight = 0; + mFlags = 0; + mInventory.mList.clear(); + } } diff --git a/components/esm/loadcont.hpp b/components/esm/loadcont.hpp index b66ca086d..b2bbab73d 100644 --- a/components/esm/loadcont.hpp +++ b/components/esm/loadcont.hpp @@ -47,6 +47,9 @@ struct Container void load(ESMReader &esm); void save(ESMWriter &esm); + + void blank(); + ///< Set record to default state (does not touch the ID). }; } #endif diff --git a/components/esm/loadcrea.cpp b/components/esm/loadcrea.cpp index b59835bd6..3698d4117 100644 --- a/components/esm/loadcrea.cpp +++ b/components/esm/loadcrea.cpp @@ -53,4 +53,28 @@ void Creature::save(ESMWriter &esm) mAiPackage.save(esm); } + void Creature::blank() + { + mData.mType = 0; + mData.mLevel = 0; + mData.mStrength = mData.mIntelligence = mData.mWillpower = mData.mAgility = + mData.mSpeed = mData.mEndurance = mData.mPersonality = mData.mLuck = 0; + mData.mHealth = mData.mMana = mData.mFatigue = 0; + mData.mSoul = 0; + mData.mCombat = mData.mMagic = mData.mStealth = 0; + for (int i=0; i<6; ++i) mData.mAttack[i] = 0; + mData.mGold = 0; + mFlags = 0; + mScale = 0; + mModel.clear(); + mName.clear(); + mScript.clear(); + mOriginal.clear(); + mInventory.mList.clear(); + mSpells.mList.clear(); + mHasAI = false; + mAiData.blank(); + mAiData.mServices = 0; + mAiPackage.mList.clear(); + } } diff --git a/components/esm/loadcrea.hpp b/components/esm/loadcrea.hpp index 1c93d995a..a97f2e0a6 100644 --- a/components/esm/loadcrea.hpp +++ b/components/esm/loadcrea.hpp @@ -84,6 +84,9 @@ struct Creature void load(ESMReader &esm); void save(ESMWriter &esm); + + void blank(); + ///< Set record to default state (does not touch the ID). }; } diff --git a/components/esm/loaddoor.cpp b/components/esm/loaddoor.cpp index b8ef029c5..a4c7b7d58 100644 --- a/components/esm/loaddoor.cpp +++ b/components/esm/loaddoor.cpp @@ -24,4 +24,12 @@ void Door::save(ESMWriter &esm) esm.writeHNOCString("ANAM", mCloseSound); } + void Door::blank() + { + mName.clear(); + mModel.clear(); + mScript.clear(); + mOpenSound.clear(); + mCloseSound.clear(); + } } diff --git a/components/esm/loaddoor.hpp b/components/esm/loaddoor.hpp index e992a592f..77ffc6489 100644 --- a/components/esm/loaddoor.hpp +++ b/components/esm/loaddoor.hpp @@ -15,6 +15,9 @@ struct Door void load(ESMReader &esm); void save(ESMWriter &esm); + + void blank(); + ///< Set record to default state (does not touch the ID). }; } #endif diff --git a/components/esm/loadingr.cpp b/components/esm/loadingr.cpp index 4312dc05b..7e31a4116 100644 --- a/components/esm/loadingr.cpp +++ b/components/esm/loadingr.cpp @@ -24,7 +24,7 @@ void Ingredient::load(ESMReader &esm) { mData.mAttributes[i] = -1; } - + // is this relevant in cycle from 0 to 4? if (mData.mEffectID[i] != 89 && mData.mEffectID[i] != 26 && @@ -46,4 +46,20 @@ void Ingredient::save(ESMWriter &esm) esm.writeHNOCString("ITEX", mIcon); } + void Ingredient::blank() + { + mData.mWeight = 0; + mData.mValue = 0; + for (int i=0; i<4; ++i) + { + mData.mEffectID[i] = 0; + mData.mSkills[i] = 0; + mData.mAttributes[i] = 0; + } + + mName.clear(); + mModel.clear(); + mIcon.clear(); + mScript.clear(); + } } diff --git a/components/esm/loadingr.hpp b/components/esm/loadingr.hpp index cd63cf39a..5e286535f 100644 --- a/components/esm/loadingr.hpp +++ b/components/esm/loadingr.hpp @@ -29,6 +29,9 @@ struct Ingredient void load(ESMReader &esm); void save(ESMWriter &esm); + + void blank(); + ///< Set record to default state (does not touch the ID). }; } #endif diff --git a/components/esm/loadlevlist.cpp b/components/esm/loadlevlist.cpp index 4cba1119b..b54a91276 100644 --- a/components/esm/loadlevlist.cpp +++ b/components/esm/loadlevlist.cpp @@ -38,7 +38,7 @@ void LeveledListBase::save(ESMWriter &esm) esm.writeHNT("DATA", mFlags); esm.writeHNT("NNAM", mChanceNone); esm.writeHNT("INDX", mList.size()); - + for (std::vector::iterator it = mList.begin(); it != mList.end(); ++it) { esm.writeHNCString(mRecName, it->mId); @@ -46,4 +46,10 @@ void LeveledListBase::save(ESMWriter &esm) } } + void LeveledListBase::blank() + { + mFlags = 0; + mChanceNone = 0; + mList.clear(); + } } diff --git a/components/esm/loadlevlist.hpp b/components/esm/loadlevlist.hpp index aa9656d72..7339cac56 100644 --- a/components/esm/loadlevlist.hpp +++ b/components/esm/loadlevlist.hpp @@ -15,7 +15,7 @@ class ESMWriter; * to implement it once. * * We should later implement the ability to merge leveled lists from - * several files. + * several files. */ struct LeveledListBase @@ -52,6 +52,9 @@ struct LeveledListBase void load(ESMReader &esm); void save(ESMWriter &esm); + + void blank(); + ///< Set record to default state (does not touch the ID). }; struct CreatureLevList: LeveledListBase diff --git a/components/esm/loadligh.cpp b/components/esm/loadligh.cpp index 48a56db3c..89a2b8c65 100644 --- a/components/esm/loadligh.cpp +++ b/components/esm/loadligh.cpp @@ -26,4 +26,18 @@ void Light::save(ESMWriter &esm) esm.writeHNOCString("SNAM", mSound); } + void Light::blank() + { + mData.mWeight = 0; + mData.mValue = 0; + mData.mTime = 0; + mData.mRadius = 0; + mData.mColor = 0; + mData.mFlags = 0; + mSound.clear(); + mScript.clear(); + mModel.clear(); + mIcon.clear(); + mName.clear(); + } } diff --git a/components/esm/loadligh.hpp b/components/esm/loadligh.hpp index b3d703cc2..3f0b76d6e 100644 --- a/components/esm/loadligh.hpp +++ b/components/esm/loadligh.hpp @@ -45,6 +45,9 @@ struct Light void load(ESMReader &esm); void save(ESMWriter &esm); + + void blank(); + ///< Set record to default state (does not touch the ID). }; } #endif diff --git a/components/esm/loadlock.cpp b/components/esm/loadlock.cpp index 02a36abfe..03eac52bd 100644 --- a/components/esm/loadlock.cpp +++ b/components/esm/loadlock.cpp @@ -21,11 +21,21 @@ void Lockpick::save(ESMWriter &esm) { esm.writeHNCString("MODL", mModel); esm.writeHNCString("FNAM", mName); - + esm.writeHNT("LKDT", mData, 16); esm.writeHNOString("SCRI", mScript); esm.writeHNOCString("ITEX", mIcon); } - + void Lockpick::blank() + { + mData.mWeight = 0; + mData.mValue = 0; + mData.mQuality = 0; + mData.mUses = 0; + mName.clear(); + mModel.clear(); + mIcon.clear(); + mScript.clear(); + } } diff --git a/components/esm/loadlock.hpp b/components/esm/loadlock.hpp index 0bbedf362..953066cb2 100644 --- a/components/esm/loadlock.hpp +++ b/components/esm/loadlock.hpp @@ -25,6 +25,9 @@ struct Lockpick void load(ESMReader &esm); void save(ESMWriter &esm); + + void blank(); + ///< Set record to default state (does not touch the ID). }; } diff --git a/components/esm/loadmisc.cpp b/components/esm/loadmisc.cpp index 3a5dded15..6006334ea 100644 --- a/components/esm/loadmisc.cpp +++ b/components/esm/loadmisc.cpp @@ -23,4 +23,14 @@ void Miscellaneous::save(ESMWriter &esm) esm.writeHNOCString("ITEX", mIcon); } + void Miscellaneous::blank() + { + mData.mWeight = 0; + mData.mValue = 0; + mData.mIsKey = 0; + mName.clear(); + mModel.clear(); + mIcon.clear(); + mScript.clear(); + } } diff --git a/components/esm/loadmisc.hpp b/components/esm/loadmisc.hpp index 26d25139c..25a9c5865 100644 --- a/components/esm/loadmisc.hpp +++ b/components/esm/loadmisc.hpp @@ -30,6 +30,9 @@ struct Miscellaneous void load(ESMReader &esm); void save(ESMWriter &esm); + + void blank(); + ///< Set record to default state (does not touch the ID). }; } #endif diff --git a/components/esm/loadnpc.cpp b/components/esm/loadnpc.cpp index 72d0b3736..3b53a20e5 100644 --- a/components/esm/loadnpc.cpp +++ b/components/esm/loadnpc.cpp @@ -56,7 +56,7 @@ void NPC::load(ESMReader &esm) mTransport.push_back(dodt); } else if (esm.retSubName() == 0x4d414e44) { // DNAM struct mTransport.back().mCellName = esm.getHString(); - } + } } mAiPackage.load(esm); esm.skipRecord(); @@ -71,14 +71,14 @@ void NPC::save(ESMWriter &esm) esm.writeHNCString("BNAM", mHead); esm.writeHNCString("KNAM", mHair); esm.writeHNOCString("SCRI", mScript); - + if (mNpdtType == 52) esm.writeHNT("NPDT", mNpdt52, 52); else if (mNpdtType == 12) esm.writeHNT("NPDT", mNpdt12, 12); esm.writeHNT("FLAG", mFlags); - + mInventory.save(esm); mSpells.save(esm); if (mHasAI) { @@ -93,4 +93,53 @@ void NPC::save(ESMWriter &esm) mAiPackage.save(esm); } + bool NPC::isMale() const { + return (mFlags & Female) == 0; + } + + void NPC::setIsMale(bool value) { + mFlags |= Female; + if (value) { + mFlags ^= Female; + } + } + + void NPC::blank() + { + mNpdtType = 0; + mNpdt52.mLevel = 0; + mNpdt52.mStrength = mNpdt52.mIntelligence = mNpdt52.mWillpower = mNpdt52.mAgility = + mNpdt52.mSpeed = mNpdt52.mEndurance = mNpdt52.mPersonality = mNpdt52.mLuck = 0; + for (int i=0; i<27; ++i) mNpdt52.mSkills[i] = 0; + mNpdt52.mReputation = 0; + mNpdt52.mHealth = mNpdt52.mMana = mNpdt52.mFatigue = 0; + mNpdt52.mDisposition = 0; + mNpdt52.mFactionID = 0; + mNpdt52.mRank = 0; + mNpdt52.mUnknown = 0; + mNpdt52.mGold = 0; + mNpdt12.mLevel = 0; + mNpdt12.mDisposition = 0; + mNpdt12.mReputation = 0; + mNpdt12.mRank = 0; + mNpdt12.mUnknown1 = 0; + mNpdt12.mUnknown2 = 0; + mNpdt12.mUnknown3 = 0; + mNpdt12.mGold = 0; + mFlags = 0; + mInventory.mList.clear(); + mSpells.mList.clear(); + mAiData.blank(); + mHasAI = false; + mTransport.clear(); + mAiPackage.mList.clear(); + mName.clear(); + mModel.clear(); + mRace.clear(); + mClass.clear(); + mFaction.clear(); + mScript.clear(); + mHair.clear(); + mHead.clear(); + } } diff --git a/components/esm/loadnpc.hpp b/components/esm/loadnpc.hpp index b30077f23..30a525565 100644 --- a/components/esm/loadnpc.hpp +++ b/components/esm/loadnpc.hpp @@ -114,20 +114,15 @@ struct NPC // body parts std::string mHair, mHead; - // Implementation moved to load_impl.cpp void load(ESMReader &esm); void save(ESMWriter &esm); - bool isMale() const { - return (mFlags & Female) == 0; - } + bool isMale() const; - void setIsMale(bool value) { - mFlags |= Female; - if (value) { - mFlags ^= Female; - } - } + void setIsMale(bool value); + + void blank(); + ///< Set record to default state (does not touch the ID). }; } #endif diff --git a/components/esm/loadprob.cpp b/components/esm/loadprob.cpp index bbaec1ce2..729f8404e 100644 --- a/components/esm/loadprob.cpp +++ b/components/esm/loadprob.cpp @@ -21,10 +21,21 @@ void Probe::save(ESMWriter &esm) { esm.writeHNCString("MODL", mModel); esm.writeHNCString("FNAM", mName); - + esm.writeHNT("PBDT", mData, 16); esm.writeHNOString("SCRI", mScript); esm.writeHNOCString("ITEX", mIcon); } + void Probe::blank() + { + mData.mWeight = 0; + mData.mValue = 0; + mData.mQuality = 0; + mData.mUses = 0; + mName.clear(); + mModel.clear(); + mIcon.clear(); + mScript.clear(); + } } diff --git a/components/esm/loadprob.hpp b/components/esm/loadprob.hpp index 4a47a8600..55b896bcd 100644 --- a/components/esm/loadprob.hpp +++ b/components/esm/loadprob.hpp @@ -25,6 +25,9 @@ struct Probe void load(ESMReader &esm); void save(ESMWriter &esm); + + void blank(); + ///< Set record to default state (does not touch the ID). }; } diff --git a/components/esm/loadrepa.cpp b/components/esm/loadrepa.cpp index f7eeddf96..ced6daa2e 100644 --- a/components/esm/loadrepa.cpp +++ b/components/esm/loadrepa.cpp @@ -27,5 +27,15 @@ void Repair::save(ESMWriter &esm) esm.writeHNOCString("ITEX", mIcon); } - + void Repair::blank() + { + mData.mWeight = 0; + mData.mValue = 0; + mData.mQuality = 0; + mData.mUses = 0; + mName.clear(); + mModel.clear(); + mIcon.clear(); + mScript.clear(); + } } diff --git a/components/esm/loadrepa.hpp b/components/esm/loadrepa.hpp index 60ff5df90..83812bad9 100644 --- a/components/esm/loadrepa.hpp +++ b/components/esm/loadrepa.hpp @@ -25,6 +25,9 @@ struct Repair void load(ESMReader &esm); void save(ESMWriter &esm); + + void blank(); + ///< Set record to default state (does not touch the ID). }; } diff --git a/components/esm/loadstat.cpp b/components/esm/loadstat.cpp index 92c9ebc71..c9346dafc 100644 --- a/components/esm/loadstat.cpp +++ b/components/esm/loadstat.cpp @@ -15,4 +15,8 @@ void Static::save(ESMWriter &esm) esm.writeHNCString("MODL", mModel); } + void Static::blank() + { + mModel.clear(); + } } diff --git a/components/esm/loadstat.hpp b/components/esm/loadstat.hpp index 790a71147..1adb7d05b 100644 --- a/components/esm/loadstat.hpp +++ b/components/esm/loadstat.hpp @@ -26,6 +26,9 @@ struct Static void load(ESMReader &esm); void save(ESMWriter &esm); + + void blank(); + ///< Set record to default state (does not touch the ID). }; } #endif diff --git a/components/esm/loadweap.cpp b/components/esm/loadweap.cpp index 18d37e56c..253712396 100644 --- a/components/esm/loadweap.cpp +++ b/components/esm/loadweap.cpp @@ -25,4 +25,24 @@ void Weapon::save(ESMWriter &esm) esm.writeHNOCString("ENAM", mEnchant); } + void Weapon::blank() + { + mData.mWeight = 0; + mData.mValue = 0; + mData.mType = 0; + mData.mHealth = 0; + mData.mSpeed = 0; + mData.mReach = 0; + mData.mEnchant = 0; + mData.mChop[0] = mData.mChop[1] = 0; + mData.mSlash[0] = mData.mSlash[1] = 0; + mData.mThrust[0] = mData.mThrust[1] = 0; + mData.mFlags = 0; + + mName.clear(); + mModel.clear(); + mIcon.clear(); + mEnchant.clear(); + mScript.clear(); + } } diff --git a/components/esm/loadweap.hpp b/components/esm/loadweap.hpp index e482d3b10..60535ee2e 100644 --- a/components/esm/loadweap.hpp +++ b/components/esm/loadweap.hpp @@ -60,6 +60,9 @@ struct Weapon void load(ESMReader &esm); void save(ESMWriter &esm); + + void blank(); + ///< Set record to default state (does not touch the ID). }; } #endif From e9f1aac7bde34c61cc4199ea0a41048af2c68c76 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 6 May 2013 14:11:55 +0200 Subject: [PATCH 11/44] added data structures for referenceable records --- apps/opencs/CMakeLists.txt | 3 +- apps/opencs/model/world/refidadapter.cpp | 6 + apps/opencs/model/world/refidadapter.hpp | 36 ++++ apps/opencs/model/world/refidcollection.cpp | 202 ++++++++++++++++++++ apps/opencs/model/world/refidcollection.hpp | 95 +++++++++ apps/opencs/model/world/refiddata.cpp | 198 +++++++++++++++++++ apps/opencs/model/world/refiddata.hpp | 188 ++++++++++++++++++ 7 files changed, 727 insertions(+), 1 deletion(-) create mode 100644 apps/opencs/model/world/refidadapter.cpp create mode 100644 apps/opencs/model/world/refidadapter.hpp create mode 100644 apps/opencs/model/world/refidcollection.cpp create mode 100644 apps/opencs/model/world/refidcollection.hpp create mode 100644 apps/opencs/model/world/refiddata.cpp create mode 100644 apps/opencs/model/world/refiddata.hpp diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index efc3551fd..102b34890 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -22,7 +22,8 @@ opencs_units (model/world opencs_units_noqt (model/world - universalid data record idcollection commands columnbase scriptcontext cell + universalid data record idcollection commands columnbase scriptcontext cell refidcollection + refidadapter refiddata ) opencs_hdrs_noqt (model/world diff --git a/apps/opencs/model/world/refidadapter.cpp b/apps/opencs/model/world/refidadapter.cpp new file mode 100644 index 000000000..94ae38c3c --- /dev/null +++ b/apps/opencs/model/world/refidadapter.cpp @@ -0,0 +1,6 @@ + +#include "refidadapter.hpp" + +CSMWorld::RefIdAdapter::RefIdAdapter() {} + +CSMWorld::RefIdAdapter::~RefIdAdapter() {} \ No newline at end of file diff --git a/apps/opencs/model/world/refidadapter.hpp b/apps/opencs/model/world/refidadapter.hpp new file mode 100644 index 000000000..fa56e2836 --- /dev/null +++ b/apps/opencs/model/world/refidadapter.hpp @@ -0,0 +1,36 @@ +#ifndef CSM_WOLRD_REDIDADAPTER_H +#define CSM_WOLRD_REFIDADAPTER_H + +#include + +class QVariant; + +namespace CSMWorld +{ + class RefIdColumn; + class RefIdData; + class RecordBase; + + class RefIdAdapter + { + // not implemented + RefIdAdapter (const RefIdAdapter&); + RefIdAdapter& operator= (const RefIdAdapter&); + + public: + + RefIdAdapter(); + + virtual ~RefIdAdapter(); + + virtual QVariant getData (const RefIdColumn *column, const RefIdData& data) const = 0; + + virtual void setData (const RefIdColumn *column, RefIdData& data, const QVariant& value) + const = 0; + ///< If the data type does not match an exception is thrown. + + virtual std::string getId (const RecordBase& record) const = 0; + }; +} + +#endif \ No newline at end of file diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp new file mode 100644 index 000000000..751d4e759 --- /dev/null +++ b/apps/opencs/model/world/refidcollection.cpp @@ -0,0 +1,202 @@ + +#include "refidcollection.hpp" + +#include + +#include "refidadapter.hpp" + +CSMWorld::RefIdColumn::RefIdColumn (const std::string& title, Display displayType, int flag, + bool editable, bool userEditable) +: ColumnBase (title, displayType, flag), mEditable (editable), mUserEditable (userEditable) +{} + +bool CSMWorld::RefIdColumn::isEditable() const +{ + return mEditable; +} + +bool CSMWorld::RefIdColumn::isUserEditable() const +{ + return mUserEditable; +} + + +const CSMWorld::RefIdAdapter& CSMWorld::RefIdCollection::findAdaptor (UniversalId::Type type) const +{ + std::map::const_iterator iter = mAdapters.find (type); + + if (iter==mAdapters.end()) + throw std::logic_error ("unsupported type in RefIdCollection"); + + return *iter->second; +} + +CSMWorld::RefIdCollection::RefIdCollection() +{ + mColumns.push_back (RefIdColumn ("ID", ColumnBase::Display_String, + ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue, false, false)); + mColumns.push_back (RefIdColumn ("*", ColumnBase::Display_Integer, + ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue, false, false)); + mColumns.push_back (RefIdColumn ("Name", ColumnBase::Display_String)); +} + +CSMWorld::RefIdCollection::~RefIdCollection() +{ + for (std::map::iterator iter (mAdapters.begin()); + iter!=mAdapters.end(); ++iter) + delete iter->second; +} + +int CSMWorld::RefIdCollection::getSize() const +{ + return mData.getSize(); +} + +std::string CSMWorld::RefIdCollection::getId (int index) const +{ + return getData (index, 0).toString().toUtf8().constData(); +} + +int CSMWorld::RefIdCollection::getIndex (const std::string& id) const +{ + int index = searchId (id); + + if (index==-1) + throw std::runtime_error ("invalid ID: " + id); + + return index; +} + +int CSMWorld::RefIdCollection::getColumns() const +{ + return mColumns.size(); +} + +const CSMWorld::ColumnBase& CSMWorld::RefIdCollection::getColumn (int column) const +{ + return mColumns.at (column); +} + +QVariant CSMWorld::RefIdCollection::getData (int index, int column) const +{ + RefIdData::LocalIndex localIndex = mData.globalToLocalIndex (index); + + const RefIdAdapter& adaptor = findAdaptor (localIndex.second); + + return adaptor.getData (&mColumns.at (column), mData); +} + +void CSMWorld::RefIdCollection::setData (int index, int column, const QVariant& data) +{ + RefIdData::LocalIndex localIndex = mData.globalToLocalIndex (index); + + const RefIdAdapter& adaptor = findAdaptor (localIndex.second); + + adaptor.setData (&mColumns.at (column), mData, data); +} + +void CSMWorld::RefIdCollection::removeRows (int index, int count) +{ + mData.erase (index, count); +} + +void CSMWorld::RefIdCollection::appendBlankRecord (const std::string& id, UniversalId::Type type) +{ + mData.appendRecord (type, id); +} + +int CSMWorld::RefIdCollection::searchId (const std::string& id) const +{ + return mData.localToGlobalIndex (mData.searchId (id)); +} + +void CSMWorld::RefIdCollection::replace (int index, const RecordBase& record) +{ + mData.getRecord (mData.globalToLocalIndex (index)).assign (record); +} + +void CSMWorld::RefIdCollection::appendRecord (const RecordBase& record, + UniversalId::Type type) +{ + std::string id = findAdaptor (type).getId (record); + + int index = mData.getAppendIndex (type); + + mData.appendRecord (type, id); + + mData.getRecord (mData.globalToLocalIndex (index)).assign (record); +} + +const CSMWorld::RecordBase& CSMWorld::RefIdCollection::getRecord (const std::string& id) const +{ + return mData.getRecord (mData.searchId (id)); +} + +const CSMWorld::RecordBase& CSMWorld::RefIdCollection::getRecord (int index) const +{ + return mData.getRecord (mData.globalToLocalIndex (index)); +} + +void CSMWorld::RefIdCollection::load (ESM::ESMReader& reader, bool base, UniversalId::Type type) +{ + std::string id = reader.getHNOString ("NAME"); + + int index = searchId (id); + + if (reader.isNextSub ("DELE")) + { + reader.skipRecord(); + + if (index==-1) + { + // deleting a record that does not exist + + // ignore it for now + + /// \todo report the problem to the user + } + else if (base) + { + mData.erase (index, 1); + } + else + { + mData.getRecord (mData.globalToLocalIndex (index)).mState = RecordBase::State_Deleted; + } + } + else + { + if (index==-1) + { + // new record + int index = mData.getAppendIndex (type); + mData.appendRecord (type, id); + + RefIdData::LocalIndex localIndex = mData.globalToLocalIndex (index); + + mData.load (localIndex, reader, base); + + mData.getRecord (localIndex).mState = + base ? RecordBase::State_BaseOnly : RecordBase::State_ModifiedOnly; + } + else + { + // old record + RefIdData::LocalIndex localIndex = mData.globalToLocalIndex (index); + + if (!base) + if (mData.getRecord (localIndex).mState==RecordBase::State_Erased) + throw std::logic_error ("attempt to access a deleted record"); + + mData.load (localIndex, reader, base); + + if (!base) + mData.getRecord (localIndex).mState = RecordBase::State_Modified; + } + } +} + +int CSMWorld::RefIdCollection::getAppendIndex (UniversalId::Type type) const +{ + return mData.getAppendIndex (type); +} \ No newline at end of file diff --git a/apps/opencs/model/world/refidcollection.hpp b/apps/opencs/model/world/refidcollection.hpp new file mode 100644 index 000000000..4f8096d25 --- /dev/null +++ b/apps/opencs/model/world/refidcollection.hpp @@ -0,0 +1,95 @@ +#ifndef CSM_WOLRD_REFIDCOLLECTION_H +#define CSM_WOLRD_REFIDCOLLECTION_H + +#include +#include + +#include "columnbase.hpp" +#include "idcollection.hpp" +#include "refiddata.hpp" + +namespace CSMWorld +{ + class RefIdAdapter; + + class RefIdColumn : public ColumnBase + { + bool mEditable; + bool mUserEditable; + + public: + + RefIdColumn (const std::string& title, Display displayType, + int flag = Flag_Table | Flag_Dialogue, bool editable = true, + bool userEditable = true); + + virtual bool isEditable() const; + + virtual bool isUserEditable() const; + }; + + class RefIdCollection : public IdCollectionBase + { + private: + + RefIdData mData; + std::vector mColumns; + std::map mAdapters; + + private: + + const RefIdAdapter& findAdaptor (UniversalId::Type) const; + ///< Throws an exception if no adaptor for \a Type can be found. + + public: + + RefIdCollection(); + + virtual ~RefIdCollection(); + + virtual int getSize() const; + + virtual std::string getId (int index) const; + + virtual int getIndex (const std::string& id) const; + + virtual int getColumns() const; + + virtual const ColumnBase& getColumn (int column) const; + + virtual QVariant getData (int index, int column) const; + + virtual void setData (int index, int column, const QVariant& data); + + virtual void removeRows (int index, int count); + + virtual void appendBlankRecord (const std::string& id, UniversalId::Type type); + ///< \param type Will be ignored, unless the collection supports multiple record types + + virtual int searchId (const std::string& id) const; + ////< Search record with \a id. + /// \return index of record (if found) or -1 (not found) + + virtual void replace (int index, const RecordBase& record); + ///< If the record type does not match, an exception is thrown. + /// + /// \attention \a record must not change the ID. + + virtual void appendRecord (const RecordBase& record, UniversalId::Type type); + ///< If the record type does not match, an exception is thrown. + /// + ///< \param type Will be ignored, unless the collection supports multiple record types + + virtual const RecordBase& getRecord (const std::string& id) const; + + virtual const RecordBase& getRecord (int index) const; + + virtual void load (ESM::ESMReader& reader, bool base, UniversalId::Type type); + + virtual int getAppendIndex (UniversalId::Type type) const; + ///< \param type Will be ignored, unless the collection supports multiple record types + + }; +} + +#endif diff --git a/apps/opencs/model/world/refiddata.cpp b/apps/opencs/model/world/refiddata.cpp new file mode 100644 index 000000000..9f6ed9be3 --- /dev/null +++ b/apps/opencs/model/world/refiddata.cpp @@ -0,0 +1,198 @@ + +#include "refiddata.hpp" + +#include + +#include + +CSMWorld::RefIdDataContainerBase::~RefIdDataContainerBase() {} + +CSMWorld::RefIdData::RefIdData() +{ + mRecordContainers.insert (std::make_pair (UniversalId::Type_Activator, &mActivators)); + mRecordContainers.insert (std::make_pair (UniversalId::Type_Potion, &mPotions)); + mRecordContainers.insert (std::make_pair (UniversalId::Type_Apparatus, &mApparati)); + mRecordContainers.insert (std::make_pair (UniversalId::Type_Armor, &mArmors)); + mRecordContainers.insert (std::make_pair (UniversalId::Type_Book, &mBooks)); + mRecordContainers.insert (std::make_pair (UniversalId::Type_Clothing, &mClothing)); + mRecordContainers.insert (std::make_pair (UniversalId::Type_Container, &mContainers)); + mRecordContainers.insert (std::make_pair (UniversalId::Type_Creature, &mCreatures)); + mRecordContainers.insert (std::make_pair (UniversalId::Type_Door, &mDoors)); + mRecordContainers.insert (std::make_pair (UniversalId::Type_Ingredient, &mIngredients)); + mRecordContainers.insert (std::make_pair (UniversalId::Type_CreatureLevelledList, + &mCreatureLevelledLists)); + mRecordContainers.insert (std::make_pair (UniversalId::Type_ItemLevelledList, &mItemLevelledLists)); + mRecordContainers.insert (std::make_pair (UniversalId::Type_Light, &mLights)); + mRecordContainers.insert (std::make_pair (UniversalId::Type_Lockpick, &mLockpicks)); + mRecordContainers.insert (std::make_pair (UniversalId::Type_Miscellaneous, &mMiscellaneous)); + mRecordContainers.insert (std::make_pair (UniversalId::Type_Npc, &mNpcs)); + mRecordContainers.insert (std::make_pair (UniversalId::Type_Probe, &mProbes)); + mRecordContainers.insert (std::make_pair (UniversalId::Type_Repair, &mRepairs)); + mRecordContainers.insert (std::make_pair (UniversalId::Type_Static, &mStatics)); + mRecordContainers.insert (std::make_pair (UniversalId::Type_Weapon, &mWeapons)); +} + +CSMWorld::RefIdData::LocalIndex CSMWorld::RefIdData::globalToLocalIndex (int index) const +{ + for (std::map::const_iterator iter ( + mRecordContainers.begin()); iter!=mRecordContainers.end(); ++iter) + { + if (indexsecond->getSize()) + return LocalIndex (index, iter->first); + + index -= iter->second->getSize(); + } + + throw std::runtime_error ("RefIdData index out of range"); +} + +int CSMWorld::RefIdData::localToGlobalIndex (const LocalIndex& index) + const +{ + std::map::const_iterator end = + mRecordContainers.find (index.second); + + if (end==mRecordContainers.end()) + throw std::logic_error ("invalid local index type"); + + int globalIndex = index.first; + + for (std::map::const_iterator iter ( + mRecordContainers.begin()); iter!=end; ++iter) + globalIndex += iter->second->getSize(); + + return globalIndex; +} + +CSMWorld::RefIdData::LocalIndex CSMWorld::RefIdData::searchId ( + const std::string& id) const +{ + std::string id2 = Misc::StringUtils::lowerCase (id); + + std::map >::const_iterator iter = mIndex.find (id2); + + if (iter!=mIndex.end()) + return std::make_pair (-1, CSMWorld::UniversalId::Type_None); + + return iter->second; +} + +void CSMWorld::RefIdData::erase (int index, int count) +{ + LocalIndex localIndex = globalToLocalIndex (index); + + std::map::const_iterator iter = + mRecordContainers.find (localIndex.second); + + while (count>0 && iter!=mRecordContainers.end()) + { + int size = iter->second->getSize(); + + if (localIndex.first+count>size) + { + erase (localIndex, size-localIndex.first); + count -= size-localIndex.first; + + ++iter; + + if (iter==mRecordContainers.end()) + throw std::runtime_error ("invalid count value for erase operation"); + + localIndex.first = 0; + localIndex.second = iter->first; + } + else + { + erase (localIndex, count); + count = 0; + } + } +} + +const CSMWorld::RecordBase& CSMWorld::RefIdData::getRecord (const LocalIndex& index) const +{ + std::map::const_iterator iter = + mRecordContainers.find (index.second); + + if (iter==mRecordContainers.end()) + throw std::logic_error ("invalid local index type"); + + return iter->second->getRecord (index.first); +} + +CSMWorld::RecordBase& CSMWorld::RefIdData::getRecord (const LocalIndex& index) +{ + std::map::iterator iter = + mRecordContainers.find (index.second); + + if (iter==mRecordContainers.end()) + throw std::logic_error ("invalid local index type"); + + return iter->second->getRecord (index.first); +} + +void CSMWorld::RefIdData::appendRecord (UniversalId::Type type, const std::string& id) +{ + std::map::iterator iter = + mRecordContainers.find (type); + + if (iter==mRecordContainers.end()) + throw std::logic_error ("invalid local index type"); + + iter->second->appendRecord (id); + + mIndex.insert (std::make_pair (Misc::StringUtils::lowerCase (id), + LocalIndex (iter->second->getSize()-1, type))); +} + +int CSMWorld::RefIdData::getAppendIndex (UniversalId::Type type) const +{ + int index = 0; + + for (std::map::const_iterator iter ( + mRecordContainers.begin()); iter!=mRecordContainers.end(); ++iter) + { + index += iter->second->getSize(); + + if (type==iter->first) + break; + } + + return index; +} + +void CSMWorld::RefIdData::load (const LocalIndex& index, ESM::ESMReader& reader, bool base) +{ + std::map::iterator iter = + mRecordContainers.find (index.second); + + if (iter==mRecordContainers.end()) + throw std::logic_error ("invalid local index type"); + + iter->second->load (index.first, reader, base); +} + +void CSMWorld::RefIdData::erase (const LocalIndex& index, int count) +{ + std::map::iterator iter = + mRecordContainers.find (index.second); + + if (iter==mRecordContainers.end()) + throw std::logic_error ("invalid local index type"); + + for (int i=index.first; i::iterator result = + mIndex.find (Misc::StringUtils::lowerCase (iter->second->getId (i))); + + if (result!=mIndex.end()) + mIndex.erase (result); + } + + iter->second->erase (index.first, count); +} + +int CSMWorld::RefIdData::getSize() const +{ + return mIndex.size(); +} diff --git a/apps/opencs/model/world/refiddata.hpp b/apps/opencs/model/world/refiddata.hpp new file mode 100644 index 000000000..475566fb5 --- /dev/null +++ b/apps/opencs/model/world/refiddata.hpp @@ -0,0 +1,188 @@ +#ifndef CSM_WOLRD_REFIDDATA_H +#define CSM_WOLRD_REFIDDATA_H + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "record.hpp" +#include "universalid.hpp" + +namespace ESM +{ + class ESMReader; +} + +namespace CSMWorld +{ + struct RefIdDataContainerBase + { + virtual ~RefIdDataContainerBase(); + + virtual int getSize() const = 0; + + virtual const RecordBase& getRecord (int index) const = 0; + + virtual RecordBase& getRecord (int index)= 0; + + virtual void appendRecord (const std::string& id) = 0; + + virtual void load (int index, ESM::ESMReader& reader, bool base) = 0; + + virtual void erase (int index, int count) = 0; + + virtual std::string getId (int index) const = 0; + }; + + template + struct RefIdDataContainer : public RefIdDataContainerBase + { + std::vector > mContainer; + + virtual int getSize() const; + + virtual const RecordBase& getRecord (int index) const; + + virtual RecordBase& getRecord (int index); + + virtual void appendRecord (const std::string& id); + + virtual void load (int index, ESM::ESMReader& reader, bool base); + + virtual void erase (int index, int count); + + virtual std::string getId (int index) const; + }; + + template + int RefIdDataContainer::getSize() const + { + return static_cast (mContainer.size()); + } + + template + const RecordBase& RefIdDataContainer::getRecord (int index) const + { + return mContainer.at (index); + } + + template + RecordBase& RefIdDataContainer::getRecord (int index) + { + return mContainer.at (index); + } + + template + void RefIdDataContainer::appendRecord (const std::string& id) + { + Record record; + record.mModified.mId = id; + record.mModified.blank(); + record.mState = RecordBase::State_ModifiedOnly; + + mContainer.push_back (record); + } + + template + void RefIdDataContainer::load (int index, ESM::ESMReader& reader, bool base) + { + (base ? mContainer.at (index).mBase : mContainer.at (index).mModified).load (reader); + } + + template + void RefIdDataContainer::erase (int index, int count) + { + if (index<0 || index+count>=getSize()) + throw std::runtime_error ("invalid RefIdDataContainer index"); + + mContainer.erase (mContainer.begin()+index, mContainer.begin()+index+count); + } + + template + std::string RefIdDataContainer::getId (int index) const + { + return mContainer.at (index).get().mId; + } + + class RefIdData + { + public: + + typedef std::pair LocalIndex; + + private: + + RefIdDataContainer mActivators; + RefIdDataContainer mPotions; + RefIdDataContainer mApparati; + RefIdDataContainer mArmors; + RefIdDataContainer mBooks; + RefIdDataContainer mClothing; + RefIdDataContainer mContainers; + RefIdDataContainer mCreatures; + RefIdDataContainer mDoors; + RefIdDataContainer mIngredients; + RefIdDataContainer mCreatureLevelledLists; + RefIdDataContainer mItemLevelledLists; + RefIdDataContainer mLights; + RefIdDataContainer mLockpicks; + RefIdDataContainer mMiscellaneous; + RefIdDataContainer mNpcs; + RefIdDataContainer mProbes; + RefIdDataContainer mRepairs; + RefIdDataContainer mStatics; + RefIdDataContainer mWeapons; + + std::map mIndex; + + std::map mRecordContainers; + + void erase (const LocalIndex& index, int count); + ///< Must not spill over into another type. + + public: + + RefIdData(); + + LocalIndex globalToLocalIndex (int index) const; + + int localToGlobalIndex (const LocalIndex& index) const; + + LocalIndex searchId (const std::string& id) const; + + void erase (int index, int count); + + const RecordBase& getRecord (const LocalIndex& index) const; + + RecordBase& getRecord (const LocalIndex& index); + + void appendRecord (UniversalId::Type type, const std::string& id); + + int getAppendIndex (UniversalId::Type type) const; + + void load (const LocalIndex& index, ESM::ESMReader& reader, bool base); + + int getSize() const; + }; +} + +#endif From f7f56a1a1f965d071b00cb08cbb2d8abc3c6c20b Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 7 May 2013 11:23:18 +0200 Subject: [PATCH 12/44] added a RefIdCollection to Data --- apps/opencs/model/world/data.cpp | 12 ++++++++++++ apps/opencs/model/world/data.hpp | 6 ++++++ apps/opencs/model/world/idcollection.hpp | 6 ++++-- 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index dedbfc4e7..9172959bb 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -140,6 +140,8 @@ CSMWorld::Data::Data() addModel (new IdTable (&mBirthsigns), UniversalId::Type_Birthsigns, UniversalId::Type_Birthsign); addModel (new IdTable (&mSpells), UniversalId::Type_Spells, UniversalId::Type_Spell); addModel (new IdTable (&mCells), UniversalId::Type_Cells, UniversalId::Type_Cell); + addModel (new IdTable (&mReferenceables), UniversalId::Type_Referenceables, + UniversalId::Type_Referenceable); } CSMWorld::Data::~Data() @@ -268,6 +270,16 @@ CSMWorld::IdCollection& CSMWorld::Data::getCells() return mCells; } +const CSMWorld::RefIdCollection& CSMWorld::Data::getReferenceables() const +{ + return mReferenceables; +} + +CSMWorld::RefIdCollection& CSMWorld::Data::getReferenceables() +{ + return mReferenceables; +} + QAbstractItemModel *CSMWorld::Data::getTableModel (const UniversalId& id) { std::map::iterator iter = mModelIndex.find (id.getType()); diff --git a/apps/opencs/model/world/data.hpp b/apps/opencs/model/world/data.hpp index 03a2448f1..ad6e4ba69 100644 --- a/apps/opencs/model/world/data.hpp +++ b/apps/opencs/model/world/data.hpp @@ -21,6 +21,7 @@ #include "idcollection.hpp" #include "universalid.hpp" #include "cell.hpp" +#include "refidcollection.hpp" class QAbstractItemModel; @@ -40,6 +41,7 @@ namespace CSMWorld IdCollection mBirthsigns; IdCollection mSpells; IdCollection mCells; + RefIdCollection mReferenceables; std::vector mModels; std::map mModelIndex; @@ -104,6 +106,10 @@ namespace CSMWorld IdCollection& getCells(); + const RefIdCollection& getReferenceables() const; + + RefIdCollection& getReferenceables(); + QAbstractItemModel *getTableModel (const UniversalId& id); ///< If no table model is available for \a id, an exception is thrown. /// diff --git a/apps/opencs/model/world/idcollection.hpp b/apps/opencs/model/world/idcollection.hpp index 93390c97b..193e4f8e2 100644 --- a/apps/opencs/model/world/idcollection.hpp +++ b/apps/opencs/model/world/idcollection.hpp @@ -46,10 +46,12 @@ namespace CSMWorld virtual void setData (int index, int column, const QVariant& data) = 0; - virtual void merge() = 0; +// Not in use. Temporarily removed so that the implementation of RefIdCollection can continue without +// these functions for now. +// virtual void merge() = 0; ///< Merge modified into base. - virtual void purge() = 0; +// virtual void purge() = 0; ///< Remove records that are flagged as erased. virtual void removeRows (int index, int count) = 0; From 0f29ab8cf998222a6a27b7c9c299ecf0c3ed7fd0 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 7 May 2013 14:19:02 +0200 Subject: [PATCH 13/44] fixed the interface of the adapter class --- apps/opencs/model/world/refidadapter.hpp | 7 ++++--- apps/opencs/model/world/refidcollection.cpp | 4 ++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/apps/opencs/model/world/refidadapter.hpp b/apps/opencs/model/world/refidadapter.hpp index fa56e2836..bb9005b27 100644 --- a/apps/opencs/model/world/refidadapter.hpp +++ b/apps/opencs/model/world/refidadapter.hpp @@ -23,10 +23,11 @@ namespace CSMWorld virtual ~RefIdAdapter(); - virtual QVariant getData (const RefIdColumn *column, const RefIdData& data) const = 0; - - virtual void setData (const RefIdColumn *column, RefIdData& data, const QVariant& value) + virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int idnex) const = 0; + + virtual void setData (const RefIdColumn *column, RefIdData& data, int index, + const QVariant& value) const = 0; ///< If the data type does not match an exception is thrown. virtual std::string getId (const RecordBase& record) const = 0; diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index 751d4e759..013970b04 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -83,7 +83,7 @@ QVariant CSMWorld::RefIdCollection::getData (int index, int column) const const RefIdAdapter& adaptor = findAdaptor (localIndex.second); - return adaptor.getData (&mColumns.at (column), mData); + return adaptor.getData (&mColumns.at (column), mData, localIndex.first); } void CSMWorld::RefIdCollection::setData (int index, int column, const QVariant& data) @@ -92,7 +92,7 @@ void CSMWorld::RefIdCollection::setData (int index, int column, const QVariant& const RefIdAdapter& adaptor = findAdaptor (localIndex.second); - adaptor.setData (&mColumns.at (column), mData, data); + adaptor.setData (&mColumns.at (column), mData, localIndex.first, data); } void CSMWorld::RefIdCollection::removeRows (int index, int count) From 02ace69511390bd0bba14555f0d6c2b4140a7cdf Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 11 May 2013 16:55:10 +0200 Subject: [PATCH 14/44] fixed RefID search --- apps/opencs/model/world/refidcollection.cpp | 14 ++++++++++++-- apps/opencs/model/world/refiddata.cpp | 2 +- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index 013970b04..1312a44e3 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -4,6 +4,7 @@ #include #include "refidadapter.hpp" +#include "refidadapterimp.hpp" CSMWorld::RefIdColumn::RefIdColumn (const std::string& title, Display displayType, int flag, bool editable, bool userEditable) @@ -37,7 +38,11 @@ CSMWorld::RefIdCollection::RefIdCollection() ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue, false, false)); mColumns.push_back (RefIdColumn ("*", ColumnBase::Display_Integer, ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue, false, false)); - mColumns.push_back (RefIdColumn ("Name", ColumnBase::Display_String)); +// mColumns.push_back (RefIdColumn ("Name", ColumnBase::Display_String)); + + mAdapters.insert (std::make_pair (UniversalId::Type_Static, new StaticRefIdAdapter (&mColumns[0], + &mColumns[1]))); + } CSMWorld::RefIdCollection::~RefIdCollection() @@ -107,7 +112,12 @@ void CSMWorld::RefIdCollection::appendBlankRecord (const std::string& id, Univer int CSMWorld::RefIdCollection::searchId (const std::string& id) const { - return mData.localToGlobalIndex (mData.searchId (id)); + RefIdData::LocalIndex localIndex = mData.searchId (id); + + if (localIndex.first==-1) + return -1; + + return mData.localToGlobalIndex (localIndex); } void CSMWorld::RefIdCollection::replace (int index, const RecordBase& record) diff --git a/apps/opencs/model/world/refiddata.cpp b/apps/opencs/model/world/refiddata.cpp index 9f6ed9be3..c95db045f 100644 --- a/apps/opencs/model/world/refiddata.cpp +++ b/apps/opencs/model/world/refiddata.cpp @@ -71,7 +71,7 @@ CSMWorld::RefIdData::LocalIndex CSMWorld::RefIdData::searchId ( std::map >::const_iterator iter = mIndex.find (id2); - if (iter!=mIndex.end()) + if (iter==mIndex.end()) return std::make_pair (-1, CSMWorld::UniversalId::Type_None); return iter->second; From 9426eda47abbca4facf4e4a8be0fd8d305ed139d Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 11 May 2013 17:01:16 +0200 Subject: [PATCH 15/44] small test with statics and two columns --- apps/opencs/CMakeLists.txt | 2 +- apps/opencs/model/world/data.cpp | 2 + apps/opencs/model/world/refidadapter.hpp | 2 +- apps/opencs/model/world/refidadapterimp.cpp | 49 +++++++++++++++++++++ apps/opencs/model/world/refidadapterimp.hpp | 28 ++++++++++++ apps/opencs/view/doc/view.cpp | 10 +++++ apps/opencs/view/doc/view.hpp | 2 + apps/opencs/view/world/subviews.cpp | 1 + 8 files changed, 94 insertions(+), 2 deletions(-) create mode 100644 apps/opencs/model/world/refidadapterimp.cpp create mode 100644 apps/opencs/model/world/refidadapterimp.hpp diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index 102b34890..26287c6bd 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -23,7 +23,7 @@ opencs_units (model/world opencs_units_noqt (model/world universalid data record idcollection commands columnbase scriptcontext cell refidcollection - refidadapter refiddata + refidadapter refiddata refidadapterimp ) opencs_hdrs_noqt (model/world diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index 9172959bb..db6629aa0 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -327,6 +327,8 @@ void CSMWorld::Data::loadFile (const boost::filesystem::path& path, bool base) case ESM::REC_SPEL: mSpells.load (reader, base); break; case ESM::REC_CELL: mCells.load (reader, base); break; + case ESM::REC_STAT: mReferenceables.load (reader, base, UniversalId::Type_Static); break; + default: /// \todo throw an exception instead, once all records are implemented diff --git a/apps/opencs/model/world/refidadapter.hpp b/apps/opencs/model/world/refidadapter.hpp index bb9005b27..df0ceae70 100644 --- a/apps/opencs/model/world/refidadapter.hpp +++ b/apps/opencs/model/world/refidadapter.hpp @@ -1,4 +1,4 @@ -#ifndef CSM_WOLRD_REDIDADAPTER_H +#ifndef CSM_WOLRD_REFIDADAPTER_H #define CSM_WOLRD_REFIDADAPTER_H #include diff --git a/apps/opencs/model/world/refidadapterimp.cpp b/apps/opencs/model/world/refidadapterimp.cpp new file mode 100644 index 000000000..5038797dd --- /dev/null +++ b/apps/opencs/model/world/refidadapterimp.cpp @@ -0,0 +1,49 @@ + +#include "refidadapterimp.hpp" + +#include + +#include + +#include "record.hpp" +#include "refiddata.hpp" +#include "universalid.hpp" + +CSMWorld::StaticRefIdAdapter::StaticRefIdAdapter (const RefIdColumn *id, const RefIdColumn *modified) +: mId (id), mModified (modified) +{} + +QVariant CSMWorld::StaticRefIdAdapter::getData (const RefIdColumn *column, const RefIdData& data, + int index) const +{ + const Record& record = static_cast&> ( + data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Static))); + + if (column==mId) + return QString::fromUtf8 (record.get().mId.c_str()); + + if (column==mModified) + { + if (record.mState==Record::State_Erased) + return static_cast (Record::State_Deleted); + + return static_cast (record.mState); + } + + return QVariant(); +} + +void CSMWorld::StaticRefIdAdapter::setData (const RefIdColumn *column, RefIdData& data, int index, + const QVariant& value) const +{ + Record& record = static_cast&> ( + data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Static))); + + if (column==mModified) + record.mState = static_cast (value.toInt()); +} + +std::string CSMWorld::StaticRefIdAdapter::getId (const RecordBase& record) const +{ + return dynamic_cast&> (record).get().mId; +} \ No newline at end of file diff --git a/apps/opencs/model/world/refidadapterimp.hpp b/apps/opencs/model/world/refidadapterimp.hpp new file mode 100644 index 000000000..c130e2f73 --- /dev/null +++ b/apps/opencs/model/world/refidadapterimp.hpp @@ -0,0 +1,28 @@ +#ifndef CSM_WOLRD_REFIDADAPTERIMP_H +#define CSM_WOLRD_REFIDADAPTERIMP_H + +#include "refidadapter.hpp" + +namespace CSMWorld +{ + class StaticRefIdAdapter : public RefIdAdapter + { + const RefIdColumn *mId; + const RefIdColumn *mModified; + + public: + + StaticRefIdAdapter (const RefIdColumn *id, const RefIdColumn *modified); + + virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int idnex) + const; + + virtual void setData (const RefIdColumn *column, RefIdData& data, int index, + const QVariant& value) const; + ///< If the data type does not match an exception is thrown. + + virtual std::string getId (const RecordBase& record) const; + }; +} + +#endif diff --git a/apps/opencs/view/doc/view.cpp b/apps/opencs/view/doc/view.cpp index a684b85c5..8b46d649f 100644 --- a/apps/opencs/view/doc/view.cpp +++ b/apps/opencs/view/doc/view.cpp @@ -129,6 +129,11 @@ void CSVDoc::View::setupWorldMenu() QAction *cells = new QAction (tr ("Cells"), this); connect (cells, SIGNAL (triggered()), this, SLOT (addCellsSubView())); world->addAction (cells); + + QAction *referenceables = new QAction (tr ("Referenceables"), this); + connect (referenceables, SIGNAL (triggered()), this, SLOT (addReferenceablesSubView())); + world->addAction (referenceables); + } void CSVDoc::View::setupUi() @@ -334,6 +339,11 @@ void CSVDoc::View::addCellsSubView() addSubView (CSMWorld::UniversalId::Type_Cells); } +void CSVDoc::View::addReferenceablesSubView() +{ + addSubView (CSMWorld::UniversalId::Type_Referenceables); +} + void CSVDoc::View::abortOperation (int type) { mDocument->abortOperation (type); diff --git a/apps/opencs/view/doc/view.hpp b/apps/opencs/view/doc/view.hpp index a240d3b01..9e1e94188 100644 --- a/apps/opencs/view/doc/view.hpp +++ b/apps/opencs/view/doc/view.hpp @@ -135,6 +135,8 @@ namespace CSVDoc void addSpellsSubView(); void addCellsSubView(); + + void addReferenceablesSubView(); }; } diff --git a/apps/opencs/view/world/subviews.cpp b/apps/opencs/view/world/subviews.cpp index 0ce3d3d6d..3d05f8860 100644 --- a/apps/opencs/view/world/subviews.cpp +++ b/apps/opencs/view/world/subviews.cpp @@ -27,6 +27,7 @@ void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager) CSMWorld::UniversalId::Type_Birthsigns, CSMWorld::UniversalId::Type_Spells, CSMWorld::UniversalId::Type_Cells, + CSMWorld::UniversalId::Type_Referenceables, CSMWorld::UniversalId::Type_None // end marker }; From d715cf5431dc9f15684d6199e6db59f704506399 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 11 May 2013 17:34:18 +0200 Subject: [PATCH 16/44] replaced static adapter with a template --- apps/opencs/model/world/refidadapterimp.cpp | 44 ------------- apps/opencs/model/world/refidadapterimp.hpp | 69 ++++++++++++++++++--- apps/opencs/model/world/refidcollection.cpp | 10 ++- apps/opencs/model/world/refidcollection.hpp | 3 +- 4 files changed, 72 insertions(+), 54 deletions(-) diff --git a/apps/opencs/model/world/refidadapterimp.cpp b/apps/opencs/model/world/refidadapterimp.cpp index 5038797dd..b24be3da5 100644 --- a/apps/opencs/model/world/refidadapterimp.cpp +++ b/apps/opencs/model/world/refidadapterimp.cpp @@ -1,49 +1,5 @@ #include "refidadapterimp.hpp" -#include -#include -#include "record.hpp" -#include "refiddata.hpp" -#include "universalid.hpp" - -CSMWorld::StaticRefIdAdapter::StaticRefIdAdapter (const RefIdColumn *id, const RefIdColumn *modified) -: mId (id), mModified (modified) -{} - -QVariant CSMWorld::StaticRefIdAdapter::getData (const RefIdColumn *column, const RefIdData& data, - int index) const -{ - const Record& record = static_cast&> ( - data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Static))); - - if (column==mId) - return QString::fromUtf8 (record.get().mId.c_str()); - - if (column==mModified) - { - if (record.mState==Record::State_Erased) - return static_cast (Record::State_Deleted); - - return static_cast (record.mState); - } - - return QVariant(); -} - -void CSMWorld::StaticRefIdAdapter::setData (const RefIdColumn *column, RefIdData& data, int index, - const QVariant& value) const -{ - Record& record = static_cast&> ( - data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Static))); - - if (column==mModified) - record.mState = static_cast (value.toInt()); -} - -std::string CSMWorld::StaticRefIdAdapter::getId (const RecordBase& record) const -{ - return dynamic_cast&> (record).get().mId; -} \ No newline at end of file diff --git a/apps/opencs/model/world/refidadapterimp.hpp b/apps/opencs/model/world/refidadapterimp.hpp index c130e2f73..021fe58a9 100644 --- a/apps/opencs/model/world/refidadapterimp.hpp +++ b/apps/opencs/model/world/refidadapterimp.hpp @@ -1,28 +1,83 @@ #ifndef CSM_WOLRD_REFIDADAPTERIMP_H #define CSM_WOLRD_REFIDADAPTERIMP_H +#include + +#include "record.hpp" +#include "refiddata.hpp" +#include "universalid.hpp" #include "refidadapter.hpp" namespace CSMWorld { - class StaticRefIdAdapter : public RefIdAdapter + struct BaseColumns { - const RefIdColumn *mId; - const RefIdColumn *mModified; + const RefIdColumn *mId; + const RefIdColumn *mModified; + }; + + template + class BaseRefIdAdapter : public RefIdAdapter + { + UniversalId::Type mType; + BaseColumns mBase; public: - StaticRefIdAdapter (const RefIdColumn *id, const RefIdColumn *modified); + BaseRefIdAdapter (UniversalId::Type type, const BaseColumns& base); - virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int idnex) + virtual std::string getId (const RecordBase& record) const; + + virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) const; virtual void setData (const RefIdColumn *column, RefIdData& data, int index, const QVariant& value) const; ///< If the data type does not match an exception is thrown. - - virtual std::string getId (const RecordBase& record) const; }; + + template + BaseRefIdAdapter::BaseRefIdAdapter (UniversalId::Type type, const BaseColumns& base) + : mType (type), mBase (base) + {} + + template + std::string BaseRefIdAdapter::getId (const RecordBase& record) const + { + return dynamic_cast&> (record).get().mId; + } + + template + QVariant BaseRefIdAdapter::getData (const RefIdColumn *column, const RefIdData& data, + int index) const + { + const Record& record = static_cast&> ( + data.getRecord (RefIdData::LocalIndex (index, mType))); + + if (column==mBase.mId) + return QString::fromUtf8 (record.get().mId.c_str()); + + if (column==mBase.mModified) + { + if (record.mState==Record::State_Erased) + return static_cast (Record::State_Deleted); + + return static_cast (record.mState); + } + + return QVariant(); + } + + template + void BaseRefIdAdapter::setData (const RefIdColumn *column, RefIdData& data, int index, + const QVariant& value) const + { + Record& record = static_cast&> ( + data.getRecord (RefIdData::LocalIndex (index, mType))); + + if (column==mBase.mModified) + record.mState = static_cast (value.toInt()); + } } #endif diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index 1312a44e3..c2969bf9c 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -34,14 +34,20 @@ const CSMWorld::RefIdAdapter& CSMWorld::RefIdCollection::findAdaptor (UniversalI CSMWorld::RefIdCollection::RefIdCollection() { + BaseColumns baseColumns; + mColumns.push_back (RefIdColumn ("ID", ColumnBase::Display_String, ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue, false, false)); + baseColumns.mId = &mColumns.back(); mColumns.push_back (RefIdColumn ("*", ColumnBase::Display_Integer, ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue, false, false)); + baseColumns.mModified = &mColumns.back(); // mColumns.push_back (RefIdColumn ("Name", ColumnBase::Display_String)); - mAdapters.insert (std::make_pair (UniversalId::Type_Static, new StaticRefIdAdapter (&mColumns[0], - &mColumns[1]))); + + + mAdapters.insert (std::make_pair (UniversalId::Type_Static, + new BaseRefIdAdapter (UniversalId::Type_Static, baseColumns))); } diff --git a/apps/opencs/model/world/refidcollection.hpp b/apps/opencs/model/world/refidcollection.hpp index 4f8096d25..a55ad38a4 100644 --- a/apps/opencs/model/world/refidcollection.hpp +++ b/apps/opencs/model/world/refidcollection.hpp @@ -3,6 +3,7 @@ #include #include +#include #include "columnbase.hpp" #include "idcollection.hpp" @@ -33,7 +34,7 @@ namespace CSMWorld private: RefIdData mData; - std::vector mColumns; + std::deque mColumns; std::map mAdapters; private: From c22f773f7231243d9e142a3c55122cfd875073e3 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 11 May 2013 17:45:28 +0200 Subject: [PATCH 17/44] load all types of referenceable IDs --- apps/opencs/model/world/data.cpp | 22 ++++++++++++ apps/opencs/model/world/refidcollection.cpp | 40 ++++++++++++++++++++- 2 files changed, 61 insertions(+), 1 deletion(-) diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index db6629aa0..1701e4289 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -327,7 +327,29 @@ void CSMWorld::Data::loadFile (const boost::filesystem::path& path, bool base) case ESM::REC_SPEL: mSpells.load (reader, base); break; case ESM::REC_CELL: mCells.load (reader, base); break; + case ESM::REC_ACTI: mReferenceables.load (reader, base, UniversalId::Type_Activator); break; + case ESM::REC_ALCH: mReferenceables.load (reader, base, UniversalId::Type_Potion); break; + case ESM::REC_APPA: mReferenceables.load (reader, base, UniversalId::Type_Apparatus); break; + case ESM::REC_ARMO: mReferenceables.load (reader, base, UniversalId::Type_Armor); break; + case ESM::REC_BOOK: mReferenceables.load (reader, base, UniversalId::Type_Book); break; + case ESM::REC_CLOT: mReferenceables.load (reader, base, UniversalId::Type_Clothing); break; + case ESM::REC_CONT: mReferenceables.load (reader, base, UniversalId::Type_Container); break; + case ESM::REC_CREA: mReferenceables.load (reader, base, UniversalId::Type_Creature); break; + case ESM::REC_DOOR: mReferenceables.load (reader, base, UniversalId::Type_Door); break; + case ESM::REC_INGR: mReferenceables.load (reader, base, UniversalId::Type_Ingredient); break; + case ESM::REC_LEVC: + mReferenceables.load (reader, base, UniversalId::Type_CreatureLevelledList); break; + case ESM::REC_LEVI: + mReferenceables.load (reader, base, UniversalId::Type_ItemLevelledList); break; + case ESM::REC_LIGH: mReferenceables.load (reader, base, UniversalId::Type_Light); break; + case ESM::REC_LOCK: mReferenceables.load (reader, base, UniversalId::Type_Lockpick); break; + case ESM::REC_MISC: + mReferenceables.load (reader, base, UniversalId::Type_Miscellaneous); break; + case ESM::REC_NPC_: mReferenceables.load (reader, base, UniversalId::Type_Npc); break; + case ESM::REC_PROB: mReferenceables.load (reader, base, UniversalId::Type_Probe); break; + case ESM::REC_REPA: mReferenceables.load (reader, base, UniversalId::Type_Repair); break; case ESM::REC_STAT: mReferenceables.load (reader, base, UniversalId::Type_Static); break; + case ESM::REC_WEAP: mReferenceables.load (reader, base, UniversalId::Type_Weapon); break; default: diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index c2969bf9c..18feb7424 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -46,9 +46,47 @@ CSMWorld::RefIdCollection::RefIdCollection() + mAdapters.insert (std::make_pair (UniversalId::Type_Activator, + new BaseRefIdAdapter (UniversalId::Type_Activator, baseColumns))); + mAdapters.insert (std::make_pair (UniversalId::Type_Potion, + new BaseRefIdAdapter (UniversalId::Type_Potion, baseColumns))); + mAdapters.insert (std::make_pair (UniversalId::Type_Apparatus, + new BaseRefIdAdapter (UniversalId::Type_Apparatus, baseColumns))); + mAdapters.insert (std::make_pair (UniversalId::Type_Armor, + new BaseRefIdAdapter (UniversalId::Type_Armor, baseColumns))); + mAdapters.insert (std::make_pair (UniversalId::Type_Book, + new BaseRefIdAdapter (UniversalId::Type_Book, baseColumns))); + mAdapters.insert (std::make_pair (UniversalId::Type_Clothing, + new BaseRefIdAdapter (UniversalId::Type_Clothing, baseColumns))); + mAdapters.insert (std::make_pair (UniversalId::Type_Container, + new BaseRefIdAdapter (UniversalId::Type_Container, baseColumns))); + mAdapters.insert (std::make_pair (UniversalId::Type_Creature, + new BaseRefIdAdapter (UniversalId::Type_Creature, baseColumns))); + mAdapters.insert (std::make_pair (UniversalId::Type_Door, + new BaseRefIdAdapter (UniversalId::Type_Door, baseColumns))); + mAdapters.insert (std::make_pair (UniversalId::Type_Ingredient, + new BaseRefIdAdapter (UniversalId::Type_Ingredient, baseColumns))); + mAdapters.insert (std::make_pair (UniversalId::Type_CreatureLevelledList, + new BaseRefIdAdapter ( + UniversalId::Type_CreatureLevelledList, baseColumns))); + mAdapters.insert (std::make_pair (UniversalId::Type_ItemLevelledList, + new BaseRefIdAdapter (UniversalId::Type_ItemLevelledList, baseColumns))); + mAdapters.insert (std::make_pair (UniversalId::Type_Light, + new BaseRefIdAdapter (UniversalId::Type_Light, baseColumns))); + mAdapters.insert (std::make_pair (UniversalId::Type_Lockpick, + new BaseRefIdAdapter (UniversalId::Type_Lockpick, baseColumns))); + mAdapters.insert (std::make_pair (UniversalId::Type_Miscellaneous, + new BaseRefIdAdapter (UniversalId::Type_Miscellaneous, baseColumns))); + mAdapters.insert (std::make_pair (UniversalId::Type_Npc, + new BaseRefIdAdapter (UniversalId::Type_Npc, baseColumns))); + mAdapters.insert (std::make_pair (UniversalId::Type_Probe, + new BaseRefIdAdapter (UniversalId::Type_Probe, baseColumns))); + mAdapters.insert (std::make_pair (UniversalId::Type_Repair, + new BaseRefIdAdapter (UniversalId::Type_Repair, baseColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Static, new BaseRefIdAdapter (UniversalId::Type_Static, baseColumns))); - + mAdapters.insert (std::make_pair (UniversalId::Type_Weapon, + new BaseRefIdAdapter (UniversalId::Type_Weapon, baseColumns))); } CSMWorld::RefIdCollection::~RefIdCollection() From 8ef2d040075352288625277a60f70cbb23fc8d32 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 11 May 2013 17:49:38 +0200 Subject: [PATCH 18/44] added type column --- apps/opencs/model/world/refidadapterimp.hpp | 4 ++++ apps/opencs/model/world/refidcollection.cpp | 3 +++ 2 files changed, 7 insertions(+) diff --git a/apps/opencs/model/world/refidadapterimp.hpp b/apps/opencs/model/world/refidadapterimp.hpp index 021fe58a9..814ac9023 100644 --- a/apps/opencs/model/world/refidadapterimp.hpp +++ b/apps/opencs/model/world/refidadapterimp.hpp @@ -14,6 +14,7 @@ namespace CSMWorld { const RefIdColumn *mId; const RefIdColumn *mModified; + const RefIdColumn *mType; }; template @@ -65,6 +66,9 @@ namespace CSMWorld return static_cast (record.mState); } + if (column==mBase.mType) + return static_cast (mType); + return QVariant(); } diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index 18feb7424..782b080c0 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -42,6 +42,9 @@ CSMWorld::RefIdCollection::RefIdCollection() mColumns.push_back (RefIdColumn ("*", ColumnBase::Display_Integer, ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue, false, false)); baseColumns.mModified = &mColumns.back(); + mColumns.push_back (RefIdColumn ("Type", ColumnBase::Display_Integer, + ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue, false, false)); + baseColumns.mType = &mColumns.back(); // mColumns.push_back (RefIdColumn ("Name", ColumnBase::Display_String)); From 318ebe0cb6c3bdfc49287ff140c4ec89ad017167 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 11 May 2013 18:35:48 +0200 Subject: [PATCH 19/44] added model column --- apps/opencs/model/world/record.hpp | 12 ++++ apps/opencs/model/world/refidadapterimp.hpp | 66 +++++++++++++++++++++ apps/opencs/model/world/refidcollection.cpp | 39 ++++++------ 3 files changed, 99 insertions(+), 18 deletions(-) diff --git a/apps/opencs/model/world/record.hpp b/apps/opencs/model/world/record.hpp index 853ed1559..861fc47a3 100644 --- a/apps/opencs/model/world/record.hpp +++ b/apps/opencs/model/world/record.hpp @@ -45,6 +45,9 @@ namespace CSMWorld const ESXRecordT& get() const; ///< Throws an exception, if the record is deleted. + ESXRecordT& get(); + ///< Throws an exception, if the record is deleted. + const ESXRecordT& getBase() const; ///< Throws an exception, if the record is deleted. Returns modified, if there is no base. @@ -76,6 +79,15 @@ namespace CSMWorld return mState==State_BaseOnly || mState==State_Deleted ? mBase : mModified; } + template + ESXRecordT& Record::get() + { + if (mState==State_Erased) + throw std::logic_error ("attempt to access a deleted record"); + + return mState==State_BaseOnly || mState==State_Deleted ? mBase : mModified; + } + template const ESXRecordT& Record::getBase() const { diff --git a/apps/opencs/model/world/refidadapterimp.hpp b/apps/opencs/model/world/refidadapterimp.hpp index 814ac9023..55aaa536e 100644 --- a/apps/opencs/model/world/refidadapterimp.hpp +++ b/apps/opencs/model/world/refidadapterimp.hpp @@ -17,6 +17,7 @@ namespace CSMWorld const RefIdColumn *mType; }; + /// \brief Base adapter for all refereceable record types template class BaseRefIdAdapter : public RefIdAdapter { @@ -35,6 +36,8 @@ namespace CSMWorld virtual void setData (const RefIdColumn *column, RefIdData& data, int index, const QVariant& value) const; ///< If the data type does not match an exception is thrown. + + UniversalId::Type getType() const; }; template @@ -82,6 +85,69 @@ namespace CSMWorld if (column==mBase.mModified) record.mState = static_cast (value.toInt()); } + + template + UniversalId::Type BaseRefIdAdapter::getType() const + { + return mType; + } + + + struct ModelColumns : public BaseColumns + { + const RefIdColumn *mModel; + + ModelColumns (const BaseColumns& base) : BaseColumns (base) {} + }; + + /// \brief Adapter for IDs with models (all but levelled lists) + template + class ModelRefIdAdapter : public BaseRefIdAdapter + { + ModelColumns mModel; + + public: + + ModelRefIdAdapter (UniversalId::Type type, const ModelColumns& columns); + + virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) + const; + + virtual void setData (const RefIdColumn *column, RefIdData& data, int index, + const QVariant& value) const; + ///< If the data type does not match an exception is thrown. + }; + + template + ModelRefIdAdapter::ModelRefIdAdapter (UniversalId::Type type, const ModelColumns& columns) + : BaseRefIdAdapter (type, columns), mModel (columns) + {} + + template + QVariant ModelRefIdAdapter::getData (const RefIdColumn *column, const RefIdData& data, + int index) const + { + const Record& record = static_cast&> ( + data.getRecord (RefIdData::LocalIndex (index, BaseRefIdAdapter::getType()))); + + if (column==mModel.mModel) + return QString::fromUtf8 (record.get().mModel.c_str()); + + return BaseRefIdAdapter::getData (column, data, index); + } + + template + void ModelRefIdAdapter::setData (const RefIdColumn *column, RefIdData& data, int index, + const QVariant& value) const + { + Record& record = static_cast&> ( + data.getRecord (RefIdData::LocalIndex (index, BaseRefIdAdapter::getType()))); + + if (column==mModel.mModel) + record.get().mModel = value.toString().toUtf8().constData(); + else + BaseRefIdAdapter::setData (column, data, index, value); + } } #endif diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index 782b080c0..9806f260f 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -47,49 +47,52 @@ CSMWorld::RefIdCollection::RefIdCollection() baseColumns.mType = &mColumns.back(); // mColumns.push_back (RefIdColumn ("Name", ColumnBase::Display_String)); + ModelColumns modelColumns (baseColumns); + mColumns.push_back (RefIdColumn ("Model", ColumnBase::Display_String)); + modelColumns.mModel = &mColumns.back(); mAdapters.insert (std::make_pair (UniversalId::Type_Activator, - new BaseRefIdAdapter (UniversalId::Type_Activator, baseColumns))); + new ModelRefIdAdapter (UniversalId::Type_Activator, modelColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Potion, - new BaseRefIdAdapter (UniversalId::Type_Potion, baseColumns))); + new ModelRefIdAdapter (UniversalId::Type_Potion, modelColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Apparatus, - new BaseRefIdAdapter (UniversalId::Type_Apparatus, baseColumns))); + new ModelRefIdAdapter (UniversalId::Type_Apparatus, modelColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Armor, - new BaseRefIdAdapter (UniversalId::Type_Armor, baseColumns))); + new ModelRefIdAdapter (UniversalId::Type_Armor, modelColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Book, - new BaseRefIdAdapter (UniversalId::Type_Book, baseColumns))); + new ModelRefIdAdapter (UniversalId::Type_Book, modelColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Clothing, - new BaseRefIdAdapter (UniversalId::Type_Clothing, baseColumns))); + new ModelRefIdAdapter (UniversalId::Type_Clothing, modelColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Container, - new BaseRefIdAdapter (UniversalId::Type_Container, baseColumns))); + new ModelRefIdAdapter (UniversalId::Type_Container, modelColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Creature, - new BaseRefIdAdapter (UniversalId::Type_Creature, baseColumns))); + new ModelRefIdAdapter (UniversalId::Type_Creature, modelColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Door, - new BaseRefIdAdapter (UniversalId::Type_Door, baseColumns))); + new ModelRefIdAdapter (UniversalId::Type_Door, modelColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Ingredient, - new BaseRefIdAdapter (UniversalId::Type_Ingredient, baseColumns))); + new ModelRefIdAdapter (UniversalId::Type_Ingredient, modelColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_CreatureLevelledList, new BaseRefIdAdapter ( UniversalId::Type_CreatureLevelledList, baseColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_ItemLevelledList, new BaseRefIdAdapter (UniversalId::Type_ItemLevelledList, baseColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Light, - new BaseRefIdAdapter (UniversalId::Type_Light, baseColumns))); + new ModelRefIdAdapter (UniversalId::Type_Light, modelColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Lockpick, - new BaseRefIdAdapter (UniversalId::Type_Lockpick, baseColumns))); + new ModelRefIdAdapter (UniversalId::Type_Lockpick, modelColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Miscellaneous, - new BaseRefIdAdapter (UniversalId::Type_Miscellaneous, baseColumns))); + new ModelRefIdAdapter (UniversalId::Type_Miscellaneous, modelColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Npc, - new BaseRefIdAdapter (UniversalId::Type_Npc, baseColumns))); + new ModelRefIdAdapter (UniversalId::Type_Npc, modelColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Probe, - new BaseRefIdAdapter (UniversalId::Type_Probe, baseColumns))); + new ModelRefIdAdapter (UniversalId::Type_Probe, modelColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Repair, - new BaseRefIdAdapter (UniversalId::Type_Repair, baseColumns))); + new ModelRefIdAdapter (UniversalId::Type_Repair, modelColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Static, - new BaseRefIdAdapter (UniversalId::Type_Static, baseColumns))); + new ModelRefIdAdapter (UniversalId::Type_Static, modelColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Weapon, - new BaseRefIdAdapter (UniversalId::Type_Weapon, baseColumns))); + new ModelRefIdAdapter (UniversalId::Type_Weapon, modelColumns))); } CSMWorld::RefIdCollection::~RefIdCollection() From e24ecfd5d26516d323caa05a4b9cc08fc83910bf Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 11 May 2013 18:43:01 +0200 Subject: [PATCH 20/44] added name column --- apps/opencs/model/world/refidadapterimp.hpp | 56 +++++++++++++++++++++ apps/opencs/model/world/refidcollection.cpp | 40 ++++++++------- 2 files changed, 78 insertions(+), 18 deletions(-) diff --git a/apps/opencs/model/world/refidadapterimp.hpp b/apps/opencs/model/world/refidadapterimp.hpp index 55aaa536e..1978ae838 100644 --- a/apps/opencs/model/world/refidadapterimp.hpp +++ b/apps/opencs/model/world/refidadapterimp.hpp @@ -148,6 +148,62 @@ namespace CSMWorld else BaseRefIdAdapter::setData (column, data, index, value); } + + struct NameColumns : public ModelColumns + { + const RefIdColumn *mName; + + NameColumns (const ModelColumns& base) : ModelColumns (base) {} + }; + + /// \brief Adapter for IDs with names (all but levelled lists and statics) + template + class NameRefIdAdapter : public ModelRefIdAdapter + { + NameColumns mName; + + public: + + NameRefIdAdapter (UniversalId::Type type, const NameColumns& columns); + + virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) + const; + + virtual void setData (const RefIdColumn *column, RefIdData& data, int index, + const QVariant& value) const; + ///< If the data type does not match an exception is thrown. + }; + + template + NameRefIdAdapter::NameRefIdAdapter (UniversalId::Type type, const NameColumns& columns) + : ModelRefIdAdapter (type, columns), mName (columns) + {} + + template + QVariant NameRefIdAdapter::getData (const RefIdColumn *column, const RefIdData& data, + int index) const + { + const Record& record = static_cast&> ( + data.getRecord (RefIdData::LocalIndex (index, BaseRefIdAdapter::getType()))); + + if (column==mName.mName) + return QString::fromUtf8 (record.get().mName.c_str()); + + return ModelRefIdAdapter::getData (column, data, index); + } + + template + void NameRefIdAdapter::setData (const RefIdColumn *column, RefIdData& data, int index, + const QVariant& value) const + { + Record& record = static_cast&> ( + data.getRecord (RefIdData::LocalIndex (index, BaseRefIdAdapter::getType()))); + + if (column==mName.mName) + record.get().mName = value.toString().toUtf8().constData(); + else + ModelRefIdAdapter::setData (column, data, index, value); + } } #endif diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index 9806f260f..9968532cb 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -45,54 +45,58 @@ CSMWorld::RefIdCollection::RefIdCollection() mColumns.push_back (RefIdColumn ("Type", ColumnBase::Display_Integer, ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue, false, false)); baseColumns.mType = &mColumns.back(); -// mColumns.push_back (RefIdColumn ("Name", ColumnBase::Display_String)); ModelColumns modelColumns (baseColumns); mColumns.push_back (RefIdColumn ("Model", ColumnBase::Display_String)); modelColumns.mModel = &mColumns.back(); + NameColumns nameColumns (modelColumns); + + mColumns.push_back (RefIdColumn ("Name", ColumnBase::Display_String)); + nameColumns.mName = &mColumns.back(); + mAdapters.insert (std::make_pair (UniversalId::Type_Activator, - new ModelRefIdAdapter (UniversalId::Type_Activator, modelColumns))); + new NameRefIdAdapter (UniversalId::Type_Activator, nameColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Potion, - new ModelRefIdAdapter (UniversalId::Type_Potion, modelColumns))); + new NameRefIdAdapter (UniversalId::Type_Potion, nameColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Apparatus, - new ModelRefIdAdapter (UniversalId::Type_Apparatus, modelColumns))); + new NameRefIdAdapter (UniversalId::Type_Apparatus, nameColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Armor, - new ModelRefIdAdapter (UniversalId::Type_Armor, modelColumns))); + new NameRefIdAdapter (UniversalId::Type_Armor, nameColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Book, - new ModelRefIdAdapter (UniversalId::Type_Book, modelColumns))); + new NameRefIdAdapter (UniversalId::Type_Book, nameColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Clothing, - new ModelRefIdAdapter (UniversalId::Type_Clothing, modelColumns))); + new NameRefIdAdapter (UniversalId::Type_Clothing, nameColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Container, - new ModelRefIdAdapter (UniversalId::Type_Container, modelColumns))); + new NameRefIdAdapter (UniversalId::Type_Container, nameColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Creature, - new ModelRefIdAdapter (UniversalId::Type_Creature, modelColumns))); + new NameRefIdAdapter (UniversalId::Type_Creature, nameColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Door, - new ModelRefIdAdapter (UniversalId::Type_Door, modelColumns))); + new NameRefIdAdapter (UniversalId::Type_Door, nameColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Ingredient, - new ModelRefIdAdapter (UniversalId::Type_Ingredient, modelColumns))); + new NameRefIdAdapter (UniversalId::Type_Ingredient, nameColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_CreatureLevelledList, new BaseRefIdAdapter ( UniversalId::Type_CreatureLevelledList, baseColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_ItemLevelledList, new BaseRefIdAdapter (UniversalId::Type_ItemLevelledList, baseColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Light, - new ModelRefIdAdapter (UniversalId::Type_Light, modelColumns))); + new NameRefIdAdapter (UniversalId::Type_Light, nameColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Lockpick, - new ModelRefIdAdapter (UniversalId::Type_Lockpick, modelColumns))); + new NameRefIdAdapter (UniversalId::Type_Lockpick, nameColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Miscellaneous, - new ModelRefIdAdapter (UniversalId::Type_Miscellaneous, modelColumns))); + new NameRefIdAdapter (UniversalId::Type_Miscellaneous, nameColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Npc, - new ModelRefIdAdapter (UniversalId::Type_Npc, modelColumns))); + new NameRefIdAdapter (UniversalId::Type_Npc, nameColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Probe, - new ModelRefIdAdapter (UniversalId::Type_Probe, modelColumns))); + new NameRefIdAdapter (UniversalId::Type_Probe, nameColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Repair, - new ModelRefIdAdapter (UniversalId::Type_Repair, modelColumns))); + new NameRefIdAdapter (UniversalId::Type_Repair, nameColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Static, new ModelRefIdAdapter (UniversalId::Type_Static, modelColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Weapon, - new ModelRefIdAdapter (UniversalId::Type_Weapon, modelColumns))); + new NameRefIdAdapter (UniversalId::Type_Weapon, nameColumns))); } CSMWorld::RefIdCollection::~RefIdCollection() From ee2bc94698bd46e3ed64fe3be748ebd1acef8753 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 11 May 2013 18:57:23 +0200 Subject: [PATCH 21/44] added script column --- apps/opencs/model/world/refidadapterimp.hpp | 6 ++++++ apps/opencs/model/world/refidcollection.cpp | 2 ++ 2 files changed, 8 insertions(+) diff --git a/apps/opencs/model/world/refidadapterimp.hpp b/apps/opencs/model/world/refidadapterimp.hpp index 1978ae838..78a363bef 100644 --- a/apps/opencs/model/world/refidadapterimp.hpp +++ b/apps/opencs/model/world/refidadapterimp.hpp @@ -152,6 +152,7 @@ namespace CSMWorld struct NameColumns : public ModelColumns { const RefIdColumn *mName; + const RefIdColumn *mScript; NameColumns (const ModelColumns& base) : ModelColumns (base) {} }; @@ -189,6 +190,9 @@ namespace CSMWorld if (column==mName.mName) return QString::fromUtf8 (record.get().mName.c_str()); + if (column==mName.mScript) + return QString::fromUtf8 (record.get().mScript.c_str()); + return ModelRefIdAdapter::getData (column, data, index); } @@ -201,6 +205,8 @@ namespace CSMWorld if (column==mName.mName) record.get().mName = value.toString().toUtf8().constData(); + else if (column==mName.mScript) + record.get().mScript = value.toString().toUtf8().constData(); else ModelRefIdAdapter::setData (column, data, index, value); } diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index 9968532cb..31055a439 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -55,6 +55,8 @@ CSMWorld::RefIdCollection::RefIdCollection() mColumns.push_back (RefIdColumn ("Name", ColumnBase::Display_String)); nameColumns.mName = &mColumns.back(); + mColumns.push_back (RefIdColumn ("Script", ColumnBase::Display_String)); + nameColumns.mScript = &mColumns.back(); mAdapters.insert (std::make_pair (UniversalId::Type_Activator, new NameRefIdAdapter (UniversalId::Type_Activator, nameColumns))); From da929213872e0e9901fd1df1dfc57f8e8fd379c2 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 11 May 2013 19:21:16 +0200 Subject: [PATCH 22/44] added columns related to items in inventories --- apps/opencs/model/world/refidadapterimp.hpp | 69 +++++++++++++++++++++ apps/opencs/model/world/refidcollection.cpp | 34 ++++++---- 2 files changed, 91 insertions(+), 12 deletions(-) diff --git a/apps/opencs/model/world/refidadapterimp.hpp b/apps/opencs/model/world/refidadapterimp.hpp index 78a363bef..4ceb01336 100644 --- a/apps/opencs/model/world/refidadapterimp.hpp +++ b/apps/opencs/model/world/refidadapterimp.hpp @@ -210,6 +210,75 @@ namespace CSMWorld else ModelRefIdAdapter::setData (column, data, index, value); } + + struct InventoryColumns : public NameColumns + { + const RefIdColumn *mIcon; + const RefIdColumn *mWeight; + const RefIdColumn *mValue; + + InventoryColumns (const NameColumns& base) : NameColumns (base) {} + }; + + /// \brief Adapter for IDs with names (all but levelled lists and statics) + template + class InventoryRefIdAdapter : public NameRefIdAdapter + { + InventoryColumns mName; + + public: + + InventoryRefIdAdapter (UniversalId::Type type, const InventoryColumns& columns); + + virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) + const; + + virtual void setData (const RefIdColumn *column, RefIdData& data, int index, + const QVariant& value) const; + ///< If the data type does not match an exception is thrown. + }; + + template + InventoryRefIdAdapter::InventoryRefIdAdapter (UniversalId::Type type, + const InventoryColumns& columns) + : NameRefIdAdapter (type, columns), mName (columns) + {} + + template + QVariant InventoryRefIdAdapter::getData (const RefIdColumn *column, const RefIdData& data, + int index) const + { + const Record& record = static_cast&> ( + data.getRecord (RefIdData::LocalIndex (index, BaseRefIdAdapter::getType()))); + + if (column==mName.mIcon) + return QString::fromUtf8 (record.get().mIcon.c_str()); + + if (column==mName.mWeight) + return record.get().mData.mWeight; + + if (column==mName.mValue) + return record.get().mData.mValue; + + return NameRefIdAdapter::getData (column, data, index); + } + + template + void InventoryRefIdAdapter::setData (const RefIdColumn *column, RefIdData& data, int index, + const QVariant& value) const + { + Record& record = static_cast&> ( + data.getRecord (RefIdData::LocalIndex (index, BaseRefIdAdapter::getType()))); + + if (column==mName.mIcon) + record.get().mIcon = value.toString().toUtf8().constData(); + else if (column==mName.mWeight) + record.get().mData.mWeight = value.toFloat(); + else if (column==mName.mValue) + record.get().mData.mValue = value.toInt(); + else + NameRefIdAdapter::setData (column, data, index, value); + } } #endif diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index 31055a439..5bfbb022d 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -58,18 +58,27 @@ CSMWorld::RefIdCollection::RefIdCollection() mColumns.push_back (RefIdColumn ("Script", ColumnBase::Display_String)); nameColumns.mScript = &mColumns.back(); + InventoryColumns inventoryColumns (nameColumns); + + mColumns.push_back (RefIdColumn ("Icon", ColumnBase::Display_String)); + inventoryColumns.mIcon = &mColumns.back(); + mColumns.push_back (RefIdColumn ("Weight", ColumnBase::Display_Float)); + inventoryColumns.mWeight = &mColumns.back(); + mColumns.push_back (RefIdColumn ("Value", ColumnBase::Display_Integer)); + inventoryColumns.mValue = &mColumns.back(); + mAdapters.insert (std::make_pair (UniversalId::Type_Activator, new NameRefIdAdapter (UniversalId::Type_Activator, nameColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Potion, - new NameRefIdAdapter (UniversalId::Type_Potion, nameColumns))); + new InventoryRefIdAdapter (UniversalId::Type_Potion, inventoryColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Apparatus, - new NameRefIdAdapter (UniversalId::Type_Apparatus, nameColumns))); + new InventoryRefIdAdapter (UniversalId::Type_Apparatus, inventoryColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Armor, - new NameRefIdAdapter (UniversalId::Type_Armor, nameColumns))); + new InventoryRefIdAdapter (UniversalId::Type_Armor, inventoryColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Book, - new NameRefIdAdapter (UniversalId::Type_Book, nameColumns))); + new InventoryRefIdAdapter (UniversalId::Type_Book, inventoryColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Clothing, - new NameRefIdAdapter (UniversalId::Type_Clothing, nameColumns))); + new InventoryRefIdAdapter (UniversalId::Type_Clothing, inventoryColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Container, new NameRefIdAdapter (UniversalId::Type_Container, nameColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Creature, @@ -77,28 +86,29 @@ CSMWorld::RefIdCollection::RefIdCollection() mAdapters.insert (std::make_pair (UniversalId::Type_Door, new NameRefIdAdapter (UniversalId::Type_Door, nameColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Ingredient, - new NameRefIdAdapter (UniversalId::Type_Ingredient, nameColumns))); + new InventoryRefIdAdapter (UniversalId::Type_Ingredient, inventoryColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_CreatureLevelledList, new BaseRefIdAdapter ( UniversalId::Type_CreatureLevelledList, baseColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_ItemLevelledList, new BaseRefIdAdapter (UniversalId::Type_ItemLevelledList, baseColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Light, - new NameRefIdAdapter (UniversalId::Type_Light, nameColumns))); + new InventoryRefIdAdapter (UniversalId::Type_Light, inventoryColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Lockpick, - new NameRefIdAdapter (UniversalId::Type_Lockpick, nameColumns))); + new InventoryRefIdAdapter (UniversalId::Type_Lockpick, inventoryColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Miscellaneous, - new NameRefIdAdapter (UniversalId::Type_Miscellaneous, nameColumns))); + new InventoryRefIdAdapter (UniversalId::Type_Miscellaneous, + inventoryColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Npc, new NameRefIdAdapter (UniversalId::Type_Npc, nameColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Probe, - new NameRefIdAdapter (UniversalId::Type_Probe, nameColumns))); + new InventoryRefIdAdapter (UniversalId::Type_Probe, inventoryColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Repair, - new NameRefIdAdapter (UniversalId::Type_Repair, nameColumns))); + new InventoryRefIdAdapter (UniversalId::Type_Repair, inventoryColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Static, new ModelRefIdAdapter (UniversalId::Type_Static, modelColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Weapon, - new NameRefIdAdapter (UniversalId::Type_Weapon, nameColumns))); + new InventoryRefIdAdapter (UniversalId::Type_Weapon, inventoryColumns))); } CSMWorld::RefIdCollection::~RefIdCollection() From 7fd277b87ab8bb8d7ed6e0094c802ebc707715ed Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 12 May 2013 15:50:29 +0200 Subject: [PATCH 23/44] added missing column for potions --- apps/opencs/model/world/refidadapterimp.cpp | 27 +++++++++++++++++++++ apps/opencs/model/world/refidadapterimp.hpp | 18 ++++++++++++++ apps/opencs/model/world/refidcollection.cpp | 5 +++- 3 files changed, 49 insertions(+), 1 deletion(-) diff --git a/apps/opencs/model/world/refidadapterimp.cpp b/apps/opencs/model/world/refidadapterimp.cpp index b24be3da5..783d9ba41 100644 --- a/apps/opencs/model/world/refidadapterimp.cpp +++ b/apps/opencs/model/world/refidadapterimp.cpp @@ -1,5 +1,32 @@ #include "refidadapterimp.hpp" +CSMWorld::PotionRefIdAdapter::PotionRefIdAdapter (const InventoryColumns& columns, + const RefIdColumn *autoCalc) +: InventoryRefIdAdapter (UniversalId::Type_Potion, columns), + mAutoCalc (autoCalc) +{} +QVariant CSMWorld::PotionRefIdAdapter::getData (const RefIdColumn *column, const RefIdData& data, + int index) const +{ + const Record& record = static_cast&> ( + data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Potion))); + if (column==mAutoCalc) + return record.get().mData.mAutoCalc; + + return InventoryRefIdAdapter::getData (column, data, index); +} + +void CSMWorld::PotionRefIdAdapter::setData (const RefIdColumn *column, RefIdData& data, int index, + const QVariant& value) const +{ + Record& record = static_cast&> ( + data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Potion))); + + if (column==mAutoCalc) + record.get().mData.mAutoCalc = value.toInt(); + else + InventoryRefIdAdapter::setData (column, data, index, value); +} \ No newline at end of file diff --git a/apps/opencs/model/world/refidadapterimp.hpp b/apps/opencs/model/world/refidadapterimp.hpp index 4ceb01336..e6bfcab8a 100644 --- a/apps/opencs/model/world/refidadapterimp.hpp +++ b/apps/opencs/model/world/refidadapterimp.hpp @@ -3,6 +3,8 @@ #include +#include + #include "record.hpp" #include "refiddata.hpp" #include "universalid.hpp" @@ -279,6 +281,22 @@ namespace CSMWorld else NameRefIdAdapter::setData (column, data, index, value); } + + class PotionRefIdAdapter : public InventoryRefIdAdapter + { + const RefIdColumn *mAutoCalc; + + public: + + PotionRefIdAdapter (const InventoryColumns& columns, const RefIdColumn *autoCalc); + + virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) + const; + + virtual void setData (const RefIdColumn *column, RefIdData& data, int index, + const QVariant& value) const; + ///< If the data type does not match an exception is thrown. + }; } #endif diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index 5bfbb022d..cc0d390d5 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -67,10 +67,13 @@ CSMWorld::RefIdCollection::RefIdCollection() mColumns.push_back (RefIdColumn ("Value", ColumnBase::Display_Integer)); inventoryColumns.mValue = &mColumns.back(); + mColumns.push_back (RefIdColumn ("Auto Calc", ColumnBase::Display_Boolean)); + const RefIdColumn *autoCalc = &mColumns.back(); + mAdapters.insert (std::make_pair (UniversalId::Type_Activator, new NameRefIdAdapter (UniversalId::Type_Activator, nameColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Potion, - new InventoryRefIdAdapter (UniversalId::Type_Potion, inventoryColumns))); + new PotionRefIdAdapter (inventoryColumns, autoCalc))); mAdapters.insert (std::make_pair (UniversalId::Type_Apparatus, new InventoryRefIdAdapter (UniversalId::Type_Apparatus, inventoryColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Armor, From 929b38ff6a06707a48770ee95e81c63f36c4a0e8 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 13 May 2013 12:51:27 +0200 Subject: [PATCH 24/44] added missing columns for apparati records --- apps/opencs/model/world/columnbase.hpp | 3 +- apps/opencs/model/world/refidadapterimp.cpp | 36 +++++++++++++++++++++ apps/opencs/model/world/refidadapterimp.hpp | 19 +++++++++++ apps/opencs/model/world/refidcollection.cpp | 8 ++++- apps/opencs/view/doc/viewmanager.cpp | 8 +++++ apps/opencs/view/world/enumdelegate.cpp | 26 +++++++++------ 6 files changed, 88 insertions(+), 12 deletions(-) diff --git a/apps/opencs/model/world/columnbase.hpp b/apps/opencs/model/world/columnbase.hpp index fea618037..3dc41f737 100644 --- a/apps/opencs/model/world/columnbase.hpp +++ b/apps/opencs/model/world/columnbase.hpp @@ -36,7 +36,8 @@ namespace CSMWorld Display_Attribute, Display_Boolean, Display_SpellType, - Display_Script + Display_Script, + Display_ApparatusType }; std::string mTitle; diff --git a/apps/opencs/model/world/refidadapterimp.cpp b/apps/opencs/model/world/refidadapterimp.cpp index 783d9ba41..eb68468de 100644 --- a/apps/opencs/model/world/refidadapterimp.cpp +++ b/apps/opencs/model/world/refidadapterimp.cpp @@ -29,4 +29,40 @@ void CSMWorld::PotionRefIdAdapter::setData (const RefIdColumn *column, RefIdData record.get().mData.mAutoCalc = value.toInt(); else InventoryRefIdAdapter::setData (column, data, index, value); +} + + +CSMWorld::ApparatusRefIdAdapter::ApparatusRefIdAdapter (const InventoryColumns& columns, + const RefIdColumn *type, const RefIdColumn *quality) +: InventoryRefIdAdapter (UniversalId::Type_Apparatus, columns), + mType (type), mQuality (quality) +{} + +QVariant CSMWorld::ApparatusRefIdAdapter::getData (const RefIdColumn *column, + const RefIdData& data, int index) const +{ + const Record& record = static_cast&> ( + data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Apparatus))); + + if (column==mType) + return record.get().mData.mType; + + if (column==mQuality) + return record.get().mData.mQuality; + + return InventoryRefIdAdapter::getData (column, data, index); +} + +void CSMWorld::ApparatusRefIdAdapter::setData (const RefIdColumn *column, RefIdData& data, int index, + const QVariant& value) const +{ + Record& record = static_cast&> ( + data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Apparatus))); + + if (column==mType) + record.get().mData.mType = value.toInt(); + else if (column==mQuality) + record.get().mData.mQuality = value.toFloat(); + else + InventoryRefIdAdapter::setData (column, data, index, value); } \ No newline at end of file diff --git a/apps/opencs/model/world/refidadapterimp.hpp b/apps/opencs/model/world/refidadapterimp.hpp index e6bfcab8a..fc641e2af 100644 --- a/apps/opencs/model/world/refidadapterimp.hpp +++ b/apps/opencs/model/world/refidadapterimp.hpp @@ -4,6 +4,7 @@ #include #include +#include #include "record.hpp" #include "refiddata.hpp" @@ -297,6 +298,24 @@ namespace CSMWorld const QVariant& value) const; ///< If the data type does not match an exception is thrown. }; + + class ApparatusRefIdAdapter : public InventoryRefIdAdapter + { + const RefIdColumn *mType; + const RefIdColumn *mQuality; + + public: + + ApparatusRefIdAdapter (const InventoryColumns& columns, const RefIdColumn *type, + const RefIdColumn *quality); + + virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) + const; + + virtual void setData (const RefIdColumn *column, RefIdData& data, int index, + const QVariant& value) const; + ///< If the data type does not match an exception is thrown. + }; } #endif diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index cc0d390d5..bc18f90ae 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -70,12 +70,18 @@ CSMWorld::RefIdCollection::RefIdCollection() mColumns.push_back (RefIdColumn ("Auto Calc", ColumnBase::Display_Boolean)); const RefIdColumn *autoCalc = &mColumns.back(); + mColumns.push_back (RefIdColumn ("Apparatus Type", ColumnBase::Display_ApparatusType)); + const RefIdColumn *apparatusType = &mColumns.back(); + + mColumns.push_back (RefIdColumn ("Quality", ColumnBase::Display_Float)); + const RefIdColumn *quality = &mColumns.back(); + mAdapters.insert (std::make_pair (UniversalId::Type_Activator, new NameRefIdAdapter (UniversalId::Type_Activator, nameColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Potion, new PotionRefIdAdapter (inventoryColumns, autoCalc))); mAdapters.insert (std::make_pair (UniversalId::Type_Apparatus, - new InventoryRefIdAdapter (UniversalId::Type_Apparatus, inventoryColumns))); + new ApparatusRefIdAdapter (inventoryColumns, apparatusType, quality))); mAdapters.insert (std::make_pair (UniversalId::Type_Armor, new InventoryRefIdAdapter (UniversalId::Type_Armor, inventoryColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Book, diff --git a/apps/opencs/view/doc/viewmanager.cpp b/apps/opencs/view/doc/viewmanager.cpp index 050bd51fe..182d87dc6 100644 --- a/apps/opencs/view/doc/viewmanager.cpp +++ b/apps/opencs/view/doc/viewmanager.cpp @@ -54,6 +54,11 @@ CSVDoc::ViewManager::ViewManager (CSMDoc::DocumentManager& documentManager) "Spell", "Ability", "Blight", "Disease", "Curse", "Power", 0 }; + static const char *sApparatusTypes[] = + { + "Mortar & Pestle", "Albemic", "Calcinator", "Retort", 0 + }; + mDelegateFactories = new CSVWorld::CommandDelegateFactoryCollection; mDelegateFactories->add (CSMWorld::ColumnBase::Display_GmstVarType, @@ -70,6 +75,9 @@ CSVDoc::ViewManager::ViewManager (CSMDoc::DocumentManager& documentManager) mDelegateFactories->add (CSMWorld::ColumnBase::Display_SpellType, new CSVWorld::EnumDelegateFactory (sSpellTypes)); + + mDelegateFactories->add (CSMWorld::ColumnBase::Display_ApparatusType, + new CSVWorld::EnumDelegateFactory (sApparatusTypes)); } CSVDoc::ViewManager::~ViewManager() diff --git a/apps/opencs/view/world/enumdelegate.cpp b/apps/opencs/view/world/enumdelegate.cpp index b1e9f7286..dd194abe9 100644 --- a/apps/opencs/view/world/enumdelegate.cpp +++ b/apps/opencs/view/world/enumdelegate.cpp @@ -44,6 +44,9 @@ CSVWorld::EnumDelegate::EnumDelegate (const std::vector QWidget *CSVWorld::EnumDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem& option, const QModelIndex& index) const { + if (!index.data().isValid()) + return 0; + QComboBox *comboBox = new QComboBox (parent); for (std::vector >::const_iterator iter (mValues.begin()); @@ -73,20 +76,23 @@ void CSVWorld::EnumDelegate::setEditorData (QWidget *editor, const QModelIndex& void CSVWorld::EnumDelegate::paint (QPainter *painter, const QStyleOptionViewItem& option, const QModelIndex& index) const { - QStyleOptionViewItemV4 option2 (option); + if (index.data().isValid()) + { + QStyleOptionViewItemV4 option2 (option); - int value = index.data().toInt(); + int value = index.data().toInt(); - for (std::vector >::const_iterator iter (mValues.begin()); - iter!=mValues.end(); ++iter) - if (iter->first==value) - { - option2.text = iter->second; + for (std::vector >::const_iterator iter (mValues.begin()); + iter!=mValues.end(); ++iter) + if (iter->first==value) + { + option2.text = iter->second; - QApplication::style()->drawControl (QStyle::CE_ItemViewItem, &option2, painter); + QApplication::style()->drawControl (QStyle::CE_ItemViewItem, &option2, painter); - break; - } + break; + } + } } From 90bae2bead10ec4f872c26d40e83a1e8cb62da4a Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 13 May 2013 12:55:28 +0200 Subject: [PATCH 25/44] do not create editors for unused columns --- apps/opencs/view/world/util.cpp | 10 ++++++++++ apps/opencs/view/world/util.hpp | 3 +++ 2 files changed, 13 insertions(+) diff --git a/apps/opencs/view/world/util.cpp b/apps/opencs/view/world/util.cpp index 5ada1d84f..5bbedbf3d 100644 --- a/apps/opencs/view/world/util.cpp +++ b/apps/opencs/view/world/util.cpp @@ -116,6 +116,16 @@ void CSVWorld::CommandDelegate::setModelData (QWidget *editor, QAbstractItemMode ///< \todo provide some kind of feedback to the user, indicating that editing is currently not possible. } +QWidget *CSVWorld::CommandDelegate::createEditor (QWidget *parent, const QStyleOptionViewItem& option, + const QModelIndex& index) const +{ + if (!index.data().isValid()) + return 0; + + return QStyledItemDelegate::createEditor (parent, option, index); +} + + void CSVWorld::CommandDelegate::setEditLock (bool locked) { mEditLock = locked; diff --git a/apps/opencs/view/world/util.hpp b/apps/opencs/view/world/util.hpp index 5334abf9c..95dfec6c5 100644 --- a/apps/opencs/view/world/util.hpp +++ b/apps/opencs/view/world/util.hpp @@ -99,6 +99,9 @@ namespace CSVWorld virtual void setModelData (QWidget *editor, QAbstractItemModel *model, const QModelIndex& index) const; + virtual QWidget *createEditor (QWidget *parent, const QStyleOptionViewItem& option, + const QModelIndex& index) const; + void setEditLock (bool locked); bool isEditLocked() const; From 52d81dc9fa9170d2d39d10c088c90513bf610ba2 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 13 May 2013 13:11:43 +0200 Subject: [PATCH 26/44] added columns for enchantments --- apps/opencs/model/world/refidadapterimp.hpp | 81 ++++++++++++++++++--- apps/opencs/model/world/refidcollection.cpp | 15 +++- 2 files changed, 83 insertions(+), 13 deletions(-) diff --git a/apps/opencs/model/world/refidadapterimp.hpp b/apps/opencs/model/world/refidadapterimp.hpp index fc641e2af..4eac0fa4b 100644 --- a/apps/opencs/model/world/refidadapterimp.hpp +++ b/apps/opencs/model/world/refidadapterimp.hpp @@ -223,11 +223,11 @@ namespace CSMWorld InventoryColumns (const NameColumns& base) : NameColumns (base) {} }; - /// \brief Adapter for IDs with names (all but levelled lists and statics) + /// \brief Adapter for IDs that can go into an inventory template class InventoryRefIdAdapter : public NameRefIdAdapter { - InventoryColumns mName; + InventoryColumns mInventory; public: @@ -244,7 +244,7 @@ namespace CSMWorld template InventoryRefIdAdapter::InventoryRefIdAdapter (UniversalId::Type type, const InventoryColumns& columns) - : NameRefIdAdapter (type, columns), mName (columns) + : NameRefIdAdapter (type, columns), mInventory (columns) {} template @@ -254,13 +254,13 @@ namespace CSMWorld const Record& record = static_cast&> ( data.getRecord (RefIdData::LocalIndex (index, BaseRefIdAdapter::getType()))); - if (column==mName.mIcon) + if (column==mInventory.mIcon) return QString::fromUtf8 (record.get().mIcon.c_str()); - if (column==mName.mWeight) + if (column==mInventory.mWeight) return record.get().mData.mWeight; - if (column==mName.mValue) + if (column==mInventory.mValue) return record.get().mData.mValue; return NameRefIdAdapter::getData (column, data, index); @@ -273,11 +273,11 @@ namespace CSMWorld Record& record = static_cast&> ( data.getRecord (RefIdData::LocalIndex (index, BaseRefIdAdapter::getType()))); - if (column==mName.mIcon) + if (column==mInventory.mIcon) record.get().mIcon = value.toString().toUtf8().constData(); - else if (column==mName.mWeight) + else if (column==mInventory.mWeight) record.get().mData.mWeight = value.toFloat(); - else if (column==mName.mValue) + else if (column==mInventory.mValue) record.get().mData.mValue = value.toInt(); else NameRefIdAdapter::setData (column, data, index, value); @@ -299,6 +299,69 @@ namespace CSMWorld ///< If the data type does not match an exception is thrown. }; + struct EnchantableColumns : public InventoryColumns + { + const RefIdColumn *mEnchantment; + const RefIdColumn *mEnchantmentPoints; + + EnchantableColumns (const InventoryColumns& base) : InventoryColumns (base) {} + }; + + /// \brief Adapter for enchantable IDs + template + class EnchantableRefIdAdapter : public InventoryRefIdAdapter + { + EnchantableColumns mEnchantable; + + public: + + EnchantableRefIdAdapter (UniversalId::Type type, const EnchantableColumns& columns); + + virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) + const; + + virtual void setData (const RefIdColumn *column, RefIdData& data, int index, + const QVariant& value) const; + ///< If the data type does not match an exception is thrown. + }; + + template + EnchantableRefIdAdapter::EnchantableRefIdAdapter (UniversalId::Type type, + const EnchantableColumns& columns) + : InventoryRefIdAdapter (type, columns), mEnchantable (columns) + {} + + template + QVariant EnchantableRefIdAdapter::getData (const RefIdColumn *column, const RefIdData& data, + int index) const + { + const Record& record = static_cast&> ( + data.getRecord (RefIdData::LocalIndex (index, BaseRefIdAdapter::getType()))); + + if (column==mEnchantable.mEnchantment) + return QString::fromUtf8 (record.get().mEnchant.c_str()); + + if (column==mEnchantable.mEnchantmentPoints) + return static_cast (record.get().mData.mEnchant); + + return InventoryRefIdAdapter::getData (column, data, index); + } + + template + void EnchantableRefIdAdapter::setData (const RefIdColumn *column, RefIdData& data, + int index, const QVariant& value) const + { + Record& record = static_cast&> ( + data.getRecord (RefIdData::LocalIndex (index, BaseRefIdAdapter::getType()))); + + if (column==mEnchantable.mEnchantment) + record.get().mEnchant = value.toString().toUtf8().constData(); + else if (column==mEnchantable.mEnchantmentPoints) + record.get().mData.mEnchant = value.toInt(); + else + InventoryRefIdAdapter::setData (column, data, index, value); + } + class ApparatusRefIdAdapter : public InventoryRefIdAdapter { const RefIdColumn *mType; diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index bc18f90ae..8ed927c70 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -67,6 +67,13 @@ CSMWorld::RefIdCollection::RefIdCollection() mColumns.push_back (RefIdColumn ("Value", ColumnBase::Display_Integer)); inventoryColumns.mValue = &mColumns.back(); + EnchantableColumns enchantableColumns (inventoryColumns); + + mColumns.push_back (RefIdColumn ("Enchantment", ColumnBase::Display_String)); + enchantableColumns.mEnchantment = &mColumns.back(); + mColumns.push_back (RefIdColumn ("Enchantment Points", ColumnBase::Display_Integer)); + enchantableColumns.mEnchantmentPoints = &mColumns.back(); + mColumns.push_back (RefIdColumn ("Auto Calc", ColumnBase::Display_Boolean)); const RefIdColumn *autoCalc = &mColumns.back(); @@ -83,11 +90,11 @@ CSMWorld::RefIdCollection::RefIdCollection() mAdapters.insert (std::make_pair (UniversalId::Type_Apparatus, new ApparatusRefIdAdapter (inventoryColumns, apparatusType, quality))); mAdapters.insert (std::make_pair (UniversalId::Type_Armor, - new InventoryRefIdAdapter (UniversalId::Type_Armor, inventoryColumns))); + new EnchantableRefIdAdapter (UniversalId::Type_Armor, enchantableColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Book, - new InventoryRefIdAdapter (UniversalId::Type_Book, inventoryColumns))); + new EnchantableRefIdAdapter (UniversalId::Type_Book, enchantableColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Clothing, - new InventoryRefIdAdapter (UniversalId::Type_Clothing, inventoryColumns))); + new EnchantableRefIdAdapter (UniversalId::Type_Clothing, enchantableColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Container, new NameRefIdAdapter (UniversalId::Type_Container, nameColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Creature, @@ -117,7 +124,7 @@ CSMWorld::RefIdCollection::RefIdCollection() mAdapters.insert (std::make_pair (UniversalId::Type_Static, new ModelRefIdAdapter (UniversalId::Type_Static, modelColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Weapon, - new InventoryRefIdAdapter (UniversalId::Type_Weapon, inventoryColumns))); + new EnchantableRefIdAdapter (UniversalId::Type_Weapon, enchantableColumns))); } CSMWorld::RefIdCollection::~RefIdCollection() From 897e55391de4032cbbfcf392f148bbac07d3a3da Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 13 May 2013 13:36:24 +0200 Subject: [PATCH 27/44] added columns for tool IDs --- apps/opencs/model/world/refidadapterimp.hpp | 62 +++++++++++++++++++++ apps/opencs/model/world/refidcollection.cpp | 18 +++--- 2 files changed, 73 insertions(+), 7 deletions(-) diff --git a/apps/opencs/model/world/refidadapterimp.hpp b/apps/opencs/model/world/refidadapterimp.hpp index 4eac0fa4b..8fc16af63 100644 --- a/apps/opencs/model/world/refidadapterimp.hpp +++ b/apps/opencs/model/world/refidadapterimp.hpp @@ -362,6 +362,68 @@ namespace CSMWorld InventoryRefIdAdapter::setData (column, data, index, value); } + struct ToolColumns : public InventoryColumns + { + const RefIdColumn *mQuality; + const RefIdColumn *mUses; + + ToolColumns (const InventoryColumns& base) : InventoryColumns (base) {} + }; + + /// \brief Adapter for tools with limited uses IDs (lockpick, repair, probes) + template + class ToolRefIdAdapter : public InventoryRefIdAdapter + { + ToolColumns mTools; + + public: + + ToolRefIdAdapter (UniversalId::Type type, const ToolColumns& columns); + + virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) + const; + + virtual void setData (const RefIdColumn *column, RefIdData& data, int index, + const QVariant& value) const; + ///< If the data type does not match an exception is thrown. + }; + + template + ToolRefIdAdapter::ToolRefIdAdapter (UniversalId::Type type, const ToolColumns& columns) + : InventoryRefIdAdapter (type, columns), mTools (columns) + {} + + template + QVariant ToolRefIdAdapter::getData (const RefIdColumn *column, const RefIdData& data, + int index) const + { + const Record& record = static_cast&> ( + data.getRecord (RefIdData::LocalIndex (index, BaseRefIdAdapter::getType()))); + + if (column==mTools.mQuality) + return record.get().mData.mQuality; + + if (column==mTools.mUses) + return record.get().mData.mUses; + + return InventoryRefIdAdapter::getData (column, data, index); + } + + template + void ToolRefIdAdapter::setData (const RefIdColumn *column, RefIdData& data, + int index, const QVariant& value) const + { + Record& record = static_cast&> ( + data.getRecord (RefIdData::LocalIndex (index, BaseRefIdAdapter::getType()))); + + if (column==mTools.mQuality) + record.get().mData.mQuality = value.toFloat(); + else if (column==mTools.mUses) + record.get().mData.mUses = value.toInt(); + else + InventoryRefIdAdapter::setData (column, data, index, value); + } + class ApparatusRefIdAdapter : public InventoryRefIdAdapter { const RefIdColumn *mType; diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index 8ed927c70..829576725 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -74,21 +74,25 @@ CSMWorld::RefIdCollection::RefIdCollection() mColumns.push_back (RefIdColumn ("Enchantment Points", ColumnBase::Display_Integer)); enchantableColumns.mEnchantmentPoints = &mColumns.back(); + ToolColumns toolsColumns (inventoryColumns); + + mColumns.push_back (RefIdColumn ("Quality", ColumnBase::Display_Float)); + toolsColumns.mQuality = &mColumns.back(); + mColumns.push_back (RefIdColumn ("Uses", ColumnBase::Display_Integer)); + toolsColumns.mUses = &mColumns.back(); + mColumns.push_back (RefIdColumn ("Auto Calc", ColumnBase::Display_Boolean)); const RefIdColumn *autoCalc = &mColumns.back(); mColumns.push_back (RefIdColumn ("Apparatus Type", ColumnBase::Display_ApparatusType)); const RefIdColumn *apparatusType = &mColumns.back(); - mColumns.push_back (RefIdColumn ("Quality", ColumnBase::Display_Float)); - const RefIdColumn *quality = &mColumns.back(); - mAdapters.insert (std::make_pair (UniversalId::Type_Activator, new NameRefIdAdapter (UniversalId::Type_Activator, nameColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Potion, new PotionRefIdAdapter (inventoryColumns, autoCalc))); mAdapters.insert (std::make_pair (UniversalId::Type_Apparatus, - new ApparatusRefIdAdapter (inventoryColumns, apparatusType, quality))); + new ApparatusRefIdAdapter (inventoryColumns, apparatusType, toolsColumns.mQuality))); mAdapters.insert (std::make_pair (UniversalId::Type_Armor, new EnchantableRefIdAdapter (UniversalId::Type_Armor, enchantableColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Book, @@ -111,16 +115,16 @@ CSMWorld::RefIdCollection::RefIdCollection() mAdapters.insert (std::make_pair (UniversalId::Type_Light, new InventoryRefIdAdapter (UniversalId::Type_Light, inventoryColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Lockpick, - new InventoryRefIdAdapter (UniversalId::Type_Lockpick, inventoryColumns))); + new ToolRefIdAdapter (UniversalId::Type_Lockpick, toolsColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Miscellaneous, new InventoryRefIdAdapter (UniversalId::Type_Miscellaneous, inventoryColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Npc, new NameRefIdAdapter (UniversalId::Type_Npc, nameColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Probe, - new InventoryRefIdAdapter (UniversalId::Type_Probe, inventoryColumns))); + new ToolRefIdAdapter (UniversalId::Type_Probe, toolsColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Repair, - new InventoryRefIdAdapter (UniversalId::Type_Repair, inventoryColumns))); + new ToolRefIdAdapter (UniversalId::Type_Repair, toolsColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Static, new ModelRefIdAdapter (UniversalId::Type_Static, modelColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Weapon, From 74d791e207d0a20e40617a9f727bb82634b446f9 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 13 May 2013 14:07:31 +0200 Subject: [PATCH 28/44] fixed auto calc column --- apps/opencs/model/world/refidadapterimp.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/opencs/model/world/refidadapterimp.cpp b/apps/opencs/model/world/refidadapterimp.cpp index eb68468de..3668198c5 100644 --- a/apps/opencs/model/world/refidadapterimp.cpp +++ b/apps/opencs/model/world/refidadapterimp.cpp @@ -14,7 +14,7 @@ QVariant CSMWorld::PotionRefIdAdapter::getData (const RefIdColumn *column, const data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Potion))); if (column==mAutoCalc) - return record.get().mData.mAutoCalc; + return record.get().mData.mAutoCalc!=0; return InventoryRefIdAdapter::getData (column, data, index); } From 7c57f2c2215e9d4b615b1c1c97374e085f19c0f4 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 14 May 2013 13:20:59 +0200 Subject: [PATCH 29/44] added AI-related actor columns --- apps/opencs/model/world/refidadapterimp.hpp | 102 ++++++++++++++++++++ apps/opencs/model/world/refidcollection.cpp | 50 +++++++++- 2 files changed, 150 insertions(+), 2 deletions(-) diff --git a/apps/opencs/model/world/refidadapterimp.hpp b/apps/opencs/model/world/refidadapterimp.hpp index 8fc16af63..0885517f2 100644 --- a/apps/opencs/model/world/refidadapterimp.hpp +++ b/apps/opencs/model/world/refidadapterimp.hpp @@ -1,6 +1,8 @@ #ifndef CSM_WOLRD_REFIDADAPTERIMP_H #define CSM_WOLRD_REFIDADAPTERIMP_H +#include + #include #include @@ -424,6 +426,106 @@ namespace CSMWorld InventoryRefIdAdapter::setData (column, data, index, value); } + struct ActorColumns : public NameColumns + { + const RefIdColumn *mHasAi; + const RefIdColumn *mHello; + const RefIdColumn *mFlee; + const RefIdColumn *mFight; + const RefIdColumn *mAlarm; + std::map mServices; + + ActorColumns (const NameColumns& base) : NameColumns (base) {} + }; + + /// \brief Adapter for actor IDs (handles common AI functionality) + template + class ActorRefIdAdapter : public NameRefIdAdapter + { + ActorColumns mActors; + + public: + + ActorRefIdAdapter (UniversalId::Type type, const ActorColumns& columns); + + virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) + const; + + virtual void setData (const RefIdColumn *column, RefIdData& data, int index, + const QVariant& value) const; + ///< If the data type does not match an exception is thrown. + }; + + template + ActorRefIdAdapter::ActorRefIdAdapter (UniversalId::Type type, + const ActorColumns& columns) + : NameRefIdAdapter (type, columns), mActors (columns) + {} + + template + QVariant ActorRefIdAdapter::getData (const RefIdColumn *column, const RefIdData& data, + int index) const + { + const Record& record = static_cast&> ( + data.getRecord (RefIdData::LocalIndex (index, BaseRefIdAdapter::getType()))); + + if (column==mActors.mHasAi) + return record.get().mHasAI!=0; + + if (column==mActors.mHello) + return record.get().mAiData.mHello; + + if (column==mActors.mFlee) + return record.get().mAiData.mFlee; + + if (column==mActors.mFight) + return record.get().mAiData.mFight; + + if (column==mActors.mAlarm) + return record.get().mAiData.mAlarm; + + std::map::const_iterator iter = + mActors.mServices.find (column); + + if (iter!=mActors.mServices.end()) + return (record.get().mAiData.mServices & iter->second)!=0; + + return NameRefIdAdapter::getData (column, data, index); + } + + template + void ActorRefIdAdapter::setData (const RefIdColumn *column, RefIdData& data, int index, + const QVariant& value) const + { + Record& record = static_cast&> ( + data.getRecord (RefIdData::LocalIndex (index, BaseRefIdAdapter::getType()))); + + if (column==mActors.mHasAi) + record.get().mHasAI = value.toInt(); + else if (column==mActors.mHello) + record.get().mAiData.mHello = value.toInt(); + else if (column==mActors.mFlee) + record.get().mAiData.mFlee = value.toInt(); + else if (column==mActors.mFight) + record.get().mAiData.mFight = value.toInt(); + else if (column==mActors.mAlarm) + record.get().mAiData.mAlarm = value.toInt(); + else + { + typename std::map::const_iterator iter = + mActors.mServices.find (column); + if (iter!=mActors.mServices.end()) + { + if (value.toInt()!=0) + record.get().mAiData.mServices |= iter->second; + else + record.get().mAiData.mServices &= ~iter->second; + } + else + NameRefIdAdapter::setData (column, data, index, value); + } + } + class ApparatusRefIdAdapter : public InventoryRefIdAdapter { const RefIdColumn *mType; diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index 829576725..452f59d19 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -81,6 +81,52 @@ CSMWorld::RefIdCollection::RefIdCollection() mColumns.push_back (RefIdColumn ("Uses", ColumnBase::Display_Integer)); toolsColumns.mUses = &mColumns.back(); + ActorColumns actorsColumns (nameColumns); + + mColumns.push_back (RefIdColumn ("AI", ColumnBase::Display_Boolean)); + actorsColumns.mHasAi = &mColumns.back(); + mColumns.push_back (RefIdColumn ("AI Hello", ColumnBase::Display_Integer)); + actorsColumns.mHello = &mColumns.back(); + mColumns.push_back (RefIdColumn ("AI Flee", ColumnBase::Display_Integer)); + actorsColumns.mFlee = &mColumns.back(); + mColumns.push_back (RefIdColumn ("AI Fight", ColumnBase::Display_Integer)); + actorsColumns.mFight = &mColumns.back(); + mColumns.push_back (RefIdColumn ("AI Alarm", ColumnBase::Display_Integer)); + actorsColumns.mAlarm = &mColumns.back(); + + static const struct + { + const char *mName; + unsigned int mFlag; + } sServiceTable[] = + { + { "Buys Weapons", ESM::NPC::Weapon}, + { "Buys Armor", ESM::NPC::Armor}, + { "Buys Clothing", ESM::NPC::Clothing}, + { "Buys Books", ESM::NPC::Books}, + { "Buys Ingredients", ESM::NPC::Ingredients}, + { "Buys Lockpicks", ESM::NPC::Picks}, + { "Buys Probes", ESM::NPC::Probes}, + { "Buys Lights", ESM::NPC::Lights}, + { "Buys Apparati", ESM::NPC::Apparatus}, + { "Buys Repair Items", ESM::NPC::RepairItem}, + { "Buys Misc Items", ESM::NPC::Misc}, + { "Buys Potions", ESM::NPC::Potions}, + { "Buys Magic Items", ESM::NPC::MagicItems}, + { "Sells Spells", ESM::NPC::Spells}, + { "Trainer", ESM::NPC::Training}, + { "Spellmaking", ESM::NPC::Spellmaking}, + { "Enchanting Service", ESM::NPC::Enchanting}, + { "Repair Serivce", ESM::NPC::Repair}, + { 0, 0 } + }; + + for (int i=0; sServiceTable[i].mName; ++i) + { + mColumns.push_back (RefIdColumn (sServiceTable[i].mName, ColumnBase::Display_Boolean)); + actorsColumns.mServices.insert (std::make_pair (&mColumns.back(), sServiceTable[i].mFlag)); + } + mColumns.push_back (RefIdColumn ("Auto Calc", ColumnBase::Display_Boolean)); const RefIdColumn *autoCalc = &mColumns.back(); @@ -102,7 +148,7 @@ CSMWorld::RefIdCollection::RefIdCollection() mAdapters.insert (std::make_pair (UniversalId::Type_Container, new NameRefIdAdapter (UniversalId::Type_Container, nameColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Creature, - new NameRefIdAdapter (UniversalId::Type_Creature, nameColumns))); + new ActorRefIdAdapter (UniversalId::Type_Creature, actorsColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Door, new NameRefIdAdapter (UniversalId::Type_Door, nameColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Ingredient, @@ -120,7 +166,7 @@ CSMWorld::RefIdCollection::RefIdCollection() new InventoryRefIdAdapter (UniversalId::Type_Miscellaneous, inventoryColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Npc, - new NameRefIdAdapter (UniversalId::Type_Npc, nameColumns))); + new ActorRefIdAdapter (UniversalId::Type_Npc, actorsColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Probe, new ToolRefIdAdapter (UniversalId::Type_Probe, toolsColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Repair, From fce9939f839a576e701fd8238b7a3c5c41c11dcc Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 14 May 2013 14:21:30 +0200 Subject: [PATCH 30/44] added missing columns for armor record --- apps/opencs/model/world/columnbase.hpp | 3 +- apps/opencs/model/world/refidadapterimp.cpp | 41 +++++++++++++++++++++ apps/opencs/model/world/refidadapterimp.hpp | 19 ++++++++++ apps/opencs/model/world/refidcollection.cpp | 11 +++++- apps/opencs/view/doc/viewmanager.cpp | 9 +++++ 5 files changed, 81 insertions(+), 2 deletions(-) diff --git a/apps/opencs/model/world/columnbase.hpp b/apps/opencs/model/world/columnbase.hpp index 3dc41f737..5fc98cca0 100644 --- a/apps/opencs/model/world/columnbase.hpp +++ b/apps/opencs/model/world/columnbase.hpp @@ -37,7 +37,8 @@ namespace CSMWorld Display_Boolean, Display_SpellType, Display_Script, - Display_ApparatusType + Display_ApparatusType, + Display_ArmorType }; std::string mTitle; diff --git a/apps/opencs/model/world/refidadapterimp.cpp b/apps/opencs/model/world/refidadapterimp.cpp index 3668198c5..7581c5ca3 100644 --- a/apps/opencs/model/world/refidadapterimp.cpp +++ b/apps/opencs/model/world/refidadapterimp.cpp @@ -65,4 +65,45 @@ void CSMWorld::ApparatusRefIdAdapter::setData (const RefIdColumn *column, RefIdD record.get().mData.mQuality = value.toFloat(); else InventoryRefIdAdapter::setData (column, data, index, value); +} + + +CSMWorld::ArmorRefIdAdapter::ArmorRefIdAdapter (const EnchantableColumns& columns, + const RefIdColumn *type, const RefIdColumn *health, const RefIdColumn *armor) +: EnchantableRefIdAdapter (UniversalId::Type_Armor, columns), + mType (type), mHealth (health), mArmor (armor) +{} + +QVariant CSMWorld::ArmorRefIdAdapter::getData (const RefIdColumn *column, + const RefIdData& data, int index) const +{ + const Record& record = static_cast&> ( + data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Armor))); + + if (column==mType) + return record.get().mData.mType; + + if (column==mHealth) + return record.get().mData.mHealth; + + if (column==mArmor) + return record.get().mData.mArmor; + + return EnchantableRefIdAdapter::getData (column, data, index); +} + +void CSMWorld::ArmorRefIdAdapter::setData (const RefIdColumn *column, RefIdData& data, int index, + const QVariant& value) const +{ + Record& record = static_cast&> ( + data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Armor))); + + if (column==mType) + record.get().mData.mType = value.toInt(); + else if (column==mHealth) + record.get().mData.mHealth = value.toInt(); + else if (column==mArmor) + record.get().mData.mArmor = value.toInt(); + else + EnchantableRefIdAdapter::setData (column, data, index, value); } \ No newline at end of file diff --git a/apps/opencs/model/world/refidadapterimp.hpp b/apps/opencs/model/world/refidadapterimp.hpp index 0885517f2..8881728f0 100644 --- a/apps/opencs/model/world/refidadapterimp.hpp +++ b/apps/opencs/model/world/refidadapterimp.hpp @@ -543,6 +543,25 @@ namespace CSMWorld const QVariant& value) const; ///< If the data type does not match an exception is thrown. }; + + class ArmorRefIdAdapter : public EnchantableRefIdAdapter + { + const RefIdColumn *mType; + const RefIdColumn *mHealth; + const RefIdColumn *mArmor; + + public: + + ArmorRefIdAdapter (const EnchantableColumns& columns, const RefIdColumn *type, + const RefIdColumn *health, const RefIdColumn *armor); + + virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) + const; + + virtual void setData (const RefIdColumn *column, RefIdData& data, int index, + const QVariant& value) const; + ///< If the data type does not match an exception is thrown. + }; } #endif diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index 452f59d19..086a509fb 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -133,6 +133,15 @@ CSMWorld::RefIdCollection::RefIdCollection() mColumns.push_back (RefIdColumn ("Apparatus Type", ColumnBase::Display_ApparatusType)); const RefIdColumn *apparatusType = &mColumns.back(); + mColumns.push_back (RefIdColumn ("Armor Type", ColumnBase::Display_ArmorType)); + const RefIdColumn *armorType = &mColumns.back(); + + mColumns.push_back (RefIdColumn ("Health", ColumnBase::Display_Integer)); + const RefIdColumn *health = &mColumns.back(); + + mColumns.push_back (RefIdColumn ("Armor Value", ColumnBase::Display_Integer)); + const RefIdColumn *armor = &mColumns.back(); + mAdapters.insert (std::make_pair (UniversalId::Type_Activator, new NameRefIdAdapter (UniversalId::Type_Activator, nameColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Potion, @@ -140,7 +149,7 @@ CSMWorld::RefIdCollection::RefIdCollection() mAdapters.insert (std::make_pair (UniversalId::Type_Apparatus, new ApparatusRefIdAdapter (inventoryColumns, apparatusType, toolsColumns.mQuality))); mAdapters.insert (std::make_pair (UniversalId::Type_Armor, - new EnchantableRefIdAdapter (UniversalId::Type_Armor, enchantableColumns))); + new ArmorRefIdAdapter (enchantableColumns, armorType, health, armor))); mAdapters.insert (std::make_pair (UniversalId::Type_Book, new EnchantableRefIdAdapter (UniversalId::Type_Book, enchantableColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Clothing, diff --git a/apps/opencs/view/doc/viewmanager.cpp b/apps/opencs/view/doc/viewmanager.cpp index 182d87dc6..7a64f765d 100644 --- a/apps/opencs/view/doc/viewmanager.cpp +++ b/apps/opencs/view/doc/viewmanager.cpp @@ -59,6 +59,12 @@ CSVDoc::ViewManager::ViewManager (CSMDoc::DocumentManager& documentManager) "Mortar & Pestle", "Albemic", "Calcinator", "Retort", 0 }; + static const char *sArmorTypes[] = + { + "Helmet", "Cuirass", "Left Pauldron", "Right Pauldron", "Greaves", "Boots", "Left Gauntlet", + "Right Gauntlet", "Shield", "Left Bracer", "Right Bracer", 0 + }; + mDelegateFactories = new CSVWorld::CommandDelegateFactoryCollection; mDelegateFactories->add (CSMWorld::ColumnBase::Display_GmstVarType, @@ -78,6 +84,9 @@ CSVDoc::ViewManager::ViewManager (CSMDoc::DocumentManager& documentManager) mDelegateFactories->add (CSMWorld::ColumnBase::Display_ApparatusType, new CSVWorld::EnumDelegateFactory (sApparatusTypes)); + + mDelegateFactories->add (CSMWorld::ColumnBase::Display_ArmorType, + new CSVWorld::EnumDelegateFactory (sArmorTypes)); } CSVDoc::ViewManager::~ViewManager() From eba9d3e3ee93099cdd49dd24a610a3b47ab1cd98 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 14 May 2013 14:40:06 +0200 Subject: [PATCH 31/44] added missing columns for book record --- apps/opencs/model/world/refidadapterimp.cpp | 35 +++++++++++++++++++++ apps/opencs/model/world/refidadapterimp.hpp | 18 +++++++++++ apps/opencs/model/world/refidcollection.cpp | 8 ++++- 3 files changed, 60 insertions(+), 1 deletion(-) diff --git a/apps/opencs/model/world/refidadapterimp.cpp b/apps/opencs/model/world/refidadapterimp.cpp index 7581c5ca3..f062c8efe 100644 --- a/apps/opencs/model/world/refidadapterimp.cpp +++ b/apps/opencs/model/world/refidadapterimp.cpp @@ -106,4 +106,39 @@ void CSMWorld::ArmorRefIdAdapter::setData (const RefIdColumn *column, RefIdData& record.get().mData.mArmor = value.toInt(); else EnchantableRefIdAdapter::setData (column, data, index, value); +} + +CSMWorld::BookRefIdAdapter::BookRefIdAdapter (const EnchantableColumns& columns, + const RefIdColumn *scroll, const RefIdColumn *skill) +: EnchantableRefIdAdapter (UniversalId::Type_Book, columns), + mScroll (scroll), mSkill (skill) +{} + +QVariant CSMWorld::BookRefIdAdapter::getData (const RefIdColumn *column, + const RefIdData& data, int index) const +{ + const Record& record = static_cast&> ( + data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Book))); + + if (column==mScroll) + return record.get().mData.mIsScroll!=0; + + if (column==mSkill) + return record.get().mData.mSkillID; + + return EnchantableRefIdAdapter::getData (column, data, index); +} + +void CSMWorld::BookRefIdAdapter::setData (const RefIdColumn *column, RefIdData& data, int index, + const QVariant& value) const +{ + Record& record = static_cast&> ( + data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Book))); + + if (column==mScroll) + record.get().mData.mIsScroll = value.toInt(); + else if (column==mSkill) + record.get().mData.mSkillID = value.toInt(); + else + EnchantableRefIdAdapter::setData (column, data, index, value); } \ No newline at end of file diff --git a/apps/opencs/model/world/refidadapterimp.hpp b/apps/opencs/model/world/refidadapterimp.hpp index 8881728f0..0fbf9fabb 100644 --- a/apps/opencs/model/world/refidadapterimp.hpp +++ b/apps/opencs/model/world/refidadapterimp.hpp @@ -562,6 +562,24 @@ namespace CSMWorld const QVariant& value) const; ///< If the data type does not match an exception is thrown. }; + + class BookRefIdAdapter : public EnchantableRefIdAdapter + { + const RefIdColumn *mScroll; + const RefIdColumn *mSkill; + + public: + + BookRefIdAdapter (const EnchantableColumns& columns, const RefIdColumn *scroll, + const RefIdColumn *skill); + + virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) + const; + + virtual void setData (const RefIdColumn *column, RefIdData& data, int index, + const QVariant& value) const; + ///< If the data type does not match an exception is thrown. + }; } #endif diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index 086a509fb..a6e2e3d0f 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -142,6 +142,12 @@ CSMWorld::RefIdCollection::RefIdCollection() mColumns.push_back (RefIdColumn ("Armor Value", ColumnBase::Display_Integer)); const RefIdColumn *armor = &mColumns.back(); + mColumns.push_back (RefIdColumn ("Scroll", ColumnBase::Display_Boolean)); + const RefIdColumn *scroll = &mColumns.back(); + + mColumns.push_back (RefIdColumn ("Attribute", ColumnBase::Display_Attribute)); + const RefIdColumn *attribute = &mColumns.back(); + mAdapters.insert (std::make_pair (UniversalId::Type_Activator, new NameRefIdAdapter (UniversalId::Type_Activator, nameColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Potion, @@ -151,7 +157,7 @@ CSMWorld::RefIdCollection::RefIdCollection() mAdapters.insert (std::make_pair (UniversalId::Type_Armor, new ArmorRefIdAdapter (enchantableColumns, armorType, health, armor))); mAdapters.insert (std::make_pair (UniversalId::Type_Book, - new EnchantableRefIdAdapter (UniversalId::Type_Book, enchantableColumns))); + new BookRefIdAdapter (enchantableColumns, scroll, attribute))); mAdapters.insert (std::make_pair (UniversalId::Type_Clothing, new EnchantableRefIdAdapter (UniversalId::Type_Clothing, enchantableColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Container, From 28f2a7d2b4989e82c2830881389baadbade0db3e Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Wed, 15 May 2013 11:37:46 +0200 Subject: [PATCH 32/44] added missing column for clothing records --- apps/opencs/model/world/columnbase.hpp | 3 ++- apps/opencs/model/world/refidadapterimp.cpp | 29 +++++++++++++++++++++ apps/opencs/model/world/refidadapterimp.hpp | 16 ++++++++++++ apps/opencs/model/world/refidcollection.cpp | 5 +++- apps/opencs/view/doc/viewmanager.cpp | 9 +++++++ 5 files changed, 60 insertions(+), 2 deletions(-) diff --git a/apps/opencs/model/world/columnbase.hpp b/apps/opencs/model/world/columnbase.hpp index 5fc98cca0..f2379304c 100644 --- a/apps/opencs/model/world/columnbase.hpp +++ b/apps/opencs/model/world/columnbase.hpp @@ -38,7 +38,8 @@ namespace CSMWorld Display_SpellType, Display_Script, Display_ApparatusType, - Display_ArmorType + Display_ArmorType, + Display_ClothingType }; std::string mTitle; diff --git a/apps/opencs/model/world/refidadapterimp.cpp b/apps/opencs/model/world/refidadapterimp.cpp index f062c8efe..57e868aa6 100644 --- a/apps/opencs/model/world/refidadapterimp.cpp +++ b/apps/opencs/model/world/refidadapterimp.cpp @@ -141,4 +141,33 @@ void CSMWorld::BookRefIdAdapter::setData (const RefIdColumn *column, RefIdData& record.get().mData.mSkillID = value.toInt(); else EnchantableRefIdAdapter::setData (column, data, index, value); +} + +CSMWorld::ClothingRefIdAdapter::ClothingRefIdAdapter (const EnchantableColumns& columns, + const RefIdColumn *type) +: EnchantableRefIdAdapter (UniversalId::Type_Clothing, columns), mType (type) +{} + +QVariant CSMWorld::ClothingRefIdAdapter::getData (const RefIdColumn *column, + const RefIdData& data, int index) const +{ + const Record& record = static_cast&> ( + data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Clothing))); + + if (column==mType) + return record.get().mData.mType; + + return EnchantableRefIdAdapter::getData (column, data, index); +} + +void CSMWorld::ClothingRefIdAdapter::setData (const RefIdColumn *column, RefIdData& data, int index, + const QVariant& value) const +{ + Record& record = static_cast&> ( + data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Clothing))); + + if (column==mType) + record.get().mData.mType = value.toInt(); + else + EnchantableRefIdAdapter::setData (column, data, index, value); } \ No newline at end of file diff --git a/apps/opencs/model/world/refidadapterimp.hpp b/apps/opencs/model/world/refidadapterimp.hpp index 0fbf9fabb..fb015b7e1 100644 --- a/apps/opencs/model/world/refidadapterimp.hpp +++ b/apps/opencs/model/world/refidadapterimp.hpp @@ -580,6 +580,22 @@ namespace CSMWorld const QVariant& value) const; ///< If the data type does not match an exception is thrown. }; + + class ClothingRefIdAdapter : public EnchantableRefIdAdapter + { + const RefIdColumn *mType; + + public: + + ClothingRefIdAdapter (const EnchantableColumns& columns, const RefIdColumn *type); + + virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) + const; + + virtual void setData (const RefIdColumn *column, RefIdData& data, int index, + const QVariant& value) const; + ///< If the data type does not match an exception is thrown. + }; } #endif diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index a6e2e3d0f..8c9e19957 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -148,6 +148,9 @@ CSMWorld::RefIdCollection::RefIdCollection() mColumns.push_back (RefIdColumn ("Attribute", ColumnBase::Display_Attribute)); const RefIdColumn *attribute = &mColumns.back(); + mColumns.push_back (RefIdColumn ("Clothing Type", ColumnBase::Display_ClothingType)); + const RefIdColumn *clothingType = &mColumns.back(); + mAdapters.insert (std::make_pair (UniversalId::Type_Activator, new NameRefIdAdapter (UniversalId::Type_Activator, nameColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Potion, @@ -159,7 +162,7 @@ CSMWorld::RefIdCollection::RefIdCollection() mAdapters.insert (std::make_pair (UniversalId::Type_Book, new BookRefIdAdapter (enchantableColumns, scroll, attribute))); mAdapters.insert (std::make_pair (UniversalId::Type_Clothing, - new EnchantableRefIdAdapter (UniversalId::Type_Clothing, enchantableColumns))); + new ClothingRefIdAdapter (enchantableColumns, clothingType))); mAdapters.insert (std::make_pair (UniversalId::Type_Container, new NameRefIdAdapter (UniversalId::Type_Container, nameColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Creature, diff --git a/apps/opencs/view/doc/viewmanager.cpp b/apps/opencs/view/doc/viewmanager.cpp index 7a64f765d..b7da23083 100644 --- a/apps/opencs/view/doc/viewmanager.cpp +++ b/apps/opencs/view/doc/viewmanager.cpp @@ -65,6 +65,12 @@ CSVDoc::ViewManager::ViewManager (CSMDoc::DocumentManager& documentManager) "Right Gauntlet", "Shield", "Left Bracer", "Right Bracer", 0 }; + static const char *sClothingTypes[] = + { + "Pants", "Shoes", "Shirt", "Belt", "Robe", "Right Glove", "Left Glove", "Skirt", "Ring", + "Amulet", 0 + }; + mDelegateFactories = new CSVWorld::CommandDelegateFactoryCollection; mDelegateFactories->add (CSMWorld::ColumnBase::Display_GmstVarType, @@ -87,6 +93,9 @@ CSVDoc::ViewManager::ViewManager (CSMDoc::DocumentManager& documentManager) mDelegateFactories->add (CSMWorld::ColumnBase::Display_ArmorType, new CSVWorld::EnumDelegateFactory (sArmorTypes)); + + mDelegateFactories->add (CSMWorld::ColumnBase::Display_ClothingType, + new CSVWorld::EnumDelegateFactory (sClothingTypes)); } CSVDoc::ViewManager::~ViewManager() From d794a62d193f7e413a34b6981304df2a7aaa958f Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Wed, 15 May 2013 17:02:34 +0200 Subject: [PATCH 33/44] added missing columns for container record --- apps/opencs/model/world/refidadapterimp.cpp | 50 +++++++++++++++++++++ apps/opencs/model/world/refidadapterimp.hpp | 20 +++++++++ apps/opencs/model/world/refidcollection.cpp | 11 ++++- 3 files changed, 80 insertions(+), 1 deletion(-) diff --git a/apps/opencs/model/world/refidadapterimp.cpp b/apps/opencs/model/world/refidadapterimp.cpp index 57e868aa6..ecd6ff7a6 100644 --- a/apps/opencs/model/world/refidadapterimp.cpp +++ b/apps/opencs/model/world/refidadapterimp.cpp @@ -170,4 +170,54 @@ void CSMWorld::ClothingRefIdAdapter::setData (const RefIdColumn *column, RefIdDa record.get().mData.mType = value.toInt(); else EnchantableRefIdAdapter::setData (column, data, index, value); +} + +CSMWorld::ContainerRefIdAdapter::ContainerRefIdAdapter (const NameColumns& columns, + const RefIdColumn *weight, const RefIdColumn *organic, const RefIdColumn *respawn) +: NameRefIdAdapter (UniversalId::Type_Container, columns), mWeight (weight), + mOrganic (organic), mRespawn (respawn) +{} + +QVariant CSMWorld::ContainerRefIdAdapter::getData (const RefIdColumn *column, const RefIdData& data, + int index) const +{ + const Record& record = static_cast&> ( + data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Container))); + + if (column==mWeight) + return record.get().mWeight; + + if (column==mOrganic) + return (record.get().mFlags & ESM::Container::Organic)!=0; + + if (column==mRespawn) + return (record.get().mFlags & ESM::Container::Respawn)!=0; + + return NameRefIdAdapter::getData (column, data, index); +} + +void CSMWorld::ContainerRefIdAdapter::setData (const RefIdColumn *column, RefIdData& data, int index, + const QVariant& value) const +{ + Record& record = static_cast&> ( + data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Container))); + + if (column==mWeight) + record.get().mWeight = value.toFloat(); + else if (column==mOrganic) + { + if (value.toInt()) + record.get().mFlags |= ESM::Container::Organic; + else + record.get().mFlags &= ~ESM::Container::Organic; + } + else if (column==mRespawn) + { + if (value.toInt()) + record.get().mFlags |= ESM::Container::Respawn; + else + record.get().mFlags &= ~ESM::Container::Respawn; + } + else + NameRefIdAdapter::setData (column, data, index, value); } \ No newline at end of file diff --git a/apps/opencs/model/world/refidadapterimp.hpp b/apps/opencs/model/world/refidadapterimp.hpp index fb015b7e1..681892165 100644 --- a/apps/opencs/model/world/refidadapterimp.hpp +++ b/apps/opencs/model/world/refidadapterimp.hpp @@ -596,6 +596,26 @@ namespace CSMWorld const QVariant& value) const; ///< If the data type does not match an exception is thrown. }; + + class ContainerRefIdAdapter : public NameRefIdAdapter + { + const RefIdColumn *mWeight; + const RefIdColumn *mOrganic; + const RefIdColumn *mRespawn; + + public: + + ContainerRefIdAdapter (const NameColumns& columns, const RefIdColumn *weight, + const RefIdColumn *organic, const RefIdColumn *respawn); + + virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) + const; + + virtual void setData (const RefIdColumn *column, RefIdData& data, int index, + const QVariant& value) const; + ///< If the data type does not match an exception is thrown. + + }; } #endif diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index 8c9e19957..e26f1dcf5 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -151,6 +151,15 @@ CSMWorld::RefIdCollection::RefIdCollection() mColumns.push_back (RefIdColumn ("Clothing Type", ColumnBase::Display_ClothingType)); const RefIdColumn *clothingType = &mColumns.back(); + mColumns.push_back (RefIdColumn ("Weight Capacity", ColumnBase::Display_Float)); + const RefIdColumn *weightCapacity = &mColumns.back(); + + mColumns.push_back (RefIdColumn ("Organic Container", ColumnBase::Display_Boolean)); + const RefIdColumn *organic = &mColumns.back(); + + mColumns.push_back (RefIdColumn ("Respawn", ColumnBase::Display_Boolean)); + const RefIdColumn *respawn = &mColumns.back(); + mAdapters.insert (std::make_pair (UniversalId::Type_Activator, new NameRefIdAdapter (UniversalId::Type_Activator, nameColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Potion, @@ -164,7 +173,7 @@ CSMWorld::RefIdCollection::RefIdCollection() mAdapters.insert (std::make_pair (UniversalId::Type_Clothing, new ClothingRefIdAdapter (enchantableColumns, clothingType))); mAdapters.insert (std::make_pair (UniversalId::Type_Container, - new NameRefIdAdapter (UniversalId::Type_Container, nameColumns))); + new ContainerRefIdAdapter (nameColumns, weightCapacity, organic, respawn))); mAdapters.insert (std::make_pair (UniversalId::Type_Creature, new ActorRefIdAdapter (UniversalId::Type_Creature, actorsColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Door, From 889a87982e77d3e19ace3696f26414ab63e2dad3 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 16 May 2013 16:27:33 +0200 Subject: [PATCH 34/44] added missing columns for creatures --- apps/opencs/model/world/columnbase.hpp | 3 +- apps/opencs/model/world/refidadapterimp.cpp | 66 +++++++++++++++++++++ apps/opencs/model/world/refidadapterimp.hpp | 26 ++++++++ apps/opencs/model/world/refidcollection.cpp | 39 +++++++++++- apps/opencs/view/doc/viewmanager.cpp | 8 +++ 5 files changed, 140 insertions(+), 2 deletions(-) diff --git a/apps/opencs/model/world/columnbase.hpp b/apps/opencs/model/world/columnbase.hpp index f2379304c..001ea4ff6 100644 --- a/apps/opencs/model/world/columnbase.hpp +++ b/apps/opencs/model/world/columnbase.hpp @@ -39,7 +39,8 @@ namespace CSMWorld Display_Script, Display_ApparatusType, Display_ArmorType, - Display_ClothingType + Display_ClothingType, + Display_CreatureType }; std::string mTitle; diff --git a/apps/opencs/model/world/refidadapterimp.cpp b/apps/opencs/model/world/refidadapterimp.cpp index ecd6ff7a6..1b54f2dad 100644 --- a/apps/opencs/model/world/refidadapterimp.cpp +++ b/apps/opencs/model/world/refidadapterimp.cpp @@ -220,4 +220,70 @@ void CSMWorld::ContainerRefIdAdapter::setData (const RefIdColumn *column, RefIdD } else NameRefIdAdapter::setData (column, data, index, value); +} + +CSMWorld::CreatureColumns::CreatureColumns (const ActorColumns& actorColumns) +: ActorColumns (actorColumns) +{} + +CSMWorld::CreatureRefIdAdapter::CreatureRefIdAdapter (const CreatureColumns& columns) +: ActorRefIdAdapter (UniversalId::Type_Creature, columns), mColumns (columns) +{} + +QVariant CSMWorld::CreatureRefIdAdapter::getData (const RefIdColumn *column, const RefIdData& data, + int index) const +{ + const Record& record = static_cast&> ( + data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Creature))); + + if (column==mColumns.mType) + return record.get().mData.mType; + + if (column==mColumns.mSoul) + return record.get().mData.mSoul; + + if (column==mColumns.mScale) + return record.get().mScale; + + if (column==mColumns.mOriginal) + return QString::fromUtf8 (record.get().mOriginal.c_str()); + + std::map::const_iterator iter = + mColumns.mFlags.find (column); + + if (iter!=mColumns.mFlags.end()) + return (record.get().mFlags & iter->second)!=0; + + return ActorRefIdAdapter::getData (column, data, index); +} + +void CSMWorld::CreatureRefIdAdapter::setData (const RefIdColumn *column, RefIdData& data, int index, + const QVariant& value) const +{ + Record& record = static_cast&> ( + data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Creature))); + + if (column==mColumns.mType) + record.get().mData.mType = value.toInt(); + else if (column==mColumns.mSoul) + record.get().mData.mSoul = value.toInt(); + else if (column==mColumns.mScale) + record.get().mScale = value.toFloat(); + else if (column==mColumns.mOriginal) + record.get().mOriginal = value.toString().toUtf8().constData(); + else + { + std::map::const_iterator iter = + mColumns.mFlags.find (column); + + if (iter!=mColumns.mFlags.end()) + { + if (value.toInt()!=0) + record.get().mFlags |= iter->second; + else + record.get().mFlags &= ~iter->second; + } + else + ActorRefIdAdapter::setData (column, data, index, value); + } } \ No newline at end of file diff --git a/apps/opencs/model/world/refidadapterimp.hpp b/apps/opencs/model/world/refidadapterimp.hpp index 681892165..328be0c6b 100644 --- a/apps/opencs/model/world/refidadapterimp.hpp +++ b/apps/opencs/model/world/refidadapterimp.hpp @@ -614,7 +614,33 @@ namespace CSMWorld virtual void setData (const RefIdColumn *column, RefIdData& data, int index, const QVariant& value) const; ///< If the data type does not match an exception is thrown. + }; + struct CreatureColumns : public ActorColumns + { + std::map mFlags; + const RefIdColumn *mType; + const RefIdColumn *mSoul; + const RefIdColumn *mScale; + const RefIdColumn *mOriginal; + + CreatureColumns (const ActorColumns& actorColumns); + }; + + class CreatureRefIdAdapter : public ActorRefIdAdapter + { + CreatureColumns mColumns; + + public: + + CreatureRefIdAdapter (const CreatureColumns& columns); + + virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) + const; + + virtual void setData (const RefIdColumn *column, RefIdData& data, int index, + const QVariant& value) const; + ///< If the data type does not match an exception is thrown. }; } diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index e26f1dcf5..5fc479f4c 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -160,6 +160,43 @@ CSMWorld::RefIdCollection::RefIdCollection() mColumns.push_back (RefIdColumn ("Respawn", ColumnBase::Display_Boolean)); const RefIdColumn *respawn = &mColumns.back(); + CreatureColumns creatureColumns (actorsColumns); + + mColumns.push_back (RefIdColumn ("Creature Type", ColumnBase::Display_CreatureType)); + creatureColumns.mType = &mColumns.back(); + mColumns.push_back (RefIdColumn ("Soul Points", ColumnBase::Display_Integer)); + creatureColumns.mSoul = &mColumns.back(); + mColumns.push_back (RefIdColumn ("Scale", ColumnBase::Display_Float)); + creatureColumns.mScale = &mColumns.back(); + mColumns.push_back (RefIdColumn ("Original Creature", ColumnBase::Display_String)); + creatureColumns.mOriginal = &mColumns.back(); + + static const struct + { + const char *mName; + unsigned int mFlag; + } sCreatureFlagTable[] = + { + { "Biped", ESM::Creature::Biped }, + { "Has Weapon", ESM::Creature::Weapon }, + { "No Movement", ESM::Creature::None }, + { "Swims", ESM::Creature::Swims }, + { "Flies", ESM::Creature::Flies }, + { "Walks", ESM::Creature::Walks }, + { "Essential", ESM::Creature::Essential }, + { "Skeleton Blood", ESM::Creature::Skeleton }, + { "Metal Blood", ESM::Creature::Metal }, + { 0, 0 } + }; + + for (int i=0; sCreatureFlagTable[i].mName; ++i) + { + mColumns.push_back (RefIdColumn (sCreatureFlagTable[i].mName, ColumnBase::Display_Boolean)); + creatureColumns.mFlags.insert (std::make_pair (&mColumns.back(), sCreatureFlagTable[i].mFlag)); + } + + creatureColumns.mFlags.insert (std::make_pair (respawn, ESM::Creature::Respawn)); + mAdapters.insert (std::make_pair (UniversalId::Type_Activator, new NameRefIdAdapter (UniversalId::Type_Activator, nameColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Potion, @@ -175,7 +212,7 @@ CSMWorld::RefIdCollection::RefIdCollection() mAdapters.insert (std::make_pair (UniversalId::Type_Container, new ContainerRefIdAdapter (nameColumns, weightCapacity, organic, respawn))); mAdapters.insert (std::make_pair (UniversalId::Type_Creature, - new ActorRefIdAdapter (UniversalId::Type_Creature, actorsColumns))); + new CreatureRefIdAdapter (creatureColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Door, new NameRefIdAdapter (UniversalId::Type_Door, nameColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Ingredient, diff --git a/apps/opencs/view/doc/viewmanager.cpp b/apps/opencs/view/doc/viewmanager.cpp index b7da23083..4e0614450 100644 --- a/apps/opencs/view/doc/viewmanager.cpp +++ b/apps/opencs/view/doc/viewmanager.cpp @@ -71,6 +71,11 @@ CSVDoc::ViewManager::ViewManager (CSMDoc::DocumentManager& documentManager) "Amulet", 0 }; + static const char *sCreatureTypes[] = + { + "Creature", "Deadra", "Undead", "Humanoid", 0 + }; + mDelegateFactories = new CSVWorld::CommandDelegateFactoryCollection; mDelegateFactories->add (CSMWorld::ColumnBase::Display_GmstVarType, @@ -96,6 +101,9 @@ CSVDoc::ViewManager::ViewManager (CSMDoc::DocumentManager& documentManager) mDelegateFactories->add (CSMWorld::ColumnBase::Display_ClothingType, new CSVWorld::EnumDelegateFactory (sClothingTypes)); + + mDelegateFactories->add (CSMWorld::ColumnBase::Display_CreatureType, + new CSVWorld::EnumDelegateFactory (sCreatureTypes)); } CSVDoc::ViewManager::~ViewManager() From 749fd418b5157812dd40d789ecacbf29cf266bb7 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 17 May 2013 15:10:41 +0200 Subject: [PATCH 35/44] added missing columns for door record --- apps/opencs/model/world/refidadapterimp.cpp | 36 +++++++++++++++++++++ apps/opencs/model/world/refidadapterimp.hpp | 18 +++++++++++ apps/opencs/model/world/refidcollection.cpp | 8 ++++- apps/opencs/model/world/refidcollection.hpp | 1 - 4 files changed, 61 insertions(+), 2 deletions(-) diff --git a/apps/opencs/model/world/refidadapterimp.cpp b/apps/opencs/model/world/refidadapterimp.cpp index 1b54f2dad..10694a79e 100644 --- a/apps/opencs/model/world/refidadapterimp.cpp +++ b/apps/opencs/model/world/refidadapterimp.cpp @@ -286,4 +286,40 @@ void CSMWorld::CreatureRefIdAdapter::setData (const RefIdColumn *column, RefIdDa else ActorRefIdAdapter::setData (column, data, index, value); } +} + + +CSMWorld::DoorRefIdAdapter::DoorRefIdAdapter (const NameColumns& columns, + const RefIdColumn *openSound, const RefIdColumn *closeSound) +: NameRefIdAdapter (UniversalId::Type_Door, columns), mOpenSound (openSound), + mCloseSound (closeSound) +{} + +QVariant CSMWorld::DoorRefIdAdapter::getData (const RefIdColumn *column, const RefIdData& data, + int index) const +{ + const Record& record = static_cast&> ( + data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Door))); + + if (column==mOpenSound) + return QString::fromUtf8 (record.get().mOpenSound.c_str()); + + if (column==mCloseSound) + return QString::fromUtf8 (record.get().mCloseSound.c_str()); + + return NameRefIdAdapter::getData (column, data, index); +} + +void CSMWorld::DoorRefIdAdapter::setData (const RefIdColumn *column, RefIdData& data, int index, + const QVariant& value) const +{ + Record& record = static_cast&> ( + data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Door))); + + if (column==mOpenSound) + record.get().mOpenSound = value.toString().toUtf8().constData(); + else if (column==mCloseSound) + record.get().mCloseSound = value.toString().toUtf8().constData(); + else + NameRefIdAdapter::setData (column, data, index, value); } \ No newline at end of file diff --git a/apps/opencs/model/world/refidadapterimp.hpp b/apps/opencs/model/world/refidadapterimp.hpp index 328be0c6b..fa25331a4 100644 --- a/apps/opencs/model/world/refidadapterimp.hpp +++ b/apps/opencs/model/world/refidadapterimp.hpp @@ -642,6 +642,24 @@ namespace CSMWorld const QVariant& value) const; ///< If the data type does not match an exception is thrown. }; + + class DoorRefIdAdapter : public NameRefIdAdapter + { + const RefIdColumn *mOpenSound; + const RefIdColumn *mCloseSound; + + public: + + DoorRefIdAdapter (const NameColumns& columns, const RefIdColumn *openSound, + const RefIdColumn *closeSound); + + virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) + const; + + virtual void setData (const RefIdColumn *column, RefIdData& data, int index, + const QVariant& value) const; + ///< If the data type does not match an exception is thrown. + }; } #endif diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index 5fc479f4c..5667d0170 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -197,6 +197,12 @@ CSMWorld::RefIdCollection::RefIdCollection() creatureColumns.mFlags.insert (std::make_pair (respawn, ESM::Creature::Respawn)); + mColumns.push_back (RefIdColumn ("Open Sound", ColumnBase::Display_String)); + const RefIdColumn *openSound = &mColumns.back(); + + mColumns.push_back (RefIdColumn ("Close Sound", ColumnBase::Display_String)); + const RefIdColumn *closeSound = &mColumns.back(); + mAdapters.insert (std::make_pair (UniversalId::Type_Activator, new NameRefIdAdapter (UniversalId::Type_Activator, nameColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Potion, @@ -214,7 +220,7 @@ CSMWorld::RefIdCollection::RefIdCollection() mAdapters.insert (std::make_pair (UniversalId::Type_Creature, new CreatureRefIdAdapter (creatureColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Door, - new NameRefIdAdapter (UniversalId::Type_Door, nameColumns))); + new DoorRefIdAdapter (nameColumns, openSound, closeSound))); mAdapters.insert (std::make_pair (UniversalId::Type_Ingredient, new InventoryRefIdAdapter (UniversalId::Type_Ingredient, inventoryColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_CreatureLevelledList, diff --git a/apps/opencs/model/world/refidcollection.hpp b/apps/opencs/model/world/refidcollection.hpp index a55ad38a4..dc86c128c 100644 --- a/apps/opencs/model/world/refidcollection.hpp +++ b/apps/opencs/model/world/refidcollection.hpp @@ -89,7 +89,6 @@ namespace CSMWorld virtual int getAppendIndex (UniversalId::Type type) const; ///< \param type Will be ignored, unless the collection supports multiple record types - }; } From 862e568f9b12649d9b02776aef1d5ee0214ff7af Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 18 May 2013 18:46:41 +0200 Subject: [PATCH 36/44] added missing columns for Light record --- apps/opencs/model/world/refidadapterimp.cpp | 68 ++++++++++++++++++++- apps/opencs/model/world/refidadapterimp.hpp | 27 ++++++++ apps/opencs/model/world/refidcollection.cpp | 40 +++++++++++- 3 files changed, 132 insertions(+), 3 deletions(-) diff --git a/apps/opencs/model/world/refidadapterimp.cpp b/apps/opencs/model/world/refidadapterimp.cpp index 10694a79e..761e5a926 100644 --- a/apps/opencs/model/world/refidadapterimp.cpp +++ b/apps/opencs/model/world/refidadapterimp.cpp @@ -288,7 +288,6 @@ void CSMWorld::CreatureRefIdAdapter::setData (const RefIdColumn *column, RefIdDa } } - CSMWorld::DoorRefIdAdapter::DoorRefIdAdapter (const NameColumns& columns, const RefIdColumn *openSound, const RefIdColumn *closeSound) : NameRefIdAdapter (UniversalId::Type_Door, columns), mOpenSound (openSound), @@ -322,4 +321,69 @@ void CSMWorld::DoorRefIdAdapter::setData (const RefIdColumn *column, RefIdData& record.get().mCloseSound = value.toString().toUtf8().constData(); else NameRefIdAdapter::setData (column, data, index, value); -} \ No newline at end of file +} + +CSMWorld::LightColumns::LightColumns (const InventoryColumns& columns) +: InventoryColumns (columns) {} + +CSMWorld::LightRefIdAdapter::LightRefIdAdapter (const LightColumns& columns) +: InventoryRefIdAdapter (UniversalId::Type_Light, columns), mColumns (columns) +{} + +QVariant CSMWorld::LightRefIdAdapter::getData (const RefIdColumn *column, const RefIdData& data, + int index) const +{ + const Record& record = static_cast&> ( + data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Light))); + + if (column==mColumns.mTime) + return record.get().mData.mTime; + + if (column==mColumns.mRadius) + return record.get().mData.mRadius; + + if (column==mColumns.mColor) + return record.get().mData.mColor; + + if (column==mColumns.mSound) + return QString::fromUtf8 (record.get().mSound.c_str()); + + std::map::const_iterator iter = + mColumns.mFlags.find (column); + + if (iter!=mColumns.mFlags.end()) + return (record.get().mData.mFlags & iter->second)!=0; + + return InventoryRefIdAdapter::getData (column, data, index); +} + +void CSMWorld::LightRefIdAdapter::setData (const RefIdColumn *column, RefIdData& data, int index, + const QVariant& value) const +{ + Record& record = static_cast&> ( + data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Light))); + + if (column==mColumns.mTime) + record.get().mData.mTime = value.toInt(); + else if (column==mColumns.mRadius) + record.get().mData.mRadius = value.toInt(); + else if (column==mColumns.mColor) + record.get().mData.mColor = value.toInt(); + else if (column==mColumns.mSound) + record.get().mSound = value.toString().toUtf8().constData(); + else + { + std::map::const_iterator iter = + mColumns.mFlags.find (column); + + if (iter!=mColumns.mFlags.end()) + { + if (value.toInt()!=0) + record.get().mData.mFlags |= iter->second; + else + record.get().mData.mFlags &= ~iter->second; + } + else + InventoryRefIdAdapter::setData (column, data, index, value); + } +} diff --git a/apps/opencs/model/world/refidadapterimp.hpp b/apps/opencs/model/world/refidadapterimp.hpp index fa25331a4..a856d5202 100644 --- a/apps/opencs/model/world/refidadapterimp.hpp +++ b/apps/opencs/model/world/refidadapterimp.hpp @@ -660,6 +660,33 @@ namespace CSMWorld const QVariant& value) const; ///< If the data type does not match an exception is thrown. }; + + struct LightColumns : public InventoryColumns + { + const RefIdColumn *mTime; + const RefIdColumn *mRadius; + const RefIdColumn *mColor; + const RefIdColumn *mSound; + std::map mFlags; + + LightColumns (const InventoryColumns& columns); + }; + + class LightRefIdAdapter : public InventoryRefIdAdapter + { + LightColumns mColumns; + + public: + + LightRefIdAdapter (const LightColumns& columns); + + virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) + const; + + virtual void setData (const RefIdColumn *column, RefIdData& data, int index, + const QVariant& value) const; + ///< If the data type does not match an exception is thrown. + }; } #endif diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index 5667d0170..45c4cb476 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -203,6 +203,44 @@ CSMWorld::RefIdCollection::RefIdCollection() mColumns.push_back (RefIdColumn ("Close Sound", ColumnBase::Display_String)); const RefIdColumn *closeSound = &mColumns.back(); + LightColumns lightColumns (inventoryColumns); + + mColumns.push_back (RefIdColumn ("Duration", ColumnBase::Display_Integer)); + lightColumns.mTime = &mColumns.back(); + + mColumns.push_back (RefIdColumn ("Radius", ColumnBase::Display_Integer)); + lightColumns.mRadius = &mColumns.back(); + + mColumns.push_back (RefIdColumn ("Colour", ColumnBase::Display_Integer)); + lightColumns.mColor = &mColumns.back(); + + mColumns.push_back (RefIdColumn ("Sound", ColumnBase::Display_String)); + lightColumns.mSound = &mColumns.back(); + + static const struct + { + const char *mName; + unsigned int mFlag; + } sLightFlagTable[] = + { + { "Dynamic", ESM::Light::Dynamic }, + { "Portable", ESM::Light::Carry }, + { "Negative Light", ESM::Light::Negative }, + { "Flickering", ESM::Light::Flicker }, + { "Slow Flickering", ESM::Light::Flicker }, + { "Pulsing", ESM::Light::Pulse }, + { "Slow Pulsing", ESM::Light::PulseSlow }, + { "Fire", ESM::Light::Fire }, + { "Off by default", ESM::Light::OffDefault }, + { 0, 0 } + }; + + for (int i=0; sLightFlagTable[i].mName; ++i) + { + mColumns.push_back (RefIdColumn (sLightFlagTable[i].mName, ColumnBase::Display_Boolean)); + lightColumns.mFlags.insert (std::make_pair (&mColumns.back(), sLightFlagTable[i].mFlag)); + } + mAdapters.insert (std::make_pair (UniversalId::Type_Activator, new NameRefIdAdapter (UniversalId::Type_Activator, nameColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Potion, @@ -229,7 +267,7 @@ CSMWorld::RefIdCollection::RefIdCollection() mAdapters.insert (std::make_pair (UniversalId::Type_ItemLevelledList, new BaseRefIdAdapter (UniversalId::Type_ItemLevelledList, baseColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Light, - new InventoryRefIdAdapter (UniversalId::Type_Light, inventoryColumns))); + new LightRefIdAdapter (lightColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Lockpick, new ToolRefIdAdapter (UniversalId::Type_Lockpick, toolsColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Miscellaneous, From 8d78bea4aab1ae70fbd524774f939e9d59cdb4f1 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 18 May 2013 18:55:23 +0200 Subject: [PATCH 37/44] added missing column for misc record --- apps/opencs/model/world/refidadapterimp.cpp | 28 +++++++++++++++++++++ apps/opencs/model/world/refidadapterimp.hpp | 16 ++++++++++++ apps/opencs/model/world/refidcollection.cpp | 6 +++-- 3 files changed, 48 insertions(+), 2 deletions(-) diff --git a/apps/opencs/model/world/refidadapterimp.cpp b/apps/opencs/model/world/refidadapterimp.cpp index 761e5a926..0b5cd7a8b 100644 --- a/apps/opencs/model/world/refidadapterimp.cpp +++ b/apps/opencs/model/world/refidadapterimp.cpp @@ -387,3 +387,31 @@ void CSMWorld::LightRefIdAdapter::setData (const RefIdColumn *column, RefIdData& InventoryRefIdAdapter::setData (column, data, index, value); } } + +CSMWorld::MiscRefIdAdapter::MiscRefIdAdapter (const InventoryColumns& columns, const RefIdColumn *key) +: InventoryRefIdAdapter (UniversalId::Type_Miscellaneous, columns), mKey (key) +{} + +QVariant CSMWorld::MiscRefIdAdapter::getData (const RefIdColumn *column, const RefIdData& data, + int index) const +{ + const Record& record = static_cast&> ( + data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Miscellaneous))); + + if (column==mKey) + return record.get().mData.mIsKey!=0; + + return InventoryRefIdAdapter::getData (column, data, index); +} + +void CSMWorld::MiscRefIdAdapter::setData (const RefIdColumn *column, RefIdData& data, int index, + const QVariant& value) const +{ + Record& record = static_cast&> ( + data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Miscellaneous))); + + if (column==mKey) + record.get().mData.mIsKey = value.toInt(); + else + InventoryRefIdAdapter::setData (column, data, index, value); +} diff --git a/apps/opencs/model/world/refidadapterimp.hpp b/apps/opencs/model/world/refidadapterimp.hpp index a856d5202..04cee12d1 100644 --- a/apps/opencs/model/world/refidadapterimp.hpp +++ b/apps/opencs/model/world/refidadapterimp.hpp @@ -687,6 +687,22 @@ namespace CSMWorld const QVariant& value) const; ///< If the data type does not match an exception is thrown. }; + + class MiscRefIdAdapter : public InventoryRefIdAdapter + { + const RefIdColumn *mKey; + + public: + + MiscRefIdAdapter (const InventoryColumns& columns, const RefIdColumn *key); + + virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) + const; + + virtual void setData (const RefIdColumn *column, RefIdData& data, int index, + const QVariant& value) const; + ///< If the data type does not match an exception is thrown. + }; } #endif diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index 45c4cb476..0ff3f3fc9 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -241,6 +241,9 @@ CSMWorld::RefIdCollection::RefIdCollection() lightColumns.mFlags.insert (std::make_pair (&mColumns.back(), sLightFlagTable[i].mFlag)); } + mColumns.push_back (RefIdColumn ("Key", ColumnBase::Display_Boolean)); + const RefIdColumn *key = &mColumns.back(); + mAdapters.insert (std::make_pair (UniversalId::Type_Activator, new NameRefIdAdapter (UniversalId::Type_Activator, nameColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Potion, @@ -271,8 +274,7 @@ CSMWorld::RefIdCollection::RefIdCollection() mAdapters.insert (std::make_pair (UniversalId::Type_Lockpick, new ToolRefIdAdapter (UniversalId::Type_Lockpick, toolsColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Miscellaneous, - new InventoryRefIdAdapter (UniversalId::Type_Miscellaneous, - inventoryColumns))); + new MiscRefIdAdapter (inventoryColumns, key))); mAdapters.insert (std::make_pair (UniversalId::Type_Npc, new ActorRefIdAdapter (UniversalId::Type_Npc, actorsColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Probe, From 4983d08fe476969cca2d39e65bba9f6b22b4ac93 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 18 May 2013 22:55:30 +0200 Subject: [PATCH 38/44] Fix a problem with statics disappearing sometimes on the map Ogre::StaticGeometry doesn't seem to like materials being changed at runtime. It stores raw pointers to Ogre::Technique objects also, which conflicts with shiny's way of managing "unloaded" materials as having zero techniques. If a static geometry object is baked from an unloaded material, it won't find any techniques to use and can't render. By moving the unload call afterwards, it will be detected as in use by a renderable and won't be unloaded. Ideally this needs fixing of Ogre::StaticGeometry to not hold on to Technique objects (they also currently need to be rebuilt whenever user settings are changed, which also causes "unloading" of materials) --- apps/openmw/mwrender/localmap.cpp | 6 +++--- apps/openmw/mwrender/renderingmanager.cpp | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/openmw/mwrender/localmap.cpp b/apps/openmw/mwrender/localmap.cpp index c86a61cfa..8043f8b12 100644 --- a/apps/openmw/mwrender/localmap.cpp +++ b/apps/openmw/mwrender/localmap.cpp @@ -197,11 +197,11 @@ void LocalMap::render(const float x, const float y, const float zlow, const float zhigh, const float xw, const float yw, const std::string& texture) { - //mCellCamera->setFarClipDistance( (zhigh-zlow) * 1.1 ); - mCellCamera->setFarClipDistance(0); // infinite + mCellCamera->setFarClipDistance( (zhigh-zlow) + 2000 ); + mCellCamera->setNearClipDistance(50); mCellCamera->setOrthoWindow(xw, yw); - mCameraNode->setPosition(Vector3(x, y, zhigh+100000)); + mCameraNode->setPosition(Vector3(x, y, zhigh+1000)); // disable fog (only necessary for fixed function, the shader based // materials already do this through local_map material configuration) diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index 6586cbba6..9061f8402 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -235,8 +235,8 @@ void RenderingManager::toggleWater() void RenderingManager::cellAdded (MWWorld::Ptr::CellStore *store) { - sh::Factory::getInstance().unloadUnreferencedMaterials(); mObjects.buildStaticGeometry (*store); + sh::Factory::getInstance().unloadUnreferencedMaterials(); mDebugging->cellAdded(store); if (store->mCell->isExterior()) mTerrainManager->cellAdded(store); From c7805e7dd27f3cf9a226fc0cf94a2357816b1e48 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 18 May 2013 23:10:37 +0200 Subject: [PATCH 39/44] Fix sun glare persisting after changing to an interior cell --- apps/openmw/mwrender/sky.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/openmw/mwrender/sky.cpp b/apps/openmw/mwrender/sky.cpp index 2912672b5..03e14dc07 100644 --- a/apps/openmw/mwrender/sky.cpp +++ b/apps/openmw/mwrender/sky.cpp @@ -640,7 +640,7 @@ Ogre::SceneNode* SkyManager::getSunNode() void SkyManager::setGlareEnabled (bool enabled) { - if (!mCreated) + if (!mCreated || !mEnabled) return; mSunGlare->setVisible (mSunEnabled && enabled); } From 2123900db5c5498ba45731a461480d6363736d37 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 19 May 2013 13:53:47 +0200 Subject: [PATCH 40/44] added missing columns for NPC records --- apps/opencs/model/world/refidadapterimp.cpp | 69 +++++++++++++++++++++ apps/opencs/model/world/refidadapterimp.hpp | 28 +++++++++ apps/opencs/model/world/refidcollection.cpp | 44 ++++++++++++- 3 files changed, 140 insertions(+), 1 deletion(-) diff --git a/apps/opencs/model/world/refidadapterimp.cpp b/apps/opencs/model/world/refidadapterimp.cpp index 0b5cd7a8b..59907b6d6 100644 --- a/apps/opencs/model/world/refidadapterimp.cpp +++ b/apps/opencs/model/world/refidadapterimp.cpp @@ -415,3 +415,72 @@ void CSMWorld::MiscRefIdAdapter::setData (const RefIdColumn *column, RefIdData& else InventoryRefIdAdapter::setData (column, data, index, value); } + +CSMWorld::NpcColumns::NpcColumns (const ActorColumns& actorColumns) : ActorColumns (actorColumns) {} + +CSMWorld::NpcRefIdAdapter::NpcRefIdAdapter (const NpcColumns& columns) +: ActorRefIdAdapter (UniversalId::Type_Npc, columns), mColumns (columns) +{} + +QVariant CSMWorld::NpcRefIdAdapter::getData (const RefIdColumn *column, const RefIdData& data, int index) + const +{ + const Record& record = static_cast&> ( + data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Npc))); + + if (column==mColumns.mRace) + return QString::fromUtf8 (record.get().mRace.c_str()); + + if (column==mColumns.mClass) + return QString::fromUtf8 (record.get().mClass.c_str()); + + if (column==mColumns.mFaction) + return QString::fromUtf8 (record.get().mFaction.c_str()); + + if (column==mColumns.mHair) + return QString::fromUtf8 (record.get().mHair.c_str()); + + if (column==mColumns.mHead) + return QString::fromUtf8 (record.get().mHead.c_str()); + + std::map::const_iterator iter = + mColumns.mFlags.find (column); + + if (iter!=mColumns.mFlags.end()) + return (record.get().mFlags & iter->second)!=0; + + return ActorRefIdAdapter::getData (column, data, index); +} + +void CSMWorld::NpcRefIdAdapter::setData (const RefIdColumn *column, RefIdData& data, int index, + const QVariant& value) const +{ + Record& record = static_cast&> ( + data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Npc))); + + if (column==mColumns.mRace) + record.get().mRace = value.toString().toUtf8().constData(); + else if (column==mColumns.mClass) + record.get().mClass = value.toString().toUtf8().constData(); + else if (column==mColumns.mFaction) + record.get().mFaction = value.toString().toUtf8().constData(); + else if (column==mColumns.mHair) + record.get().mHair = value.toString().toUtf8().constData(); + else if (column==mColumns.mHead) + record.get().mHead = value.toString().toUtf8().constData(); + else + { + std::map::const_iterator iter = + mColumns.mFlags.find (column); + + if (iter!=mColumns.mFlags.end()) + { + if (value.toInt()!=0) + record.get().mFlags |= iter->second; + else + record.get().mFlags &= ~iter->second; + } + else + ActorRefIdAdapter::setData (column, data, index, value); + } +} \ No newline at end of file diff --git a/apps/opencs/model/world/refidadapterimp.hpp b/apps/opencs/model/world/refidadapterimp.hpp index 04cee12d1..04569b16f 100644 --- a/apps/opencs/model/world/refidadapterimp.hpp +++ b/apps/opencs/model/world/refidadapterimp.hpp @@ -703,6 +703,34 @@ namespace CSMWorld const QVariant& value) const; ///< If the data type does not match an exception is thrown. }; + + struct NpcColumns : public ActorColumns + { + std::map mFlags; + const RefIdColumn *mRace; + const RefIdColumn *mClass; + const RefIdColumn *mFaction; + const RefIdColumn *mHair; + const RefIdColumn *mHead; + + NpcColumns (const ActorColumns& actorColumns); + }; + + class NpcRefIdAdapter : public ActorRefIdAdapter + { + NpcColumns mColumns; + + public: + + NpcRefIdAdapter (const NpcColumns& columns); + + virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) + const; + + virtual void setData (const RefIdColumn *column, RefIdData& data, int index, + const QVariant& value) const; + ///< If the data type does not match an exception is thrown. + }; } #endif diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index 0ff3f3fc9..f7c697233 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -189,10 +189,22 @@ CSMWorld::RefIdCollection::RefIdCollection() { 0, 0 } }; + // for re-use in NPC records + const RefIdColumn *essential = 0; + const RefIdColumn *skeletonBlood = 0; + const RefIdColumn *metalBlood = 0; + for (int i=0; sCreatureFlagTable[i].mName; ++i) { mColumns.push_back (RefIdColumn (sCreatureFlagTable[i].mName, ColumnBase::Display_Boolean)); creatureColumns.mFlags.insert (std::make_pair (&mColumns.back(), sCreatureFlagTable[i].mFlag)); + + switch (sCreatureFlagTable[i].mFlag) + { + case ESM::Creature::Essential: essential = &mColumns.back(); break; + case ESM::Creature::Skeleton: skeletonBlood = &mColumns.back(); break; + case ESM::Creature::Metal: metalBlood = &mColumns.back(); break; + } } creatureColumns.mFlags.insert (std::make_pair (respawn, ESM::Creature::Respawn)); @@ -244,6 +256,36 @@ CSMWorld::RefIdCollection::RefIdCollection() mColumns.push_back (RefIdColumn ("Key", ColumnBase::Display_Boolean)); const RefIdColumn *key = &mColumns.back(); + NpcColumns npcColumns (actorsColumns); + + mColumns.push_back (RefIdColumn ("Race", ColumnBase::Display_String)); + npcColumns.mRace = &mColumns.back(); + + mColumns.push_back (RefIdColumn ("Class", ColumnBase::Display_String)); + npcColumns.mClass = &mColumns.back(); + + mColumns.push_back (RefIdColumn ("Faction", ColumnBase::Display_String)); + npcColumns.mFaction = &mColumns.back(); + + mColumns.push_back (RefIdColumn ("Hair", ColumnBase::Display_String)); + npcColumns.mHair = &mColumns.back(); + + mColumns.push_back (RefIdColumn ("Head", ColumnBase::Display_String)); + npcColumns.mHead = &mColumns.back(); + + mColumns.push_back (RefIdColumn ("Female", ColumnBase::Display_Boolean)); + npcColumns.mFlags.insert (std::make_pair (&mColumns.back(), ESM::NPC::Female)); + + npcColumns.mFlags.insert (std::make_pair (essential, ESM::NPC::Essential)); + + npcColumns.mFlags.insert (std::make_pair (respawn, ESM::NPC::Respawn)); + + npcColumns.mFlags.insert (std::make_pair (autoCalc, ESM::NPC::Autocalc)); + + npcColumns.mFlags.insert (std::make_pair (skeletonBlood, ESM::NPC::Skeleton)); + + npcColumns.mFlags.insert (std::make_pair (metalBlood, ESM::NPC::Metal)); + mAdapters.insert (std::make_pair (UniversalId::Type_Activator, new NameRefIdAdapter (UniversalId::Type_Activator, nameColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Potion, @@ -276,7 +318,7 @@ CSMWorld::RefIdCollection::RefIdCollection() mAdapters.insert (std::make_pair (UniversalId::Type_Miscellaneous, new MiscRefIdAdapter (inventoryColumns, key))); mAdapters.insert (std::make_pair (UniversalId::Type_Npc, - new ActorRefIdAdapter (UniversalId::Type_Npc, actorsColumns))); + new NpcRefIdAdapter (npcColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Probe, new ToolRefIdAdapter (UniversalId::Type_Probe, toolsColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Repair, From ca33d66ed91eff9078e63201f8296ddddd4241ae Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 19 May 2013 14:44:41 +0200 Subject: [PATCH 41/44] added missing columns for weapon records --- apps/opencs/model/world/columnbase.hpp | 3 +- apps/opencs/model/world/refidadapterimp.cpp | 89 +++++++++++++++++++++ apps/opencs/model/world/refidadapterimp.hpp | 30 +++++++ apps/opencs/model/world/refidcollection.cpp | 46 ++++++++++- apps/opencs/view/doc/viewmanager.cpp | 10 +++ 5 files changed, 176 insertions(+), 2 deletions(-) diff --git a/apps/opencs/model/world/columnbase.hpp b/apps/opencs/model/world/columnbase.hpp index 001ea4ff6..8cc435f3a 100644 --- a/apps/opencs/model/world/columnbase.hpp +++ b/apps/opencs/model/world/columnbase.hpp @@ -40,7 +40,8 @@ namespace CSMWorld Display_ApparatusType, Display_ArmorType, Display_ClothingType, - Display_CreatureType + Display_CreatureType, + Display_WeaponType }; std::string mTitle; diff --git a/apps/opencs/model/world/refidadapterimp.cpp b/apps/opencs/model/world/refidadapterimp.cpp index 59907b6d6..f00e9fc77 100644 --- a/apps/opencs/model/world/refidadapterimp.cpp +++ b/apps/opencs/model/world/refidadapterimp.cpp @@ -483,4 +483,93 @@ void CSMWorld::NpcRefIdAdapter::setData (const RefIdColumn *column, RefIdData& d else ActorRefIdAdapter::setData (column, data, index, value); } +} + +CSMWorld::WeaponColumns::WeaponColumns (const EnchantableColumns& columns) +: EnchantableColumns (columns) {} + +CSMWorld::WeaponRefIdAdapter::WeaponRefIdAdapter (const WeaponColumns& columns) +: EnchantableRefIdAdapter (UniversalId::Type_Weapon, columns), mColumns (columns) +{} + +QVariant CSMWorld::WeaponRefIdAdapter::getData (const RefIdColumn *column, const RefIdData& data, + int index) const +{ + const Record& record = static_cast&> ( + data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Weapon))); + + if (column==mColumns.mType) + return record.get().mData.mType; + + if (column==mColumns.mHealth) + return record.get().mData.mHealth; + + if (column==mColumns.mSpeed) + return record.get().mData.mSpeed; + + if (column==mColumns.mReach) + return record.get().mData.mReach; + + for (int i=0; i<2; ++i) + { + if (column==mColumns.mChop[i]) + return record.get().mData.mChop[i]; + + if (column==mColumns.mSlash[i]) + return record.get().mData.mSlash[i]; + + if (column==mColumns.mThrust[i]) + return record.get().mData.mThrust[i]; + } + + std::map::const_iterator iter = + mColumns.mFlags.find (column); + + if (iter!=mColumns.mFlags.end()) + return (record.get().mData.mFlags & iter->second)!=0; + + return EnchantableRefIdAdapter::getData (column, data, index); +} + +void CSMWorld::WeaponRefIdAdapter::setData (const RefIdColumn *column, RefIdData& data, int index, + const QVariant& value) const +{ + Record& record = static_cast&> ( + data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Weapon))); + + if (column==mColumns.mType) + record.get().mData.mType = value.toInt(); + else if (column==mColumns.mHealth) + record.get().mData.mHealth = value.toInt(); + else if (column==mColumns.mSpeed) + record.get().mData.mSpeed = value.toFloat(); + else if (column==mColumns.mReach) + record.get().mData.mReach = value.toFloat(); + else if (column==mColumns.mChop[0]) + record.get().mData.mChop[0] = value.toInt(); + else if (column==mColumns.mChop[1]) + record.get().mData.mChop[1] = value.toInt(); + else if (column==mColumns.mSlash[0]) + record.get().mData.mSlash[0] = value.toInt(); + else if (column==mColumns.mSlash[1]) + record.get().mData.mSlash[1] = value.toInt(); + else if (column==mColumns.mThrust[0]) + record.get().mData.mThrust[0] = value.toInt(); + else if (column==mColumns.mThrust[1]) + record.get().mData.mThrust[1] = value.toInt(); + else + { + std::map::const_iterator iter = + mColumns.mFlags.find (column); + + if (iter!=mColumns.mFlags.end()) + { + if (value.toInt()!=0) + record.get().mData.mFlags |= iter->second; + else + record.get().mData.mFlags &= ~iter->second; + } + else + EnchantableRefIdAdapter::setData (column, data, index, value); + } } \ No newline at end of file diff --git a/apps/opencs/model/world/refidadapterimp.hpp b/apps/opencs/model/world/refidadapterimp.hpp index 04569b16f..d5d84a8f7 100644 --- a/apps/opencs/model/world/refidadapterimp.hpp +++ b/apps/opencs/model/world/refidadapterimp.hpp @@ -731,6 +731,36 @@ namespace CSMWorld const QVariant& value) const; ///< If the data type does not match an exception is thrown. }; + + struct WeaponColumns : public EnchantableColumns + { + const RefIdColumn *mType; + const RefIdColumn *mHealth; + const RefIdColumn *mSpeed; + const RefIdColumn *mReach; + const RefIdColumn *mChop[2]; + const RefIdColumn *mSlash[2]; + const RefIdColumn *mThrust[2]; + std::map mFlags; + + WeaponColumns (const EnchantableColumns& columns); + }; + + class WeaponRefIdAdapter : public EnchantableRefIdAdapter + { + WeaponColumns mColumns; + + public: + + WeaponRefIdAdapter (const WeaponColumns& columns); + + virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) + const; + + virtual void setData (const RefIdColumn *column, RefIdData& data, int index, + const QVariant& value) const; + ///< If the data type does not match an exception is thrown. + }; } #endif diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index f7c697233..e11fe0fc8 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -286,6 +286,50 @@ CSMWorld::RefIdCollection::RefIdCollection() npcColumns.mFlags.insert (std::make_pair (metalBlood, ESM::NPC::Metal)); + WeaponColumns weaponColumns (enchantableColumns); + + mColumns.push_back (RefIdColumn ("Weapon Type", ColumnBase::Display_WeaponType)); + weaponColumns.mType = &mColumns.back(); + + weaponColumns.mHealth = health; + + mColumns.push_back (RefIdColumn ("Weapon Speed", ColumnBase::Display_Float)); + weaponColumns.mSpeed = &mColumns.back(); + + mColumns.push_back (RefIdColumn ("Weapon Reach", ColumnBase::Display_Float)); + weaponColumns.mReach = &mColumns.back(); + + for (int i=0; i<2; ++i) + { + std::string suffix = i==0 ? "Min " : "Max "; + + mColumns.push_back (RefIdColumn ("Chop" + suffix, ColumnBase::Display_Integer)); + weaponColumns.mChop[i] = &mColumns.back(); + + mColumns.push_back (RefIdColumn ("Slash" + suffix, ColumnBase::Display_Integer)); + weaponColumns.mSlash[i] = &mColumns.back(); + + mColumns.push_back (RefIdColumn ("Thrust" + suffix, ColumnBase::Display_Integer)); + weaponColumns.mThrust[i] = &mColumns.back(); + } + + static const struct + { + const char *mName; + unsigned int mFlag; + } sWeaponFlagTable[] = + { + { "Magical", ESM::Weapon::Magical }, + { "Silver", ESM::Weapon::Silver }, + { 0, 0 } + }; + + for (int i=0; sWeaponFlagTable[i].mName; ++i) + { + mColumns.push_back (RefIdColumn (sWeaponFlagTable[i].mName, ColumnBase::Display_Boolean)); + weaponColumns.mFlags.insert (std::make_pair (&mColumns.back(), sWeaponFlagTable[i].mFlag)); + } + mAdapters.insert (std::make_pair (UniversalId::Type_Activator, new NameRefIdAdapter (UniversalId::Type_Activator, nameColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Potion, @@ -326,7 +370,7 @@ CSMWorld::RefIdCollection::RefIdCollection() mAdapters.insert (std::make_pair (UniversalId::Type_Static, new ModelRefIdAdapter (UniversalId::Type_Static, modelColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Weapon, - new EnchantableRefIdAdapter (UniversalId::Type_Weapon, enchantableColumns))); + new WeaponRefIdAdapter (weaponColumns))); } CSMWorld::RefIdCollection::~RefIdCollection() diff --git a/apps/opencs/view/doc/viewmanager.cpp b/apps/opencs/view/doc/viewmanager.cpp index 4e0614450..e1c6ab7e1 100644 --- a/apps/opencs/view/doc/viewmanager.cpp +++ b/apps/opencs/view/doc/viewmanager.cpp @@ -76,6 +76,13 @@ CSVDoc::ViewManager::ViewManager (CSMDoc::DocumentManager& documentManager) "Creature", "Deadra", "Undead", "Humanoid", 0 }; + static const char *sWeaponTypes[] = + { + "Short Blade 1H", "Long Blade 1H", "Long Blade 2H", "Blunt 1H", "Blunt 2H Close", + "Blunt 2H Wide", "Spear 2H", "Axe 1H", "Axe 2H", "Bow", "Crossbow", "Thrown", "Arrow", + "Bolt", 0 + }; + mDelegateFactories = new CSVWorld::CommandDelegateFactoryCollection; mDelegateFactories->add (CSMWorld::ColumnBase::Display_GmstVarType, @@ -104,6 +111,9 @@ CSVDoc::ViewManager::ViewManager (CSMDoc::DocumentManager& documentManager) mDelegateFactories->add (CSMWorld::ColumnBase::Display_CreatureType, new CSVWorld::EnumDelegateFactory (sCreatureTypes)); + + mDelegateFactories->add (CSMWorld::ColumnBase::Display_WeaponType, + new CSVWorld::EnumDelegateFactory (sWeaponTypes)); } CSVDoc::ViewManager::~ViewManager() From 7a2d1cd8ceb0e0fc3fd92d29d6f10dd2908625b1 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 19 May 2013 18:40:37 +0200 Subject: [PATCH 42/44] Security skill --- apps/openmw/CMakeLists.txt | 2 +- apps/openmw/mwgui/container.cpp | 2 +- apps/openmw/mwinput/inputmanagerimp.cpp | 6 ++ apps/openmw/mwmechanics/security.cpp | 118 ++++++++++++++++++++++ apps/openmw/mwmechanics/security.hpp | 19 ++++ apps/openmw/mwrender/animation.cpp | 8 ++ apps/openmw/mwrender/animation.hpp | 3 + apps/openmw/mwrender/characterpreview.cpp | 5 +- apps/openmw/mwrender/characterpreview.hpp | 2 - apps/openmw/mwrender/npcanimation.cpp | 2 - apps/openmw/mwworld/player.cpp | 43 ++++++++ apps/openmw/mwworld/player.hpp | 3 + 12 files changed, 205 insertions(+), 8 deletions(-) create mode 100644 apps/openmw/mwmechanics/security.cpp create mode 100644 apps/openmw/mwmechanics/security.hpp diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index 306ef4173..660e45115 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -67,7 +67,7 @@ add_openmw_dir (mwclass add_openmw_dir (mwmechanics mechanicsmanagerimp stat character creaturestats magiceffects movement actors objects drawstate spells activespells npcstats aipackage aisequence alchemy aiwander aitravel aifollow - aiescort aiactivate repair enchanting pathfinding + aiescort aiactivate repair enchanting pathfinding security ) add_openmw_dir (mwbase diff --git a/apps/openmw/mwgui/container.cpp b/apps/openmw/mwgui/container.cpp index 60cb186e2..85c2cf5fb 100644 --- a/apps/openmw/mwgui/container.cpp +++ b/apps/openmw/mwgui/container.cpp @@ -233,6 +233,7 @@ namespace MWGui { // transfer everything into the player's inventory ItemModel* playerModel = MWBase::Environment::get().getWindowManager()->getInventoryWindow()->getModel(); + mModel->update(); for (size_t i=0; igetItemCount(); ++i) { if (i==0) @@ -257,7 +258,6 @@ namespace MWGui { onTakeAllButtonClicked(mTakeButton); - /// \todo if corpse is non-disposable: messagebox #{sDisposeCorpseFail} if (MWWorld::Class::get(mPtr).isPersistent(mPtr)) MWBase::Environment::get().getWindowManager()->messageBox("#{sDisposeCorpseFail}"); else diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index b31d51e6e..00c520de9 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -241,6 +241,10 @@ namespace MWInput case A_ToggleHUD: mWindows.toggleHud(); break; + case A_Use: + if (!MWBase::Environment::get().getWindowManager()->isGuiMode()) + mPlayer.use(); + break; } } } @@ -803,6 +807,7 @@ namespace MWInput { std::map descriptions; + descriptions[A_Use] = "sUse"; descriptions[A_Activate] = "sActivate"; descriptions[A_MoveBackward] = "sBack"; descriptions[A_MoveForward] = "sForward"; @@ -865,6 +870,7 @@ namespace MWInput ret.push_back(A_AlwaysRun); ret.push_back(A_Sneak); ret.push_back(A_Activate); + ret.push_back(A_Use); ret.push_back(A_ToggleWeapon); ret.push_back(A_ToggleSpell); ret.push_back(A_AutoMove); diff --git a/apps/openmw/mwmechanics/security.cpp b/apps/openmw/mwmechanics/security.cpp new file mode 100644 index 000000000..818412b8e --- /dev/null +++ b/apps/openmw/mwmechanics/security.cpp @@ -0,0 +1,118 @@ +#include "security.hpp" + +#include "../mwworld/class.hpp" +#include "../mwworld/player.hpp" + +#include "../mwbase/world.hpp" +#include "../mwbase/environment.hpp" +#include "../mwbase/windowmanager.hpp" + +#include "npcstats.hpp" +#include "creaturestats.hpp" + +namespace MWMechanics +{ + + void Security::pickLock(const MWWorld::Ptr &actor, const MWWorld::Ptr &lock, const MWWorld::Ptr &lockpick) + { + if (lock.getCellRef().mLockLevel <= 0) + return; + + int lockStrength = lock.getCellRef().mLockLevel; + + float pickQuality = lockpick.get()->mBase->mData.mQuality; + + CreatureStats& creatureStats = MWWorld::Class::get(actor).getCreatureStats(actor); + NpcStats& npcStats = MWWorld::Class::get(actor).getNpcStats(actor); + float pcAgility = creatureStats.getAttribute(ESM::Attribute::Agility).getModified(); + float pcLuck = creatureStats.getAttribute(ESM::Attribute::Luck).getModified(); + float securitySkill = npcStats.getSkill(ESM::Skill::Security).getModified(); + float fatigueTerm = creatureStats.getFatigueTerm(); + + float fPickLockMult = MWBase::Environment::get().getWorld()->getStore().get().find("fPickLockMult")->getFloat(); + + float x = 0.2 * pcAgility + 0.1 * pcLuck + securitySkill; + x *= pickQuality * fatigueTerm; + x += fPickLockMult * lockStrength; + + bool isPlayer = actor == MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + + if (x <= 0) + { + if (isPlayer) + MWBase::Environment::get().getWindowManager()->messageBox("#{sLockImpossible}"); + } + else + { + int roll = static_cast (std::rand()) / RAND_MAX * 100; + if (roll <= x) + { + MWWorld::Class::get(lock).unlock(lock); + if (isPlayer) + MWBase::Environment::get().getWindowManager()->messageBox("#{sLockSuccess}"); + MWWorld::Class::get(actor).skillUsageSucceeded(actor, ESM::Skill::Security, 1); + } + else if (isPlayer) + MWBase::Environment::get().getWindowManager()->messageBox("#{sLockFail}"); + } + + if (lockpick.getCellRef().mCharge == -1) + lockpick.getCellRef().mCharge = lockpick.get()->mBase->mData.mUses; + --lockpick.getCellRef().mCharge; + if (!lockpick.getCellRef().mCharge) + lockpick.getRefData().setCount(0); + } + + void Security::probeTrap(const MWWorld::Ptr &actor, const MWWorld::Ptr &trap, const MWWorld::Ptr &probe) + { + if (trap.getCellRef().mTrap == "") + return; + + CreatureStats& creatureStats = MWWorld::Class::get(actor).getCreatureStats(actor); + NpcStats& npcStats = MWWorld::Class::get(actor).getNpcStats(actor); + + float probeQuality = probe.get()->mBase->mData.mQuality; + + const ESM::Spell* trapSpell = MWBase::Environment::get().getWorld()->getStore().get().find(trap.getCellRef().mTrap); + float trapSpellPoints = trapSpell->mData.mCost; + + float pcAgility = creatureStats.getAttribute(ESM::Attribute::Agility).getModified(); + float pcLuck = creatureStats.getAttribute(ESM::Attribute::Luck).getModified(); + float securitySkill = npcStats.getSkill(ESM::Skill::Security).getModified(); + float fatigueTerm = creatureStats.getFatigueTerm(); + + float fTrapCostMult = MWBase::Environment::get().getWorld()->getStore().get().find("fTrapCostMult")->getFloat(); + + float x = 0.2 * pcAgility + 0.1 * pcLuck + securitySkill; + x += fTrapCostMult * trapSpellPoints; + x *= probeQuality * fatigueTerm; + + bool isPlayer = actor == MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + + if (x <= 0) + { + if (isPlayer) + MWBase::Environment::get().getWindowManager()->messageBox("#{sTrapImpossible}"); + } + else + { + int roll = static_cast (std::rand()) / RAND_MAX * 100; + if (roll <= x) + { + trap.getCellRef().mTrap = ""; + if (isPlayer) + MWBase::Environment::get().getWindowManager()->messageBox("#{sTrapSuccess}"); + MWWorld::Class::get(actor).skillUsageSucceeded(actor, ESM::Skill::Security, 0); + } + else if (isPlayer) + MWBase::Environment::get().getWindowManager()->messageBox("#{sTrapFail}"); + } + + if (probe.getCellRef().mCharge == -1) + probe.getCellRef().mCharge = probe.get()->mBase->mData.mUses; + --probe.getCellRef().mCharge; + if (!probe.getCellRef().mCharge) + probe.getRefData().setCount(0); + } + +} diff --git a/apps/openmw/mwmechanics/security.hpp b/apps/openmw/mwmechanics/security.hpp new file mode 100644 index 000000000..4d655f6e0 --- /dev/null +++ b/apps/openmw/mwmechanics/security.hpp @@ -0,0 +1,19 @@ +#ifndef MWMECHANICS_SECURITY_H +#define MWMECHANICS_SECURITY_H + +#include "../mwworld/ptr.hpp" + +namespace MWMechanics +{ + + /// @brief implementation of Security skill + class Security + { + public: + static void pickLock (const MWWorld::Ptr& actor, const MWWorld::Ptr& lock, const MWWorld::Ptr& lockpick); + static void probeTrap (const MWWorld::Ptr& actor, const MWWorld::Ptr& trap, const MWWorld::Ptr& probe); + }; + +} + +#endif diff --git a/apps/openmw/mwrender/animation.cpp b/apps/openmw/mwrender/animation.cpp index 7dc6cfc13..853ffc375 100644 --- a/apps/openmw/mwrender/animation.cpp +++ b/apps/openmw/mwrender/animation.cpp @@ -728,4 +728,12 @@ void Animation::showWeapons(bool showWeapon) { } +bool Animation::isPriorityActive(int priority) const +{ + for (AnimStateMap::const_iterator it = mStates.begin(); it != mStates.end(); ++it) + if (it->second.mPriority == priority) + return true; + return false; +} + } diff --git a/apps/openmw/mwrender/animation.hpp b/apps/openmw/mwrender/animation.hpp index 443b5b7b4..31be0fb2a 100644 --- a/apps/openmw/mwrender/animation.hpp +++ b/apps/openmw/mwrender/animation.hpp @@ -148,6 +148,9 @@ public: bool hasAnimation(const std::string &anim); + bool isPriorityActive (int priority) const; + ///< Is there an animation playing with the given priority? + // Specifies the axis' to accumulate on. Non-accumulated axis will just // move visually, but not affect the actual movement. Each x/y/z value // should be on the scale of 0 to 1. diff --git a/apps/openmw/mwrender/characterpreview.cpp b/apps/openmw/mwrender/characterpreview.cpp index c931c8e00..e4bba289f 100644 --- a/apps/openmw/mwrender/characterpreview.cpp +++ b/apps/openmw/mwrender/characterpreview.cpp @@ -193,6 +193,7 @@ namespace MWRender mNode->setOrientation (Ogre::Quaternion::IDENTITY); mRenderTarget->update(); + mSelectionBuffer->update(); } @@ -203,8 +204,8 @@ namespace MWRender void InventoryPreview::onSetup () { - if (!mSelectionBuffer) - mSelectionBuffer = new OEngine::Render::SelectionBuffer(mCamera, 512, 1024, 0); + delete mSelectionBuffer; + mSelectionBuffer = new OEngine::Render::SelectionBuffer(mCamera, 512, 1024, 0); mAnimation->showWeapons(true); diff --git a/apps/openmw/mwrender/characterpreview.hpp b/apps/openmw/mwrender/characterpreview.hpp index d8f43f71b..562cb3784 100644 --- a/apps/openmw/mwrender/characterpreview.hpp +++ b/apps/openmw/mwrender/characterpreview.hpp @@ -73,8 +73,6 @@ namespace MWRender int getSlotSelected(int posX, int posY); - void setNpcAnimation (NpcAnimation* anim); - private: OEngine::Render::SelectionBuffer* mSelectionBuffer; diff --git a/apps/openmw/mwrender/npcanimation.cpp b/apps/openmw/mwrender/npcanimation.cpp index f0df1ba4b..b5f2ea031 100644 --- a/apps/openmw/mwrender/npcanimation.cpp +++ b/apps/openmw/mwrender/npcanimation.cpp @@ -128,8 +128,6 @@ void NpcAnimation::setViewMode(NpcAnimation::ViewMode viewMode) assert(viewMode != VM_HeadOnly); mViewMode = viewMode; - Ogre::SceneNode *node = mInsert->getParentSceneNode(); - const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore(); const ESM::Race *race = store.get().find(mNpc->mRace); bool isBeast = (race->mData.mFlags & ESM::Race::Beast) != 0; diff --git a/apps/openmw/mwworld/player.cpp b/apps/openmw/mwworld/player.cpp index 08d908e62..ca604f55d 100644 --- a/apps/openmw/mwworld/player.cpp +++ b/apps/openmw/mwworld/player.cpp @@ -2,11 +2,18 @@ #include "player.hpp" #include "../mwbase/environment.hpp" +#include "../mwbase/world.hpp" +#include "../mwbase/windowmanager.hpp" #include "../mwworld/ptr.hpp" +#include "../mwworld/inventorystore.hpp" #include "../mwmechanics/movement.hpp" #include "../mwmechanics/npcstats.hpp" +#include "../mwmechanics/character.hpp" +#include "../mwmechanics/security.hpp" + +#include "../mwrender/animation.hpp" #include "class.hpp" @@ -133,6 +140,42 @@ namespace MWWorld MWWorld::Class::get(ptr).getMovementSettings(ptr).mRotation[1] = roll; } + void Player::use() + { + MWWorld::InventoryStore& store = MWWorld::Class::get(getPlayer()).getInventoryStore(getPlayer()); + MWWorld::ContainerStoreIterator equipped = store.getSlot(MWWorld::InventoryStore::Slot_CarriedRight); + + if (getDrawState() == MWMechanics::DrawState_Weapon) + { + if (equipped != store.end()) + { + MWWorld::Ptr item = *equipped; + MWRender::Animation* anim = MWBase::Environment::get().getWorld()->getAnimation(getPlayer()); + MWWorld::Ptr target = MWBase::Environment::get().getWorld()->getFacedObject(); + + if (anim->isPriorityActive(MWMechanics::Priority_Weapon)) + return; + + if (item.getTypeName() == typeid(ESM::Lockpick).name()) + { + if (!target.isEmpty()) + MWMechanics::Security::pickLock(getPlayer(), target, item); + anim->play("pickprobe", MWMechanics::Priority_Weapon, MWRender::Animation::Group_UpperBody, true, "start", "stop", 0.0, 0); + } + else if (item.getTypeName() == typeid(ESM::Probe).name()) + { + if (!target.isEmpty()) + MWMechanics::Security::probeTrap(getPlayer(), target, item); + anim->play("pickprobe", MWMechanics::Priority_Weapon, MWRender::Animation::Group_UpperBody, true, "start", "stop", 0.0, 0); + } + + // tool used up? + if (!item.getRefData().getCount()) + MWBase::Environment::get().getWindowManager()->setSelectedWeapon(MWWorld::Ptr()); + } + } + } + MWMechanics::DrawState_ Player::getDrawState() { MWWorld::Ptr ptr = getPlayer(); diff --git a/apps/openmw/mwworld/player.hpp b/apps/openmw/mwworld/player.hpp index f51d8f890..fd25f749f 100644 --- a/apps/openmw/mwworld/player.hpp +++ b/apps/openmw/mwworld/player.hpp @@ -58,6 +58,9 @@ namespace MWWorld void setForwardBackward (int value); void setUpDown(int value); + void use (); + ///< Use item equipped on right hand, or fists + void setRunState(bool run); void setSneak(bool sneak); From 5173779f4b20925a40b9835711b4b6884d412886 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 19 May 2013 19:48:51 +0200 Subject: [PATCH 43/44] Add sounds for security skill --- apps/openmw/mwmechanics/security.cpp | 39 ++++++++++++---------------- apps/openmw/mwmechanics/security.hpp | 6 +++-- apps/openmw/mwworld/player.cpp | 12 +++++++-- 3 files changed, 31 insertions(+), 26 deletions(-) diff --git a/apps/openmw/mwmechanics/security.cpp b/apps/openmw/mwmechanics/security.cpp index 818412b8e..11edc6450 100644 --- a/apps/openmw/mwmechanics/security.cpp +++ b/apps/openmw/mwmechanics/security.cpp @@ -13,7 +13,8 @@ namespace MWMechanics { - void Security::pickLock(const MWWorld::Ptr &actor, const MWWorld::Ptr &lock, const MWWorld::Ptr &lockpick) + void Security::pickLock(const MWWorld::Ptr &actor, const MWWorld::Ptr &lock, const MWWorld::Ptr &lockpick, + std::string& resultMessage, std::string& resultSound) { if (lock.getCellRef().mLockLevel <= 0) return; @@ -35,25 +36,21 @@ namespace MWMechanics x *= pickQuality * fatigueTerm; x += fPickLockMult * lockStrength; - bool isPlayer = actor == MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); - + resultSound = "Open Lock Fail"; if (x <= 0) - { - if (isPlayer) - MWBase::Environment::get().getWindowManager()->messageBox("#{sLockImpossible}"); - } + resultMessage = "#{sLockImpossible}"; else { int roll = static_cast (std::rand()) / RAND_MAX * 100; if (roll <= x) { MWWorld::Class::get(lock).unlock(lock); - if (isPlayer) - MWBase::Environment::get().getWindowManager()->messageBox("#{sLockSuccess}"); + resultMessage = "#{sLockSuccess}"; + resultSound = "Open Lock"; MWWorld::Class::get(actor).skillUsageSucceeded(actor, ESM::Skill::Security, 1); } - else if (isPlayer) - MWBase::Environment::get().getWindowManager()->messageBox("#{sLockFail}"); + else + resultMessage = "#{sLockFail}"; } if (lockpick.getCellRef().mCharge == -1) @@ -63,7 +60,8 @@ namespace MWMechanics lockpick.getRefData().setCount(0); } - void Security::probeTrap(const MWWorld::Ptr &actor, const MWWorld::Ptr &trap, const MWWorld::Ptr &probe) + void Security::probeTrap(const MWWorld::Ptr &actor, const MWWorld::Ptr &trap, const MWWorld::Ptr &probe, + std::string& resultMessage, std::string& resultSound) { if (trap.getCellRef().mTrap == "") return; @@ -87,25 +85,22 @@ namespace MWMechanics x += fTrapCostMult * trapSpellPoints; x *= probeQuality * fatigueTerm; - bool isPlayer = actor == MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); - + resultSound = "Disarm Trap Fail"; if (x <= 0) - { - if (isPlayer) - MWBase::Environment::get().getWindowManager()->messageBox("#{sTrapImpossible}"); - } + resultMessage = "#{sTrapImpossible}"; else { int roll = static_cast (std::rand()) / RAND_MAX * 100; if (roll <= x) { trap.getCellRef().mTrap = ""; - if (isPlayer) - MWBase::Environment::get().getWindowManager()->messageBox("#{sTrapSuccess}"); + + resultSound = "Disarm Trap"; + resultMessage = "#{sTrapSuccess}"; MWWorld::Class::get(actor).skillUsageSucceeded(actor, ESM::Skill::Security, 0); } - else if (isPlayer) - MWBase::Environment::get().getWindowManager()->messageBox("#{sTrapFail}"); + else + resultMessage = "#{sTrapFail}"; } if (probe.getCellRef().mCharge == -1) diff --git a/apps/openmw/mwmechanics/security.hpp b/apps/openmw/mwmechanics/security.hpp index 4d655f6e0..17a914459 100644 --- a/apps/openmw/mwmechanics/security.hpp +++ b/apps/openmw/mwmechanics/security.hpp @@ -10,8 +10,10 @@ namespace MWMechanics class Security { public: - static void pickLock (const MWWorld::Ptr& actor, const MWWorld::Ptr& lock, const MWWorld::Ptr& lockpick); - static void probeTrap (const MWWorld::Ptr& actor, const MWWorld::Ptr& trap, const MWWorld::Ptr& probe); + static void pickLock (const MWWorld::Ptr& actor, const MWWorld::Ptr& lock, const MWWorld::Ptr& lockpick, + std::string& resultMessage, std::string& resultSound); + static void probeTrap (const MWWorld::Ptr& actor, const MWWorld::Ptr& trap, const MWWorld::Ptr& probe, + std::string& resultMessage, std::string& resultSound); }; } diff --git a/apps/openmw/mwworld/player.cpp b/apps/openmw/mwworld/player.cpp index ca604f55d..b597dccf3 100644 --- a/apps/openmw/mwworld/player.cpp +++ b/apps/openmw/mwworld/player.cpp @@ -4,6 +4,7 @@ #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" #include "../mwbase/windowmanager.hpp" +#include "../mwbase/soundmanager.hpp" #include "../mwworld/ptr.hpp" #include "../mwworld/inventorystore.hpp" @@ -156,19 +157,26 @@ namespace MWWorld if (anim->isPriorityActive(MWMechanics::Priority_Weapon)) return; + std::string resultMessage, resultSound; + if (item.getTypeName() == typeid(ESM::Lockpick).name()) { if (!target.isEmpty()) - MWMechanics::Security::pickLock(getPlayer(), target, item); + MWMechanics::Security::pickLock(getPlayer(), target, item, resultMessage, resultSound); anim->play("pickprobe", MWMechanics::Priority_Weapon, MWRender::Animation::Group_UpperBody, true, "start", "stop", 0.0, 0); } else if (item.getTypeName() == typeid(ESM::Probe).name()) { if (!target.isEmpty()) - MWMechanics::Security::probeTrap(getPlayer(), target, item); + MWMechanics::Security::probeTrap(getPlayer(), target, item, resultMessage, resultSound); anim->play("pickprobe", MWMechanics::Priority_Weapon, MWRender::Animation::Group_UpperBody, true, "start", "stop", 0.0, 0); } + if (!resultMessage.empty()) + MWBase::Environment::get().getWindowManager()->messageBox(resultMessage); + if (!resultSound.empty()) + MWBase::Environment::get().getSoundManager()->playSound(resultSound,1,1); + // tool used up? if (!item.getRefData().getCount()) MWBase::Environment::get().getWindowManager()->setSelectedWeapon(MWWorld::Ptr()); From 2715520d6fba458d0e0549de51b5ddccd4e68a68 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 19 May 2013 23:19:48 +0200 Subject: [PATCH 44/44] Cleanup Security class --- apps/openmw/mwmechanics/security.cpp | 41 ++++++++++++---------------- apps/openmw/mwmechanics/security.hpp | 10 +++++-- apps/openmw/mwworld/player.cpp | 4 +-- 3 files changed, 28 insertions(+), 27 deletions(-) diff --git a/apps/openmw/mwmechanics/security.cpp b/apps/openmw/mwmechanics/security.cpp index 11edc6450..090e8ced3 100644 --- a/apps/openmw/mwmechanics/security.cpp +++ b/apps/openmw/mwmechanics/security.cpp @@ -13,7 +13,17 @@ namespace MWMechanics { - void Security::pickLock(const MWWorld::Ptr &actor, const MWWorld::Ptr &lock, const MWWorld::Ptr &lockpick, + Security::Security(const MWWorld::Ptr &actor) + { + CreatureStats& creatureStats = MWWorld::Class::get(actor).getCreatureStats(actor); + NpcStats& npcStats = MWWorld::Class::get(actor).getNpcStats(actor); + mAgility = creatureStats.getAttribute(ESM::Attribute::Agility).getModified(); + mLuck = creatureStats.getAttribute(ESM::Attribute::Luck).getModified(); + mSecuritySkill = npcStats.getSkill(ESM::Skill::Security).getModified(); + mFatigueTerm = creatureStats.getFatigueTerm(); + } + + void Security::pickLock(const MWWorld::Ptr &lock, const MWWorld::Ptr &lockpick, std::string& resultMessage, std::string& resultSound) { if (lock.getCellRef().mLockLevel <= 0) @@ -23,17 +33,10 @@ namespace MWMechanics float pickQuality = lockpick.get()->mBase->mData.mQuality; - CreatureStats& creatureStats = MWWorld::Class::get(actor).getCreatureStats(actor); - NpcStats& npcStats = MWWorld::Class::get(actor).getNpcStats(actor); - float pcAgility = creatureStats.getAttribute(ESM::Attribute::Agility).getModified(); - float pcLuck = creatureStats.getAttribute(ESM::Attribute::Luck).getModified(); - float securitySkill = npcStats.getSkill(ESM::Skill::Security).getModified(); - float fatigueTerm = creatureStats.getFatigueTerm(); - float fPickLockMult = MWBase::Environment::get().getWorld()->getStore().get().find("fPickLockMult")->getFloat(); - float x = 0.2 * pcAgility + 0.1 * pcLuck + securitySkill; - x *= pickQuality * fatigueTerm; + float x = 0.2 * mAgility + 0.1 * mLuck + mSecuritySkill; + x *= pickQuality * mFatigueTerm; x += fPickLockMult * lockStrength; resultSound = "Open Lock Fail"; @@ -47,7 +50,7 @@ namespace MWMechanics MWWorld::Class::get(lock).unlock(lock); resultMessage = "#{sLockSuccess}"; resultSound = "Open Lock"; - MWWorld::Class::get(actor).skillUsageSucceeded(actor, ESM::Skill::Security, 1); + MWWorld::Class::get(mActor).skillUsageSucceeded(mActor, ESM::Skill::Security, 1); } else resultMessage = "#{sLockFail}"; @@ -60,30 +63,22 @@ namespace MWMechanics lockpick.getRefData().setCount(0); } - void Security::probeTrap(const MWWorld::Ptr &actor, const MWWorld::Ptr &trap, const MWWorld::Ptr &probe, + void Security::probeTrap(const MWWorld::Ptr &trap, const MWWorld::Ptr &probe, std::string& resultMessage, std::string& resultSound) { if (trap.getCellRef().mTrap == "") return; - CreatureStats& creatureStats = MWWorld::Class::get(actor).getCreatureStats(actor); - NpcStats& npcStats = MWWorld::Class::get(actor).getNpcStats(actor); - float probeQuality = probe.get()->mBase->mData.mQuality; const ESM::Spell* trapSpell = MWBase::Environment::get().getWorld()->getStore().get().find(trap.getCellRef().mTrap); float trapSpellPoints = trapSpell->mData.mCost; - float pcAgility = creatureStats.getAttribute(ESM::Attribute::Agility).getModified(); - float pcLuck = creatureStats.getAttribute(ESM::Attribute::Luck).getModified(); - float securitySkill = npcStats.getSkill(ESM::Skill::Security).getModified(); - float fatigueTerm = creatureStats.getFatigueTerm(); - float fTrapCostMult = MWBase::Environment::get().getWorld()->getStore().get().find("fTrapCostMult")->getFloat(); - float x = 0.2 * pcAgility + 0.1 * pcLuck + securitySkill; + float x = 0.2 * mAgility + 0.1 * mLuck + mSecuritySkill; x += fTrapCostMult * trapSpellPoints; - x *= probeQuality * fatigueTerm; + x *= probeQuality * mFatigueTerm; resultSound = "Disarm Trap Fail"; if (x <= 0) @@ -97,7 +92,7 @@ namespace MWMechanics resultSound = "Disarm Trap"; resultMessage = "#{sTrapSuccess}"; - MWWorld::Class::get(actor).skillUsageSucceeded(actor, ESM::Skill::Security, 0); + MWWorld::Class::get(mActor).skillUsageSucceeded(mActor, ESM::Skill::Security, 0); } else resultMessage = "#{sTrapFail}"; diff --git a/apps/openmw/mwmechanics/security.hpp b/apps/openmw/mwmechanics/security.hpp index 17a914459..f3efb04ed 100644 --- a/apps/openmw/mwmechanics/security.hpp +++ b/apps/openmw/mwmechanics/security.hpp @@ -10,10 +10,16 @@ namespace MWMechanics class Security { public: - static void pickLock (const MWWorld::Ptr& actor, const MWWorld::Ptr& lock, const MWWorld::Ptr& lockpick, + Security (const MWWorld::Ptr& actor); + + void pickLock (const MWWorld::Ptr& lock, const MWWorld::Ptr& lockpick, std::string& resultMessage, std::string& resultSound); - static void probeTrap (const MWWorld::Ptr& actor, const MWWorld::Ptr& trap, const MWWorld::Ptr& probe, + void probeTrap (const MWWorld::Ptr& trap, const MWWorld::Ptr& probe, std::string& resultMessage, std::string& resultSound); + + private: + float mAgility, mLuck, mSecuritySkill, mFatigueTerm; + MWWorld::Ptr mActor; }; } diff --git a/apps/openmw/mwworld/player.cpp b/apps/openmw/mwworld/player.cpp index b597dccf3..ebc9cd86d 100644 --- a/apps/openmw/mwworld/player.cpp +++ b/apps/openmw/mwworld/player.cpp @@ -162,13 +162,13 @@ namespace MWWorld if (item.getTypeName() == typeid(ESM::Lockpick).name()) { if (!target.isEmpty()) - MWMechanics::Security::pickLock(getPlayer(), target, item, resultMessage, resultSound); + MWMechanics::Security(getPlayer()).pickLock(target, item, resultMessage, resultSound); anim->play("pickprobe", MWMechanics::Priority_Weapon, MWRender::Animation::Group_UpperBody, true, "start", "stop", 0.0, 0); } else if (item.getTypeName() == typeid(ESM::Probe).name()) { if (!target.isEmpty()) - MWMechanics::Security::probeTrap(getPlayer(), target, item, resultMessage, resultSound); + MWMechanics::Security(getPlayer()).probeTrap(target, item, resultMessage, resultSound); anim->play("pickprobe", MWMechanics::Priority_Weapon, MWRender::Animation::Group_UpperBody, true, "start", "stop", 0.0, 0); }