mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-19 21:23:52 +00:00
Merge branch 'scripts'
This commit is contained in:
commit
c9cd7fb6b7
82 changed files with 843 additions and 294 deletions
|
@ -9,7 +9,7 @@ opencs_units (model/doc
|
||||||
)
|
)
|
||||||
|
|
||||||
opencs_units_noqt (model/doc
|
opencs_units_noqt (model/doc
|
||||||
stage savingstate savingstages
|
stage savingstate savingstages blacklist
|
||||||
)
|
)
|
||||||
|
|
||||||
opencs_hdrs_noqt (model/doc
|
opencs_hdrs_noqt (model/doc
|
||||||
|
|
|
@ -86,7 +86,11 @@ std::pair<Files::PathContainer, std::vector<std::string> > CS::Editor::readConfi
|
||||||
("encoding", boost::program_options::value<std::string>()->default_value("win1252"))
|
("encoding", boost::program_options::value<std::string>()->default_value("win1252"))
|
||||||
("resources", boost::program_options::value<std::string>()->default_value("resources"))
|
("resources", boost::program_options::value<std::string>()->default_value("resources"))
|
||||||
("fallback-archive", boost::program_options::value<std::vector<std::string> >()->
|
("fallback-archive", boost::program_options::value<std::vector<std::string> >()->
|
||||||
default_value(std::vector<std::string>(), "fallback-archive")->multitoken());
|
default_value(std::vector<std::string>(), "fallback-archive")->multitoken())
|
||||||
|
("script-blacklist", boost::program_options::value<std::vector<std::string> >()->default_value(std::vector<std::string>(), "")
|
||||||
|
->multitoken(), "exclude specified script from the verifier (if the use of the blacklist is enabled)")
|
||||||
|
("script-blacklist-use", boost::program_options::value<bool>()->implicit_value(true)
|
||||||
|
->default_value(true), "enable script blacklisting");
|
||||||
|
|
||||||
boost::program_options::notify(variables);
|
boost::program_options::notify(variables);
|
||||||
|
|
||||||
|
@ -97,6 +101,10 @@ std::pair<Files::PathContainer, std::vector<std::string> > CS::Editor::readConfi
|
||||||
|
|
||||||
mDocumentManager.setResourceDir (mResources = variables["resources"].as<std::string>());
|
mDocumentManager.setResourceDir (mResources = variables["resources"].as<std::string>());
|
||||||
|
|
||||||
|
if (variables["script-blacklist-use"].as<bool>())
|
||||||
|
mDocumentManager.setBlacklistedScripts (
|
||||||
|
variables["script-blacklist"].as<std::vector<std::string> >());
|
||||||
|
|
||||||
mFsStrict = variables["fs-strict"].as<bool>();
|
mFsStrict = variables["fs-strict"].as<bool>();
|
||||||
|
|
||||||
Files::PathContainer dataDirs, dataLocal;
|
Files::PathContainer dataDirs, dataLocal;
|
||||||
|
|
31
apps/opencs/model/doc/blacklist.cpp
Normal file
31
apps/opencs/model/doc/blacklist.cpp
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
|
||||||
|
#include "blacklist.hpp"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
#include <components/misc/stringops.hpp>
|
||||||
|
|
||||||
|
bool CSMDoc::Blacklist::isBlacklisted (const CSMWorld::UniversalId& id) const
|
||||||
|
{
|
||||||
|
std::map<CSMWorld::UniversalId::Type, std::vector<std::string> >::const_iterator iter =
|
||||||
|
mIds.find (id.getType());
|
||||||
|
|
||||||
|
if (iter==mIds.end())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return std::binary_search (iter->second.begin(), iter->second.end(),
|
||||||
|
Misc::StringUtils::lowerCase (id.getId()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSMDoc::Blacklist::add (CSMWorld::UniversalId::Type type,
|
||||||
|
const std::vector<std::string>& ids)
|
||||||
|
{
|
||||||
|
std::vector<std::string>& list = mIds[type];
|
||||||
|
|
||||||
|
int size = list.size();
|
||||||
|
|
||||||
|
list.resize (size+ids.size());
|
||||||
|
|
||||||
|
std::transform (ids.begin(), ids.end(), list.begin()+size, Misc::StringUtils::lowerCase);
|
||||||
|
std::sort (list.begin(), list.end());
|
||||||
|
}
|
25
apps/opencs/model/doc/blacklist.hpp
Normal file
25
apps/opencs/model/doc/blacklist.hpp
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
#ifndef CSM_DOC_BLACKLIST_H
|
||||||
|
#define CSM_DOC_BLACKLIST_H
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "../world/universalid.hpp"
|
||||||
|
|
||||||
|
namespace CSMDoc
|
||||||
|
{
|
||||||
|
/// \brief ID blacklist sorted by UniversalId type
|
||||||
|
class Blacklist
|
||||||
|
{
|
||||||
|
std::map<CSMWorld::UniversalId::Type, std::vector<std::string> > mIds;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
bool isBlacklisted (const CSMWorld::UniversalId& id) const;
|
||||||
|
|
||||||
|
void add (CSMWorld::UniversalId::Type type, const std::vector<std::string>& ids);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -2205,9 +2205,10 @@ void CSMDoc::Document::createBase()
|
||||||
CSMDoc::Document::Document (const Files::ConfigurationManager& configuration,
|
CSMDoc::Document::Document (const Files::ConfigurationManager& configuration,
|
||||||
const std::vector< boost::filesystem::path >& files, bool new_,
|
const std::vector< boost::filesystem::path >& files, bool new_,
|
||||||
const boost::filesystem::path& savePath, const boost::filesystem::path& resDir,
|
const boost::filesystem::path& savePath, const boost::filesystem::path& resDir,
|
||||||
ToUTF8::FromType encoding, const CSMWorld::ResourcesManager& resourcesManager)
|
ToUTF8::FromType encoding, const CSMWorld::ResourcesManager& resourcesManager,
|
||||||
|
const std::vector<std::string>& blacklistedScripts)
|
||||||
: mSavePath (savePath), mContentFiles (files), mNew (new_), mData (encoding, resourcesManager),
|
: mSavePath (savePath), mContentFiles (files), mNew (new_), mData (encoding, resourcesManager),
|
||||||
mTools (mData), mResDir(resDir),
|
mTools (*this), mResDir(resDir),
|
||||||
mProjectPath ((configuration.getUserDataPath() / "projects") /
|
mProjectPath ((configuration.getUserDataPath() / "projects") /
|
||||||
(savePath.filename().string() + ".project")),
|
(savePath.filename().string() + ".project")),
|
||||||
mSaving (*this, mProjectPath, encoding)
|
mSaving (*this, mProjectPath, encoding)
|
||||||
|
@ -2239,6 +2240,8 @@ CSMDoc::Document::Document (const Files::ConfigurationManager& configuration,
|
||||||
createBase();
|
createBase();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mBlacklist.add (CSMWorld::UniversalId::Type_Script, blacklistedScripts);
|
||||||
|
|
||||||
addOptionalGmsts();
|
addOptionalGmsts();
|
||||||
addOptionalGlobals();
|
addOptionalGlobals();
|
||||||
|
|
||||||
|
@ -2358,6 +2361,13 @@ CSMTools::ReportModel *CSMDoc::Document::getReport (const CSMWorld::UniversalId&
|
||||||
return mTools.getReport (id);
|
return mTools.getReport (id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CSMDoc::Document::isBlacklisted (const CSMWorld::UniversalId& id)
|
||||||
|
const
|
||||||
|
{
|
||||||
|
return mBlacklist.isBlacklisted (id);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void CSMDoc::Document::progress (int current, int max, int type)
|
void CSMDoc::Document::progress (int current, int max, int type)
|
||||||
{
|
{
|
||||||
emit progress (current, max, type, 1, this);
|
emit progress (current, max, type, 1, this);
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
|
|
||||||
#include "state.hpp"
|
#include "state.hpp"
|
||||||
#include "saving.hpp"
|
#include "saving.hpp"
|
||||||
|
#include "blacklist.hpp"
|
||||||
|
|
||||||
class QAbstractItemModel;
|
class QAbstractItemModel;
|
||||||
|
|
||||||
|
@ -52,6 +53,7 @@ namespace CSMDoc
|
||||||
boost::filesystem::path mProjectPath;
|
boost::filesystem::path mProjectPath;
|
||||||
Saving mSaving;
|
Saving mSaving;
|
||||||
boost::filesystem::path mResDir;
|
boost::filesystem::path mResDir;
|
||||||
|
Blacklist mBlacklist;
|
||||||
|
|
||||||
// It is important that the undo stack is declared last, because on desctruction it fires a signal, that is connected to a slot, that is
|
// It is important that the undo stack is declared last, because on desctruction it fires a signal, that is connected to a slot, that is
|
||||||
// using other member variables. Unfortunately this connection is cut only in the QObject destructor, which is way too late.
|
// using other member variables. Unfortunately this connection is cut only in the QObject destructor, which is way too late.
|
||||||
|
@ -78,7 +80,8 @@ namespace CSMDoc
|
||||||
Document (const Files::ConfigurationManager& configuration,
|
Document (const Files::ConfigurationManager& configuration,
|
||||||
const std::vector< boost::filesystem::path >& files, bool new_,
|
const std::vector< boost::filesystem::path >& files, bool new_,
|
||||||
const boost::filesystem::path& savePath, const boost::filesystem::path& resDir,
|
const boost::filesystem::path& savePath, const boost::filesystem::path& resDir,
|
||||||
ToUTF8::FromType encoding, const CSMWorld::ResourcesManager& resourcesManager);
|
ToUTF8::FromType encoding, const CSMWorld::ResourcesManager& resourcesManager,
|
||||||
|
const std::vector<std::string>& blacklistedScripts);
|
||||||
|
|
||||||
~Document();
|
~Document();
|
||||||
|
|
||||||
|
@ -110,6 +113,8 @@ namespace CSMDoc
|
||||||
CSMTools::ReportModel *getReport (const CSMWorld::UniversalId& id);
|
CSMTools::ReportModel *getReport (const CSMWorld::UniversalId& id);
|
||||||
///< The ownership of the returned report is not transferred.
|
///< The ownership of the returned report is not transferred.
|
||||||
|
|
||||||
|
bool isBlacklisted (const CSMWorld::UniversalId& id) const;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
void stateChanged (int state, CSMDoc::Document *document);
|
void stateChanged (int state, CSMDoc::Document *document);
|
||||||
|
|
|
@ -52,7 +52,7 @@ CSMDoc::DocumentManager::~DocumentManager()
|
||||||
void CSMDoc::DocumentManager::addDocument (const std::vector<boost::filesystem::path>& files, const boost::filesystem::path& savePath,
|
void CSMDoc::DocumentManager::addDocument (const std::vector<boost::filesystem::path>& files, const boost::filesystem::path& savePath,
|
||||||
bool new_)
|
bool new_)
|
||||||
{
|
{
|
||||||
Document *document = new Document (mConfiguration, files, new_, savePath, mResDir, mEncoding, mResourcesManager);
|
Document *document = new Document (mConfiguration, files, new_, savePath, mResDir, mEncoding, mResourcesManager, mBlacklistedScripts);
|
||||||
|
|
||||||
mDocuments.push_back (document);
|
mDocuments.push_back (document);
|
||||||
|
|
||||||
|
@ -85,6 +85,11 @@ void CSMDoc::DocumentManager::setEncoding (ToUTF8::FromType encoding)
|
||||||
mEncoding = encoding;
|
mEncoding = encoding;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CSMDoc::DocumentManager::setBlacklistedScripts (const std::vector<std::string>& scriptIds)
|
||||||
|
{
|
||||||
|
mBlacklistedScripts = scriptIds;
|
||||||
|
}
|
||||||
|
|
||||||
void CSMDoc::DocumentManager::listResources()
|
void CSMDoc::DocumentManager::listResources()
|
||||||
{
|
{
|
||||||
mResourcesManager.listResources();
|
mResourcesManager.listResources();
|
||||||
|
|
|
@ -34,6 +34,7 @@ namespace CSMDoc
|
||||||
Loader mLoader;
|
Loader mLoader;
|
||||||
ToUTF8::FromType mEncoding;
|
ToUTF8::FromType mEncoding;
|
||||||
CSMWorld::ResourcesManager mResourcesManager;
|
CSMWorld::ResourcesManager mResourcesManager;
|
||||||
|
std::vector<std::string> mBlacklistedScripts;
|
||||||
|
|
||||||
DocumentManager (const DocumentManager&);
|
DocumentManager (const DocumentManager&);
|
||||||
DocumentManager& operator= (const DocumentManager&);
|
DocumentManager& operator= (const DocumentManager&);
|
||||||
|
@ -53,6 +54,8 @@ namespace CSMDoc
|
||||||
|
|
||||||
void setEncoding (ToUTF8::FromType encoding);
|
void setEncoding (ToUTF8::FromType encoding);
|
||||||
|
|
||||||
|
void setBlacklistedScripts (const std::vector<std::string>& scriptIds);
|
||||||
|
|
||||||
/// Ask OGRE for a list of available resources.
|
/// Ask OGRE for a list of available resources.
|
||||||
void listResources();
|
void listResources();
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
#include <components/compiler/exception.hpp>
|
#include <components/compiler/exception.hpp>
|
||||||
#include <components/compiler/extensions0.hpp>
|
#include <components/compiler/extensions0.hpp>
|
||||||
|
|
||||||
|
#include "../doc/document.hpp"
|
||||||
|
|
||||||
#include "../world/data.hpp"
|
#include "../world/data.hpp"
|
||||||
|
|
||||||
void CSMTools::ScriptCheckStage::report (const std::string& message, const Compiler::TokenLoc& loc,
|
void CSMTools::ScriptCheckStage::report (const std::string& message, const Compiler::TokenLoc& loc,
|
||||||
|
@ -37,8 +39,8 @@ void CSMTools::ScriptCheckStage::report (const std::string& message, Type type)
|
||||||
(type==ErrorMessage ? "error: " : "warning: ") + message));
|
(type==ErrorMessage ? "error: " : "warning: ") + message));
|
||||||
}
|
}
|
||||||
|
|
||||||
CSMTools::ScriptCheckStage::ScriptCheckStage (const CSMWorld::Data& data)
|
CSMTools::ScriptCheckStage::ScriptCheckStage (const CSMDoc::Document& document)
|
||||||
: mData (data), mContext (data), mMessages (0)
|
: mDocument (document), mContext (document.getData()), mMessages (0)
|
||||||
{
|
{
|
||||||
/// \todo add an option to configure warning mode
|
/// \todo add an option to configure warning mode
|
||||||
setWarningsMode (0);
|
setWarningsMode (0);
|
||||||
|
@ -53,18 +55,25 @@ int CSMTools::ScriptCheckStage::setup()
|
||||||
mMessages = 0;
|
mMessages = 0;
|
||||||
mId.clear();
|
mId.clear();
|
||||||
|
|
||||||
return mData.getScripts().getSize();
|
return mDocument.getData().getScripts().getSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSMTools::ScriptCheckStage::perform (int stage, Messages& messages)
|
void CSMTools::ScriptCheckStage::perform (int stage, Messages& messages)
|
||||||
{
|
{
|
||||||
|
mId = mDocument.getData().getScripts().getId (stage);
|
||||||
|
|
||||||
|
if (mDocument.isBlacklisted (
|
||||||
|
CSMWorld::UniversalId (CSMWorld::UniversalId::Type_Script, mId)))
|
||||||
|
return;
|
||||||
|
|
||||||
mMessages = &messages;
|
mMessages = &messages;
|
||||||
mId = mData.getScripts().getId (stage);
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
mFile = mData.getScripts().getRecord (stage).get().mId;
|
const CSMWorld::Data& data = mDocument.getData();
|
||||||
std::istringstream input (mData.getScripts().getRecord (stage).get().mScriptText);
|
|
||||||
|
mFile = data.getScripts().getRecord (stage).get().mId;
|
||||||
|
std::istringstream input (data.getScripts().getRecord (stage).get().mScriptText);
|
||||||
|
|
||||||
Compiler::Scanner scanner (*this, input, mContext.getExtensions());
|
Compiler::Scanner scanner (*this, input, mContext.getExtensions());
|
||||||
|
|
||||||
|
|
|
@ -8,12 +8,17 @@
|
||||||
|
|
||||||
#include "../world/scriptcontext.hpp"
|
#include "../world/scriptcontext.hpp"
|
||||||
|
|
||||||
|
namespace CSMDoc
|
||||||
|
{
|
||||||
|
class Document;
|
||||||
|
}
|
||||||
|
|
||||||
namespace CSMTools
|
namespace CSMTools
|
||||||
{
|
{
|
||||||
/// \brief VerifyStage: make sure that scripts compile
|
/// \brief VerifyStage: make sure that scripts compile
|
||||||
class ScriptCheckStage : public CSMDoc::Stage, private Compiler::ErrorHandler
|
class ScriptCheckStage : public CSMDoc::Stage, private Compiler::ErrorHandler
|
||||||
{
|
{
|
||||||
const CSMWorld::Data& mData;
|
const CSMDoc::Document& mDocument;
|
||||||
Compiler::Extensions mExtensions;
|
Compiler::Extensions mExtensions;
|
||||||
CSMWorld::ScriptContext mContext;
|
CSMWorld::ScriptContext mContext;
|
||||||
std::string mId;
|
std::string mId;
|
||||||
|
@ -28,7 +33,7 @@ namespace CSMTools
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
ScriptCheckStage (const CSMWorld::Data& data);
|
ScriptCheckStage (const CSMDoc::Document& document);
|
||||||
|
|
||||||
virtual int setup();
|
virtual int setup();
|
||||||
///< \return number of steps
|
///< \return number of steps
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
#include "../doc/state.hpp"
|
#include "../doc/state.hpp"
|
||||||
#include "../doc/operation.hpp"
|
#include "../doc/operation.hpp"
|
||||||
|
#include "../doc/document.hpp"
|
||||||
|
|
||||||
#include "../world/data.hpp"
|
#include "../world/data.hpp"
|
||||||
#include "../world/universalid.hpp"
|
#include "../world/universalid.hpp"
|
||||||
|
@ -80,13 +81,14 @@ CSMDoc::Operation *CSMTools::Tools::getVerifier()
|
||||||
|
|
||||||
mVerifier->appendStage (new ReferenceableCheckStage (mData.getReferenceables().getDataSet(), mData.getRaces(), mData.getClasses(), mData.getFactions()));
|
mVerifier->appendStage (new ReferenceableCheckStage (mData.getReferenceables().getDataSet(), mData.getRaces(), mData.getClasses(), mData.getFactions()));
|
||||||
|
|
||||||
mVerifier->appendStage (new ScriptCheckStage (mData));
|
mVerifier->appendStage (new ScriptCheckStage (mDocument));
|
||||||
}
|
}
|
||||||
|
|
||||||
return mVerifier;
|
return mVerifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
CSMTools::Tools::Tools (CSMWorld::Data& data) : mData (data), mVerifier (0), mNextReportNumber (0)
|
CSMTools::Tools::Tools (CSMDoc::Document& document)
|
||||||
|
: mDocument (document), mData (document.getData()), mVerifier (0), mNextReportNumber (0)
|
||||||
{
|
{
|
||||||
// index 0: load error log
|
// index 0: load error log
|
||||||
mReports.insert (std::make_pair (mNextReportNumber++, new ReportModel));
|
mReports.insert (std::make_pair (mNextReportNumber++, new ReportModel));
|
||||||
|
|
|
@ -14,6 +14,7 @@ namespace CSMWorld
|
||||||
namespace CSMDoc
|
namespace CSMDoc
|
||||||
{
|
{
|
||||||
class Operation;
|
class Operation;
|
||||||
|
class Document;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace CSMTools
|
namespace CSMTools
|
||||||
|
@ -24,6 +25,7 @@ namespace CSMTools
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
|
CSMDoc::Document& mDocument;
|
||||||
CSMWorld::Data& mData;
|
CSMWorld::Data& mData;
|
||||||
CSMDoc::Operation *mVerifier;
|
CSMDoc::Operation *mVerifier;
|
||||||
std::map<int, ReportModel *> mReports;
|
std::map<int, ReportModel *> mReports;
|
||||||
|
@ -44,7 +46,7 @@ namespace CSMTools
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Tools (CSMWorld::Data& data);
|
Tools (CSMDoc::Document& document);
|
||||||
|
|
||||||
virtual ~Tools();
|
virtual ~Tools();
|
||||||
|
|
||||||
|
|
|
@ -180,6 +180,7 @@ OMW::Engine::Engine(Files::ConfigurationManager& configurationManager)
|
||||||
, mEncoder(NULL)
|
, mEncoder(NULL)
|
||||||
, mActivationDistanceOverride(-1)
|
, mActivationDistanceOverride(-1)
|
||||||
, mGrab(true)
|
, mGrab(true)
|
||||||
|
, mScriptBlacklistUse (true)
|
||||||
|
|
||||||
{
|
{
|
||||||
std::srand ( std::time(NULL) );
|
std::srand ( std::time(NULL) );
|
||||||
|
@ -406,7 +407,8 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings)
|
||||||
mScriptContext->setExtensions (&mExtensions);
|
mScriptContext->setExtensions (&mExtensions);
|
||||||
|
|
||||||
mEnvironment.setScriptManager (new MWScript::ScriptManager (MWBase::Environment::get().getWorld()->getStore(),
|
mEnvironment.setScriptManager (new MWScript::ScriptManager (MWBase::Environment::get().getWorld()->getStore(),
|
||||||
mVerboseScripts, *mScriptContext, mWarningsMode));
|
mVerboseScripts, *mScriptContext, mWarningsMode,
|
||||||
|
mScriptBlacklistUse ? mScriptBlacklist : std::vector<std::string>()));
|
||||||
|
|
||||||
// Create game mechanics system
|
// Create game mechanics system
|
||||||
MWMechanics::MechanicsManager* mechanics = new MWMechanics::MechanicsManager;
|
MWMechanics::MechanicsManager* mechanics = new MWMechanics::MechanicsManager;
|
||||||
|
@ -565,3 +567,13 @@ void OMW::Engine::setWarningsMode (int mode)
|
||||||
{
|
{
|
||||||
mWarningsMode = mode;
|
mWarningsMode = mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OMW::Engine::setScriptBlacklist (const std::vector<std::string>& list)
|
||||||
|
{
|
||||||
|
mScriptBlacklist = list;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OMW::Engine::setScriptBlacklistUse (bool use)
|
||||||
|
{
|
||||||
|
mScriptBlacklistUse = use;
|
||||||
|
}
|
|
@ -89,6 +89,8 @@ namespace OMW
|
||||||
Files::Collections mFileCollections;
|
Files::Collections mFileCollections;
|
||||||
bool mFSStrict;
|
bool mFSStrict;
|
||||||
Translation::Storage mTranslationDataStorage;
|
Translation::Storage mTranslationDataStorage;
|
||||||
|
std::vector<std::string> mScriptBlacklist;
|
||||||
|
bool mScriptBlacklistUse;
|
||||||
|
|
||||||
// not implemented
|
// not implemented
|
||||||
Engine (const Engine&);
|
Engine (const Engine&);
|
||||||
|
@ -181,6 +183,10 @@ namespace OMW
|
||||||
|
|
||||||
void setWarningsMode (int mode);
|
void setWarningsMode (int mode);
|
||||||
|
|
||||||
|
void setScriptBlacklist (const std::vector<std::string>& list);
|
||||||
|
|
||||||
|
void setScriptBlacklistUse (bool use);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Files::ConfigurationManager& mCfgMgr;
|
Files::ConfigurationManager& mCfgMgr;
|
||||||
};
|
};
|
||||||
|
|
|
@ -144,6 +144,12 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat
|
||||||
"\t1 - show warning but consider script as correctly compiled anyway\n"
|
"\t1 - show warning but consider script as correctly compiled anyway\n"
|
||||||
"\t2 - treat warnings as errors")
|
"\t2 - treat warnings as errors")
|
||||||
|
|
||||||
|
("script-blacklist", bpo::value<StringsVector>()->default_value(StringsVector(), "")
|
||||||
|
->multitoken(), "ignore the specified script (if the use of the blacklist is enabled)")
|
||||||
|
|
||||||
|
("script-blacklist-use", bpo::value<bool>()->implicit_value(true)
|
||||||
|
->default_value(true), "enable script blacklisting")
|
||||||
|
|
||||||
("skip-menu", bpo::value<bool>()->implicit_value(true)
|
("skip-menu", bpo::value<bool>()->implicit_value(true)
|
||||||
->default_value(false), "skip main menu on game startup")
|
->default_value(false), "skip main menu on game startup")
|
||||||
|
|
||||||
|
@ -241,15 +247,19 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat
|
||||||
engine.setCell(variables["start"].as<std::string>());
|
engine.setCell(variables["start"].as<std::string>());
|
||||||
engine.setSkipMenu (variables["skip-menu"].as<bool>());
|
engine.setSkipMenu (variables["skip-menu"].as<bool>());
|
||||||
|
|
||||||
// other settings
|
// scripts
|
||||||
engine.setSoundUsage(!variables["no-sound"].as<bool>());
|
|
||||||
engine.setScriptsVerbosity(variables["script-verbose"].as<bool>());
|
|
||||||
engine.setCompileAll(variables["script-all"].as<bool>());
|
engine.setCompileAll(variables["script-all"].as<bool>());
|
||||||
engine.setFallbackValues(variables["fallback"].as<FallbackMap>().mMap);
|
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>());
|
||||||
engine.setActivationDistanceOverride (variables["activate-dist"].as<int>());
|
|
||||||
engine.setWarningsMode (variables["script-warn"].as<int>());
|
engine.setWarningsMode (variables["script-warn"].as<int>());
|
||||||
|
engine.setScriptBlacklist (variables["script-blacklist"].as<StringsVector>());
|
||||||
|
engine.setScriptBlacklistUse (variables["script-blacklist-use"].as<bool>());
|
||||||
|
|
||||||
|
// other settings
|
||||||
|
engine.setSoundUsage(!variables["no-sound"].as<bool>());
|
||||||
|
engine.setFallbackValues(variables["fallback"].as<FallbackMap>().mMap);
|
||||||
|
engine.setActivationDistanceOverride (variables["activate-dist"].as<int>());
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,16 +46,10 @@ namespace MWBase
|
||||||
///< Compile all scripts
|
///< Compile all scripts
|
||||||
/// \return count, success
|
/// \return count, success
|
||||||
|
|
||||||
virtual Compiler::Locals& getLocals (const std::string& name) = 0;
|
virtual const Compiler::Locals& getLocals (const std::string& name) = 0;
|
||||||
///< Return locals for script \a name.
|
///< Return locals for script \a name.
|
||||||
|
|
||||||
virtual MWScript::GlobalScripts& getGlobalScripts() = 0;
|
virtual MWScript::GlobalScripts& getGlobalScripts() = 0;
|
||||||
|
|
||||||
virtual int getLocalIndex (const std::string& scriptId, const std::string& variable,
|
|
||||||
char type) = 0;
|
|
||||||
///< Return index of the variable of the given name and type in the given script. Will
|
|
||||||
/// throw an exception, if there is no such script or variable or the type does not match.
|
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,11 @@
|
||||||
|
|
||||||
namespace MWClass
|
namespace MWClass
|
||||||
{
|
{
|
||||||
|
std::string Activator::getId (const MWWorld::Ptr& ptr) const
|
||||||
|
{
|
||||||
|
return ptr.get<ESM::Activator>()->mBase->mId;
|
||||||
|
}
|
||||||
|
|
||||||
void Activator::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
|
void Activator::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
|
||||||
{
|
{
|
||||||
const std::string model = getModel(ptr);
|
const std::string model = getModel(ptr);
|
||||||
|
|
|
@ -13,6 +13,9 @@ namespace MWClass
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
/// Return ID of \a ptr
|
||||||
|
virtual std::string getId (const MWWorld::Ptr& ptr) const;
|
||||||
|
|
||||||
virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const;
|
virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const;
|
||||||
///< Add reference into a cell for rendering
|
///< Add reference into a cell for rendering
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,11 @@
|
||||||
|
|
||||||
namespace MWClass
|
namespace MWClass
|
||||||
{
|
{
|
||||||
|
std::string Apparatus::getId (const MWWorld::Ptr& ptr) const
|
||||||
|
{
|
||||||
|
return ptr.get<ESM::Apparatus>()->mBase->mId;
|
||||||
|
}
|
||||||
|
|
||||||
void Apparatus::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
|
void Apparatus::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
|
||||||
{
|
{
|
||||||
const std::string model = getModel(ptr);
|
const std::string model = getModel(ptr);
|
||||||
|
|
|
@ -13,6 +13,9 @@ namespace MWClass
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
/// Return ID of \a ptr
|
||||||
|
virtual std::string getId (const MWWorld::Ptr& ptr) const;
|
||||||
|
|
||||||
virtual float getWeight (const MWWorld::Ptr& ptr) const;
|
virtual float getWeight (const MWWorld::Ptr& ptr) const;
|
||||||
|
|
||||||
virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const;
|
virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const;
|
||||||
|
|
|
@ -25,6 +25,11 @@
|
||||||
|
|
||||||
namespace MWClass
|
namespace MWClass
|
||||||
{
|
{
|
||||||
|
std::string Armor::getId (const MWWorld::Ptr& ptr) const
|
||||||
|
{
|
||||||
|
return ptr.get<ESM::Armor>()->mBase->mId;
|
||||||
|
}
|
||||||
|
|
||||||
void Armor::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
|
void Armor::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
|
||||||
{
|
{
|
||||||
const std::string model = getModel(ptr);
|
const std::string model = getModel(ptr);
|
||||||
|
|
|
@ -12,6 +12,9 @@ namespace MWClass
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
/// Return ID of \a ptr
|
||||||
|
virtual std::string getId (const MWWorld::Ptr& ptr) const;
|
||||||
|
|
||||||
virtual float getWeight (const MWWorld::Ptr& ptr) const;
|
virtual float getWeight (const MWWorld::Ptr& ptr) const;
|
||||||
|
|
||||||
virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const;
|
virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const;
|
||||||
|
|
|
@ -22,6 +22,11 @@
|
||||||
|
|
||||||
namespace MWClass
|
namespace MWClass
|
||||||
{
|
{
|
||||||
|
std::string Book::getId (const MWWorld::Ptr& ptr) const
|
||||||
|
{
|
||||||
|
return ptr.get<ESM::Book>()->mBase->mId;
|
||||||
|
}
|
||||||
|
|
||||||
void Book::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
|
void Book::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
|
||||||
{
|
{
|
||||||
const std::string model = getModel(ptr);
|
const std::string model = getModel(ptr);
|
||||||
|
|
|
@ -12,6 +12,9 @@ namespace MWClass
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
/// Return ID of \a ptr
|
||||||
|
virtual std::string getId (const MWWorld::Ptr& ptr) const;
|
||||||
|
|
||||||
virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const;
|
virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const;
|
||||||
///< Add reference into a cell for rendering
|
///< Add reference into a cell for rendering
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,11 @@
|
||||||
|
|
||||||
namespace MWClass
|
namespace MWClass
|
||||||
{
|
{
|
||||||
|
std::string Clothing::getId (const MWWorld::Ptr& ptr) const
|
||||||
|
{
|
||||||
|
return ptr.get<ESM::Clothing>()->mBase->mId;
|
||||||
|
}
|
||||||
|
|
||||||
void Clothing::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
|
void Clothing::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
|
||||||
{
|
{
|
||||||
const std::string model = getModel(ptr);
|
const std::string model = getModel(ptr);
|
||||||
|
|
|
@ -12,6 +12,9 @@ namespace MWClass
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
/// Return ID of \a ptr
|
||||||
|
virtual std::string getId (const MWWorld::Ptr& ptr) const;
|
||||||
|
|
||||||
virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const;
|
virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const;
|
||||||
///< Add reference into a cell for rendering
|
///< Add reference into a cell for rendering
|
||||||
|
|
||||||
|
|
|
@ -43,6 +43,11 @@ namespace
|
||||||
|
|
||||||
namespace MWClass
|
namespace MWClass
|
||||||
{
|
{
|
||||||
|
std::string Container::getId (const MWWorld::Ptr& ptr) const
|
||||||
|
{
|
||||||
|
return ptr.get<ESM::Container>()->mBase->mId;
|
||||||
|
}
|
||||||
|
|
||||||
void Container::ensureCustomData (const MWWorld::Ptr& ptr) const
|
void Container::ensureCustomData (const MWWorld::Ptr& ptr) const
|
||||||
{
|
{
|
||||||
if (!ptr.getRefData().getCustomData())
|
if (!ptr.getRefData().getCustomData())
|
||||||
|
|
|
@ -15,6 +15,9 @@ namespace MWClass
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
/// Return ID of \a ptr
|
||||||
|
virtual std::string getId (const MWWorld::Ptr& ptr) const;
|
||||||
|
|
||||||
virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const;
|
virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const;
|
||||||
///< Add reference into a cell for rendering
|
///< Add reference into a cell for rendering
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,11 @@ namespace
|
||||||
|
|
||||||
namespace MWClass
|
namespace MWClass
|
||||||
{
|
{
|
||||||
|
std::string CreatureLevList::getId (const MWWorld::Ptr& ptr) const
|
||||||
|
{
|
||||||
|
return ptr.get<ESM::CreatureLevList>()->mBase->mId;
|
||||||
|
}
|
||||||
|
|
||||||
std::string CreatureLevList::getName (const MWWorld::Ptr& ptr) const
|
std::string CreatureLevList::getName (const MWWorld::Ptr& ptr) const
|
||||||
{
|
{
|
||||||
return "";
|
return "";
|
||||||
|
|
|
@ -11,6 +11,9 @@ namespace MWClass
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
/// Return ID of \a ptr
|
||||||
|
virtual std::string getId (const MWWorld::Ptr& ptr) const;
|
||||||
|
|
||||||
virtual std::string getName (const MWWorld::Ptr& ptr) const;
|
virtual std::string getName (const MWWorld::Ptr& ptr) const;
|
||||||
///< \return name (the one that is to be presented to the user; not the internal one);
|
///< \return name (the one that is to be presented to the user; not the internal one);
|
||||||
/// can return an empty string.
|
/// can return an empty string.
|
||||||
|
|
|
@ -42,6 +42,11 @@ namespace
|
||||||
|
|
||||||
namespace MWClass
|
namespace MWClass
|
||||||
{
|
{
|
||||||
|
std::string Door::getId (const MWWorld::Ptr& ptr) const
|
||||||
|
{
|
||||||
|
return ptr.get<ESM::Door>()->mBase->mId;
|
||||||
|
}
|
||||||
|
|
||||||
void Door::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
|
void Door::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
|
||||||
{
|
{
|
||||||
const std::string model = getModel(ptr);
|
const std::string model = getModel(ptr);
|
||||||
|
|
|
@ -16,6 +16,9 @@ namespace MWClass
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
/// Return ID of \a ptr
|
||||||
|
virtual std::string getId (const MWWorld::Ptr& ptr) const;
|
||||||
|
|
||||||
virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const;
|
virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const;
|
||||||
///< Add reference into a cell for rendering
|
///< Add reference into a cell for rendering
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,11 @@
|
||||||
|
|
||||||
namespace MWClass
|
namespace MWClass
|
||||||
{
|
{
|
||||||
|
std::string ItemLevList::getId (const MWWorld::Ptr& ptr) const
|
||||||
|
{
|
||||||
|
return ptr.get<ESM::ItemLevList>()->mBase->mId;
|
||||||
|
}
|
||||||
|
|
||||||
std::string ItemLevList::getName (const MWWorld::Ptr& ptr) const
|
std::string ItemLevList::getName (const MWWorld::Ptr& ptr) const
|
||||||
{
|
{
|
||||||
return "";
|
return "";
|
||||||
|
|
|
@ -9,6 +9,9 @@ namespace MWClass
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
/// Return ID of \a ptr
|
||||||
|
virtual std::string getId (const MWWorld::Ptr& ptr) const;
|
||||||
|
|
||||||
virtual std::string getName (const MWWorld::Ptr& ptr) const;
|
virtual std::string getName (const MWWorld::Ptr& ptr) const;
|
||||||
///< \return name (the one that is to be presented to the user; not the internal one);
|
///< \return name (the one that is to be presented to the user; not the internal one);
|
||||||
/// can return an empty string.
|
/// can return an empty string.
|
||||||
|
|
|
@ -47,6 +47,11 @@ namespace
|
||||||
|
|
||||||
namespace MWClass
|
namespace MWClass
|
||||||
{
|
{
|
||||||
|
std::string Light::getId (const MWWorld::Ptr& ptr) const
|
||||||
|
{
|
||||||
|
return ptr.get<ESM::Light>()->mBase->mId;
|
||||||
|
}
|
||||||
|
|
||||||
void Light::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
|
void Light::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
|
||||||
{
|
{
|
||||||
const std::string model = getModel(ptr);
|
const std::string model = getModel(ptr);
|
||||||
|
|
|
@ -14,6 +14,9 @@ namespace MWClass
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
/// Return ID of \a ptr
|
||||||
|
virtual std::string getId (const MWWorld::Ptr& ptr) const;
|
||||||
|
|
||||||
virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const;
|
virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const;
|
||||||
///< Add reference into a cell for rendering
|
///< Add reference into a cell for rendering
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,11 @@
|
||||||
|
|
||||||
namespace MWClass
|
namespace MWClass
|
||||||
{
|
{
|
||||||
|
std::string Lockpick::getId (const MWWorld::Ptr& ptr) const
|
||||||
|
{
|
||||||
|
return ptr.get<ESM::Lockpick>()->mBase->mId;
|
||||||
|
}
|
||||||
|
|
||||||
void Lockpick::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
|
void Lockpick::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
|
||||||
{
|
{
|
||||||
const std::string model = getModel(ptr);
|
const std::string model = getModel(ptr);
|
||||||
|
|
|
@ -12,6 +12,9 @@ namespace MWClass
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
/// Return ID of \a ptr
|
||||||
|
virtual std::string getId (const MWWorld::Ptr& ptr) const;
|
||||||
|
|
||||||
virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const;
|
virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const;
|
||||||
///< Add reference into a cell for rendering
|
///< Add reference into a cell for rendering
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,11 @@ bool isGold (const MWWorld::Ptr& ptr)
|
||||||
|
|
||||||
namespace MWClass
|
namespace MWClass
|
||||||
{
|
{
|
||||||
|
std::string Miscellaneous::getId (const MWWorld::Ptr& ptr) const
|
||||||
|
{
|
||||||
|
return ptr.get<ESM::Miscellaneous>()->mBase->mId;
|
||||||
|
}
|
||||||
|
|
||||||
void Miscellaneous::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
|
void Miscellaneous::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
|
||||||
{
|
{
|
||||||
const std::string model = getModel(ptr);
|
const std::string model = getModel(ptr);
|
||||||
|
|
|
@ -12,6 +12,9 @@ namespace MWClass
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
/// Return ID of \a ptr
|
||||||
|
virtual std::string getId (const MWWorld::Ptr& ptr) const;
|
||||||
|
|
||||||
virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const;
|
virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const;
|
||||||
///< Add reference into a cell for rendering
|
///< Add reference into a cell for rendering
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,11 @@
|
||||||
|
|
||||||
namespace MWClass
|
namespace MWClass
|
||||||
{
|
{
|
||||||
|
std::string Potion::getId (const MWWorld::Ptr& ptr) const
|
||||||
|
{
|
||||||
|
return ptr.get<ESM::Potion>()->mBase->mId;
|
||||||
|
}
|
||||||
|
|
||||||
void Potion::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
|
void Potion::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
|
||||||
{
|
{
|
||||||
const std::string model = getModel(ptr);
|
const std::string model = getModel(ptr);
|
||||||
|
|
|
@ -12,6 +12,9 @@ namespace MWClass
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
/// Return ID of \a ptr
|
||||||
|
virtual std::string getId (const MWWorld::Ptr& ptr) const;
|
||||||
|
|
||||||
virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const;
|
virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const;
|
||||||
///< Add reference into a cell for rendering
|
///< Add reference into a cell for rendering
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,11 @@
|
||||||
|
|
||||||
namespace MWClass
|
namespace MWClass
|
||||||
{
|
{
|
||||||
|
std::string Probe::getId (const MWWorld::Ptr& ptr) const
|
||||||
|
{
|
||||||
|
return ptr.get<ESM::Probe>()->mBase->mId;
|
||||||
|
}
|
||||||
|
|
||||||
void Probe::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
|
void Probe::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
|
||||||
{
|
{
|
||||||
const std::string model = getModel(ptr);
|
const std::string model = getModel(ptr);
|
||||||
|
|
|
@ -12,6 +12,9 @@ namespace MWClass
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
/// Return ID of \a ptr
|
||||||
|
virtual std::string getId (const MWWorld::Ptr& ptr) const;
|
||||||
|
|
||||||
virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const;
|
virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const;
|
||||||
///< Add reference into a cell for rendering
|
///< Add reference into a cell for rendering
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,11 @@
|
||||||
|
|
||||||
namespace MWClass
|
namespace MWClass
|
||||||
{
|
{
|
||||||
|
std::string Repair::getId (const MWWorld::Ptr& ptr) const
|
||||||
|
{
|
||||||
|
return ptr.get<ESM::Repair>()->mBase->mId;
|
||||||
|
}
|
||||||
|
|
||||||
void Repair::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
|
void Repair::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
|
||||||
{
|
{
|
||||||
const std::string model = getModel(ptr);
|
const std::string model = getModel(ptr);
|
||||||
|
|
|
@ -12,6 +12,9 @@ namespace MWClass
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
/// Return ID of \a ptr
|
||||||
|
virtual std::string getId (const MWWorld::Ptr& ptr) const;
|
||||||
|
|
||||||
virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const;
|
virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const;
|
||||||
///< Add reference into a cell for rendering
|
///< Add reference into a cell for rendering
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,11 @@
|
||||||
|
|
||||||
namespace MWClass
|
namespace MWClass
|
||||||
{
|
{
|
||||||
|
std::string Static::getId (const MWWorld::Ptr& ptr) const
|
||||||
|
{
|
||||||
|
return ptr.get<ESM::Static>()->mBase->mId;
|
||||||
|
}
|
||||||
|
|
||||||
void Static::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
|
void Static::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
|
||||||
{
|
{
|
||||||
MWWorld::LiveCellRef<ESM::Static> *ref =
|
MWWorld::LiveCellRef<ESM::Static> *ref =
|
||||||
|
|
|
@ -12,6 +12,9 @@ namespace MWClass
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
/// Return ID of \a ptr
|
||||||
|
virtual std::string getId (const MWWorld::Ptr& ptr) const;
|
||||||
|
|
||||||
virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const;
|
virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const;
|
||||||
///< Add reference into a cell for rendering
|
///< Add reference into a cell for rendering
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,14 @@
|
||||||
|
|
||||||
#include "filter.hpp"
|
#include "filter.hpp"
|
||||||
|
|
||||||
|
#include <components/compiler/locals.hpp>
|
||||||
|
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
#include "../mwbase/world.hpp"
|
#include "../mwbase/world.hpp"
|
||||||
#include "../mwbase/journal.hpp"
|
#include "../mwbase/journal.hpp"
|
||||||
#include "../mwbase/mechanicsmanager.hpp"
|
#include "../mwbase/mechanicsmanager.hpp"
|
||||||
#include "../mwbase/dialoguemanager.hpp"
|
#include "../mwbase/dialoguemanager.hpp"
|
||||||
|
#include "../mwbase/scriptmanager.hpp"
|
||||||
|
|
||||||
#include "../mwworld/class.hpp"
|
#include "../mwworld/class.hpp"
|
||||||
#include "../mwworld/inventorystore.hpp"
|
#include "../mwworld/inventorystore.hpp"
|
||||||
|
@ -197,33 +200,28 @@ bool MWDialogue::Filter::testSelectStructNumeric (const SelectWrapper& select) c
|
||||||
if (scriptName.empty())
|
if (scriptName.empty())
|
||||||
return false; // no script
|
return false; // no script
|
||||||
|
|
||||||
const ESM::Script *script =
|
std::string name = Misc::StringUtils::lowerCase (select.getName());
|
||||||
MWBase::Environment::get().getWorld()->getStore().get<ESM::Script>().find (scriptName);
|
|
||||||
|
|
||||||
std::string name = select.getName();
|
const Compiler::Locals& localDefs =
|
||||||
|
MWBase::Environment::get().getScriptManager()->getLocals (scriptName);
|
||||||
|
|
||||||
int i = 0;
|
char type = localDefs.getType (name);
|
||||||
|
|
||||||
for (; i<static_cast<int> (script->mVarNames.size()); ++i)
|
if (type==' ')
|
||||||
if (Misc::StringUtils::ciEqual(script->mVarNames[i], name))
|
return false; // script does not have a variable of this name.
|
||||||
break;
|
|
||||||
|
|
||||||
if (i>=static_cast<int> (script->mVarNames.size()))
|
int index = localDefs.getIndex (name);
|
||||||
return false; // script does not have a variable of this name
|
|
||||||
|
|
||||||
const MWScript::Locals& locals = mActor.getRefData().getLocals();
|
const MWScript::Locals& locals = mActor.getRefData().getLocals();
|
||||||
|
|
||||||
if (i<script->mData.mNumShorts)
|
switch (type)
|
||||||
return select.selectCompare (static_cast<int> (locals.mShorts[i]));
|
{
|
||||||
|
case 's': return select.selectCompare (static_cast<int> (locals.mShorts[index]));
|
||||||
|
case 'l': return select.selectCompare (locals.mLongs[index]);
|
||||||
|
case 'f': return select.selectCompare (locals.mFloats[index]);
|
||||||
|
}
|
||||||
|
|
||||||
i -= script->mData.mNumShorts;
|
throw std::logic_error ("unknown local variable type in dialogue filter");
|
||||||
|
|
||||||
if (i<script->mData.mNumLongs)
|
|
||||||
return select.selectCompare (locals.mLongs[i]);
|
|
||||||
|
|
||||||
i -= script->mData.mNumLongs;
|
|
||||||
|
|
||||||
return select.selectCompare (locals.mFloats.at (i));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case SelectWrapper::Function_PcHealthPercent:
|
case SelectWrapper::Function_PcHealthPercent:
|
||||||
|
@ -463,20 +461,10 @@ bool MWDialogue::Filter::getSelectStructBoolean (const SelectWrapper& select) co
|
||||||
// This actor has no attached script, so there is no local variable
|
// This actor has no attached script, so there is no local variable
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
const ESM::Script *script =
|
const Compiler::Locals& localDefs =
|
||||||
MWBase::Environment::get().getWorld()->getStore().get<ESM::Script>().find (scriptName);
|
MWBase::Environment::get().getScriptManager()->getLocals (scriptName);
|
||||||
|
|
||||||
std::string name = select.getName();
|
return localDefs.getIndex (Misc::StringUtils::lowerCase (select.getName()))==-1;
|
||||||
|
|
||||||
int i = 0;
|
|
||||||
for (; i < static_cast<int> (script->mVarNames.size()); ++i)
|
|
||||||
if (Misc::StringUtils::ciEqual(script->mVarNames[i], name))
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (i >= static_cast<int> (script->mVarNames.size()))
|
|
||||||
return true; // script does not have a variable of this name
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case SelectWrapper::Function_SameGender:
|
case SelectWrapper::Function_SameGender:
|
||||||
|
|
|
@ -15,61 +15,69 @@
|
||||||
|
|
||||||
namespace MWScript
|
namespace MWScript
|
||||||
{
|
{
|
||||||
|
GlobalScriptDesc::GlobalScriptDesc() : mRunning (false) {}
|
||||||
|
|
||||||
|
|
||||||
GlobalScripts::GlobalScripts (const MWWorld::ESMStore& store)
|
GlobalScripts::GlobalScripts (const MWWorld::ESMStore& store)
|
||||||
: mStore (store)
|
: mStore (store)
|
||||||
{
|
{}
|
||||||
addStartup();
|
|
||||||
}
|
|
||||||
|
|
||||||
void GlobalScripts::addScript (const std::string& name)
|
void GlobalScripts::addScript (const std::string& name, const std::string& targetId)
|
||||||
{
|
{
|
||||||
std::map<std::string, std::pair<bool, Locals> >::iterator iter =
|
std::map<std::string, GlobalScriptDesc>::iterator iter =
|
||||||
mScripts.find (::Misc::StringUtils::lowerCase (name));
|
mScripts.find (::Misc::StringUtils::lowerCase (name));
|
||||||
|
|
||||||
if (iter==mScripts.end())
|
if (iter==mScripts.end())
|
||||||
{
|
{
|
||||||
if (const ESM::Script *script = mStore.get<ESM::Script>().find (name))
|
if (const ESM::Script *script = mStore.get<ESM::Script>().find (name))
|
||||||
{
|
{
|
||||||
Locals locals;
|
GlobalScriptDesc desc;
|
||||||
|
desc.mRunning = true;
|
||||||
|
desc.mLocals.configure (*script);
|
||||||
|
desc.mId = targetId;
|
||||||
|
|
||||||
locals.configure (*script);
|
mScripts.insert (std::make_pair (name, desc));
|
||||||
|
|
||||||
mScripts.insert (std::make_pair (name, std::make_pair (true, locals)));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else if (!iter->second.mRunning)
|
||||||
iter->second.first = true;
|
{
|
||||||
|
iter->second.mRunning = true;
|
||||||
|
iter->second.mId = targetId;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GlobalScripts::removeScript (const std::string& name)
|
void GlobalScripts::removeScript (const std::string& name)
|
||||||
{
|
{
|
||||||
std::map<std::string, std::pair<bool, Locals> >::iterator iter =
|
std::map<std::string, GlobalScriptDesc>::iterator iter =
|
||||||
mScripts.find (::Misc::StringUtils::lowerCase (name));
|
mScripts.find (::Misc::StringUtils::lowerCase (name));
|
||||||
|
|
||||||
if (iter!=mScripts.end())
|
if (iter!=mScripts.end())
|
||||||
iter->second.first = false;
|
iter->second.mRunning = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GlobalScripts::isRunning (const std::string& name) const
|
bool GlobalScripts::isRunning (const std::string& name) const
|
||||||
{
|
{
|
||||||
std::map<std::string, std::pair<bool, Locals> >::const_iterator iter =
|
std::map<std::string, GlobalScriptDesc>::const_iterator iter =
|
||||||
mScripts.find (::Misc::StringUtils::lowerCase (name));
|
mScripts.find (::Misc::StringUtils::lowerCase (name));
|
||||||
|
|
||||||
if (iter==mScripts.end())
|
if (iter==mScripts.end())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return iter->second.first;
|
return iter->second.mRunning;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GlobalScripts::run()
|
void GlobalScripts::run()
|
||||||
{
|
{
|
||||||
for (std::map<std::string, std::pair<bool, Locals> >::iterator iter (mScripts.begin());
|
for (std::map<std::string, GlobalScriptDesc>::iterator iter (mScripts.begin());
|
||||||
iter!=mScripts.end(); ++iter)
|
iter!=mScripts.end(); ++iter)
|
||||||
{
|
{
|
||||||
if (iter->second.first)
|
if (iter->second.mRunning)
|
||||||
{
|
{
|
||||||
|
MWWorld::Ptr ptr;
|
||||||
|
|
||||||
MWScript::InterpreterContext interpreterContext (
|
MWScript::InterpreterContext interpreterContext (
|
||||||
&iter->second.second, MWWorld::Ptr());
|
&iter->second.mLocals, MWWorld::Ptr(), iter->second.mId);
|
||||||
|
|
||||||
MWBase::Environment::get().getScriptManager()->run (iter->first, interpreterContext);
|
MWBase::Environment::get().getScriptManager()->run (iter->first, interpreterContext);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -99,16 +107,18 @@ namespace MWScript
|
||||||
|
|
||||||
void GlobalScripts::write (ESM::ESMWriter& writer, Loading::Listener& progress) const
|
void GlobalScripts::write (ESM::ESMWriter& writer, Loading::Listener& progress) const
|
||||||
{
|
{
|
||||||
for (std::map<std::string, std::pair<bool, Locals> >::const_iterator iter (mScripts.begin());
|
for (std::map<std::string, GlobalScriptDesc>::const_iterator iter (mScripts.begin());
|
||||||
iter!=mScripts.end(); ++iter)
|
iter!=mScripts.end(); ++iter)
|
||||||
{
|
{
|
||||||
ESM::GlobalScript script;
|
ESM::GlobalScript script;
|
||||||
|
|
||||||
script.mId = iter->first;
|
script.mId = iter->first;
|
||||||
|
|
||||||
iter->second.second.write (script.mLocals, iter->first);
|
iter->second.mLocals.write (script.mLocals, iter->first);
|
||||||
|
|
||||||
script.mRunning = iter->second.first ? 1 : 0;
|
script.mRunning = iter->second.mRunning ? 1 : 0;
|
||||||
|
|
||||||
|
script.mTargetId = iter->second.mId;
|
||||||
|
|
||||||
writer.startRecord (ESM::REC_GSCR);
|
writer.startRecord (ESM::REC_GSCR);
|
||||||
script.save (writer);
|
script.save (writer);
|
||||||
|
@ -124,25 +134,25 @@ namespace MWScript
|
||||||
ESM::GlobalScript script;
|
ESM::GlobalScript script;
|
||||||
script.load (reader);
|
script.load (reader);
|
||||||
|
|
||||||
std::map<std::string, std::pair<bool, Locals> >::iterator iter =
|
std::map<std::string, GlobalScriptDesc>::iterator iter =
|
||||||
mScripts.find (script.mId);
|
mScripts.find (script.mId);
|
||||||
|
|
||||||
if (iter==mScripts.end())
|
if (iter==mScripts.end())
|
||||||
{
|
{
|
||||||
if (const ESM::Script *scriptRecord = mStore.get<ESM::Script>().search (script.mId))
|
if (const ESM::Script *scriptRecord = mStore.get<ESM::Script>().search (script.mId))
|
||||||
{
|
{
|
||||||
std::pair<bool, Locals> data (false, Locals());
|
GlobalScriptDesc desc;
|
||||||
|
desc.mLocals.configure (*scriptRecord);
|
||||||
|
|
||||||
data.second.configure (*scriptRecord);
|
iter = mScripts.insert (std::make_pair (script.mId, desc)).first;
|
||||||
|
|
||||||
iter = mScripts.insert (std::make_pair (script.mId, data)).first;
|
|
||||||
}
|
}
|
||||||
else // script does not exist anymore
|
else // script does not exist anymore
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
iter->second.first = script.mRunning!=0;
|
iter->second.mRunning = script.mRunning!=0;
|
||||||
iter->second.second.read (script.mLocals, script.mId);
|
iter->second.mLocals.read (script.mLocals, script.mId);
|
||||||
|
iter->second.mId = script.mTargetId;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -153,21 +163,19 @@ namespace MWScript
|
||||||
Locals& GlobalScripts::getLocals (const std::string& name)
|
Locals& GlobalScripts::getLocals (const std::string& name)
|
||||||
{
|
{
|
||||||
std::string name2 = ::Misc::StringUtils::lowerCase (name);
|
std::string name2 = ::Misc::StringUtils::lowerCase (name);
|
||||||
std::map<std::string, std::pair<bool, Locals> >::iterator iter =
|
std::map<std::string, GlobalScriptDesc>::iterator iter = mScripts.find (name2);
|
||||||
mScripts.find (name2);
|
|
||||||
|
|
||||||
if (iter==mScripts.end())
|
if (iter==mScripts.end())
|
||||||
{
|
{
|
||||||
if (const ESM::Script *script = mStore.get<ESM::Script>().find (name))
|
if (const ESM::Script *script = mStore.get<ESM::Script>().find (name))
|
||||||
{
|
{
|
||||||
Locals locals;
|
GlobalScriptDesc desc;
|
||||||
|
desc.mLocals.configure (*script);
|
||||||
|
|
||||||
locals.configure (*script);
|
iter = mScripts.insert (std::make_pair (name, desc)).first;
|
||||||
|
|
||||||
iter = mScripts.insert (std::make_pair (name, std::make_pair (false, locals))).first;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return iter->second.second;
|
return iter->second.mLocals;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,16 +26,25 @@ namespace MWWorld
|
||||||
|
|
||||||
namespace MWScript
|
namespace MWScript
|
||||||
{
|
{
|
||||||
|
struct GlobalScriptDesc
|
||||||
|
{
|
||||||
|
bool mRunning;
|
||||||
|
Locals mLocals;
|
||||||
|
std::string mId; // ID used to start targeted script (empty if not a targeted script)
|
||||||
|
|
||||||
|
GlobalScriptDesc();
|
||||||
|
};
|
||||||
|
|
||||||
class GlobalScripts
|
class GlobalScripts
|
||||||
{
|
{
|
||||||
const MWWorld::ESMStore& mStore;
|
const MWWorld::ESMStore& mStore;
|
||||||
std::map<std::string, std::pair<bool, Locals> > mScripts; // running, local variables
|
std::map<std::string, GlobalScriptDesc> mScripts;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
GlobalScripts (const MWWorld::ESMStore& store);
|
GlobalScripts (const MWWorld::ESMStore& store);
|
||||||
|
|
||||||
void addScript (const std::string& name);
|
void addScript (const std::string& name, const std::string& targetId = "");
|
||||||
|
|
||||||
void removeScript (const std::string& name);
|
void removeScript (const std::string& name);
|
||||||
|
|
||||||
|
|
|
@ -3,8 +3,12 @@
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
#include <components/interpreter/types.hpp>
|
#include <components/interpreter/types.hpp>
|
||||||
|
|
||||||
|
#include <components/compiler/locals.hpp>
|
||||||
|
|
||||||
#include "../mwworld/esmstore.hpp"
|
#include "../mwworld/esmstore.hpp"
|
||||||
|
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
|
@ -22,7 +26,7 @@
|
||||||
|
|
||||||
namespace MWScript
|
namespace MWScript
|
||||||
{
|
{
|
||||||
MWWorld::Ptr InterpreterContext::getReference (
|
MWWorld::Ptr InterpreterContext::getReferenceImp (
|
||||||
const std::string& id, bool activeOnly, bool doThrow)
|
const std::string& id, bool activeOnly, bool doThrow)
|
||||||
{
|
{
|
||||||
if (!id.empty())
|
if (!id.empty())
|
||||||
|
@ -31,6 +35,10 @@ namespace MWScript
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (mReference.isEmpty() && !mTargetId.empty())
|
||||||
|
mReference =
|
||||||
|
MWBase::Environment::get().getWorld()->searchPtr (mTargetId, false);
|
||||||
|
|
||||||
if (mReference.isEmpty() && doThrow)
|
if (mReference.isEmpty() && doThrow)
|
||||||
throw std::runtime_error ("no implicit reference");
|
throw std::runtime_error ("no implicit reference");
|
||||||
|
|
||||||
|
@ -38,7 +46,7 @@ namespace MWScript
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const MWWorld::Ptr InterpreterContext::getReference (
|
const MWWorld::Ptr InterpreterContext::getReferenceImp (
|
||||||
const std::string& id, bool activeOnly, bool doThrow) const
|
const std::string& id, bool activeOnly, bool doThrow) const
|
||||||
{
|
{
|
||||||
if (!id.empty())
|
if (!id.empty())
|
||||||
|
@ -47,6 +55,10 @@ namespace MWScript
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (mReference.isEmpty() && !mTargetId.empty())
|
||||||
|
mReference =
|
||||||
|
MWBase::Environment::get().getWorld()->searchPtr (mTargetId, false);
|
||||||
|
|
||||||
if (mReference.isEmpty() && doThrow)
|
if (mReference.isEmpty() && doThrow)
|
||||||
throw std::runtime_error ("no implicit reference");
|
throw std::runtime_error ("no implicit reference");
|
||||||
|
|
||||||
|
@ -64,7 +76,7 @@ namespace MWScript
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const MWWorld::Ptr ptr = getReference (id, false);
|
const MWWorld::Ptr ptr = getReferenceImp (id, false);
|
||||||
|
|
||||||
id = ptr.getClass().getScript (ptr);
|
id = ptr.getClass().getScript (ptr);
|
||||||
|
|
||||||
|
@ -84,7 +96,7 @@ namespace MWScript
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const MWWorld::Ptr ptr = getReference (id, false);
|
const MWWorld::Ptr ptr = getReferenceImp (id, false);
|
||||||
|
|
||||||
id = ptr.getClass().getScript (ptr);
|
id = ptr.getClass().getScript (ptr);
|
||||||
|
|
||||||
|
@ -95,11 +107,43 @@ namespace MWScript
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int InterpreterContext::findLocalVariableIndex (const std::string& scriptId,
|
||||||
|
const std::string& name, char type) const
|
||||||
|
{
|
||||||
|
int index = MWBase::Environment::get().getScriptManager()->getLocals (scriptId).
|
||||||
|
search (type, name);
|
||||||
|
|
||||||
|
if (index!=-1)
|
||||||
|
return index;
|
||||||
|
|
||||||
|
std::ostringstream stream;
|
||||||
|
|
||||||
|
stream << "Failed to access ";
|
||||||
|
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case 's': stream << "short"; break;
|
||||||
|
case 'l': stream << "long"; break;
|
||||||
|
case 'f': stream << "float"; break;
|
||||||
|
}
|
||||||
|
|
||||||
|
stream << " member variable " << name << " in script " << scriptId;
|
||||||
|
|
||||||
|
throw std::runtime_error (stream.str().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
InterpreterContext::InterpreterContext (
|
InterpreterContext::InterpreterContext (
|
||||||
MWScript::Locals *locals, MWWorld::Ptr reference)
|
MWScript::Locals *locals, MWWorld::Ptr reference, const std::string& targetId)
|
||||||
: mLocals (locals), mReference (reference),
|
: mLocals (locals), mReference (reference),
|
||||||
mActivationHandled (false)
|
mActivationHandled (false), mTargetId (targetId)
|
||||||
{}
|
{
|
||||||
|
// If we run on a reference (local script, dialogue script or console with object
|
||||||
|
// selected), store the ID of that reference store it so it can be inherited by
|
||||||
|
// targeted scripts started from this one.
|
||||||
|
if (targetId.empty() && !reference.isEmpty())
|
||||||
|
mTargetId = reference.getClass().getId (reference);
|
||||||
|
}
|
||||||
|
|
||||||
int InterpreterContext::getLocalShort (int index) const
|
int InterpreterContext::getLocalShort (int index) const
|
||||||
{
|
{
|
||||||
|
@ -236,34 +280,34 @@ namespace MWScript
|
||||||
|
|
||||||
std::string InterpreterContext::getNPCName() const
|
std::string InterpreterContext::getNPCName() const
|
||||||
{
|
{
|
||||||
ESM::NPC npc = *mReference.get<ESM::NPC>()->mBase;
|
ESM::NPC npc = *getReferenceImp().get<ESM::NPC>()->mBase;
|
||||||
return npc.mName;
|
return npc.mName;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string InterpreterContext::getNPCRace() const
|
std::string InterpreterContext::getNPCRace() const
|
||||||
{
|
{
|
||||||
ESM::NPC npc = *mReference.get<ESM::NPC>()->mBase;
|
ESM::NPC npc = *getReferenceImp().get<ESM::NPC>()->mBase;
|
||||||
const ESM::Race* race = MWBase::Environment::get().getWorld()->getStore().get<ESM::Race>().find(npc.mRace);
|
const ESM::Race* race = MWBase::Environment::get().getWorld()->getStore().get<ESM::Race>().find(npc.mRace);
|
||||||
return race->mName;
|
return race->mName;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string InterpreterContext::getNPCClass() const
|
std::string InterpreterContext::getNPCClass() const
|
||||||
{
|
{
|
||||||
ESM::NPC npc = *mReference.get<ESM::NPC>()->mBase;
|
ESM::NPC npc = *getReferenceImp().get<ESM::NPC>()->mBase;
|
||||||
const ESM::Class* class_ = MWBase::Environment::get().getWorld()->getStore().get<ESM::Class>().find(npc.mClass);
|
const ESM::Class* class_ = MWBase::Environment::get().getWorld()->getStore().get<ESM::Class>().find(npc.mClass);
|
||||||
return class_->mName;
|
return class_->mName;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string InterpreterContext::getNPCFaction() const
|
std::string InterpreterContext::getNPCFaction() const
|
||||||
{
|
{
|
||||||
ESM::NPC npc = *mReference.get<ESM::NPC>()->mBase;
|
ESM::NPC npc = *getReferenceImp().get<ESM::NPC>()->mBase;
|
||||||
const ESM::Faction* faction = MWBase::Environment::get().getWorld()->getStore().get<ESM::Faction>().find(npc.mFaction);
|
const ESM::Faction* faction = MWBase::Environment::get().getWorld()->getStore().get<ESM::Faction>().find(npc.mFaction);
|
||||||
return faction->mName;
|
return faction->mName;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string InterpreterContext::getNPCRank() const
|
std::string InterpreterContext::getNPCRank() const
|
||||||
{
|
{
|
||||||
std::map<std::string, int> ranks = mReference.getClass().getNpcStats (mReference).getFactionRanks();
|
std::map<std::string, int> ranks = getReferenceImp().getClass().getNpcStats (getReferenceImp()).getFactionRanks();
|
||||||
std::map<std::string, int>::const_iterator it = ranks.begin();
|
std::map<std::string, int>::const_iterator it = ranks.begin();
|
||||||
|
|
||||||
MWBase::World *world = MWBase::Environment::get().getWorld();
|
MWBase::World *world = MWBase::Environment::get().getWorld();
|
||||||
|
@ -299,7 +343,7 @@ namespace MWScript
|
||||||
MWBase::World *world = MWBase::Environment::get().getWorld();
|
MWBase::World *world = MWBase::Environment::get().getWorld();
|
||||||
MWWorld::Ptr player = world->getPlayerPtr();
|
MWWorld::Ptr player = world->getPlayerPtr();
|
||||||
|
|
||||||
std::string factionId = mReference.getClass().getNpcStats (mReference).getFactionRanks().begin()->first;
|
std::string factionId = getReferenceImp().getClass().getNpcStats (getReferenceImp()).getFactionRanks().begin()->first;
|
||||||
|
|
||||||
std::map<std::string, int> ranks = player.getClass().getNpcStats (player).getFactionRanks();
|
std::map<std::string, int> ranks = player.getClass().getNpcStats (player).getFactionRanks();
|
||||||
std::map<std::string, int>::const_iterator it = ranks.find(factionId);
|
std::map<std::string, int>::const_iterator it = ranks.find(factionId);
|
||||||
|
@ -326,7 +370,7 @@ namespace MWScript
|
||||||
MWBase::World *world = MWBase::Environment::get().getWorld();
|
MWBase::World *world = MWBase::Environment::get().getWorld();
|
||||||
MWWorld::Ptr player = world->getPlayerPtr();
|
MWWorld::Ptr player = world->getPlayerPtr();
|
||||||
|
|
||||||
std::string factionId = mReference.getClass().getNpcStats (mReference).getFactionRanks().begin()->first;
|
std::string factionId = getReferenceImp().getClass().getNpcStats (getReferenceImp()).getFactionRanks().begin()->first;
|
||||||
|
|
||||||
std::map<std::string, int> ranks = player.getClass().getNpcStats (player).getFactionRanks();
|
std::map<std::string, int> ranks = player.getClass().getNpcStats (player).getFactionRanks();
|
||||||
std::map<std::string, int>::const_iterator it = ranks.find(factionId);
|
std::map<std::string, int>::const_iterator it = ranks.find(factionId);
|
||||||
|
@ -366,9 +410,9 @@ namespace MWScript
|
||||||
return MWBase::Environment::get().getScriptManager()->getGlobalScripts().isRunning (name);
|
return MWBase::Environment::get().getScriptManager()->getGlobalScripts().isRunning (name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InterpreterContext::startScript (const std::string& name)
|
void InterpreterContext::startScript (const std::string& name, const std::string& targetId)
|
||||||
{
|
{
|
||||||
MWBase::Environment::get().getScriptManager()->getGlobalScripts().addScript (name);
|
MWBase::Environment::get().getScriptManager()->getGlobalScripts().addScript (name, targetId);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InterpreterContext::stopScript (const std::string& name)
|
void InterpreterContext::stopScript (const std::string& name)
|
||||||
|
@ -383,7 +427,7 @@ namespace MWScript
|
||||||
MWWorld::Ptr ref2;
|
MWWorld::Ptr ref2;
|
||||||
|
|
||||||
if (id.empty())
|
if (id.empty())
|
||||||
ref2 = getReference("", true, true);
|
ref2 = getReferenceImp();
|
||||||
else
|
else
|
||||||
ref2 = MWBase::Environment::get().getWorld()->searchPtr(id, true);
|
ref2 = MWBase::Environment::get().getWorld()->searchPtr(id, true);
|
||||||
|
|
||||||
|
@ -448,19 +492,19 @@ namespace MWScript
|
||||||
|
|
||||||
bool InterpreterContext::isDisabled (const std::string& id) const
|
bool InterpreterContext::isDisabled (const std::string& id) const
|
||||||
{
|
{
|
||||||
const MWWorld::Ptr ref = getReference (id, false);
|
const MWWorld::Ptr ref = getReferenceImp (id, false);
|
||||||
return !ref.getRefData().isEnabled();
|
return !ref.getRefData().isEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
void InterpreterContext::enable (const std::string& id)
|
void InterpreterContext::enable (const std::string& id)
|
||||||
{
|
{
|
||||||
MWWorld::Ptr ref = getReference (id, false);
|
MWWorld::Ptr ref = getReferenceImp (id, false);
|
||||||
MWBase::Environment::get().getWorld()->enable (ref);
|
MWBase::Environment::get().getWorld()->enable (ref);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InterpreterContext::disable (const std::string& id)
|
void InterpreterContext::disable (const std::string& id)
|
||||||
{
|
{
|
||||||
MWWorld::Ptr ref = getReference (id, false);
|
MWWorld::Ptr ref = getReferenceImp (id, false);
|
||||||
MWBase::Environment::get().getWorld()->disable (ref);
|
MWBase::Environment::get().getWorld()->disable (ref);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -471,10 +515,7 @@ namespace MWScript
|
||||||
|
|
||||||
const Locals& locals = getMemberLocals (scriptId, global);
|
const Locals& locals = getMemberLocals (scriptId, global);
|
||||||
|
|
||||||
int index = MWBase::Environment::get().getScriptManager()->getLocalIndex (
|
return locals.mShorts[findLocalVariableIndex (scriptId, name, 's')];
|
||||||
scriptId, name, 's');
|
|
||||||
|
|
||||||
return locals.mShorts[index];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int InterpreterContext::getMemberLong (const std::string& id, const std::string& name,
|
int InterpreterContext::getMemberLong (const std::string& id, const std::string& name,
|
||||||
|
@ -484,10 +525,7 @@ namespace MWScript
|
||||||
|
|
||||||
const Locals& locals = getMemberLocals (scriptId, global);
|
const Locals& locals = getMemberLocals (scriptId, global);
|
||||||
|
|
||||||
int index = MWBase::Environment::get().getScriptManager()->getLocalIndex (
|
return locals.mLongs[findLocalVariableIndex (scriptId, name, 'l')];
|
||||||
scriptId, name, 'l');
|
|
||||||
|
|
||||||
return locals.mLongs[index];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
float InterpreterContext::getMemberFloat (const std::string& id, const std::string& name,
|
float InterpreterContext::getMemberFloat (const std::string& id, const std::string& name,
|
||||||
|
@ -497,10 +535,7 @@ namespace MWScript
|
||||||
|
|
||||||
const Locals& locals = getMemberLocals (scriptId, global);
|
const Locals& locals = getMemberLocals (scriptId, global);
|
||||||
|
|
||||||
int index = MWBase::Environment::get().getScriptManager()->getLocalIndex (
|
return locals.mFloats[findLocalVariableIndex (scriptId, name, 'f')];
|
||||||
scriptId, name, 'f');
|
|
||||||
|
|
||||||
return locals.mFloats[index];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void InterpreterContext::setMemberShort (const std::string& id, const std::string& name,
|
void InterpreterContext::setMemberShort (const std::string& id, const std::string& name,
|
||||||
|
@ -510,10 +545,7 @@ namespace MWScript
|
||||||
|
|
||||||
Locals& locals = getMemberLocals (scriptId, global);
|
Locals& locals = getMemberLocals (scriptId, global);
|
||||||
|
|
||||||
int index =
|
locals.mShorts[findLocalVariableIndex (scriptId, name, 's')] = value;
|
||||||
MWBase::Environment::get().getScriptManager()->getLocalIndex (scriptId, name, 's');
|
|
||||||
|
|
||||||
locals.mShorts[index] = value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void InterpreterContext::setMemberLong (const std::string& id, const std::string& name, int value, bool global)
|
void InterpreterContext::setMemberLong (const std::string& id, const std::string& name, int value, bool global)
|
||||||
|
@ -522,10 +554,7 @@ namespace MWScript
|
||||||
|
|
||||||
Locals& locals = getMemberLocals (scriptId, global);
|
Locals& locals = getMemberLocals (scriptId, global);
|
||||||
|
|
||||||
int index =
|
locals.mLongs[findLocalVariableIndex (scriptId, name, 'l')] = value;
|
||||||
MWBase::Environment::get().getScriptManager()->getLocalIndex (scriptId, name, 'l');
|
|
||||||
|
|
||||||
locals.mLongs[index] = value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void InterpreterContext::setMemberFloat (const std::string& id, const std::string& name, float value, bool global)
|
void InterpreterContext::setMemberFloat (const std::string& id, const std::string& name, float value, bool global)
|
||||||
|
@ -534,14 +563,16 @@ namespace MWScript
|
||||||
|
|
||||||
Locals& locals = getMemberLocals (scriptId, global);
|
Locals& locals = getMemberLocals (scriptId, global);
|
||||||
|
|
||||||
int index =
|
locals.mFloats[findLocalVariableIndex (scriptId, name, 'f')] = value;
|
||||||
MWBase::Environment::get().getScriptManager()->getLocalIndex (scriptId, name, 'f');
|
|
||||||
|
|
||||||
locals.mFloats[index] = value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MWWorld::Ptr InterpreterContext::getReference(bool required)
|
MWWorld::Ptr InterpreterContext::getReference(bool required)
|
||||||
{
|
{
|
||||||
return getReference ("", true, required);
|
return getReferenceImp ("", true, required);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string InterpreterContext::getTargetId() const
|
||||||
|
{
|
||||||
|
return mTargetId;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,14 +27,22 @@ namespace MWScript
|
||||||
class InterpreterContext : public Interpreter::Context
|
class InterpreterContext : public Interpreter::Context
|
||||||
{
|
{
|
||||||
Locals *mLocals;
|
Locals *mLocals;
|
||||||
MWWorld::Ptr mReference;
|
mutable MWWorld::Ptr mReference;
|
||||||
|
|
||||||
MWWorld::Ptr mActivated;
|
MWWorld::Ptr mActivated;
|
||||||
bool mActivationHandled;
|
bool mActivationHandled;
|
||||||
|
|
||||||
MWWorld::Ptr getReference (const std::string& id, bool activeOnly, bool doThrow=true);
|
std::string mTargetId;
|
||||||
|
|
||||||
const MWWorld::Ptr getReference (const std::string& id, bool activeOnly, bool doThrow=true) const;
|
/// If \a id is empty, a reference the script is run from is returned or in case
|
||||||
|
/// of a non-local script the reference derived from the target ID.
|
||||||
|
MWWorld::Ptr getReferenceImp (const std::string& id = "", bool activeOnly = false,
|
||||||
|
bool doThrow=true);
|
||||||
|
|
||||||
|
/// If \a id is empty, a reference the script is run from is returned or in case
|
||||||
|
/// of a non-local script the reference derived from the target ID.
|
||||||
|
const MWWorld::Ptr getReferenceImp (const std::string& id = "",
|
||||||
|
bool activeOnly = false, bool doThrow=true) const;
|
||||||
|
|
||||||
const Locals& getMemberLocals (std::string& id, bool global) const;
|
const Locals& getMemberLocals (std::string& id, bool global) const;
|
||||||
///< \a id is changed to the respective script ID, if \a id wasn't a script ID before
|
///< \a id is changed to the respective script ID, if \a id wasn't a script ID before
|
||||||
|
@ -42,9 +50,14 @@ namespace MWScript
|
||||||
Locals& getMemberLocals (std::string& id, bool global);
|
Locals& getMemberLocals (std::string& id, bool global);
|
||||||
///< \a id is changed to the respective script ID, if \a id wasn't a script ID before
|
///< \a id is changed to the respective script ID, if \a id wasn't a script ID before
|
||||||
|
|
||||||
|
/// Throws an exception if local variable can't be found.
|
||||||
|
int findLocalVariableIndex (const std::string& scriptId, const std::string& name,
|
||||||
|
char type) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
InterpreterContext (MWScript::Locals *locals, MWWorld::Ptr reference);
|
InterpreterContext (MWScript::Locals *locals, MWWorld::Ptr reference,
|
||||||
|
const std::string& targetId = "");
|
||||||
///< The ownership of \a locals is not transferred. 0-pointer allowed.
|
///< The ownership of \a locals is not transferred. 0-pointer allowed.
|
||||||
|
|
||||||
virtual int getLocalShort (int index) const;
|
virtual int getLocalShort (int index) const;
|
||||||
|
@ -113,7 +126,7 @@ namespace MWScript
|
||||||
|
|
||||||
virtual bool isScriptRunning (const std::string& name) const;
|
virtual bool isScriptRunning (const std::string& name) const;
|
||||||
|
|
||||||
virtual void startScript (const std::string& name);
|
virtual void startScript (const std::string& name, const std::string& targetId = "");
|
||||||
|
|
||||||
virtual void stopScript (const std::string& name);
|
virtual void stopScript (const std::string& name);
|
||||||
|
|
||||||
|
@ -158,6 +171,8 @@ namespace MWScript
|
||||||
|
|
||||||
MWWorld::Ptr getReference(bool required=true);
|
MWWorld::Ptr getReference(bool required=true);
|
||||||
///< Reference, that the script is running from (can be empty)
|
///< Reference, that the script is running from (can be empty)
|
||||||
|
|
||||||
|
virtual std::string getTargetId() const;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,12 +14,15 @@ namespace MWScript
|
||||||
{
|
{
|
||||||
void Locals::configure (const ESM::Script& script)
|
void Locals::configure (const ESM::Script& script)
|
||||||
{
|
{
|
||||||
|
const Compiler::Locals& locals =
|
||||||
|
MWBase::Environment::get().getScriptManager()->getLocals (script.mId);
|
||||||
|
|
||||||
mShorts.clear();
|
mShorts.clear();
|
||||||
mShorts.resize (script.mData.mNumShorts, 0);
|
mShorts.resize (locals.get ('s').size(), 0);
|
||||||
mLongs.clear();
|
mLongs.clear();
|
||||||
mLongs.resize (script.mData.mNumLongs, 0);
|
mLongs.resize (locals.get ('l').size(), 0);
|
||||||
mFloats.clear();
|
mFloats.clear();
|
||||||
mFloats.resize (script.mData.mNumFloats, 0);
|
mFloats.resize (locals.get ('f').size(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Locals::isEmpty() const
|
bool Locals::isEmpty() const
|
||||||
|
@ -29,7 +32,7 @@ namespace MWScript
|
||||||
|
|
||||||
int Locals::getIntVar(const std::string &script, const std::string &var)
|
int Locals::getIntVar(const std::string &script, const std::string &var)
|
||||||
{
|
{
|
||||||
Compiler::Locals locals = MWBase::Environment::get().getScriptManager()->getLocals(script);
|
const Compiler::Locals& locals = MWBase::Environment::get().getScriptManager()->getLocals(script);
|
||||||
int index = locals.getIndex(var);
|
int index = locals.getIndex(var);
|
||||||
char type = locals.getType(var);
|
char type = locals.getType(var);
|
||||||
if(index != -1)
|
if(index != -1)
|
||||||
|
@ -53,7 +56,7 @@ namespace MWScript
|
||||||
|
|
||||||
bool Locals::setVarByInt(const std::string& script, const std::string& var, int val)
|
bool Locals::setVarByInt(const std::string& script, const std::string& var, int val)
|
||||||
{
|
{
|
||||||
Compiler::Locals locals = MWBase::Environment::get().getScriptManager()->getLocals(script);
|
const Compiler::Locals& locals = MWBase::Environment::get().getScriptManager()->getLocals(script);
|
||||||
int index = locals.getIndex(var);
|
int index = locals.getIndex(var);
|
||||||
char type = locals.getType(var);
|
char type = locals.getType(var);
|
||||||
if(index != -1)
|
if(index != -1)
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <exception>
|
#include <exception>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
#include <components/esm/loadscpt.hpp>
|
#include <components/esm/loadscpt.hpp>
|
||||||
|
|
||||||
|
@ -22,12 +23,19 @@
|
||||||
namespace MWScript
|
namespace MWScript
|
||||||
{
|
{
|
||||||
ScriptManager::ScriptManager (const MWWorld::ESMStore& store, bool verbose,
|
ScriptManager::ScriptManager (const MWWorld::ESMStore& store, bool verbose,
|
||||||
Compiler::Context& compilerContext, int warningsMode)
|
Compiler::Context& compilerContext, int warningsMode,
|
||||||
|
const std::vector<std::string>& scriptBlacklist)
|
||||||
: mErrorHandler (std::cerr), mStore (store), mVerbose (verbose),
|
: mErrorHandler (std::cerr), mStore (store), mVerbose (verbose),
|
||||||
mCompilerContext (compilerContext), mParser (mErrorHandler, mCompilerContext),
|
mCompilerContext (compilerContext), mParser (mErrorHandler, mCompilerContext),
|
||||||
mOpcodesInstalled (false), mGlobalScripts (store)
|
mOpcodesInstalled (false), mGlobalScripts (store)
|
||||||
{
|
{
|
||||||
mErrorHandler.setWarningsMode (warningsMode);
|
mErrorHandler.setWarningsMode (warningsMode);
|
||||||
|
|
||||||
|
mScriptBlacklist.resize (scriptBlacklist.size());
|
||||||
|
|
||||||
|
std::transform (scriptBlacklist.begin(), scriptBlacklist.end(),
|
||||||
|
mScriptBlacklist.begin(), Misc::StringUtils::lowerCase);
|
||||||
|
std::sort (mScriptBlacklist.begin(), mScriptBlacklist.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ScriptManager::compile (const std::string& name)
|
bool ScriptManager::compile (const std::string& name)
|
||||||
|
@ -133,16 +141,22 @@ namespace MWScript
|
||||||
int success = 0;
|
int success = 0;
|
||||||
|
|
||||||
const MWWorld::Store<ESM::Script>& scripts = mStore.get<ESM::Script>();
|
const MWWorld::Store<ESM::Script>& scripts = mStore.get<ESM::Script>();
|
||||||
MWWorld::Store<ESM::Script>::iterator it = scripts.begin();
|
|
||||||
|
|
||||||
for (; it != scripts.end(); ++it, ++count)
|
for (MWWorld::Store<ESM::Script>::iterator iter = scripts.begin();
|
||||||
if (compile (it->mId))
|
iter != scripts.end(); ++iter)
|
||||||
|
if (!std::binary_search (mScriptBlacklist.begin(), mScriptBlacklist.end(),
|
||||||
|
Misc::StringUtils::lowerCase (iter->mId)))
|
||||||
|
{
|
||||||
|
++count;
|
||||||
|
|
||||||
|
if (compile (iter->mId))
|
||||||
++success;
|
++success;
|
||||||
|
}
|
||||||
|
|
||||||
return std::make_pair (count, success);
|
return std::make_pair (count, success);
|
||||||
}
|
}
|
||||||
|
|
||||||
Compiler::Locals& ScriptManager::getLocals (const std::string& name)
|
const Compiler::Locals& ScriptManager::getLocals (const std::string& name)
|
||||||
{
|
{
|
||||||
std::string name2 = Misc::StringUtils::lowerCase (name);
|
std::string name2 = Misc::StringUtils::lowerCase (name);
|
||||||
|
|
||||||
|
@ -182,46 +196,4 @@ namespace MWScript
|
||||||
{
|
{
|
||||||
return mGlobalScripts;
|
return mGlobalScripts;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ScriptManager::getLocalIndex (const std::string& scriptId, const std::string& variable,
|
|
||||||
char type)
|
|
||||||
{
|
|
||||||
const ESM::Script *script = mStore.get<ESM::Script>().find (scriptId);
|
|
||||||
|
|
||||||
int offset = 0;
|
|
||||||
int size = 0;
|
|
||||||
|
|
||||||
switch (type)
|
|
||||||
{
|
|
||||||
case 's':
|
|
||||||
|
|
||||||
offset = 0;
|
|
||||||
size = script->mData.mNumShorts;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'l':
|
|
||||||
|
|
||||||
offset = script->mData.mNumShorts;
|
|
||||||
size = script->mData.mNumLongs;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'f':
|
|
||||||
|
|
||||||
offset = script->mData.mNumShorts+script->mData.mNumLongs;
|
|
||||||
size = script->mData.mNumFloats;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
|
|
||||||
throw std::runtime_error ("invalid variable type");
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string variable2 = Misc::StringUtils::lowerCase (variable);
|
|
||||||
|
|
||||||
for (int i=0; i<size; ++i)
|
|
||||||
if (Misc::StringUtils::lowerCase (script->mVarNames.at (i+offset))==variable2)
|
|
||||||
return i;
|
|
||||||
|
|
||||||
throw std::runtime_error ("unable to access local variable " + variable + " of " + scriptId);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,11 +48,13 @@ namespace MWScript
|
||||||
ScriptCollection mScripts;
|
ScriptCollection mScripts;
|
||||||
GlobalScripts mGlobalScripts;
|
GlobalScripts mGlobalScripts;
|
||||||
std::map<std::string, Compiler::Locals> mOtherLocals;
|
std::map<std::string, Compiler::Locals> mOtherLocals;
|
||||||
|
std::vector<std::string> mScriptBlacklist;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
ScriptManager (const MWWorld::ESMStore& store, bool verbose,
|
ScriptManager (const MWWorld::ESMStore& store, bool verbose,
|
||||||
Compiler::Context& compilerContext, int warningsMode);
|
Compiler::Context& compilerContext, int warningsMode,
|
||||||
|
const std::vector<std::string>& scriptBlacklist);
|
||||||
|
|
||||||
virtual void run (const std::string& name, Interpreter::Context& interpreterContext);
|
virtual void run (const std::string& name, Interpreter::Context& interpreterContext);
|
||||||
///< Run the script with the given name (compile first, if not compiled yet)
|
///< Run the script with the given name (compile first, if not compiled yet)
|
||||||
|
@ -65,15 +67,10 @@ namespace MWScript
|
||||||
///< Compile all scripts
|
///< Compile all scripts
|
||||||
/// \return count, success
|
/// \return count, success
|
||||||
|
|
||||||
virtual Compiler::Locals& getLocals (const std::string& name);
|
virtual const Compiler::Locals& getLocals (const std::string& name);
|
||||||
///< Return locals for script \a name.
|
///< Return locals for script \a name.
|
||||||
|
|
||||||
virtual GlobalScripts& getGlobalScripts();
|
virtual GlobalScripts& getGlobalScripts();
|
||||||
|
|
||||||
virtual int getLocalIndex (const std::string& scriptId, const std::string& variable,
|
|
||||||
char type);
|
|
||||||
///< Return index of the variable of the given name and type in the given script. Will
|
|
||||||
/// throw an exception, if there is no such script or variable or the type does not match.
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -132,12 +132,12 @@ void MWState::StateManager::newGame (bool bypass)
|
||||||
{
|
{
|
||||||
cleanup();
|
cleanup();
|
||||||
|
|
||||||
MWBase::Environment::get().getWorld()->startNewGame (bypass);
|
|
||||||
|
|
||||||
if (!bypass)
|
if (!bypass)
|
||||||
MWBase::Environment::get().getWindowManager()->setNewGame (true);
|
MWBase::Environment::get().getWindowManager()->setNewGame (true);
|
||||||
else
|
|
||||||
MWBase::Environment::get().getWorld()->setGlobalInt ("chargenstate", -1);
|
MWBase::Environment::get().getScriptManager()->getGlobalScripts().addStartup();
|
||||||
|
|
||||||
|
MWBase::Environment::get().getWorld()->startNewGame (bypass);
|
||||||
|
|
||||||
mState = State_Running;
|
mState = State_Running;
|
||||||
}
|
}
|
||||||
|
@ -401,6 +401,8 @@ void MWState::StateManager::loadGame (const Character *character, const Slot *sl
|
||||||
// Use detectWorldSpaceChange=false, otherwise some of the data we just loaded would be cleared again
|
// Use detectWorldSpaceChange=false, otherwise some of the data we just loaded would be cleared again
|
||||||
MWBase::Environment::get().getWorld()->changeToCell (cellId, ptr.getRefData().getPosition(), false);
|
MWBase::Environment::get().getWorld()->changeToCell (cellId, ptr.getRefData().getPosition(), false);
|
||||||
|
|
||||||
|
MWBase::Environment::get().getScriptManager()->getGlobalScripts().addStartup();
|
||||||
|
|
||||||
// Do not trigger erroneous cellChanged events
|
// Do not trigger erroneous cellChanged events
|
||||||
MWBase::Environment::get().getWorld()->markCellAsUnchanged();
|
MWBase::Environment::get().getWorld()->markCellAsUnchanged();
|
||||||
}
|
}
|
||||||
|
|
|
@ -211,9 +211,9 @@ namespace MWWorld
|
||||||
// set new game mark
|
// set new game mark
|
||||||
mGlobalVariables["chargenstate"].setInteger (1);
|
mGlobalVariables["chargenstate"].setInteger (1);
|
||||||
mGlobalVariables["pcrace"].setInteger (3);
|
mGlobalVariables["pcrace"].setInteger (3);
|
||||||
|
|
||||||
MWBase::Environment::get().getScriptManager()->getGlobalScripts().addStartup();
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
mGlobalVariables["chargenstate"].setInteger (-1);
|
||||||
|
|
||||||
if (bypass && !mStartCell.empty())
|
if (bypass && !mStartCell.empty())
|
||||||
{
|
{
|
||||||
|
|
|
@ -58,7 +58,7 @@ add_component_dir (compiler
|
||||||
context controlparser errorhandler exception exprparser extensions fileparser generator
|
context controlparser errorhandler exception exprparser extensions fileparser generator
|
||||||
lineparser literals locals output parser scanner scriptparser skipparser streamerrorhandler
|
lineparser literals locals output parser scanner scriptparser skipparser streamerrorhandler
|
||||||
stringparser tokenloc nullerrorhandler opcodes extensions0 declarationparser
|
stringparser tokenloc nullerrorhandler opcodes extensions0 declarationparser
|
||||||
quickfileparser
|
quickfileparser discardparser
|
||||||
)
|
)
|
||||||
|
|
||||||
add_component_dir (interpreter
|
add_component_dir (interpreter
|
||||||
|
|
70
components/compiler/discardparser.cpp
Normal file
70
components/compiler/discardparser.cpp
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
|
||||||
|
#include "discardparser.hpp"
|
||||||
|
|
||||||
|
#include "scanner.hpp"
|
||||||
|
|
||||||
|
namespace Compiler
|
||||||
|
{
|
||||||
|
DiscardParser::DiscardParser (ErrorHandler& errorHandler, const Context& context)
|
||||||
|
: Parser (errorHandler, context), mState (StartState)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DiscardParser::parseInt (int value, const TokenLoc& loc, Scanner& scanner)
|
||||||
|
{
|
||||||
|
if (mState==StartState || mState==CommaState || mState==MinusState)
|
||||||
|
{
|
||||||
|
start();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Parser::parseInt (value, loc, scanner);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DiscardParser::parseFloat (float value, const TokenLoc& loc, Scanner& scanner)
|
||||||
|
{
|
||||||
|
if (mState==StartState || mState==CommaState || mState==MinusState)
|
||||||
|
{
|
||||||
|
start();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Parser::parseFloat (value, loc, scanner);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DiscardParser::parseName (const std::string& name, const TokenLoc& loc,
|
||||||
|
Scanner& scanner)
|
||||||
|
{
|
||||||
|
if (mState==StartState || mState==CommaState)
|
||||||
|
{
|
||||||
|
start();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Parser::parseName (name, loc, scanner);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DiscardParser::parseSpecial (int code, const TokenLoc& loc, Scanner& scanner)
|
||||||
|
{
|
||||||
|
if (code==Scanner::S_comma && mState==StartState)
|
||||||
|
{
|
||||||
|
mState = CommaState;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (code==Scanner::S_minus && (mState==StartState || mState==CommaState))
|
||||||
|
{
|
||||||
|
mState = MinusState;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Parser::parseSpecial (code, loc, scanner);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DiscardParser::reset()
|
||||||
|
{
|
||||||
|
mState = StartState;
|
||||||
|
Parser::reset();
|
||||||
|
}
|
||||||
|
}
|
45
components/compiler/discardparser.hpp
Normal file
45
components/compiler/discardparser.hpp
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
#ifndef COMPILER_DISCARDPARSER_H_INCLUDED
|
||||||
|
#define COMPILER_DISCARDPARSER_H_INCLUDED
|
||||||
|
|
||||||
|
#include "parser.hpp"
|
||||||
|
|
||||||
|
namespace Compiler
|
||||||
|
{
|
||||||
|
/// \brief Parse a single optional numeric value or string and discard it
|
||||||
|
class DiscardParser : public Parser
|
||||||
|
{
|
||||||
|
enum State
|
||||||
|
{
|
||||||
|
StartState, CommaState, MinusState
|
||||||
|
};
|
||||||
|
|
||||||
|
State mState;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
DiscardParser (ErrorHandler& errorHandler, const Context& context);
|
||||||
|
|
||||||
|
virtual bool parseInt (int value, const TokenLoc& loc, Scanner& scanner);
|
||||||
|
///< Handle an int token.
|
||||||
|
/// \return fetch another token?
|
||||||
|
|
||||||
|
virtual bool parseFloat (float value, const TokenLoc& loc, Scanner& scanner);
|
||||||
|
///< Handle a float token.
|
||||||
|
/// \return fetch another token?
|
||||||
|
|
||||||
|
virtual bool parseName (const std::string& name, const TokenLoc& loc,
|
||||||
|
Scanner& scanner);
|
||||||
|
///< Handle a name token.
|
||||||
|
/// \return fetch another token?
|
||||||
|
|
||||||
|
virtual bool parseSpecial (int code, const TokenLoc& loc, Scanner& scanner);
|
||||||
|
///< Handle a special character token.
|
||||||
|
/// \return fetch another token?
|
||||||
|
|
||||||
|
virtual void reset();
|
||||||
|
///< Reset parser to clean state.
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -3,11 +3,8 @@
|
||||||
|
|
||||||
namespace Compiler
|
namespace Compiler
|
||||||
{
|
{
|
||||||
// constructor
|
ErrorHandler::ErrorHandler()
|
||||||
|
: mWarnings (0), mErrors (0), mWarningsMode (1), mDowngradeErrors (false) {}
|
||||||
ErrorHandler::ErrorHandler() : mWarnings (0), mErrors (0), mWarningsMode (1) {}
|
|
||||||
|
|
||||||
// destructor
|
|
||||||
|
|
||||||
ErrorHandler::~ErrorHandler() {}
|
ErrorHandler::~ErrorHandler() {}
|
||||||
|
|
||||||
|
@ -49,6 +46,12 @@ namespace Compiler
|
||||||
|
|
||||||
void ErrorHandler::error (const std::string& message, const TokenLoc& loc)
|
void ErrorHandler::error (const std::string& message, const TokenLoc& loc)
|
||||||
{
|
{
|
||||||
|
if (mDowngradeErrors)
|
||||||
|
{
|
||||||
|
warning (message, loc);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
++mErrors;
|
++mErrors;
|
||||||
report (message, loc, ErrorMessage);
|
report (message, loc, ErrorMessage);
|
||||||
}
|
}
|
||||||
|
@ -72,4 +75,21 @@ namespace Compiler
|
||||||
{
|
{
|
||||||
mWarningsMode = mode;
|
mWarningsMode = mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ErrorHandler::downgradeErrors (bool downgrade)
|
||||||
|
{
|
||||||
|
mDowngradeErrors = downgrade;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ErrorDowngrade::ErrorDowngrade (ErrorHandler& handler) : mHandler (handler)
|
||||||
|
{
|
||||||
|
mHandler.downgradeErrors (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
ErrorDowngrade::~ErrorDowngrade()
|
||||||
|
{
|
||||||
|
mHandler.downgradeErrors (false);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@ namespace Compiler
|
||||||
int mWarnings;
|
int mWarnings;
|
||||||
int mErrors;
|
int mErrors;
|
||||||
int mWarningsMode;
|
int mWarningsMode;
|
||||||
|
bool mDowngradeErrors;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
@ -66,6 +67,26 @@ namespace Compiler
|
||||||
|
|
||||||
void setWarningsMode (int mode);
|
void setWarningsMode (int mode);
|
||||||
///< // 0 ignore, 1 rate as warning, 2 rate as error
|
///< // 0 ignore, 1 rate as warning, 2 rate as error
|
||||||
|
|
||||||
|
/// Treat errors as warnings.
|
||||||
|
void downgradeErrors (bool downgrade);
|
||||||
|
};
|
||||||
|
|
||||||
|
class ErrorDowngrade
|
||||||
|
{
|
||||||
|
ErrorHandler& mHandler;
|
||||||
|
|
||||||
|
/// not implemented
|
||||||
|
ErrorDowngrade (const ErrorDowngrade&);
|
||||||
|
|
||||||
|
/// not implemented
|
||||||
|
ErrorDowngrade& operator= (const ErrorDowngrade&);
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
ErrorDowngrade (ErrorHandler& handler);
|
||||||
|
|
||||||
|
~ErrorDowngrade();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include "stringparser.hpp"
|
#include "stringparser.hpp"
|
||||||
#include "extensions.hpp"
|
#include "extensions.hpp"
|
||||||
#include "context.hpp"
|
#include "context.hpp"
|
||||||
|
#include "discardparser.hpp"
|
||||||
|
|
||||||
namespace Compiler
|
namespace Compiler
|
||||||
{
|
{
|
||||||
|
@ -386,6 +387,9 @@ namespace Compiler
|
||||||
mExplicit.clear();
|
mExplicit.clear();
|
||||||
mRefOp = false;
|
mRefOp = false;
|
||||||
|
|
||||||
|
std::vector<Interpreter::Type_Code> ignore;
|
||||||
|
parseArguments ("x", scanner, ignore);
|
||||||
|
|
||||||
mNextOperand = false;
|
mNextOperand = false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -404,6 +408,21 @@ namespace Compiler
|
||||||
mNextOperand = false;
|
mNextOperand = false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
else if (keyword==Scanner::K_scriptrunning)
|
||||||
|
{
|
||||||
|
start();
|
||||||
|
|
||||||
|
mTokenLoc = loc;
|
||||||
|
parseArguments ("c", scanner);
|
||||||
|
|
||||||
|
Generator::scriptRunning (mCode);
|
||||||
|
mOperands.push_back ('l');
|
||||||
|
|
||||||
|
mExplicit.clear();
|
||||||
|
mRefOp = false;
|
||||||
|
mNextOperand = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// check for custom extensions
|
// check for custom extensions
|
||||||
if (const Extensions *extensions = getContext().getExtensions())
|
if (const Extensions *extensions = getContext().getExtensions())
|
||||||
|
@ -527,6 +546,9 @@ namespace Compiler
|
||||||
Generator::getDisabled (mCode, mLiterals, "");
|
Generator::getDisabled (mCode, mLiterals, "");
|
||||||
mOperands.push_back ('l');
|
mOperands.push_back ('l');
|
||||||
|
|
||||||
|
std::vector<Interpreter::Type_Code> ignore;
|
||||||
|
parseArguments ("x", scanner, ignore);
|
||||||
|
|
||||||
mNextOperand = false;
|
mNextOperand = false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -737,6 +759,7 @@ namespace Compiler
|
||||||
|
|
||||||
ExprParser parser (getErrorHandler(), getContext(), mLocals, mLiterals, true);
|
ExprParser parser (getErrorHandler(), getContext(), mLocals, mLiterals, true);
|
||||||
StringParser stringParser (getErrorHandler(), getContext(), mLiterals);
|
StringParser stringParser (getErrorHandler(), getContext(), mLiterals);
|
||||||
|
DiscardParser discardParser (getErrorHandler(), getContext());
|
||||||
|
|
||||||
std::stack<std::vector<Interpreter::Type_Code> > stack;
|
std::stack<std::vector<Interpreter::Type_Code> > stack;
|
||||||
|
|
||||||
|
@ -771,11 +794,32 @@ namespace Compiler
|
||||||
++optionalCount;
|
++optionalCount;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (*iter=='X')
|
||||||
|
{
|
||||||
|
parser.reset();
|
||||||
|
|
||||||
|
parser.setOptional (true);
|
||||||
|
|
||||||
|
scanner.scan (parser);
|
||||||
|
|
||||||
|
if (parser.isEmpty())
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (*iter=='z')
|
||||||
|
{
|
||||||
|
discardParser.reset();
|
||||||
|
discardParser.setOptional (true);
|
||||||
|
|
||||||
|
scanner.scan (discardParser);
|
||||||
|
|
||||||
|
if (discardParser.isEmpty())
|
||||||
|
break;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
parser.reset();
|
parser.reset();
|
||||||
|
|
||||||
if (optional || *iter == 'X')
|
if (optional)
|
||||||
parser.setOptional (true);
|
parser.setOptional (true);
|
||||||
|
|
||||||
scanner.scan (parser);
|
scanner.scan (parser);
|
||||||
|
@ -783,8 +827,6 @@ namespace Compiler
|
||||||
if (optional && parser.isEmpty())
|
if (optional && parser.isEmpty())
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (*iter != 'X')
|
|
||||||
{
|
|
||||||
std::vector<Interpreter::Type_Code> tmp;
|
std::vector<Interpreter::Type_Code> tmp;
|
||||||
|
|
||||||
char type = parser.append (tmp);
|
char type = parser.append (tmp);
|
||||||
|
@ -798,7 +840,6 @@ namespace Compiler
|
||||||
++optionalCount;
|
++optionalCount;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
while (!stack.empty())
|
while (!stack.empty())
|
||||||
{
|
{
|
||||||
|
|
|
@ -21,7 +21,8 @@ namespace Compiler
|
||||||
s - Short <BR>
|
s - Short <BR>
|
||||||
S - String, case preserved <BR>
|
S - String, case preserved <BR>
|
||||||
x - Optional, ignored string argument
|
x - Optional, ignored string argument
|
||||||
X - Optional, ignored integer argument
|
X - Optional, ignored numeric expression
|
||||||
|
z - Optional, ignored string or numeric argument
|
||||||
**/
|
**/
|
||||||
typedef std::string ScriptArgs;
|
typedef std::string ScriptArgs;
|
||||||
|
|
||||||
|
|
|
@ -118,7 +118,7 @@ namespace Compiler
|
||||||
opcodeGetItemCountExplicit);
|
opcodeGetItemCountExplicit);
|
||||||
extensions.registerInstruction ("removeitem", "cl", opcodeRemoveItem,
|
extensions.registerInstruction ("removeitem", "cl", opcodeRemoveItem,
|
||||||
opcodeRemoveItemExplicit);
|
opcodeRemoveItemExplicit);
|
||||||
extensions.registerInstruction ("equip", "c", opcodeEquip, opcodeEquipExplicit);
|
extensions.registerInstruction ("equip", "cX", opcodeEquip, opcodeEquipExplicit);
|
||||||
extensions.registerFunction ("getarmortype", 'l', "l", opcodeGetArmorType, opcodeGetArmorTypeExplicit);
|
extensions.registerFunction ("getarmortype", 'l', "l", opcodeGetArmorType, opcodeGetArmorTypeExplicit);
|
||||||
extensions.registerFunction ("hasitemequipped", 'l', "c", opcodeHasItemEquipped, opcodeHasItemEquippedExplicit);
|
extensions.registerFunction ("hasitemequipped", 'l', "c", opcodeHasItemEquipped, opcodeHasItemEquippedExplicit);
|
||||||
extensions.registerFunction ("hassoulgem", 'l', "c", opcodeHasSoulGem, opcodeHasSoulGemExplicit);
|
extensions.registerFunction ("hassoulgem", 'l', "c", opcodeHasSoulGem, opcodeHasSoulGemExplicit);
|
||||||
|
@ -406,7 +406,7 @@ namespace Compiler
|
||||||
extensions.registerInstruction ("setpccrimelevel", "f", opcodeSetPCCrimeLevel);
|
extensions.registerInstruction ("setpccrimelevel", "f", opcodeSetPCCrimeLevel);
|
||||||
extensions.registerInstruction ("modpccrimelevel", "f", opcodeModPCCrimeLevel);
|
extensions.registerInstruction ("modpccrimelevel", "f", opcodeModPCCrimeLevel);
|
||||||
|
|
||||||
extensions.registerInstruction ("addspell", "cxX", opcodeAddSpell, opcodeAddSpellExplicit);
|
extensions.registerInstruction ("addspell", "cz", opcodeAddSpell, opcodeAddSpellExplicit);
|
||||||
extensions.registerInstruction ("removespell", "c", opcodeRemoveSpell,
|
extensions.registerInstruction ("removespell", "c", opcodeRemoveSpell,
|
||||||
opcodeRemoveSpellExplicit);
|
opcodeRemoveSpellExplicit);
|
||||||
extensions.registerInstruction ("removespelleffects", "c", opcodeRemoveSpellEffects,
|
extensions.registerInstruction ("removespelleffects", "c", opcodeRemoveSpellEffects,
|
||||||
|
|
|
@ -51,6 +51,12 @@ namespace Compiler
|
||||||
/// \todo allow this workaround to be disabled for newer scripts
|
/// \todo allow this workaround to be disabled for newer scripts
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mState==BeginCompleteState)
|
||||||
|
{
|
||||||
|
reportWarning ("Stray string (" + name + ") after begin statement", loc);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return Parser::parseName (name, loc, scanner);
|
return Parser::parseName (name, loc, scanner);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -300,9 +300,9 @@ namespace
|
||||||
code.push_back (Compiler::Generator::segment5 (46));
|
code.push_back (Compiler::Generator::segment5 (46));
|
||||||
}
|
}
|
||||||
|
|
||||||
void opStartScript (Compiler::Generator::CodeContainer& code)
|
void opStartScript (Compiler::Generator::CodeContainer& code, bool targeted)
|
||||||
{
|
{
|
||||||
code.push_back (Compiler::Generator::segment5 (47));
|
code.push_back (Compiler::Generator::segment5 (targeted ? 71 : 47));
|
||||||
}
|
}
|
||||||
|
|
||||||
void opStopScript (Compiler::Generator::CodeContainer& code)
|
void opStopScript (Compiler::Generator::CodeContainer& code)
|
||||||
|
@ -830,9 +830,16 @@ namespace Compiler
|
||||||
opScriptRunning (code);
|
opScriptRunning (code);
|
||||||
}
|
}
|
||||||
|
|
||||||
void startScript (CodeContainer& code)
|
void startScript (CodeContainer& code, Literals& literals, const std::string& id)
|
||||||
{
|
{
|
||||||
opStartScript (code);
|
if (id.empty())
|
||||||
|
opStartScript (code, false);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int index = literals.addString (id);
|
||||||
|
opPushInt (code, index);
|
||||||
|
opStartScript (code, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void stopScript (CodeContainer& code)
|
void stopScript (CodeContainer& code)
|
||||||
|
|
|
@ -113,7 +113,7 @@ namespace Compiler
|
||||||
|
|
||||||
void scriptRunning (CodeContainer& code);
|
void scriptRunning (CodeContainer& code);
|
||||||
|
|
||||||
void startScript (CodeContainer& code);
|
void startScript (CodeContainer& code, Literals& literals, const std::string& id);
|
||||||
|
|
||||||
void stopScript (CodeContainer& code);
|
void stopScript (CodeContainer& code);
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include "generator.hpp"
|
#include "generator.hpp"
|
||||||
#include "extensions.hpp"
|
#include "extensions.hpp"
|
||||||
#include "declarationparser.hpp"
|
#include "declarationparser.hpp"
|
||||||
|
#include "exception.hpp"
|
||||||
|
|
||||||
namespace Compiler
|
namespace Compiler
|
||||||
{
|
{
|
||||||
|
@ -262,6 +263,20 @@ namespace Compiler
|
||||||
Generator::disable (mCode, mLiterals, mExplicit);
|
Generator::disable (mCode, mLiterals, mExplicit);
|
||||||
mState = PotentialEndState;
|
mState = PotentialEndState;
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
case Scanner::K_startscript:
|
||||||
|
|
||||||
|
mExprParser.parseArguments ("c", scanner, mCode);
|
||||||
|
Generator::startScript (mCode, mLiterals, mExplicit);
|
||||||
|
mState = EndState;
|
||||||
|
return true;
|
||||||
|
|
||||||
|
case Scanner::K_stopscript:
|
||||||
|
|
||||||
|
mExprParser.parseArguments ("c", scanner, mCode);
|
||||||
|
Generator::stopScript (mCode);
|
||||||
|
mState = EndState;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check for custom extensions
|
// check for custom extensions
|
||||||
|
@ -278,9 +293,31 @@ namespace Compiler
|
||||||
mExplicit.clear();
|
mExplicit.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
int optionals = mExprParser.parseArguments (argumentType, scanner, mCode);
|
int optionals = 0;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ErrorDowngrade errorDowngrade (getErrorHandler());
|
||||||
|
std::vector<Interpreter::Type_Code> code;
|
||||||
|
optionals = mExprParser.parseArguments (argumentType, scanner, code);
|
||||||
|
mCode.insert (mCode.begin(), code.begin(), code.end());
|
||||||
|
extensions->generateInstructionCode (keyword, mCode, mLiterals,
|
||||||
|
mExplicit, optionals);
|
||||||
|
}
|
||||||
|
catch (const SourceException& exception)
|
||||||
|
{
|
||||||
|
// Ignore argument exceptions for positioncell.
|
||||||
|
/// \todo add option to disable this
|
||||||
|
if (Misc::StringUtils::lowerCase (loc.mLiteral)=="positioncell")
|
||||||
|
{
|
||||||
|
SkipParser skip (getErrorHandler(), getContext());
|
||||||
|
scanner.scan (skip);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
extensions->generateInstructionCode (keyword, mCode, mLiterals, mExplicit, optionals);
|
|
||||||
mState = EndState;
|
mState = EndState;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -349,7 +386,7 @@ namespace Compiler
|
||||||
if (declaration.parseKeyword (keyword, loc, scanner))
|
if (declaration.parseKeyword (keyword, loc, scanner))
|
||||||
scanner.scan (declaration);
|
scanner.scan (declaration);
|
||||||
|
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
case Scanner::K_set: mState = SetState; return true;
|
case Scanner::K_set: mState = SetState; return true;
|
||||||
|
@ -361,13 +398,6 @@ namespace Compiler
|
||||||
mState = EndState;
|
mState = EndState;
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case Scanner::K_startscript:
|
|
||||||
|
|
||||||
mExprParser.parseArguments ("c", scanner, mCode);
|
|
||||||
Generator::startScript (mCode);
|
|
||||||
mState = EndState;
|
|
||||||
return true;
|
|
||||||
|
|
||||||
case Scanner::K_stopscript:
|
case Scanner::K_stopscript:
|
||||||
|
|
||||||
mExprParser.parseArguments ("c", scanner, mCode);
|
mExprParser.parseArguments ("c", scanner, mCode);
|
||||||
|
|
|
@ -17,8 +17,6 @@ namespace Compiler
|
||||||
|
|
||||||
int searchIndex (char type, const std::string& name) const;
|
int searchIndex (char type, const std::string& name) const;
|
||||||
|
|
||||||
bool search (char type, const std::string& name) const;
|
|
||||||
|
|
||||||
std::vector<std::string>& get (char type);
|
std::vector<std::string>& get (char type);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -29,6 +27,10 @@ namespace Compiler
|
||||||
int getIndex (const std::string& name) const;
|
int getIndex (const std::string& name) const;
|
||||||
///< return index for local variable \a name (-1: does not exist).
|
///< return index for local variable \a name (-1: does not exist).
|
||||||
|
|
||||||
|
/// Return index for local variable \a name of type \a type (-1: variable does not
|
||||||
|
/// exit).
|
||||||
|
bool search (char type, const std::string& name) const;
|
||||||
|
|
||||||
const std::vector<std::string>& get (char type) const;
|
const std::vector<std::string>& get (char type) const;
|
||||||
|
|
||||||
void write (std::ostream& localFile) const;
|
void write (std::ostream& localFile) const;
|
||||||
|
|
|
@ -343,17 +343,13 @@ namespace Compiler
|
||||||
}
|
}
|
||||||
else if (!(c=='"' && name.empty()))
|
else if (!(c=='"' && name.empty()))
|
||||||
{
|
{
|
||||||
if (!(std::isalpha (c) || std::isdigit (c) || c=='_' || c=='`' ||
|
if (!isStringCharacter (c))
|
||||||
/// \todo add an option to disable the following hack. Also, find out who is
|
|
||||||
/// responsible for allowing it in the first place and meet up with that person in
|
|
||||||
/// a dark alley.
|
|
||||||
(c=='-' && !name.empty() && std::isalpha (mStream.peek()))))
|
|
||||||
{
|
{
|
||||||
putback (c);
|
putback (c);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (first && std::isdigit (c))
|
if (first && (std::isdigit (c) || c=='`' || c=='-'))
|
||||||
error = true;
|
error = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -499,6 +495,17 @@ namespace Compiler
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Scanner::isStringCharacter (char c, bool lookAhead)
|
||||||
|
{
|
||||||
|
return std::isalpha (c) || std::isdigit (c) || c=='_' ||
|
||||||
|
/// \todo disable this when doing more stricter compiling
|
||||||
|
c=='`' ||
|
||||||
|
/// \todo disable this when doing more stricter compiling. Also, find out who is
|
||||||
|
/// responsible for allowing it in the first place and meet up with that person in
|
||||||
|
/// a dark alley.
|
||||||
|
(c=='-' && (!lookAhead || isStringCharacter (mStream.peek(), false)));
|
||||||
|
}
|
||||||
|
|
||||||
bool Scanner::isWhitespace (char c)
|
bool Scanner::isWhitespace (char c)
|
||||||
{
|
{
|
||||||
return c==' ' || c=='\t';
|
return c==' ' || c=='\t';
|
||||||
|
|
|
@ -92,6 +92,8 @@ namespace Compiler
|
||||||
|
|
||||||
bool scanSpecial (char c, Parser& parser, bool& cont);
|
bool scanSpecial (char c, Parser& parser, bool& cont);
|
||||||
|
|
||||||
|
bool isStringCharacter (char c, bool lookAhead = true);
|
||||||
|
|
||||||
static bool isWhitespace (char c);
|
static bool isWhitespace (char c);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -12,6 +12,8 @@ void ESM::GlobalScript::load (ESMReader &esm)
|
||||||
|
|
||||||
mRunning = 0;
|
mRunning = 0;
|
||||||
esm.getHNOT (mRunning, "RUN_");
|
esm.getHNOT (mRunning, "RUN_");
|
||||||
|
|
||||||
|
mTargetId = esm.getHNOString ("TARG");
|
||||||
}
|
}
|
||||||
|
|
||||||
void ESM::GlobalScript::save (ESMWriter &esm) const
|
void ESM::GlobalScript::save (ESMWriter &esm) const
|
||||||
|
@ -22,4 +24,6 @@ void ESM::GlobalScript::save (ESMWriter &esm) const
|
||||||
|
|
||||||
if (mRunning)
|
if (mRunning)
|
||||||
esm.writeHNT ("RUN_", mRunning);
|
esm.writeHNT ("RUN_", mRunning);
|
||||||
|
|
||||||
|
esm.writeHNOString ("TARG", mTargetId);
|
||||||
}
|
}
|
|
@ -15,6 +15,7 @@ namespace ESM
|
||||||
std::string mId;
|
std::string mId;
|
||||||
Locals mLocals;
|
Locals mLocals;
|
||||||
int mRunning;
|
int mRunning;
|
||||||
|
std::string mTargetId; // for targeted scripts
|
||||||
|
|
||||||
void load (ESMReader &esm);
|
void load (ESMReader &esm);
|
||||||
void save (ESMWriter &esm) const;
|
void save (ESMWriter &esm) const;
|
||||||
|
|
|
@ -23,29 +23,8 @@ public:
|
||||||
|
|
||||||
struct SCHDstruct
|
struct SCHDstruct
|
||||||
{
|
{
|
||||||
/* Script name.
|
/// Data from script-precompling in the editor.
|
||||||
|
/// \warning Do not use them. OpenCS currently does not precompile scripts.
|
||||||
NOTE: You should handle the name "Main" (case insensitive) with
|
|
||||||
care. With tribunal, modders got the ability to add 'start
|
|
||||||
scripts' to their mods, which is a script that is run at
|
|
||||||
startup and which runs throughout the game (I think.)
|
|
||||||
|
|
||||||
However, before Tribunal, there was only one startup script,
|
|
||||||
called "Main". If mods wanted to make their own start scripts,
|
|
||||||
they had to overwrite Main. This is obviously problem if
|
|
||||||
multiple mods to this at the same time.
|
|
||||||
|
|
||||||
Although most mods have switched to using Trib-style startup
|
|
||||||
scripts, some legacy mods might still overwrite Main, and this
|
|
||||||
can cause problems if several mods do it. I think the best
|
|
||||||
course of action is to NEVER overwrite main, but instead add
|
|
||||||
each with a separate unique name and add them to the start
|
|
||||||
script list. But there might be other problems with this
|
|
||||||
approach though.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// These describe the sizes we need to allocate for the script
|
|
||||||
// data.
|
|
||||||
int mNumShorts, mNumLongs, mNumFloats, mScriptDataSize, mStringTableSize;
|
int mNumShorts, mNumLongs, mNumFloats, mScriptDataSize, mStringTableSize;
|
||||||
}; // 52 bytes
|
}; // 52 bytes
|
||||||
|
|
||||||
|
@ -53,9 +32,16 @@ public:
|
||||||
|
|
||||||
SCHDstruct mData;
|
SCHDstruct mData;
|
||||||
|
|
||||||
std::vector<std::string> mVarNames; // Variable names
|
/// Variable names generated by script-precompiling in the editor.
|
||||||
std::vector<unsigned char> mScriptData; // Compiled bytecode
|
/// \warning Do not use this field. OpenCS currently does not precompile scripts.
|
||||||
std::string mScriptText; // Uncompiled script
|
std::vector<std::string> mVarNames;
|
||||||
|
|
||||||
|
/// Bytecode generated from script-precompiling in the editor.
|
||||||
|
/// \warning Do not use this field. OpenCS currently does not precompile scripts.
|
||||||
|
std::vector<unsigned char> mScriptData;
|
||||||
|
|
||||||
|
/// Script source code
|
||||||
|
std::string mScriptText;
|
||||||
|
|
||||||
void load(ESMReader &esm);
|
void load(ESMReader &esm);
|
||||||
void save(ESMWriter &esm) const;
|
void save(ESMWriter &esm) const;
|
||||||
|
|
|
@ -81,7 +81,7 @@ namespace Interpreter
|
||||||
|
|
||||||
virtual bool isScriptRunning (const std::string& name) const = 0;
|
virtual bool isScriptRunning (const std::string& name) const = 0;
|
||||||
|
|
||||||
virtual void startScript (const std::string& name) = 0;
|
virtual void startScript (const std::string& name, const std::string& targetId = "") = 0;
|
||||||
|
|
||||||
virtual void stopScript (const std::string& name) = 0;
|
virtual void stopScript (const std::string& name) = 0;
|
||||||
|
|
||||||
|
@ -108,6 +108,8 @@ namespace Interpreter
|
||||||
|
|
||||||
virtual void setMemberFloat (const std::string& id, const std::string& name, float value, bool global)
|
virtual void setMemberFloat (const std::string& id, const std::string& name, float value, bool global)
|
||||||
= 0;
|
= 0;
|
||||||
|
|
||||||
|
virtual std::string getTargetId() const = 0;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -133,5 +133,6 @@ op 67: store stack[0] in member float stack[2] of global script with ID stack[1]
|
||||||
op 68: replace stack[0] with member short stack[1] of global script with ID stack[0]
|
op 68: replace stack[0] with member short stack[1] of global script with ID stack[0]
|
||||||
op 69: replace stack[0] with member short stack[1] of global script with ID stack[0]
|
op 69: replace stack[0] with member short stack[1] of global script with ID stack[0]
|
||||||
op 70: replace stack[0] with member short stack[1] of global script with ID stack[0]
|
op 70: replace stack[0] with member short stack[1] of global script with ID stack[0]
|
||||||
opcodes 71-33554431 unused
|
op 71: explicit reference (target) = stack[0]; pop; start script stack[0] and pop
|
||||||
|
opcodes 72-33554431 unused
|
||||||
opcodes 33554432-67108863 reserved for extensions
|
opcodes 33554432-67108863 reserved for extensions
|
||||||
|
|
|
@ -113,6 +113,7 @@ namespace Interpreter
|
||||||
interpreter.installSegment5 (46, new OpScriptRunning);
|
interpreter.installSegment5 (46, new OpScriptRunning);
|
||||||
interpreter.installSegment5 (47, new OpStartScript);
|
interpreter.installSegment5 (47, new OpStartScript);
|
||||||
interpreter.installSegment5 (48, new OpStopScript);
|
interpreter.installSegment5 (48, new OpStopScript);
|
||||||
|
interpreter.installSegment5 (71, new OpStartScriptExplicit);
|
||||||
|
|
||||||
// spacial
|
// spacial
|
||||||
interpreter.installSegment5 (49, new OpGetDistance);
|
interpreter.installSegment5 (49, new OpGetDistance);
|
||||||
|
|
|
@ -26,7 +26,23 @@ namespace Interpreter
|
||||||
{
|
{
|
||||||
std::string name = runtime.getStringLiteral (runtime[0].mInteger);
|
std::string name = runtime.getStringLiteral (runtime[0].mInteger);
|
||||||
runtime.pop();
|
runtime.pop();
|
||||||
runtime.getContext().startScript (name);
|
runtime.getContext().startScript (name, runtime.getContext().getTargetId());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class OpStartScriptExplicit : public Opcode0
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
virtual void execute (Runtime& runtime)
|
||||||
|
{
|
||||||
|
std::string targetId = runtime.getStringLiteral (runtime[0].mInteger);
|
||||||
|
runtime.pop();
|
||||||
|
|
||||||
|
std::string name = runtime.getStringLiteral (runtime[0].mInteger);
|
||||||
|
runtime.pop();
|
||||||
|
|
||||||
|
runtime.getContext().startScript (name, targetId);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -2,3 +2,6 @@ data="?global?data"
|
||||||
data="?mw?Data Files"
|
data="?mw?Data Files"
|
||||||
data-local="?userdata?data"
|
data-local="?userdata?data"
|
||||||
resources=${OPENMW_RESOURCE_FILES}
|
resources=${OPENMW_RESOURCE_FILES}
|
||||||
|
script-blacklist=Museum
|
||||||
|
script-blacklist=MockChangeScript
|
||||||
|
script-blacklist=doortestwarp
|
||||||
|
|
|
@ -3,3 +3,6 @@ data="?mw?Data Files"
|
||||||
data=./data
|
data=./data
|
||||||
data-local="?userdata?data"
|
data-local="?userdata?data"
|
||||||
resources=./resources
|
resources=./resources
|
||||||
|
script-blacklist=Museum
|
||||||
|
script-blacklist=MockChangeScript
|
||||||
|
script-blacklist=doortestwarp
|
||||||
|
|
Loading…
Reference in a new issue