1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-01-16 15:29:55 +00:00

Add key flag on load

This commit is contained in:
Evil Eye 2022-09-30 12:16:45 +02:00
parent b1cf4ace3c
commit e6592aa850
9 changed files with 37 additions and 20 deletions

View file

@ -19,6 +19,7 @@
Bug #6992: Crossbow reloading doesn't look the same as in Morrowind 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 #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 #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 #6933: Support high-resolution cursor textures
Feature #6945: Support S3TC-compressed and BGR/BGRA NiPixelData 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 Feature #6979: Add support of loading and displaying LOD assets purely based on their filename extension

View file

@ -1042,7 +1042,7 @@ namespace EsmTool
std::cout << " Script: " << mData.mScript << std::endl; std::cout << " Script: " << mData.mScript << std::endl;
std::cout << " Weight: " << mData.mData.mWeight << std::endl; std::cout << " Weight: " << mData.mData.mWeight << std::endl;
std::cout << " Value: " << mData.mData.mValue << 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; std::cout << " Deleted: " << mIsDeleted << std::endl;
} }

View file

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

View file

@ -155,7 +155,7 @@ namespace MWClass
std::string text; std::string text;
text += MWGui::ToolTips::getWeightString(ref->mBase->mData.mWeight, "#{sWeight}"); 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}"); text += MWGui::ToolTips::getValueString(getValue(ptr), "#{sValue}");
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) if (MWBase::Environment::get().getWindowManager()->getFullHelp())
@ -221,7 +221,7 @@ namespace MWClass
{ {
const MWWorld::LiveCellRef<ESM::Miscellaneous>* ref = item.get<ESM::Miscellaneous>(); 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 float Miscellaneous::getWeight(const MWWorld::ConstPtr& ptr) const
@ -233,7 +233,7 @@ namespace MWClass
bool Miscellaneous::isKey(const MWWorld::ConstPtr& ptr) const bool Miscellaneous::isKey(const MWWorld::ConstPtr& ptr) const
{ {
const MWWorld::LiveCellRef<ESM::Miscellaneous>* ref = ptr.get<ESM::Miscellaneous>(); 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 bool Miscellaneous::isSoulGem(const MWWorld::ConstPtr& ptr) const

View file

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

View file

@ -34,8 +34,8 @@ namespace
constexpr std::size_t deletedRefID = std::numeric_limits<std::size_t>::max(); constexpr std::size_t deletedRefID = std::numeric_limits<std::size_t>::max();
void readRefs( void readRefs(const ESM::Cell& cell, std::vector<Ref>& refs, std::vector<std::string>& refIDs,
const ESM::Cell& cell, std::vector<Ref>& refs, std::vector<std::string>& refIDs, ESM::ReadersCache& readers) std::set<std::string, Misc::StringUtils::CiComp>& keyIDs, ESM::ReadersCache& readers)
{ {
// TODO: we have many similar copies of this code. // TODO: we have many similar copies of this code.
for (size_t i = 0; i < cell.mContextList.size(); i++) 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) else if (std::find(cell.mMovedRefs.begin(), cell.mMovedRefs.end(), ref.mRefNum)
== cell.mMovedRefs.end()) == cell.mMovedRefs.end())
{ {
if (!ref.mKey.empty())
keyIDs.insert(std::move(ref.mKey));
refs.emplace_back(ref.mRefNum, refIDs.size()); refs.emplace_back(ref.mRefNum, refIDs.size());
refIDs.push_back(std::move(ref.mRefID)); refIDs.push_back(std::move(ref.mRefID));
} }
@ -64,6 +66,8 @@ namespace
refs.emplace_back(value.mRefNum, deletedRefID); refs.emplace_back(value.mRefNum, deletedRefID);
else else
{ {
if (!value.mKey.empty())
keyIDs.insert(std::move(value.mKey));
refs.emplace_back(value.mRefNum, refIDs.size()); refs.emplace_back(value.mRefNum, refIDs.size());
refIDs.push_back(value.mRefID); refIDs.push_back(value.mRefID);
} }
@ -403,10 +407,10 @@ namespace MWWorld
void ESMStore::validateRecords(ESM::ReadersCache& readers) void ESMStore::validateRecords(ESM::ReadersCache& readers)
{ {
validate(); 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. // TODO: We currently need to read entire files here again.
// We should consider consolidating or deferring this reading. // We should consider consolidating or deferring this reading.
@ -414,11 +418,12 @@ namespace MWWorld
return; return;
std::vector<Ref> refs; std::vector<Ref> refs;
std::vector<std::string> refIDs; 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) 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) 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; }; const auto lessByRefNum = [](const Ref& l, const Ref& r) { return l.mRefNum < r.mRefNum; };
std::stable_sort(refs.begin(), refs.end(), lessByRefNum); std::stable_sort(refs.begin(), refs.end(), lessByRefNum);
const auto equalByRefNum = [](const Ref& l, const Ref& r) { return l.mRefNum == r.mRefNum; }; 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); 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 int ESMStore::getRefCount(std::string_view id) const

View file

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

View file

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

View file

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