1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-02-03 17:54:06 +00:00

added scriptrunning/startscript/stopscript; sorted out more case problems

This commit is contained in:
Marc Zinnschlag 2010-07-04 16:00:32 +02:00
parent 185f8bd56d
commit a61b2c39f0
26 changed files with 274 additions and 42 deletions

View File

@ -101,6 +101,15 @@ namespace SAInterpreter
void Context::setGlobalFloat (const std::string& name, float value) {} void Context::setGlobalFloat (const std::string& name, float value) {}
bool Context::isScriptRunning (const std::string& name)
{
return false;
}
void Context::startScript (const std::string& name) {}
void Context::stopScript (const std::string& name) {}
void Context::report() void Context::report()
{ {
std::size_t i = 0; std::size_t i = 0;

View File

@ -52,6 +52,12 @@ namespace SAInterpreter
virtual void setGlobalFloat (const std::string& name, float value); virtual void setGlobalFloat (const std::string& name, float value);
virtual bool isScriptRunning (const std::string& name);
virtual void startScript (const std::string& name);
virtual void stopScript (const std::string& name);
void report(); void report();
///< Write state to std::cout ///< Write state to std::cout
}; };

View File

@ -42,7 +42,7 @@ bool OMW::Engine::frameStarted(const Ogre::FrameEvent& evt)
executeLocalScripts(); executeLocalScripts();
// global scripts // global scripts
mGlobalScripts->run (mEnvironment); mEnvironment.mGlobalScripts->run (mEnvironment);
return true; return true;
} }
@ -63,7 +63,7 @@ void OMW::Engine::processCommands()
} }
OMW::Engine::Engine() OMW::Engine::Engine()
: mDebug (false), mVerboseScripts (false), mScriptManager (0), mGlobalScripts (0), : mDebug (false), mVerboseScripts (false), mNewGame (false), mScriptManager (0),
mScriptContext (0) mScriptContext (0)
{ {
mspCommandServer.reset( mspCommandServer.reset(
@ -75,7 +75,7 @@ OMW::Engine::~Engine()
// mspCommandServer->stop(); // mspCommandServer->stop();
delete mEnvironment.mWorld; delete mEnvironment.mWorld;
delete mEnvironment.mSoundManager; delete mEnvironment.mSoundManager;
delete mGlobalScripts; delete mEnvironment.mGlobalScripts;
delete mScriptManager; delete mScriptManager;
delete mScriptContext; delete mScriptContext;
} }
@ -146,6 +146,11 @@ void OMW::Engine::enableVerboseScripts()
mVerboseScripts = true; mVerboseScripts = true;
} }
void OMW::Engine::setNewGame()
{
mNewGame = true;
}
// Initialise and enter main loop. // Initialise and enter main loop.
void OMW::Engine::go() void OMW::Engine::go()
@ -174,7 +179,7 @@ void OMW::Engine::go()
loadBSA(); loadBSA();
// Create the world // Create the world
mEnvironment.mWorld = new MWWorld::World (mOgre, mDataDir, mMaster, mCellName); mEnvironment.mWorld = new MWWorld::World (mOgre, mDataDir, mMaster, mCellName, mNewGame);
mEnvironment.mSoundManager = new MWSound::SoundManager; mEnvironment.mSoundManager = new MWSound::SoundManager;
@ -187,7 +192,8 @@ void OMW::Engine::go()
mScriptManager = new MWScript::ScriptManager (mEnvironment.mWorld->getStore(), mVerboseScripts, mScriptManager = new MWScript::ScriptManager (mEnvironment.mWorld->getStore(), mVerboseScripts,
*mScriptContext); *mScriptContext);
mGlobalScripts = new MWScript::GlobalScripts (mEnvironment.mWorld->getStore(), *mScriptManager); mEnvironment.mGlobalScripts = new MWScript::GlobalScripts (mEnvironment.mWorld->getStore(),
*mScriptManager);
std::cout << "Setting up input system\n"; std::cout << "Setting up input system\n";

View File

@ -23,7 +23,6 @@ namespace Compiler
namespace MWScript namespace MWScript
{ {
class ScriptManager; class ScriptManager;
class GlobalScripts;
} }
namespace MWSound namespace MWSound
@ -50,13 +49,13 @@ namespace OMW
std::string mMaster; std::string mMaster;
bool mDebug; bool mDebug;
bool mVerboseScripts; bool mVerboseScripts;
bool mNewGame;
TsDeque<OMW::Command> mCommandQueue; TsDeque<OMW::Command> mCommandQueue;
std::auto_ptr<OMW::CommandServer::Server> mspCommandServer; std::auto_ptr<OMW::CommandServer::Server> mspCommandServer;
MWWorld::Environment mEnvironment; MWWorld::Environment mEnvironment;
MWScript::ScriptManager *mScriptManager; MWScript::ScriptManager *mScriptManager;
MWScript::GlobalScripts *mGlobalScripts;
Compiler::Extensions mExtensions; Compiler::Extensions mExtensions;
Compiler::Context *mScriptContext; Compiler::Context *mScriptContext;
@ -101,6 +100,9 @@ namespace OMW
/// Enable verbose script output /// Enable verbose script output
void enableVerboseScripts(); void enableVerboseScripts();
/// Start as a new game.
void setNewGame();
/// Initialise and enter main loop. /// Initialise and enter main loop.
void go(); void go();

View File

@ -31,6 +31,7 @@ bool parseOptions (int argc, char**argv, OMW::Engine& engine)
"master file") "master file")
( "debug", "debug mode" ) ( "debug", "debug mode" )
( "script-verbose", "verbose script output" ) ( "script-verbose", "verbose script output" )
( "new-game", "activate char gen/new game mechanics" )
; ;
bpo::variables_map variables; bpo::variables_map variables;
@ -59,6 +60,9 @@ bool parseOptions (int argc, char**argv, OMW::Engine& engine)
if (variables.count ("script-verbose")) if (variables.count ("script-verbose"))
engine.enableVerboseScripts(); engine.enableVerboseScripts();
if (variables.count ("new-game"))
engine.setNewGame();
return true; return true;
} }

View File

@ -1,5 +1,8 @@
#include "globalscripts.hpp" #include "globalscripts.hpp"
#include <cassert>
#include "interpretercontext.hpp" #include "interpretercontext.hpp"
#include "scriptmanager.hpp" #include "scriptmanager.hpp"
@ -25,22 +28,42 @@ namespace MWScript
locals.configure (*script); locals.configure (*script);
mScripts.insert (std::make_pair (name, locals)); mScripts.insert (std::make_pair (name, std::make_pair (true, locals)));
} }
} }
void GlobalScripts::removeScript (const std::string& name)
{
std::map<std::string, std::pair<bool, Locals> >::iterator iter = mScripts.find (name);
if (iter!=mScripts.end())
iter->second.first = false;
}
bool GlobalScripts::isRunning (const std::string& name) const
{
std::map<std::string, std::pair<bool, Locals> >::const_iterator iter =
mScripts.find (name);
if (iter==mScripts.end())
return false;
return iter->second.first;
}
void GlobalScripts::run (MWWorld::Environment& environment) void GlobalScripts::run (MWWorld::Environment& environment)
{ {
std::map<std::string, Locals>::iterator iter = mScripts.begin(); for (std::map<std::string, std::pair<bool, Locals> >::iterator iter (mScripts.begin());
iter!=mScripts.end(); ++iter)
while (iter!=mScripts.end())
{ {
MWScript::InterpreterContext interpreterContext (environment, if (iter->second.first)
&iter->second, MWWorld::Ptr()); {
mScriptManager.run (iter->first, interpreterContext); MWScript::InterpreterContext interpreterContext (environment,
&iter->second.second, MWWorld::Ptr());
++iter; mScriptManager.run (iter->first, interpreterContext);
}
} }
} }
} }

View File

@ -24,7 +24,7 @@ namespace MWScript
{ {
const ESMS::ESMStore& mStore; const ESMS::ESMStore& mStore;
ScriptManager& mScriptManager; ScriptManager& mScriptManager;
std::map<std::string, Locals> mScripts; std::map<std::string, std::pair<bool, Locals> > mScripts; // running, local variables
public: public:
@ -32,7 +32,12 @@ namespace MWScript
void addScript (const std::string& name); void addScript (const std::string& name);
void removeScript (const std::string& name);
bool isRunning (const std::string& name) const;
void run (MWWorld::Environment& environment); void run (MWWorld::Environment& environment);
///< run all active global scripts
}; };
} }

View File

@ -6,12 +6,14 @@
#include <components/interpreter/types.hpp> #include <components/interpreter/types.hpp>
#include "locals.hpp"
#include "../mwworld/world.hpp" #include "../mwworld/world.hpp"
#include "locals.hpp"
#include "globalscripts.hpp"
namespace MWScript namespace MWScript
{ {
InterpreterContext::InterpreterContext (const MWWorld::Environment& environment, InterpreterContext::InterpreterContext (MWWorld::Environment& environment,
MWScript::Locals *locals, MWWorld::Ptr reference) MWScript::Locals *locals, MWWorld::Ptr reference)
: mEnvironment (environment), mLocals (locals), mReference (reference) : mEnvironment (environment), mLocals (locals), mReference (reference)
{} {}
@ -119,7 +121,22 @@ namespace MWScript
mEnvironment.mWorld->getGlobalVariable (name) = mEnvironment.mWorld->getGlobalVariable (name) =
*reinterpret_cast<Interpreter::Type_Data *> (&value); *reinterpret_cast<Interpreter::Type_Data *> (&value);
} }
bool InterpreterContext::isScriptRunning (const std::string& name)
{
return mEnvironment.mGlobalScripts->isRunning (name);
}
void InterpreterContext::startScript (const std::string& name)
{
mEnvironment.mGlobalScripts->addScript (name);
}
void InterpreterContext::stopScript (const std::string& name)
{
mEnvironment.mGlobalScripts->removeScript (name);
}
MWWorld::World& InterpreterContext::getWorld() MWWorld::World& InterpreterContext::getWorld()
{ {
return *mEnvironment.mWorld; return *mEnvironment.mWorld;

View File

@ -22,13 +22,13 @@ namespace MWScript
class InterpreterContext : public Interpreter::Context class InterpreterContext : public Interpreter::Context
{ {
MWWorld::Environment mEnvironment; MWWorld::Environment& mEnvironment;
Locals *mLocals; Locals *mLocals;
MWWorld::Ptr mReference; MWWorld::Ptr mReference;
public: public:
InterpreterContext (const MWWorld::Environment& environment, InterpreterContext (MWWorld::Environment& environment,
MWScript::Locals *locals, MWWorld::Ptr reference); MWScript::Locals *locals, MWWorld::Ptr reference);
///< The ownership of \a locals is not transferred. 0-pointer allowed. ///< The ownership of \a locals is not transferred. 0-pointer allowed.
@ -61,6 +61,12 @@ namespace MWScript
virtual void setGlobalFloat (const std::string& name, float value); virtual void setGlobalFloat (const std::string& name, float value);
virtual bool isScriptRunning (const std::string& name);
virtual void startScript (const std::string& name);
virtual void stopScript (const std::string& name);
MWWorld::World& getWorld(); MWWorld::World& getWorld();
MWSound::SoundManager& getSoundManager(); MWSound::SoundManager& getSoundManager();

View File

@ -205,15 +205,15 @@ namespace MWSound
extensions.registerInstruction ("say", "SS", Script::opcodeSay); extensions.registerInstruction ("say", "SS", Script::opcodeSay);
extensions.registerFunction ("saydone", 'l', "", Script::opcodeSayDone); extensions.registerFunction ("saydone", 'l', "", Script::opcodeSayDone);
extensions.registerInstruction ("streammusic", "S", Script::opcodeStreamMusic); extensions.registerInstruction ("streammusic", "S", Script::opcodeStreamMusic);
extensions.registerInstruction ("playsound", "S", Script::opcodePlaySound); extensions.registerInstruction ("playsound", "c", Script::opcodePlaySound);
extensions.registerInstruction ("playsoundvp", "Sff", Script::opcodePlaySoundVP); extensions.registerInstruction ("playsoundvp", "cff", Script::opcodePlaySoundVP);
extensions.registerInstruction ("playsound3d", "S", Script::opcodePlaySound3D); extensions.registerInstruction ("playsound3d", "c", Script::opcodePlaySound3D);
extensions.registerInstruction ("playsound3dvp", "Sff", Script::opcodePlaySound3DVP); extensions.registerInstruction ("playsound3dvp", "cff", Script::opcodePlaySound3DVP);
extensions.registerInstruction ("playloopsound3d", "S", Script::opcodePlayLoopSound3D); extensions.registerInstruction ("playloopsound3d", "c", Script::opcodePlayLoopSound3D);
extensions.registerInstruction ("playloopsound3dvp", "Sff", extensions.registerInstruction ("playloopsound3dvp", "cff",
Script::opcodePlayLoopSound3DVP); Script::opcodePlayLoopSound3DVP);
extensions.registerInstruction ("stopsound", "S", Script::opcodeStopSound); extensions.registerInstruction ("stopsound", "c", Script::opcodeStopSound);
extensions.registerFunction ("getsoundplaying", 'l', "S", Script::opcodeGetSoundPlaying); extensions.registerFunction ("getsoundplaying", 'l', "c", Script::opcodeGetSoundPlaying);
} }
void installOpcodes (Interpreter::Interpreter& interpreter) void installOpcodes (Interpreter::Interpreter& interpreter)

View File

@ -6,6 +6,11 @@ namespace MWSound
class SoundManager; class SoundManager;
} }
namespace MWScript
{
class GlobalScripts;
}
namespace MWWorld namespace MWWorld
{ {
class World; class World;
@ -13,10 +18,11 @@ namespace MWWorld
///< Collection of script-accessable sub-systems ///< Collection of script-accessable sub-systems
struct Environment struct Environment
{ {
Environment() : mWorld (0), mSoundManager (0) {} Environment() : mWorld (0), mSoundManager (0), mGlobalScripts (0) {}
World *mWorld; World *mWorld;
MWSound::SoundManager *mSoundManager; MWSound::SoundManager *mSoundManager;
MWScript::GlobalScripts *mGlobalScripts;
}; };
} }

View File

@ -57,7 +57,7 @@ namespace MWWorld
} }
World::World (Render::OgreRenderer& renderer, const boost::filesystem::path& dataDir, World::World (Render::OgreRenderer& renderer, const boost::filesystem::path& dataDir,
const std::string& master, const std::string& startCell) const std::string& master, const std::string& startCell, bool newGame)
: mSkyManager (0), mScene (renderer), mPlayerPos (mScene.getCamera()) : mSkyManager (0), mScene (renderer), mPlayerPos (mScene.getCamera())
{ {
boost::filesystem::path masterPath (dataDir); boost::filesystem::path masterPath (dataDir);
@ -79,6 +79,14 @@ namespace MWWorld
iter != mStore.globals.list.end(); ++iter) iter != mStore.globals.list.end(); ++iter)
mGlobalVariables.insert (std::make_pair (iter->first, iter->second.value)); mGlobalVariables.insert (std::make_pair (iter->first, iter->second.value));
if (newGame)
{
// set new game mark
float newGameState = 1;
mGlobalVariables["chargenstate"] =
*reinterpret_cast<Interpreter::Type_Data *> (&newGameState);
}
std::cout << "\nSetting up cell rendering\n"; std::cout << "\nSetting up cell rendering\n";
// This connects the cell data with the rendering scene. // This connects the cell data with the rendering scene.

View File

@ -62,7 +62,7 @@ namespace MWWorld
public: public:
World (Render::OgreRenderer& renderer, const boost::filesystem::path& master, World (Render::OgreRenderer& renderer, const boost::filesystem::path& master,
const std::string& dataDir, const std::string& startCell); const std::string& dataDir, const std::string& startCell, bool newGame);
~World(); ~World();

View File

@ -315,6 +315,17 @@ namespace Compiler
mNextOperand = false; mNextOperand = false;
return true; return true;
} }
else if (keyword==Scanner::K_scriptrunning)
{
mTokenLoc = loc;
parseArguments ("c", scanner);
Generator::scriptRunning (mCode);
mOperands.push_back ('l');
mNextOperand = false;
return true;
}
else else
{ {
// check for custom extensions // check for custom extensions
@ -492,9 +503,10 @@ namespace Compiler
for (std::string::const_iterator iter (arguments.begin()); iter!=arguments.end(); for (std::string::const_iterator iter (arguments.begin()); iter!=arguments.end();
++iter) ++iter)
{ {
if (*iter=='S') if (*iter=='S' || *iter=='c')
{ {
stringParser.reset(); stringParser.reset();
if (*iter=='c') stringParser.smashCase();
scanner.scan (stringParser); scanner.scan (stringParser);
if (invert) if (invert)

View File

@ -94,7 +94,7 @@ namespace Compiler
std::vector<Interpreter::Type_Code>& code, bool invert = false); std::vector<Interpreter::Type_Code>& code, bool invert = false);
///< Parse sequence of arguments specified by \a arguments. ///< Parse sequence of arguments specified by \a arguments.
/// \param arguments Each character represents one arguments ('l': integer, /// \param arguments Each character represents one arguments ('l': integer,
/// 'f': float, 'S': string) /// 'f': float, 'S': string, 'c': string (case smashed))
/// \param invert Store arguments in reverted order. /// \param invert Store arguments in reverted order.
}; };
} }

View File

@ -259,6 +259,21 @@ namespace
{ {
code.push_back (Compiler::Generator::segment5 (45)); code.push_back (Compiler::Generator::segment5 (45));
} }
void opScriptRunning (Compiler::Generator::CodeContainer& code)
{
code.push_back (Compiler::Generator::segment5 (46));
}
void opStartScript (Compiler::Generator::CodeContainer& code)
{
code.push_back (Compiler::Generator::segment5 (47));
}
void opStopScript (Compiler::Generator::CodeContainer& code)
{
code.push_back (Compiler::Generator::segment5 (48));
}
} }
namespace Compiler namespace Compiler
@ -635,6 +650,21 @@ namespace Compiler
{ {
opRandom (code); opRandom (code);
} }
void scriptRunning (CodeContainer& code)
{
opScriptRunning (code);
}
void startScript (CodeContainer& code)
{
opStartScript (code);
}
void stopScript (CodeContainer& code)
{
opStopScript (code);
}
} }
} }

View File

@ -100,6 +100,12 @@ namespace Compiler
const std::string& name); const std::string& name);
void random (CodeContainer& code); void random (CodeContainer& code);
void scriptRunning (CodeContainer& code);
void startScript (CodeContainer& code);
void stopScript (CodeContainer& code);
} }
} }

View File

@ -145,6 +145,20 @@ namespace Compiler
Generator::exit (mCode); Generator::exit (mCode);
mState = EndState; mState = EndState;
return true; return true;
case Scanner::K_startscript:
mExprParser.parseArguments ("c", scanner, mCode, true);
Generator::startScript (mCode);
mState = EndState;
return true;
case Scanner::K_stopscript:
mExprParser.parseArguments ("c", scanner, mCode, true);
Generator::stopScript (mCode);
mState = EndState;
return true;
} }
// check for custom extensions // check for custom extensions

View File

@ -244,6 +244,7 @@ namespace Compiler
"getsquareroot", "getsquareroot",
"menumode", "menumode",
"random", "random",
"startscript", "stopscript", "scriptrunning",
0 0
}; };

View File

@ -50,7 +50,8 @@ namespace Compiler
K_set, K_to, K_set, K_to,
K_getsquareroot, K_getsquareroot,
K_menumode, K_menumode,
K_random K_random,
K_startscript, K_stopscript, K_scriptrunning
}; };
enum special enum special

View File

@ -10,7 +10,7 @@
namespace Compiler namespace Compiler
{ {
StringParser::StringParser (ErrorHandler& errorHandler, Context& context, Literals& literals) StringParser::StringParser (ErrorHandler& errorHandler, Context& context, Literals& literals)
: Parser (errorHandler, context), mLiterals (literals), mState (StartState) : Parser (errorHandler, context), mLiterals (literals), mState (StartState), mSmashCase (false)
{ {
} }
@ -20,7 +20,11 @@ namespace Compiler
{ {
if (mState==StartState || mState==CommaState) if (mState==StartState || mState==CommaState)
{ {
Generator::pushString (mCode, mLiterals, name); if (mSmashCase)
Generator::pushString (mCode, mLiterals, toLower (name));
else
Generator::pushString (mCode, mLiterals, name);
return false; return false;
} }
@ -47,6 +51,12 @@ namespace Compiler
{ {
mState = StartState; mState = StartState;
mCode.clear(); mCode.clear();
mSmashCase = false;
}
void StringParser::smashCase()
{
mSmashCase = false;
} }
} }

View File

@ -21,6 +21,7 @@ namespace Compiler
Literals& mLiterals; Literals& mLiterals;
State mState; State mState;
std::vector<Interpreter::Type_Code> mCode; std::vector<Interpreter::Type_Code> mCode;
bool mSmashCase;
public: public:
@ -38,8 +39,11 @@ namespace Compiler
void append (std::vector<Interpreter::Type_Code>& code); void append (std::vector<Interpreter::Type_Code>& code);
///< Append code for parsed string. ///< Append code for parsed string.
void smashCase();
///< Transform all scanned strings to lower case
void reset(); void reset();
///< Reset parser to clean state. ///< Reset parser to clean state (this includes the smashCase function).
}; };
} }

View File

@ -45,7 +45,13 @@ namespace Interpreter
virtual void setGlobalLong (const std::string& name, int value) = 0; virtual void setGlobalLong (const std::string& name, int value) = 0;
virtual void setGlobalFloat (const std::string& name, float value) = 0; virtual void setGlobalFloat (const std::string& name, float value) = 0;
virtual bool isScriptRunning (const std::string& name) = 0;
virtual void startScript (const std::string& name) = 0;
virtual void stopScript (const std::string& name) = 0;
}; };
} }

View File

@ -104,6 +104,9 @@ op 42: replace stack[0] with global short stack[0]
op 43: replace stack[0] with global long stack[0] op 43: replace stack[0] with global long stack[0]
op 44: replace stack[0] with global float stack[0] op 44: replace stack[0] with global float stack[0]
op 45: replace stack[0] with a random integer value in the range [0, stack[0]-1] op 45: replace stack[0] with a random integer value in the range [0, stack[0]-1]
opcodes 46-33554431 unused 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
opcodes 33554432-67108863 reserved for extensions opcodes 33554432-67108863 reserved for extensions

View File

@ -9,6 +9,7 @@
#include "mathopcodes.hpp" #include "mathopcodes.hpp"
#include "controlopcodes.hpp" #include "controlopcodes.hpp"
#include "miscopcodes.hpp" #include "miscopcodes.hpp"
#include "scriptopcodes.hpp"
namespace Interpreter namespace Interpreter
{ {
@ -86,6 +87,11 @@ namespace Interpreter
interpreter.installSegment3 (0, new OpMessageBox); interpreter.installSegment3 (0, new OpMessageBox);
interpreter.installSegment5 (38, new OpMenuMode); interpreter.installSegment5 (38, new OpMenuMode);
interpreter.installSegment5 (45, new OpRandom); interpreter.installSegment5 (45, new OpRandom);
// script control
interpreter.installSegment5 (46, new OpScriptRunning);
interpreter.installSegment5 (47, new OpStartScript);
interpreter.installSegment5 (48, new OpStopScript);
} }
} }

View File

@ -0,0 +1,47 @@
#ifndef INTERPRETER_SCRIPTOPCODES_H_INCLUDED
#define INTERPRETER_SCRIPTOPCODES_H_INCLUDED
#include "opcodes.hpp"
#include "runtime.hpp"
#include "context.hpp"
namespace Interpreter
{
class OpScriptRunning : public Opcode0
{
public:
virtual void execute (Runtime& runtime)
{
std::string name = runtime.getStringLiteral (runtime[0]);
runtime[0] = runtime.getContext().isScriptRunning (name);
}
};
class OpStartScript : public Opcode0
{
public:
virtual void execute (Runtime& runtime)
{
std::string name = runtime.getStringLiteral (runtime[0]);
runtime.pop();
runtime.getContext().startScript (name);
}
};
class OpStopScript : public Opcode0
{
public:
virtual void execute (Runtime& runtime)
{
std::string name = runtime.getStringLiteral (runtime[0]);
runtime.pop();
runtime.getContext().stopScript (name);
}
};
}
#endif