#include "luascripts.hpp" #include "components/esm3/esmreader.hpp" #include "components/esm3/esmwriter.hpp" // List of all records, that are related to Lua. // // Records: // LUAL - LuaScriptsCfg - list of all scripts (in content files) // LUAM - MWLua::LuaManager (in saves) // // Subrecords: // LUAF - LuaScriptCfg::mFlags // 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) void ESM::saveLuaBinaryData(ESMWriter& esm, const std::string& data) { if (data.empty()) return; esm.startSubRecord("LUAD"); esm.write(data.data(), data.size()); esm.endRecord("LUAD"); } std::string ESM::loadLuaBinaryData(ESMReader& esm) { std::string data; if (esm.isNextSub("LUAD")) { esm.getSubHeader(); data.resize(esm.getSubSize()); esm.getExact(data.data(), static_cast(data.size())); } return data; } 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}); } } void ESM::LuaScriptsCfg::save(ESMWriter& esm) const { for (const LuaScriptCfg& script : mScripts) { esm.writeHNString("LUAS", script.mScriptPath); esm.writeHNT("LUAF", script.mFlags); saveLuaBinaryData(esm, script.mInitializationData); } } void ESM::LuaScripts::load(ESMReader& esm) { while (esm.isNextSub("LUAS")) { std::string name = esm.getHString(); std::string data = loadLuaBinaryData(esm); std::vector timers; while (esm.isNextSub("LUAT")) { esm.getSubHeader(); LuaTimer timer; esm.getT(timer.mType); esm.getT(timer.mTime); timer.mCallbackName = esm.getHNString("LUAC"); timer.mCallbackArgument = loadLuaBinaryData(esm); timers.push_back(std::move(timer)); } mScripts.push_back({std::move(name), std::move(data), std::move(timers)}); } } void ESM::LuaScripts::save(ESMWriter& esm) const { for (const LuaScript& script : mScripts) { esm.writeHNString("LUAS", script.mScriptPath); saveLuaBinaryData(esm, script.mData); for (const LuaTimer& timer : script.mTimers) { esm.startSubRecord("LUAT"); esm.writeT(timer.mType); esm.writeT(timer.mTime); esm.endRecord("LUAT"); esm.writeHNString("LUAC", timer.mCallbackName); if (!timer.mCallbackArgument.empty()) saveLuaBinaryData(esm, timer.mCallbackArgument); } } }