diff --git a/apps/mwinterpreter/context.cpp b/apps/mwinterpreter/context.cpp index 9119521fb..712c369e4 100644 --- a/apps/mwinterpreter/context.cpp +++ b/apps/mwinterpreter/context.cpp @@ -110,6 +110,11 @@ namespace SAInterpreter void Context::stopScript (const std::string& name) {} + float Context::getDistance (const std::string& name) + { + return 0; + } + void Context::report() { std::size_t i = 0; diff --git a/apps/mwinterpreter/context.hpp b/apps/mwinterpreter/context.hpp index 217b2a1d4..7920da5b9 100644 --- a/apps/mwinterpreter/context.hpp +++ b/apps/mwinterpreter/context.hpp @@ -58,6 +58,8 @@ namespace SAInterpreter virtual void stopScript (const std::string& name); + virtual float getDistance (const std::string& name); + void report(); ///< Write state to std::cout }; diff --git a/apps/openmw/mwscript/interpretercontext.cpp b/apps/openmw/mwscript/interpretercontext.cpp index 525aef183..b06401a3a 100644 --- a/apps/openmw/mwscript/interpretercontext.cpp +++ b/apps/openmw/mwscript/interpretercontext.cpp @@ -1,6 +1,7 @@ #include "interpretercontext.hpp" +#include #include #include @@ -137,6 +138,22 @@ namespace MWScript mEnvironment.mGlobalScripts->removeScript (name); } + float InterpreterContext::getDistance (const std::string& name) + { + if (mReference.isEmpty()) + throw std::runtime_error ("no implicit reference"); + + std::pair ref = + mEnvironment.mWorld->getPtr (name, true); + + double diff[3]; + + for (int i=0; i<3; ++i) + diff[i] = ref.first.getCellRef().pos.pos[i] - mReference.getCellRef().pos.pos[i]; + + return std::sqrt (diff[0]*diff[0] + diff[1]*diff[1] + diff[2]*diff[2]); + } + MWWorld::World& InterpreterContext::getWorld() { return *mEnvironment.mWorld; diff --git a/apps/openmw/mwscript/interpretercontext.hpp b/apps/openmw/mwscript/interpretercontext.hpp index f0efae65c..22cb14e45 100644 --- a/apps/openmw/mwscript/interpretercontext.hpp +++ b/apps/openmw/mwscript/interpretercontext.hpp @@ -67,6 +67,8 @@ namespace MWScript virtual void stopScript (const std::string& name); + virtual float getDistance (const std::string& name); + MWWorld::World& getWorld(); MWSound::SoundManager& getSoundManager(); diff --git a/components/compiler/exprparser.cpp b/components/compiler/exprparser.cpp index fd44c5e41..6d3415e22 100644 --- a/components/compiler/exprparser.cpp +++ b/components/compiler/exprparser.cpp @@ -326,6 +326,19 @@ namespace Compiler mNextOperand = false; return true; } + else if (keyword==Scanner::K_getdistance) + { + mTokenLoc = loc; + parseArguments ("c", scanner); + + Generator::getDistance (mCode); + mOperands.push_back ('f'); + + mNextOperand = false; + return true; + } + + else { // check for custom extensions diff --git a/components/compiler/generator.cpp b/components/compiler/generator.cpp index f9893ad9a..05b311724 100644 --- a/components/compiler/generator.cpp +++ b/components/compiler/generator.cpp @@ -274,6 +274,11 @@ namespace { code.push_back (Compiler::Generator::segment5 (48)); } + + void opGetDistance (Compiler::Generator::CodeContainer& code) + { + code.push_back (Compiler::Generator::segment5 (49)); + } } namespace Compiler @@ -665,6 +670,11 @@ namespace Compiler { opStopScript (code); } + + void getDistance (CodeContainer& code) + { + opGetDistance (code); + } } } diff --git a/components/compiler/generator.hpp b/components/compiler/generator.hpp index cebb5b00f..c03ac7caf 100644 --- a/components/compiler/generator.hpp +++ b/components/compiler/generator.hpp @@ -106,6 +106,8 @@ namespace Compiler void startScript (CodeContainer& code); void stopScript (CodeContainer& code); + + void getDistance (CodeContainer& code); } } diff --git a/components/compiler/scanner.cpp b/components/compiler/scanner.cpp index 092d8074a..25c536151 100644 --- a/components/compiler/scanner.cpp +++ b/components/compiler/scanner.cpp @@ -245,6 +245,7 @@ namespace Compiler "menumode", "random", "startscript", "stopscript", "scriptrunning", + "getdistance", 0 }; diff --git a/components/compiler/scanner.hpp b/components/compiler/scanner.hpp index 88e070673..e8f2b3d26 100644 --- a/components/compiler/scanner.hpp +++ b/components/compiler/scanner.hpp @@ -51,7 +51,8 @@ namespace Compiler K_getsquareroot, K_menumode, K_random, - K_startscript, K_stopscript, K_scriptrunning + K_startscript, K_stopscript, K_scriptrunning, + K_getdistance }; enum special diff --git a/components/interpreter/context.hpp b/components/interpreter/context.hpp index 3373d3303..91302a944 100644 --- a/components/interpreter/context.hpp +++ b/components/interpreter/context.hpp @@ -51,7 +51,9 @@ namespace Interpreter virtual void startScript (const std::string& name) = 0; - virtual void stopScript (const std::string& name) = 0; + virtual void stopScript (const std::string& name) = 0; + + virtual float getDistance (const std::string& name) = 0; }; } diff --git a/components/interpreter/docs/vmformat.txt b/components/interpreter/docs/vmformat.txt index 2812cd380..d45906a4c 100644 --- a/components/interpreter/docs/vmformat.txt +++ b/components/interpreter/docs/vmformat.txt @@ -107,6 +107,7 @@ op 45: replace stack[0] with a random integer value in the range [0, stack[0]-1 op 46: replace stack[0] with 1, if global script stack[0] is running, 0 else op 47: start script stack[0] and pop op 48: stop script stack[0] and pop -opcodes 49-33554431 unused +op 49: replace stack[0] with distance between implicit reference and a reference of ID stack[0] +opcodes 50-33554431 unused opcodes 33554432-67108863 reserved for extensions diff --git a/components/interpreter/installopcodes.cpp b/components/interpreter/installopcodes.cpp index 36fd01f01..186ee7587 100644 --- a/components/interpreter/installopcodes.cpp +++ b/components/interpreter/installopcodes.cpp @@ -10,6 +10,7 @@ #include "controlopcodes.hpp" #include "miscopcodes.hpp" #include "scriptopcodes.hpp" +#include "spatialopcodes.hpp" namespace Interpreter { @@ -92,6 +93,9 @@ namespace Interpreter interpreter.installSegment5 (46, new OpScriptRunning); interpreter.installSegment5 (47, new OpStartScript); interpreter.installSegment5 (48, new OpStopScript); + + // spacial + interpreter.installSegment5 (49, new OpGetDistance); } } diff --git a/components/interpreter/spatialopcodes.hpp b/components/interpreter/spatialopcodes.hpp new file mode 100644 index 000000000..7e2430852 --- /dev/null +++ b/components/interpreter/spatialopcodes.hpp @@ -0,0 +1,22 @@ +#ifndef INTERPRETER_SPATIALOPCODES_H_INCLUDED +#define INTERPRETER_SPATIALOPCODES_H_INCLUDED + +#include "opcodes.hpp" +#include "runtime.hpp" + +namespace Interpreter +{ + class OpGetDistance : public Opcode0 + { + public: + + virtual void execute (Runtime& runtime) + { + std::string name = runtime.getStringLiteral (runtime[0]); + runtime[0] = runtime.getContext().getDistance (name); + } + }; +} + +#endif +