Add key flag on load

coverity_retry
Evil Eye 2 years ago
parent b1cf4ace3c
commit e6592aa850

@ -19,6 +19,7 @@
Bug #6992: Crossbow reloading doesn't look the same as in Morrowind
Bug #6993: Shooting your last round of ammunition causes the attack animation to cancel
Bug #7009: Falling actors teleport to the ground without receiving any damage on cell loading
Bug #7034: Misc items defined in one content file are not treated as keys if another content file uses them as such
Feature #6933: Support high-resolution cursor textures
Feature #6945: Support S3TC-compressed and BGR/BGRA NiPixelData
Feature #6979: Add support of loading and displaying LOD assets purely based on their filename extension

@ -1042,7 +1042,7 @@ namespace EsmTool
std::cout << " Script: " << mData.mScript << std::endl;
std::cout << " Weight: " << mData.mData.mWeight << std::endl;
std::cout << " Value: " << mData.mData.mValue << std::endl;
std::cout << " Is Key: " << mData.mData.mIsKey << std::endl;
std::cout << " Is Key: " << (mData.mData.mFlags & ESM::Miscellaneous::Key) << std::endl;
std::cout << " Deleted: " << mIsDeleted << std::endl;
}

@ -726,7 +726,7 @@ QVariant CSMWorld::MiscRefIdAdapter::getData(const RefIdColumn* column, const Re
data.getRecord(RefIdData::LocalIndex(index, UniversalId::Type_Miscellaneous)));
if (column == mKey)
return record.get().mData.mIsKey != 0;
return bool(record.get().mData.mFlags & ESM::Miscellaneous::Key);
return InventoryRefIdAdapter<ESM::Miscellaneous>::getData(column, data, index);
}
@ -740,7 +740,7 @@ void CSMWorld::MiscRefIdAdapter::setData(
ESM::Miscellaneous misc = record.get();
if (column == mKey)
misc.mData.mIsKey = value.toInt();
misc.mData.mFlags = value.toInt();
else
{
InventoryRefIdAdapter<ESM::Miscellaneous>::setData(column, data, index, value);

@ -155,7 +155,7 @@ namespace MWClass
std::string text;
text += MWGui::ToolTips::getWeightString(ref->mBase->mData.mWeight, "#{sWeight}");
if (!gold && !ref->mBase->mData.mIsKey)
if (!gold && !(ref->mBase->mData.mFlags & ESM::Miscellaneous::Key))
text += MWGui::ToolTips::getValueString(getValue(ptr), "#{sValue}");
if (MWBase::Environment::get().getWindowManager()->getFullHelp())
@ -221,7 +221,7 @@ namespace MWClass
{
const MWWorld::LiveCellRef<ESM::Miscellaneous>* ref = item.get<ESM::Miscellaneous>();
return !ref->mBase->mData.mIsKey && (npcServices & ESM::NPC::Misc) && !isGold(item);
return !(ref->mBase->mData.mFlags & ESM::Miscellaneous::Key) && (npcServices & ESM::NPC::Misc) && !isGold(item);
}
float Miscellaneous::getWeight(const MWWorld::ConstPtr& ptr) const
@ -233,7 +233,7 @@ namespace MWClass
bool Miscellaneous::isKey(const MWWorld::ConstPtr& ptr) const
{
const MWWorld::LiveCellRef<ESM::Miscellaneous>* ref = ptr.get<ESM::Miscellaneous>();
return ref->mBase->mData.mIsKey != 0;
return ref->mBase->mData.mFlags & ESM::Miscellaneous::Key;
}
bool Miscellaneous::isSoulGem(const MWWorld::ConstPtr& ptr) const

@ -42,8 +42,8 @@ namespace MWLua
record["icon"] = sol::readonly_property([vfs](const ESM::Miscellaneous& rec) -> std::string {
return Misc::ResourceHelpers::correctIconPath(rec.mIcon, vfs);
});
record["isKey"]
= sol::readonly_property([](const ESM::Miscellaneous& rec) -> bool { return rec.mData.mIsKey; });
record["isKey"] = sol::readonly_property(
[](const ESM::Miscellaneous& rec) -> bool { return rec.mData.mFlags & ESM::Miscellaneous::Key; });
record["value"] = sol::readonly_property([](const ESM::Miscellaneous& rec) -> int { return rec.mData.mValue; });
record["weight"]
= sol::readonly_property([](const ESM::Miscellaneous& rec) -> float { return rec.mData.mWeight; });

@ -34,8 +34,8 @@ namespace
constexpr std::size_t deletedRefID = std::numeric_limits<std::size_t>::max();
void readRefs(
const ESM::Cell& cell, std::vector<Ref>& refs, std::vector<std::string>& refIDs, ESM::ReadersCache& readers)
void readRefs(const ESM::Cell& cell, std::vector<Ref>& refs, std::vector<std::string>& refIDs,
std::set<std::string, Misc::StringUtils::CiComp>& keyIDs, ESM::ReadersCache& readers)
{
// TODO: we have many similar copies of this code.
for (size_t i = 0; i < cell.mContextList.size(); i++)
@ -53,6 +53,8 @@ namespace
else if (std::find(cell.mMovedRefs.begin(), cell.mMovedRefs.end(), ref.mRefNum)
== cell.mMovedRefs.end())
{
if (!ref.mKey.empty())
keyIDs.insert(std::move(ref.mKey));
refs.emplace_back(ref.mRefNum, refIDs.size());
refIDs.push_back(std::move(ref.mRefID));
}
@ -64,6 +66,8 @@ namespace
refs.emplace_back(value.mRefNum, deletedRefID);
else
{
if (!value.mKey.empty())
keyIDs.insert(std::move(value.mKey));
refs.emplace_back(value.mRefNum, refIDs.size());
refIDs.push_back(value.mRefID);
}
@ -403,10 +407,10 @@ namespace MWWorld
void ESMStore::validateRecords(ESM::ReadersCache& readers)
{
validate();
countAllCellRefs(readers);
countAllCellRefsAndMarkKeys(readers);
}
void ESMStore::countAllCellRefs(ESM::ReadersCache& readers)
void ESMStore::countAllCellRefsAndMarkKeys(ESM::ReadersCache& readers)
{
// TODO: We currently need to read entire files here again.
// We should consider consolidating or deferring this reading.
@ -414,11 +418,12 @@ namespace MWWorld
return;
std::vector<Ref> refs;
std::vector<std::string> refIDs;
Store<ESM::Cell> Cells = getWritable<ESM::Cell>();
std::set<std::string, Misc::StringUtils::CiComp> keyIDs;
Store<ESM::Cell> Cells = get<ESM::Cell>();
for (auto it = Cells.intBegin(); it != Cells.intEnd(); ++it)
readRefs(*it, refs, refIDs, readers);
readRefs(*it, refs, refIDs, keyIDs, readers);
for (auto it = Cells.extBegin(); it != Cells.extEnd(); ++it)
readRefs(*it, refs, refIDs, readers);
readRefs(*it, refs, refIDs, keyIDs, readers);
const auto lessByRefNum = [](const Ref& l, const Ref& r) { return l.mRefNum < r.mRefNum; };
std::stable_sort(refs.begin(), refs.end(), lessByRefNum);
const auto equalByRefNum = [](const Ref& l, const Ref& r) { return l.mRefNum == r.mRefNum; };
@ -432,6 +437,13 @@ namespace MWWorld
}
};
Misc::forEachUnique(refs.rbegin(), refs.rend(), equalByRefNum, incrementRefCount);
auto& store = getWritable<ESM::Miscellaneous>().mStatic;
for (const std::string& id : keyIDs)
{
auto it = store.find(id);
if (it != store.end())
it->second.mData.mFlags |= ESM::Miscellaneous::Key;
}
}
int ESMStore::getRefCount(std::string_view id) const

@ -125,7 +125,7 @@ namespace MWWorld
/// Validate entries in store after setup
void validate();
void countAllCellRefs(ESM::ReadersCache& readers);
void countAllCellRefsAndMarkKeys(ESM::ReadersCache& readers);
template <class T>
void removeMissingObjects(Store<T>& store);

@ -75,7 +75,7 @@ namespace ESM
mRecordFlags = 0;
mData.mWeight = 0;
mData.mValue = 0;
mData.mIsKey = 0;
mData.mFlags = 0;
mName.clear();
mModel.clear();
mIcon.clear();

@ -27,10 +27,14 @@ namespace ESM
{
float mWeight;
int mValue;
int mIsKey; // There are many keys in Morrowind.esm that has this
// set to 0. TODO: Check what this field corresponds to
// in the editor.
int mFlags;
};
enum Flags
{
Key = 0x1 // Assigned as a key in the content file that defined the record
};
MCDTstruct mData;
unsigned int mRecordFlags;

Loading…
Cancel
Save