#include "globalscripts.hpp" #include #include #include #include #include #include "../mwworld/esmstore.hpp" #include "../mwbase/environment.hpp" #include "../mwbase/scriptmanager.hpp" #include "interpretercontext.hpp" namespace MWScript { GlobalScriptDesc::GlobalScriptDesc() : mRunning (false) {} GlobalScripts::GlobalScripts (const MWWorld::ESMStore& store) : mStore (store) {} void GlobalScripts::addScript (const std::string& name, const std::string& targetId) { std::map::iterator iter = mScripts.find (::Misc::StringUtils::lowerCase (name)); if (iter==mScripts.end()) { if (const ESM::Script *script = mStore.get().find (name)) { GlobalScriptDesc desc; desc.mRunning = true; desc.mLocals.configure (*script); desc.mId = targetId; mScripts.insert (std::make_pair (name, desc)); } } else if (!iter->second.mRunning) { iter->second.mRunning = true; iter->second.mId = targetId; } } void GlobalScripts::removeScript (const std::string& name) { std::map::iterator iter = mScripts.find (::Misc::StringUtils::lowerCase (name)); if (iter!=mScripts.end()) iter->second.mRunning = false; } bool GlobalScripts::isRunning (const std::string& name) const { std::map::const_iterator iter = mScripts.find (::Misc::StringUtils::lowerCase (name)); if (iter==mScripts.end()) return false; return iter->second.mRunning; } void GlobalScripts::run() { for (std::map::iterator iter (mScripts.begin()); iter!=mScripts.end(); ++iter) { if (iter->second.mRunning) { MWWorld::Ptr ptr; MWScript::InterpreterContext interpreterContext ( &iter->second.mLocals, MWWorld::Ptr(), iter->second.mId); /* Start of tes3mp addition Mark this InterpreterContext as having a GLOBAL_SCRIPT context, so that packets sent by the Interpreter can have their origin determined by serverside scripts */ interpreterContext.setContextType(Interpreter::Context::SCRIPT_GLOBAL); /* End of tes3mp addition */ MWBase::Environment::get().getScriptManager()->run (iter->first, interpreterContext); } } } void GlobalScripts::clear() { mScripts.clear(); } void GlobalScripts::addStartup() { // make list of global scripts to be added std::vector scripts; scripts.push_back ("main"); for (MWWorld::Store::iterator iter = mStore.get().begin(); iter != mStore.get().end(); ++iter) { scripts.push_back (iter->mId); } // add scripts for (std::vector::const_iterator iter (scripts.begin()); iter!=scripts.end(); ++iter) { try { addScript (*iter); } catch (const std::exception& exception) { std::cerr << "Failed to add start script " << *iter << " because an exception has " << "been thrown: " << exception.what() << std::endl; } } } int GlobalScripts::countSavedGameRecords() const { return mScripts.size(); } void GlobalScripts::write (ESM::ESMWriter& writer, Loading::Listener& progress) const { for (std::map::const_iterator iter (mScripts.begin()); iter!=mScripts.end(); ++iter) { ESM::GlobalScript script; script.mId = iter->first; iter->second.mLocals.write (script.mLocals, iter->first); 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); } } bool GlobalScripts::readRecord (ESM::ESMReader& reader, uint32_t type) { if (type==ESM::REC_GSCR) { ESM::GlobalScript script; script.load (reader); std::map::iterator iter = mScripts.find (script.mId); if (iter==mScripts.end()) { if (const ESM::Script *scriptRecord = mStore.get().search (script.mId)) { try { GlobalScriptDesc desc; desc.mLocals.configure (*scriptRecord); iter = mScripts.insert (std::make_pair (script.mId, desc)).first; } catch (const std::exception& exception) { std::cerr << "Failed to add start script " << script.mId << " because an exception has been thrown: " << exception.what() << std::endl; return true; } } else // script does not exist anymore return true; } iter->second.mRunning = script.mRunning!=0; iter->second.mLocals.read (script.mLocals, script.mId); iter->second.mId = script.mTargetId; return true; } return false; } Locals& GlobalScripts::getLocals (const std::string& name) { std::string name2 = ::Misc::StringUtils::lowerCase (name); std::map::iterator iter = mScripts.find (name2); if (iter==mScripts.end()) { const ESM::Script *script = mStore.get().find (name); GlobalScriptDesc desc; desc.mLocals.configure (*script); iter = mScripts.insert (std::make_pair (name2, desc)).first; } return iter->second.mLocals; } }