Load LuaScriptsCfg from both *.omwscripts and *.omwaddon files.

pull/3207/head
Petr Mikheev 3 years ago
parent 4ec7f0625e
commit 47c89567fb

@ -495,11 +495,6 @@ void OMW::Engine::addGroundcoverFile(const std::string& file)
mGroundcoverFiles.emplace_back(file);
}
void OMW::Engine::addLuaScriptListFile(const std::string& file)
{
mLuaScriptListFiles.push_back(file);
}
void OMW::Engine::setSkipMenu (bool skipMenu, bool newGame)
{
mSkipMenu = skipMenu;
@ -714,7 +709,7 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings)
mViewer->addEventHandler(mScreenCaptureHandler);
mLuaManager = new MWLua::LuaManager(mVFS.get(), mLuaScriptListFiles);
mLuaManager = new MWLua::LuaManager(mVFS.get());
mEnvironment.setLuaManager(mLuaManager);
// Create input and UI first to set up a bootstrapping environment for

@ -72,7 +72,6 @@ namespace OMW
std::string mCellName;
std::vector<std::string> mContentFiles;
std::vector<std::string> mGroundcoverFiles;
std::vector<std::string> mLuaScriptListFiles;
bool mSkipMenu;
bool mUseSound;
bool mCompileAll;
@ -146,7 +145,6 @@ namespace OMW
*/
void addContentFile(const std::string& file);
void addGroundcoverFile(const std::string& file);
void addLuaScriptListFile(const std::string& file);
/// Disable or enable all sounds
void setSoundUsage(bool soundUsage);

@ -124,9 +124,11 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat
engine.addGroundcoverFile(file);
}
StringsVector luaScriptLists = variables["lua-scripts"].as<Files::EscapeStringVector>().toStdStringVector();
for (const auto& file : luaScriptLists)
engine.addLuaScriptListFile(file);
if (variables.count("lua-scripts"))
{
Log(Debug::Warning) << "Lua scripts have been specified via the old lua-scripts option and will not be loaded. "
"Please update them to a version which uses the new omwscripts format.";
}
// startup-settings
engine.setCell(variables["start"].as<Files::EscapeHashString>().toStdString());

@ -11,6 +11,7 @@
#include "../mwbase/windowmanager.hpp"
#include "../mwworld/class.hpp"
#include "../mwworld/esmstore.hpp"
#include "../mwworld/ptr.hpp"
#include "luabindings.hpp"
@ -19,8 +20,7 @@
namespace MWLua
{
LuaManager::LuaManager(const VFS::Manager* vfs, std::vector<std::string> OMWScriptsFiles) :
mVFS(vfs), mOMWScriptsFiles(std::move(OMWScriptsFiles)), mLua(vfs, &mConfiguration)
LuaManager::LuaManager(const VFS::Manager* vfs) : mLua(vfs, &mConfiguration)
{
Log(Debug::Info) << "Lua version: " << LuaUtil::getLuaVersion();
@ -34,23 +34,7 @@ namespace MWLua
void LuaManager::initConfiguration()
{
ESM::LuaScriptsCfg cfg;
for (const std::string& file : mOMWScriptsFiles)
{
if (!Misc::StringUtils::endsWith(file, ".omwscripts"))
{
Log(Debug::Error) << "Script list should have suffix '.omwscripts', got: '" << file << "'";
continue;
}
try
{
std::string content(std::istreambuf_iterator<char>(*mVFS->get(file)), {});
LuaUtil::parseOMWScripts(cfg, content);
}
catch (std::exception& e) { Log(Debug::Error) << e.what(); }
}
// TODO: Add data from content files
mConfiguration.init(cfg);
mConfiguration.init(MWBase::Environment::get().getWorld()->getStore().getLuaScriptsCfg());
Log(Debug::Verbose) << "Lua scripts configuration (" << mConfiguration.size() << " scripts):";
for (size_t i = 0; i < mConfiguration.size(); ++i)
Log(Debug::Verbose) << "#" << i << " " << LuaUtil::scriptCfgToString(mConfiguration[i]);

@ -35,7 +35,7 @@ namespace MWLua
class LuaManager : public MWBase::LuaManager
{
public:
LuaManager(const VFS::Manager* vfs, std::vector<std::string> OMWScriptsFiles);
LuaManager(const VFS::Manager* vfs);
// Called by engine.cpp when the environment is fully initialized.
void init();
@ -97,9 +97,6 @@ namespace MWLua
void initConfiguration();
LocalScripts* createLocalScripts(const MWWorld::Ptr& ptr, ESM::LuaScriptCfg::Flags);
const VFS::Manager* mVFS;
const std::vector<std::string> mOMWScriptsFiles;
bool mInitialized = false;
bool mGlobalScriptsStarted = false;
LuaUtil::ScriptsConfiguration mConfiguration;

@ -1,14 +1,16 @@
#include "esmstore.hpp"
#include <algorithm>
#include <fstream>
#include <set>
#include <boost/filesystem/operations.hpp>
#include <components/debug/debuglog.hpp>
#include <components/loadinglistener/loadinglistener.hpp>
#include <components/esm/esmreader.hpp>
#include <components/esm/esmwriter.hpp>
#include <components/loadinglistener/loadinglistener.hpp>
#include <components/lua/configuration.hpp>
#include <components/misc/algorithm.hpp>
#include "../mwmechanics/spelllist.hpp"
@ -166,7 +168,10 @@ void ESMStore::load(ESM::ESMReader &esm, Loading::Listener* listener)
std::string fname = mast.name;
int index = ~0;
for (int i = 0; i < esm.getIndex(); i++) {
const std::string candidate = allPlugins->at(i).getContext().filename;
ESM::ESMReader& reader = allPlugins->at(i);
if (reader.getFileSize() == 0)
continue; // Content file in non-ESM format
const std::string candidate = reader.getContext().filename;
std::string fnamecandidate = boost::filesystem::path(candidate).filename().string();
if (Misc::StringUtils::ciEqual(fname, fnamecandidate)) {
index = i;
@ -213,6 +218,13 @@ void ESMStore::load(ESM::ESMReader &esm, Loading::Listener* listener)
// ignore project file only records
esm.skipRecord();
}
else if (n.toInt() == ESM::REC_LUAL)
{
ESM::LuaScriptsCfg cfg;
cfg.load(esm);
// TODO: update refnums in cfg.mScripts[].mInitializationData according to load order
mLuaContent.push_back(std::move(cfg));
}
else {
throw std::runtime_error("Unknown record: " + n.toString());
}
@ -234,6 +246,32 @@ void ESMStore::load(ESM::ESMReader &esm, Loading::Listener* listener)
}
}
ESM::LuaScriptsCfg ESMStore::getLuaScriptsCfg() const
{
ESM::LuaScriptsCfg cfg;
for (const LuaContent& c : mLuaContent)
{
if (std::holds_alternative<std::string>(c))
{
// *.omwscripts are intentionally reloaded every time when `getLuaScriptsCfg` is called.
// It is important for the `reloadlua` console command.
try
{
auto file = std::ifstream(std::get<std::string>(c));
std::string fileContent(std::istreambuf_iterator<char>(file), {});
LuaUtil::parseOMWScripts(cfg, fileContent);
}
catch (std::exception& e) { Log(Debug::Error) << e.what(); }
}
else
{
const ESM::LuaScriptsCfg& addition = std::get<ESM::LuaScriptsCfg>(c);
cfg.mScripts.insert(cfg.mScripts.end(), addition.mScripts.begin(), addition.mScripts.end());
}
}
return cfg;
}
void ESMStore::setUp(bool validateRecords)
{
mIds.clear();

@ -6,6 +6,7 @@
#include <stdexcept>
#include <unordered_map>
#include <components/esm/luascripts.hpp>
#include <components/esm/records.hpp>
#include "store.hpp"
@ -92,7 +93,16 @@ namespace MWWorld
template<class T>
void removeMissingObjects(Store<T>& store);
using LuaContent = std::variant<
ESM::LuaScriptsCfg, // data from an omwaddon
std::string>; // path to an omwscripts file
std::vector<LuaContent> mLuaContent;
public:
void addOMWScripts(std::string filePath) { mLuaContent.push_back(std::move(filePath)); }
ESM::LuaScriptsCfg getLuaScriptsCfg() const;
/// \todo replace with SharedIterator<StoreBase>
typedef std::map<int, StoreBase *>::const_iterator iterator;

@ -111,6 +111,17 @@ namespace MWWorld
LoadersContainer mLoaders;
};
struct OMWScriptsLoader : public ContentLoader
{
ESMStore& mStore;
OMWScriptsLoader(Loading::Listener& listener, ESMStore& store) : ContentLoader(listener), mStore(store) {}
void load(const boost::filesystem::path& filepath, int& index) override
{
ContentLoader::load(filepath.filename(), index);
mStore.addOMWScripts(filepath.string());
}
};
void World::adjustSky()
{
if (mSky && (isCellExterior() || isCellQuasiExterior()))
@ -156,6 +167,9 @@ namespace MWWorld
gameContentLoader.addLoader(".omwaddon", &esmLoader);
gameContentLoader.addLoader(".project", &esmLoader);
OMWScriptsLoader omwScriptsLoader(*listener, mStore);
gameContentLoader.addLoader(".omwscripts", &omwScriptsLoader);
loadContentFiles(fileCollections, contentFiles, groundcoverFiles, gameContentLoader);
listener->loadingOff();

@ -40,14 +40,11 @@ namespace OpenMW
"set initial cell")
("content", bpo::value<Files::EscapeStringVector>()->default_value(Files::EscapeStringVector(), "")
->multitoken()->composing(), "content file(s): esm/esp, or omwgame/omwaddon")
->multitoken()->composing(), "content file(s): esm/esp, or omwgame/omwaddon/omwscripts")
("groundcover", bpo::value<Files::EscapeStringVector>()->default_value(Files::EscapeStringVector(), "")
->multitoken()->composing(), "groundcover content file(s): esm/esp, or omwgame/omwaddon")
("lua-scripts", bpo::value<Files::EscapeStringVector>()->default_value(Files::EscapeStringVector(), "")
->multitoken()->composing(), "file(s) with a list of global Lua scripts: omwscripts")
("no-sound", bpo::value<bool>()->implicit_value(true)
->default_value(false), "disable all sounds")

@ -7,6 +7,7 @@
#include <components/esm/esmreader.hpp>
#include <components/esm/esmwriter.hpp>
#include <components/loadinglistener/loadinglistener.hpp>
#include <components/misc/stringops.hpp>
#include "apps/openmw/mwworld/esmstore.hpp"
#include "apps/openmw/mwmechanics/spelllist.hpp"
@ -88,7 +89,10 @@ struct ContentFileTest : public ::testing::Test
std::vector<std::string> contentFiles = variables["content"].as<Files::EscapeStringVector>().toStdStringVector();
for (auto & contentFile : contentFiles)
mContentFiles.push_back(collections.getPath(contentFile));
{
if (!Misc::StringUtils::ciEndsWith(contentFile, ".omwscripts"))
mContentFiles.push_back(collections.getPath(contentFile));
}
}
protected:

@ -165,6 +165,7 @@ enum RecNameInts
// format 1
REC_FILT = FourCC<'F','I','L','T'>::value,
REC_DBGP = FourCC<'D','B','G','P'>::value, ///< only used in project files
REC_LUAL = FourCC<'L','U','A','L'>::value, // LuaScriptsCfg
// format 16 - Lua scripts in saved games
REC_LUAM = FourCC<'L','U','A','M'>::value, // LuaManager data

Loading…
Cancel
Save