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:
parent
b1cf4ace3c
commit
e6592aa850
9 changed files with 37 additions and 20 deletions
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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; });
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue