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

Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Pieter van der Kloet 2011-04-29 14:29:09 +02:00
commit c22f39be8b
52 changed files with 1100 additions and 237 deletions

View file

@ -14,15 +14,15 @@ find_program(DPKG_PROGRAM dpkg DOC "dpkg program of Debian-based systems")
# Location of morrowind data files # Location of morrowind data files
if(DPKG_PROGRAM) if(DPKG_PROGRAM)
set(MORROWIND_DATA_FILES "/usr/share/games/openmw/data/" CACHE PATH "location of Morrowind data files") set(MORROWIND_DATA_FILES "/usr/share/games/openmw/data/" CACHE PATH "location of Morrowind data files")
set(MORROWIND_RESOURCE_FILES "/usr/share/games/openmw/resources/" CACHE PATH "location of Morrowind data files") set(MORROWIND_RESOURCE_FILES "/usr/share/games/openmw/resources/" CACHE PATH "location of OpenMW resources files")
else() else()
if (APPLE) if (APPLE)
# set path inside bundle # set path inside bundle
set(MORROWIND_DATA_FILES "../data" CACHE PATH "location of Morrowind data files") set(MORROWIND_DATA_FILES "../data" CACHE PATH "location of Morrowind data files")
set(MORROWIND_RESOURCE_FILES "Contents/Resources/resources" CACHE PATH "location of Morrowind data files") set(MORROWIND_RESOURCE_FILES "Contents/Resources/resources" CACHE PATH "location of OpenMW resources files")
else() else()
set(MORROWIND_DATA_FILES "data" CACHE PATH "location of Morrowind data files") set(MORROWIND_DATA_FILES "data" CACHE PATH "location of Morrowind data files")
set(MORROWIND_RESOURCE_FILES "resources" CACHE PATH "location of Morrowind data files") set(MORROWIND_RESOURCE_FILES "resources" CACHE PATH "location of OpenMW resources files")
endif(APPLE) endif(APPLE)
endif(DPKG_PROGRAM) endif(DPKG_PROGRAM)
@ -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
@ -336,6 +344,11 @@ endif (APPLE)
# Other files # Other files
configure_file(${OpenMW_SOURCE_DIR}/files/openmw.cfg.local
"${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
"${OpenMW_BINARY_DIR}/plugins.cfg" COPYONLY) "${OpenMW_BINARY_DIR}/plugins.cfg" COPYONLY)
@ -424,7 +437,7 @@ if(DPKG_PROGRAM)
endif() endif()
#Install global configuration files #Install global configuration files
INSTALL(FILES "${OpenMW_BINARY_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>
@ -47,23 +48,43 @@ bool parseOptions (int argc, char**argv, OMW::Engine& engine)
"set resources directory") "set resources directory")
("start", bpo::value<std::string>()->default_value ("Beshara"), ("start", bpo::value<std::string>()->default_value ("Beshara"),
"set initial cell") "set initial cell")
("master", bpo::value<std::string>()->default_value ("Morrowind"), ("master", bpo::value<std::vector<std::string> >()
"master file") ->default_value (std::vector<std::string>(), "")
( "showfps", "show fps counter") ->multitoken(),
( "debug", "debug mode" ) "master file(s)")
( "nosound", "disable all sound" ) ("plugin", bpo::value<std::vector<std::string> >()
( "script-verbose", "verbose script output" ) ->default_value (std::vector<std::string>(), "")
( "new-game", "activate char gen/new game mechanics" ) ->multitoken(),
( "script-all", "compile all scripts (excluding dialogue scripts) at startup") "plugin file(s)")
( "fps", boost::program_options::value<bool>()->
implicit_value (true)->default_value (false), "show fps counter")
( "debug", boost::program_options::value<bool>()->
implicit_value (true)->default_value (false), "debug mode" )
( "nosound", boost::program_options::value<bool>()->
implicit_value (true)->default_value (false), "disable all sound" )
( "script-verbose", boost::program_options::value<bool>()->
implicit_value (true)->default_value (false), "verbose script output" )
( "new-game", boost::program_options::value<bool>()->
implicit_value (true)->default_value (false),
"activate char gen/new game mechanics" )
( "script-all", boost::program_options::value<bool>()->
implicit_value (true)->default_value (false),
"compile all scripts (excluding dialogue scripts) at startup")
; ;
bpo::variables_map variables; bpo::variables_map variables;
std::string cfgFile = OMW::Path::getPath(OMW::Path::GLOBAL_CFG_PATH, "openmw", "openmw.cfg"); //If there is an openmw.cfg in the current path use that as global config
//Otherwise try getPath
std::string cfgFile = "openmw.cfg";
if(!isFile(cfgFile.c_str()))
{
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());
@ -83,27 +104,52 @@ bool parseOptions (int argc, char**argv, OMW::Engine& engine)
return false; return false;
} }
// directory settings
engine.setDataDir (variables["data"].as<std::string>()); engine.setDataDir (variables["data"].as<std::string>());
engine.setResourceDir (variables["resources"].as<std::string>()); engine.setResourceDir (variables["resources"].as<std::string>());
// master and plugin
std::vector<std::string> master = variables["master"].as<std::vector<std::string> >();
if (master.empty())
{
std::cout << "No master file given. Assuming Morrowind.esm" << std::endl;
master.push_back ("Morrowind");
}
if (master.size()>1)
{
std::cout
<< "Ignoring all but the first master file (multiple master files not yet supported)."
<< std::endl;
}
engine.addMaster (master[0]);
std::vector<std::string> plugin = variables["plugin"].as<std::vector<std::string> >();
if (!plugin.empty())
std::cout << "Ignoring plugin files (plugins not yet supported)." << std::endl;
// startup-settings
engine.setCell (variables["start"].as<std::string>()); engine.setCell (variables["start"].as<std::string>());
engine.addMaster (variables["master"].as<std::string>());
if (variables.count ("showfps")) if (variables["new-game"].as<bool>()==true)
engine.showFPS();
if (variables.count ("debug"))
engine.enableDebugMode();
if (variables.count ("nosound"))
engine.disableSound();
if (variables.count ("script-verbose"))
engine.enableVerboseScripts();
if (variables.count ("new-game"))
engine.setNewGame(); engine.setNewGame();
if (variables.count ("script-all")) // other settings
if (variables["fps"].as<bool>()==true)
engine.showFPS();
if (variables["debug"].as<bool>()==true)
engine.enableDebugMode();
if (variables["nosound"].as<bool>()==true)
engine.disableSound();
if (variables["script-verbose"].as<bool>()==true)
engine.enableVerboseScripts();
if (variables["script-all"].as<bool>()==true)
engine.setCompileAll (true); engine.setCompileAll (true);
return true; return true;

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,7 +119,7 @@ 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();
@ -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,7 +196,7 @@ 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();
@ -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;

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,7 +212,7 @@ 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();
@ -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());
bool enabled =
context.getWorld().toggleRenderMode (MWWorld::World::Render_CollisionDebug); context.getWorld().toggleRenderMode (MWWorld::World::Render_CollisionDebug);
context.report (enabled ?
"Collsion Mesh Rendering -> On" : "Collision Mesh Rendering -> Off");
} }
}; };

View file

@ -22,7 +22,9 @@ namespace MWScript
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");
} }
}; };
@ -104,4 +106,3 @@ namespace MWScript
} }
} }
} }

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.

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

@ -33,6 +33,8 @@ namespace Interpreter
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;
@ -67,5 +69,3 @@ namespace Interpreter
} }
#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,30 +13,8 @@
namespace Interpreter namespace Interpreter
{ {
class OpMessageBox : public Opcode1 inline std::string formatMessage (const std::string& message, Runtime& runtime)
{ {
public:
virtual void execute (Runtime& runtime, unsigned int arg0)
{
// message
int index = runtime[0].mInteger;
runtime.pop();
std::string message = runtime.getStringLiteral (index);
// buttons
std::vector<std::string> buttons;
for (std::size_t i=0; i<arg0; ++i)
{
int index = runtime[0].mInteger;
runtime.pop();
buttons.push_back (runtime.getStringLiteral (index));
}
std::reverse (buttons.begin(), buttons.end());
// additional parameters
std::string formattedMessage; std::string formattedMessage;
for (std::size_t i=0; i<message.size(); ++i) for (std::size_t i=0; i<message.size(); ++i)
@ -92,10 +70,57 @@ namespace Interpreter
} }
} }
return formattedMessage;
}
class OpMessageBox : public Opcode1
{
public:
virtual void execute (Runtime& runtime, unsigned int arg0)
{
// message
int index = runtime[0].mInteger;
runtime.pop();
std::string message = runtime.getStringLiteral (index);
// buttons
std::vector<std::string> buttons;
for (std::size_t i=0; i<arg0; ++i)
{
int index = runtime[0].mInteger;
runtime.pop();
buttons.push_back (runtime.getStringLiteral (index));
}
std::reverse (buttons.begin(), buttons.end());
// handle additional parameters
std::string formattedMessage = formatMessage (message, runtime);
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:

2
files/openmw.cfg.local Normal file
View file

@ -0,0 +1,2 @@
data=./data
resources=./resources