From ade27293be7cd76163c917602c8d092925623367 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Fri, 25 Jul 2014 17:11:18 +0200 Subject: [PATCH] handling destination for guides --- apps/opencs/model/world/columnbase.hpp | 1 + apps/opencs/model/world/columns.cpp | 9 ++ apps/opencs/model/world/columns.hpp | 8 ++ apps/opencs/model/world/nestedadaptors.hpp | 145 ++++++++++++++++++++ apps/opencs/model/world/refidadapter.cpp | 5 + apps/opencs/model/world/refidadapter.hpp | 3 + apps/opencs/model/world/refidadapterimp.cpp | 9 +- apps/opencs/model/world/refidadapterimp.hpp | 1 + apps/opencs/model/world/refidcollection.cpp | 10 ++ 9 files changed, 189 insertions(+), 2 deletions(-) diff --git a/apps/opencs/model/world/columnbase.hpp b/apps/opencs/model/world/columnbase.hpp index 5e4dac3ce..05fecaec0 100644 --- a/apps/opencs/model/world/columnbase.hpp +++ b/apps/opencs/model/world/columnbase.hpp @@ -95,6 +95,7 @@ namespace CSMWorld //Those are top level columns that nest other columns Display_NestedItemList, Display_NestedSpellList, + Display_NestedDestinationsList, Display_EnchantmentType, Display_BodyPartType, diff --git a/apps/opencs/model/world/columns.cpp b/apps/opencs/model/world/columns.cpp index 1f13645da..212772450 100644 --- a/apps/opencs/model/world/columns.cpp +++ b/apps/opencs/model/world/columns.cpp @@ -174,6 +174,7 @@ namespace CSMWorld { ColumnId_PcRank, "PC Rank" }, { ColumnId_Scope, "Scope" }, { ColumnId_ReferenceableId, "Referenceable ID" }, + { ColumnId_NpcDestinations, "Destinations" }, { ColumnId_InventoryItemId, "ID"}, { ColumnId_SpellId, "ID"}, { ColumnId_ItemCount, "Count"}, @@ -184,6 +185,14 @@ namespace CSMWorld { ColumnId_Vampire, "Vampire" }, { ColumnId_BodyPartType, "Bodypart Type" }, { ColumnId_MeshType, "Mesh Type" }, + + { ColumnId_NpcDestinations, "Cell"}, + { ColumnId_PosX, "X"}, + { ColumnId_PosY, "Y"}, + { ColumnId_PosZ, "Z"}, + { ColumnId_RotX, "Rotation X"}, + { ColumnId_RotY, "Rotation Y"}, + { ColumnId_RotZ, "Rotation Z"}, { ColumnId_UseValue1, "Use value 1" }, { ColumnId_UseValue2, "Use value 2" }, diff --git a/apps/opencs/model/world/columns.hpp b/apps/opencs/model/world/columns.hpp index 908165e9d..7efaf2bd0 100644 --- a/apps/opencs/model/world/columns.hpp +++ b/apps/opencs/model/world/columns.hpp @@ -182,6 +182,14 @@ namespace CSMWorld ColumnId_ActorInventory = 167, ColumnId_ActorSpells = 168, ColumnId_SpellId = 169, + ColumnId_NpcDestinations = 170, + ColumnId_PosX = 171, + ColumnId_PosY = 172, + ColumnId_PosZ = 173, + ColumnId_RotX = 174, + ColumnId_RotY = 175, + ColumnId_RotZ = 176, + ColumnId_DestinationCell = 177, // Allocated to a separate value range, so we don't get a collision should we ever need // to extend the number of use values. diff --git a/apps/opencs/model/world/nestedadaptors.hpp b/apps/opencs/model/world/nestedadaptors.hpp index 095bcdf95..319fe1569 100644 --- a/apps/opencs/model/world/nestedadaptors.hpp +++ b/apps/opencs/model/world/nestedadaptors.hpp @@ -11,6 +11,8 @@ #include "refiddata.hpp" #include "refidadapter.hpp" #include +#include +#include #include @@ -172,6 +174,149 @@ namespace CSMWorld }; + template + class DestinationsHelper : public CastableHelper + { + public: + + DestinationsHelper(CSMWorld::UniversalId::Type type) + : CastableHelper(type) {} + + virtual void setNestedTable(RefIdData& data, + int index, + const NestedTableWrapperBase& nestedTable) + { + CastableHelper::getRecord(data, index).get().mTransport = + (static_cast >&>(nestedTable)).mNestedTable; + } + + virtual NestedTableWrapperBase* nestedTable(const RefIdData& data, + int index) const + { + return new NestedTableWrapper >(CastableHelper::getRecord(data, index).get().mTransport); + } + + virtual QVariant getNestedData(const CSMWorld::RefIdData& data, + int index, + int subRowIndex, + int subColIndex) const + { + const ESM::NPC::Dest& content = CastableHelper::getRecord(data, index).get().mTransport.at(subRowIndex); + + switch (subColIndex) + { + case 0: + return QString::fromUtf8(content.mCellName.c_str()); + + case 1: + return content.mPos.pos[0]; + + case 2: + return content.mPos.pos[1]; + + case 3: + return content.mPos.pos[2]; + + case 4: + return content.mPos.rot[0]; + + case 5: + return content.mPos.rot[1]; + + case 6: + return content.mPos.rot[2]; + + default: + throw std::logic_error("Trying to access non-existing column in the nested table!"); + } + } + + virtual void removeNestedRow (RefIdData& data, int index, int rowToRemove) const + { + std::vector& list = CastableHelper::getRecord(data, index).get().mTransport; + + list.erase (list.begin () + rowToRemove); + } + + void setNestedData (RefIdData& data, + int index, + const QVariant& value, + int subRowIndex, + int subColIndex) const + { + switch(subColIndex) + { + case 0: + CastableHelper::getRecord(data, index).get().mTransport.at(subRowIndex).mCellName = std::string(value.toString().toUtf8().constData()); + break; + + case 1: + CastableHelper::getRecord(data, index).get().mTransport.at(subRowIndex).mPos.pos[0] = value.toFloat(); + break; + + case 2: + CastableHelper::getRecord(data, index).get().mTransport.at(subRowIndex).mPos.pos[1] = value.toFloat(); + break; + + case 3: + CastableHelper::getRecord(data, index).get().mTransport.at(subRowIndex).mPos.pos[2] = value.toFloat(); + break; + + case 4: + CastableHelper::getRecord(data, index).get().mTransport.at(subRowIndex).mPos.rot[0] = value.toFloat(); + break; + + case 5: + CastableHelper::getRecord(data, index).get().mTransport.at(subRowIndex).mPos.rot[1] = value.toFloat(); + break; + + case 6: + CastableHelper::getRecord(data, index).get().mTransport.at(subRowIndex).mPos.rot[2] = value.toFloat(); + break; + + default: + throw std::logic_error("Trying to access non-existing column in the nested table!"); + } + } + + virtual void addNestedRow (RefIdData& data, int index, int position) const + { + std::vector& list = CastableHelper::getRecord(data, index).get().mTransport; + + ESM::Position newPos; + for (unsigned i = 0; i < 3; ++i) + { + newPos.pos[i] = 0; + newPos.rot[i] = 0; + } + + ESM::NPC::Dest newRow; + newRow.mPos = newPos; + newRow.mCellName = ""; + + if (position >= (int)list.size()) + { + list.push_back(newRow); + return; + } + + list.insert(list.begin()+position, newRow); + } + + virtual int getNestedColumnsCount(const RefIdData& data) const + { + return 7; + } + + + virtual int getNestedRowsCount(const RefIdData& data, + int index) const + { + return CastableHelper::getRecord(data, index).get().mTransport.size(); + } + + }; + template class InventoryHelper : public CastableHelper { diff --git a/apps/opencs/model/world/refidadapter.cpp b/apps/opencs/model/world/refidadapter.cpp index 631c192fd..58b775f47 100644 --- a/apps/opencs/model/world/refidadapter.cpp +++ b/apps/opencs/model/world/refidadapter.cpp @@ -87,3 +87,8 @@ void CSMWorld::NestedRefIdAdapter::setAssocColumns(const std::vector& assocColumn) +{ + mAssociatedColumns.push_back(assocColumn); +} diff --git a/apps/opencs/model/world/refidadapter.hpp b/apps/opencs/model/world/refidadapter.hpp index 22941fd9f..d18e7f02e 100644 --- a/apps/opencs/model/world/refidadapter.hpp +++ b/apps/opencs/model/world/refidadapter.hpp @@ -106,6 +106,9 @@ namespace CSMWorld ///The ownership of the column pointers it not transfered (it is not surprising, since columns are created by collection). ///You MUST call this method to setup the nested adaptor! + void addAssocColumn(const std::pair & assocColumn); + ///Like setAssocColumn, when it is impossible to set all columns at once + private: HelperBase* getHelper(const RefIdColumn *column) const; diff --git a/apps/opencs/model/world/refidadapterimp.cpp b/apps/opencs/model/world/refidadapterimp.cpp index 18287d596..ac546db51 100644 --- a/apps/opencs/model/world/refidadapterimp.cpp +++ b/apps/opencs/model/world/refidadapterimp.cpp @@ -452,7 +452,9 @@ CSMWorld::NpcColumns::NpcColumns (const ActorColumns& actorColumns) : ActorColum CSMWorld::NpcRefIdAdapter::NpcRefIdAdapter (const NpcColumns& columns) : ActorRefIdAdapter (UniversalId::Type_Npc, columns), mColumns (columns) -{} +{ + NestedRefIdAdapter::addAssocColumn(std::make_pair(columns.mDestinations, new DestinationsHelper(UniversalId::Type_Npc))); +} QVariant CSMWorld::NpcRefIdAdapter::getData (const RefIdColumn *column, const RefIdData& data, int index) const @@ -474,13 +476,16 @@ QVariant CSMWorld::NpcRefIdAdapter::getData (const RefIdColumn *column, const Re if (column==mColumns.mHead) return QString::fromUtf8 (record.get().mHead.c_str()); + + if (column==mColumns.mDestinations) + return true; 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); } diff --git a/apps/opencs/model/world/refidadapterimp.hpp b/apps/opencs/model/world/refidadapterimp.hpp index 4c65da85c..6fd42b00e 100644 --- a/apps/opencs/model/world/refidadapterimp.hpp +++ b/apps/opencs/model/world/refidadapterimp.hpp @@ -742,6 +742,7 @@ namespace CSMWorld const RefIdColumn *mFaction; const RefIdColumn *mHair; const RefIdColumn *mHead; + const RefIdColumn *mDestinations; NpcColumns (const ActorColumns& actorColumns); }; diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index eb25b277e..d776931f8 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -315,6 +315,16 @@ CSMWorld::RefIdCollection::RefIdCollection() npcColumns.mFlags.insert (std::make_pair (metalBlood, ESM::NPC::Metal)); + mColumns.push_back(RefIdColumn (Columns::ColumnId_NpcDestinations, ColumnBase::Display_NestedDestinationsList, ColumnBase::Flag_Dialogue, true, true, true)); + npcColumns.mDestinations = &mColumns.back(); + mColumns.back().addNestedColumn(Columns::ColumnId_DestinationCell, CSMWorld::ColumnBase::Display_String); + mColumns.back().addNestedColumn(Columns::ColumnId_PosX, CSMWorld::ColumnBase::Display_Float); + mColumns.back().addNestedColumn(Columns::ColumnId_PosY, CSMWorld::ColumnBase::Display_Float); + mColumns.back().addNestedColumn(Columns::ColumnId_PosZ, CSMWorld::ColumnBase::Display_Float); + mColumns.back().addNestedColumn(Columns::ColumnId_RotX, CSMWorld::ColumnBase::Display_Float); + mColumns.back().addNestedColumn(Columns::ColumnId_RotY, CSMWorld::ColumnBase::Display_Float); + mColumns.back().addNestedColumn(Columns::ColumnId_RotZ, CSMWorld::ColumnBase::Display_Float); + WeaponColumns weaponColumns (enchantableColumns); mColumns.push_back (RefIdColumn (Columns::ColumnId_WeaponType, ColumnBase::Display_WeaponType));