mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-03-03 13:49:40 +00:00
Add --script-all-dialogue switch to compile all dialogue scripts (Fixes #1659)
This commit is contained in:
parent
912dcdc418
commit
ba65c6cc7f
10 changed files with 188 additions and 5 deletions
|
@ -44,7 +44,7 @@ add_openmw_dir (mwgui
|
||||||
)
|
)
|
||||||
|
|
||||||
add_openmw_dir (mwdialogue
|
add_openmw_dir (mwdialogue
|
||||||
dialoguemanagerimp journalimp journalentry quest topic filter selectwrapper hypertextparser keywordsearch
|
dialoguemanagerimp journalimp journalentry quest topic filter selectwrapper hypertextparser keywordsearch scripttest
|
||||||
)
|
)
|
||||||
|
|
||||||
add_openmw_dir (mwscript
|
add_openmw_dir (mwscript
|
||||||
|
|
|
@ -40,6 +40,7 @@
|
||||||
|
|
||||||
#include "mwdialogue/dialoguemanagerimp.hpp"
|
#include "mwdialogue/dialoguemanagerimp.hpp"
|
||||||
#include "mwdialogue/journalimp.hpp"
|
#include "mwdialogue/journalimp.hpp"
|
||||||
|
#include "mwdialogue/scripttest.hpp"
|
||||||
|
|
||||||
#include "mwmechanics/mechanicsmanagerimp.hpp"
|
#include "mwmechanics/mechanicsmanagerimp.hpp"
|
||||||
|
|
||||||
|
@ -174,6 +175,7 @@ OMW::Engine::Engine(Files::ConfigurationManager& configurationManager)
|
||||||
, mSkipMenu (false)
|
, mSkipMenu (false)
|
||||||
, mUseSound (true)
|
, mUseSound (true)
|
||||||
, mCompileAll (false)
|
, mCompileAll (false)
|
||||||
|
, mCompileAllDialogue (false)
|
||||||
, mWarningsMode (1)
|
, mWarningsMode (1)
|
||||||
, mScriptContext (0)
|
, mScriptContext (0)
|
||||||
, mFSStrict (false)
|
, mFSStrict (false)
|
||||||
|
@ -425,7 +427,6 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings)
|
||||||
if (mCompileAll)
|
if (mCompileAll)
|
||||||
{
|
{
|
||||||
std::pair<int, int> result = MWBase::Environment::get().getScriptManager()->compileAll();
|
std::pair<int, int> result = MWBase::Environment::get().getScriptManager()->compileAll();
|
||||||
|
|
||||||
if (result.first)
|
if (result.first)
|
||||||
std::cout
|
std::cout
|
||||||
<< "compiled " << result.second << " of " << result.first << " scripts ("
|
<< "compiled " << result.second << " of " << result.first << " scripts ("
|
||||||
|
@ -433,6 +434,16 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings)
|
||||||
<< "%)"
|
<< "%)"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
}
|
}
|
||||||
|
if (mCompileAllDialogue)
|
||||||
|
{
|
||||||
|
std::pair<int, int> result = MWDialogue::ScriptTest::compileAll(&mExtensions);
|
||||||
|
if (result.first)
|
||||||
|
std::cout
|
||||||
|
<< "compiled " << result.second << " of " << result.first << " dialogue script/actor combinations a("
|
||||||
|
<< 100*static_cast<double> (result.second)/result.first
|
||||||
|
<< "%)"
|
||||||
|
<< std::endl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialise and enter main loop.
|
// Initialise and enter main loop.
|
||||||
|
@ -535,6 +546,11 @@ void OMW::Engine::setCompileAll (bool all)
|
||||||
mCompileAll = all;
|
mCompileAll = all;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OMW::Engine::setCompileAllDialogue (bool all)
|
||||||
|
{
|
||||||
|
mCompileAllDialogue = all;
|
||||||
|
}
|
||||||
|
|
||||||
void OMW::Engine::setSoundUsage(bool soundUsage)
|
void OMW::Engine::setSoundUsage(bool soundUsage)
|
||||||
{
|
{
|
||||||
mUseSound = soundUsage;
|
mUseSound = soundUsage;
|
||||||
|
|
|
@ -76,6 +76,7 @@ namespace OMW
|
||||||
bool mSkipMenu;
|
bool mSkipMenu;
|
||||||
bool mUseSound;
|
bool mUseSound;
|
||||||
bool mCompileAll;
|
bool mCompileAll;
|
||||||
|
bool mCompileAllDialogue;
|
||||||
int mWarningsMode;
|
int mWarningsMode;
|
||||||
std::string mFocusName;
|
std::string mFocusName;
|
||||||
std::map<std::string,std::string> mFallbackMap;
|
std::map<std::string,std::string> mFallbackMap;
|
||||||
|
@ -178,6 +179,9 @@ namespace OMW
|
||||||
/// Compile all scripts (excludign dialogue scripts) at startup?
|
/// Compile all scripts (excludign dialogue scripts) at startup?
|
||||||
void setCompileAll (bool all);
|
void setCompileAll (bool all);
|
||||||
|
|
||||||
|
/// Compile all dialogue scripts at startup?
|
||||||
|
void setCompileAllDialogue (bool all);
|
||||||
|
|
||||||
/// Font encoding
|
/// Font encoding
|
||||||
void setEncoding(const ToUTF8::FromType& encoding);
|
void setEncoding(const ToUTF8::FromType& encoding);
|
||||||
|
|
||||||
|
|
|
@ -130,6 +130,9 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat
|
||||||
("script-all", bpo::value<bool>()->implicit_value(true)
|
("script-all", bpo::value<bool>()->implicit_value(true)
|
||||||
->default_value(false), "compile all scripts (excluding dialogue scripts) at startup")
|
->default_value(false), "compile all scripts (excluding dialogue scripts) at startup")
|
||||||
|
|
||||||
|
("script-all-dialogue", bpo::value<bool>()->implicit_value(true)
|
||||||
|
->default_value(false), "compile all dialogue scripts at startup")
|
||||||
|
|
||||||
("script-console", bpo::value<bool>()->implicit_value(true)
|
("script-console", bpo::value<bool>()->implicit_value(true)
|
||||||
->default_value(false), "enable console-only script functionality")
|
->default_value(false), "enable console-only script functionality")
|
||||||
|
|
||||||
|
@ -264,6 +267,7 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat
|
||||||
|
|
||||||
// scripts
|
// scripts
|
||||||
engine.setCompileAll(variables["script-all"].as<bool>());
|
engine.setCompileAll(variables["script-all"].as<bool>());
|
||||||
|
engine.setCompileAllDialogue(variables["script-all-dialogue"].as<bool>());
|
||||||
engine.setScriptsVerbosity(variables["script-verbose"].as<bool>());
|
engine.setScriptsVerbosity(variables["script-verbose"].as<bool>());
|
||||||
engine.setScriptConsoleMode (variables["script-console"].as<bool>());
|
engine.setScriptConsoleMode (variables["script-console"].as<bool>());
|
||||||
engine.setStartupScript (variables["script-run"].as<std::string>());
|
engine.setStartupScript (variables["script-run"].as<std::string>());
|
||||||
|
|
|
@ -47,7 +47,7 @@
|
||||||
namespace MWDialogue
|
namespace MWDialogue
|
||||||
{
|
{
|
||||||
DialogueManager::DialogueManager (const Compiler::Extensions& extensions, bool scriptVerbose, Translation::Storage& translationDataStorage) :
|
DialogueManager::DialogueManager (const Compiler::Extensions& extensions, bool scriptVerbose, Translation::Storage& translationDataStorage) :
|
||||||
mCompilerContext (MWScript::CompilerContext::Type_Dialgoue),
|
mCompilerContext (MWScript::CompilerContext::Type_Dialogue),
|
||||||
mErrorStream(std::cout.rdbuf()),mErrorHandler(mErrorStream)
|
mErrorStream(std::cout.rdbuf()),mErrorHandler(mErrorStream)
|
||||||
, mTemporaryDispositionChange(0.f)
|
, mTemporaryDispositionChange(0.f)
|
||||||
, mPermanentDispositionChange(0.f), mScriptVerbose (scriptVerbose)
|
, mPermanentDispositionChange(0.f), mScriptVerbose (scriptVerbose)
|
||||||
|
|
|
@ -603,6 +603,17 @@ const ESM::DialInfo* MWDialogue::Filter::search (const ESM::Dialogue& dialogue,
|
||||||
return suitableInfos[0];
|
return suitableInfos[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<const ESM::DialInfo *> MWDialogue::Filter::listAll (const ESM::Dialogue& dialogue) const
|
||||||
|
{
|
||||||
|
std::vector<const ESM::DialInfo *> infos;
|
||||||
|
for (ESM::Dialogue::InfoContainer::const_iterator iter = dialogue.mInfo.begin(); iter!=dialogue.mInfo.end(); ++iter)
|
||||||
|
{
|
||||||
|
if (testActor (*iter))
|
||||||
|
infos.push_back(&*iter);
|
||||||
|
}
|
||||||
|
return infos;
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<const ESM::DialInfo *> MWDialogue::Filter::list (const ESM::Dialogue& dialogue,
|
std::vector<const ESM::DialInfo *> MWDialogue::Filter::list (const ESM::Dialogue& dialogue,
|
||||||
bool fallbackToInfoRefusal, bool searchAll, bool invertDisposition) const
|
bool fallbackToInfoRefusal, bool searchAll, bool invertDisposition) const
|
||||||
{
|
{
|
||||||
|
|
|
@ -55,7 +55,11 @@ namespace MWDialogue
|
||||||
|
|
||||||
std::vector<const ESM::DialInfo *> list (const ESM::Dialogue& dialogue,
|
std::vector<const ESM::DialInfo *> list (const ESM::Dialogue& dialogue,
|
||||||
bool fallbackToInfoRefusal, bool searchAll, bool invertDisposition=false) const;
|
bool fallbackToInfoRefusal, bool searchAll, bool invertDisposition=false) const;
|
||||||
///< \note If fallbackToInfoRefusal is used, the returned DialInfo might not be from the supplied ESM::Dialogue.
|
///< List all infos that could be used on the given actor, using the current runtime state of the actor.
|
||||||
|
/// \note If fallbackToInfoRefusal is used, the returned DialInfo might not be from the supplied ESM::Dialogue.
|
||||||
|
|
||||||
|
std::vector<const ESM::DialInfo *> listAll (const ESM::Dialogue& dialogue) const;
|
||||||
|
///< List all infos that could possibly be used on the given actor, ignoring runtime state filters and ignoring player filters.
|
||||||
|
|
||||||
const ESM::DialInfo* search (const ESM::Dialogue& dialogue, const bool fallbackToInfoRefusal) const;
|
const ESM::DialInfo* search (const ESM::Dialogue& dialogue, const bool fallbackToInfoRefusal) const;
|
||||||
///< Get a matching response for the requested dialogue.
|
///< Get a matching response for the requested dialogue.
|
||||||
|
|
124
apps/openmw/mwdialogue/scripttest.cpp
Normal file
124
apps/openmw/mwdialogue/scripttest.cpp
Normal file
|
@ -0,0 +1,124 @@
|
||||||
|
#include "scripttest.hpp"
|
||||||
|
|
||||||
|
#include "../mwworld/manualref.hpp"
|
||||||
|
#include "../mwworld/class.hpp"
|
||||||
|
|
||||||
|
#include "../mwbase/environment.hpp"
|
||||||
|
#include "../mwbase/world.hpp"
|
||||||
|
#include "../mwbase/scriptmanager.hpp"
|
||||||
|
|
||||||
|
#include "../mwscript/compilercontext.hpp"
|
||||||
|
|
||||||
|
#include <components/compiler/exception.hpp>
|
||||||
|
#include <components/compiler/streamerrorhandler.hpp>
|
||||||
|
#include <components/compiler/scanner.hpp>
|
||||||
|
#include <components/compiler/locals.hpp>
|
||||||
|
#include <components/compiler/output.hpp>
|
||||||
|
#include <components/compiler/scriptparser.hpp>
|
||||||
|
|
||||||
|
#include "filter.hpp"
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
|
void test(const MWWorld::Ptr& actor, int &compiled, int &total, const Compiler::Extensions* extensions)
|
||||||
|
{
|
||||||
|
MWDialogue::Filter filter(actor, 0, false);
|
||||||
|
|
||||||
|
MWScript::CompilerContext compilerContext(MWScript::CompilerContext::Type_Dialogue);
|
||||||
|
compilerContext.setExtensions(extensions);
|
||||||
|
std::ostream errorStream(std::cout.rdbuf());
|
||||||
|
Compiler::StreamErrorHandler errorHandler(errorStream);
|
||||||
|
|
||||||
|
const MWWorld::Store<ESM::Dialogue>& dialogues = MWBase::Environment::get().getWorld()->getStore().get<ESM::Dialogue>();
|
||||||
|
for (MWWorld::Store<ESM::Dialogue>::iterator it = dialogues.begin(); it != dialogues.end(); ++it)
|
||||||
|
{
|
||||||
|
std::vector<const ESM::DialInfo*> infos = filter.listAll(*it);
|
||||||
|
|
||||||
|
for (std::vector<const ESM::DialInfo*>::iterator it = infos.begin(); it != infos.end(); ++it)
|
||||||
|
{
|
||||||
|
const ESM::DialInfo* info = *it;
|
||||||
|
if (!info->mResultScript.empty())
|
||||||
|
{
|
||||||
|
bool success = true;
|
||||||
|
++total;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
errorHandler.reset();
|
||||||
|
|
||||||
|
std::istringstream input (info->mResultScript + "\n");
|
||||||
|
|
||||||
|
Compiler::Scanner scanner (errorHandler, input, extensions);
|
||||||
|
|
||||||
|
Compiler::Locals locals;
|
||||||
|
|
||||||
|
std::string actorScript = actor.getClass().getScript(actor);
|
||||||
|
|
||||||
|
if (!actorScript.empty())
|
||||||
|
{
|
||||||
|
// grab local variables from actor's script, if available.
|
||||||
|
locals = MWBase::Environment::get().getScriptManager()->getLocals (actorScript);
|
||||||
|
}
|
||||||
|
|
||||||
|
Compiler::ScriptParser parser(errorHandler, compilerContext, locals, false);
|
||||||
|
|
||||||
|
scanner.scan (parser);
|
||||||
|
|
||||||
|
if (!errorHandler.isGood())
|
||||||
|
success = false;
|
||||||
|
|
||||||
|
++compiled;
|
||||||
|
}
|
||||||
|
catch (const Compiler::SourceException& /* error */)
|
||||||
|
{
|
||||||
|
// error has already been reported via error handler
|
||||||
|
success = false;
|
||||||
|
}
|
||||||
|
catch (const std::exception& error)
|
||||||
|
{
|
||||||
|
std::cerr << std::string ("Dialogue error: An exception has been thrown: ") + error.what() << std::endl;
|
||||||
|
success = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!success)
|
||||||
|
{
|
||||||
|
std::cerr
|
||||||
|
<< "compiling failed (dialogue script)" << std::endl
|
||||||
|
<< info->mResultScript
|
||||||
|
<< std::endl << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace MWDialogue
|
||||||
|
{
|
||||||
|
|
||||||
|
namespace ScriptTest
|
||||||
|
{
|
||||||
|
|
||||||
|
std::pair<int, int> compileAll(const Compiler::Extensions *extensions)
|
||||||
|
{
|
||||||
|
int compiled = 0, total = 0;
|
||||||
|
const MWWorld::Store<ESM::NPC>& npcs = MWBase::Environment::get().getWorld()->getStore().get<ESM::NPC>();
|
||||||
|
for (MWWorld::Store<ESM::NPC>::iterator it = npcs.begin(); it != npcs.end(); ++it)
|
||||||
|
{
|
||||||
|
MWWorld::ManualRef ref(MWBase::Environment::get().getWorld()->getStore(), it->mId);
|
||||||
|
test(ref.getPtr(), compiled, total, extensions);
|
||||||
|
}
|
||||||
|
|
||||||
|
const MWWorld::Store<ESM::Creature>& creatures = MWBase::Environment::get().getWorld()->getStore().get<ESM::Creature>();
|
||||||
|
for (MWWorld::Store<ESM::Creature>::iterator it = creatures.begin(); it != creatures.end(); ++it)
|
||||||
|
{
|
||||||
|
MWWorld::ManualRef ref(MWBase::Environment::get().getWorld()->getStore(), it->mId);
|
||||||
|
test(ref.getPtr(), compiled, total, extensions);
|
||||||
|
}
|
||||||
|
return std::make_pair(total, compiled);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
20
apps/openmw/mwdialogue/scripttest.hpp
Normal file
20
apps/openmw/mwdialogue/scripttest.hpp
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
#ifndef OPENMW_MWDIALOGUE_SCRIPTTEST_H
|
||||||
|
#define OPENMW_MWDIALOGUE_SCRIPTTEST_H
|
||||||
|
|
||||||
|
#include <components/compiler/extensions.hpp>
|
||||||
|
|
||||||
|
namespace MWDialogue
|
||||||
|
{
|
||||||
|
|
||||||
|
namespace ScriptTest
|
||||||
|
{
|
||||||
|
|
||||||
|
/// Attempt to compile all dialogue scripts, use for verification purposes
|
||||||
|
/// @return A pair containing <total number of scripts, number of successfully compiled scripts>
|
||||||
|
std::pair<int, int> compileAll(const Compiler::Extensions* extensions);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -12,7 +12,7 @@ namespace MWScript
|
||||||
enum Type
|
enum Type
|
||||||
{
|
{
|
||||||
Type_Full, // global, local, targetted
|
Type_Full, // global, local, targetted
|
||||||
Type_Dialgoue,
|
Type_Dialogue,
|
||||||
Type_Console
|
Type_Console
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue