1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-06-21 10:41:33 +00:00

Merge branch 'OpenCS-preserve-blocked' into 'master'

OpenCS - Preserve "blocked" record flags when saving. #6288

Closes #6288

See merge request OpenMW/openmw!1052
This commit is contained in:
psi29a 2021-09-27 19:21:20 +00:00
commit 782e0710af
44 changed files with 92 additions and 6 deletions

View file

@ -54,9 +54,11 @@
Feature #6199: Support FBO Rendering Feature #6199: Support FBO Rendering
Feature #6249: Alpha testing support for Collada Feature #6249: Alpha testing support for Collada
Feature #6251: OpenMW-CS: Set instance movement based on camera zoom Feature #6251: OpenMW-CS: Set instance movement based on camera zoom
Feature #6288: Preserve the "blocked" record flag for referenceable objects.
Task #6201: Remove the "Note: No relevant classes found. No output generated" warnings Task #6201: Remove the "Note: No relevant classes found. No output generated" warnings
Task #6264: Remove the old classes in animation.cpp Task #6264: Remove the old classes in animation.cpp
0.47.0 0.47.0
------ ------

View file

@ -108,7 +108,7 @@ namespace CSMDoc
state == CSMWorld::RecordBase::State_ModifiedOnly || state == CSMWorld::RecordBase::State_ModifiedOnly ||
state == CSMWorld::RecordBase::State_Deleted) state == CSMWorld::RecordBase::State_Deleted)
{ {
writer.startRecord (record.sRecordId); writer.startRecord (record.sRecordId, record.mRecordFlags);
record.save (writer, state == CSMWorld::RecordBase::State_Deleted); record.save (writer, state == CSMWorld::RecordBase::State_Deleted);
writer.endRecord (record.sRecordId); writer.endRecord (record.sRecordId);
} }

View file

@ -371,6 +371,7 @@ namespace CSMWorld
{ ColumnId_Skill7, "Skill 7" }, { ColumnId_Skill7, "Skill 7" },
{ ColumnId_Persistent, "Persistent" }, { ColumnId_Persistent, "Persistent" },
{ ColumnId_Blocked, "Blocked" },
{ -1, 0 } // end marker { -1, 0 } // end marker
}; };

View file

@ -344,6 +344,7 @@ namespace CSMWorld
ColumnId_FactionAttrib2 = 312, ColumnId_FactionAttrib2 = 312,
ColumnId_Persistent = 313, ColumnId_Persistent = 313,
ColumnId_Blocked = 314,
// Allocated to a separate value range, so we don't get a collision should we ever need // Allocated to a separate value range, so we don't get a collision should we ever need
// to extend the number of use values. // to extend the number of use values.

View file

@ -123,6 +123,14 @@ Qt::ItemFlags CSMWorld::IdTable::flags (const QModelIndex & index) const
if (mIdCollection->getColumn (index.column()).isUserEditable()) if (mIdCollection->getColumn (index.column()).isUserEditable())
flags |= Qt::ItemIsEditable; flags |= Qt::ItemIsEditable;
int blockedColumn = searchColumnIndex(Columns::ColumnId_Blocked);
if (blockedColumn != -1 && blockedColumn != index.column())
{
bool isBlocked = mIdCollection->getData(index.row(), blockedColumn).toInt();
if (isBlocked)
flags = Qt::ItemIsSelectable; // not enabled (to grey out)
}
return flags; return flags;
} }

View file

@ -25,6 +25,9 @@ namespace CSMWorld
const RefIdColumn *mId; const RefIdColumn *mId;
const RefIdColumn *mModified; const RefIdColumn *mModified;
const RefIdColumn *mType; const RefIdColumn *mType;
const RefIdColumn *mBlocked;
BaseColumns () : mBlocked(nullptr) {}
}; };
/// \brief Base adapter for all refereceable record types /// \brief Base adapter for all refereceable record types
@ -90,6 +93,9 @@ namespace CSMWorld
if (column==mBase.mType) if (column==mBase.mType)
return static_cast<int> (mType); return static_cast<int> (mType);
if (column==mBase.mBlocked)
return (record.get().mRecordFlags & ESM::FLAG_Blocked) != 0;
return QVariant(); return QVariant();
} }
@ -102,6 +108,17 @@ namespace CSMWorld
if (column==mBase.mModified) if (column==mBase.mModified)
record.mState = static_cast<RecordBase::State> (value.toInt()); record.mState = static_cast<RecordBase::State> (value.toInt());
else if (column==mBase.mBlocked)
{
RecordT record2 = record.get();
if (value.toInt() != 0)
record2.mRecordFlags |= ESM::FLAG_Blocked;
else
record2.mRecordFlags &= ~ESM::FLAG_Blocked;
record.setModified(record2);
}
} }
template<typename RecordT> template<typename RecordT>
@ -110,6 +127,14 @@ namespace CSMWorld
return mType; return mType;
} }
// NOTE: Body Part should not have persistence (but BodyPart is not listed in the Objects
// table at the moment).
//
// Spellmaking - not persistent - currently not part of objects table
// Enchanting - not persistent - currently not part of objects table
//
// Leveled Creature - no model, so not persistent
// Leveled Item - no model, so not persistent
struct ModelColumns : public BaseColumns struct ModelColumns : public BaseColumns
{ {

View file

@ -50,13 +50,16 @@ CSMWorld::RefIdCollection::RefIdCollection()
mColumns.emplace_back(Columns::ColumnId_RecordType, ColumnBase::Display_RefRecordType, mColumns.emplace_back(Columns::ColumnId_RecordType, ColumnBase::Display_RefRecordType,
ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue, false, false); ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue, false, false);
baseColumns.mType = &mColumns.back(); baseColumns.mType = &mColumns.back();
mColumns.emplace_back(Columns::ColumnId_Blocked, ColumnBase::Display_Boolean,
ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue | ColumnBase::Flag_Dialogue_Refresh);
baseColumns.mBlocked = &mColumns.back();
ModelColumns modelColumns (baseColumns); ModelColumns modelColumns (baseColumns);
mColumns.emplace_back(Columns::ColumnId_Model, ColumnBase::Display_Mesh);
modelColumns.mModel = &mColumns.back();
mColumns.emplace_back(Columns::ColumnId_Persistent, ColumnBase::Display_Boolean); mColumns.emplace_back(Columns::ColumnId_Persistent, ColumnBase::Display_Boolean);
modelColumns.mPersistence = &mColumns.back(); modelColumns.mPersistence = &mColumns.back();
mColumns.emplace_back(Columns::ColumnId_Model, ColumnBase::Display_Mesh);
modelColumns.mModel = &mColumns.back();
NameColumns nameColumns (modelColumns); NameColumns nameColumns (modelColumns);

View file

@ -538,6 +538,9 @@ void CSVWorld::EditWidget::remake(int row)
mainLayout->addLayout(tablesLayout, QSizePolicy::Preferred); mainLayout->addLayout(tablesLayout, QSizePolicy::Preferred);
mainLayout->addStretch(1); mainLayout->addStretch(1);
int blockedColumn = mTable->searchColumnIndex(CSMWorld::Columns::ColumnId_Blocked);
bool isBlocked = mTable->data(mTable->index(row, blockedColumn)).toInt();
int unlocked = 0; int unlocked = 0;
int locked = 0; int locked = 0;
const int columns = mTable->columnCount(); const int columns = mTable->columnCount();
@ -583,6 +586,8 @@ void CSVWorld::EditWidget::remake(int row)
NestedTable* table = NestedTable* table =
new NestedTable(mDocument, id, mNestedModels.back(), this, editable, fixedRows); new NestedTable(mDocument, id, mNestedModels.back(), this, editable, fixedRows);
table->resizeColumnsToContents(); table->resizeColumnsToContents();
if (isBlocked)
table->setEditTriggers(QAbstractItemView::NoEditTriggers);
int rows = mTable->rowCount(mTable->index(row, i)); int rows = mTable->rowCount(mTable->index(row, i));
int rowHeight = (rows == 0) ? table->horizontalHeader()->height() : table->rowHeight(0); int rowHeight = (rows == 0) ? table->horizontalHeader()->height() : table->rowHeight(0);
@ -617,7 +622,9 @@ void CSVWorld::EditWidget::remake(int row)
label->setSizePolicy (QSizePolicy::Fixed, QSizePolicy::Fixed); label->setSizePolicy (QSizePolicy::Fixed, QSizePolicy::Fixed);
editor->setSizePolicy (QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); editor->setSizePolicy (QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
if (! (mTable->flags (mTable->index (row, i)) & Qt::ItemIsEditable)) // HACK: the blocked checkbox needs to keep the same position
// FIXME: unfortunately blocked record displays a little differently to unblocked one
if (!(mTable->flags (mTable->index (row, i)) & Qt::ItemIsEditable) || i == blockedColumn)
{ {
lockedLayout->addWidget (label, locked, 0); lockedLayout->addWidget (label, locked, 0);
lockedLayout->addWidget (editor, locked, 1); lockedLayout->addWidget (editor, locked, 1);
@ -639,7 +646,7 @@ void CSVWorld::EditWidget::remake(int row)
createEditorContextMenu(editor, display, row); createEditorContextMenu(editor, display, row);
} }
} }
else else // Flag_Dialogue_List
{ {
CSMWorld::IdTree *tree = static_cast<CSMWorld::IdTree *>(mTable); CSMWorld::IdTree *tree = static_cast<CSMWorld::IdTree *>(mTable);
mNestedTableMapper = new QDataWidgetMapper (this); mNestedTableMapper = new QDataWidgetMapper (this);
@ -686,7 +693,10 @@ void CSVWorld::EditWidget::remake(int row)
label->setEnabled(false); label->setEnabled(false);
} }
if (!isBlocked)
createEditorContextMenu(editor, display, row); createEditorContextMenu(editor, display, row);
else
editor->setEnabled(false);
} }
} }
mNestedTableMapper->setCurrentModelIndex(tree->index(0, 0, tree->index(row, i))); mNestedTableMapper->setCurrentModelIndex(tree->index(0, 0, tree->index(row, i)));

View file

@ -9,6 +9,7 @@ unsigned int ESM::DebugProfile::sRecordId = REC_DBGP;
void ESM::DebugProfile::load (ESMReader& esm, bool &isDeleted) void ESM::DebugProfile::load (ESMReader& esm, bool &isDeleted)
{ {
isDeleted = false; isDeleted = false;
mRecordFlags = esm.getRecordFlags();
while (esm.hasMoreSubs()) while (esm.hasMoreSubs())
{ {

View file

@ -19,6 +19,7 @@ namespace ESM
Flag_Global = 4 // make available from main menu (i.e. not location specific) Flag_Global = 4 // make available from main menu (i.e. not location specific)
}; };
unsigned int mRecordFlags;
std::string mId; std::string mId;
std::string mDescription; std::string mDescription;

View file

@ -9,6 +9,7 @@ unsigned int ESM::Filter::sRecordId = REC_FILT;
void ESM::Filter::load (ESMReader& esm, bool &isDeleted) void ESM::Filter::load (ESMReader& esm, bool &isDeleted)
{ {
isDeleted = false; isDeleted = false;
mRecordFlags = esm.getRecordFlags();
while (esm.hasMoreSubs()) while (esm.hasMoreSubs())
{ {

View file

@ -12,6 +12,7 @@ namespace ESM
{ {
static unsigned int sRecordId; static unsigned int sRecordId;
unsigned int mRecordFlags;
std::string mId; std::string mId;
std::string mDescription; std::string mDescription;

View file

@ -11,6 +11,7 @@ namespace ESM
void BodyPart::load(ESMReader &esm, bool &isDeleted) void BodyPart::load(ESMReader &esm, bool &isDeleted)
{ {
isDeleted = false; isDeleted = false;
mRecordFlags = esm.getRecordFlags();
bool hasName = false; bool hasName = false;
bool hasData = false; bool hasData = false;

View file

@ -58,6 +58,7 @@ struct BodyPart
}; };
BYDTstruct mData; BYDTstruct mData;
unsigned int mRecordFlags;
std::string mId, mModel, mRace; std::string mId, mModel, mRace;
void load(ESMReader &esm, bool &isDeleted); void load(ESMReader &esm, bool &isDeleted);

View file

@ -11,6 +11,7 @@ namespace ESM
void BirthSign::load(ESMReader &esm, bool &isDeleted) void BirthSign::load(ESMReader &esm, bool &isDeleted)
{ {
isDeleted = false; isDeleted = false;
mRecordFlags = esm.getRecordFlags();
mPowers.mList.clear(); mPowers.mList.clear();

View file

@ -17,6 +17,7 @@ struct BirthSign
/// Return a string descriptor for this record type. Currently used for debugging / error logs only. /// Return a string descriptor for this record type. Currently used for debugging / error logs only.
static std::string getRecordType() { return "BirthSign"; } static std::string getRecordType() { return "BirthSign"; }
unsigned int mRecordFlags;
std::string mId, mName, mDescription, mTexture; std::string mId, mName, mDescription, mTexture;
// List of powers and abilities that come with this birth sign. // List of powers and abilities that come with this birth sign.

View file

@ -41,6 +41,7 @@ namespace ESM
void Class::load(ESMReader &esm, bool &isDeleted) void Class::load(ESMReader &esm, bool &isDeleted)
{ {
isDeleted = false; isDeleted = false;
mRecordFlags = esm.getRecordFlags();
bool hasName = false; bool hasName = false;
bool hasData = false; bool hasData = false;

View file

@ -70,6 +70,7 @@ struct Class
///< Throws an exception for invalid values of \a index. ///< Throws an exception for invalid values of \a index.
}; // 60 bytes }; // 60 bytes
unsigned int mRecordFlags;
std::string mId, mName, mDescription; std::string mId, mName, mDescription;
CLDTstruct mData; CLDTstruct mData;

View file

@ -11,6 +11,7 @@ namespace ESM
void Enchantment::load(ESMReader &esm, bool &isDeleted) void Enchantment::load(ESMReader &esm, bool &isDeleted)
{ {
isDeleted = false; isDeleted = false;
mRecordFlags = esm.getRecordFlags();
mEffects.mList.clear(); mEffects.mList.clear();
bool hasName = false; bool hasName = false;

View file

@ -42,6 +42,7 @@ struct Enchantment
int mFlags; int mFlags;
}; };
unsigned int mRecordFlags;
std::string mId; std::string mId;
ENDTstruct mData; ENDTstruct mData;
EffectList mEffects; EffectList mEffects;

View file

@ -29,6 +29,7 @@ namespace ESM
void Faction::load(ESMReader &esm, bool &isDeleted) void Faction::load(ESMReader &esm, bool &isDeleted)
{ {
isDeleted = false; isDeleted = false;
mRecordFlags = esm.getRecordFlags();
mReactions.clear(); mReactions.clear();
for (int i=0;i<10;++i) for (int i=0;i<10;++i)

View file

@ -34,6 +34,7 @@ struct Faction
/// Return a string descriptor for this record type. Currently used for debugging / error logs only. /// Return a string descriptor for this record type. Currently used for debugging / error logs only.
static std::string getRecordType() { return "Faction"; } static std::string getRecordType() { return "Faction"; }
unsigned int mRecordFlags;
std::string mId, mName; std::string mId, mName;
struct FADTstruct struct FADTstruct

View file

@ -11,6 +11,7 @@ namespace ESM
void Global::load (ESMReader &esm, bool &isDeleted) void Global::load (ESMReader &esm, bool &isDeleted)
{ {
isDeleted = false; isDeleted = false;
mRecordFlags = esm.getRecordFlags();
mId = esm.getHNString ("NAME"); mId = esm.getHNString ("NAME");

View file

@ -21,6 +21,7 @@ struct Global
/// Return a string descriptor for this record type. Currently used for debugging / error logs only. /// Return a string descriptor for this record type. Currently used for debugging / error logs only.
static std::string getRecordType() { return "Global"; } static std::string getRecordType() { return "Global"; }
unsigned int mRecordFlags;
std::string mId; std::string mId;
Variant mValue; Variant mValue;

View file

@ -11,6 +11,7 @@ namespace ESM
void GameSetting::load (ESMReader &esm, bool &isDeleted) void GameSetting::load (ESMReader &esm, bool &isDeleted)
{ {
isDeleted = false; // GameSetting record can't be deleted now (may be changed in the future) isDeleted = false; // GameSetting record can't be deleted now (may be changed in the future)
mRecordFlags = esm.getRecordFlags();
mId = esm.getHNString("NAME"); mId = esm.getHNString("NAME");
mValue.read (esm, ESM::Variant::Format_Gmst); mValue.read (esm, ESM::Variant::Format_Gmst);

View file

@ -22,6 +22,7 @@ struct GameSetting
/// Return a string descriptor for this record type. Currently used for debugging / error logs only. /// Return a string descriptor for this record type. Currently used for debugging / error logs only.
static std::string getRecordType() { return "GameSetting"; } static std::string getRecordType() { return "GameSetting"; }
unsigned int mRecordFlags;
std::string mId; std::string mId;
Variant mValue; Variant mValue;

View file

@ -189,6 +189,7 @@ namespace ESM
void MagicEffect::load(ESMReader &esm, bool &isDeleted) void MagicEffect::load(ESMReader &esm, bool &isDeleted)
{ {
isDeleted = false; // MagicEffect record can't be deleted now (may be changed in the future) isDeleted = false; // MagicEffect record can't be deleted now (may be changed in the future)
mRecordFlags = esm.getRecordFlags();
esm.getHNT(mIndex, "INDX"); esm.getHNT(mIndex, "INDX");

View file

@ -16,6 +16,7 @@ struct MagicEffect
/// Return a string descriptor for this record type. Currently used for debugging / error logs only. /// Return a string descriptor for this record type. Currently used for debugging / error logs only.
static std::string getRecordType() { return "MagicEffect"; } static std::string getRecordType() { return "MagicEffect"; }
unsigned int mRecordFlags;
std::string mId; std::string mId;
enum Flags enum Flags

View file

@ -21,6 +21,7 @@ namespace ESM
void Race::load(ESMReader &esm, bool &isDeleted) void Race::load(ESMReader &esm, bool &isDeleted)
{ {
isDeleted = false; isDeleted = false;
mRecordFlags = esm.getRecordFlags();
mPowers.mList.clear(); mPowers.mList.clear();

View file

@ -65,6 +65,7 @@ struct Race
RADTstruct mData; RADTstruct mData;
unsigned int mRecordFlags;
std::string mId, mName, mDescription; std::string mId, mName, mDescription;
SpellList mPowers; SpellList mPowers;

View file

@ -11,6 +11,7 @@ namespace ESM
void Region::load(ESMReader &esm, bool &isDeleted) void Region::load(ESMReader &esm, bool &isDeleted)
{ {
isDeleted = false; isDeleted = false;
mRecordFlags = esm.getRecordFlags();
bool hasName = false; bool hasName = false;
while (esm.hasMoreSubs()) while (esm.hasMoreSubs())

View file

@ -45,6 +45,7 @@ struct Region
WEATstruct mData; WEATstruct mData;
int mMapColor; // RGBA int mMapColor; // RGBA
unsigned int mRecordFlags;
// sleepList refers to a leveled list of creatures you can meet if // sleepList refers to a leveled list of creatures you can meet if
// you sleep outside in this region. // you sleep outside in this region.
std::string mId, mName, mSleepList; std::string mId, mName, mSleepList;

View file

@ -83,6 +83,7 @@ namespace ESM
void Script::load(ESMReader &esm, bool &isDeleted) void Script::load(ESMReader &esm, bool &isDeleted)
{ {
isDeleted = false; isDeleted = false;
mRecordFlags = esm.getRecordFlags();
mVarNames.clear(); mVarNames.clear();

View file

@ -35,6 +35,7 @@ public:
Script::SCHDstruct mData; Script::SCHDstruct mData;
}; };
unsigned int mRecordFlags;
std::string mId; std::string mId;
SCHDstruct mData; SCHDstruct mData;

View file

@ -130,6 +130,7 @@ namespace ESM
void Skill::load(ESMReader &esm, bool &isDeleted) void Skill::load(ESMReader &esm, bool &isDeleted)
{ {
isDeleted = false; // Skill record can't be deleted now (may be changed in the future) isDeleted = false; // Skill record can't be deleted now (may be changed in the future)
mRecordFlags = esm.getRecordFlags();
bool hasIndex = false; bool hasIndex = false;
bool hasData = false; bool hasData = false;

View file

@ -22,6 +22,7 @@ struct Skill
/// Return a string descriptor for this record type. Currently used for debugging / error logs only. /// Return a string descriptor for this record type. Currently used for debugging / error logs only.
static std::string getRecordType() { return "Skill"; } static std::string getRecordType() { return "Skill"; }
unsigned int mRecordFlags;
std::string mId; std::string mId;
struct SKDTstruct struct SKDTstruct

View file

@ -11,6 +11,7 @@ namespace ESM
void SoundGenerator::load(ESMReader &esm, bool &isDeleted) void SoundGenerator::load(ESMReader &esm, bool &isDeleted)
{ {
isDeleted = false; isDeleted = false;
mRecordFlags = esm.getRecordFlags();
bool hasName = false; bool hasName = false;
bool hasData = false; bool hasData = false;

View file

@ -34,6 +34,7 @@ struct SoundGenerator
// Type // Type
int mType; int mType;
unsigned int mRecordFlags;
std::string mId, mCreature, mSound; std::string mId, mCreature, mSound;
void load(ESMReader &esm, bool &isDeleted); void load(ESMReader &esm, bool &isDeleted);

View file

@ -11,6 +11,7 @@ namespace ESM
void Sound::load(ESMReader &esm, bool &isDeleted) void Sound::load(ESMReader &esm, bool &isDeleted)
{ {
isDeleted = false; isDeleted = false;
mRecordFlags = esm.getRecordFlags();
bool hasName = false; bool hasName = false;
bool hasData = false; bool hasData = false;

View file

@ -21,6 +21,7 @@ struct Sound
static std::string getRecordType() { return "Sound"; } static std::string getRecordType() { return "Sound"; }
SOUNstruct mData; SOUNstruct mData;
unsigned int mRecordFlags;
std::string mId, mSound; std::string mId, mSound;
void load(ESMReader &esm, bool &isDeleted); void load(ESMReader &esm, bool &isDeleted);

View file

@ -11,6 +11,7 @@ namespace ESM
void Spell::load(ESMReader &esm, bool &isDeleted) void Spell::load(ESMReader &esm, bool &isDeleted)
{ {
isDeleted = false; isDeleted = false;
mRecordFlags = esm.getRecordFlags();
mEffects.mList.clear(); mEffects.mList.clear();

View file

@ -42,6 +42,7 @@ struct Spell
}; };
SPDTstruct mData; SPDTstruct mData;
unsigned int mRecordFlags;
std::string mId, mName; std::string mId, mName;
EffectList mEffects; EffectList mEffects;

View file

@ -11,6 +11,7 @@ namespace ESM
void StartScript::load(ESMReader &esm, bool &isDeleted) void StartScript::load(ESMReader &esm, bool &isDeleted)
{ {
isDeleted = false; isDeleted = false;
mRecordFlags = esm.getRecordFlags();
bool hasData = false; bool hasData = false;
bool hasName = false; bool hasName = false;

View file

@ -24,6 +24,7 @@ struct StartScript
static std::string getRecordType() { return "StartScript"; } static std::string getRecordType() { return "StartScript"; }
std::string mData; std::string mData;
unsigned int mRecordFlags;
std::string mId; std::string mId;
// Load a record and add it to the list // Load a record and add it to the list