mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-04-28 21:07:59 +03:00
Lua scripts configuration in omwaddon
This commit is contained in:
parent
58fd560ce9
commit
a70d5831c5
26 changed files with 700 additions and 236 deletions
|
@ -3,6 +3,8 @@
|
|||
#include "components/esm3/esmreader.hpp"
|
||||
#include "components/esm3/esmwriter.hpp"
|
||||
|
||||
#include <components/lua/serialization.hpp>
|
||||
|
||||
// List of all records, that are related to Lua.
|
||||
//
|
||||
// Records:
|
||||
|
@ -10,13 +12,15 @@
|
|||
// LUAM - MWLua::LuaManager (in saves)
|
||||
//
|
||||
// Subrecords:
|
||||
// LUAF - LuaScriptCfg::mFlags
|
||||
// LUAF - LuaScriptCfg::mFlags and ESM::RecNameInts list
|
||||
// LUAW - Start of MWLua::WorldView data
|
||||
// LUAE - Start of MWLua::LocalEvent or MWLua::GlobalEvent (eventName)
|
||||
// LUAS - VFS path to a Lua script
|
||||
// LUAD - Serialized Lua variable
|
||||
// LUAT - MWLua::ScriptsContainer::Timer
|
||||
// LUAC - Name of a timer callback (string)
|
||||
// LUAR - Attach script to a specific record (LuaScriptCfg::PerRecordCfg)
|
||||
// LUAI - Attach script to a specific instance (LuaScriptCfg::PerRefCfg)
|
||||
|
||||
void ESM::saveLuaBinaryData(ESMWriter& esm, const std::string& data)
|
||||
{
|
||||
|
@ -39,25 +43,120 @@ std::string ESM::loadLuaBinaryData(ESMReader& esm)
|
|||
return data;
|
||||
}
|
||||
|
||||
static bool readBool(ESM::ESMReader& esm)
|
||||
{
|
||||
char c;
|
||||
esm.getT<char>(c);
|
||||
return c != 0;
|
||||
}
|
||||
|
||||
void ESM::LuaScriptsCfg::load(ESMReader& esm)
|
||||
{
|
||||
while (esm.isNextSub("LUAS"))
|
||||
{
|
||||
std::string name = esm.getHString();
|
||||
uint64_t flags;
|
||||
esm.getHNT(flags, "LUAF");
|
||||
std::string data = loadLuaBinaryData(esm);
|
||||
mScripts.push_back({std::move(name), std::move(data), flags});
|
||||
mScripts.emplace_back();
|
||||
ESM::LuaScriptCfg& script = mScripts.back();
|
||||
script.mScriptPath = esm.getHString();
|
||||
|
||||
esm.getSubNameIs("LUAF");
|
||||
esm.getSubHeader();
|
||||
if (esm.getSubSize() < 4 || (esm.getSubSize() % 4 != 0))
|
||||
esm.fail("Incorrect LUAF size");
|
||||
esm.getT(script.mFlags);
|
||||
script.mTypes.resize((esm.getSubSize() - 4) / 4);
|
||||
for (uint32_t& type : script.mTypes)
|
||||
esm.getT(type);
|
||||
|
||||
script.mInitializationData = loadLuaBinaryData(esm);
|
||||
|
||||
while (esm.isNextSub("LUAR"))
|
||||
{
|
||||
esm.getSubHeader();
|
||||
script.mRecords.emplace_back();
|
||||
ESM::LuaScriptCfg::PerRecordCfg& recordCfg = script.mRecords.back();
|
||||
recordCfg.mRecordId.resize(esm.getSubSize() - 1);
|
||||
recordCfg.mAttach = readBool(esm);
|
||||
esm.getExact(recordCfg.mRecordId.data(), static_cast<int>(recordCfg.mRecordId.size()));
|
||||
recordCfg.mInitializationData = loadLuaBinaryData(esm);
|
||||
}
|
||||
while (esm.isNextSub("LUAI"))
|
||||
{
|
||||
esm.getSubHeader();
|
||||
script.mRefs.emplace_back();
|
||||
ESM::LuaScriptCfg::PerRefCfg& refCfg = script.mRefs.back();
|
||||
refCfg.mAttach = readBool(esm);
|
||||
esm.getT<uint32_t>(refCfg.mRefnumIndex);
|
||||
esm.getT<int32_t>(refCfg.mRefnumContentFile);
|
||||
refCfg.mInitializationData = loadLuaBinaryData(esm);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ESM::LuaScriptsCfg::adjustRefNums(const ESMReader& esm)
|
||||
{
|
||||
auto adjustRefNumFn = [&esm](int contentFile) -> int
|
||||
{
|
||||
if (contentFile == 0)
|
||||
return esm.getIndex();
|
||||
else if (contentFile > 0 && contentFile <= static_cast<int>(esm.getParentFileIndices().size()))
|
||||
return esm.getParentFileIndices()[contentFile - 1];
|
||||
else
|
||||
throw std::runtime_error("Incorrect contentFile index");
|
||||
};
|
||||
|
||||
lua_State* L = lua_open();
|
||||
LuaUtil::BasicSerializer serializer(adjustRefNumFn);
|
||||
|
||||
auto adjustLuaData = [&](std::string& data)
|
||||
{
|
||||
if (data.empty())
|
||||
return;
|
||||
sol::object luaData = LuaUtil::deserialize(L, data, &serializer);
|
||||
data = LuaUtil::serialize(luaData, &serializer);
|
||||
};
|
||||
|
||||
for (LuaScriptCfg& script : mScripts)
|
||||
{
|
||||
adjustLuaData(script.mInitializationData);
|
||||
for (LuaScriptCfg::PerRecordCfg& recordCfg : script.mRecords)
|
||||
adjustLuaData(recordCfg.mInitializationData);
|
||||
for (LuaScriptCfg::PerRefCfg& refCfg : script.mRefs)
|
||||
{
|
||||
adjustLuaData(refCfg.mInitializationData);
|
||||
refCfg.mRefnumContentFile = adjustRefNumFn(refCfg.mRefnumContentFile);
|
||||
}
|
||||
}
|
||||
lua_close(L);
|
||||
}
|
||||
|
||||
void ESM::LuaScriptsCfg::save(ESMWriter& esm) const
|
||||
{
|
||||
for (const LuaScriptCfg& script : mScripts)
|
||||
{
|
||||
esm.writeHNString("LUAS", script.mScriptPath);
|
||||
esm.writeHNT("LUAF", script.mFlags);
|
||||
esm.startSubRecord("LUAF");
|
||||
esm.writeT<uint32_t>(script.mFlags);
|
||||
for (uint32_t type : script.mTypes)
|
||||
esm.writeT<uint32_t>(type);
|
||||
esm.endRecord("LUAF");
|
||||
saveLuaBinaryData(esm, script.mInitializationData);
|
||||
for (const LuaScriptCfg::PerRecordCfg& recordCfg : script.mRecords)
|
||||
{
|
||||
esm.startSubRecord("LUAR");
|
||||
esm.writeT<char>(recordCfg.mAttach ? 1 : 0);
|
||||
esm.write(recordCfg.mRecordId.data(), recordCfg.mRecordId.size());
|
||||
esm.endRecord("LUAR");
|
||||
saveLuaBinaryData(esm, recordCfg.mInitializationData);
|
||||
}
|
||||
for (const LuaScriptCfg::PerRefCfg& refCfg : script.mRefs)
|
||||
{
|
||||
esm.startSubRecord("LUAI");
|
||||
esm.writeT<char>(refCfg.mAttach ? 1 : 0);
|
||||
esm.writeT<uint32_t>(refCfg.mRefnumIndex);
|
||||
esm.writeT<int32_t>(refCfg.mRefnumContentFile);
|
||||
esm.endRecord("LUAI");
|
||||
saveLuaBinaryData(esm, refCfg.mInitializationData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue