1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-01-21 06:53:53 +00:00

Merge remote-tracking branch 'upstream/master' into newlauncher

Conflicts:
	CMakeLists.txt
	apps/openmw/main.cpp
	components/esm/defs.hpp
	components/esm/loadappa.hpp
	components/esm/loadbody.hpp
	components/esm/loadclas.hpp
	components/esm/loadcrea.hpp
	components/esm/loadsndg.hpp
	components/interpreter/installopcodes.cpp
This commit is contained in:
Pieter van der Kloet 2011-04-28 22:03:19 +02:00
commit 7b554897e7
51 changed files with 1040 additions and 227 deletions

View file

@ -168,7 +168,7 @@ set(ESM
${COMP_DIR}/esm/loadsscr.cpp ${COMP_DIR}/esm/loadsscr.cpp
${COMP_DIR}/esm/loadstat.cpp ${COMP_DIR}/esm/loadstat.cpp
${COMP_DIR}/esm/loadweap.cpp ${COMP_DIR}/esm/loadweap.cpp
) )
source_group(components\\esm FILES ${ESM_HEADER} ${ESM}) source_group(components\\esm FILES ${ESM_HEADER} ${ESM})
@ -181,6 +181,14 @@ set(MISC_HEADER
${COMP_DIR}/misc/stringops.hpp) ${COMP_DIR}/misc/stringops.hpp)
source_group(components\\misc FILES ${MISC} ${MISC_HEADER}) source_group(components\\misc FILES ${MISC} ${MISC_HEADER})
set(FILES
${COMP_DIR}/files/path.cpp
)
set(FILES_HEADER
${COMP_DIR}/files/path.hpp
)
source_group(components\\files FILES ${FILES} ${FILES_HEADER})
file(GLOB COMPILER ${COMP_DIR}/compiler/*.cpp) file(GLOB COMPILER ${COMP_DIR}/compiler/*.cpp)
file(GLOB COMPILER_HEADER ${COMP_DIR}/compiler/*.hpp) file(GLOB COMPILER_HEADER ${COMP_DIR}/compiler/*.hpp)
source_group(components\\compiler FILES ${COMPILER} ${COMPILER_HEADER}) source_group(components\\compiler FILES ${COMPILER} ${COMPILER_HEADER})
@ -190,10 +198,10 @@ file(GLOB INTERPRETER_HEADER ${COMP_DIR}/interpreter/*.hpp)
source_group(components\\interpreter FILES ${INTERPRETER} ${INTERPRETER_HEADER}) source_group(components\\interpreter FILES ${INTERPRETER} ${INTERPRETER_HEADER})
set(COMPONENTS ${BSA} ${NIF} ${NIFOGRE} ${ESM_STORE} ${MISC} ${TO_UTF8} set(COMPONENTS ${BSA} ${NIF} ${NIFOGRE} ${ESM_STORE} ${MISC} ${TO_UTF8}
${COMPILER} ${INTERPRETER} ${ESM} ${FILE_FINDER} ${NIFBULLET}) ${COMPILER} ${INTERPRETER} ${ESM} ${FILE_FINDER} ${NIFBULLET} ${FILES})
set(COMPONENTS_HEADER ${BSA_HEADER} ${NIF_HEADER} ${NIFOGRE_HEADER} ${ESM_STORE_HEADER} set(COMPONENTS_HEADER ${BSA_HEADER} ${NIF_HEADER} ${NIFOGRE_HEADER} ${ESM_STORE_HEADER}
${ESM_HEADER} ${MISC_HEADER} ${COMPILER_HEADER} ${TO_UTF8_HEADER} ${ESM_HEADER} ${MISC_HEADER} ${COMPILER_HEADER} ${TO_UTF8_HEADER}
${INTERPRETER_HEADER} ${FILE_FINDER_HEADER} ${NIFBULLET_HEADER}) ${INTERPRETER_HEADER} ${FILE_FINDER_HEADER} ${NIFBULLET_HEADER} ${FILES_HEADER})
# source directory: libs # source directory: libs
@ -337,8 +345,9 @@ endif (APPLE)
# Other files # Other files
configure_file(${OpenMW_SOURCE_DIR}/files/openmw.cfg.local configure_file(${OpenMW_SOURCE_DIR}/files/openmw.cfg.local
"${OpenMW_BINARY_DIR}/openmw.cfg" COPYONLY) "${OpenMW_BINARY_DIR}/openmw.cfg")
configure_file(${OpenMW_SOURCE_DIR}/files/openmw.cfg
"${OpenMW_BINARY_DIR}/openmw.cfg.install")
if (WIN32) if (WIN32)
configure_file(${OpenMW_SOURCE_DIR}/files/plugins.cfg.win32 configure_file(${OpenMW_SOURCE_DIR}/files/plugins.cfg.win32
@ -353,28 +362,29 @@ endif()
if (APPLE) if (APPLE)
configure_file(${OpenMW_SOURCE_DIR}/files/plugins.cfg.mac configure_file(${OpenMW_SOURCE_DIR}/files/plugins.cfg.mac
"${APP_BUNDLE_DIR}/Contents/MacOS/plugins.cfg") "${APP_BUNDLE_DIR}/Contents/MacOS/plugins.cfg")
configure_file(${OpenMW_SOURCE_DIR}/files/mac/Info.plist configure_file(${OpenMW_SOURCE_DIR}/files/mac/Info.plist
"${APP_BUNDLE_DIR}/Contents/Info.plist" COPYONLY) "${APP_BUNDLE_DIR}/Contents/Info.plist" COPYONLY)
configure_file(${OpenMW_SOURCE_DIR}/files/mac/openmw.icns configure_file(${OpenMW_SOURCE_DIR}/files/mac/openmw.icns
"${APP_BUNDLE_DIR}/Contents/Resources/OpenMW.icns" COPYONLY) "${APP_BUNDLE_DIR}/Contents/Resources/OpenMW.icns" COPYONLY)
# prepare plugins # prepare plugins
configure_file(${OGRE_PLUGIN_DIR}/RenderSystem_GL.dylib configure_file(${OGRE_PLUGIN_DIR}/RenderSystem_GL.dylib
"${APP_BUNDLE_DIR}/Contents/Plugins/RenderSystem_GL.dylib" COPYONLY) "${APP_BUNDLE_DIR}/Contents/Plugins/RenderSystem_GL.dylib" COPYONLY)
configure_file(${OGRE_PLUGIN_DIR}/Plugin_OctreeSceneManager.dylib configure_file(${OGRE_PLUGIN_DIR}/Plugin_OctreeSceneManager.dylib
"${APP_BUNDLE_DIR}/Contents/Plugins/Plugin_OctreeSceneManager.dylib" COPYONLY) "${APP_BUNDLE_DIR}/Contents/Plugins/Plugin_OctreeSceneManager.dylib" COPYONLY)
configure_file(${OGRE_PLUGIN_DIR}/Plugin_ParticleFX.dylib configure_file(${OGRE_PLUGIN_DIR}/Plugin_ParticleFX.dylib
"${APP_BUNDLE_DIR}/Contents/Plugins/Plugin_ParticleFX.dylib" COPYONLY) "${APP_BUNDLE_DIR}/Contents/Plugins/Plugin_ParticleFX.dylib" COPYONLY)
configure_file(${OpenMW_SOURCE_DIR}/files/openmw.cfg
"${APP_BUNDLE_DIR}/Contents/MacOS/openmw.cfg")
endif (APPLE) endif (APPLE)
configure_file(${OpenMW_SOURCE_DIR}/files/openmw.cfg
"${APP_BUNDLE_DIR}/Contents/MacOS/openmw.cfg")
# Compiler settings # Compiler settings
if (CMAKE_COMPILER_IS_GNUCC) if (CMAKE_COMPILER_IS_GNUCC)
@ -384,13 +394,13 @@ endif (CMAKE_COMPILER_IS_GNUCC)
# Apple bundling # Apple bundling
if (APPLE) if (APPLE)
set(MISC_FILES set(MISC_FILES
${APP_BUNDLE_DIR}/Contents/MacOS/openmw.cfg ${APP_BUNDLE_DIR}/Contents/MacOS/openmw.cfg
${APP_BUNDLE_DIR}/Contents/MacOS/plugins.cfg) ${APP_BUNDLE_DIR}/Contents/MacOS/plugins.cfg)
set(OGRE_PLUGINS set(OGRE_PLUGINS
${APP_BUNDLE_DIR}/Contents/Plugins/*) ${APP_BUNDLE_DIR}/Contents/Plugins/*)
install(FILES ${MISC_FILES} DESTINATION ../MacOS) install(FILES ${MISC_FILES} DESTINATION ../MacOS)
install(DIRECTORY "${APP_BUNDLE_DIR}/Contents/Plugins" DESTINATION ..) install(DIRECTORY "${APP_BUNDLE_DIR}/Contents/Plugins" DESTINATION ..)
install(DIRECTORY "${APP_BUNDLE_DIR}/Contents/Resources/resources" DESTINATION ../Resources) install(DIRECTORY "${APP_BUNDLE_DIR}/Contents/Resources/resources" DESTINATION ../Resources)
@ -427,7 +437,7 @@ if(DPKG_PROGRAM)
endif() endif()
#Install global configuration files #Install global configuration files
INSTALL(FILES "${OpenMW_SOURCE_DIR}/openmw.cfg" DESTINATION "../etc/openmw/" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ COMPONENT "openmw") INSTALL(FILES "${OpenMW_BINARY_DIR}/openmw.cfg.install" DESTINATION "../etc/openmw/" RENAME "openmw.cfg" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ COMPONENT "openmw")
INSTALL(FILES "${OpenMW_BINARY_DIR}/plugins.cfg" DESTINATION "../etc/openmw/" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ COMPONENT "openmw") INSTALL(FILES "${OpenMW_BINARY_DIR}/plugins.cfg" DESTINATION "../etc/openmw/" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ COMPONENT "openmw")
#Install resources #Install resources

View file

@ -5,7 +5,7 @@ project(OpenMW)
set(GAME set(GAME
main.cpp main.cpp
engine.cpp engine.cpp
path.cpp) )
set(GAME_HEADER set(GAME_HEADER
engine.hpp) engine.hpp)
source_group(game FILES ${GAME} ${GAME_HEADER}) source_group(game FILES ${GAME} ${GAME_HEADER})
@ -70,9 +70,17 @@ source_group(apps\\openmw\\mwgui FILES ${GAMEGUI_HEADER} ${GAMEGUI})
set(GAMEDIALOGUE_HEADER set(GAMEDIALOGUE_HEADER
mwdialogue/dialoguemanager.hpp mwdialogue/dialoguemanager.hpp
mwdialogue/journal.hpp
mwdialogue/journalentry.hpp
mwdialogue/quest.hpp
mwdialogue/topic.hpp
) )
set(GAMEDIALOGUE set(GAMEDIALOGUE
mwdialogue/dialoguemanager.cpp mwdialogue/dialoguemanager.cpp
mwdialogue/journal.cpp
mwdialogue/journalentry.cpp
mwdialogue/quest.cpp
mwdialogue/topic.cpp
) )
source_group(apps\\openmw\\mwdialogue FILES ${GAMEDIALOGUE_HEADER} ${GAMEDIALOGUE}) source_group(apps\\openmw\\mwdialogue FILES ${GAMEDIALOGUE_HEADER} ${GAMEDIALOGUE})
@ -91,6 +99,7 @@ set(GAMESCRIPT
mwscript/controlextensions.cpp mwscript/controlextensions.cpp
mwscript/extensions.cpp mwscript/extensions.cpp
mwscript/globalscripts.cpp mwscript/globalscripts.cpp
mwscript/dialogueextensions.cpp
) )
set(GAMESCRIPT_HEADER set(GAMESCRIPT_HEADER
mwscript/locals.hpp mwscript/locals.hpp
@ -109,6 +118,7 @@ set(GAMESCRIPT_HEADER
mwscript/extensions.hpp mwscript/extensions.hpp
mwscript/globalscripts.hpp mwscript/globalscripts.hpp
mwscript/ref.hpp mwscript/ref.hpp
mwscript/dialogueextensions.hpp
) )
source_group(apps\\openmw\\mwscript FILES ${GAMESCRIPT} ${GAMESCRIPT_HEADER}) source_group(apps\\openmw\\mwscript FILES ${GAMESCRIPT} ${GAMESCRIPT_HEADER})

View file

@ -14,6 +14,8 @@
#include <components/bsa/bsa_archive.hpp> #include <components/bsa/bsa_archive.hpp>
#include <components/esm/loadregn.hpp> #include <components/esm/loadregn.hpp>
#include <components/esm/esm_reader.hpp> #include <components/esm/esm_reader.hpp>
#include <components/files/path.hpp>
#include <openengine/gui/manager.hpp> #include <openengine/gui/manager.hpp>
#include "mwgui/window_manager.hpp" #include "mwgui/window_manager.hpp"
@ -36,6 +38,7 @@
#include "mwclass/classes.hpp" #include "mwclass/classes.hpp"
#include "mwdialogue/dialoguemanager.hpp" #include "mwdialogue/dialoguemanager.hpp"
#include "mwdialogue/journal.hpp"
#include "mwmechanics/mechanicsmanager.hpp" #include "mwmechanics/mechanicsmanager.hpp"
@ -47,7 +50,6 @@
#include <MyGUI_WidgetManager.h> #include <MyGUI_WidgetManager.h>
#include "mwgui/class.hpp" #include "mwgui/class.hpp"
#include "path.hpp"
#include "components/nifbullet/bullet_nif_loader.hpp" #include "components/nifbullet/bullet_nif_loader.hpp"
@ -228,6 +230,7 @@ OMW::Engine::~Engine()
delete mEnvironment.mGlobalScripts; delete mEnvironment.mGlobalScripts;
delete mEnvironment.mMechanicsManager; delete mEnvironment.mMechanicsManager;
delete mEnvironment.mDialogueManager; delete mEnvironment.mDialogueManager;
delete mEnvironment.mJournal;
delete mScriptManager; delete mScriptManager;
delete mScriptContext; delete mScriptContext;
delete mPhysicEngine; delete mPhysicEngine;
@ -322,12 +325,10 @@ void OMW::Engine::go()
test.name = ""; test.name = "";
total = 0; total = 0;
std::cout << "Data directory: " << mDataDir << "\n"; std::cout << "Data directory: " << mDataDir << "\n";
std::string cfgDir = OMW::Path::getPath(OMW::Path::GLOBAL_CFG_PATH, "openmw", ""); std::string cfgDir = Files::getPath (Files::Path_ConfigGlobal, "openmw", "");
std::string cfgUserDir = OMW::Path::getPath(OMW::Path::USER_CFG_PATH, "openmw", ""); std::string cfgUserDir = Files::getPath (Files::Path_ConfigUser, "openmw", "");
std::string plugCfg = "plugins.cfg"; std::string plugCfg = "plugins.cfg";
std::string ogreCfg = "ogre.cfg"; std::string ogreCfg = "ogre.cfg";
ogreCfg.insert(0, cfgUserDir); ogreCfg.insert(0, cfgUserDir);
@ -396,6 +397,7 @@ void OMW::Engine::go()
mEnvironment.mMechanicsManager = new MWMechanics::MechanicsManager (mEnvironment); mEnvironment.mMechanicsManager = new MWMechanics::MechanicsManager (mEnvironment);
// Create dialog system // Create dialog system
mEnvironment.mJournal = new MWDialogue::Journal (mEnvironment);
mEnvironment.mDialogueManager = new MWDialogue::DialogueManager (mEnvironment); mEnvironment.mDialogueManager = new MWDialogue::DialogueManager (mEnvironment);
// load cell // load cell

View file

@ -6,8 +6,9 @@
#include <boost/program_options.hpp> #include <boost/program_options.hpp>
#include <components/misc/fileops.hpp> #include <components/misc/fileops.hpp>
#include <components/files/path.hpp>
#include "engine.hpp" #include "engine.hpp"
#include "path.hpp"
#if defined(_WIN32) && !defined(_CONSOLE) #if defined(_WIN32) && !defined(_CONSOLE)
#include <boost/iostreams/concepts.hpp> #include <boost/iostreams/concepts.hpp>
@ -78,12 +79,12 @@ bool parseOptions (int argc, char**argv, OMW::Engine& engine)
std::string cfgFile = "openmw.cfg"; std::string cfgFile = "openmw.cfg";
if(!isFile(cfgFile.c_str())) if(!isFile(cfgFile.c_str()))
{ {
cfgFile = OMW::Path::getPath(OMW::Path::GLOBAL_CFG_PATH, "openmw", "openmw.cfg"); cfgFile = Files::getPath (Files::Path_ConfigGlobal, "openmw", "openmw.cfg");
} }
std::cout << "Using global config file: " << cfgFile << std::endl; std::cout << "Using global config file: " << cfgFile << std::endl;
std::ifstream globalConfigFile(cfgFile.c_str()); std::ifstream globalConfigFile(cfgFile.c_str());
cfgFile = OMW::Path::getPath(OMW::Path::USER_CFG_PATH, "openmw", "openmw.cfg"); cfgFile = Files::getPath (Files::Path_ConfigUser, "openmw", "openmw.cfg");
std::cout << "Using user config file: " << cfgFile << std::endl; std::cout << "Using user config file: " << cfgFile << std::endl;
std::ifstream userConfigFile(cfgFile.c_str()); std::ifstream userConfigFile(cfgFile.c_str());

View file

@ -0,0 +1,95 @@
#include "journal.hpp"
#include "../mwworld/environment.hpp"
namespace MWDialogue
{
Quest& Journal::getQuest (const std::string& id)
{
TQuestContainer::iterator iter = mQuests.find (id);
if (iter==mQuests.end())
{
std::pair<TQuestContainer::iterator, bool> result =
mQuests.insert (std::make_pair (id, Quest (id)));
iter = result.first;
}
return iter->second;
}
Journal::Journal (MWWorld::Environment& environment)
: mEnvironment (environment)
{}
void Journal::addEntry (const std::string& id, int index)
{
StampedJournalEntry entry =
StampedJournalEntry::makeFromQuest (id, index, *mEnvironment.mWorld);
mJournal.push_back (entry);
Quest& quest = getQuest (id);
quest.addEntry (entry, *mEnvironment.mWorld); // we are doing slicing on purpose here
}
void Journal::setJournalIndex (const std::string& id, int index)
{
Quest& quest = getQuest (id);
quest.setIndex (index, *mEnvironment.mWorld);
}
void Journal::addTopic (const std::string& topicId, const std::string& infoId)
{
TTopicContainer::iterator iter = mTopics.find (topicId);
if (iter==mTopics.end())
{
std::pair<TTopicContainer::iterator, bool> result
= mTopics.insert (std::make_pair (topicId, Topic (topicId)));
iter = result.first;
}
iter->second.addEntry (JournalEntry (topicId, infoId), *mEnvironment.mWorld);
}
int Journal::getJournalIndex (const std::string& id) const
{
return 0;
}
Journal::TEntryIter Journal::begin() const
{
return mJournal.begin();
}
Journal::TEntryIter Journal::end() const
{
return mJournal.end();
}
Journal::TQuestIter Journal::questBegin() const
{
return mQuests.begin();
}
Journal::TQuestIter Journal::questEnd() const
{
return mQuests.end();
}
Journal::TTopicIter Journal::topicBegin() const
{
return mTopics.begin();
}
Journal::TTopicIter Journal::topicEnd() const
{
return mTopics.end();
}
}

View file

@ -0,0 +1,78 @@
#ifndef GAME_MMDIALOG_JOURNAL_H
#define GAME_MWDIALOG_JOURNAL_H
#include <string>
#include <deque>
#include <map>
#include "journalentry.hpp"
#include "quest.hpp"
namespace MWWorld
{
struct Environment;
}
namespace MWDialogue
{
/// \brief The player's journal
class Journal
{
public:
typedef std::deque<StampedJournalEntry> TEntryContainer;
typedef TEntryContainer::const_iterator TEntryIter;
typedef std::map<std::string, Quest> TQuestContainer; // topc, quest
typedef TQuestContainer::const_iterator TQuestIter;
typedef std::map<std::string, Topic> TTopicContainer; // topic-id, topic-content
typedef TTopicContainer::const_iterator TTopicIter;
private:
MWWorld::Environment& mEnvironment;
TEntryContainer mJournal;
TQuestContainer mQuests;
TTopicContainer mTopics;
Quest& getQuest (const std::string& id);
public:
Journal (MWWorld::Environment& environment);
void addEntry (const std::string& id, int index);
///< Add a journal entry.
void setJournalIndex (const std::string& id, int index);
///< Set the journal index without adding an entry.
int getJournalIndex (const std::string& id) const;
///< Get the journal index.
void addTopic (const std::string& topicId, const std::string& infoId);
TEntryIter begin() const;
///< Iterator pointing to the begin of the main journal.
///
/// \note Iterators to main journal entries will never become invalid.
TEntryIter end() const;
///< Iterator pointing past the end of the main journal.
TQuestIter questBegin() const;
///< Iterator pointing to the first quest (sorted by topic ID)
TQuestIter questEnd() const;
///< Iterator pointing past the last quest.
TTopicIter topicBegin() const;
///< Iterator pointing to the first topic (sorted by topic ID)
///
/// \note The topic ID is identical with the user-visible topic string.
TTopicIter topicEnd() const;
///< Iterator pointing past the last topic.
};
}
#endif

View file

@ -0,0 +1,69 @@
#include "journalentry.hpp"
#include <stdexcept>
#include <components/esm_store/store.hpp>
#include "../mwworld/world.hpp"
namespace MWDialogue
{
JournalEntry::JournalEntry() {}
JournalEntry::JournalEntry (const std::string& topic, const std::string& infoId)
: mTopic (topic), mInfoId (infoId)
{}
std::string JournalEntry::getText (const ESMS::ESMStore& store) const
{
const ESM::Dialogue *dialogue = store.dialogs.find (mTopic);
for (std::vector<ESM::DialInfo>::const_iterator iter (dialogue->mInfo.begin());
iter!=dialogue->mInfo.end(); ++iter)
if (iter->id==mInfoId)
return iter->response;
throw std::runtime_error ("unknown info ID " + mInfoId + " for topic " + mTopic);
}
JournalEntry JournalEntry::makeFromQuest (const std::string& topic, int index,
const MWWorld::World& world)
{
return JournalEntry (topic, idFromIndex (topic, index, world));
}
std::string JournalEntry::idFromIndex (const std::string& topic, int index,
const MWWorld::World& world)
{
const ESM::Dialogue *dialogue = world.getStore().dialogs.find (topic);
for (std::vector<ESM::DialInfo>::const_iterator iter (dialogue->mInfo.begin());
iter!=dialogue->mInfo.end(); ++iter)
if (iter->data.disposition==index) /// \todo cleanup info structure
{
iter->id;
}
throw std::runtime_error ("unknown journal index for topic " + topic);
}
StampedJournalEntry::StampedJournalEntry()
: mDay (0), mMonth (0), mDayOfMonth (0)
{}
StampedJournalEntry::StampedJournalEntry (const std::string& topic, const std::string& infoId,
int day, int month, int dayOfMonth)
: JournalEntry (topic, infoId), mDay (day), mMonth (month), mDayOfMonth (dayOfMonth)
{}
StampedJournalEntry StampedJournalEntry::makeFromQuest (const std::string& topic, int index,
const MWWorld::World& world)
{
int day = world.getGlobalVariable ("dayspassed").mLong;
int month = world.getGlobalVariable ("day").mLong;
int dayOfMonth = world.getGlobalVariable ("month").mLong;
return StampedJournalEntry (topic, idFromIndex (topic, index, world), day, month, dayOfMonth);
}
}

View file

@ -0,0 +1,54 @@
#ifndef GAME_MMDIALOGUE_JOURNALENTRY_H
#define GAME_MMDIALOGUE_JOURNALENTRY_H
#include <string>
namespace ESMS
{
struct ESMStore;
}
namespace MWWorld
{
class World;
}
namespace MWDialogue
{
/// \brief A quest or dialogue entry
struct JournalEntry
{
std::string mTopic;
std::string mInfoId;
JournalEntry();
JournalEntry (const std::string& topic, const std::string& infoId);
std::string getText (const ESMS::ESMStore& store) const;
static JournalEntry makeFromQuest (const std::string& topic, int index,
const MWWorld::World& world);
static std::string idFromIndex (const std::string& topic, int index,
const MWWorld::World& world);
};
/// \biref A quest entry with a timestamp.
struct StampedJournalEntry : public JournalEntry
{
int mDay;
int mMonth;
int mDayOfMonth;
StampedJournalEntry();
StampedJournalEntry (const std::string& topic, const std::string& infoId,
int day, int month, int dayOfMonth);
static StampedJournalEntry makeFromQuest (const std::string& topic, int index,
const MWWorld::World& world);
};
}
#endif

View file

@ -0,0 +1,86 @@
#include "quest.hpp"
#include <components/esm_store/store.hpp>
#include "../mwworld/world.hpp"
namespace MWDialogue
{
Quest::Quest()
: Topic(), mIndex (0), mFinished (false)
{}
Quest::Quest (const std::string& topic)
: Topic (topic), mIndex (0), mFinished (false)
{}
const std::string Quest::getName (const MWWorld::World& world) const
{
const ESM::Dialogue *dialogue = world.getStore().dialogs.find (mTopic);
for (std::vector<ESM::DialInfo>::const_iterator iter (dialogue->mInfo.begin());
iter!=dialogue->mInfo.end(); ++iter)
if (iter->questStatus==ESM::DialInfo::QS_Name)
return iter->response;
return "";
}
int Quest::getIndex() const
{
return mIndex;
}
void Quest::setIndex (int index, const MWWorld::World& world)
{
const ESM::Dialogue *dialogue = world.getStore().dialogs.find (mTopic);
for (std::vector<ESM::DialInfo>::const_iterator iter (dialogue->mInfo.begin());
iter!=dialogue->mInfo.end(); ++iter)
if (iter->data.disposition==index && iter->questStatus!=ESM::DialInfo::QS_Name)
{
mIndex = index;
if (iter->questStatus==ESM::DialInfo::QS_Finished)
mFinished = true;
else if (iter->questStatus==ESM::DialInfo::QS_Restart)
mFinished = false;
return;
}
throw std::runtime_error ("unknown journal index for topic " + mTopic);
}
bool Quest::isFinished() const
{
return mFinished;
}
void Quest::addEntry (const JournalEntry& entry, const MWWorld::World& world)
{
int index = -1;
const ESM::Dialogue *dialogue = world.getStore().dialogs.find (entry.mTopic);
for (std::vector<ESM::DialInfo>::const_iterator iter (dialogue->mInfo.begin());
iter!=dialogue->mInfo.end(); ++iter)
if (iter->id==entry.mInfoId)
{
index = iter->data.disposition; /// \todo cleanup info structure
break;
}
if (index==-1)
throw std::runtime_error ("unknown journal entry for topic " + mTopic);
setIndex (index, world);
for (TEntryIter iter (mEntries.begin()); iter!=mEntries.end(); ++iter)
if (*iter==entry.mInfoId)
return;
mEntries.push_back (entry.mInfoId);
}
}

View file

@ -0,0 +1,37 @@
#ifndef GAME_MMDIALOG_QUEST_H
#define GAME_MWDIALOG_QUEST_H
#include "topic.hpp"
namespace MWDialogue
{
/// \brief A quest in progress or a compelted quest
class Quest : public Topic
{
int mIndex;
bool mFinished;
public:
Quest();
Quest (const std::string& topic);
const std::string getName (const MWWorld::World& world) const;
///< May be an empty string
int getIndex() const;
void setIndex (int index, const MWWorld::World& world);
///< Calling this function with a non-existant index while throw an exception.
bool isFinished() const;
virtual void addEntry (const JournalEntry& entry, const MWWorld::World& world);
///< Add entry and adjust index accordingly.
///
/// \note Redundant entries are ignored, but the index is still adjusted.
};
}
#endif

View file

@ -0,0 +1,46 @@
#include "topic.hpp"
#include <components/esm_store/store.hpp>
#include "../mwworld/world.hpp"
namespace MWDialogue
{
Topic::Topic()
{}
Topic::Topic (const std::string& topic)
: mTopic (topic)
{}
Topic::~Topic()
{}
void Topic::addEntry (const JournalEntry& entry, const MWWorld::World& world)
{
if (entry.mTopic!=mTopic)
throw std::runtime_error ("topic does not match: " + mTopic);
for (TEntryIter iter = begin(); iter!=end(); ++iter)
if (*iter==entry.mInfoId)
return;
mEntries.push_back (entry.mInfoId);
}
Topic::TEntryIter Topic::begin()
{
return mEntries.begin();
}
Topic::TEntryIter Topic::end()
{
return mEntries.end();
}
JournalEntry Topic::getEntry (const std::string& infoId)
{
return JournalEntry (mTopic, infoId);
}
}

View file

@ -0,0 +1,52 @@
#ifndef GAME_MMDIALOG_TOPIC_H
#define GAME_MWDIALOG_TOPIC_H
#include <string>
#include <vector>
#include "journalentry.hpp"
namespace MWWorld
{
class World;
}
namespace MWDialogue
{
/// \brief Collection of seen responses for a topic
class Topic
{
public:
typedef std::vector<std::string> TEntryContainer;
typedef TEntryContainer::const_iterator TEntryIter;
protected:
std::string mTopic;
TEntryContainer mEntries; // info-IDs
public:
Topic();
Topic (const std::string& topic);
virtual ~Topic();
virtual void addEntry (const JournalEntry& entry, const MWWorld::World& world);
///< Add entry
///
/// \note Redundant entries are ignored.
TEntryIter begin();
///< Iterator pointing to the begin of the journal for this topic.
TEntryIter end();
///< Iterator pointing past the end of the journal for this topic.
JournalEntry getEntry (const std::string& infoId);
};
}
#endif

View file

@ -119,8 +119,8 @@ void BirthDialog::updateBirths()
{ {
birthList->removeAllItems(); birthList->removeAllItems();
ESMS::ESMStore &store = mWindowManager.getStore(); const ESMS::ESMStore &store = mWindowManager.getStore();
ESMS::RecListT<ESM::BirthSign>::MapType::const_iterator it = store.birthSigns.list.begin(); ESMS::RecListT<ESM::BirthSign>::MapType::const_iterator it = store.birthSigns.list.begin();
ESMS::RecListT<ESM::BirthSign>::MapType::const_iterator end = store.birthSigns.list.end(); ESMS::RecListT<ESM::BirthSign>::MapType::const_iterator end = store.birthSigns.list.end();
int index = 0; int index = 0;
@ -149,7 +149,7 @@ void BirthDialog::updateSpells()
const int lineHeight = 18; const int lineHeight = 18;
MyGUI::IntCoord coord(0, 0, spellArea->getWidth(), 18); MyGUI::IntCoord coord(0, 0, spellArea->getWidth(), 18);
ESMS::ESMStore &store = mWindowManager.getStore(); const ESMS::ESMStore &store = mWindowManager.getStore();
const ESM::BirthSign *birth = store.birthSigns.find(currentBirthId); const ESM::BirthSign *birth = store.birthSigns.find(currentBirthId);
std::string texturePath = std::string("textures\\") + birth->texture; std::string texturePath = std::string("textures\\") + birth->texture;

View file

@ -50,7 +50,7 @@ void GenerateClassResultDialog::setClassId(const std::string &classId)
{ {
currentClassId = classId; currentClassId = classId;
classImage->setImageTexture(std::string("textures\\levelup\\") + currentClassId + ".dds"); classImage->setImageTexture(std::string("textures\\levelup\\") + currentClassId + ".dds");
ESMS::ESMStore &store = mWindowManager.getStore(); const ESMS::ESMStore &store = mWindowManager.getStore();
className->setCaption(store.classes.find(currentClassId)->name); className->setCaption(store.classes.find(currentClassId)->name);
} }
@ -196,8 +196,8 @@ void PickClassDialog::updateClasses()
{ {
classList->removeAllItems(); classList->removeAllItems();
ESMS::ESMStore &store = mWindowManager.getStore(); const ESMS::ESMStore &store = mWindowManager.getStore();
ESMS::RecListT<ESM::Class>::MapType::const_iterator it = store.classes.list.begin(); ESMS::RecListT<ESM::Class>::MapType::const_iterator it = store.classes.list.begin();
ESMS::RecListT<ESM::Class>::MapType::const_iterator end = store.classes.list.end(); ESMS::RecListT<ESM::Class>::MapType::const_iterator end = store.classes.list.end();
int index = 0; int index = 0;
@ -220,7 +220,7 @@ void PickClassDialog::updateStats()
{ {
if (currentClassId.empty()) if (currentClassId.empty())
return; return;
ESMS::ESMStore &store = mWindowManager.getStore(); const ESMS::ESMStore &store = mWindowManager.getStore();
const ESM::Class *klass = store.classes.search(currentClassId); const ESM::Class *klass = store.classes.search(currentClassId);
if (!klass) if (!klass)
return; return;
@ -767,7 +767,7 @@ SelectSkillDialog::SelectSkillDialog(WindowManager& parWindowManager)
{ {
char theIndex = '0'+i; char theIndex = '0'+i;
getWidget(combatSkill[i], std::string("CombatSkill").append(1, theIndex)); getWidget(combatSkill[i], std::string("CombatSkill").append(1, theIndex));
getWidget(magicSkill[i], std::string("MagicSkill").append(1, theIndex)); getWidget(magicSkill[i], std::string("MagicSkill").append(1, theIndex));
getWidget(stealthSkill[i], std::string("StealthSkill").append(1, theIndex)); getWidget(stealthSkill[i], std::string("StealthSkill").append(1, theIndex));
} }
@ -782,8 +782,8 @@ SelectSkillDialog::SelectSkillDialog(WindowManager& parWindowManager)
{combatSkill[6], ESM::Skill::Axe}, {combatSkill[6], ESM::Skill::Axe},
{combatSkill[7], ESM::Skill::Spear}, {combatSkill[7], ESM::Skill::Spear},
{combatSkill[8], ESM::Skill::Athletics} {combatSkill[8], ESM::Skill::Athletics}
}, },
{ {
{magicSkill[0], ESM::Skill::Enchant}, {magicSkill[0], ESM::Skill::Enchant},
{magicSkill[1], ESM::Skill::Destruction}, {magicSkill[1], ESM::Skill::Destruction},
{magicSkill[2], ESM::Skill::Alteration}, {magicSkill[2], ESM::Skill::Alteration},
@ -793,8 +793,8 @@ SelectSkillDialog::SelectSkillDialog(WindowManager& parWindowManager)
{magicSkill[6], ESM::Skill::Restoration}, {magicSkill[6], ESM::Skill::Restoration},
{magicSkill[7], ESM::Skill::Alchemy}, {magicSkill[7], ESM::Skill::Alchemy},
{magicSkill[8], ESM::Skill::Unarmored} {magicSkill[8], ESM::Skill::Unarmored}
}, },
{ {
{stealthSkill[0], ESM::Skill::Security}, {stealthSkill[0], ESM::Skill::Security},
{stealthSkill[1], ESM::Skill::Sneak}, {stealthSkill[1], ESM::Skill::Sneak},
{stealthSkill[2], ESM::Skill::Acrobatics}, {stealthSkill[2], ESM::Skill::Acrobatics},

View file

@ -17,6 +17,8 @@ namespace MWGui
ConsoleInterpreterContext (Console& console, MWWorld::Environment& environment, ConsoleInterpreterContext (Console& console, MWWorld::Environment& environment,
MWWorld::Ptr reference); MWWorld::Ptr reference);
virtual void report (const std::string& message);
}; };
ConsoleInterpreterContext::ConsoleInterpreterContext (Console& console, ConsoleInterpreterContext::ConsoleInterpreterContext (Console& console,
@ -26,6 +28,11 @@ namespace MWGui
mConsole (console) mConsole (console)
{} {}
void ConsoleInterpreterContext::report (const std::string& message)
{
mConsole.printOK (message);
}
bool Console::compile (const std::string& cmd, Compiler::Output& output) bool Console::compile (const std::string& cmd, Compiler::Output& output)
{ {
try try

View file

@ -212,8 +212,8 @@ void RaceDialog::updateRaces()
{ {
raceList->removeAllItems(); raceList->removeAllItems();
ESMS::ESMStore &store = mWindowManager.getStore(); const ESMS::ESMStore &store = mWindowManager.getStore();
ESMS::RecListT<ESM::Race>::MapType::const_iterator it = store.races.list.begin(); ESMS::RecListT<ESM::Race>::MapType::const_iterator it = store.races.list.begin();
ESMS::RecListT<ESM::Race>::MapType::const_iterator end = store.races.list.end(); ESMS::RecListT<ESM::Race>::MapType::const_iterator end = store.races.list.end();
int index = 0; int index = 0;
@ -246,7 +246,7 @@ void RaceDialog::updateSkills()
const int lineHeight = 18; const int lineHeight = 18;
MyGUI::IntCoord coord1(0, 0, skillList->getWidth(), 18); MyGUI::IntCoord coord1(0, 0, skillList->getWidth(), 18);
ESMS::ESMStore &store = mWindowManager.getStore(); const ESMS::ESMStore &store = mWindowManager.getStore();
const ESM::Race *race = store.races.find(currentRaceId); const ESM::Race *race = store.races.find(currentRaceId);
int count = sizeof(race->data.bonus)/sizeof(race->data.bonus[0]); // TODO: Find a portable macro for this ARRAYSIZE? int count = sizeof(race->data.bonus)/sizeof(race->data.bonus[0]); // TODO: Find a portable macro for this ARRAYSIZE?
for (int i = 0; i < count; ++i) for (int i = 0; i < count; ++i)
@ -282,7 +282,7 @@ void RaceDialog::updateSpellPowers()
const int lineHeight = 18; const int lineHeight = 18;
MyGUI::IntCoord coord(0, 0, spellPowerList->getWidth(), 18); MyGUI::IntCoord coord(0, 0, spellPowerList->getWidth(), 18);
ESMS::ESMStore &store = mWindowManager.getStore(); const ESMS::ESMStore &store = mWindowManager.getStore();
const ESM::Race *race = store.races.find(currentRaceId); const ESM::Race *race = store.races.find(currentRaceId);
std::vector<std::string>::const_iterator it = race->powers.list.begin(); std::vector<std::string>::const_iterator it = race->powers.list.begin();

View file

@ -323,7 +323,7 @@ void StatsWindow::updateSkillArea()
if (!miscSkills.empty()) if (!miscSkills.empty())
addSkills(miscSkills, "sSkillClassMisc", "Misc Skills", coord1, coord2); addSkills(miscSkills, "sSkillClassMisc", "Misc Skills", coord1, coord2);
ESMS::ESMStore &store = mWindowManager.getStore(); const ESMS::ESMStore &store = mWindowManager.getStore();
if (!factions.empty()) if (!factions.empty())
{ {

View file

@ -278,7 +278,7 @@ void MWSpell::setSpellId(const std::string &spellId)
void MWSpell::createEffectWidgets(std::vector<MyGUI::WidgetPtr> &effects, MyGUI::WidgetPtr creator, MyGUI::IntCoord &coord) void MWSpell::createEffectWidgets(std::vector<MyGUI::WidgetPtr> &effects, MyGUI::WidgetPtr creator, MyGUI::IntCoord &coord)
{ {
ESMS::ESMStore &store = mWindowManager->getStore(); const ESMS::ESMStore &store = mWindowManager->getStore();
const ESM::Spell *spell = store.spells.search(id); const ESM::Spell *spell = store.spells.search(id);
MYGUI_ASSERT(spell, "spell with id '" << id << "' not found"); MYGUI_ASSERT(spell, "spell with id '" << id << "' not found");
@ -298,7 +298,7 @@ void MWSpell::updateWidgets()
{ {
if (spellNameWidget && mWindowManager) if (spellNameWidget && mWindowManager)
{ {
ESMS::ESMStore &store = mWindowManager->getStore(); const ESMS::ESMStore &store = mWindowManager->getStore();
const ESM::Spell *spell = store.spells.search(id); const ESM::Spell *spell = store.spells.search(id);
if (spell) if (spell)
spellNameWidget->setCaption(spell->name); spellNameWidget->setCaption(spell->name);
@ -363,7 +363,7 @@ void MWSpellEffect::updateWidgets()
if (!mWindowManager) if (!mWindowManager)
return; return;
ESMS::ESMStore &store = mWindowManager->getStore(); const ESMS::ESMStore &store = mWindowManager->getStore();
const ESM::MagicEffect *magicEffect = store.magicEffects.search(effect.effectID); const ESM::MagicEffect *magicEffect = store.magicEffects.search(effect.effectID);
if (textWidget) if (textWidget)
{ {

View file

@ -940,7 +940,7 @@ void WindowManager::onReviewActivateDialog(int parDialog)
}; };
} }
ESMS::ESMStore& WindowManager::getStore() const ESMS::ESMStore& WindowManager::getStore() const
{ {
return environment.mWorld->getStore(); return environment.mWorld->getStore();
} }

View file

@ -257,7 +257,7 @@ namespace MWGui
*/ */
const std::string &getGameSettingString(const std::string &id, const std::string &default_); const std::string &getGameSettingString(const std::string &id, const std::string &default_);
ESMS::ESMStore& getStore(); const ESMS::ESMStore& getStore() const;
private: private:

View file

@ -191,7 +191,7 @@ void MWScene::scaleObject (const std::string& handle, float scale)
} }
void MWScene::toggleCollisionMode() bool MWScene::toggleCollisionMode()
{ {
for(std::map<std::string,OEngine::Physic::PhysicActor*>::iterator it = eng->PhysicActorMap.begin(); it != eng->PhysicActorMap.end();it++) for(std::map<std::string,OEngine::Physic::PhysicActor*>::iterator it = eng->PhysicActorMap.begin(); it != eng->PhysicActorMap.end();it++)
{ {
@ -203,6 +203,7 @@ void MWScene::toggleCollisionMode()
act->setGravity(0.); act->setGravity(0.);
act->setVerticalVelocity(0); act->setVerticalVelocity(0);
mFreeFly = true; mFreeFly = true;
return false;
} }
else else
{ {
@ -210,11 +211,15 @@ void MWScene::toggleCollisionMode()
act->enableCollisions(true); act->enableCollisions(true);
act->setGravity(4.); act->setGravity(4.);
act->setVerticalVelocity(0); act->setVerticalVelocity(0);
return true;
} }
} }
return false; // This should never happen, but it shall not bother us now, since
// this part of the code needs a rewrite anyway.
} }
void MWScene::toggleRenderMode (int mode) bool MWScene::toggleRenderMode (int mode)
{ {
switch (mode) switch (mode)
{ {
@ -223,6 +228,8 @@ void MWScene::toggleRenderMode (int mode)
// TODO use a proper function instead of accessing the member variable // TODO use a proper function instead of accessing the member variable
// directly. // directly.
eng->setDebugRenderingMode (!eng->isDebugCreated); eng->setDebugRenderingMode (!eng->isDebugCreated);
break; return eng->isDebugCreated;
} }
return false;
} }

View file

@ -91,12 +91,14 @@ namespace MWRender
/// Toggle collision mode for player. If disabled player object should ignore /// Toggle collision mode for player. If disabled player object should ignore
/// collisions and gravity. /// collisions and gravity.
void toggleCollisionMode(); /// \return Resulting mode
bool toggleCollisionMode();
/// Toggle render mode /// Toggle render mode
/// \todo Using an int instead of a enum here to avoid cyclic includes. Will be fixed /// \todo Using an int instead of a enum here to avoid cyclic includes. Will be fixed
/// when the mw*-refactoring is done. /// when the mw*-refactoring is done.
void toggleRenderMode (int mode); /// \return Resulting mode
bool toggleRenderMode (int mode);
}; };
} }

View file

@ -102,10 +102,42 @@ namespace MWScript
} }
}; };
class OpGetPCCell : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
InterpreterContext& context
= static_cast<InterpreterContext&> (runtime.getContext());
std::string name = runtime.getStringLiteral (runtime[0].mInteger);
runtime.pop();
const ESM::Cell *cell = context.getWorld().getPlayer().getPlayer().getCell()->cell;
std::string current = cell->name;
if (!(cell->data.flags & ESM::Cell::Interior) && current.empty())
{
const ESM::Region *region =
context.getWorld().getStore().regions.find (cell->region);
current = region->name;
}
bool match = current.length()>=name.length() &&
current.substr (0, name.length())==name;
runtime.push (match ? 1 : 0);
}
};
const int opcodeCellChanged = 0x2000000; const int opcodeCellChanged = 0x2000000;
const int opcodeCOC = 0x2000026; const int opcodeCOC = 0x2000026;
const int opcodeCOE = 0x200008e; const int opcodeCOE = 0x200008e;
const int opcodeGetInterior = 0x2000131; const int opcodeGetInterior = 0x2000131;
const int opcodeGetPCCell = 0x2000136;
void registerExtensions (Compiler::Extensions& extensions) void registerExtensions (Compiler::Extensions& extensions)
{ {
@ -115,6 +147,7 @@ namespace MWScript
extensions.registerInstruction ("coe", "ll", opcodeCOE); extensions.registerInstruction ("coe", "ll", opcodeCOE);
extensions.registerInstruction ("centeronexterior", "ll", opcodeCOE); extensions.registerInstruction ("centeronexterior", "ll", opcodeCOE);
extensions.registerFunction ("getinterior", 'l', "", opcodeGetInterior); extensions.registerFunction ("getinterior", 'l', "", opcodeGetInterior);
extensions.registerFunction ("getpccell", 'l', "c", opcodeGetPCCell);
} }
void installOpcodes (Interpreter::Interpreter& interpreter) void installOpcodes (Interpreter::Interpreter& interpreter)
@ -123,6 +156,7 @@ namespace MWScript
interpreter.installSegment5 (opcodeCOC, new OpCOC); interpreter.installSegment5 (opcodeCOC, new OpCOC);
interpreter.installSegment5 (opcodeCOE, new OpCOE); interpreter.installSegment5 (opcodeCOE, new OpCOE);
interpreter.installSegment5 (opcodeGetInterior, new OpGetInterior); interpreter.installSegment5 (opcodeGetInterior, new OpGetInterior);
interpreter.installSegment5 (opcodeGetPCCell, new OpGetPCCell);
} }
} }
} }

View file

@ -46,7 +46,9 @@ namespace MWScript
InterpreterContext& context InterpreterContext& context
= static_cast<InterpreterContext&> (runtime.getContext()); = static_cast<InterpreterContext&> (runtime.getContext());
context.getWorld().toggleCollisionMode(); bool enabled = context.getWorld().toggleCollisionMode();
context.report (enabled ? "Collsion -> On" : "Collision -> Off");
} }
}; };
@ -74,6 +76,7 @@ namespace MWScript
} }
extensions.registerInstruction ("togglecollision", "", opcodeToggleCollision); extensions.registerInstruction ("togglecollision", "", opcodeToggleCollision);
extensions.registerInstruction ("tcl", "", opcodeToggleCollision);
} }
void installOpcodes (Interpreter::Interpreter& interpreter) void installOpcodes (Interpreter::Interpreter& interpreter)

View file

@ -0,0 +1,94 @@
#include "dialogueextensions.hpp"
#include <components/compiler/extensions.hpp>
#include <components/interpreter/interpreter.hpp>
#include <components/interpreter/runtime.hpp>
#include <components/interpreter/opcodes.hpp>
#include "../mwdialogue/journal.hpp"
#include "interpretercontext.hpp"
namespace MWScript
{
namespace Dialogue
{
class OpJournal : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
MWScript::InterpreterContext& context
= static_cast<MWScript::InterpreterContext&> (runtime.getContext());
std::string quest = runtime.getStringLiteral (runtime[0].mInteger);
runtime.pop();
Interpreter::Type_Integer index = runtime[0].mInteger;
runtime.pop();
context.getEnvironment().mJournal->addEntry (quest, index);
}
};
class OpSetJournalIndex : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
MWScript::InterpreterContext& context
= static_cast<MWScript::InterpreterContext&> (runtime.getContext());
std::string quest = runtime.getStringLiteral (runtime[0].mInteger);
runtime.pop();
Interpreter::Type_Integer index = runtime[0].mInteger;
runtime.pop();
context.getEnvironment().mJournal->setJournalIndex (quest, index);
}
};
class OpGetJournalIndex : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
MWScript::InterpreterContext& context
= static_cast<MWScript::InterpreterContext&> (runtime.getContext());
std::string quest = runtime.getStringLiteral (runtime[0].mInteger);
runtime.pop();
int index = context.getEnvironment().mJournal->getJournalIndex (quest);
runtime.push (index);
}
};
const int opcodeJournal = 0x2000133;
const int opcodeSetJournalIndex = 0x2000134;
const int opcodeGetJournalIndex = 0x2000135;
void registerExtensions (Compiler::Extensions& extensions)
{
extensions.registerInstruction ("journal", "cl", opcodeJournal);
extensions.registerInstruction ("setjournalindex", "cl", opcodeSetJournalIndex);
extensions.registerFunction ("getjournalindex", 'l', "c", opcodeGetJournalIndex);
}
void installOpcodes (Interpreter::Interpreter& interpreter)
{
interpreter.installSegment5 (opcodeJournal, new OpJournal);
interpreter.installSegment5 (opcodeSetJournalIndex, new OpSetJournalIndex);
interpreter.installSegment5 (opcodeGetJournalIndex, new OpGetJournalIndex);
}
}
}

View file

@ -0,0 +1,25 @@
#ifndef GAME_SCRIPT_DIALOGUEEXTENSIONS_H
#define GAME_SCRIPT_DIALOGUEEXTENSIONS_H
namespace Compiler
{
class Extensions;
}
namespace Interpreter
{
class Interpreter;
}
namespace MWScript
{
/// \brief Dialogue/Journal-related script functionality
namespace Dialogue
{
void registerExtensions (Compiler::Extensions& extensions);
void installOpcodes (Interpreter::Interpreter& interpreter);
}
}
#endif

View file

@ -104,4 +104,8 @@ op 0x2000115-0x200012f: ModSKill, explicit reference
op 0x2000130: ToggleCollision op 0x2000130: ToggleCollision
op 0x2000131: GetInterior op 0x2000131: GetInterior
op 0x2000132: ToggleCollsionDebug op 0x2000132: ToggleCollsionDebug
opcodes 0x2000133-0x3ffffff unused op 0x2000133: Journal
op 0x2000134: SetJournalIndex
op 0x2000135: GetJournalIndex
op 0x2000136: GetPCCell
opcodes 0x2000137-0x3ffffff unused

View file

@ -13,6 +13,7 @@
#include "containerextensions.hpp" #include "containerextensions.hpp"
#include "aiextensions.hpp" #include "aiextensions.hpp"
#include "controlextensions.hpp" #include "controlextensions.hpp"
#include "dialogueextensions.hpp"
namespace MWScript namespace MWScript
{ {
@ -27,6 +28,7 @@ namespace MWScript
Container::registerExtensions (extensions); Container::registerExtensions (extensions);
Ai::registerExtensions (extensions); Ai::registerExtensions (extensions);
Control::registerExtensions (extensions); Control::registerExtensions (extensions);
Dialogue::registerExtensions (extensions);
} }
void installOpcodes (Interpreter::Interpreter& interpreter) void installOpcodes (Interpreter::Interpreter& interpreter)
@ -41,5 +43,6 @@ namespace MWScript
Container::installOpcodes (interpreter); Container::installOpcodes (interpreter);
Ai::installOpcodes (interpreter); Ai::installOpcodes (interpreter);
Control::installOpcodes (interpreter); Control::installOpcodes (interpreter);
Dialogue::installOpcodes (interpreter);
} }
} }

View file

@ -110,6 +110,11 @@ namespace MWScript
mEnvironment.mWindowManager->messageBox (message, buttons); mEnvironment.mWindowManager->messageBox (message, buttons);
} }
void InterpreterContext::report (const std::string& message)
{
messageBox (message);
}
bool InterpreterContext::menuMode() bool InterpreterContext::menuMode()
{ {
return mEnvironment.mWindowManager->isGuiMode(); return mEnvironment.mWindowManager->isGuiMode();
@ -260,6 +265,11 @@ namespace MWScript
mEnvironment.mWorld->disable (ref); mEnvironment.mWorld->disable (ref);
} }
MWWorld::Environment& InterpreterContext::getEnvironment()
{
return mEnvironment;
}
MWGui::WindowManager& InterpreterContext::getWindowManager() MWGui::WindowManager& InterpreterContext::getWindowManager()
{ {
return *mEnvironment.mWindowManager; return *mEnvironment.mWindowManager;

View file

@ -57,9 +57,13 @@ namespace MWScript
virtual void setLocalFloat (int index, float value); virtual void setLocalFloat (int index, float value);
using Interpreter::Context::messageBox; using Interpreter::Context::messageBox;
virtual void messageBox (const std::string& message, virtual void messageBox (const std::string& message,
const std::vector<std::string>& buttons); const std::vector<std::string>& buttons);
virtual void report (const std::string& message);
///< By default echo via messageBox.
virtual bool menuMode(); virtual bool menuMode();
virtual int getGlobalShort (const std::string& name) const; virtual int getGlobalShort (const std::string& name) const;
@ -106,6 +110,10 @@ namespace MWScript
virtual void disable (const std::string& id = ""); virtual void disable (const std::string& id = "");
MWWorld::Environment& getEnvironment();
/// \todo remove the following functions (extentions should use getEnvironment instead)
MWWorld::World& getWorld(); MWWorld::World& getWorld();
MWSound::SoundManager& getSoundManager(); MWSound::SoundManager& getSoundManager();

View file

@ -99,7 +99,11 @@ namespace MWScript
InterpreterContext& context = InterpreterContext& context =
static_cast<InterpreterContext&> (runtime.getContext()); static_cast<InterpreterContext&> (runtime.getContext());
context.getWorld().toggleRenderMode (MWWorld::World::Render_CollisionDebug); bool enabled =
context.getWorld().toggleRenderMode (MWWorld::World::Render_CollisionDebug);
context.report (enabled ?
"Collsion Mesh Rendering -> On" : "Collision Mesh Rendering -> Off");
} }
}; };

View file

@ -16,68 +16,70 @@ namespace MWScript
class OpToggleSky : public Interpreter::Opcode0 class OpToggleSky : public Interpreter::Opcode0
{ {
public: public:
virtual void execute (Interpreter::Runtime& runtime) virtual void execute (Interpreter::Runtime& runtime)
{ {
InterpreterContext& context = InterpreterContext& context =
static_cast<InterpreterContext&> (runtime.getContext()); static_cast<InterpreterContext&> (runtime.getContext());
context.getWorld().toggleSky(); bool enabled = context.getWorld().toggleSky();
}
}; context.report (enabled ? "Sky -> On" : "Sky -> Off");
}
};
class OpTurnMoonWhite : public Interpreter::Opcode0 class OpTurnMoonWhite : public Interpreter::Opcode0
{ {
public: public:
virtual void execute (Interpreter::Runtime& runtime) virtual void execute (Interpreter::Runtime& runtime)
{ {
InterpreterContext& context = InterpreterContext& context =
static_cast<InterpreterContext&> (runtime.getContext()); static_cast<InterpreterContext&> (runtime.getContext());
context.getWorld().setMoonColour (false); context.getWorld().setMoonColour (false);
} }
}; };
class OpTurnMoonRed : public Interpreter::Opcode0 class OpTurnMoonRed : public Interpreter::Opcode0
{ {
public: public:
virtual void execute (Interpreter::Runtime& runtime) virtual void execute (Interpreter::Runtime& runtime)
{ {
InterpreterContext& context = InterpreterContext& context =
static_cast<InterpreterContext&> (runtime.getContext()); static_cast<InterpreterContext&> (runtime.getContext());
context.getWorld().setMoonColour (true); context.getWorld().setMoonColour (true);
} }
}; };
class OpGetMasserPhase : public Interpreter::Opcode0 class OpGetMasserPhase : public Interpreter::Opcode0
{ {
public: public:
virtual void execute (Interpreter::Runtime& runtime) virtual void execute (Interpreter::Runtime& runtime)
{ {
InterpreterContext& context = InterpreterContext& context =
static_cast<InterpreterContext&> (runtime.getContext()); static_cast<InterpreterContext&> (runtime.getContext());
runtime.push (context.getWorld().getMasserPhase()); runtime.push (context.getWorld().getMasserPhase());
} }
}; };
class OpGetSecundaPhase : public Interpreter::Opcode0 class OpGetSecundaPhase : public Interpreter::Opcode0
{ {
public: public:
virtual void execute (Interpreter::Runtime& runtime) virtual void execute (Interpreter::Runtime& runtime)
{ {
InterpreterContext& context = InterpreterContext& context =
static_cast<InterpreterContext&> (runtime.getContext()); static_cast<InterpreterContext&> (runtime.getContext());
runtime.push (context.getWorld().getSecundaPhase()); runtime.push (context.getWorld().getSecundaPhase());
} }
}; };
const int opcodeToggleSky = 0x2000021; const int opcodeToggleSky = 0x2000021;
const int opcodeTurnMoonWhite = 0x2000022; const int opcodeTurnMoonWhite = 0x2000022;
const int opcodeTurnMoonRed = 0x2000023; const int opcodeTurnMoonRed = 0x2000023;
@ -93,7 +95,7 @@ namespace MWScript
extensions.registerFunction ("getmasserphase", 'l', "", opcodeGetMasserPhase); extensions.registerFunction ("getmasserphase", 'l', "", opcodeGetMasserPhase);
extensions.registerFunction ("getsecundaphase", 'l', "", opcodeGetSecundaPhase); extensions.registerFunction ("getsecundaphase", 'l', "", opcodeGetSecundaPhase);
} }
void installOpcodes (Interpreter::Interpreter& interpreter) void installOpcodes (Interpreter::Interpreter& interpreter)
{ {
interpreter.installSegment5 (opcodeToggleSky, new OpToggleSky); interpreter.installSegment5 (opcodeToggleSky, new OpToggleSky);
@ -101,7 +103,6 @@ namespace MWScript
interpreter.installSegment5 (opcodeTurnMoonRed, new OpTurnMoonRed); interpreter.installSegment5 (opcodeTurnMoonRed, new OpTurnMoonRed);
interpreter.installSegment5 (opcodeGetMasserPhase, new OpGetMasserPhase); interpreter.installSegment5 (opcodeGetMasserPhase, new OpGetMasserPhase);
interpreter.installSegment5 (opcodeGetSecundaPhase, new OpGetSecundaPhase); interpreter.installSegment5 (opcodeGetSecundaPhase, new OpGetSecundaPhase);
} }
} }
} }

View file

@ -24,6 +24,7 @@ namespace MWMechanics
namespace MWDialogue namespace MWDialogue
{ {
class DialogueManager; class DialogueManager;
class Journal;
} }
namespace MWInput namespace MWInput
@ -41,7 +42,7 @@ namespace MWWorld
public: public:
Environment() Environment()
: mWorld (0), mSoundManager (0), mGlobalScripts (0), mWindowManager (0), : mWorld (0), mSoundManager (0), mGlobalScripts (0), mWindowManager (0),
mMechanicsManager (0), mDialogueManager (0), mFrameDuration (0), mMechanicsManager (0), mDialogueManager (0), mJournal (0), mFrameDuration (0),
mInputManager (0) mInputManager (0)
{} {}
@ -51,6 +52,7 @@ namespace MWWorld
MWGui::WindowManager *mWindowManager; MWGui::WindowManager *mWindowManager;
MWMechanics::MechanicsManager *mMechanicsManager; MWMechanics::MechanicsManager *mMechanicsManager;
MWDialogue::DialogueManager *mDialogueManager; MWDialogue::DialogueManager *mDialogueManager;
MWDialogue::Journal *mJournal;
float mFrameDuration; float mFrameDuration;
// For setting GUI mode // For setting GUI mode

View file

@ -460,7 +460,7 @@ namespace MWWorld
return *mPlayer; return *mPlayer;
} }
ESMS::ESMStore& World::getStore() const ESMS::ESMStore& World::getStore() const
{ {
return mStore; return mStore;
} }
@ -480,6 +480,11 @@ namespace MWWorld
return (*mGlobalVariables)[name]; return (*mGlobalVariables)[name];
} }
Globals::Data World::getGlobalVariable (const std::string& name) const
{
return (*mGlobalVariables)[name];
}
char World::getGlobalVariableType (const std::string& name) const char World::getGlobalVariableType (const std::string& name) const
{ {
return mGlobalVariables->getType (name); return mGlobalVariables->getType (name);
@ -645,12 +650,13 @@ namespace MWWorld
mSkyManager->setDate (mGlobalVariables->getInt ("day"), month); mSkyManager->setDate (mGlobalVariables->getInt ("day"), month);
} }
void World::toggleSky() bool World::toggleSky()
{ {
if (mSky) if (mSky)
{ {
mSky = false; mSky = false;
mSkyManager->disable(); mSkyManager->disable();
return false;
} }
else else
{ {
@ -660,6 +666,7 @@ namespace MWWorld
mSkyManager->setDate (mGlobalVariables->getInt ("day"), mSkyManager->setDate (mGlobalVariables->getInt ("day"),
mGlobalVariables->getInt ("month")); mGlobalVariables->getInt ("month"));
mSkyManager->enable(); mSkyManager->enable();
return true;
} }
} }
@ -853,13 +860,13 @@ namespace MWWorld
mScene.doPhysics (duration, *this, actors); mScene.doPhysics (duration, *this, actors);
} }
void World::toggleCollisionMode() bool World::toggleCollisionMode()
{ {
mScene.toggleCollisionMode(); return mScene.toggleCollisionMode();
} }
void World::toggleRenderMode (RenderMode mode) bool World::toggleRenderMode (RenderMode mode)
{ {
mScene.toggleRenderMode (mode); return mScene.toggleRenderMode (mode);
} }
} }

View file

@ -115,7 +115,7 @@ namespace MWWorld
MWWorld::Player& getPlayer(); MWWorld::Player& getPlayer();
ESMS::ESMStore& getStore(); const ESMS::ESMStore& getStore() const;
const ScriptList& getLocalScripts() const; const ScriptList& getLocalScripts() const;
///< Names and local variable state of all local scripts in active cells. ///< Names and local variable state of all local scripts in active cells.
@ -125,6 +125,8 @@ namespace MWWorld
Globals::Data& getGlobalVariable (const std::string& name); Globals::Data& getGlobalVariable (const std::string& name);
Globals::Data getGlobalVariable (const std::string& name) const;
char getGlobalVariableType (const std::string& name) const; char getGlobalVariableType (const std::string& name) const;
///< Return ' ', if there is no global variable with this name. ///< Return ' ', if there is no global variable with this name.
@ -147,7 +149,8 @@ namespace MWWorld
void setDay (int day); void setDay (int day);
void toggleSky(); bool toggleSky();
///< \return Resulting mode
int getMasserPhase() const; int getMasserPhase() const;
@ -185,12 +188,14 @@ namespace MWWorld
float duration); float duration);
///< Run physics simulation and modify \a world accordingly. ///< Run physics simulation and modify \a world accordingly.
void toggleCollisionMode(); bool toggleCollisionMode();
///< Toggle collision mode for player. If disabled player object should ignore ///< Toggle collision mode for player. If disabled player object should ignore
/// collisions and gravity. /// collisions and gravity.
///< \return Resulting mode
void toggleRenderMode (RenderMode mode); bool toggleRenderMode (RenderMode mode);
///< Toggle a render mode. ///< Toggle a render mode.
///< \return Resulting mode
}; };
} }

View file

@ -1,25 +0,0 @@
#ifndef PATH__HPP
#define PATH__HPP
#include <OgrePlatform.h>
#include <string>
#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE
#include <OSX/macUtils.h>
#endif
namespace OMW
{
class Path
{
public:
enum PathTypeEnum
{
USER_CFG_PATH,
GLOBAL_CFG_PATH
};
static std::string getPath(PathTypeEnum parType, const std::string parApp, const std::string parFile);
};
}
#endif

View file

@ -125,6 +125,11 @@ namespace
code.push_back (Compiler::Generator::segment3 (0, buttons)); code.push_back (Compiler::Generator::segment3 (0, buttons));
} }
void opReport (Compiler::Generator::CodeContainer& code)
{
code.push_back (Compiler::Generator::segment5 (58));
}
void opFetchLocalShort (Compiler::Generator::CodeContainer& code) void opFetchLocalShort (Compiler::Generator::CodeContainer& code)
{ {
code.push_back (Compiler::Generator::segment5 (21)); code.push_back (Compiler::Generator::segment5 (21));
@ -516,6 +521,14 @@ namespace Compiler
opMessageBox (code, buttons); opMessageBox (code, buttons);
} }
void report (CodeContainer& code, Literals& literals, const std::string& message)
{
int index = literals.addString (message);
opPushInt (code, index);
opReport (code);
}
void fetchLocal (CodeContainer& code, char localType, int localIndex) void fetchLocal (CodeContainer& code, char localType, int localIndex)
{ {
opPushInt (code, localIndex); opPushInt (code, localIndex);

View file

@ -81,6 +81,8 @@ namespace Compiler
void message (CodeContainer& code, Literals& literals, const std::string& message, void message (CodeContainer& code, Literals& literals, const std::string& message,
int buttons); int buttons);
void report (CodeContainer& code, Literals& literals, const std::string& message);
void fetchLocal (CodeContainer& code, char localType, int localIndex); void fetchLocal (CodeContainer& code, char localType, int localIndex);
void jump (CodeContainer& code, int offset); void jump (CodeContainer& code, int offset);

View file

@ -30,12 +30,12 @@ namespace Compiler
{ {
case 'l': case 'l':
Generator::message (mCode, mLiterals, "%g", 0); Generator::report (mCode, mLiterals, "%g");
break; break;
case 'f': case 'f':
Generator::message (mCode, mLiterals, "%f", 0); Generator::report (mCode, mLiterals, "%f");
break; break;
default: default:

View file

@ -23,12 +23,16 @@ enum VarType
enum Specialization enum Specialization
{ {
SPC_Combat = 0, SPC_Magic = 1, SPC_Stealth = 2 SPC_Combat = 0,
SPC_Magic = 1,
SPC_Stealth = 2
}; };
enum RangeType enum RangeType
{ {
RT_Self = 0, RT_Touch = 1, RT_Target = 2 RT_Self = 0,
RT_Touch = 1,
RT_Target = 2
}; };
/** A list of references to spells and spell effects. This is shared /** A list of references to spells and spell effects. This is shared

View file

@ -14,7 +14,10 @@ struct Apparatus
{ {
enum AppaType enum AppaType
{ {
MortarPestle = 0, Albemic = 1, Calcinator = 2, Retort = 3 MortarPestle = 0,
Albemic = 1,
Calcinator = 2,
Retort = 3
}; };
struct AADTstruct struct AADTstruct

View file

@ -29,12 +29,15 @@ struct BodyPart
enum Flags enum Flags
{ {
BPF_Female = 1, BPF_Playable = 2 BPF_Female = 1,
BPF_Playable = 2
}; };
enum MeshType enum MeshType
{ {
MT_Skin = 0, MT_Clothing = 1, MT_Armor = 2 MT_Skin = 0,
MT_Clothing = 1,
MT_Armor = 2
}; };
struct BYDTstruct struct BYDTstruct

View file

@ -38,7 +38,9 @@ struct Class
enum Specialization enum Specialization
{ {
Combat = 0, Magic = 1, Stealth = 2 Combat = 0,
Magic = 1,
Stealth = 2
}; };
static const Specialization specializationIds[3]; static const Specialization specializationIds[3];

View file

@ -30,7 +30,10 @@ struct Creature
enum Type enum Type
{ {
Creatures = 0, Deadra = 1, Undead = 2, Humanoid = 3 Creatures = 0,
Deadra = 1,
Undead = 2,
Humanoid = 3
}; };
struct NPDTstruct struct NPDTstruct

View file

@ -3,7 +3,8 @@
#include "esm_reader.hpp" #include "esm_reader.hpp"
namespace ESM { namespace ESM
{
/* /*
* Sound generator. This describes the sounds a creature make. * Sound generator. This describes the sounds a creature make.
@ -11,24 +12,24 @@ namespace ESM {
struct SoundGenerator struct SoundGenerator
{ {
enum Type enum Type
{ {
LeftFoot = 0, LeftFoot = 0,
RightFoot = 1, RightFoot = 1,
SwimLeft = 2, SwimLeft = 2,
SwimRight = 3, SwimRight = 3,
Moan = 4, Moan = 4,
Roar = 5, Roar = 5,
Scream = 6, Scream = 6,
Land = 7 Land = 7
}; };
// Type // Type
int type; int type;
std::string creature, sound; std::string creature, sound;
void load(ESMReader &esm); void load(ESMReader &esm);
}; };
} }
#endif #endif

View file

@ -2,15 +2,21 @@
#include <boost/filesystem.hpp> #include <boost/filesystem.hpp>
#include <OgrePlatform.h>
#include <string>
#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE
#include <OSX/macUtils.h>
#endif
#if OGRE_PLATFORM == OGRE_PLATFORM_LINUX #if OGRE_PLATFORM == OGRE_PLATFORM_LINUX
#include <stdlib.h> //getenv #include <stdlib.h> //getenv
#endif #endif
std::string Files::getPath (PathTypeEnum parType, const std::string parApp, const std::string parFile)
std::string OMW::Path::getPath(PathTypeEnum parType, const std::string parApp, const std::string parFile)
{ {
std::string theBasePath; std::string theBasePath;
if(parType == GLOBAL_CFG_PATH) if (parType==Path_ConfigGlobal)
{ {
#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE #if OGRE_PLATFORM == OGRE_PLATFORM_APPLE
theBasePath = Ogre::macBundlePath() + "/Contents/MacOS/"; //FIXME do we have global/local with OSX? theBasePath = Ogre::macBundlePath() + "/Contents/MacOS/"; //FIXME do we have global/local with OSX?
@ -21,7 +27,7 @@ std::string OMW::Path::getPath(PathTypeEnum parType, const std::string parApp, c
#endif #endif
} }
else else if (parType==Path_ConfigUser)
{ {
#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE #if OGRE_PLATFORM == OGRE_PLATFORM_APPLE
theBasePath = Ogre::macBundlePath() + "/Contents/MacOS/"; //FIXME do we have global/local with OSX? theBasePath = Ogre::macBundlePath() + "/Contents/MacOS/"; //FIXME do we have global/local with OSX?
@ -53,4 +59,3 @@ std::string OMW::Path::getPath(PathTypeEnum parType, const std::string parApp, c
theBasePath.append(parFile); theBasePath.append(parFile);
return theBasePath; return theBasePath;
} }

17
components/files/path.hpp Normal file
View file

@ -0,0 +1,17 @@
#ifndef COMPONENTS_FILES_PATH_HPP
#define COMPONENTS_FILES_PATH_HPP
#include <string>
namespace Files
{
enum PathTypeEnum
{
Path_ConfigUser,
Path_ConfigGlobal
};
std::string getPath (PathTypeEnum parType, const std::string parApp, const std::string parFile);
}
#endif

View file

@ -18,21 +18,23 @@ namespace Interpreter
virtual float getLocalFloat (int index) const = 0; virtual float getLocalFloat (int index) const = 0;
virtual void setLocalShort (int index, int value) = 0; virtual void setLocalShort (int index, int value) = 0;
virtual void setLocalLong (int index, int value) = 0; virtual void setLocalLong (int index, int value) = 0;
virtual void setLocalFloat (int index, float value) = 0; virtual void setLocalFloat (int index, float value) = 0;
virtual void messageBox (const std::string& message, virtual void messageBox (const std::string& message,
const std::vector<std::string>& buttons) = 0; const std::vector<std::string>& buttons) = 0;
void messageBox (const std::string& message) void messageBox (const std::string& message)
{ {
std::vector<std::string> empty; std::vector<std::string> empty;
messageBox (message, empty); messageBox (message, empty);
} }
virtual void report (const std::string& message) = 0;
virtual bool menuMode() = 0; virtual bool menuMode() = 0;
virtual int getGlobalShort (const std::string& name) const = 0; virtual int getGlobalShort (const std::string& name) const = 0;
@ -41,31 +43,29 @@ namespace Interpreter
virtual float getGlobalFloat (const std::string& name) const = 0; virtual float getGlobalFloat (const std::string& name) const = 0;
virtual void setGlobalShort (const std::string& name, int value) = 0; virtual void setGlobalShort (const std::string& name, int value) = 0;
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) const = 0; virtual bool isScriptRunning (const std::string& name) const = 0;
virtual void startScript (const std::string& name) = 0; virtual void startScript (const std::string& name) = 0;
virtual void stopScript (const std::string& name) = 0; virtual void stopScript (const std::string& name) = 0;
virtual float getDistance (const std::string& name, const std::string& id = "") const virtual float getDistance (const std::string& name, const std::string& id = "") const
= 0; = 0;
virtual float getSecondsPassed() const = 0; virtual float getSecondsPassed() const = 0;
virtual bool isDisabled (const std::string& id = "") const = 0; virtual bool isDisabled (const std::string& id = "") const = 0;
virtual void enable (const std::string& id = "") = 0; virtual void enable (const std::string& id = "") = 0;
virtual void disable (const std::string& id = "") = 0; virtual void disable (const std::string& id = "") = 0;
}; };
} }
#endif #endif

View file

@ -117,5 +117,9 @@ op 55: explicit reference = stack[0]; pop; disable explicit reference
op 56: explicit reference = stack[0]; pop; push 1, if explicit reference is disabled, 0 else op 56: explicit reference = stack[0]; pop; push 1, if explicit reference is disabled, 0 else
op 57: explicit reference = stack[0]; pop; op 57: explicit reference = stack[0]; pop;
replace stack[0] with distance between explicit reference and a reference of ID stack[0] replace stack[0] with distance between explicit reference and a reference of ID stack[0]
opcodes 58-33554431 unused op 58: report string literal index in stack[0];
additional arguments (if any) in stack[n]..stack[1];
n is determined according to the message string
all arguments are removed from stack
opcodes 59-33554431 unused
opcodes 33554432-67108863 reserved for extensions opcodes 33554432-67108863 reserved for extensions

View file

@ -95,6 +95,7 @@ namespace Interpreter
interpreter.installSegment5 (54, new OpEnableExplicit); interpreter.installSegment5 (54, new OpEnableExplicit);
interpreter.installSegment5 (55, new OpDisableExplicit); interpreter.installSegment5 (55, new OpDisableExplicit);
interpreter.installSegment5 (56, new OpGetDisabledExplicit); interpreter.installSegment5 (56, new OpGetDisabledExplicit);
interpreter.installSegment5 (58, new OpReport);
// script control // script control
interpreter.installSegment5 (46, new OpScriptRunning); interpreter.installSegment5 (46, new OpScriptRunning);
@ -106,4 +107,3 @@ namespace Interpreter
interpreter.installSegment5 (57, new OpGetDistanceExplicit); interpreter.installSegment5 (57, new OpGetDistanceExplicit);
} }
} }

View file

@ -13,6 +13,66 @@
namespace Interpreter namespace Interpreter
{ {
inline std::string formatMessage (const std::string& message, Runtime& runtime)
{
std::string formattedMessage;
for (std::size_t i=0; i<message.size(); ++i)
{
char c = message[i];
if (c!='%')
formattedMessage += c;
else
{
++i;
if (i<message.size())
{
c = message[i];
if (c=='S' || c=='s')
{
int index = runtime[0].mInteger;
runtime.pop();
formattedMessage += runtime.getStringLiteral (index);
}
else if (c=='g' || c=='G')
{
Type_Integer value = runtime[0].mInteger;
runtime.pop();
std::ostringstream out;
out << value;
formattedMessage += out.str();
}
else if (c=='f' || c=='F' || c=='.')
{
while (c!='f' && i<message.size())
{
++i;
}
float value = runtime[0].mFloat;
runtime.pop();
std::ostringstream out;
out << value;
formattedMessage += out.str();
}
else if (c=='%')
formattedMessage += "%";
else
{
formattedMessage += "%";
formattedMessage += c;
}
}
}
}
return formattedMessage;
}
class OpMessageBox : public Opcode1 class OpMessageBox : public Opcode1
{ {
public: public:
@ -36,66 +96,31 @@ namespace Interpreter
std::reverse (buttons.begin(), buttons.end()); std::reverse (buttons.begin(), buttons.end());
// additional parameters // handle additional parameters
std::string formattedMessage; std::string formattedMessage = formatMessage (message, runtime);
for (std::size_t i=0; i<message.size(); ++i)
{
char c = message[i];
if (c!='%')
formattedMessage += c;
else
{
++i;
if (i<message.size())
{
c = message[i];
if (c=='S' || c=='s')
{
int index = runtime[0].mInteger;
runtime.pop();
formattedMessage += runtime.getStringLiteral (index);
}
else if (c=='g' || c=='G')
{
Type_Integer value = runtime[0].mInteger;
runtime.pop();
std::ostringstream out;
out << value;
formattedMessage += out.str();
}
else if (c=='f' || c=='F' || c=='.')
{
while (c!='f' && i<message.size())
{
++i;
}
float value = runtime[0].mFloat;
runtime.pop();
std::ostringstream out;
out << value;
formattedMessage += out.str();
}
else if (c=='%')
formattedMessage += "%";
else
{
formattedMessage += "%";
formattedMessage += c;
}
}
}
}
runtime.getContext().messageBox (formattedMessage, buttons); runtime.getContext().messageBox (formattedMessage, buttons);
} }
}; };
class OpReport : public Opcode0
{
public:
virtual void execute (Runtime& runtime)
{
// message
int index = runtime[0].mInteger;
runtime.pop();
std::string message = runtime.getStringLiteral (index);
// handle additional parameters
std::string formattedMessage = formatMessage (message, runtime);
runtime.getContext().report (formattedMessage);
}
};
class OpMenuMode : public Opcode0 class OpMenuMode : public Opcode0
{ {
public: public: