1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-02-03 17:54:06 +00:00

Moved persistence flag from references to the header flags of referenceables (e.g. Static, Weapon, etc). Editing widget is not fully working.

This commit is contained in:
cc9cii 2021-06-29 23:25:26 +10:00
parent f6eab52a1b
commit 2a76634f5f
47 changed files with 205 additions and 39 deletions

View File

@ -257,6 +257,8 @@ int CSMDoc::WriteCellCollectionStage::writeReferences (const std::deque<int>& re
{
ESM::ESMWriter& writer = mState.getWriter();
size_t refCount = 0;
const CSMWorld::RefIdCollection& referenceables = mDocument.getData().getReferenceables();
const CSMWorld::RefIdData& refIdData = referenceables.getDataSet();
for (std::deque<int>::const_iterator iter (references.begin());
iter!=references.end(); ++iter)
@ -264,7 +266,10 @@ int CSMDoc::WriteCellCollectionStage::writeReferences (const std::deque<int>& re
const CSMWorld::Record<CSMWorld::CellRef>& ref =
mDocument.getData().getReferences().getRecord (*iter);
if (temp && ref.get().mIsPersistent || !temp && !ref.get().mIsPersistent)
unsigned int recordFlags = refIdData.getRecordFlags(ref.get().mId);
bool isPersistent = (recordFlags & 0x00000400) != 0;
if (temp && isPersistent || !temp && !isPersistent)
continue;
refCount++;

View File

@ -1429,33 +1429,6 @@ namespace CSMWorld
}
};
template<typename ESXRecordT>
struct PersistentColumn : public Column<ESXRecordT>
{
PersistentColumn()
: Column<ESXRecordT> (Columns::ColumnId_Persistent, ColumnBase::Display_Boolean)
{}
QVariant get (const Record<ESXRecordT>& record) const override
{
return record.get().mIsPersistent;
}
void set (Record<ESXRecordT>& record, const QVariant& data) override
{
ESXRecordT record2 = record.get();
record2.mIsPersistent = data.toInt();
record.setModified (record2);
}
bool isEditable() const override
{
return true;
}
};
template<typename ESXRecordT>
struct QuestStatusTypeColumn : public Column<ESXRecordT>
{

View File

@ -528,7 +528,6 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, bool fsStrict, const Files::Pat
mRefs.addColumn (new TrapColumn<CellRef>);
mRefs.addColumn (new OwnerGlobalColumn<CellRef>);
mRefs.addColumn (new RefNumColumn<CellRef>);
mRefs.addColumn (new PersistentColumn<CellRef>);
mFilters.addColumn (new StringIdColumn<ESM::Filter>);
mFilters.addColumn (new RecordStateColumn<ESM::Filter>);

View File

@ -114,8 +114,9 @@ namespace CSMWorld
struct ModelColumns : public BaseColumns
{
const RefIdColumn *mModel;
const RefIdColumn *mPersistence;
ModelColumns (const BaseColumns& base) : BaseColumns (base), mModel(nullptr) {}
ModelColumns (const BaseColumns& base) : BaseColumns (base), mModel(nullptr), mPersistence(nullptr) {}
};
/// \brief Adapter for IDs with models (all but levelled lists)
@ -151,6 +152,12 @@ namespace CSMWorld
if (column==mModel.mModel)
return QString::fromUtf8 (record.get().mModel.c_str());
if (column==mModel.mPersistence)
{
bool isPersistent = (record.get().mRecordFlags & 0x00000400) != 0;
return QString::fromUtf8 (isPersistent ? "Yes" : "No");
}
return BaseRefIdAdapter<RecordT>::getData (column, data, index);
}
@ -164,6 +171,17 @@ namespace CSMWorld
RecordT record2 = record.get();
if (column==mModel.mModel)
record2.mModel = value.toString().toUtf8().constData();
else if (column==mModel.mPersistence)
{
unsigned int flag = record2.mRecordFlags;
std::string val = value.toString().toUtf8().constData();
if (val == "Yes")
flag |= 0x00000400;
else if (val == "No")
flag &= ~0x00000400;
record2.mRecordFlags = flag;
}
else
{
BaseRefIdAdapter<RecordT>::setData (column, data, index, value);

View File

@ -54,6 +54,8 @@ CSMWorld::RefIdCollection::RefIdCollection()
mColumns.emplace_back(Columns::ColumnId_Model, ColumnBase::Display_Mesh);
modelColumns.mModel = &mColumns.back();
mColumns.emplace_back(Columns::ColumnId_Persistent, ColumnBase::Display_Boolean);
modelColumns.mPersistence = &mColumns.back();
NameColumns nameColumns (modelColumns);

View File

@ -87,6 +87,139 @@ CSMWorld::RefIdData::LocalIndex CSMWorld::RefIdData::searchId (
return iter->second;
}
unsigned int CSMWorld::RefIdData::getRecordFlags (const std::string& id) const
{
LocalIndex localIndex = searchId (id);
switch (localIndex.second)
{
case UniversalId::Type_Activator:
{
const RefIdDataContainer<ESM::Activator>& records = getActivators();
const ESM::Activator& record = dynamic_cast<const ESM::Activator&>(records.getRecord(localIndex.first));
return record.mRecordFlags;
}
case UniversalId::Type_Potion:
{
const RefIdDataContainer<ESM::Potion>& records = getPotions();
const ESM::Potion& record = dynamic_cast<const ESM::Potion&>(records.getRecord(localIndex.first));
return record.mRecordFlags;
}
case UniversalId::Type_Apparatus:
{
const RefIdDataContainer<ESM::Apparatus>& records = getApparati();
const ESM::Apparatus& record = dynamic_cast<const ESM::Apparatus&>(records.getRecord(localIndex.first));
return record.mRecordFlags;
}
case UniversalId::Type_Armor:
{
const RefIdDataContainer<ESM::Armor>& records = getArmors();
const ESM::Armor& record = dynamic_cast<const ESM::Armor&>(records.getRecord(localIndex.first));
return record.mRecordFlags;
}
case UniversalId::Type_Book:
{
const RefIdDataContainer<ESM::Book>& records = getBooks();
const ESM::Book& record = dynamic_cast<const ESM::Book&>(records.getRecord(localIndex.first));
return record.mRecordFlags;
}
case UniversalId::Type_Clothing:
{
const RefIdDataContainer<ESM::Clothing>& records = getClothing();
const ESM::Clothing& record = dynamic_cast<const ESM::Clothing&>(records.getRecord(localIndex.first));
return record.mRecordFlags;
}
case UniversalId::Type_Container:
{
const RefIdDataContainer<ESM::Container>& records = getContainers();
const ESM::Container& record = dynamic_cast<const ESM::Container&>(records.getRecord(localIndex.first));
return record.mRecordFlags;
}
case UniversalId::Type_Creature:
{
const RefIdDataContainer<ESM::Creature>& records = getCreatures();
const ESM::Creature& record = dynamic_cast<const ESM::Creature&>(records.getRecord(localIndex.first));
return record.mRecordFlags;
}
case UniversalId::Type_Door:
{
const RefIdDataContainer<ESM::Door>& records = getDoors();
const ESM::Door& record = dynamic_cast<const ESM::Door&>(records.getRecord(localIndex.first));
return record.mRecordFlags;
}
case UniversalId::Type_Ingredient:
{
const RefIdDataContainer<ESM::Ingredient>& records = getIngredients();
const ESM::Ingredient& record = dynamic_cast<const ESM::Ingredient&>(records.getRecord(localIndex.first));
return record.mRecordFlags;
}
case UniversalId::Type_CreatureLevelledList:
{
const RefIdDataContainer<ESM::CreatureLevList>& records = getCreatureLevelledLists();
const ESM::CreatureLevList& record = dynamic_cast<const ESM::CreatureLevList&>(records.getRecord(localIndex.first));
return record.mRecordFlags;
}
case UniversalId::Type_ItemLevelledList:
{
const RefIdDataContainer<ESM::ItemLevList>& records = getItemLevelledList();
const ESM::ItemLevList& record = dynamic_cast<const ESM::ItemLevList&>(records.getRecord(localIndex.first));
return record.mRecordFlags;
}
case UniversalId::Type_Light:
{
const RefIdDataContainer<ESM::Light>& records = getLights();
const ESM::Light& record = dynamic_cast<const ESM::Light&>(records.getRecord(localIndex.first));
return record.mRecordFlags;
}
case UniversalId::Type_Lockpick:
{
const RefIdDataContainer<ESM::Lockpick>& records = getLocpicks();
const ESM::Lockpick& record = dynamic_cast<const ESM::Lockpick&>(records.getRecord(localIndex.first));
return record.mRecordFlags;
}
case UniversalId::Type_Miscellaneous:
{
const RefIdDataContainer<ESM::Miscellaneous>& records = getMiscellaneous();
const ESM::Miscellaneous& record = dynamic_cast<const ESM::Miscellaneous&>(records.getRecord(localIndex.first));
return record.mRecordFlags;
}
case UniversalId::Type_Npc:
{
const RefIdDataContainer<ESM::NPC>& records = getNPCs();
const ESM::NPC& record = dynamic_cast<const ESM::NPC&>(records.getRecord(localIndex.first));
return record.mRecordFlags;
}
case UniversalId::Type_Probe:
{
const RefIdDataContainer<ESM::Probe>& records = getProbes();
const ESM::Probe& record = dynamic_cast<const ESM::Probe&>(records.getRecord(localIndex.first));
return record.mRecordFlags;
}
case UniversalId::Type_Repair:
{
const RefIdDataContainer<ESM::Repair>& records = getRepairs();
const ESM::Repair& record = dynamic_cast<const ESM::Repair&>(records.getRecord(localIndex.first));
return record.mRecordFlags;
}
case UniversalId::Type_Static:
{
const RefIdDataContainer<ESM::Static>& records = getStatics();
const ESM::Static& record = dynamic_cast<const ESM::Static&>(records.getRecord(localIndex.first));
return record.mRecordFlags;
}
case UniversalId::Type_Weapon:
{
const RefIdDataContainer<ESM::Weapon>& records = getWeapons();
const ESM::Weapon& record = dynamic_cast<const ESM::Weapon&>(records.getRecord(localIndex.first));
return record.mRecordFlags;
}
default:
break;
}
return 0;
}
void CSMWorld::RefIdData::erase (int index, int count)
{
LocalIndex localIndex = globalToLocalIndex (index);

View File

@ -209,7 +209,7 @@ namespace CSMWorld
if (record.isModified() || record.mState == RecordBase::State_Deleted)
{
RecordT esmRecord = record.get();
writer.startRecord(esmRecord.sRecordId);
writer.startRecord(esmRecord.sRecordId, esmRecord.mRecordFlags);
esmRecord.save(writer, record.mState == RecordBase::State_Deleted);
writer.endRecord(esmRecord.sRecordId);
}
@ -273,6 +273,8 @@ namespace CSMWorld
RecordBase& getRecord (const LocalIndex& index);
unsigned int getRecordFlags(const std::string& id) const;
void appendRecord (UniversalId::Type type, const std::string& id, bool base);
int getAppendIndex (UniversalId::Type type) const;

View File

@ -60,8 +60,6 @@ void ESM::CellRef::loadId (ESMReader& esm, bool wideRefNum)
void ESM::CellRef::loadData(ESMReader &esm, bool &isDeleted, int *tempRefCount)
{
isDeleted = false;
mIsPersistent = !tempRefCount // default to persistent
|| (tempRefCount && *tempRefCount == -1);
bool isLoaded = false;
while (!isLoaded && esm.hasMoreSubs())
@ -247,6 +245,4 @@ void ESM::CellRef::blank()
mPos.pos[i] = 0;
mPos.rot[i] = 0;
}
mIsPersistent = false;
}

View File

@ -106,8 +106,6 @@ namespace ESM
// Position and rotation of this object within the cell
Position mPos;
bool mIsPersistent;
/// Calls loadId and loadData
void load (ESMReader& esm, bool &isDeleted, int *tempRefCount, bool wideRefNum = false);

View File

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

View File

@ -15,6 +15,7 @@ struct Activator
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
static std::string getRecordType() { return "Activator"; }
unsigned int mRecordFlags;
std::string mId, mName, mScript, mModel;
void load(ESMReader &esm, bool &isDeleted);

View File

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

View File

@ -30,6 +30,7 @@ struct Potion
};
ALDTstruct mData;
unsigned int mRecordFlags;
std::string mId, mName, mModel, mIcon, mScript;
EffectList mEffects;

View File

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

View File

@ -36,6 +36,7 @@ struct Apparatus
};
AADTstruct mData;
unsigned int mRecordFlags;
std::string mId, mModel, mIcon, mScript, mName;
void load(ESMReader &esm, bool &isDeleted);

View File

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

View File

@ -94,6 +94,7 @@ struct Armor
AODTstruct mData;
PartReferenceList mParts;
unsigned int mRecordFlags;
std::string mId, mName, mModel, mIcon, mScript, mEnchant;
void load(ESMReader &esm, bool &isDeleted);

View File

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

View File

@ -26,6 +26,7 @@ struct Book
BKDTstruct mData;
std::string mName, mModel, mIcon, mScript, mEnchant, mText;
unsigned int mRecordFlags;
std::string mId;
void load(ESMReader &esm, bool &isDeleted);

View File

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

View File

@ -46,6 +46,7 @@ struct Clothing
PartReferenceList mParts;
unsigned int mRecordFlags;
std::string mId, mName, mModel, mIcon, mEnchant, mScript;
void load(ESMReader &esm, bool &isDeleted);

View File

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

View File

@ -46,6 +46,7 @@ struct Container
Unknown = 8
};
unsigned int mRecordFlags;
std::string mId, mName, mModel, mScript;
float mWeight; // Not sure, might be max total weight allowed?

View File

@ -13,8 +13,9 @@ namespace ESM {
void Creature::load(ESMReader &esm, bool &isDeleted)
{
isDeleted = false;
mRecordFlags = esm.getRecordFlags();
mPersistent = (esm.getRecordFlags() & 0x0400) != 0;
mPersistent = (mRecordFlags & 0x0400) != 0;
mAiPackage.mList.clear();
mInventory.mList.clear();

View File

@ -80,6 +80,7 @@ struct Creature
float mScale;
unsigned int mRecordFlags;
std::string mId, mModel, mName, mScript;
std::string mOriginal; // Base creature that this is a modification of

View File

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

View File

@ -15,6 +15,7 @@ struct Door
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
static std::string getRecordType() { return "Door"; }
unsigned int mRecordFlags;
std::string mId, mName, mModel, mScript, mOpenSound, mCloseSound;
void load(ESMReader &esm, bool &isDeleted);

View File

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

View File

@ -29,6 +29,7 @@ struct Ingredient
};
IRDTstruct mData;
unsigned int mRecordFlags;
std::string mId, mName, mModel, mIcon, mScript;
void load(ESMReader &esm, bool &isDeleted);

View File

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

View File

@ -22,6 +22,7 @@ struct LevelledListBase
{
int mFlags;
unsigned char mChanceNone; // Chance that none are selected (0-100)
unsigned int mRecordFlags;
std::string mId;
// Record name used to read references. Must be set before load() is

View File

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

View File

@ -45,6 +45,7 @@ struct Light
LHDTstruct mData;
unsigned int mRecordFlags;
std::string mSound, mScript, mModel, mIcon, mName, mId;
void load(ESMReader &esm, bool &isDeleted);

View File

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

View File

@ -25,6 +25,7 @@ struct Lockpick
}; // Size = 16
Data mData;
unsigned int mRecordFlags;
std::string mId, mName, mModel, mIcon, mScript;
void load(ESMReader &esm, bool &isDeleted);

View File

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

View File

@ -30,6 +30,7 @@ struct Miscellaneous
};
MCDTstruct mData;
unsigned int mRecordFlags;
std::string mId, mName, mModel, mIcon, mScript;
void load(ESMReader &esm, bool &isDeleted);

View File

@ -11,8 +11,9 @@ namespace ESM
void NPC::load(ESMReader &esm, bool &isDeleted)
{
isDeleted = false;
mRecordFlags = esm.getRecordFlags();
mPersistent = (esm.getRecordFlags() & 0x0400) != 0;
mPersistent = (mRecordFlags & 0x0400) != 0;
mSpells.mList.clear();
mInventory.mList.clear();

View File

@ -129,6 +129,7 @@ struct NPC
AIPackageList mAiPackage;
unsigned int mRecordFlags;
std::string mId, mName, mModel, mRace, mClass, mFaction, mScript;
// body parts

View File

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

View File

@ -25,6 +25,7 @@ struct Probe
}; // Size = 16
Data mData;
unsigned int mRecordFlags;
std::string mId, mName, mModel, mIcon, mScript;
void load(ESMReader &esm, bool &isDeleted);

View File

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

View File

@ -25,6 +25,7 @@ struct Repair
}; // Size = 16
Data mData;
unsigned int mRecordFlags;
std::string mId, mName, mModel, mIcon, mScript;
void load(ESMReader &esm, bool &isDeleted);

View File

@ -11,6 +11,9 @@ namespace ESM
void Static::load(ESMReader &esm, bool &isDeleted)
{
isDeleted = false;
mRecordFlags = esm.getRecordFlags();
//bool isBlocked = (mRecordFlags & 0x00002000) != 0;
//bool isPersistent = (mRecordFlags & 0x00000400) != 0;
bool hasName = false;
while (esm.hasMoreSubs())

View File

@ -26,6 +26,7 @@ struct Static
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
static std::string getRecordType() { return "Static"; }
unsigned int mRecordFlags;
std::string mId, mModel;
void load(ESMReader &esm, bool &isDeleted);

View File

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

View File

@ -73,6 +73,7 @@ struct Weapon
WPDTstruct mData;
unsigned int mRecordFlags;
std::string mId, mName, mModel, mIcon, mEnchant, mScript;
void load(ESMReader &esm, bool &isDeleted);