From 563c2e57309d33d2ef6156045b4202344b0540c9 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 15 Jul 2014 10:39:11 +0200 Subject: [PATCH 01/32] be a bit more relaxed about allowing - in names (Fixes #1593) --- components/compiler/scanner.cpp | 19 +++++++++++++------ components/compiler/scanner.hpp | 2 ++ 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/components/compiler/scanner.cpp b/components/compiler/scanner.cpp index 46e50a2e9..dd8fb431b 100644 --- a/components/compiler/scanner.cpp +++ b/components/compiler/scanner.cpp @@ -343,17 +343,13 @@ namespace Compiler } else if (!(c=='"' && name.empty())) { - if (!(std::isalpha (c) || std::isdigit (c) || c=='_' || 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())))) + if (!isStringCharacter (c)) { putback (c); break; } - if (first && std::isdigit (c)) + if (first && (std::isdigit (c) || c=='`' || c=='-')) error = true; } @@ -499,6 +495,17 @@ namespace Compiler 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) { return c==' ' || c=='\t'; diff --git a/components/compiler/scanner.hpp b/components/compiler/scanner.hpp index 344ae0582..7f6609f76 100644 --- a/components/compiler/scanner.hpp +++ b/components/compiler/scanner.hpp @@ -92,6 +92,8 @@ namespace Compiler bool scanSpecial (char c, Parser& parser, bool& cont); + bool isStringCharacter (char c, bool lookAhead = true); + static bool isWhitespace (char c); public: From 8241ee59c3e0a9519200f9af64acabc18291bf85 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 15 Jul 2014 12:59:02 +0200 Subject: [PATCH 02/32] modified GlobalScripts data structures to accommodate targeted script data --- apps/openmw/mwscript/globalscripts.cpp | 60 +++++++++++++------------- apps/openmw/mwscript/globalscripts.hpp | 11 ++++- 2 files changed, 40 insertions(+), 31 deletions(-) diff --git a/apps/openmw/mwscript/globalscripts.cpp b/apps/openmw/mwscript/globalscripts.cpp index 8e118e2f8..411a0ec13 100644 --- a/apps/openmw/mwscript/globalscripts.cpp +++ b/apps/openmw/mwscript/globalscripts.cpp @@ -15,6 +15,9 @@ namespace MWScript { + GlobalScriptDesc::GlobalScriptDesc() : mRunning (false) {} + + GlobalScripts::GlobalScripts (const MWWorld::ESMStore& store) : mStore (store) { @@ -23,53 +26,53 @@ namespace MWScript void GlobalScripts::addScript (const std::string& name) { - std::map >::iterator iter = + std::map::iterator iter = mScripts.find (::Misc::StringUtils::lowerCase (name)); if (iter==mScripts.end()) { if (const ESM::Script *script = mStore.get().find (name)) { - Locals locals; + GlobalScriptDesc desc; + desc.mRunning = true; + desc.mLocals.configure (*script); - locals.configure (*script); - - mScripts.insert (std::make_pair (name, std::make_pair (true, locals))); + mScripts.insert (std::make_pair (name, desc)); } } else - iter->second.first = true; + iter->second.mRunning = true; } void GlobalScripts::removeScript (const std::string& name) { - std::map >::iterator iter = + std::map::iterator iter = mScripts.find (::Misc::StringUtils::lowerCase (name)); if (iter!=mScripts.end()) - iter->second.first = false; + iter->second.mRunning = false; } bool GlobalScripts::isRunning (const std::string& name) const { - std::map >::const_iterator iter = + std::map::const_iterator iter = mScripts.find (::Misc::StringUtils::lowerCase (name)); if (iter==mScripts.end()) return false; - return iter->second.first; + return iter->second.mRunning; } void GlobalScripts::run() { - for (std::map >::iterator iter (mScripts.begin()); + for (std::map::iterator iter (mScripts.begin()); iter!=mScripts.end(); ++iter) { - if (iter->second.first) + if (iter->second.mRunning) { MWScript::InterpreterContext interpreterContext ( - &iter->second.second, MWWorld::Ptr()); + &iter->second.mLocals, MWWorld::Ptr()); MWBase::Environment::get().getScriptManager()->run (iter->first, interpreterContext); } } @@ -99,16 +102,16 @@ namespace MWScript void GlobalScripts::write (ESM::ESMWriter& writer, Loading::Listener& progress) const { - for (std::map >::const_iterator iter (mScripts.begin()); + for (std::map::const_iterator iter (mScripts.begin()); iter!=mScripts.end(); ++iter) { ESM::GlobalScript script; 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; writer.startRecord (ESM::REC_GSCR); script.save (writer); @@ -124,25 +127,24 @@ namespace MWScript ESM::GlobalScript script; script.load (reader); - std::map >::iterator iter = + std::map::iterator iter = mScripts.find (script.mId); if (iter==mScripts.end()) { if (const ESM::Script *scriptRecord = mStore.get().search (script.mId)) { - std::pair data (false, Locals()); + GlobalScriptDesc desc; + desc.mLocals.configure (*scriptRecord); - data.second.configure (*scriptRecord); - - iter = mScripts.insert (std::make_pair (script.mId, data)).first; + iter = mScripts.insert (std::make_pair (script.mId, desc)).first; } else // script does not exist anymore return true; } - iter->second.first = script.mRunning!=0; - iter->second.second.read (script.mLocals, script.mId); + iter->second.mRunning = script.mRunning!=0; + iter->second.mLocals.read (script.mLocals, script.mId); return true; } @@ -153,21 +155,19 @@ namespace MWScript Locals& GlobalScripts::getLocals (const std::string& name) { std::string name2 = ::Misc::StringUtils::lowerCase (name); - std::map >::iterator iter = - mScripts.find (name2); + std::map::iterator iter = mScripts.find (name2); if (iter==mScripts.end()) { if (const ESM::Script *script = mStore.get().find (name)) { - Locals locals; + GlobalScriptDesc desc; + desc.mLocals.configure (*script); - locals.configure (*script); - - iter = mScripts.insert (std::make_pair (name, std::make_pair (false, locals))).first; + iter = mScripts.insert (std::make_pair (name, desc)).first; } } - return iter->second.second; + return iter->second.mLocals; } } diff --git a/apps/openmw/mwscript/globalscripts.hpp b/apps/openmw/mwscript/globalscripts.hpp index 97584a5b8..9ad9361b6 100644 --- a/apps/openmw/mwscript/globalscripts.hpp +++ b/apps/openmw/mwscript/globalscripts.hpp @@ -26,10 +26,19 @@ namespace MWWorld 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 { const MWWorld::ESMStore& mStore; - std::map > mScripts; // running, local variables + std::map mScripts; public: From e9377ad5c41abdfaecb6e12c79d91750cd0cfd12 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 15 Jul 2014 13:05:38 +0200 Subject: [PATCH 03/32] include targeted script data in saved games --- apps/openmw/mwscript/globalscripts.cpp | 3 +++ components/esm/globalscript.cpp | 4 ++++ components/esm/globalscript.hpp | 1 + 3 files changed, 8 insertions(+) diff --git a/apps/openmw/mwscript/globalscripts.cpp b/apps/openmw/mwscript/globalscripts.cpp index 411a0ec13..3335f4415 100644 --- a/apps/openmw/mwscript/globalscripts.cpp +++ b/apps/openmw/mwscript/globalscripts.cpp @@ -113,6 +113,8 @@ namespace MWScript script.mRunning = iter->second.mRunning ? 1 : 0; + script.mTargetId = iter->second.mId; + writer.startRecord (ESM::REC_GSCR); script.save (writer); writer.endRecord (ESM::REC_GSCR); @@ -145,6 +147,7 @@ namespace MWScript iter->second.mRunning = script.mRunning!=0; iter->second.mLocals.read (script.mLocals, script.mId); + iter->second.mId = script.mTargetId; return true; } diff --git a/components/esm/globalscript.cpp b/components/esm/globalscript.cpp index dcbd91140..467fe54a1 100644 --- a/components/esm/globalscript.cpp +++ b/components/esm/globalscript.cpp @@ -12,6 +12,8 @@ void ESM::GlobalScript::load (ESMReader &esm) mRunning = 0; esm.getHNOT (mRunning, "RUN_"); + + mTargetId = esm.getHNOString ("TARG"); } void ESM::GlobalScript::save (ESMWriter &esm) const @@ -22,4 +24,6 @@ void ESM::GlobalScript::save (ESMWriter &esm) const if (mRunning) esm.writeHNT ("RUN_", mRunning); + + esm.writeHNOString ("TARG", mTargetId); } \ No newline at end of file diff --git a/components/esm/globalscript.hpp b/components/esm/globalscript.hpp index 4fb8b7c48..43c859e09 100644 --- a/components/esm/globalscript.hpp +++ b/components/esm/globalscript.hpp @@ -15,6 +15,7 @@ namespace ESM std::string mId; Locals mLocals; int mRunning; + std::string mTargetId; // for targeted scripts void load (ESMReader &esm); void save (ESMWriter &esm) const; From 75ab8de3d200e24b934a86727f65f37cd787fe25 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 15 Jul 2014 13:26:04 +0200 Subject: [PATCH 04/32] added opcode for running scripts with explicit references (targeted scripts) --- apps/openmw/mwscript/globalscripts.cpp | 8 ++++-- apps/openmw/mwscript/globalscripts.hpp | 2 +- apps/openmw/mwscript/interpretercontext.cpp | 4 +-- apps/openmw/mwscript/interpretercontext.hpp | 2 +- components/interpreter/context.hpp | 2 +- components/interpreter/docs/vmformat.txt | 3 ++- components/interpreter/installopcodes.cpp | 1 + components/interpreter/scriptopcodes.hpp | 28 ++++++++++++++++----- 8 files changed, 36 insertions(+), 14 deletions(-) diff --git a/apps/openmw/mwscript/globalscripts.cpp b/apps/openmw/mwscript/globalscripts.cpp index 3335f4415..83c6560f0 100644 --- a/apps/openmw/mwscript/globalscripts.cpp +++ b/apps/openmw/mwscript/globalscripts.cpp @@ -24,7 +24,7 @@ namespace MWScript addStartup(); } - void GlobalScripts::addScript (const std::string& name) + void GlobalScripts::addScript (const std::string& name, const std::string& targetId) { std::map::iterator iter = mScripts.find (::Misc::StringUtils::lowerCase (name)); @@ -36,12 +36,16 @@ namespace MWScript GlobalScriptDesc desc; desc.mRunning = true; desc.mLocals.configure (*script); + desc.mId = targetId; mScripts.insert (std::make_pair (name, desc)); } } - else + else if (!iter->second.mRunning) + { iter->second.mRunning = true; + iter->second.mId = targetId; + } } void GlobalScripts::removeScript (const std::string& name) diff --git a/apps/openmw/mwscript/globalscripts.hpp b/apps/openmw/mwscript/globalscripts.hpp index 9ad9361b6..55c2e9321 100644 --- a/apps/openmw/mwscript/globalscripts.hpp +++ b/apps/openmw/mwscript/globalscripts.hpp @@ -44,7 +44,7 @@ namespace MWScript 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); diff --git a/apps/openmw/mwscript/interpretercontext.cpp b/apps/openmw/mwscript/interpretercontext.cpp index 028f83a61..0b474510d 100644 --- a/apps/openmw/mwscript/interpretercontext.cpp +++ b/apps/openmw/mwscript/interpretercontext.cpp @@ -366,9 +366,9 @@ namespace MWScript 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) diff --git a/apps/openmw/mwscript/interpretercontext.hpp b/apps/openmw/mwscript/interpretercontext.hpp index 99026392e..0f4eefeeb 100644 --- a/apps/openmw/mwscript/interpretercontext.hpp +++ b/apps/openmw/mwscript/interpretercontext.hpp @@ -113,7 +113,7 @@ namespace MWScript 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); diff --git a/components/interpreter/context.hpp b/components/interpreter/context.hpp index 97e4fad4f..25a3ab30d 100644 --- a/components/interpreter/context.hpp +++ b/components/interpreter/context.hpp @@ -81,7 +81,7 @@ namespace Interpreter 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; diff --git a/components/interpreter/docs/vmformat.txt b/components/interpreter/docs/vmformat.txt index 990762268..5d1eba088 100644 --- a/components/interpreter/docs/vmformat.txt +++ b/components/interpreter/docs/vmformat.txt @@ -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 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] -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 diff --git a/components/interpreter/installopcodes.cpp b/components/interpreter/installopcodes.cpp index 721cde3d8..d705a109c 100644 --- a/components/interpreter/installopcodes.cpp +++ b/components/interpreter/installopcodes.cpp @@ -113,6 +113,7 @@ namespace Interpreter interpreter.installSegment5 (46, new OpScriptRunning); interpreter.installSegment5 (47, new OpStartScript); interpreter.installSegment5 (48, new OpStopScript); + interpreter.installSegment5 (71, new OpStartScriptExplicit); // spacial interpreter.installSegment5 (49, new OpGetDistance); diff --git a/components/interpreter/scriptopcodes.hpp b/components/interpreter/scriptopcodes.hpp index 56502d510..c98bcd23e 100644 --- a/components/interpreter/scriptopcodes.hpp +++ b/components/interpreter/scriptopcodes.hpp @@ -10,36 +10,52 @@ namespace Interpreter class OpScriptRunning : public Opcode0 { public: - + virtual void execute (Runtime& runtime) { std::string name = runtime.getStringLiteral (runtime[0].mInteger); runtime[0].mInteger = runtime.getContext().isScriptRunning (name); - } + } }; class OpStartScript : public Opcode0 { public: - + virtual void execute (Runtime& runtime) { std::string name = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); runtime.getContext().startScript (name); - } + } + }; + + 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); + } }; class OpStopScript : public Opcode0 { public: - + virtual void execute (Runtime& runtime) { std::string name = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); runtime.getContext().stopScript (name); - } + } }; } From e8322da6631ecf49a6761210df1e9f89ac26725a Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 17 Jul 2014 08:35:28 +0200 Subject: [PATCH 05/32] added support for targeted scripts to script compiler --- components/compiler/generator.cpp | 15 +++++++++++---- components/compiler/generator.hpp | 2 +- components/compiler/lineparser.cpp | 14 +++++++------- 3 files changed, 19 insertions(+), 12 deletions(-) diff --git a/components/compiler/generator.cpp b/components/compiler/generator.cpp index c67e51e57..235b163ad 100644 --- a/components/compiler/generator.cpp +++ b/components/compiler/generator.cpp @@ -300,9 +300,9 @@ namespace 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) @@ -830,9 +830,16 @@ namespace Compiler 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) diff --git a/components/compiler/generator.hpp b/components/compiler/generator.hpp index b51116122..2619033c8 100644 --- a/components/compiler/generator.hpp +++ b/components/compiler/generator.hpp @@ -113,7 +113,7 @@ namespace Compiler void scriptRunning (CodeContainer& code); - void startScript (CodeContainer& code); + void startScript (CodeContainer& code, Literals& literals, const std::string& id); void stopScript (CodeContainer& code); diff --git a/components/compiler/lineparser.cpp b/components/compiler/lineparser.cpp index f7d2726e3..b1b831bc2 100644 --- a/components/compiler/lineparser.cpp +++ b/components/compiler/lineparser.cpp @@ -262,6 +262,13 @@ namespace Compiler Generator::disable (mCode, mLiterals, mExplicit); mState = PotentialEndState; return true; + + case Scanner::K_startscript: + + mExprParser.parseArguments ("c", scanner, mCode); + Generator::startScript (mCode, mLiterals, mExplicit); + mState = EndState; + return true; } // check for custom extensions @@ -361,13 +368,6 @@ namespace Compiler mState = EndState; return true; - case Scanner::K_startscript: - - mExprParser.parseArguments ("c", scanner, mCode); - Generator::startScript (mCode); - mState = EndState; - return true; - case Scanner::K_stopscript: mExprParser.parseArguments ("c", scanner, mCode); From dba6a9ebff4ba8c3ad8b4d2cee94a5b3bf3d7212 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 17 Jul 2014 09:15:41 +0200 Subject: [PATCH 06/32] run targeted scripts with an implicit reference based on the ID given --- apps/openmw/mwscript/globalscripts.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwscript/globalscripts.cpp b/apps/openmw/mwscript/globalscripts.cpp index 83c6560f0..332431b16 100644 --- a/apps/openmw/mwscript/globalscripts.cpp +++ b/apps/openmw/mwscript/globalscripts.cpp @@ -75,8 +75,15 @@ namespace MWScript { if (iter->second.mRunning) { + MWWorld::Ptr ptr; + + if (!iter->second.mId.empty()) + ptr = MWBase::Environment::get().getWorld()->getPtr ( + iter->second.mId, false); + MWScript::InterpreterContext interpreterContext ( - &iter->second.mLocals, MWWorld::Ptr()); + &iter->second.mLocals, ptr); + MWBase::Environment::get().getScriptManager()->run (iter->first, interpreterContext); } } From 35b27ea8cb480e07ddffb24e91e7255f79d4de87 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 17 Jul 2014 11:29:04 +0200 Subject: [PATCH 07/32] ignore stray string argument after GetDisabled --- components/compiler/exprparser.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/components/compiler/exprparser.cpp b/components/compiler/exprparser.cpp index e54b2e2a8..d0cda0ec2 100644 --- a/components/compiler/exprparser.cpp +++ b/components/compiler/exprparser.cpp @@ -386,6 +386,9 @@ namespace Compiler mExplicit.clear(); mRefOp = false; + std::vector ignore; + parseArguments ("x", scanner, ignore); + mNextOperand = false; return true; } @@ -527,6 +530,9 @@ namespace Compiler Generator::getDisabled (mCode, mLiterals, ""); mOperands.push_back ('l'); + std::vector ignore; + parseArguments ("x", scanner, ignore); + mNextOperand = false; return true; } From 27c84d6cb7130204334af3575edabfe589337762 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 17 Jul 2014 13:36:55 +0200 Subject: [PATCH 08/32] the reference for a targeted script is now determined when needed instead of at the start of the script execution --- apps/openmw/mwscript/globalscripts.cpp | 6 +-- apps/openmw/mwscript/interpretercontext.cpp | 49 +++++++++++++-------- apps/openmw/mwscript/interpretercontext.hpp | 19 ++++++-- components/interpreter/context.hpp | 2 + 4 files changed, 49 insertions(+), 27 deletions(-) diff --git a/apps/openmw/mwscript/globalscripts.cpp b/apps/openmw/mwscript/globalscripts.cpp index 332431b16..0c94f503b 100644 --- a/apps/openmw/mwscript/globalscripts.cpp +++ b/apps/openmw/mwscript/globalscripts.cpp @@ -77,12 +77,8 @@ namespace MWScript { MWWorld::Ptr ptr; - if (!iter->second.mId.empty()) - ptr = MWBase::Environment::get().getWorld()->getPtr ( - iter->second.mId, false); - MWScript::InterpreterContext interpreterContext ( - &iter->second.mLocals, ptr); + &iter->second.mLocals, MWWorld::Ptr(), iter->second.mId); MWBase::Environment::get().getScriptManager()->run (iter->first, interpreterContext); } diff --git a/apps/openmw/mwscript/interpretercontext.cpp b/apps/openmw/mwscript/interpretercontext.cpp index 0b474510d..c64b4c0d3 100644 --- a/apps/openmw/mwscript/interpretercontext.cpp +++ b/apps/openmw/mwscript/interpretercontext.cpp @@ -22,7 +22,7 @@ namespace MWScript { - MWWorld::Ptr InterpreterContext::getReference ( + MWWorld::Ptr InterpreterContext::getReferenceImp ( const std::string& id, bool activeOnly, bool doThrow) { if (!id.empty()) @@ -31,6 +31,10 @@ namespace MWScript } else { + if (mReference.isEmpty() && !mTargetId.empty()) + mReference = + MWBase::Environment::get().getWorld()->searchPtr (mTargetId, false); + if (mReference.isEmpty() && doThrow) throw std::runtime_error ("no implicit reference"); @@ -38,7 +42,7 @@ namespace MWScript } } - const MWWorld::Ptr InterpreterContext::getReference ( + const MWWorld::Ptr InterpreterContext::getReferenceImp ( const std::string& id, bool activeOnly, bool doThrow) const { if (!id.empty()) @@ -47,6 +51,10 @@ namespace MWScript } else { + if (mReference.isEmpty() && !mTargetId.empty()) + mReference = + MWBase::Environment::get().getWorld()->searchPtr (mTargetId, false); + if (mReference.isEmpty() && doThrow) throw std::runtime_error ("no implicit reference"); @@ -64,7 +72,7 @@ namespace MWScript } else { - const MWWorld::Ptr ptr = getReference (id, false); + const MWWorld::Ptr ptr = getReferenceImp (id, false); id = ptr.getClass().getScript (ptr); @@ -84,7 +92,7 @@ namespace MWScript } else { - const MWWorld::Ptr ptr = getReference (id, false); + const MWWorld::Ptr ptr = getReferenceImp (id, false); id = ptr.getClass().getScript (ptr); @@ -96,9 +104,9 @@ namespace MWScript } InterpreterContext::InterpreterContext ( - MWScript::Locals *locals, MWWorld::Ptr reference) + MWScript::Locals *locals, MWWorld::Ptr reference, const std::string& targetId) : mLocals (locals), mReference (reference), - mActivationHandled (false) + mActivationHandled (false), mTargetId (targetId) {} int InterpreterContext::getLocalShort (int index) const @@ -236,34 +244,34 @@ namespace MWScript std::string InterpreterContext::getNPCName() const { - ESM::NPC npc = *mReference.get()->mBase; + ESM::NPC npc = *getReferenceImp().get()->mBase; return npc.mName; } std::string InterpreterContext::getNPCRace() const { - ESM::NPC npc = *mReference.get()->mBase; + ESM::NPC npc = *getReferenceImp().get()->mBase; const ESM::Race* race = MWBase::Environment::get().getWorld()->getStore().get().find(npc.mRace); return race->mName; } std::string InterpreterContext::getNPCClass() const { - ESM::NPC npc = *mReference.get()->mBase; + ESM::NPC npc = *getReferenceImp().get()->mBase; const ESM::Class* class_ = MWBase::Environment::get().getWorld()->getStore().get().find(npc.mClass); return class_->mName; } std::string InterpreterContext::getNPCFaction() const { - ESM::NPC npc = *mReference.get()->mBase; + ESM::NPC npc = *getReferenceImp().get()->mBase; const ESM::Faction* faction = MWBase::Environment::get().getWorld()->getStore().get().find(npc.mFaction); return faction->mName; } std::string InterpreterContext::getNPCRank() const { - std::map ranks = mReference.getClass().getNpcStats (mReference).getFactionRanks(); + std::map ranks = getReferenceImp().getClass().getNpcStats (getReferenceImp()).getFactionRanks(); std::map::const_iterator it = ranks.begin(); MWBase::World *world = MWBase::Environment::get().getWorld(); @@ -299,7 +307,7 @@ namespace MWScript MWBase::World *world = MWBase::Environment::get().getWorld(); 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 ranks = player.getClass().getNpcStats (player).getFactionRanks(); std::map::const_iterator it = ranks.find(factionId); @@ -326,7 +334,7 @@ namespace MWScript MWBase::World *world = MWBase::Environment::get().getWorld(); 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 ranks = player.getClass().getNpcStats (player).getFactionRanks(); std::map::const_iterator it = ranks.find(factionId); @@ -383,7 +391,7 @@ namespace MWScript MWWorld::Ptr ref2; if (id.empty()) - ref2 = getReference("", true, true); + ref2 = getReferenceImp(); else ref2 = MWBase::Environment::get().getWorld()->searchPtr(id, true); @@ -448,19 +456,19 @@ namespace MWScript 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(); } 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); } 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); } @@ -542,6 +550,11 @@ namespace MWScript MWWorld::Ptr InterpreterContext::getReference(bool required) { - return getReference ("", true, required); + return getReferenceImp ("", true, required); + } + + std::string InterpreterContext::getTargetId() const + { + return mTargetId; } } diff --git a/apps/openmw/mwscript/interpretercontext.hpp b/apps/openmw/mwscript/interpretercontext.hpp index 0f4eefeeb..f897282e2 100644 --- a/apps/openmw/mwscript/interpretercontext.hpp +++ b/apps/openmw/mwscript/interpretercontext.hpp @@ -27,14 +27,22 @@ namespace MWScript class InterpreterContext : public Interpreter::Context { Locals *mLocals; - MWWorld::Ptr mReference; + mutable MWWorld::Ptr mReference; MWWorld::Ptr mActivated; 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; ///< \a id is changed to the respective script ID, if \a id wasn't a script ID before @@ -44,7 +52,8 @@ namespace MWScript 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. virtual int getLocalShort (int index) const; @@ -158,6 +167,8 @@ namespace MWScript MWWorld::Ptr getReference(bool required=true); ///< Reference, that the script is running from (can be empty) + + virtual std::string getTargetId() const; }; } diff --git a/components/interpreter/context.hpp b/components/interpreter/context.hpp index 25a3ab30d..881687366 100644 --- a/components/interpreter/context.hpp +++ b/components/interpreter/context.hpp @@ -108,6 +108,8 @@ namespace Interpreter virtual void setMemberFloat (const std::string& id, const std::string& name, float value, bool global) = 0; + + virtual std::string getTargetId() const = 0; }; } From 8952154488789989e7721678c1bfc5672590a1ff Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 17 Jul 2014 13:37:57 +0200 Subject: [PATCH 09/32] inherit target ID when starting a script from another script --- components/interpreter/scriptopcodes.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/interpreter/scriptopcodes.hpp b/components/interpreter/scriptopcodes.hpp index c98bcd23e..976390eb5 100644 --- a/components/interpreter/scriptopcodes.hpp +++ b/components/interpreter/scriptopcodes.hpp @@ -26,7 +26,7 @@ namespace Interpreter { std::string name = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); - runtime.getContext().startScript (name); + runtime.getContext().startScript (name, runtime.getContext().getTargetId()); } }; From 4fb897f2f8ea61f3f40a133c9a908d0db8092863 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 18 Jul 2014 09:56:58 +0200 Subject: [PATCH 10/32] added missing getId functions to classes derived from MWWorld::Class --- apps/openmw/mwclass/activator.cpp | 5 +++++ apps/openmw/mwclass/activator.hpp | 3 +++ apps/openmw/mwclass/apparatus.cpp | 5 +++++ apps/openmw/mwclass/apparatus.hpp | 3 +++ apps/openmw/mwclass/armor.cpp | 5 +++++ apps/openmw/mwclass/armor.hpp | 3 +++ apps/openmw/mwclass/book.cpp | 5 +++++ apps/openmw/mwclass/book.hpp | 3 +++ apps/openmw/mwclass/clothing.cpp | 5 +++++ apps/openmw/mwclass/clothing.hpp | 3 +++ apps/openmw/mwclass/container.cpp | 5 +++++ apps/openmw/mwclass/container.hpp | 3 +++ apps/openmw/mwclass/creaturelevlist.cpp | 5 +++++ apps/openmw/mwclass/creaturelevlist.hpp | 3 +++ apps/openmw/mwclass/door.cpp | 5 +++++ apps/openmw/mwclass/door.hpp | 3 +++ apps/openmw/mwclass/itemlevlist.cpp | 5 +++++ apps/openmw/mwclass/itemlevlist.hpp | 3 +++ apps/openmw/mwclass/light.cpp | 5 +++++ apps/openmw/mwclass/light.hpp | 3 +++ apps/openmw/mwclass/lockpick.cpp | 5 +++++ apps/openmw/mwclass/lockpick.hpp | 3 +++ apps/openmw/mwclass/misc.cpp | 5 +++++ apps/openmw/mwclass/misc.hpp | 3 +++ apps/openmw/mwclass/potion.cpp | 5 +++++ apps/openmw/mwclass/potion.hpp | 3 +++ apps/openmw/mwclass/probe.cpp | 5 +++++ apps/openmw/mwclass/probe.hpp | 3 +++ apps/openmw/mwclass/repair.cpp | 5 +++++ apps/openmw/mwclass/repair.hpp | 3 +++ apps/openmw/mwclass/static.cpp | 5 +++++ apps/openmw/mwclass/static.hpp | 3 +++ 32 files changed, 128 insertions(+) diff --git a/apps/openmw/mwclass/activator.cpp b/apps/openmw/mwclass/activator.cpp index 043aadd35..0585ced51 100644 --- a/apps/openmw/mwclass/activator.cpp +++ b/apps/openmw/mwclass/activator.cpp @@ -25,6 +25,11 @@ namespace MWClass { + std::string Activator::getId (const MWWorld::Ptr& ptr) const + { + return ptr.get()->mBase->mId; + } + void Activator::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const { const std::string model = getModel(ptr); diff --git a/apps/openmw/mwclass/activator.hpp b/apps/openmw/mwclass/activator.hpp index 1e772ef4f..3e4bc3de4 100644 --- a/apps/openmw/mwclass/activator.hpp +++ b/apps/openmw/mwclass/activator.hpp @@ -13,6 +13,9 @@ namespace MWClass 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; ///< Add reference into a cell for rendering diff --git a/apps/openmw/mwclass/apparatus.cpp b/apps/openmw/mwclass/apparatus.cpp index d61ba038a..32f2e0bb7 100644 --- a/apps/openmw/mwclass/apparatus.cpp +++ b/apps/openmw/mwclass/apparatus.cpp @@ -21,6 +21,11 @@ namespace MWClass { + std::string Apparatus::getId (const MWWorld::Ptr& ptr) const + { + return ptr.get()->mBase->mId; + } + void Apparatus::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const { const std::string model = getModel(ptr); diff --git a/apps/openmw/mwclass/apparatus.hpp b/apps/openmw/mwclass/apparatus.hpp index 17b8b9254..5cdda8f26 100644 --- a/apps/openmw/mwclass/apparatus.hpp +++ b/apps/openmw/mwclass/apparatus.hpp @@ -13,6 +13,9 @@ namespace MWClass public: + /// Return ID of \a ptr + virtual std::string getId (const MWWorld::Ptr& ptr) const; + virtual float getWeight (const MWWorld::Ptr& ptr) const; virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const; diff --git a/apps/openmw/mwclass/armor.cpp b/apps/openmw/mwclass/armor.cpp index b29bf36b2..79766e9ec 100644 --- a/apps/openmw/mwclass/armor.cpp +++ b/apps/openmw/mwclass/armor.cpp @@ -25,6 +25,11 @@ namespace MWClass { + std::string Armor::getId (const MWWorld::Ptr& ptr) const + { + return ptr.get()->mBase->mId; + } + void Armor::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const { const std::string model = getModel(ptr); diff --git a/apps/openmw/mwclass/armor.hpp b/apps/openmw/mwclass/armor.hpp index e9164f920..8b7804c63 100644 --- a/apps/openmw/mwclass/armor.hpp +++ b/apps/openmw/mwclass/armor.hpp @@ -12,6 +12,9 @@ namespace MWClass public: + /// Return ID of \a ptr + virtual std::string getId (const MWWorld::Ptr& ptr) const; + virtual float getWeight (const MWWorld::Ptr& ptr) const; virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const; diff --git a/apps/openmw/mwclass/book.cpp b/apps/openmw/mwclass/book.cpp index 0adee57e3..91b570783 100644 --- a/apps/openmw/mwclass/book.cpp +++ b/apps/openmw/mwclass/book.cpp @@ -22,6 +22,11 @@ namespace MWClass { + std::string Book::getId (const MWWorld::Ptr& ptr) const + { + return ptr.get()->mBase->mId; + } + void Book::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const { const std::string model = getModel(ptr); diff --git a/apps/openmw/mwclass/book.hpp b/apps/openmw/mwclass/book.hpp index b60ef41d6..49d21e8bf 100644 --- a/apps/openmw/mwclass/book.hpp +++ b/apps/openmw/mwclass/book.hpp @@ -12,6 +12,9 @@ namespace MWClass 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; ///< Add reference into a cell for rendering diff --git a/apps/openmw/mwclass/clothing.cpp b/apps/openmw/mwclass/clothing.cpp index dc98e323e..1a9a497d7 100644 --- a/apps/openmw/mwclass/clothing.cpp +++ b/apps/openmw/mwclass/clothing.cpp @@ -22,6 +22,11 @@ namespace MWClass { + std::string Clothing::getId (const MWWorld::Ptr& ptr) const + { + return ptr.get()->mBase->mId; + } + void Clothing::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const { const std::string model = getModel(ptr); diff --git a/apps/openmw/mwclass/clothing.hpp b/apps/openmw/mwclass/clothing.hpp index 052928238..99ce61ece 100644 --- a/apps/openmw/mwclass/clothing.hpp +++ b/apps/openmw/mwclass/clothing.hpp @@ -12,6 +12,9 @@ namespace MWClass 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; ///< Add reference into a cell for rendering diff --git a/apps/openmw/mwclass/container.cpp b/apps/openmw/mwclass/container.cpp index 53add4274..044d67536 100644 --- a/apps/openmw/mwclass/container.cpp +++ b/apps/openmw/mwclass/container.cpp @@ -43,6 +43,11 @@ namespace namespace MWClass { + std::string Container::getId (const MWWorld::Ptr& ptr) const + { + return ptr.get()->mBase->mId; + } + void Container::ensureCustomData (const MWWorld::Ptr& ptr) const { if (!ptr.getRefData().getCustomData()) diff --git a/apps/openmw/mwclass/container.hpp b/apps/openmw/mwclass/container.hpp index 9fc013e45..e926a71fe 100644 --- a/apps/openmw/mwclass/container.hpp +++ b/apps/openmw/mwclass/container.hpp @@ -15,6 +15,9 @@ namespace MWClass 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; ///< Add reference into a cell for rendering diff --git a/apps/openmw/mwclass/creaturelevlist.cpp b/apps/openmw/mwclass/creaturelevlist.cpp index 784304804..754780b1d 100644 --- a/apps/openmw/mwclass/creaturelevlist.cpp +++ b/apps/openmw/mwclass/creaturelevlist.cpp @@ -27,6 +27,11 @@ namespace namespace MWClass { + std::string CreatureLevList::getId (const MWWorld::Ptr& ptr) const + { + return ptr.get()->mBase->mId; + } + std::string CreatureLevList::getName (const MWWorld::Ptr& ptr) const { return ""; diff --git a/apps/openmw/mwclass/creaturelevlist.hpp b/apps/openmw/mwclass/creaturelevlist.hpp index 6c51a3189..7016524eb 100644 --- a/apps/openmw/mwclass/creaturelevlist.hpp +++ b/apps/openmw/mwclass/creaturelevlist.hpp @@ -11,6 +11,9 @@ namespace MWClass public: + /// Return ID of \a ptr + virtual std::string getId (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); /// can return an empty string. diff --git a/apps/openmw/mwclass/door.cpp b/apps/openmw/mwclass/door.cpp index 677ad462e..889268a9a 100644 --- a/apps/openmw/mwclass/door.cpp +++ b/apps/openmw/mwclass/door.cpp @@ -42,6 +42,11 @@ namespace namespace MWClass { + std::string Door::getId (const MWWorld::Ptr& ptr) const + { + return ptr.get()->mBase->mId; + } + void Door::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const { const std::string model = getModel(ptr); diff --git a/apps/openmw/mwclass/door.hpp b/apps/openmw/mwclass/door.hpp index 12b360aa8..23e11d336 100644 --- a/apps/openmw/mwclass/door.hpp +++ b/apps/openmw/mwclass/door.hpp @@ -16,6 +16,9 @@ namespace MWClass 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; ///< Add reference into a cell for rendering diff --git a/apps/openmw/mwclass/itemlevlist.cpp b/apps/openmw/mwclass/itemlevlist.cpp index 6ed9ab2e5..d31080bb2 100644 --- a/apps/openmw/mwclass/itemlevlist.cpp +++ b/apps/openmw/mwclass/itemlevlist.cpp @@ -5,6 +5,11 @@ namespace MWClass { + std::string ItemLevList::getId (const MWWorld::Ptr& ptr) const + { + return ptr.get()->mBase->mId; + } + std::string ItemLevList::getName (const MWWorld::Ptr& ptr) const { return ""; diff --git a/apps/openmw/mwclass/itemlevlist.hpp b/apps/openmw/mwclass/itemlevlist.hpp index 0b71b072c..2b507135f 100644 --- a/apps/openmw/mwclass/itemlevlist.hpp +++ b/apps/openmw/mwclass/itemlevlist.hpp @@ -9,6 +9,9 @@ namespace MWClass { public: + /// Return ID of \a ptr + virtual std::string getId (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); /// can return an empty string. diff --git a/apps/openmw/mwclass/light.cpp b/apps/openmw/mwclass/light.cpp index 8a2c20f69..6178984cf 100644 --- a/apps/openmw/mwclass/light.cpp +++ b/apps/openmw/mwclass/light.cpp @@ -47,6 +47,11 @@ namespace namespace MWClass { + std::string Light::getId (const MWWorld::Ptr& ptr) const + { + return ptr.get()->mBase->mId; + } + void Light::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const { const std::string model = getModel(ptr); diff --git a/apps/openmw/mwclass/light.hpp b/apps/openmw/mwclass/light.hpp index 5568e1727..584039336 100644 --- a/apps/openmw/mwclass/light.hpp +++ b/apps/openmw/mwclass/light.hpp @@ -14,6 +14,9 @@ namespace MWClass 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; ///< Add reference into a cell for rendering diff --git a/apps/openmw/mwclass/lockpick.cpp b/apps/openmw/mwclass/lockpick.cpp index bc6855129..9cce5694d 100644 --- a/apps/openmw/mwclass/lockpick.cpp +++ b/apps/openmw/mwclass/lockpick.cpp @@ -22,6 +22,11 @@ namespace MWClass { + std::string Lockpick::getId (const MWWorld::Ptr& ptr) const + { + return ptr.get()->mBase->mId; + } + void Lockpick::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const { const std::string model = getModel(ptr); diff --git a/apps/openmw/mwclass/lockpick.hpp b/apps/openmw/mwclass/lockpick.hpp index 8f5a699d9..d4bdf3fa6 100644 --- a/apps/openmw/mwclass/lockpick.hpp +++ b/apps/openmw/mwclass/lockpick.hpp @@ -12,6 +12,9 @@ namespace MWClass 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; ///< Add reference into a cell for rendering diff --git a/apps/openmw/mwclass/misc.cpp b/apps/openmw/mwclass/misc.cpp index 1044fb01d..7bd2f9b67 100644 --- a/apps/openmw/mwclass/misc.cpp +++ b/apps/openmw/mwclass/misc.cpp @@ -38,6 +38,11 @@ bool isGold (const MWWorld::Ptr& ptr) namespace MWClass { + std::string Miscellaneous::getId (const MWWorld::Ptr& ptr) const + { + return ptr.get()->mBase->mId; + } + void Miscellaneous::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const { const std::string model = getModel(ptr); diff --git a/apps/openmw/mwclass/misc.hpp b/apps/openmw/mwclass/misc.hpp index 16e9ca10b..53a8e050b 100644 --- a/apps/openmw/mwclass/misc.hpp +++ b/apps/openmw/mwclass/misc.hpp @@ -12,6 +12,9 @@ namespace MWClass 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; ///< Add reference into a cell for rendering diff --git a/apps/openmw/mwclass/potion.cpp b/apps/openmw/mwclass/potion.cpp index 440121d35..b0b15193d 100644 --- a/apps/openmw/mwclass/potion.cpp +++ b/apps/openmw/mwclass/potion.cpp @@ -24,6 +24,11 @@ namespace MWClass { + std::string Potion::getId (const MWWorld::Ptr& ptr) const + { + return ptr.get()->mBase->mId; + } + void Potion::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const { const std::string model = getModel(ptr); diff --git a/apps/openmw/mwclass/potion.hpp b/apps/openmw/mwclass/potion.hpp index 0f0578ca0..4c407d161 100644 --- a/apps/openmw/mwclass/potion.hpp +++ b/apps/openmw/mwclass/potion.hpp @@ -12,6 +12,9 @@ namespace MWClass 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; ///< Add reference into a cell for rendering diff --git a/apps/openmw/mwclass/probe.cpp b/apps/openmw/mwclass/probe.cpp index ed8625eec..030426dee 100644 --- a/apps/openmw/mwclass/probe.cpp +++ b/apps/openmw/mwclass/probe.cpp @@ -22,6 +22,11 @@ namespace MWClass { + std::string Probe::getId (const MWWorld::Ptr& ptr) const + { + return ptr.get()->mBase->mId; + } + void Probe::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const { const std::string model = getModel(ptr); diff --git a/apps/openmw/mwclass/probe.hpp b/apps/openmw/mwclass/probe.hpp index a959e6c42..047cb8ed4 100644 --- a/apps/openmw/mwclass/probe.hpp +++ b/apps/openmw/mwclass/probe.hpp @@ -12,6 +12,9 @@ namespace MWClass 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; ///< Add reference into a cell for rendering diff --git a/apps/openmw/mwclass/repair.cpp b/apps/openmw/mwclass/repair.cpp index d7a080534..f62d5f6cf 100644 --- a/apps/openmw/mwclass/repair.cpp +++ b/apps/openmw/mwclass/repair.cpp @@ -21,6 +21,11 @@ namespace MWClass { + std::string Repair::getId (const MWWorld::Ptr& ptr) const + { + return ptr.get()->mBase->mId; + } + void Repair::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const { const std::string model = getModel(ptr); diff --git a/apps/openmw/mwclass/repair.hpp b/apps/openmw/mwclass/repair.hpp index 28ca5ad4c..17730d6ec 100644 --- a/apps/openmw/mwclass/repair.hpp +++ b/apps/openmw/mwclass/repair.hpp @@ -12,6 +12,9 @@ namespace MWClass 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; ///< Add reference into a cell for rendering diff --git a/apps/openmw/mwclass/static.cpp b/apps/openmw/mwclass/static.cpp index 8768bde06..c241935ab 100644 --- a/apps/openmw/mwclass/static.cpp +++ b/apps/openmw/mwclass/static.cpp @@ -12,6 +12,11 @@ namespace MWClass { + std::string Static::getId (const MWWorld::Ptr& ptr) const + { + return ptr.get()->mBase->mId; + } + void Static::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const { MWWorld::LiveCellRef *ref = diff --git a/apps/openmw/mwclass/static.hpp b/apps/openmw/mwclass/static.hpp index e36b3d142..2ac2e8682 100644 --- a/apps/openmw/mwclass/static.hpp +++ b/apps/openmw/mwclass/static.hpp @@ -12,6 +12,9 @@ namespace MWClass 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; ///< Add reference into a cell for rendering From 6a3ff211b18cbf5505dfb6f06a554aac4cf8355d Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 18 Jul 2014 09:57:47 +0200 Subject: [PATCH 11/32] automatically get target ID at InterpreterContext construction, if a reference is available --- apps/openmw/mwscript/interpretercontext.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwscript/interpretercontext.cpp b/apps/openmw/mwscript/interpretercontext.cpp index c64b4c0d3..e1dc6273c 100644 --- a/apps/openmw/mwscript/interpretercontext.cpp +++ b/apps/openmw/mwscript/interpretercontext.cpp @@ -107,7 +107,13 @@ namespace MWScript MWScript::Locals *locals, MWWorld::Ptr reference, const std::string& targetId) : mLocals (locals), mReference (reference), 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 { From e33ee52b917c2e9a295b89b20c6cd117db32a439 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 18 Jul 2014 12:29:20 +0200 Subject: [PATCH 12/32] make stray names in the begin line a warning instead of an error --- components/compiler/fileparser.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/components/compiler/fileparser.cpp b/components/compiler/fileparser.cpp index 185af4a51..e90e9a8f6 100644 --- a/components/compiler/fileparser.cpp +++ b/components/compiler/fileparser.cpp @@ -51,6 +51,12 @@ namespace Compiler /// \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); } From d87630b41a0c5dc5deada97c2b3f363361f9554f Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 21 Jul 2014 09:34:10 +0200 Subject: [PATCH 13/32] blacklisting for scripts in OpenMW --- apps/openmw/engine.cpp | 14 ++++++++++++- apps/openmw/engine.hpp | 6 ++++++ apps/openmw/main.cpp | 20 ++++++++++++++----- apps/openmw/mwscript/scriptmanagerimp.cpp | 24 ++++++++++++++++++----- apps/openmw/mwscript/scriptmanagerimp.hpp | 4 +++- files/openmw.cfg | 1 + files/openmw.cfg.local | 1 + 7 files changed, 58 insertions(+), 12 deletions(-) diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index f8b4c9856..66eae5f5d 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -180,6 +180,7 @@ OMW::Engine::Engine(Files::ConfigurationManager& configurationManager) , mEncoder(NULL) , mActivationDistanceOverride(-1) , mGrab(true) + , mScriptBlacklistUse (true) { std::srand ( std::time(NULL) ); @@ -406,7 +407,8 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings) mScriptContext->setExtensions (&mExtensions); mEnvironment.setScriptManager (new MWScript::ScriptManager (MWBase::Environment::get().getWorld()->getStore(), - mVerboseScripts, *mScriptContext, mWarningsMode)); + mVerboseScripts, *mScriptContext, mWarningsMode, + mScriptBlacklistUse ? mScriptBlacklist : std::vector())); // Create game mechanics system MWMechanics::MechanicsManager* mechanics = new MWMechanics::MechanicsManager; @@ -565,3 +567,13 @@ void OMW::Engine::setWarningsMode (int mode) { mWarningsMode = mode; } + +void OMW::Engine::setScriptBlacklist (const std::vector& list) +{ + mScriptBlacklist = list; +} + +void OMW::Engine::setScriptBlacklistUse (bool use) +{ + mScriptBlacklistUse = use; +} \ No newline at end of file diff --git a/apps/openmw/engine.hpp b/apps/openmw/engine.hpp index e0f51d0dc..203379a93 100644 --- a/apps/openmw/engine.hpp +++ b/apps/openmw/engine.hpp @@ -89,6 +89,8 @@ namespace OMW Files::Collections mFileCollections; bool mFSStrict; Translation::Storage mTranslationDataStorage; + std::vector mScriptBlacklist; + bool mScriptBlacklistUse; // not implemented Engine (const Engine&); @@ -181,6 +183,10 @@ namespace OMW void setWarningsMode (int mode); + void setScriptBlacklist (const std::vector& list); + + void setScriptBlacklistUse (bool use); + private: Files::ConfigurationManager& mCfgMgr; }; diff --git a/apps/openmw/main.cpp b/apps/openmw/main.cpp index adde408b9..8cdab74d8 100644 --- a/apps/openmw/main.cpp +++ b/apps/openmw/main.cpp @@ -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" "\t2 - treat warnings as errors") + ("script-blacklist", bpo::value()->default_value(StringsVector(), "") + ->multitoken(), "ignore the specified script (if the use of the blacklist is enabled)") + + ("script-blacklist-use", bpo::value()->implicit_value(true) + ->default_value(true), "enable script blacklisting") + ("skip-menu", bpo::value()->implicit_value(true) ->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()); engine.setSkipMenu (variables["skip-menu"].as()); - // other settings - engine.setSoundUsage(!variables["no-sound"].as()); - engine.setScriptsVerbosity(variables["script-verbose"].as()); + // scripts engine.setCompileAll(variables["script-all"].as()); - engine.setFallbackValues(variables["fallback"].as().mMap); + engine.setScriptsVerbosity(variables["script-verbose"].as()); engine.setScriptConsoleMode (variables["script-console"].as()); engine.setStartupScript (variables["script-run"].as()); - engine.setActivationDistanceOverride (variables["activate-dist"].as()); engine.setWarningsMode (variables["script-warn"].as()); + engine.setScriptBlacklist (variables["script-blacklist"].as()); + engine.setScriptBlacklistUse (variables["script-blacklist-use"].as()); + + // other settings + engine.setSoundUsage(!variables["no-sound"].as()); + engine.setFallbackValues(variables["fallback"].as().mMap); + engine.setActivationDistanceOverride (variables["activate-dist"].as()); return true; } diff --git a/apps/openmw/mwscript/scriptmanagerimp.cpp b/apps/openmw/mwscript/scriptmanagerimp.cpp index 7b858dacf..781c16299 100644 --- a/apps/openmw/mwscript/scriptmanagerimp.cpp +++ b/apps/openmw/mwscript/scriptmanagerimp.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include @@ -22,12 +23,19 @@ namespace MWScript { ScriptManager::ScriptManager (const MWWorld::ESMStore& store, bool verbose, - Compiler::Context& compilerContext, int warningsMode) + Compiler::Context& compilerContext, int warningsMode, + const std::vector& scriptBlacklist) : mErrorHandler (std::cerr), mStore (store), mVerbose (verbose), mCompilerContext (compilerContext), mParser (mErrorHandler, mCompilerContext), mOpcodesInstalled (false), mGlobalScripts (store) { 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) @@ -133,11 +141,17 @@ namespace MWScript int success = 0; const MWWorld::Store& scripts = mStore.get(); - MWWorld::Store::iterator it = scripts.begin(); - for (; it != scripts.end(); ++it, ++count) - if (compile (it->mId)) - ++success; + for (MWWorld::Store::iterator iter = scripts.begin(); + iter != scripts.end(); ++iter) + if (!std::binary_search (mScriptBlacklist.begin(), mScriptBlacklist.end(), + Misc::StringUtils::lowerCase (iter->mId))) + { + ++count; + + if (compile (iter->mId)) + ++success; + } return std::make_pair (count, success); } diff --git a/apps/openmw/mwscript/scriptmanagerimp.hpp b/apps/openmw/mwscript/scriptmanagerimp.hpp index da3abc60b..4edc09eca 100644 --- a/apps/openmw/mwscript/scriptmanagerimp.hpp +++ b/apps/openmw/mwscript/scriptmanagerimp.hpp @@ -48,11 +48,13 @@ namespace MWScript ScriptCollection mScripts; GlobalScripts mGlobalScripts; std::map mOtherLocals; + std::vector mScriptBlacklist; public: ScriptManager (const MWWorld::ESMStore& store, bool verbose, - Compiler::Context& compilerContext, int warningsMode); + Compiler::Context& compilerContext, int warningsMode, + const std::vector& scriptBlacklist); virtual void run (const std::string& name, Interpreter::Context& interpreterContext); ///< Run the script with the given name (compile first, if not compiled yet) diff --git a/files/openmw.cfg b/files/openmw.cfg index b67b79a96..4ebe287d5 100644 --- a/files/openmw.cfg +++ b/files/openmw.cfg @@ -2,3 +2,4 @@ data="?global?data" data="?mw?Data Files" data-local="?userdata?data" resources=${OPENMW_RESOURCE_FILES} +script-blacklist=Museum diff --git a/files/openmw.cfg.local b/files/openmw.cfg.local index 6a578542d..4ae51382e 100644 --- a/files/openmw.cfg.local +++ b/files/openmw.cfg.local @@ -3,3 +3,4 @@ data="?mw?Data Files" data=./data data-local="?userdata?data" resources=./resources +script-blacklist=Museum From a9f9dec923927934c3adc9772b963cedd28e3874 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 21 Jul 2014 12:15:21 +0200 Subject: [PATCH 14/32] consider script blacklist in OpenCS verifier --- apps/opencs/CMakeLists.txt | 2 +- apps/opencs/editor.cpp | 10 +++++++- apps/opencs/model/doc/blacklist.cpp | 31 +++++++++++++++++++++++ apps/opencs/model/doc/blacklist.hpp | 25 ++++++++++++++++++ apps/opencs/model/doc/document.cpp | 14 ++++++++-- apps/opencs/model/doc/document.hpp | 7 ++++- apps/opencs/model/doc/documentmanager.cpp | 7 ++++- apps/opencs/model/doc/documentmanager.hpp | 3 +++ apps/opencs/model/tools/scriptcheck.cpp | 21 ++++++++++----- apps/opencs/model/tools/scriptcheck.hpp | 9 +++++-- apps/opencs/model/tools/tools.cpp | 6 +++-- apps/opencs/model/tools/tools.hpp | 4 ++- 12 files changed, 122 insertions(+), 17 deletions(-) create mode 100644 apps/opencs/model/doc/blacklist.cpp create mode 100644 apps/opencs/model/doc/blacklist.hpp diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index c03cc3138..e1e467889 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -9,7 +9,7 @@ opencs_units (model/doc ) opencs_units_noqt (model/doc - stage savingstate savingstages + stage savingstate savingstages blacklist ) opencs_hdrs_noqt (model/doc diff --git a/apps/opencs/editor.cpp b/apps/opencs/editor.cpp index b3513a7f1..44d66b236 100644 --- a/apps/opencs/editor.cpp +++ b/apps/opencs/editor.cpp @@ -86,7 +86,11 @@ std::pair > CS::Editor::readConfi ("encoding", boost::program_options::value()->default_value("win1252")) ("resources", boost::program_options::value()->default_value("resources")) ("fallback-archive", boost::program_options::value >()-> - default_value(std::vector(), "fallback-archive")->multitoken()); + default_value(std::vector(), "fallback-archive")->multitoken()) + ("script-blacklist", boost::program_options::value >()->default_value(std::vector(), "") + ->multitoken(), "exclude specified script from the verifier (if the use of the blacklist is enabled)") + ("script-blacklist-use", boost::program_options::value()->implicit_value(true) + ->default_value(true), "enable script blacklisting"); boost::program_options::notify(variables); @@ -97,6 +101,10 @@ std::pair > CS::Editor::readConfi mDocumentManager.setResourceDir (mResources = variables["resources"].as()); + if (variables["script-blacklist-use"].as()) + mDocumentManager.setBlacklistedScripts ( + variables["script-blacklist"].as >()); + mFsStrict = variables["fs-strict"].as(); Files::PathContainer dataDirs, dataLocal; diff --git a/apps/opencs/model/doc/blacklist.cpp b/apps/opencs/model/doc/blacklist.cpp new file mode 100644 index 000000000..9b37a4302 --- /dev/null +++ b/apps/opencs/model/doc/blacklist.cpp @@ -0,0 +1,31 @@ + +#include "blacklist.hpp" + +#include + +#include + +bool CSMDoc::Blacklist::isBlacklisted (const CSMWorld::UniversalId& id) const +{ + std::map >::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& ids) +{ + std::vector& 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()); +} \ No newline at end of file diff --git a/apps/opencs/model/doc/blacklist.hpp b/apps/opencs/model/doc/blacklist.hpp new file mode 100644 index 000000000..9bf7f1d86 --- /dev/null +++ b/apps/opencs/model/doc/blacklist.hpp @@ -0,0 +1,25 @@ +#ifndef CSM_DOC_BLACKLIST_H +#define CSM_DOC_BLACKLIST_H + +#include +#include +#include + +#include "../world/universalid.hpp" + +namespace CSMDoc +{ + /// \brief ID blacklist sorted by UniversalId type + class Blacklist + { + std::map > mIds; + + public: + + bool isBlacklisted (const CSMWorld::UniversalId& id) const; + + void add (CSMWorld::UniversalId::Type type, const std::vector& ids); + }; +} + +#endif diff --git a/apps/opencs/model/doc/document.cpp b/apps/opencs/model/doc/document.cpp index 23a47b313..c608757e0 100644 --- a/apps/opencs/model/doc/document.cpp +++ b/apps/opencs/model/doc/document.cpp @@ -2205,9 +2205,10 @@ void CSMDoc::Document::createBase() CSMDoc::Document::Document (const Files::ConfigurationManager& configuration, const std::vector< boost::filesystem::path >& files, bool new_, 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& blacklistedScripts) : mSavePath (savePath), mContentFiles (files), mNew (new_), mData (encoding, resourcesManager), - mTools (mData), mResDir(resDir), + mTools (*this), mResDir(resDir), mProjectPath ((configuration.getUserDataPath() / "projects") / (savePath.filename().string() + ".project")), mSaving (*this, mProjectPath, encoding) @@ -2239,6 +2240,8 @@ CSMDoc::Document::Document (const Files::ConfigurationManager& configuration, createBase(); } + mBlacklist.add (CSMWorld::UniversalId::Type_Script, blacklistedScripts); + addOptionalGmsts(); addOptionalGlobals(); @@ -2358,6 +2361,13 @@ CSMTools::ReportModel *CSMDoc::Document::getReport (const CSMWorld::UniversalId& 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) { emit progress (current, max, type, 1, this); diff --git a/apps/opencs/model/doc/document.hpp b/apps/opencs/model/doc/document.hpp index d092b47c8..d0e94d5e0 100644 --- a/apps/opencs/model/doc/document.hpp +++ b/apps/opencs/model/doc/document.hpp @@ -17,6 +17,7 @@ #include "state.hpp" #include "saving.hpp" +#include "blacklist.hpp" class QAbstractItemModel; @@ -52,6 +53,7 @@ namespace CSMDoc boost::filesystem::path mProjectPath; Saving mSaving; 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 // 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, const std::vector< boost::filesystem::path >& files, bool new_, 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& blacklistedScripts); ~Document(); @@ -110,6 +113,8 @@ namespace CSMDoc CSMTools::ReportModel *getReport (const CSMWorld::UniversalId& id); ///< The ownership of the returned report is not transferred. + bool isBlacklisted (const CSMWorld::UniversalId& id) const; + signals: void stateChanged (int state, CSMDoc::Document *document); diff --git a/apps/opencs/model/doc/documentmanager.cpp b/apps/opencs/model/doc/documentmanager.cpp index 6953db0ed..9b807225c 100644 --- a/apps/opencs/model/doc/documentmanager.cpp +++ b/apps/opencs/model/doc/documentmanager.cpp @@ -52,7 +52,7 @@ CSMDoc::DocumentManager::~DocumentManager() void CSMDoc::DocumentManager::addDocument (const std::vector& files, const boost::filesystem::path& savePath, 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); @@ -85,6 +85,11 @@ void CSMDoc::DocumentManager::setEncoding (ToUTF8::FromType encoding) mEncoding = encoding; } +void CSMDoc::DocumentManager::setBlacklistedScripts (const std::vector& scriptIds) +{ + mBlacklistedScripts = scriptIds; +} + void CSMDoc::DocumentManager::listResources() { mResourcesManager.listResources(); diff --git a/apps/opencs/model/doc/documentmanager.hpp b/apps/opencs/model/doc/documentmanager.hpp index cebae6f6d..c545b9a9f 100644 --- a/apps/opencs/model/doc/documentmanager.hpp +++ b/apps/opencs/model/doc/documentmanager.hpp @@ -34,6 +34,7 @@ namespace CSMDoc Loader mLoader; ToUTF8::FromType mEncoding; CSMWorld::ResourcesManager mResourcesManager; + std::vector mBlacklistedScripts; DocumentManager (const DocumentManager&); DocumentManager& operator= (const DocumentManager&); @@ -53,6 +54,8 @@ namespace CSMDoc void setEncoding (ToUTF8::FromType encoding); + void setBlacklistedScripts (const std::vector& scriptIds); + /// Ask OGRE for a list of available resources. void listResources(); diff --git a/apps/opencs/model/tools/scriptcheck.cpp b/apps/opencs/model/tools/scriptcheck.cpp index b989e22a2..d2c647bda 100644 --- a/apps/opencs/model/tools/scriptcheck.cpp +++ b/apps/opencs/model/tools/scriptcheck.cpp @@ -7,6 +7,8 @@ #include #include +#include "../doc/document.hpp" + #include "../world/data.hpp" 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)); } -CSMTools::ScriptCheckStage::ScriptCheckStage (const CSMWorld::Data& data) -: mData (data), mContext (data), mMessages (0) +CSMTools::ScriptCheckStage::ScriptCheckStage (const CSMDoc::Document& document) +: mDocument (document), mContext (document.getData()), mMessages (0) { /// \todo add an option to configure warning mode setWarningsMode (0); @@ -53,18 +55,25 @@ int CSMTools::ScriptCheckStage::setup() mMessages = 0; mId.clear(); - return mData.getScripts().getSize(); + return mDocument.getData().getScripts().getSize(); } 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; - mId = mData.getScripts().getId (stage); try { - mFile = mData.getScripts().getRecord (stage).get().mId; - std::istringstream input (mData.getScripts().getRecord (stage).get().mScriptText); + const CSMWorld::Data& data = mDocument.getData(); + + mFile = data.getScripts().getRecord (stage).get().mId; + std::istringstream input (data.getScripts().getRecord (stage).get().mScriptText); Compiler::Scanner scanner (*this, input, mContext.getExtensions()); diff --git a/apps/opencs/model/tools/scriptcheck.hpp b/apps/opencs/model/tools/scriptcheck.hpp index ecf8d61b7..75f11b9d4 100644 --- a/apps/opencs/model/tools/scriptcheck.hpp +++ b/apps/opencs/model/tools/scriptcheck.hpp @@ -8,12 +8,17 @@ #include "../world/scriptcontext.hpp" +namespace CSMDoc +{ + class Document; +} + namespace CSMTools { /// \brief VerifyStage: make sure that scripts compile class ScriptCheckStage : public CSMDoc::Stage, private Compiler::ErrorHandler { - const CSMWorld::Data& mData; + const CSMDoc::Document& mDocument; Compiler::Extensions mExtensions; CSMWorld::ScriptContext mContext; std::string mId; @@ -28,7 +33,7 @@ namespace CSMTools public: - ScriptCheckStage (const CSMWorld::Data& data); + ScriptCheckStage (const CSMDoc::Document& document); virtual int setup(); ///< \return number of steps diff --git a/apps/opencs/model/tools/tools.cpp b/apps/opencs/model/tools/tools.cpp index 2f93db48e..fcf98868a 100644 --- a/apps/opencs/model/tools/tools.cpp +++ b/apps/opencs/model/tools/tools.cpp @@ -5,6 +5,7 @@ #include "../doc/state.hpp" #include "../doc/operation.hpp" +#include "../doc/document.hpp" #include "../world/data.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 ScriptCheckStage (mData)); + mVerifier->appendStage (new ScriptCheckStage (mDocument)); } 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 mReports.insert (std::make_pair (mNextReportNumber++, new ReportModel)); diff --git a/apps/opencs/model/tools/tools.hpp b/apps/opencs/model/tools/tools.hpp index 3394d3f62..4d677142d 100644 --- a/apps/opencs/model/tools/tools.hpp +++ b/apps/opencs/model/tools/tools.hpp @@ -14,6 +14,7 @@ namespace CSMWorld namespace CSMDoc { class Operation; + class Document; } namespace CSMTools @@ -24,6 +25,7 @@ namespace CSMTools { Q_OBJECT + CSMDoc::Document& mDocument; CSMWorld::Data& mData; CSMDoc::Operation *mVerifier; std::map mReports; @@ -44,7 +46,7 @@ namespace CSMTools public: - Tools (CSMWorld::Data& data); + Tools (CSMDoc::Document& document); virtual ~Tools(); From 11a2c767cc474a3a8c1f3b831d5a67b7e7449c72 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 21 Jul 2014 12:50:29 +0200 Subject: [PATCH 15/32] some argument parsing cleanup --- components/compiler/exprparser.cpp | 30 +++++++++++++++++++----------- components/compiler/extensions.hpp | 2 +- 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/components/compiler/exprparser.cpp b/components/compiler/exprparser.cpp index d0cda0ec2..6e29626b1 100644 --- a/components/compiler/exprparser.cpp +++ b/components/compiler/exprparser.cpp @@ -777,11 +777,22 @@ namespace Compiler ++optionalCount; } } + else if (*iter=='X') + { + parser.reset(); + + parser.setOptional (true); + + scanner.scan (parser); + + if (optional && parser.isEmpty()) + break; + } else { parser.reset(); - if (optional || *iter == 'X') + if (optional) parser.setOptional (true); scanner.scan (parser); @@ -789,20 +800,17 @@ namespace Compiler if (optional && parser.isEmpty()) break; - if (*iter != 'X') - { - std::vector tmp; + std::vector tmp; - char type = parser.append (tmp); + char type = parser.append (tmp); - if (type!=*iter) - Generator::convert (tmp, type, *iter); + if (type!=*iter) + Generator::convert (tmp, type, *iter); - stack.push (tmp); + stack.push (tmp); - if (optional) - ++optionalCount; - } + if (optional) + ++optionalCount; } } diff --git a/components/compiler/extensions.hpp b/components/compiler/extensions.hpp index d229751de..aa62fd0eb 100644 --- a/components/compiler/extensions.hpp +++ b/components/compiler/extensions.hpp @@ -21,7 +21,7 @@ namespace Compiler s - Short
S - String, case preserved
x - Optional, ignored string argument - X - Optional, ignored integer argument + X - Optional, ignored float argument **/ typedef std::string ScriptArgs; From aa8c0bccb4b8c304bcdef0cbdda0f808aa31d437 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Wed, 23 Jul 2014 09:44:29 +0200 Subject: [PATCH 16/32] added new argument type: z (optional, any) --- components/CMakeLists.txt | 2 +- components/compiler/discardparser.cpp | 70 +++++++++++++++++++++++++++ components/compiler/discardparser.hpp | 45 +++++++++++++++++ components/compiler/exprparser.cpp | 14 +++++- components/compiler/extensions.hpp | 3 +- 5 files changed, 131 insertions(+), 3 deletions(-) create mode 100644 components/compiler/discardparser.cpp create mode 100644 components/compiler/discardparser.hpp diff --git a/components/CMakeLists.txt b/components/CMakeLists.txt index b8ebb84b1..a9bd376a9 100644 --- a/components/CMakeLists.txt +++ b/components/CMakeLists.txt @@ -58,7 +58,7 @@ add_component_dir (compiler context controlparser errorhandler exception exprparser extensions fileparser generator lineparser literals locals output parser scanner scriptparser skipparser streamerrorhandler stringparser tokenloc nullerrorhandler opcodes extensions0 declarationparser - quickfileparser + quickfileparser discardparser ) add_component_dir (interpreter diff --git a/components/compiler/discardparser.cpp b/components/compiler/discardparser.cpp new file mode 100644 index 000000000..6028968bb --- /dev/null +++ b/components/compiler/discardparser.cpp @@ -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(); + } +} diff --git a/components/compiler/discardparser.hpp b/components/compiler/discardparser.hpp new file mode 100644 index 000000000..bee8a87bb --- /dev/null +++ b/components/compiler/discardparser.hpp @@ -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 + diff --git a/components/compiler/exprparser.cpp b/components/compiler/exprparser.cpp index 6e29626b1..d94f6c436 100644 --- a/components/compiler/exprparser.cpp +++ b/components/compiler/exprparser.cpp @@ -16,6 +16,7 @@ #include "stringparser.hpp" #include "extensions.hpp" #include "context.hpp" +#include "discardparser.hpp" namespace Compiler { @@ -743,6 +744,7 @@ namespace Compiler ExprParser parser (getErrorHandler(), getContext(), mLocals, mLiterals, true); StringParser stringParser (getErrorHandler(), getContext(), mLiterals); + DiscardParser discardParser (getErrorHandler(), getContext()); std::stack > stack; @@ -785,7 +787,17 @@ namespace Compiler scanner.scan (parser); - if (optional && parser.isEmpty()) + if (parser.isEmpty()) + break; + } + else if (*iter=='z') + { + discardParser.reset(); + discardParser.setOptional (true); + + scanner.scan (discardParser); + + if (discardParser.isEmpty()) break; } else diff --git a/components/compiler/extensions.hpp b/components/compiler/extensions.hpp index aa62fd0eb..a15218d99 100644 --- a/components/compiler/extensions.hpp +++ b/components/compiler/extensions.hpp @@ -21,7 +21,8 @@ namespace Compiler s - Short
S - String, case preserved
x - Optional, ignored string argument - X - Optional, ignored float argument + X - Optional, ignored numeric expression + z - Optional, ignored string or numeric argument **/ typedef std::string ScriptArgs; From 19f4c46fe4eac193e0423dca48803f7b48af301e Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Wed, 23 Jul 2014 12:33:35 +0200 Subject: [PATCH 17/32] alllow (and ignore) explicit references for StopScript and ScriptRunning --- components/compiler/exprparser.cpp | 15 +++++++++++++++ components/compiler/lineparser.cpp | 7 +++++++ 2 files changed, 22 insertions(+) diff --git a/components/compiler/exprparser.cpp b/components/compiler/exprparser.cpp index d94f6c436..6dcca08df 100644 --- a/components/compiler/exprparser.cpp +++ b/components/compiler/exprparser.cpp @@ -408,6 +408,21 @@ namespace Compiler mNextOperand = false; 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 if (const Extensions *extensions = getContext().getExtensions()) diff --git a/components/compiler/lineparser.cpp b/components/compiler/lineparser.cpp index b1b831bc2..cdbfaa04a 100644 --- a/components/compiler/lineparser.cpp +++ b/components/compiler/lineparser.cpp @@ -269,6 +269,13 @@ namespace Compiler 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 From f55084463b47cb3bee1d420f7badee83de0f710f Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Wed, 23 Jul 2014 12:35:15 +0200 Subject: [PATCH 18/32] added MockChangeScript to script blacklist --- files/openmw.cfg | 1 + files/openmw.cfg.local | 1 + 2 files changed, 2 insertions(+) diff --git a/files/openmw.cfg b/files/openmw.cfg index 4ebe287d5..de1f22e50 100644 --- a/files/openmw.cfg +++ b/files/openmw.cfg @@ -3,3 +3,4 @@ data="?mw?Data Files" data-local="?userdata?data" resources=${OPENMW_RESOURCE_FILES} script-blacklist=Museum +script-blacklist=MockChangeScript \ No newline at end of file diff --git a/files/openmw.cfg.local b/files/openmw.cfg.local index 4ae51382e..b2970fb19 100644 --- a/files/openmw.cfg.local +++ b/files/openmw.cfg.local @@ -4,3 +4,4 @@ data=./data data-local="?userdata?data" resources=./resources script-blacklist=Museum +script-blacklist=MockChangeScript From 2e355df8b31a60a1c72b0b837c895caf0b0c8714 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 25 Jul 2014 07:59:50 +0200 Subject: [PATCH 19/32] removed function ScriptManager::getLocalIndex (was redundant and was also depending on precompiled scripts) --- apps/openmw/mwbase/scriptmanager.hpp | 8 +-- apps/openmw/mwscript/interpretercontext.cpp | 60 ++++++++++++--------- apps/openmw/mwscript/interpretercontext.hpp | 4 ++ apps/openmw/mwscript/scriptmanagerimp.cpp | 42 --------------- apps/openmw/mwscript/scriptmanagerimp.hpp | 5 -- components/compiler/locals.hpp | 6 ++- 6 files changed, 45 insertions(+), 80 deletions(-) diff --git a/apps/openmw/mwbase/scriptmanager.hpp b/apps/openmw/mwbase/scriptmanager.hpp index ae146e064..1a9eee456 100644 --- a/apps/openmw/mwbase/scriptmanager.hpp +++ b/apps/openmw/mwbase/scriptmanager.hpp @@ -50,13 +50,7 @@ namespace MWBase ///< Return locals for script \a name. 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. - - }; + }; } #endif diff --git a/apps/openmw/mwscript/interpretercontext.cpp b/apps/openmw/mwscript/interpretercontext.cpp index e1dc6273c..121b07e34 100644 --- a/apps/openmw/mwscript/interpretercontext.cpp +++ b/apps/openmw/mwscript/interpretercontext.cpp @@ -3,8 +3,12 @@ #include #include +#include #include + +#include + #include "../mwworld/esmstore.hpp" #include "../mwbase/environment.hpp" @@ -103,6 +107,32 @@ 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 ( MWScript::Locals *locals, MWWorld::Ptr reference, const std::string& targetId) : mLocals (locals), mReference (reference), @@ -485,10 +515,7 @@ namespace MWScript const Locals& locals = getMemberLocals (scriptId, global); - int index = MWBase::Environment::get().getScriptManager()->getLocalIndex ( - scriptId, name, 's'); - - return locals.mShorts[index]; + return locals.mShorts[findLocalVariableIndex (scriptId, name, 's')]; } int InterpreterContext::getMemberLong (const std::string& id, const std::string& name, @@ -498,10 +525,7 @@ namespace MWScript const Locals& locals = getMemberLocals (scriptId, global); - int index = MWBase::Environment::get().getScriptManager()->getLocalIndex ( - scriptId, name, 'l'); - - return locals.mLongs[index]; + return locals.mLongs[findLocalVariableIndex (scriptId, name, 'l')]; } float InterpreterContext::getMemberFloat (const std::string& id, const std::string& name, @@ -511,10 +535,7 @@ namespace MWScript const Locals& locals = getMemberLocals (scriptId, global); - int index = MWBase::Environment::get().getScriptManager()->getLocalIndex ( - scriptId, name, 'f'); - - return locals.mFloats[index]; + return locals.mFloats[findLocalVariableIndex (scriptId, name, 'f')]; } void InterpreterContext::setMemberShort (const std::string& id, const std::string& name, @@ -524,10 +545,7 @@ namespace MWScript Locals& locals = getMemberLocals (scriptId, global); - int index = - MWBase::Environment::get().getScriptManager()->getLocalIndex (scriptId, name, 's'); - - locals.mShorts[index] = value; + locals.mShorts[findLocalVariableIndex (scriptId, name, 's')] = value; } void InterpreterContext::setMemberLong (const std::string& id, const std::string& name, int value, bool global) @@ -536,10 +554,7 @@ namespace MWScript Locals& locals = getMemberLocals (scriptId, global); - int index = - MWBase::Environment::get().getScriptManager()->getLocalIndex (scriptId, name, 'l'); - - locals.mLongs[index] = value; + locals.mLongs[findLocalVariableIndex (scriptId, name, 'l')] = value; } void InterpreterContext::setMemberFloat (const std::string& id, const std::string& name, float value, bool global) @@ -548,10 +563,7 @@ namespace MWScript Locals& locals = getMemberLocals (scriptId, global); - int index = - MWBase::Environment::get().getScriptManager()->getLocalIndex (scriptId, name, 'f'); - - locals.mFloats[index] = value; + locals.mFloats[findLocalVariableIndex (scriptId, name, 'f')] = value; } MWWorld::Ptr InterpreterContext::getReference(bool required) diff --git a/apps/openmw/mwscript/interpretercontext.hpp b/apps/openmw/mwscript/interpretercontext.hpp index f897282e2..bc43f3e44 100644 --- a/apps/openmw/mwscript/interpretercontext.hpp +++ b/apps/openmw/mwscript/interpretercontext.hpp @@ -50,6 +50,10 @@ namespace MWScript 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 + /// Throws an exception if local variable can't be found. + int findLocalVariableIndex (const std::string& scriptId, const std::string& name, + char type) const; + public: InterpreterContext (MWScript::Locals *locals, MWWorld::Ptr reference, diff --git a/apps/openmw/mwscript/scriptmanagerimp.cpp b/apps/openmw/mwscript/scriptmanagerimp.cpp index 781c16299..289fd9a70 100644 --- a/apps/openmw/mwscript/scriptmanagerimp.cpp +++ b/apps/openmw/mwscript/scriptmanagerimp.cpp @@ -196,46 +196,4 @@ namespace MWScript { return mGlobalScripts; } - - int ScriptManager::getLocalIndex (const std::string& scriptId, const std::string& variable, - char type) - { - const ESM::Script *script = mStore.get().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; imVarNames.at (i+offset))==variable2) - return i; - - throw std::runtime_error ("unable to access local variable " + variable + " of " + scriptId); - } } diff --git a/apps/openmw/mwscript/scriptmanagerimp.hpp b/apps/openmw/mwscript/scriptmanagerimp.hpp index 4edc09eca..7b1121aca 100644 --- a/apps/openmw/mwscript/scriptmanagerimp.hpp +++ b/apps/openmw/mwscript/scriptmanagerimp.hpp @@ -71,11 +71,6 @@ namespace MWScript ///< Return locals for script \a name. 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. }; } diff --git a/components/compiler/locals.hpp b/components/compiler/locals.hpp index d5bf05253..cf7899b5c 100644 --- a/components/compiler/locals.hpp +++ b/components/compiler/locals.hpp @@ -17,8 +17,6 @@ namespace Compiler int searchIndex (char type, const std::string& name) const; - bool search (char type, const std::string& name) const; - std::vector& get (char type); public: @@ -29,6 +27,10 @@ namespace Compiler 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 of type \a type (-1: variable does not + /// exit). + bool search (char type, const std::string& name) const; + const std::vector& get (char type) const; void write (std::ostream& localFile) const; From 9f69db0d69538add19a714391e825c01a7254da2 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 25 Jul 2014 08:12:53 +0200 Subject: [PATCH 20/32] added missing const to ScriptManager::getLocals --- apps/openmw/mwbase/scriptmanager.hpp | 2 +- apps/openmw/mwscript/scriptmanagerimp.cpp | 2 +- apps/openmw/mwscript/scriptmanagerimp.hpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/openmw/mwbase/scriptmanager.hpp b/apps/openmw/mwbase/scriptmanager.hpp index 1a9eee456..7bdeba132 100644 --- a/apps/openmw/mwbase/scriptmanager.hpp +++ b/apps/openmw/mwbase/scriptmanager.hpp @@ -46,7 +46,7 @@ namespace MWBase ///< Compile all scripts /// \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. virtual MWScript::GlobalScripts& getGlobalScripts() = 0; diff --git a/apps/openmw/mwscript/scriptmanagerimp.cpp b/apps/openmw/mwscript/scriptmanagerimp.cpp index 289fd9a70..5af214268 100644 --- a/apps/openmw/mwscript/scriptmanagerimp.cpp +++ b/apps/openmw/mwscript/scriptmanagerimp.cpp @@ -156,7 +156,7 @@ namespace MWScript 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); diff --git a/apps/openmw/mwscript/scriptmanagerimp.hpp b/apps/openmw/mwscript/scriptmanagerimp.hpp index 7b1121aca..6026f6aba 100644 --- a/apps/openmw/mwscript/scriptmanagerimp.hpp +++ b/apps/openmw/mwscript/scriptmanagerimp.hpp @@ -67,7 +67,7 @@ namespace MWScript ///< Compile all scripts /// \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. virtual GlobalScripts& getGlobalScripts(); From f6b502b195f508e12db8491a0c29b0db72820081 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 25 Jul 2014 09:05:17 +0200 Subject: [PATCH 21/32] rewrote dialgoue filter access to local variables --- apps/openmw/mwdialogue/filter.cpp | 52 ++++++++++++------------------- 1 file changed, 20 insertions(+), 32 deletions(-) diff --git a/apps/openmw/mwdialogue/filter.cpp b/apps/openmw/mwdialogue/filter.cpp index 08cdb1d00..b7f91613a 100644 --- a/apps/openmw/mwdialogue/filter.cpp +++ b/apps/openmw/mwdialogue/filter.cpp @@ -1,11 +1,14 @@ #include "filter.hpp" +#include + #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" #include "../mwbase/journal.hpp" #include "../mwbase/mechanicsmanager.hpp" #include "../mwbase/dialoguemanager.hpp" +#include "../mwbase/scriptmanager.hpp" #include "../mwworld/class.hpp" #include "../mwworld/inventorystore.hpp" @@ -187,33 +190,28 @@ bool MWDialogue::Filter::testSelectStructNumeric (const SelectWrapper& select) c if (scriptName.empty()) return false; // no script - const ESM::Script *script = - MWBase::Environment::get().getWorld()->getStore().get().find (scriptName); + std::string name = Misc::StringUtils::lowerCase (select.getName()); - 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 (script->mVarNames.size()); ++i) - if (Misc::StringUtils::ciEqual(script->mVarNames[i], name)) - break; + if (type==' ') + return false; // script does not have a variable of this name. - if (i>=static_cast (script->mVarNames.size())) - return false; // script does not have a variable of this name + int index = localDefs.getIndex (name); const MWScript::Locals& locals = mActor.getRefData().getLocals(); - if (imData.mNumShorts) - return select.selectCompare (static_cast (locals.mShorts[i])); + switch (type) + { + case 's': return select.selectCompare (static_cast (locals.mShorts[index])); + case 'l': return select.selectCompare (locals.mLongs[index]); + case 'f': return select.selectCompare (locals.mFloats[index]); + } - i -= script->mData.mNumShorts; - - if (imData.mNumLongs) - return select.selectCompare (locals.mLongs[i]); - - i -= script->mData.mNumLongs; - - return select.selectCompare (locals.mFloats.at (i)); + throw std::logic_error ("unknown local variable type in dialogue filter"); } case SelectWrapper::Function_PcHealthPercent: @@ -453,20 +451,10 @@ bool MWDialogue::Filter::getSelectStructBoolean (const SelectWrapper& select) co // This actor has no attached script, so there is no local variable return true; - const ESM::Script *script = - MWBase::Environment::get().getWorld()->getStore().get().find (scriptName); + const Compiler::Locals& localDefs = + MWBase::Environment::get().getScriptManager()->getLocals (scriptName); - std::string name = select.getName(); - - int i = 0; - for (; i < static_cast (script->mVarNames.size()); ++i) - if (Misc::StringUtils::ciEqual(script->mVarNames[i], name)) - break; - - if (i >= static_cast (script->mVarNames.size())) - return true; // script does not have a variable of this name - - return false; + return localDefs.getIndex (Misc::StringUtils::lowerCase (select.getName()))==-1; } case SelectWrapper::Function_SameGender: From 87c54adb2460fa1028aae89c3a7cca52a154ebbe Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 25 Jul 2014 09:26:30 +0200 Subject: [PATCH 22/32] some cleanup --- apps/openmw/mwscript/locals.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwscript/locals.cpp b/apps/openmw/mwscript/locals.cpp index 57584ac30..6a8a857d8 100644 --- a/apps/openmw/mwscript/locals.cpp +++ b/apps/openmw/mwscript/locals.cpp @@ -29,7 +29,7 @@ namespace MWScript 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); char type = locals.getType(var); if(index != -1) @@ -53,7 +53,7 @@ namespace MWScript 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); char type = locals.getType(var); if(index != -1) From a3c4000198b1b970d52275ff8cdb67515158fc6a Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 25 Jul 2014 09:36:02 +0200 Subject: [PATCH 23/32] moved call to Globalscripts::addStartup out of the constructor because at the time of construction the environment may not be set up yet to perform this operation --- apps/openmw/engine.cpp | 2 ++ apps/openmw/mwscript/globalscripts.cpp | 4 +--- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index 66eae5f5d..6a48789a5 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -421,6 +421,8 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings) mOgre->getRoot()->addFrameListener (this); // scripts + mEnvironment.getScriptManager()->getGlobalScripts().addStartup(); + if (mCompileAll) { std::pair result = MWBase::Environment::get().getScriptManager()->compileAll(); diff --git a/apps/openmw/mwscript/globalscripts.cpp b/apps/openmw/mwscript/globalscripts.cpp index 0c94f503b..8270c4e6b 100644 --- a/apps/openmw/mwscript/globalscripts.cpp +++ b/apps/openmw/mwscript/globalscripts.cpp @@ -20,9 +20,7 @@ namespace MWScript GlobalScripts::GlobalScripts (const MWWorld::ESMStore& store) : mStore (store) - { - addStartup(); - } + {} void GlobalScripts::addScript (const std::string& name, const std::string& targetId) { From 1ca0cc4988caccd1ccc848dce3a2b2c8a200b606 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 25 Jul 2014 09:37:21 +0200 Subject: [PATCH 24/32] rewrote MWScript::Locals::configure to be independent of precompiled script data --- apps/openmw/mwscript/locals.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/apps/openmw/mwscript/locals.cpp b/apps/openmw/mwscript/locals.cpp index 6a8a857d8..a1ee48ae6 100644 --- a/apps/openmw/mwscript/locals.cpp +++ b/apps/openmw/mwscript/locals.cpp @@ -14,12 +14,15 @@ namespace MWScript { void Locals::configure (const ESM::Script& script) { + const Compiler::Locals& locals = + MWBase::Environment::get().getScriptManager()->getLocals (script.mId); + mShorts.clear(); - mShorts.resize (script.mData.mNumShorts, 0); + mShorts.resize (locals.get ('s').size(), 0); mLongs.clear(); - mLongs.resize (script.mData.mNumLongs, 0); + mLongs.resize (locals.get ('l').size(), 0); mFloats.clear(); - mFloats.resize (script.mData.mNumFloats, 0); + mFloats.resize (locals.get ('f').size(), 0); } bool Locals::isEmpty() const From acb728195f84f199bfa5bdd704d79819e6439f60 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 25 Jul 2014 10:37:34 +0200 Subject: [PATCH 25/32] improved documentation of ESM::Script member variables --- components/esm/loadscpt.hpp | 38 ++++++++++++------------------------- 1 file changed, 12 insertions(+), 26 deletions(-) diff --git a/components/esm/loadscpt.hpp b/components/esm/loadscpt.hpp index d5200d4c1..38160e7f4 100644 --- a/components/esm/loadscpt.hpp +++ b/components/esm/loadscpt.hpp @@ -23,29 +23,8 @@ public: struct SCHDstruct { - /* Script name. - - 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. + /// Data from script-precompling in the editor. + /// \warning Do not use them. OpenCS currently does not precompile scripts. int mNumShorts, mNumLongs, mNumFloats, mScriptDataSize, mStringTableSize; }; // 52 bytes @@ -53,9 +32,16 @@ public: SCHDstruct mData; - std::vector mVarNames; // Variable names - std::vector mScriptData; // Compiled bytecode - std::string mScriptText; // Uncompiled script + /// Variable names generated by script-precompiling in the editor. + /// \warning Do not use this field. OpenCS currently does not precompile scripts. + std::vector mVarNames; + + /// Bytecode generated from script-precompiling in the editor. + /// \warning Do not use this field. OpenCS currently does not precompile scripts. + std::vector mScriptData; + + /// Script source code + std::string mScriptText; void load(ESMReader &esm); void save(ESMWriter &esm) const; From 5e543ac8065cbeaa7625ab838176d3e76ea6d2f4 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 25 Jul 2014 11:53:30 +0200 Subject: [PATCH 26/32] added script doortestwarp to blacklist --- files/openmw.cfg | 3 ++- files/openmw.cfg.local | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/files/openmw.cfg b/files/openmw.cfg index de1f22e50..e105b6304 100644 --- a/files/openmw.cfg +++ b/files/openmw.cfg @@ -3,4 +3,5 @@ data="?mw?Data Files" data-local="?userdata?data" resources=${OPENMW_RESOURCE_FILES} script-blacklist=Museum -script-blacklist=MockChangeScript \ No newline at end of file +script-blacklist=MockChangeScript +script-blacklist=doortestwarp diff --git a/files/openmw.cfg.local b/files/openmw.cfg.local index b2970fb19..9d86174d9 100644 --- a/files/openmw.cfg.local +++ b/files/openmw.cfg.local @@ -5,3 +5,4 @@ data-local="?userdata?data" resources=./resources script-blacklist=Museum script-blacklist=MockChangeScript +script-blacklist=doortestwarp From d0654f3adefc86a82641a7435e4b84682e606600 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 25 Jul 2014 12:17:15 +0200 Subject: [PATCH 27/32] move starting of startup scripts from engine startup to new game start; also restart all startup scripts on saved game load --- apps/openmw/engine.cpp | 2 -- apps/openmw/mwstate/statemanagerimp.cpp | 5 +++++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index 6a48789a5..66eae5f5d 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -421,8 +421,6 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings) mOgre->getRoot()->addFrameListener (this); // scripts - mEnvironment.getScriptManager()->getGlobalScripts().addStartup(); - if (mCompileAll) { std::pair result = MWBase::Environment::get().getScriptManager()->compileAll(); diff --git a/apps/openmw/mwstate/statemanagerimp.cpp b/apps/openmw/mwstate/statemanagerimp.cpp index a3604cc66..b69e6b908 100644 --- a/apps/openmw/mwstate/statemanagerimp.cpp +++ b/apps/openmw/mwstate/statemanagerimp.cpp @@ -139,6 +139,9 @@ void MWState::StateManager::newGame (bool bypass) else MWBase::Environment::get().getWorld()->setGlobalInt ("chargenstate", -1); + + MWBase::Environment::get().getScriptManager()->getGlobalScripts().addStartup(); + mState = State_Running; } @@ -401,6 +404,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 MWBase::Environment::get().getWorld()->changeToCell (cellId, ptr.getRefData().getPosition(), false); + MWBase::Environment::get().getScriptManager()->getGlobalScripts().addStartup(); + // Do not trigger erroneous cellChanged events MWBase::Environment::get().getWorld()->markCellAsUnchanged(); } From af54bb96237e17066ed81ce56712fbada9353372 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 25 Jul 2014 12:23:18 +0200 Subject: [PATCH 28/32] removed some redundancies; some more general cleanup --- apps/openmw/mwstate/statemanagerimp.cpp | 7 ++----- apps/openmw/mwworld/worldimp.cpp | 4 ++-- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/apps/openmw/mwstate/statemanagerimp.cpp b/apps/openmw/mwstate/statemanagerimp.cpp index b69e6b908..96f14d7e9 100644 --- a/apps/openmw/mwstate/statemanagerimp.cpp +++ b/apps/openmw/mwstate/statemanagerimp.cpp @@ -132,16 +132,13 @@ void MWState::StateManager::newGame (bool bypass) { cleanup(); - MWBase::Environment::get().getWorld()->startNewGame (bypass); - if (!bypass) 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; } diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 386834882..98025b00e 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -211,9 +211,9 @@ namespace MWWorld // set new game mark mGlobalVariables["chargenstate"].setInteger (1); mGlobalVariables["pcrace"].setInteger (3); - - MWBase::Environment::get().getScriptManager()->getGlobalScripts().addStartup(); } + else + mGlobalVariables["chargenstate"].setInteger (-1); if (bypass && !mStartCell.empty()) { From 6a745c014fec66622bdda9759c3c6e181067d5e7 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 27 Jul 2014 11:51:53 +0200 Subject: [PATCH 29/32] workaround for incorrect argument order for PositionCell instruction --- components/compiler/errorhandler.cpp | 30 +++++++++++++++++++++++----- components/compiler/errorhandler.hpp | 21 +++++++++++++++++++ components/compiler/lineparser.cpp | 27 +++++++++++++++++++++++-- 3 files changed, 71 insertions(+), 7 deletions(-) diff --git a/components/compiler/errorhandler.cpp b/components/compiler/errorhandler.cpp index fe58836cc..bcd30ef2d 100644 --- a/components/compiler/errorhandler.cpp +++ b/components/compiler/errorhandler.cpp @@ -3,11 +3,8 @@ namespace Compiler { - // constructor - - ErrorHandler::ErrorHandler() : mWarnings (0), mErrors (0), mWarningsMode (1) {} - - // destructor + ErrorHandler::ErrorHandler() + : mWarnings (0), mErrors (0), mWarningsMode (1), mDowngradeErrors (false) {} ErrorHandler::~ErrorHandler() {} @@ -49,6 +46,12 @@ namespace Compiler void ErrorHandler::error (const std::string& message, const TokenLoc& loc) { + if (mDowngradeErrors) + { + warning (message, loc); + return; + } + ++mErrors; report (message, loc, ErrorMessage); } @@ -72,4 +75,21 @@ namespace Compiler { mWarningsMode = mode; } + + void ErrorHandler::downgradeErrors (bool downgrade) + { + mDowngradeErrors = downgrade; + } + + + ErrorDowngrade::ErrorDowngrade (ErrorHandler& handler) : mHandler (handler) + { + mHandler.downgradeErrors (true); + } + + ErrorDowngrade::~ErrorDowngrade() + { + mHandler.downgradeErrors (false); + } + } diff --git a/components/compiler/errorhandler.hpp b/components/compiler/errorhandler.hpp index e5922a6be..c92e7bb8d 100644 --- a/components/compiler/errorhandler.hpp +++ b/components/compiler/errorhandler.hpp @@ -17,6 +17,7 @@ namespace Compiler int mWarnings; int mErrors; int mWarningsMode; + bool mDowngradeErrors; protected: @@ -66,6 +67,26 @@ namespace Compiler void setWarningsMode (int mode); ///< // 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(); }; } diff --git a/components/compiler/lineparser.cpp b/components/compiler/lineparser.cpp index cdbfaa04a..2226f5845 100644 --- a/components/compiler/lineparser.cpp +++ b/components/compiler/lineparser.cpp @@ -11,6 +11,7 @@ #include "generator.hpp" #include "extensions.hpp" #include "declarationparser.hpp" +#include "exception.hpp" namespace Compiler { @@ -292,9 +293,31 @@ namespace Compiler mExplicit.clear(); } - int optionals = mExprParser.parseArguments (argumentType, scanner, mCode); + int optionals = 0; + + try + { + ErrorDowngrade errorDowngrade (getErrorHandler()); + std::vector 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; return true; } From 2abc4e42c8610d97901db3c863c50cabfa15c0a2 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 27 Jul 2014 20:49:57 +0200 Subject: [PATCH 30/32] end parsing of line after parsing a declaration --- components/compiler/lineparser.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/compiler/lineparser.cpp b/components/compiler/lineparser.cpp index 2226f5845..0a3629912 100644 --- a/components/compiler/lineparser.cpp +++ b/components/compiler/lineparser.cpp @@ -386,7 +386,7 @@ namespace Compiler if (declaration.parseKeyword (keyword, loc, scanner)) scanner.scan (declaration); - return true; + return false; } case Scanner::K_set: mState = SetState; return true; From 17bd094afd9fabc19dc3a86a6a542996805db2c8 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 27 Jul 2014 20:55:54 +0200 Subject: [PATCH 31/32] allow a few more stray arguments --- components/compiler/extensions0.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/components/compiler/extensions0.cpp b/components/compiler/extensions0.cpp index ef4fe4fbd..3945b73cc 100644 --- a/components/compiler/extensions0.cpp +++ b/components/compiler/extensions0.cpp @@ -59,7 +59,7 @@ namespace Compiler extensions.registerInstruction ("modfight", "l", opcodeModFight, opcodeModFightExplicit); extensions.registerInstruction ("modflee", "l", opcodeModFlee, opcodeModFleeExplicit); extensions.registerInstruction ("modalarm", "l", opcodeModAlarm, opcodeModAlarmExplicit); - extensions.registerInstruction ("toggleai", "", opcodeToggleAI, opcodeToggleAI); + extensions.registerInstruction ("toggleai", "X", opcodeToggleAI, opcodeToggleAI); extensions.registerInstruction ("tai", "", opcodeToggleAI, opcodeToggleAI); extensions.registerInstruction("startcombat", "c", opcodeStartCombat, opcodeStartCombatExplicit); extensions.registerInstruction("stopcombat", "x", opcodeStopCombat, opcodeStopCombatExplicit); @@ -113,12 +113,12 @@ namespace Compiler { void registerExtensions (Extensions& extensions) { - extensions.registerInstruction ("additem", "cl", opcodeAddItem, opcodeAddItemExplicit); + extensions.registerInstruction ("additem", "clxx", opcodeAddItem, opcodeAddItemExplicit); extensions.registerFunction ("getitemcount", 'l', "c", opcodeGetItemCount, opcodeGetItemCountExplicit); extensions.registerInstruction ("removeitem", "cl", opcodeRemoveItem, opcodeRemoveItemExplicit); - extensions.registerInstruction ("equip", "c", opcodeEquip, opcodeEquipExplicit); + extensions.registerInstruction ("equip", "cX", opcodeEquip, opcodeEquipExplicit); extensions.registerFunction ("getarmortype", 'l', "l", opcodeGetArmorType, opcodeGetArmorTypeExplicit); extensions.registerFunction ("hasitemequipped", 'l', "c", opcodeHasItemEquipped, opcodeHasItemEquippedExplicit); extensions.registerFunction ("hassoulgem", 'l', "c", opcodeHasSoulGem, opcodeHasSoulGemExplicit); @@ -163,7 +163,7 @@ namespace Compiler { void registerExtensions (Extensions& extensions) { - extensions.registerInstruction ("journal", "cl", opcodeJournal); + extensions.registerInstruction ("journal", "clxxX", opcodeJournal); extensions.registerInstruction ("setjournalindex", "cl", opcodeSetJournalIndex); extensions.registerFunction ("getjournalindex", 'l', "c", opcodeGetJournalIndex); extensions.registerInstruction ("addtopic", "S" , opcodeAddTopic); @@ -406,7 +406,7 @@ namespace Compiler extensions.registerInstruction ("setpccrimelevel", "f", opcodeSetPCCrimeLevel); extensions.registerInstruction ("modpccrimelevel", "f", opcodeModPCCrimeLevel); - extensions.registerInstruction ("addspell", "cxX", opcodeAddSpell, opcodeAddSpellExplicit); + extensions.registerInstruction ("addspell", "cz", opcodeAddSpell, opcodeAddSpellExplicit); extensions.registerInstruction ("removespell", "c", opcodeRemoveSpell, opcodeRemoveSpellExplicit); extensions.registerInstruction ("removespelleffects", "c", opcodeRemoveSpellEffects, From ad50b926f5a667fed85b2ef4a6b44ccad091eeb8 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 28 Jul 2014 09:01:44 +0200 Subject: [PATCH 32/32] reducing some stray arguments again --- components/compiler/extensions0.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/components/compiler/extensions0.cpp b/components/compiler/extensions0.cpp index 3945b73cc..0181fae96 100644 --- a/components/compiler/extensions0.cpp +++ b/components/compiler/extensions0.cpp @@ -59,7 +59,7 @@ namespace Compiler extensions.registerInstruction ("modfight", "l", opcodeModFight, opcodeModFightExplicit); extensions.registerInstruction ("modflee", "l", opcodeModFlee, opcodeModFleeExplicit); extensions.registerInstruction ("modalarm", "l", opcodeModAlarm, opcodeModAlarmExplicit); - extensions.registerInstruction ("toggleai", "X", opcodeToggleAI, opcodeToggleAI); + extensions.registerInstruction ("toggleai", "", opcodeToggleAI, opcodeToggleAI); extensions.registerInstruction ("tai", "", opcodeToggleAI, opcodeToggleAI); extensions.registerInstruction("startcombat", "c", opcodeStartCombat, opcodeStartCombatExplicit); extensions.registerInstruction("stopcombat", "x", opcodeStopCombat, opcodeStopCombatExplicit); @@ -113,7 +113,7 @@ namespace Compiler { void registerExtensions (Extensions& extensions) { - extensions.registerInstruction ("additem", "clxx", opcodeAddItem, opcodeAddItemExplicit); + extensions.registerInstruction ("additem", "cl", opcodeAddItem, opcodeAddItemExplicit); extensions.registerFunction ("getitemcount", 'l', "c", opcodeGetItemCount, opcodeGetItemCountExplicit); extensions.registerInstruction ("removeitem", "cl", opcodeRemoveItem, @@ -163,7 +163,7 @@ namespace Compiler { void registerExtensions (Extensions& extensions) { - extensions.registerInstruction ("journal", "clxxX", opcodeJournal); + extensions.registerInstruction ("journal", "cl", opcodeJournal); extensions.registerInstruction ("setjournalindex", "cl", opcodeSetJournalIndex); extensions.registerFunction ("getjournalindex", 'l', "c", opcodeGetJournalIndex); extensions.registerInstruction ("addtopic", "S" , opcodeAddTopic);