From 3721a69747b388fa9d144e4867cae33241a6ca36 Mon Sep 17 00:00:00 2001 From: Alexei Kotov Date: Thu, 21 Mar 2024 18:16:11 +0300 Subject: [PATCH] ESM4: Make script local variable loading more reliable --- components/esm4/loadinfo.cpp | 11 ++++++----- components/esm4/loadscpt.cpp | 12 +++++++----- components/esm4/script.hpp | 7 ------- 3 files changed, 13 insertions(+), 17 deletions(-) diff --git a/components/esm4/loadinfo.cpp b/components/esm4/loadinfo.cpp index 40e366d5d7..d3339d350a 100644 --- a/components/esm4/loadinfo.cpp +++ b/components/esm4/loadinfo.cpp @@ -41,7 +41,6 @@ void ESM4::DialogInfo::load(ESM4::Reader& reader) mEditorId = ESM::RefId(mId).serializeText(); // FIXME: quick workaround to use existing code - ScriptLocalVariableData localVar; bool ignore = false; while (reader.getSubRecordHeader()) @@ -125,22 +124,24 @@ void ESM4::DialogInfo::load(ESM4::Reader& reader) break; case ESM::fourCC("SLSD"): { - localVar.clear(); + ScriptLocalVariableData localVar; reader.get(localVar.index); reader.get(localVar.unknown1); reader.get(localVar.unknown2); reader.get(localVar.unknown3); reader.get(localVar.type); reader.get(localVar.unknown4); + mScript.localVarData.push_back(std::move(localVar)); // WARN: assumes SCVR will follow immediately break; } case ESM::fourCC("SCVR"): // assumed always pair with SLSD { - reader.getZString(localVar.variableName); - - mScript.localVarData.push_back(localVar); + if (!mScript.localVarData.empty()) + reader.getZString(mScript.localVarData.back().variableName); + else + reader.skipSubRecordData(); break; } diff --git a/components/esm4/loadscpt.cpp b/components/esm4/loadscpt.cpp index 7eaef816c8..dbc75b75d6 100644 --- a/components/esm4/loadscpt.cpp +++ b/components/esm4/loadscpt.cpp @@ -36,8 +36,6 @@ void ESM4::Script::load(ESM4::Reader& reader) mId = reader.getFormIdFromHeader(); mFlags = reader.hdr().record.flags; - ScriptLocalVariableData localVar; - while (reader.getSubRecordHeader()) { const ESM4::SubRecordHeader& subHdr = reader.subRecordHeader(); @@ -117,20 +115,24 @@ void ESM4::Script::load(ESM4::Reader& reader) break; case ESM::fourCC("SLSD"): { - localVar.clear(); + ScriptLocalVariableData localVar; reader.get(localVar.index); reader.get(localVar.unknown1); reader.get(localVar.unknown2); reader.get(localVar.unknown3); reader.get(localVar.type); reader.get(localVar.unknown4); + mScript.localVarData.push_back(std::move(localVar)); // WARN: assumes SCVR will follow immediately break; } case ESM::fourCC("SCVR"): // assumed always pair with SLSD - reader.getZString(localVar.variableName); - mScript.localVarData.push_back(localVar); + if (!mScript.localVarData.empty()) + reader.getZString(mScript.localVarData.back().variableName); + else + reader.skipSubRecordData(); + break; case ESM::fourCC("SCRV"): { diff --git a/components/esm4/script.hpp b/components/esm4/script.hpp index 57dd85367b..3715ea55d4 100644 --- a/components/esm4/script.hpp +++ b/components/esm4/script.hpp @@ -365,13 +365,6 @@ namespace ESM4 std::uint32_t unknown4; // SCVR std::string variableName; - - void clear() - { - index = 0; - type = 0; - variableName.clear(); - } }; struct ScriptDefinition