1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-07-21 03:14:06 +00:00

Merge remote branch 'zini/master' into sound-rewrite

Conflicts:
	apps/openmw/mwsound/soundmanager.cpp
	apps/openmw/mwsound/soundmanager.hpp
This commit is contained in:
Chris Robinson 2012-03-20 06:17:02 -07:00
commit 74e79bb4af
45 changed files with 1613 additions and 512 deletions

View file

@ -18,7 +18,7 @@ include (OpenMWMacros)
# Version # Version
set (OPENMW_VERSION_MAJOR 0) set (OPENMW_VERSION_MAJOR 0)
set (OPENMW_VERSION_MINOR 12) set (OPENMW_VERSION_MINOR 13)
set (OPENMW_VERSION_RELEASE 0) set (OPENMW_VERSION_RELEASE 0)
set (OPENMW_VERSION "${OPENMW_VERSION_MAJOR}.${OPENMW_VERSION_MINOR}.${OPENMW_VERSION_RELEASE}") set (OPENMW_VERSION "${OPENMW_VERSION_MAJOR}.${OPENMW_VERSION_MINOR}.${OPENMW_VERSION_RELEASE}")
@ -27,6 +27,8 @@ set (OPENMW_VERSION "${OPENMW_VERSION_MAJOR}.${OPENMW_VERSION_MINOR}.${OPENMW_VE
configure_file ("${OpenMW_SOURCE_DIR}/Docs/mainpage.hpp.cmake" "${OpenMW_SOURCE_DIR}/Docs/mainpage.hpp") configure_file ("${OpenMW_SOURCE_DIR}/Docs/mainpage.hpp.cmake" "${OpenMW_SOURCE_DIR}/Docs/mainpage.hpp")
option(OGRE_STATIC "Link static build of Ogre and Ogre Plugins into the binaries" FALSE)
# Sound source selection # Sound source selection
option(USE_FFMPEG "use ffmpeg for sound" OFF) option(USE_FFMPEG "use ffmpeg for sound" OFF)
option(USE_MPG123 "use mpg123 + libsndfile for sound" ON) option(USE_MPG123 "use mpg123 + libsndfile for sound" ON)
@ -159,13 +161,26 @@ endif (APPLE)
# Dependencies # Dependencies
# Fix for not visible pthreads functions for linker with glibc 2.15
if (UNIX AND NOT APPLE)
find_package (Threads)
endif()
find_package(OGRE REQUIRED) find_package(OGRE REQUIRED)
find_package(Boost REQUIRED COMPONENTS system filesystem program_options thread) find_package(Boost REQUIRED COMPONENTS system filesystem program_options thread)
find_package(OIS REQUIRED) find_package(OIS REQUIRED)
find_package(OpenAL REQUIRED) find_package(OpenAL REQUIRED)
find_package(Bullet REQUIRED) find_package(Bullet REQUIRED)
IF(OGRE_STATIC)
find_package(Cg REQUIRED)
IF(WIN32)
set(OGRE_PLUGIN_INCLUDE_DIRS ${OGRE_Plugin_CgProgramManager_INCLUDE_DIRS} ${OGRE_Plugin_OctreeSceneManager_INCLUDE_DIRS} ${OGRE_Plugin_ParticleFX_INCLUDE_DIRS} ${OGRE_RenderSystem_Direct3D9_INCLUDE_DIRS} ${OGRE_RenderSystem_GL_INCLUDE_DIRS})
ELSE(WIN32)
set(OGRE_PLUGIN_INCLUDE_DIRS ${OGRE_Plugin_CgProgramManager_INCLUDE_DIRS} ${OGRE_Plugin_OctreeSceneManager_INCLUDE_DIRS} ${OGRE_Plugin_ParticleFX_INCLUDE_DIRS} ${OGRE_RenderSystem_GL_INCLUDE_DIRS})
ENDIF(WIN32)
ENDIF(OGRE_STATIC)
include_directories("." include_directories("."
${OGRE_INCLUDE_DIR} ${OGRE_INCLUDE_DIR}/Ogre ${OGRE_INCLUDE_DIR}/OGRE ${OGRE_INCLUDE_DIR} ${OGRE_INCLUDE_DIR}/Ogre ${OGRE_INCLUDE_DIR}/OGRE ${OGRE_PLUGIN_INCLUDE_DIRS}
${OIS_INCLUDE_DIRS} ${Boost_INCLUDE_DIR} ${OIS_INCLUDE_DIRS} ${Boost_INCLUDE_DIR}
${PLATFORM_INCLUDE_DIR} ${PLATFORM_INCLUDE_DIR}
${CMAKE_HOME_DIRECTORY}/extern/mygui_3.0.1/MyGUIEngine/include ${CMAKE_HOME_DIRECTORY}/extern/mygui_3.0.1/MyGUIEngine/include
@ -287,7 +302,7 @@ if(DPKG_PROGRAM)
SET(CPACK_DEBIAN_PACKAGE_NAME "openmw") SET(CPACK_DEBIAN_PACKAGE_NAME "openmw")
SET(CPACK_DEBIAN_PACKAGE_VERSION "${VERSION_STRING}") SET(CPACK_DEBIAN_PACKAGE_VERSION "${VERSION_STRING}")
SET(CPACK_PACKAGE_EXECUTABLES "openmw;OpenMW esmtool;Esmtool omwlauncher;OMWLauncher") SET(CPACK_PACKAGE_EXECUTABLES "openmw;OpenMW esmtool;Esmtool omwlauncher;OMWLauncher")
SET(CPACK_DEBIAN_PACKAGE_DEPENDS "libogre-1.7.3 (>= 1.7.3), libbullet0 (>= 2.77), libboost-filesystem1.46.1 (>= 1.46.1), libboost-program-options1.46.1 (>= 1.46.1), libboost-system1.46.1 (>= 1.46.1), libboost-thread1.46.1 (>= 1.46.1), libc6 (>= 2.11.2), libfreetype6 (>= 2.2.1), libgcc1 (>= 1:4.1.1), libmpg123-0 (>= 1.12.1), libois-1.3.0 (>= 1.3.0), libopenal1 (>= 1:1.12.854), libsndfile1 (>= 1.0.23), libstdc++6 (>= 4.4.5), libuuid1 (>= 2.17.2), libqtgui4 (>= 4.7.0)") SET(CPACK_DEBIAN_PACKAGE_DEPENDS "nvidia-cg-toolkit (>= 2.1), libboost-filesystem1.46.1 (>= 1.46.1), libboost-program-options1.46.1 (>= 1.46.1), libboost-system1.46.1 (>= 1.46.1), libboost-thread1.46.1 (>= 1.46.1), libc6 (>= 2.11.2), libfreetype6 (>= 2.2.1), libgcc1 (>= 1:4.1.1), libmpg123-0 (>= 1.12.1), libois-1.3.0 (>= 1.3.0), libopenal1 (>= 1:1.12.854), libsndfile1 (>= 1.0.23), libstdc++6 (>= 4.4.5), libuuid1 (>= 2.17.2), libqtgui4 (>= 4.7.0)")
SET(CPACK_DEBIAN_PACKAGE_SECTION "Games") SET(CPACK_DEBIAN_PACKAGE_SECTION "Games")
@ -423,7 +438,9 @@ if (WIN32)
endforeach(d) endforeach(d)
set_target_properties(components PROPERTIES COMPILE_FLAGS ${WARNINGS}) set_target_properties(components PROPERTIES COMPILE_FLAGS ${WARNINGS})
if (BUILD_LAUNCHER)
set_target_properties(omwlauncher PROPERTIES COMPILE_FLAGS ${WARNINGS}) set_target_properties(omwlauncher PROPERTIES COMPILE_FLAGS ${WARNINGS})
endif (BUILD_LAUNCHER)
set_target_properties(openmw PROPERTIES COMPILE_FLAGS ${WARNINGS}) set_target_properties(openmw PROPERTIES COMPILE_FLAGS ${WARNINGS})
endif(MSVC) endif(MSVC)

View file

@ -53,6 +53,15 @@ QT4_WRAP_CPP(MOC_SRCS ${LAUNCHER_HEADER_MOC})
include(${QT_USE_FILE}) include(${QT_USE_FILE})
# Main executable # Main executable
IF(OGRE_STATIC)
IF(WIN32)
ADD_DEFINITIONS(-DENABLE_PLUGIN_Direct3D9 -DENABLE_PLUGIN_GL)
set(OGRE_STATIC_PLUGINS ${OGRE_RenderSystem_Direct3D9_LIBRARIES} ${OGRE_RenderSystem_GL_LIBRARIES})
ELSE(WIN32)
ADD_DEFINITIONS(-DENABLE_PLUGIN_GL)
set(OGRE_STATIC_PLUGINS ${OGRE_RenderSystem_GL_LIBRARIES})
ENDIF(WIN32)
ENDIF(OGRE_STATIC)
add_executable(omwlauncher add_executable(omwlauncher
${GUI_TYPE} ${GUI_TYPE}
${LAUNCHER} ${LAUNCHER}
@ -63,6 +72,7 @@ add_executable(omwlauncher
target_link_libraries(omwlauncher target_link_libraries(omwlauncher
${Boost_LIBRARIES} ${Boost_LIBRARIES}
${OGRE_LIBRARIES} ${OGRE_LIBRARIES}
${OGRE_STATIC_PLUGINS}
${QT_LIBRARIES} ${QT_LIBRARIES}
components components
) )

View file

@ -222,7 +222,7 @@ void DataFilesPage::setupDataFiles()
QMessageBox msgBox; QMessageBox msgBox;
msgBox.setWindowTitle("Error detecting Morrowind installation"); msgBox.setWindowTitle("Error detecting Morrowind installation");
msgBox.setIcon(QMessageBox::Critical); msgBox.setIcon(QMessageBox::Warning);
msgBox.setStandardButtons(QMessageBox::Cancel); msgBox.setStandardButtons(QMessageBox::Cancel);
msgBox.setText(tr("<br><b>Could not find the Data Files location</b><br><br> \ msgBox.setText(tr("<br><b>Could not find the Data Files location</b><br><br> \
The directory containing the Data Files was not found.<br><br> \ The directory containing the Data Files was not found.<br><br> \
@ -279,6 +279,8 @@ void DataFilesPage::setupDataFiles()
const Files::MultiDirCollection &esp = fileCollections.getCollection(".esp"); const Files::MultiDirCollection &esp = fileCollections.getCollection(".esp");
for (Files::MultiDirCollection::TIter iter(esp.begin()); iter!=esp.end(); ++iter) { for (Files::MultiDirCollection::TIter iter(esp.begin()); iter!=esp.end(); ++iter) {
try {
ESMReader fileReader; ESMReader fileReader;
QStringList availableMasters; // Will contain all found masters QStringList availableMasters; // Will contain all found masters
@ -346,6 +348,11 @@ void DataFilesPage::setupDataFiles()
currentItem->appendRow(child); currentItem->appendRow(child);
} }
} }
} catch(std::runtime_error &e) {
// An error occurred while reading the .esp
continue;
}
} }
readConfig(); readConfig();

View file

@ -186,7 +186,11 @@ void GraphicsPage::setupOgre()
try try
{ {
#if defined(ENABLE_PLUGIN_GL) || defined(ENABLE_PLUGIN_Direct3D9)
mOgre = new Ogre::Root("", file.fileName().toStdString(), "./launcherOgre.log");
#else
mOgre = new Ogre::Root(pluginCfg.toStdString(), file.fileName().toStdString(), "./launcherOgre.log"); mOgre = new Ogre::Root(pluginCfg.toStdString(), file.fileName().toStdString(), "./launcherOgre.log");
#endif
} }
catch(Ogre::Exception &ex) catch(Ogre::Exception &ex)
{ {
@ -207,6 +211,15 @@ void GraphicsPage::setupOgre()
return; return;
} }
#ifdef ENABLE_PLUGIN_GL
mGLPlugin = new Ogre::GLPlugin();
mOgre->installPlugin(mGLPlugin);
#endif
#ifdef ENABLE_PLUGIN_Direct3D9
mD3D9Plugin = new Ogre::D3D9Plugin();
mOgre->installPlugin(mD3D9Plugin);
#endif
// Get the available renderers and put them in the combobox // Get the available renderers and put them in the combobox
const Ogre::RenderSystemList &renderers = mOgre->getAvailableRenderers(); const Ogre::RenderSystemList &renderers = mOgre->getAvailableRenderers();

View file

@ -8,6 +8,14 @@
#include <OgreConfigFile.h> #include <OgreConfigFile.h>
#include <OgreConfigDialog.h> #include <OgreConfigDialog.h>
// Static plugin headers
#ifdef ENABLE_PLUGIN_GL
# include "OgreGLPlugin.h"
#endif
#ifdef ENABLE_PLUGIN_Direct3D9
# include "OgreD3D9Plugin.h"
#endif
class QComboBox; class QComboBox;
class QCheckBox; class QCheckBox;
class QStackedWidget; class QStackedWidget;
@ -32,6 +40,12 @@ private:
Ogre::RenderSystem *mSelectedRenderSystem; Ogre::RenderSystem *mSelectedRenderSystem;
Ogre::RenderSystem *mOpenGLRenderSystem; Ogre::RenderSystem *mOpenGLRenderSystem;
Ogre::RenderSystem *mDirect3DRenderSystem; Ogre::RenderSystem *mDirect3DRenderSystem;
#ifdef ENABLE_PLUGIN_GL
Ogre::GLPlugin* mGLPlugin;
#endif
#ifdef ENABLE_PLUGIN_Direct3D9
Ogre::D3D9Plugin* mD3D9Plugin;
#endif
QComboBox *mRendererComboBox; QComboBox *mRendererComboBox;

View file

@ -57,6 +57,15 @@ add_openmw_dir (mwmechanics
) )
# Main executable # Main executable
IF(OGRE_STATIC)
IF(WIN32)
ADD_DEFINITIONS(-DENABLE_PLUGIN_CgProgramManager -DENABLE_PLUGIN_OctreeSceneManager -DENABLE_PLUGIN_ParticleFX -DENABLE_PLUGIN_-DENABLE_PLUGIN_Direct3D9 -DENABLE_PLUGIN_GL)
set(OGRE_STATIC_PLUGINS ${OGRE_Plugin_CgProgramManager_LIBRARIES} ${OGRE_Plugin_OctreeSceneManager_LIBRARIES} ${OGRE_Plugin_ParticleFX_LIBRARIES} ${OGRE_RenderSystem_Direct3D9_LIBRARIES} ${OGRE_RenderSystem_GL_LIBRARIES})
ELSE(WIN32)
ADD_DEFINITIONS(-DENABLE_PLUGIN_CgProgramManager -DENABLE_PLUGIN_OctreeSceneManager -DENABLE_PLUGIN_ParticleFX -DENABLE_PLUGIN_GL)
set(OGRE_STATIC_PLUGINS ${OGRE_Plugin_CgProgramManager_LIBRARIES} ${Cg_LIBRARIES} ${OGRE_Plugin_OctreeSceneManager_LIBRARIES} ${OGRE_Plugin_ParticleFX_LIBRARIES} ${OGRE_RenderSystem_GL_LIBRARIES})
ENDIF(WIN32)
ENDIF(OGRE_STATIC)
add_executable(openmw add_executable(openmw
${OPENMW_LIBS} ${OPENMW_LIBS_HEADER} ${OPENMW_LIBS} ${OPENMW_LIBS_HEADER}
${COMPONENT_FILES} ${COMPONENT_FILES}
@ -72,6 +81,7 @@ add_definitions(${SOUND_DEFINE})
target_link_libraries(openmw target_link_libraries(openmw
${OGRE_LIBRARIES} ${OGRE_LIBRARIES}
${OGRE_STATIC_PLUGINS}
${OIS_LIBRARIES} ${OIS_LIBRARIES}
${Boost_LIBRARIES} ${Boost_LIBRARIES}
${OPENAL_LIBRARY} ${OPENAL_LIBRARY}
@ -82,6 +92,11 @@ target_link_libraries(openmw
MyGUIOgrePlatform MyGUIOgrePlatform
) )
# Fix for not visible pthreads functions for linker with glibc 2.15
if (UNIX AND NOT APPLE)
target_link_libraries(openmw ${CMAKE_THREAD_LIBS_INIT})
endif()
if(APPLE) if(APPLE)
find_library(CARBON_FRAMEWORK Carbon) find_library(CARBON_FRAMEWORK Carbon)
target_link_libraries(openmw ${CARBON_FRAMEWORK}) target_link_libraries(openmw ${CARBON_FRAMEWORK})

View file

@ -60,7 +60,7 @@ void OMW::Engine::executeLocalScripts()
MWScript::InterpreterContext interpreterContext (mEnvironment, MWScript::InterpreterContext interpreterContext (mEnvironment,
&script.second.getRefData().getLocals(), script.second); &script.second.getRefData().getLocals(), script.second);
mScriptManager->run (script.first, interpreterContext); mEnvironment.mScriptManager->run (script.first, interpreterContext);
if (mEnvironment.mWorld->hasCellChanged()) if (mEnvironment.mWorld->hasCellChanged())
break; break;
@ -182,7 +182,6 @@ OMW::Engine::Engine(Files::ConfigurationManager& configurationManager)
, mCompileAll (false) , mCompileAll (false)
, mReportFocus (false) , mReportFocus (false)
, mFocusTDiff (0) , mFocusTDiff (0)
, mScriptManager (0)
, mScriptContext (0) , mScriptContext (0)
, mFSStrict (false) , mFSStrict (false)
, mCfgMgr(configurationManager) , mCfgMgr(configurationManager)
@ -199,7 +198,7 @@ OMW::Engine::~Engine()
delete mEnvironment.mMechanicsManager; delete mEnvironment.mMechanicsManager;
delete mEnvironment.mDialogueManager; delete mEnvironment.mDialogueManager;
delete mEnvironment.mJournal; delete mEnvironment.mJournal;
delete mScriptManager; delete mEnvironment.mScriptManager;
delete mScriptContext; delete mScriptContext;
delete mOgre; delete mOgre;
} }
@ -348,18 +347,18 @@ void OMW::Engine::go()
mEnvironment); mEnvironment);
mScriptContext->setExtensions (&mExtensions); mScriptContext->setExtensions (&mExtensions);
mScriptManager = new MWScript::ScriptManager (mEnvironment.mWorld->getStore(), mVerboseScripts, mEnvironment.mScriptManager = new MWScript::ScriptManager (mEnvironment.mWorld->getStore(),
*mScriptContext); mVerboseScripts, *mScriptContext);
mEnvironment.mGlobalScripts = new MWScript::GlobalScripts (mEnvironment.mWorld->getStore(), mEnvironment.mGlobalScripts = new MWScript::GlobalScripts (mEnvironment.mWorld->getStore(),
*mScriptManager); *mEnvironment.mScriptManager);
// Create game mechanics system // Create game mechanics system
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.mJournal = new MWDialogue::Journal (mEnvironment);
mEnvironment.mDialogueManager = new MWDialogue::DialogueManager (mEnvironment); mEnvironment.mDialogueManager = new MWDialogue::DialogueManager (mEnvironment,mExtensions);
// load cell // load cell
ESM::Position pos; ESM::Position pos;
@ -393,7 +392,7 @@ void OMW::Engine::go()
// scripts // scripts
if (mCompileAll) if (mCompileAll)
{ {
std::pair<int, int> result = mScriptManager->compileAll(); std::pair<int, int> result = mEnvironment.mScriptManager->compileAll();
if (result.first) if (result.first)
std::cout std::cout
@ -411,6 +410,9 @@ void OMW::Engine::go()
void OMW::Engine::activate() void OMW::Engine::activate()
{ {
if (mEnvironment.mWindowManager->getMode()!=MWGui::GM_Game)
return;
std::string handle = mEnvironment.mWorld->getFacedHandle(); std::string handle = mEnvironment.mWorld->getFacedHandle();
if (handle.empty()) if (handle.empty())
@ -435,7 +437,7 @@ void OMW::Engine::activate()
if (!script.empty()) if (!script.empty())
{ {
mEnvironment.mWorld->getLocalScripts().setIgnore (ptr); mEnvironment.mWorld->getLocalScripts().setIgnore (ptr);
mScriptManager->run (script, interpreterContext); mEnvironment.mScriptManager->run (script, interpreterContext);
} }
if (!interpreterContext.hasActivationBeenHandled()) if (!interpreterContext.hasActivationBeenHandled())

View file

@ -78,7 +78,6 @@ namespace OMW
std::string mFocusName; std::string mFocusName;
MWWorld::Environment mEnvironment; MWWorld::Environment mEnvironment;
MWScript::ScriptManager *mScriptManager;
Compiler::Extensions mExtensions; Compiler::Extensions mExtensions;
Compiler::Context *mScriptContext; Compiler::Context *mScriptContext;

View file

@ -9,16 +9,36 @@
#include <components/esm_store/store.hpp> #include <components/esm_store/store.hpp>
#include "../mwworld/class.hpp" #include "../mwworld/class.hpp"
#include "../mwworld/environment.hpp" #include "../mwworld/environment.hpp"
#include "../mwworld/world.hpp" #include "../mwworld/world.hpp"
#include "../mwworld/refdata.hpp" #include "../mwworld/refdata.hpp"
#include "../mwworld/player.hpp" #include "../mwworld/player.hpp"
#include "../mwworld/containerstore.hpp"
#include "../mwinput/inputmanager.hpp" #include "../mwinput/inputmanager.hpp"
#include "../mwgui/dialogue.hpp"
#include "../mwgui/window_manager.hpp"
#include "journal.hpp"
#include <iostream> #include <iostream>
#include "../mwscript/extensions.hpp"
#include "../mwscript/scriptmanager.hpp"
#include <components/compiler/exception.hpp>
#include <components/compiler/errorhandler.hpp>
#include <components/compiler/scanner.hpp>
#include <components/compiler/locals.hpp>
#include <components/compiler/output.hpp>
#include <components/interpreter/interpreter.hpp>
#include "../mwscript/compilercontext.hpp"
#include "../mwscript/interpretercontext.hpp"
#include <components/compiler/scriptparser.hpp>
namespace namespace
{ {
std::string toLower (const std::string& name) std::string toLower (const std::string& name)
@ -31,6 +51,7 @@ namespace
return lowerCase; return lowerCase;
} }
template<typename T1, typename T2> template<typename T1, typename T2>
bool selectCompare (char comp, T1 value1, T2 value2) bool selectCompare (char comp, T1 value1, T2 value2)
{ {
@ -115,6 +136,125 @@ namespace
namespace MWDialogue namespace MWDialogue
{ {
//helper function
std::string::size_type find_str_ci(const std::string& str, const std::string& substr,size_t pos)
{
return toLower(str).find(toLower(substr),pos);
}
bool DialogueManager::functionFilter(const MWWorld::Ptr& actor, const ESM::DialInfo& info,bool choice)
{
for (std::vector<ESM::DialInfo::SelectStruct>::const_iterator iter (info.selects.begin());
iter != info.selects.end(); ++iter)
{
ESM::DialInfo::SelectStruct select = *iter;
char type = select.selectRule[1];
if(type == '1')
{
char comp = select.selectRule[4];
std::string name = select.selectRule.substr (5);
std::string function = select.selectRule.substr(2,2);
int ifunction;
std::istringstream iss(function);
iss >> ifunction;
switch(ifunction)
{
case 39://PC Expelled
if(!selectCompare<int,int>(comp,0,select.i)) return false;
break;
case 40://PC Common Disease
if(!selectCompare<int,int>(comp,0,select.i)) return false;
break;
case 41://PC Blight Disease
if(!selectCompare<int,int>(comp,0,select.i)) return false;
break;
case 43://PC Crime level
if(!selectCompare<int,int>(comp,0,select.i)) return false;
break;
case 46://Same faction
if(!selectCompare<int,int>(comp,0,select.i)) return false;
break;
case 48://Detected
if(!selectCompare<int,int>(comp,1,select.i)) return false;
break;
case 49://Alarmed
if(!selectCompare<int,int>(comp,0,select.i)) return false;
break;
case 50://choice
if(choice)
{
if(!selectCompare<int,int>(comp,mChoice,select.i)) return false;
}
break;
case 60://PC Vampire
if(!selectCompare<int,int>(comp,0,select.i)) return false;
break;
case 61://Level
if(!selectCompare<int,int>(comp,1,select.i)) return false;
break;
case 62://Attacked
if(!selectCompare<int,int>(comp,0,select.i)) return false;
break;
case 63://Talked to PC
if(!selectCompare<int,int>(comp,0,select.i)) return false;
break;
case 64://PC Health
if(!selectCompare<int,int>(comp,50,select.i)) return false;
break;
case 65://Creature target
if(!selectCompare<int,int>(comp,0,select.i)) return false;
break;
case 66://Friend hit
if(!selectCompare<int,int>(comp,0,select.i)) return false;
break;
case 67://Fight
if(!selectCompare<int,int>(comp,0,select.i)) return false;
break;
case 68://Hello????
if(!selectCompare<int,int>(comp,0,select.i)) return false;
break;
case 69://Alarm
if(!selectCompare<int,int>(comp,0,select.i)) return false;
break;
case 70://Flee
if(!selectCompare<int,int>(comp,0,select.i)) return false;
break;
case 71://Should Attack
if(!selectCompare<int,int>(comp,0,select.i)) return false;
break;
default:
break;
}
}
}
return true;
}
bool DialogueManager::isMatching (const MWWorld::Ptr& actor, bool DialogueManager::isMatching (const MWWorld::Ptr& actor,
const ESM::DialInfo::SelectStruct& select) const const ESM::DialInfo::SelectStruct& select) const
{ {
@ -124,14 +264,13 @@ namespace MWDialogue
{ {
char comp = select.selectRule[4]; char comp = select.selectRule[4];
std::string name = select.selectRule.substr (5); std::string name = select.selectRule.substr (5);
std::string function = select.selectRule.substr(1,2);
// TODO types 4, 5, 6, 7, 8, 9, A, B, C
switch (type) switch (type)
{ {
case '1': // function case '1': // function
return false; // TODO implement functions return true; // TODO implement functions
case '2': // global case '2': // global
@ -173,6 +312,122 @@ namespace MWDialogue
return true; return true;
case '4'://journal
if(select.type==ESM::VT_Int)
{
if(!selectCompare<int,int>(comp,mEnvironment.mJournal->getJournalIndex(toLower(name)),select.i)) return false;
}
else
throw std::runtime_error (
"unsupported variable type in dialogue info select");
return true;
case '5'://item
{
MWWorld::Ptr player = mEnvironment.mWorld->getPlayer().getPlayer();
MWWorld::ContainerStore& store = MWWorld::Class::get (player).getContainerStore (player);
int sum = 0;
for (MWWorld::ContainerStoreIterator iter (store.begin()); iter!=store.end(); ++iter)
if (iter->getCellRef().refID==name)
sum += iter->getRefData().getCount();
if(!selectCompare<int,int>(comp,sum,select.i)) return false;
}
return true;
case '6'://dead
if(!selectCompare<int,int>(comp,0,select.i)) return false;
case '7':// not ID
if(select.type==ESM::VT_String ||select.type==ESM::VT_Int)//bug in morrowind here? it's not a short, it's a string
{
int isID = int(toLower(name)==toLower(MWWorld::Class::get (actor).getId (actor)));
if (selectCompare<int,int>(comp,!isID,select.i)) return false;
}
else
throw std::runtime_error (
"unsupported variable type in dialogue info select");
return true;
case '8':// not faction
if(select.type==ESM::VT_Int)
{
ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData>* npc = actor.get<ESM::NPC>();
int isFaction = int(toLower(npc->base->faction) == toLower(name));
if(selectCompare<int,int>(comp,!isFaction,select.i))
return false;
}
else
throw std::runtime_error (
"unsupported variable type in dialogue info select");
return true;
case '9':// not class
if(select.type==ESM::VT_Int)
{
ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData>* npc = actor.get<ESM::NPC>();
int isClass = int(toLower(npc->base->cls) == toLower(name));
if(selectCompare<int,int>(comp,!isClass,select.i))
return false;
}
else
throw std::runtime_error (
"unsupported variable type in dialogue info select");
return true;
case 'A'://not Race
if(select.type==ESM::VT_Int)
{
ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData>* npc = actor.get<ESM::NPC>();
int isRace = int(toLower(npc->base->race) == toLower(name));
if(selectCompare<int,int>(comp,!isRace,select.i))
return false;
}
else
throw std::runtime_error (
"unsupported variable type in dialogue info select");
return true;
case 'B'://not Cell
if(select.type==ESM::VT_Int)
{
int isCell = int(toLower(actor.getCell()->cell->name) == toLower(name));
if(selectCompare<int,int>(comp,!isCell,select.i))
return false;
}
else
throw std::runtime_error (
"unsupported variable type in dialogue info select");
return true;
case 'C'://not local
if (select.type==ESM::VT_Short || select.type==ESM::VT_Int ||
select.type==ESM::VT_Long)
{
if (checkLocal (comp, toLower (name), select.i, actor,
mEnvironment.mWorld->getStore()))
return false;
}
else if (select.type==ESM::VT_Float)
{
if (checkLocal (comp, toLower (name), select.f, actor,
mEnvironment.mWorld->getStore()))
return false;
}
else
throw std::runtime_error (
"unsupported variable type in dialogue info select");
return true;
default: default:
std::cout << "unchecked select: " << type << " " << comp << " " << name << std::endl; std::cout << "unchecked select: " << type << " " << comp << " " << name << std::endl;
@ -189,6 +444,10 @@ namespace MWDialogue
if (toLower (info.actor)!=MWWorld::Class::get (actor).getId (actor)) if (toLower (info.actor)!=MWWorld::Class::get (actor).getId (actor))
return false; return false;
//PC Faction
if(!info.pcFaction.empty()) return false;
//NPC race
if (!info.race.empty()) if (!info.race.empty())
{ {
ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData> *cellRef = actor.get<ESM::NPC>(); ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData> *cellRef = actor.get<ESM::NPC>();
@ -200,6 +459,7 @@ namespace MWDialogue
return false; return false;
} }
//NPC class
if (!info.clas.empty()) if (!info.clas.empty())
{ {
ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData> *cellRef = actor.get<ESM::NPC>(); ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData> *cellRef = actor.get<ESM::NPC>();
@ -211,6 +471,7 @@ namespace MWDialogue
return false; return false;
} }
//NPC faction
if (!info.npcFaction.empty()) if (!info.npcFaction.empty())
{ {
ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData> *cellRef = actor.get<ESM::NPC>(); ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData> *cellRef = actor.get<ESM::NPC>();
@ -220,66 +481,320 @@ namespace MWDialogue
if (toLower (info.npcFaction)!=toLower (cellRef->base->faction)) if (toLower (info.npcFaction)!=toLower (cellRef->base->faction))
return false; return false;
//check NPC rank
if(cellRef->base->npdt52.gold != -10)
{
if(cellRef->base->npdt52.rank < info.data.rank) return false;
}
else
{
if(cellRef->base->npdt12.rank < info.data.rank) return false;
}
} }
// TODO check player faction // TODO check player faction
//check gender
ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData>* npc = actor.get<ESM::NPC>();
if(npc->base->flags&npc->base->Female)
{
if(static_cast<int> (info.data.gender)==0) return false;
}
else
{
if(static_cast<int> (info.data.gender)==1) return false;
}
// check cell // check cell
if (!info.cell.empty()) if (!info.cell.empty())
if (mEnvironment.mWorld->getPlayer().getPlayer().getCell()->cell->name != info.cell) if (mEnvironment.mWorld->getPlayer().getPlayer().getCell()->cell->name != info.cell)
return false; return false;
// TODO check DATAstruct // TODO check DATAstruct
for (std::vector<ESM::DialInfo::SelectStruct>::const_iterator iter (info.selects.begin()); for (std::vector<ESM::DialInfo::SelectStruct>::const_iterator iter (info.selects.begin());
iter != info.selects.end(); ++iter) iter != info.selects.end(); ++iter)
if (!isMatching (actor, *iter)) if (!isMatching (actor, *iter))
return false; return false;
std::cout
<< "unchecked entries:" << std::endl
<< " player faction: " << info.pcFaction << std::endl
<< " disposition: " << info.data.disposition << std::endl
<< " NPC rank: " << static_cast<int> (info.data.rank) << std::endl
<< " gender: " << static_cast<int> (info.data.gender) << std::endl
<< " PC rank: " << static_cast<int> (info.data.PCrank) << std::endl;
return true; return true;
} }
DialogueManager::DialogueManager (MWWorld::Environment& environment) : mEnvironment (environment) {} DialogueManager::DialogueManager (MWWorld::Environment& environment,const Compiler::Extensions& extensions) :
mEnvironment (environment),mCompilerContext (MWScript::CompilerContext::Type_Dialgoue, environment),
mErrorStream(std::cout.rdbuf()),mErrorHandler(mErrorStream)
{
mChoice = -1;
mIsInChoice = false;
mCompilerContext.setExtensions (&extensions);
}
void DialogueManager::addTopic(std::string topic)
{
knownTopics[toLower(topic)] = true;
}
void DialogueManager::parseText(std::string text)
{
std::list<std::string>::iterator it;
for(it = actorKnownTopics.begin();it != actorKnownTopics.end();it++)
{
size_t pos = find_str_ci(text,*it,0);
if(pos !=std::string::npos)
{
if(pos==0)
{
knownTopics[*it] = true;
}
else if(text.substr(pos -1,1) == " ")
{
knownTopics[*it] = true;
}
}
}
updateTopics();
}
void DialogueManager::startDialogue (const MWWorld::Ptr& actor) void DialogueManager::startDialogue (const MWWorld::Ptr& actor)
{ {
std::cout << "talking with " << MWWorld::Class::get (actor).getName (actor) << std::endl; mChoice = -1;
mIsInChoice = false;
const ESM::Dialogue *dialogue = mEnvironment.mWorld->getStore().dialogs.find ("hello"); mActor = actor;
for (std::vector<ESM::DialInfo>::const_iterator iter (dialogue->mInfo.begin()); mDialogueMap.clear();
iter!=dialogue->mInfo.end(); ++iter) actorKnownTopics.clear();
ESMS::RecListT<ESM::Dialogue>::MapType dialogueList = mEnvironment.mWorld->getStore().dialogs.list;
for(ESMS::RecListT<ESM::Dialogue>::MapType::iterator it = dialogueList.begin(); it!=dialogueList.end();it++)
{ {
if (isMatching (actor, *iter)) mDialogueMap[it->first] = it->second;
}
//initialise the GUI
mEnvironment.mInputManager->setGuiMode(MWGui::GM_Dialogue);
MWGui::DialogueWindow* win = mEnvironment.mWindowManager->getDialogueWindow();
win->startDialogue(MWWorld::Class::get (actor).getName (actor));
//setup the list of topics known by the actor. Topics who are also on the knownTopics list will be added to the GUI
updateTopics();
//greeting
bool greetingFound = false;
//ESMS::RecListT<ESM::Dialogue>::MapType dialogueList = mEnvironment.mWorld->getStore().dialogs.list;
for(ESMS::RecListT<ESM::Dialogue>::MapType::iterator it = dialogueList.begin(); it!=dialogueList.end();it++)
{
ESM::Dialogue ndialogue = it->second;
if(ndialogue.type == ESM::Dialogue::Greeting)
{
if (greetingFound) break;
for (std::vector<ESM::DialInfo>::const_iterator iter (it->second.mInfo.begin());
iter!=it->second.mInfo.end(); ++iter)
{
if (isMatching (actor, *iter) && functionFilter(mActor,*iter,true))
{ {
// start dialogue
std::cout << "found matching info record" << std::endl;
std::cout << "response: " << iter->response << std::endl;
if (!iter->sound.empty()) if (!iter->sound.empty())
{ {
// TODO play sound // TODO play sound
} }
if (!iter->resultScript.empty()) std::string text = iter->response;
{ parseText(text);
std::cout << "script: " << iter->resultScript << std::endl; win->addText(iter->response);
// TODO execute script executeScript(iter->resultScript);
} greetingFound = true;
mLastTopic = it->first;
mEnvironment.mInputManager->setGuiMode(MWGui::GM_Dialogue); mLastDialogue = *iter;
break; break;
} }
} }
} }
}
}
bool DialogueManager::compile (const std::string& cmd,std::vector<Interpreter::Type_Code>& code)
{
try
{
mErrorHandler.reset();
std::istringstream input (cmd + "\n");
Compiler::Scanner scanner (mErrorHandler, input, mCompilerContext.getExtensions());
Compiler::Locals locals;
std::string actorScript = MWWorld::Class::get (mActor).getScript (mActor);
if (!actorScript.empty())
{
// grab local variables from actor's script, if available.
locals = mEnvironment.mScriptManager->getLocals (actorScript);
}
Compiler::ScriptParser parser(mErrorHandler,mCompilerContext, locals, false);
scanner.scan (parser);
if(mErrorHandler.isGood())
{
parser.getCode(code);
return true;
}
return false;
}
catch (const Compiler::SourceException& error)
{
// error has already been reported via error handler
}
catch (const std::exception& error)
{
printError (std::string ("An exception has been thrown: ") + error.what());
}
return false;
}
void DialogueManager::executeScript(std::string script)
{
std::vector<Interpreter::Type_Code> code;
if(compile(script,code))
{
try
{
MWScript::InterpreterContext interpreterContext(mEnvironment,&mActor.getRefData().getLocals(),mActor);
Interpreter::Interpreter interpreter;
MWScript::installOpcodes (interpreter);
interpreter.run (&code[0], code.size(), interpreterContext);
}
catch (const std::exception& error)
{
printError (std::string ("An exception has been thrown: ") + error.what());
}
}
}
void DialogueManager::updateTopics()
{
std::list<std::string> keywordList;
int choice = mChoice;
mChoice = -1;
actorKnownTopics.clear();
MWGui::DialogueWindow* win = mEnvironment.mWindowManager->getDialogueWindow();
ESMS::RecListT<ESM::Dialogue>::MapType dialogueList = mEnvironment.mWorld->getStore().dialogs.list;
for(ESMS::RecListT<ESM::Dialogue>::MapType::iterator it = dialogueList.begin(); it!=dialogueList.end();it++)
{
ESM::Dialogue ndialogue = it->second;
if(ndialogue.type == ESM::Dialogue::Topic)
{
for (std::vector<ESM::DialInfo>::const_iterator iter (it->second.mInfo.begin());
iter!=it->second.mInfo.end(); ++iter)
{
if (isMatching (mActor, *iter) && functionFilter(mActor,*iter,true))
{
actorKnownTopics.push_back(it->first);
//does the player know the topic?
if(knownTopics.find(toLower(it->first)) != knownTopics.end())
{
keywordList.push_back(it->first);
break;
}
}
}
}
}
win->setKeywords(keywordList);
mChoice = choice;
}
void DialogueManager::keywordSelected(std::string keyword)
{
if(!mIsInChoice)
{
if(mDialogueMap.find(keyword) != mDialogueMap.end())
{
ESM::Dialogue ndialogue = mDialogueMap[keyword];
if(ndialogue.type == ESM::Dialogue::Topic)
{
for (std::vector<ESM::DialInfo>::const_iterator iter = ndialogue.mInfo.begin();
iter!=ndialogue.mInfo.end(); ++iter)
{
if (isMatching (mActor, *iter) && functionFilter(mActor,*iter,true))
{
std::string text = iter->response;
std::string script = iter->resultScript;
parseText(text);
MWGui::DialogueWindow* win = mEnvironment.mWindowManager->getDialogueWindow();
win->addTitle(keyword);
win->addText(iter->response);
executeScript(script);
mLastTopic = keyword;
mLastDialogue = *iter;
break;
}
}
}
}
}
updateTopics();
}
void DialogueManager::goodbyeSelected()
{
mEnvironment.mInputManager->setGuiMode(MWGui::GM_Game);
}
void DialogueManager::questionAnswered(std::string answere)
{
if(mChoiceMap.find(answere) != mChoiceMap.end())
{
mChoice = mChoiceMap[answere];
std::vector<ESM::DialInfo>::const_iterator iter;
if(mDialogueMap.find(mLastTopic) != mDialogueMap.end())
{
ESM::Dialogue ndialogue = mDialogueMap[mLastTopic];
if(ndialogue.type == ESM::Dialogue::Topic)
{
for (std::vector<ESM::DialInfo>::const_iterator iter = ndialogue.mInfo.begin();
iter!=ndialogue.mInfo.end(); ++iter)
{
if (isMatching (mActor, *iter) && functionFilter(mActor,*iter,true))
{
mChoiceMap.clear();
mChoice = -1;
mIsInChoice = false;
MWGui::DialogueWindow* win = mEnvironment.mWindowManager->getDialogueWindow();
std::string text = iter->response;
parseText(text);
win->addText(text);
executeScript(iter->resultScript);
mLastTopic = mLastTopic;
mLastDialogue = *iter;
break;
}
}
}
}
updateTopics();
}
}
void DialogueManager::printError(std::string error)
{
MWGui::DialogueWindow* win = mEnvironment.mWindowManager->getDialogueWindow();
win->addText(error);
}
void DialogueManager::askQuestion(std::string question, int choice)
{
MWGui::DialogueWindow* win = mEnvironment.mWindowManager->getDialogueWindow();
win->askQuestion(question);
mChoiceMap[question] = choice;
mIsInChoice = true;
}
} }

View file

@ -3,7 +3,13 @@
#include <components/esm/loadinfo.hpp> #include <components/esm/loadinfo.hpp>
#include <components/compiler/streamerrorhandler.hpp>
#include "../mwscript/compilercontext.hpp"
#include "../mwscript/interpretercontext.hpp"
#include <components/compiler/output.hpp>
#include "../mwworld/ptr.hpp" #include "../mwworld/ptr.hpp"
#include <map>
namespace MWWorld namespace MWWorld
{ {
@ -20,12 +26,48 @@ namespace MWDialogue
bool isMatching (const MWWorld::Ptr& actor, const ESM::DialInfo& info) const; bool isMatching (const MWWorld::Ptr& actor, const ESM::DialInfo& info) const;
bool functionFilter(const MWWorld::Ptr& actor, const ESM::DialInfo& info,bool choice);
void parseText(std::string text);
void updateTopics();
std::map<std::string,ESM::Dialogue> mDialogueMap;
std::map<std::string,bool> knownTopics;// Those are the topics the player knows.
std::list<std::string> actorKnownTopics;
MWScript::CompilerContext mCompilerContext;
std::ostream mErrorStream;
Compiler::StreamErrorHandler mErrorHandler;
bool compile (const std::string& cmd,std::vector<Interpreter::Type_Code>& code);
void executeScript(std::string script);
MWWorld::Ptr mActor;
void printError(std::string error);
int mChoice;
std::map<std::string,int> mChoiceMap;
std::string mLastTopic;
ESM::DialInfo mLastDialogue;
bool mIsInChoice;
public: public:
DialogueManager (MWWorld::Environment& environment); DialogueManager (MWWorld::Environment& environment,const Compiler::Extensions& extensions);
void startDialogue (const MWWorld::Ptr& actor); void startDialogue (const MWWorld::Ptr& actor);
void addTopic(std::string topic);
void askQuestion(std::string question,int choice);
//calbacks for the GUI
void keywordSelected(std::string keyword);
void goodbyeSelected();
void questionAnswered(std::string answere);
}; };
} }

View file

@ -3,6 +3,9 @@
#include "../mwworld/environment.hpp" #include "../mwworld/environment.hpp"
#include "../mwgui/window_manager.hpp"
#include "../mwgui/messagebox.hpp"
namespace MWDialogue namespace MWDialogue
{ {
Quest& Journal::getQuest (const std::string& id) Quest& Journal::getQuest (const std::string& id)
@ -34,6 +37,10 @@ namespace MWDialogue
Quest& quest = getQuest (id); Quest& quest = getQuest (id);
quest.addEntry (entry, *mEnvironment.mWorld); // we are doing slicing on purpose here quest.addEntry (entry, *mEnvironment.mWorld); // we are doing slicing on purpose here
std::vector<std::string> empty;
std::string notification = "Your Journal has been updated.";
mEnvironment.mWindowManager->messageBox (notification, empty);
} }
void Journal::setJournalIndex (const std::string& id, int index) void Journal::setJournalIndex (const std::string& id, int index)
@ -60,7 +67,12 @@ namespace MWDialogue
int Journal::getJournalIndex (const std::string& id) const int Journal::getJournalIndex (const std::string& id) const
{ {
TQuestContainer::const_iterator iter = mQuests.find (id);
if (iter==mQuests.end())
return 0; return 0;
return iter->second.getIndex();
} }
Journal::TEntryIter Journal::begin() const Journal::TEntryIter Journal::begin() const

View file

@ -139,6 +139,9 @@ namespace MWGui
void Console::disable() void Console::disable()
{ {
setVisible(false); setVisible(false);
// Remove keyboard focus from the console input whenever the
// console is turned off
MyGUI::InputManager::getInstance().setKeyFocusWidget(NULL);
} }
void Console::setFont(const std::string &fntName) void Console::setFont(const std::string &fntName)

View file

@ -3,6 +3,8 @@
#include "window_manager.hpp" #include "window_manager.hpp"
#include "widgets.hpp" #include "widgets.hpp"
#include "components/esm_store/store.hpp" #include "components/esm_store/store.hpp"
#include "../mwworld/environment.hpp"
#include "../mwdialogue/dialoguemanager.hpp"
#include <assert.h> #include <assert.h>
#include <iostream> #include <iostream>
@ -14,8 +16,29 @@
using namespace MWGui; using namespace MWGui;
using namespace Widgets; using namespace Widgets;
DialogueWindow::DialogueWindow(WindowManager& parWindowManager) /**
: WindowBase("openmw_dialogue_window_layout.xml", parWindowManager) *Copied from the internet.
*/
std::string lower_string(const std::string& str)
{
std::string lowerCase;
std::transform (str.begin(), str.end(), std::back_inserter (lowerCase),
(int(*)(int)) std::tolower);
return lowerCase;
}
std::string::size_type find_str_ci(const std::string& str, const std::string& substr,size_t pos)
{
return lower_string(str).find(lower_string(substr),pos);
}
DialogueWindow::DialogueWindow(WindowManager& parWindowManager,MWWorld::Environment& environment)
: WindowBase("openmw_dialogue_window_layout.xml", parWindowManager),
mEnvironment(environment)
{ {
// Centre dialog // Centre dialog
center(); center();
@ -27,19 +50,20 @@ DialogueWindow::DialogueWindow(WindowManager& parWindowManager)
getWidget(history, "History"); getWidget(history, "History");
history->setOverflowToTheLeft(true); history->setOverflowToTheLeft(true);
history->getClient()->eventMouseButtonClick = MyGUI::newDelegate(this, &DialogueWindow::onHistoryClicked); history->getClient()->eventMouseButtonClick = MyGUI::newDelegate(this, &DialogueWindow::onHistoryClicked);
history->setMaxTextLength(1000000);
//Topics list //Topics list
getWidget(topicsList, "TopicsList"); getWidget(topicsList, "TopicsList");
topicsList->setScrollVisible(true); topicsList->setScrollVisible(true);
topicsList->eventListSelectAccept = MyGUI::newDelegate(this, &DialogueWindow::onSelectTopic); //topicsList->eventListSelectAccept = MyGUI::newDelegate(this, &DialogueWindow::onSelectTopic);
topicsList->eventListMouseItemActivate = MyGUI::newDelegate(this, &DialogueWindow::onSelectTopic); topicsList->eventListMouseItemActivate = MyGUI::newDelegate(this, &DialogueWindow::onSelectTopic);
topicsList->eventListChangePosition = MyGUI::newDelegate(this, &DialogueWindow::onSelectTopic); //topicsList->eventListChangePosition = MyGUI::newDelegate(this, &DialogueWindow::onSelectTopic);
MyGUI::ButtonPtr byeButton; MyGUI::ButtonPtr byeButton;
getWidget(byeButton, "ByeButton"); getWidget(byeButton, "ByeButton");
byeButton->eventMouseButtonClick = MyGUI::newDelegate(this, &DialogueWindow::onByeClicked); byeButton->eventMouseButtonClick = MyGUI::newDelegate(this, &DialogueWindow::onByeClicked);
updateOptions(); getWidget(pDispositionBar, "Disposition");
getWidget(pDispositionText,"DispositionText");
} }
void DialogueWindow::onHistoryClicked(MyGUI::Widget* _sender) void DialogueWindow::onHistoryClicked(MyGUI::Widget* _sender)
@ -51,70 +75,126 @@ void DialogueWindow::onHistoryClicked(MyGUI::Widget* _sender)
const IntPoint& lastPressed = InputManager::getInstance().getLastLeftPressed(); const IntPoint& lastPressed = InputManager::getInstance().getLastLeftPressed();
size_t cursorPosition = t->getCursorPosition(lastPressed); size_t cursorPosition = t->getCursorPosition(lastPressed);
if(history->getColorAtPos(cursorPosition) != "#FFFFFF") MyGUI::UString color = history->getColorAtPos(cursorPosition);
if(color != "#B29154")
{ {
UString key = history->getColorTextAt(cursorPosition); UString key = history->getColorTextAt(cursorPosition);
std::cout << "Clicked on key: " << key << std::endl; if(color == "#686EBA") mEnvironment.mDialogueManager->keywordSelected(lower_string(key));
//eventTopicSelected(key);
if(color == "#572D21") mEnvironment.mDialogueManager->questionAnswered(key);
} }
} }
void DialogueWindow::open() void DialogueWindow::open()
{ {
topicsList->removeAllItems();
pTopicsText.clear();
history->eraseText(0,history->getTextLength());
updateOptions(); updateOptions();
setVisible(true); setVisible(true);
} }
void DialogueWindow::onByeClicked(MyGUI::Widget* _sender) void DialogueWindow::onByeClicked(MyGUI::Widget* _sender)
{ {
eventBye(); mEnvironment.mDialogueManager->goodbyeSelected();
} }
void DialogueWindow::onSelectTopic(MyGUI::List* _sender, size_t _index) void DialogueWindow::onSelectTopic(MyGUI::List* _sender, size_t _index)
{ {
if (_index == MyGUI::ITEM_NONE) if (_index == MyGUI::ITEM_NONE)
return; return;
std::string topic = _sender->getItemNameAt(_index);
//const std::string* theTopic = topicsList->getItemDataAt<std::string>(_index); mEnvironment.mDialogueManager->keywordSelected(lower_string(topic));
//std::cout << "Selected: "<< theTopic << std::endl;
//eventTopicSelected(key);
} }
void DialogueWindow::startDialogue(std::string npcName)
{
setText("NpcName", npcName);
}
void DialogueWindow::setKeywords(std::list<std::string> keyWords)
{
topicsList->removeAllItems();
for(std::list<std::string>::iterator it = keyWords.begin(); it != keyWords.end(); it++)
{
topicsList->addItem(*it);
}
}
void DialogueWindow::removeKeyword(std::string keyWord)
{
if(topicsList->findItemIndexWith(keyWord) != MyGUI::ITEM_NONE)
{
topicsList->removeItemAt(topicsList->findItemIndexWith(keyWord));
pTopicsText.erase(keyWord);
}
}
void addColorInString(std::string& str, const std::string& keyword,std::string color1, std::string color2)
{
size_t pos = 0;
while((pos = find_str_ci(str,keyword, pos)) != std::string::npos)
{
if(pos==0)
{
str.insert(pos,color1);
pos += color1.length();
pos += keyword.length();
str.insert(pos,color2);
pos+= color2.length();
}
else
{
if(str.substr(pos -1,1) == " ")
{
str.insert(pos,color1);
pos += color1.length();
pos += keyword.length();
str.insert(pos,color2);
pos+= color2.length();
}
else
{
pos += keyword.length();
}
}
}
}
std::string DialogueWindow::parseText(std::string text)
{
for(unsigned int i = 0;i<topicsList->getItemCount();i++)
{
std::string keyWord = topicsList->getItemNameAt(i);
addColorInString(text,keyWord,"#686EBA","#B29154");
}
return text;
}
void DialogueWindow::addText(std::string text)
{
history->addDialogText("#B29154"+parseText(text)+"#B29154");
}
void DialogueWindow::addTitle(std::string text)
{
history->addDialogHeading(text);
}
void DialogueWindow::askQuestion(std::string question)
{
history->addDialogText("#572D21"+question+"#B29154"+" ");
}
void DialogueWindow::updateOptions() void DialogueWindow::updateOptions()
{ {
//FIXME Add this properly
history->addDialogText("Through the translucent surface of the orb, you see shifting images of distant locations...");
for(int z = 0; z < 10; z++)
{
history->addDialogHeading("Fort Frostmoth");
history->addDialogText("The image in the orb flickers, and you see.... The cold courtyard of #FF0000Fort Frostmoth#FFFFFF, battered bu werewolf attack, but still standing, still projecting Imperial might even to this distant and cold corner of the world.");
}
//Clear the list of topics //Clear the list of topics
topicsList->removeAllItems(); topicsList->removeAllItems();
int i = 0; pTopicsText.clear();
topicsList->addItem("Ald'ruhn", i++); history->eraseText(0,history->getTextLength());
topicsList->addItem("Balmora", i++);
topicsList->addItem("Sadrith Mora", i++);
topicsList->addItem("Vivec", i++);
topicsList->addItem("Ald Velothi", i++);
topicsList->addItem("Caldera", i++);
topicsList->addItem("Dagon Fel ", i++);
topicsList->addItem("Gnaar Mok", i++);
topicsList->addItem("Gnisis", i++);
topicsList->addItem("Hla Oad", i++);
topicsList->addItem("Khuul", i++);
topicsList->addItem("Maar Gan", i++);
topicsList->addItem("Molag Mar", i++);
topicsList->addItem("Pelagiad", i++);
topicsList->addItem("Seyda Neen", i++);
topicsList->addItem("Suran", i++);
topicsList->addItem("Tel Aruhn", i++);
topicsList->addItem("Tel Branora", i++);
topicsList->addItem("Tel Fyr", i++);
topicsList->addItem("Tel Mora", i++);
topicsList->addItem("Tel Vos", i++);
topicsList->addItem("Vos", i++);
}
pDispositionBar->setProgressRange(100);
pDispositionBar->setProgressPosition(40);
pDispositionText->eraseText(0,pDispositionText->getTextLength());
pDispositionText->addText("#B29154"+std::string("40/100")+"#B29154");
}

View file

@ -9,6 +9,11 @@ namespace MWGui
class WindowManager; class WindowManager;
} }
namespace MWWorld
{
class Environment;
}
/* /*
This file contains the dialouge window This file contains the dialouge window
Layout is defined by resources/mygui/openmw_dialogue_window_layout.xml. Layout is defined by resources/mygui/openmw_dialogue_window_layout.xml.
@ -23,7 +28,7 @@ namespace MWGui
class DialogueWindow: public WindowBase class DialogueWindow: public WindowBase
{ {
public: public:
DialogueWindow(WindowManager& parWindowManager); DialogueWindow(WindowManager& parWindowManager,MWWorld::Environment& environment);
void open(); void open();
@ -35,6 +40,14 @@ namespace MWGui
*/ */
EventHandle_Void eventBye; EventHandle_Void eventBye;
void startDialogue(std::string npcName);
void stopDialogue();
void setKeywords(std::list<std::string> keyWord);
void removeKeyword(std::string keyWord);
void addText(std::string text);
void addTitle(std::string text);
void askQuestion(std::string question);
protected: protected:
void onSelectTopic(MyGUI::List* _sender, size_t _index); void onSelectTopic(MyGUI::List* _sender, size_t _index);
void onByeClicked(MyGUI::Widget* _sender); void onByeClicked(MyGUI::Widget* _sender);
@ -42,9 +55,18 @@ namespace MWGui
private: private:
void updateOptions(); void updateOptions();
/**
*Helper function that add topic keyword in blue in a text.
*/
std::string parseText(std::string text);
DialogeHistory* history; DialogeHistory* history;
MyGUI::ListPtr topicsList; MyGUI::ListPtr topicsList;
MyGUI::ProgressPtr pDispositionBar;
MyGUI::EditPtr pDispositionText;
std::map<std::string,std::string> pTopicsText;// this map links keyword and "real" text.
MWWorld::Environment& mEnvironment;
}; };
} }
#endif #endif

View file

@ -61,9 +61,9 @@ UString DialogeHistory::getColorTextAt(size_t _pos)
void DialogeHistory::addDialogHeading(const UString& parText) void DialogeHistory::addDialogHeading(const UString& parText)
{ {
UString head("\n#00FF00"); UString head("\n#D8C09A");
head.append(parText); head.append(parText);
head.append("#FFFFFF\n"); head.append("#B29154\n");
addText(head); addText(head);
} }

View file

@ -4,6 +4,8 @@
#include "../mwworld/environment.hpp" #include "../mwworld/environment.hpp"
#include "../mwworld/world.hpp" #include "../mwworld/world.hpp"
#include "../mwsound/soundmanager.hpp"
namespace namespace
{ {
struct book struct book
@ -115,6 +117,8 @@ MWGui::JournalWindow::JournalWindow (WindowManager& parWindowManager)
void MWGui::JournalWindow::open() void MWGui::JournalWindow::open()
{ {
mPageNumber = 0; mPageNumber = 0;
std::string journalOpenSound = "book open";
mWindowManager.getEnvironment().mSoundManager->playSound (journalOpenSound, 1.0, 1.0);
if(mWindowManager.getEnvironment().mJournal->begin()!=mWindowManager.getEnvironment().mJournal->end()) if(mWindowManager.getEnvironment().mJournal->begin()!=mWindowManager.getEnvironment().mJournal->end())
{ {
book journal; book journal;
@ -176,6 +180,8 @@ void MWGui::JournalWindow::notifyNextPage(MyGUI::WidgetPtr _sender)
{ {
if(mPageNumber < int(leftPages.size())-1) if(mPageNumber < int(leftPages.size())-1)
{ {
std::string nextSound = "book page2";
mWindowManager.getEnvironment().mSoundManager->playSound (nextSound, 1.0, 1.0);
mPageNumber = mPageNumber + 1; mPageNumber = mPageNumber + 1;
displayLeftText(leftPages[mPageNumber]); displayLeftText(leftPages[mPageNumber]);
displayRightText(rightPages[mPageNumber]); displayRightText(rightPages[mPageNumber]);
@ -186,6 +192,8 @@ void MWGui::JournalWindow::notifyPrevPage(MyGUI::WidgetPtr _sender)
{ {
if(mPageNumber > 0) if(mPageNumber > 0)
{ {
std::string prevSound = "book page";
mWindowManager.getEnvironment().mSoundManager->playSound (prevSound, 1.0, 1.0);
mPageNumber = mPageNumber - 1; mPageNumber = mPageNumber - 1;
displayLeftText(leftPages[mPageNumber]); displayLeftText(leftPages[mPageNumber]);
displayRightText(rightPages[mPageNumber]); displayRightText(rightPages[mPageNumber]);

View file

@ -57,8 +57,6 @@ void MessageBoxManager::onFrame (float frameDuration)
void MessageBoxManager::createMessageBox (const std::string& message) void MessageBoxManager::createMessageBox (const std::string& message)
{ {
std::cout << "MessageBox: " << message << std::endl;
MessageBox *box = new MessageBox(*this, message); MessageBox *box = new MessageBox(*this, message);
removeMessageBox(message.length()*mMessageBoxSpeed, box); removeMessageBox(message.length()*mMessageBoxSpeed, box);
@ -387,8 +385,3 @@ int InteractiveMessageBox::readPressedButton ()
mButtonPressed = -1; mButtonPressed = -1;
return pressed; return pressed;
} }

View file

@ -51,6 +51,7 @@ WindowManager::WindowManager(MWWorld::Environment& environment,
console = new Console(w,h, environment, extensions); console = new Console(w,h, environment, extensions);
mJournal = new JournalWindow(*this); mJournal = new JournalWindow(*this);
mMessageBoxManager = new MessageBoxManager(this); mMessageBoxManager = new MessageBoxManager(this);
dialogueWindow = new DialogueWindow(*this,environment);
// The HUD is always on // The HUD is always on
hud->setVisible(true); hud->setVisible(true);
@ -149,6 +150,7 @@ void WindowManager::updateVisible()
stats->setVisible(false); stats->setVisible(false);
console->disable(); console->disable();
mJournal->setVisible(false); mJournal->setVisible(false);
dialogueWindow->setVisible(false);
// Mouse is visible whenever we're not in game mode // Mouse is visible whenever we're not in game mode
gui->setVisiblePointer(isGuiMode()); gui->setVisiblePointer(isGuiMode());
@ -195,11 +197,6 @@ void WindowManager::updateVisible()
if (mode == GM_Dialogue) if (mode == GM_Dialogue)
{ {
if (!dialogueWindow)
{
dialogueWindow = new DialogueWindow(*this);
dialogueWindow->eventBye = MyGUI::newDelegate(this, &WindowManager::onDialogueWindowBye);
}
dialogueWindow->open(); dialogueWindow->open();
return; return;
} }
@ -349,6 +346,7 @@ void WindowManager::updateSkillArea()
void WindowManager::removeDialog(OEngine::GUI::Layout*dialog) void WindowManager::removeDialog(OEngine::GUI::Layout*dialog)
{ {
std::cout << "dialogue a la poubelle";
assert(dialog); assert(dialog);
if (!dialog) if (!dialog)
return; return;
@ -387,7 +385,8 @@ void WindowManager::onDialogueWindowBye()
if (dialogueWindow) if (dialogueWindow)
{ {
//FIXME set some state and stuff? //FIXME set some state and stuff?
removeDialog(dialogueWindow); //removeDialog(dialogueWindow);
dialogueWindow->setVisible(false);
} }
setGuiMode(GM_Game); setGuiMode(GM_Game);
} }

View file

@ -124,6 +124,8 @@ namespace MWGui
updateVisible(); updateVisible();
} }
MWGui::DialogueWindow* getDialogueWindow() {return dialogueWindow;}
MyGUI::Gui* getGui() const { return gui; } MyGUI::Gui* getGui() const { return gui; }
void wmUpdateFps(float fps, size_t triangleCount, size_t batchCount) void wmUpdateFps(float fps, size_t triangleCount, size_t batchCount)

View file

@ -51,7 +51,7 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const
cameraPitchNode->attachObject(mRendering.getCamera()); cameraPitchNode->attachObject(mRendering.getCamera());
//mSkyManager = 0; //mSkyManager = 0;
mSkyManager = new SkyManager(mMwRoot, mRendering.getCamera()); mSkyManager = new SkyManager(mMwRoot, mRendering.getCamera(), &environment);
mPlayer = new MWRender::Player (mRendering.getCamera(), playerNode); mPlayer = new MWRender::Player (mRendering.getCamera(), playerNode);
mSun = 0; mSun = 0;

View file

@ -10,16 +10,12 @@
#include <components/nifogre/ogre_nif_loader.hpp> #include <components/nifogre/ogre_nif_loader.hpp>
#include "../mwworld/environment.hpp"
#include "../mwworld/world.hpp"
using namespace MWRender; using namespace MWRender;
using namespace Ogre; using namespace Ogre;
// the speed at which the clouds are animated
#define CLOUD_SPEED 0.001
// this distance has to be set accordingly so that the
// celestial bodies are behind the clouds, but in front of the atmosphere
#define CELESTIAL_BODY_DISTANCE 1000.f
BillboardObject::BillboardObject( const String& textureName, BillboardObject::BillboardObject( const String& textureName,
const float initialSize, const float initialSize,
const Vector3& position, const Vector3& position,
@ -50,7 +46,7 @@ void BillboardObject::setVisibility(const float visibility)
void BillboardObject::setPosition(const Vector3& pPosition) void BillboardObject::setPosition(const Vector3& pPosition)
{ {
Vector3 normalised = pPosition.normalisedCopy(); Vector3 normalised = pPosition.normalisedCopy();
Vector3 finalPosition = normalised * CELESTIAL_BODY_DISTANCE; Vector3 finalPosition = normalised * 1000.f;
mBBSet->setCommonDirection( -normalised ); mBBSet->setCommonDirection( -normalised );
@ -85,7 +81,7 @@ void BillboardObject::init(const String& textureName,
{ {
SceneManager* sceneMgr = rootNode->getCreator(); SceneManager* sceneMgr = rootNode->getCreator();
Vector3 finalPosition = position.normalisedCopy() * CELESTIAL_BODY_DISTANCE; Vector3 finalPosition = position.normalisedCopy() * 1000.f;
static unsigned int bodyCount=0; static unsigned int bodyCount=0;
@ -296,9 +292,10 @@ void SkyManager::ModVertexAlpha(Entity* ent, unsigned int meshType)
ent->getMesh()->getSubMesh(0)->vertexData->vertexBufferBinding->getBuffer(ves_diffuse->getSource())->unlock(); ent->getMesh()->getSubMesh(0)->vertexData->vertexBufferBinding->getBuffer(ves_diffuse->getSource())->unlock();
} }
SkyManager::SkyManager (SceneNode* pMwRoot, Camera* pCamera) : SkyManager::SkyManager (SceneNode* pMwRoot, Camera* pCamera, MWWorld::Environment* env) :
mGlareFade(0), mGlareEnabled(false) mGlareFade(0), mGlareEnabled(false)
{ {
mEnvironment = env;
mViewport = pCamera->getViewport(); mViewport = pCamera->getViewport();
mSceneMgr = pMwRoot->getCreator(); mSceneMgr = pMwRoot->getCreator();
mRootNode = pCamera->getParentSceneNode()->createChildSceneNode(); mRootNode = pCamera->getParentSceneNode()->createChildSceneNode();
@ -312,7 +309,7 @@ SkyManager::SkyManager (SceneNode* pMwRoot, Camera* pCamera) :
Pass* pass = material->getTechnique(0)->getPass(0); Pass* pass = material->getTechnique(0)->getPass(0);
pass->setSceneBlending(SBT_TRANSPARENT_ALPHA); pass->setSceneBlending(SBT_TRANSPARENT_ALPHA);
mThunderTextureUnit = pass->createTextureUnitState(); mThunderTextureUnit = pass->createTextureUnitState();
mThunderTextureUnit->setColourOperationEx(LBX_SOURCE1, LBS_MANUAL, LBS_CURRENT, ColourValue(1.f, 1.f, 1.f)); // always black colour mThunderTextureUnit->setColourOperationEx(LBX_SOURCE1, LBS_MANUAL, LBS_CURRENT, ColourValue(1.f, 1.f, 1.f));
mThunderTextureUnit->setAlphaOperation(LBX_SOURCE1, LBS_MANUAL, LBS_CURRENT, 0.5f); mThunderTextureUnit->setAlphaOperation(LBX_SOURCE1, LBS_MANUAL, LBS_CURRENT, 0.5f);
OverlayManager& ovm = OverlayManager::getSingleton(); OverlayManager& ovm = OverlayManager::getSingleton();
mThunderOverlay = ovm.create( "ThunderOverlay" ); mThunderOverlay = ovm.create( "ThunderOverlay" );
@ -504,7 +501,7 @@ SkyManager::SkyManager (SceneNode* pMwRoot, Camera* pCamera) :
" uniform float4 emissive \n" " uniform float4 emissive \n"
") \n" ") \n"
"{ \n" "{ \n"
" uv += float2(1,1) * time * speed * "<<CLOUD_SPEED<<"; \n" // Scroll in x,y direction " uv += float2(1,0) * time * speed * 0.003; \n" // Scroll in x direction
" float4 tex = lerp(tex2D(texture, uv), tex2D(secondTexture, uv), transitionFactor); \n" " float4 tex = lerp(tex2D(texture, uv), tex2D(secondTexture, uv), transitionFactor); \n"
" oColor = color * float4(emissive.xyz,1) * tex * float4(1,1,1,opacity); \n" " oColor = color * float4(emissive.xyz,1) * tex * float4(1,1,1,opacity); \n"
"}"; "}";
@ -558,7 +555,7 @@ void SkyManager::update(float duration)
if (!mEnabled) return; if (!mEnabled) return;
// UV Scroll the clouds // UV Scroll the clouds
mCloudMaterial->getTechnique(0)->getPass(0)->getFragmentProgramParameters()->setNamedConstantFromTime("time", 1); mCloudMaterial->getTechnique(0)->getPass(0)->getFragmentProgramParameters()->setNamedConstantFromTime("time", mEnvironment->mWorld->getTimeScaleFactor()/30.f);
/// \todo improve this /// \todo improve this
mMasser->setPhase( static_cast<Moon::Phase>( (int) ((mDay % 32)/4.f)) ); mMasser->setPhase( static_cast<Moon::Phase>( (int) ((mDay % 32)/4.f)) );
@ -594,8 +591,8 @@ void SkyManager::update(float duration)
mMasser->setVisible(mMasserEnabled); mMasser->setVisible(mMasserEnabled);
mSecunda->setVisible(mSecundaEnabled); mSecunda->setVisible(mSecundaEnabled);
// rotate the whole sky by 360 degrees every 4 days // rotate the stars by 360 degrees every 4 days
mRootNode->roll(Degree(mHourDiff*360/96.f)); mAtmosphereNight->roll(Degree(mEnvironment->mWorld->getTimeScaleFactor()*duration*360 / (3600*96.f)));
} }
void SkyManager::enable() void SkyManager::enable()
@ -692,6 +689,7 @@ void SkyManager::setWeather(const MWWorld::WeatherResult& weather)
strength = 1.f; strength = 1.f;
mSunGlare->setVisibility(weather.mGlareView * strength); mSunGlare->setVisibility(weather.mGlareView * strength);
mSun->setVisibility(strength);
mAtmosphereNight->setVisible(weather.mNight && mEnabled); mAtmosphereNight->setVisible(weather.mNight && mEnabled);
} }
@ -775,9 +773,6 @@ void SkyManager::setSecundaFade(const float fade)
void SkyManager::setHour(double hour) void SkyManager::setHour(double hour)
{ {
mHourDiff = mHour - hour;
if (mHourDiff > 0) mHourDiff -= 24;
mHour = hour; mHour = hour;
} }

View file

@ -107,7 +107,7 @@ namespace MWRender
class SkyManager class SkyManager
{ {
public: public:
SkyManager(Ogre::SceneNode* pMwRoot, Ogre::Camera* pCamera); SkyManager(Ogre::SceneNode* pMwRoot, Ogre::Camera* pCamera, MWWorld::Environment* env);
~SkyManager(); ~SkyManager();
void update(float duration); void update(float duration);
@ -164,12 +164,11 @@ namespace MWRender
Ogre::Vector3 getRealSunPos(); Ogre::Vector3 getRealSunPos();
private: private:
MWWorld::Environment* mEnvironment;
float mHour; float mHour;
int mDay; int mDay;
int mMonth; int mMonth;
float mHourDiff;
BillboardObject* mSun; BillboardObject* mSun;
BillboardObject* mSunGlare; BillboardObject* mSunGlare;
Moon* mMasser; Moon* mMasser;

View file

@ -8,6 +8,7 @@
#include <components/interpreter/opcodes.hpp> #include <components/interpreter/opcodes.hpp>
#include "../mwdialogue/journal.hpp" #include "../mwdialogue/journal.hpp"
#include "../mwdialogue/dialoguemanager.hpp"
#include "interpretercontext.hpp" #include "interpretercontext.hpp"
@ -72,15 +73,62 @@ namespace MWScript
} }
}; };
class OpAddTopic : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
MWScript::InterpreterContext& context
= static_cast<MWScript::InterpreterContext&> (runtime.getContext());
std::string topic = runtime.getStringLiteral (runtime[0].mInteger);
runtime.pop();
context.getEnvironment().mDialogueManager->addTopic(topic);
}
};
class OpChoice : public Interpreter::Opcode1
{
public:
virtual void execute (Interpreter::Runtime& runtime, unsigned int arg0)
{
MWScript::InterpreterContext& context
= static_cast<MWScript::InterpreterContext&> (runtime.getContext());
MWDialogue::DialogueManager* dialogue = context.getEnvironment().mDialogueManager;
while(arg0>0)
{
std::string question = runtime.getStringLiteral (runtime[0].mInteger);
runtime.pop();
arg0 = arg0 -1;
Interpreter::Type_Integer choice = 1;
if(arg0>0)
{
choice = runtime[0].mInteger;
runtime.pop();
arg0 = arg0 -1;
}
dialogue->askQuestion(question,choice);
}
}
};
const int opcodeJournal = 0x2000133; const int opcodeJournal = 0x2000133;
const int opcodeSetJournalIndex = 0x2000134; const int opcodeSetJournalIndex = 0x2000134;
const int opcodeGetJournalIndex = 0x2000135; const int opcodeGetJournalIndex = 0x2000135;
const int opcodeAddTopic = 0x200013a;
const int opcodeChoice = 0x2000a;
void registerExtensions (Compiler::Extensions& extensions) void registerExtensions (Compiler::Extensions& extensions)
{ {
extensions.registerInstruction ("journal", "cl", opcodeJournal); extensions.registerInstruction ("journal", "cl", opcodeJournal);
extensions.registerInstruction ("setjournalindex", "cl", opcodeSetJournalIndex); extensions.registerInstruction ("setjournalindex", "cl", opcodeSetJournalIndex);
extensions.registerFunction ("getjournalindex", 'l', "c", opcodeGetJournalIndex); extensions.registerFunction ("getjournalindex", 'l', "c", opcodeGetJournalIndex);
extensions.registerInstruction ("addtopic", "S" , opcodeAddTopic);
extensions.registerInstruction ("choice", "/SlSlSlSlSlSlSlSlSlSlSlSlSlSlSlSl", opcodeChoice);
} }
void installOpcodes (Interpreter::Interpreter& interpreter) void installOpcodes (Interpreter::Interpreter& interpreter)
@ -88,6 +136,8 @@ namespace MWScript
interpreter.installSegment5 (opcodeJournal, new OpJournal); interpreter.installSegment5 (opcodeJournal, new OpJournal);
interpreter.installSegment5 (opcodeSetJournalIndex, new OpSetJournalIndex); interpreter.installSegment5 (opcodeSetJournalIndex, new OpSetJournalIndex);
interpreter.installSegment5 (opcodeGetJournalIndex, new OpGetJournalIndex); interpreter.installSegment5 (opcodeGetJournalIndex, new OpGetJournalIndex);
interpreter.installSegment5 (opcodeAddTopic, new OpAddTopic);
interpreter.installSegment3 (opcodeChoice,new OpChoice);
} }
} }

View file

@ -23,7 +23,8 @@ op 0x20006: PlayAnim
op 0x20007: PlayAnim, explicit reference op 0x20007: PlayAnim, explicit reference
op 0x20008: LoopAnim op 0x20008: LoopAnim
op 0x20009: LoopAnim, explicit reference op 0x20009: LoopAnim, explicit reference
opcodes 0x2000a-0x3ffff unused op 0x2000a: Choice
opcodes 0x2000b-0x3ffff unused
Segment 4: Segment 4:
(not implemented yet) (not implemented yet)
@ -115,6 +116,7 @@ op 0x2000136: GetPCCell
op 0x2000137: GetButtonPressed op 0x2000137: GetButtonPressed
op 0x2000138: SkipAnim op 0x2000138: SkipAnim
op 0x2000139: SkipAnim, expplicit reference op 0x2000139: SkipAnim, expplicit reference
op 0x200013a: AddTopic
op 0x200013b: twf op 0x200013b: twf
op 0x200013c: FadeIn op 0x200013c: FadeIn
op 0x200013d: FadeOut op 0x200013d: FadeOut

View file

@ -63,7 +63,7 @@ namespace MWScript
{ {
std::vector<Interpreter::Type_Code> code; std::vector<Interpreter::Type_Code> code;
mParser.getCode (code); mParser.getCode (code);
mScripts.insert (std::make_pair (name, code)); mScripts.insert (std::make_pair (name, std::make_pair (code, mParser.getLocals())));
// TODO sanity check on generated locals // TODO sanity check on generated locals
@ -77,8 +77,7 @@ namespace MWScript
void ScriptManager::run (const std::string& name, Interpreter::Context& interpreterContext) void ScriptManager::run (const std::string& name, Interpreter::Context& interpreterContext)
{ {
// compile script // compile script
std::map<std::string, std::vector<Interpreter::Type_Code> >::iterator iter = ScriptCollection::iterator iter = mScripts.find (name);
mScripts.find (name);
if (iter==mScripts.end()) if (iter==mScripts.end())
{ {
@ -86,7 +85,7 @@ namespace MWScript
{ {
// failed -> ignore script from now on. // failed -> ignore script from now on.
std::vector<Interpreter::Type_Code> empty; std::vector<Interpreter::Type_Code> empty;
mScripts.insert (std::make_pair (name, empty)); mScripts.insert (std::make_pair (name, std::make_pair (empty, Compiler::Locals())));
return; return;
} }
@ -95,7 +94,7 @@ namespace MWScript
} }
// execute script // execute script
if (!iter->second.empty()) if (!iter->second.first.empty())
try try
{ {
if (!mOpcodesInstalled) if (!mOpcodesInstalled)
@ -104,7 +103,7 @@ namespace MWScript
mOpcodesInstalled = true; mOpcodesInstalled = true;
} }
mInterpreter.run (&iter->second[0], iter->second.size(), interpreterContext); mInterpreter.run (&iter->second.first[0], iter->second.first.size(), interpreterContext);
} }
catch (const std::exception& e) catch (const std::exception& e)
{ {
@ -113,7 +112,7 @@ namespace MWScript
if (mVerbose) if (mVerbose)
std::cerr << "(" << e.what() << ")" << std::endl; std::cerr << "(" << e.what() << ")" << std::endl;
iter->second.clear(); // don't execute again. iter->second.first.clear(); // don't execute again.
} }
} }
@ -132,4 +131,24 @@ namespace MWScript
return std::make_pair (count, success); return std::make_pair (count, success);
} }
Compiler::Locals& ScriptManager::getLocals (const std::string& name)
{
ScriptCollection::iterator iter = mScripts.find (name);
if (iter==mScripts.end())
{
if (!compile (name))
{
// failed -> ignore script from now on.
std::vector<Interpreter::Type_Code> empty;
mScripts.insert (std::make_pair (name, std::make_pair (empty, Compiler::Locals())));
throw std::runtime_error ("failed to compile script " + name);
}
iter = mScripts.find (name);
}
return iter->second.second;
}
} }

View file

@ -39,7 +39,11 @@ namespace MWScript
Interpreter::Interpreter mInterpreter; Interpreter::Interpreter mInterpreter;
bool mOpcodesInstalled; bool mOpcodesInstalled;
std::map<std::string, std::vector<Interpreter::Type_Code> > mScripts; typedef std::pair<std::vector<Interpreter::Type_Code>, Compiler::Locals> CompiledScript;
typedef std::map<std::string, CompiledScript> ScriptCollection;
ScriptCollection mScripts;
public: public:
@ -56,6 +60,9 @@ namespace MWScript
std::pair<int, int> compileAll(); std::pair<int, int> compileAll();
///< Compile all scripts ///< Compile all scripts
/// \return count, success /// \return count, success
Compiler::Locals& getLocals (const std::string& name);
///< Return locals for script \a name.
}; };
}; };

View file

@ -40,6 +40,7 @@ namespace MWSound
: mFSStrict(fsstrict) : mFSStrict(fsstrict)
, mEnvironment(environment) , mEnvironment(environment)
, mCurrentPlaylist(NULL) , mCurrentPlaylist(NULL)
, mUsingSound(useSound)
{ {
if(!useSound) if(!useSound)
return; return;
@ -238,6 +239,9 @@ namespace MWSound
void SoundManager::playPlaylist(std::string playlist) void SoundManager::playPlaylist(std::string playlist)
{ {
if (!mUsingSound)
return;
if (playlist == "") if (playlist == "")
{ {
if(!isMusicPlaying()) if(!isMusicPlaying())

View file

@ -9,6 +9,7 @@ namespace MWSound
namespace MWScript namespace MWScript
{ {
class GlobalScripts; class GlobalScripts;
class ScriptManager;
} }
namespace MWGui namespace MWGui
@ -41,7 +42,7 @@ namespace MWWorld
{ {
public: public:
Environment() Environment()
: mWorld (0), mSoundManager (0), mGlobalScripts (0), mWindowManager (0), : mWorld (0), mSoundManager (0), mGlobalScripts (0), mScriptManager (0), mWindowManager (0),
mMechanicsManager (0), mDialogueManager (0), mJournal (0), mFrameDuration (0), mMechanicsManager (0), mDialogueManager (0), mJournal (0), mFrameDuration (0),
mInputManager (0) mInputManager (0)
{} {}
@ -49,6 +50,7 @@ namespace MWWorld
World *mWorld; World *mWorld;
MWSound::SoundManager *mSoundManager; MWSound::SoundManager *mSoundManager;
MWScript::GlobalScripts *mGlobalScripts; MWScript::GlobalScripts *mGlobalScripts;
MWScript::ScriptManager *mScriptManager;
MWGui::WindowManager *mWindowManager; MWGui::WindowManager *mWindowManager;
MWMechanics::MechanicsManager *mMechanicsManager; MWMechanics::MechanicsManager *mMechanicsManager;
MWDialogue::DialogueManager *mDialogueManager; MWDialogue::DialogueManager *mDialogueManager;

View file

@ -21,6 +21,18 @@ const std::string WeatherGlobals::mThunderSoundID0 = "Thunder0";
const std::string WeatherGlobals::mThunderSoundID1 = "Thunder1"; const std::string WeatherGlobals::mThunderSoundID1 = "Thunder1";
const std::string WeatherGlobals::mThunderSoundID2 = "Thunder2"; const std::string WeatherGlobals::mThunderSoundID2 = "Thunder2";
const std::string WeatherGlobals::mThunderSoundID3 = "Thunder3"; const std::string WeatherGlobals::mThunderSoundID3 = "Thunder3";
const float WeatherGlobals::mSunriseTime = 8;
const float WeatherGlobals::mSunsetTime = 18;
const float WeatherGlobals::mSunriseDuration = 2;
const float WeatherGlobals::mSunsetDuration = 2;
const float WeatherGlobals::mWeatherUpdateTime = 20.f;
// morrowind sets these per-weather, but since they are only used by 'thunderstorm'
// weather setting anyway, we can just as well set them globally
const float WeatherGlobals::mThunderFrequency = .4;
const float WeatherGlobals::mThunderThreshold = 0.6;
const float WeatherGlobals::mThunderSoundDelay = 0.25;
WeatherManager::WeatherManager(MWRender::RenderingManager* rendering, Environment* env) : WeatherManager::WeatherManager(MWRender::RenderingManager* rendering, Environment* env) :
mHour(14), mCurrentWeather("clear"), mFirstUpdate(true), mWeatherUpdateTime(0), mHour(14), mCurrentWeather("clear"), mFirstUpdate(true), mWeatherUpdateTime(0),
@ -260,6 +272,7 @@ WeatherManager::WeatherManager(MWRender::RenderingManager* rendering, Environmen
blight.mAmbientLoopSoundID = "blight"; blight.mAmbientLoopSoundID = "blight";
mWeatherSettings["blight"] = blight; mWeatherSettings["blight"] = blight;
/*
Weather snow; Weather snow;
snow.mCloudTexture = "tx_bm_sky_snow.dds"; snow.mCloudTexture = "tx_bm_sky_snow.dds";
snow.mCloudsMaximumPercent = 1.0; snow.mCloudsMaximumPercent = 1.0;
@ -316,10 +329,14 @@ WeatherManager::WeatherManager(MWRender::RenderingManager* rendering, Environmen
blizzard.mGlareView = 0; blizzard.mGlareView = 0;
blizzard.mAmbientLoopSoundID = "BM Blizzard"; blizzard.mAmbientLoopSoundID = "BM Blizzard";
mWeatherSettings["blizzard"] = blizzard; mWeatherSettings["blizzard"] = blizzard;
*/
} }
void WeatherManager::setWeather(const String& weather, bool instant) void WeatherManager::setWeather(const String& weather, bool instant)
{ {
if (weather == mCurrentWeather && mNextWeather == "")
return;
if (instant || mFirstUpdate) if (instant || mFirstUpdate)
{ {
mNextWeather = ""; mNextWeather = "";
@ -331,12 +348,12 @@ void WeatherManager::setWeather(const String& weather, bool instant)
if (mNextWeather != "") if (mNextWeather != "")
{ {
// transition more than 50% finished? // transition more than 50% finished?
if (mRemainingTransitionTime/(mWeatherSettings[mCurrentWeather].mTransitionDelta*24.f*60) <= 0.5) if (mRemainingTransitionTime/(mWeatherSettings[mCurrentWeather].mTransitionDelta*24.f*3600) <= 0.5)
mCurrentWeather = mNextWeather; mCurrentWeather = mNextWeather;
} }
mNextWeather = weather; mNextWeather = weather;
mRemainingTransitionTime = mWeatherSettings[mCurrentWeather].mTransitionDelta*24.f*60; mRemainingTransitionTime = mWeatherSettings[mCurrentWeather].mTransitionDelta*24.f*3600;
} }
} }
@ -354,15 +371,12 @@ WeatherResult WeatherManager::getResult(const String& weather)
result.mAmbientLoopSoundID = current.mAmbientLoopSoundID; result.mAmbientLoopSoundID = current.mAmbientLoopSoundID;
result.mSunColor = current.mSunDiscSunsetColor; result.mSunColor = current.mSunDiscSunsetColor;
const float fade_duration = current.mTransitionDelta * 24.f; result.mNight = (mHour < 6 || mHour > 19);
result.mNight = (mHour < 6.f+fade_duration || mHour > 20.f-fade_duration);
result.mFogDepth = result.mNight ? current.mLandFogNightDepth : current.mLandFogDayDepth; result.mFogDepth = result.mNight ? current.mLandFogNightDepth : current.mLandFogDayDepth;
// night // night
if (mHour <= (WeatherGlobals::mSunriseTime-WeatherGlobals::mSunriseDuration) if (mHour <= 5.5f || mHour >= 21)
|| mHour >= (WeatherGlobals::mSunsetTime+WeatherGlobals::mSunsetDuration))
{ {
result.mFogColor = current.mFogNightColor; result.mFogColor = current.mFogNightColor;
result.mAmbientColor = current.mAmbientNightColor; result.mAmbientColor = current.mAmbientNightColor;
@ -372,40 +386,33 @@ WeatherResult WeatherManager::getResult(const String& weather)
} }
// sunrise // sunrise
else if (mHour >= (WeatherGlobals::mSunriseTime-WeatherGlobals::mSunriseDuration) && mHour <= WeatherGlobals::mSunriseTime) else if (mHour >= 5.5f && mHour <= 9)
{ {
if (mHour <= (WeatherGlobals::mSunriseTime-WeatherGlobals::mSunriseDuration+fade_duration)) if (mHour <= 6)
{ {
// fade in // fade in
float advance = (WeatherGlobals::mSunriseTime-WeatherGlobals::mSunriseDuration+fade_duration)-mHour; float advance = 6-mHour;
float factor = (advance / fade_duration); float factor = advance / 0.5f;
result.mFogColor = lerp(current.mFogSunriseColor, current.mFogNightColor); result.mFogColor = lerp(current.mFogSunriseColor, current.mFogNightColor);
result.mAmbientColor = lerp(current.mAmbientSunriseColor, current.mAmbientNightColor); result.mAmbientColor = lerp(current.mAmbientSunriseColor, current.mAmbientNightColor);
result.mSunColor = lerp(current.mSunSunriseColor, current.mSunNightColor); result.mSunColor = lerp(current.mSunSunriseColor, current.mSunNightColor);
result.mSkyColor = lerp(current.mSkySunriseColor, current.mSkyNightColor); result.mSkyColor = lerp(current.mSkySunriseColor, current.mSkyNightColor);
result.mNightFade = factor; result.mNightFade = factor;
} }
else if (mHour >= (WeatherGlobals::mSunriseTime-fade_duration)) else //if (mHour >= 6)
{ {
// fade out // fade out
float advance = mHour-(WeatherGlobals::mSunriseTime-fade_duration); float advance = mHour-6;
float factor = advance / fade_duration; float factor = advance / 3.f;
result.mFogColor = lerp(current.mFogSunriseColor, current.mFogDayColor); result.mFogColor = lerp(current.mFogSunriseColor, current.mFogDayColor);
result.mAmbientColor = lerp(current.mAmbientSunriseColor, current.mAmbientDayColor); result.mAmbientColor = lerp(current.mAmbientSunriseColor, current.mAmbientDayColor);
result.mSunColor = lerp(current.mSunSunriseColor, current.mSunDayColor); result.mSunColor = lerp(current.mSunSunriseColor, current.mSunDayColor);
result.mSkyColor = lerp(current.mSkySunriseColor, current.mSkyDayColor); result.mSkyColor = lerp(current.mSkySunriseColor, current.mSkyDayColor);
} }
else
{
result.mFogColor = current.mFogSunriseColor;
result.mAmbientColor = current.mAmbientSunriseColor;
result.mSunColor = current.mSunSunriseColor;
result.mSkyColor = current.mSkySunriseColor;
}
} }
// day // day
else if (mHour >= (WeatherGlobals::mSunriseTime) && mHour <= (WeatherGlobals::mSunsetTime)) else if (mHour >= 9 && mHour <= 17)
{ {
result.mFogColor = current.mFogDayColor; result.mFogColor = current.mFogDayColor;
result.mAmbientColor = current.mAmbientDayColor; result.mAmbientColor = current.mAmbientDayColor;
@ -414,36 +421,29 @@ WeatherResult WeatherManager::getResult(const String& weather)
} }
// sunset // sunset
else if (mHour >= (WeatherGlobals::mSunsetTime) && mHour <= (WeatherGlobals::mSunsetTime+WeatherGlobals::mSunsetDuration)) else if (mHour >= 17 && mHour <= 21)
{ {
if (mHour <= (WeatherGlobals::mSunsetTime+fade_duration)) if (mHour <= 19)
{ {
// fade in // fade in
float advance = (WeatherGlobals::mSunsetTime+fade_duration)-mHour; float advance = 19-mHour;
float factor = (advance / fade_duration); float factor = (advance / 2);
result.mFogColor = lerp(current.mFogSunsetColor, current.mFogDayColor); result.mFogColor = lerp(current.mFogSunsetColor, current.mFogDayColor);
result.mAmbientColor = lerp(current.mAmbientSunsetColor, current.mAmbientDayColor); result.mAmbientColor = lerp(current.mAmbientSunsetColor, current.mAmbientDayColor);
result.mSunColor = lerp(current.mSunSunsetColor, current.mSunDayColor); result.mSunColor = lerp(current.mSunSunsetColor, current.mSunDayColor);
result.mSkyColor = lerp(current.mSkySunsetColor, current.mSkyDayColor); result.mSkyColor = lerp(current.mSkySunsetColor, current.mSkyDayColor);
} }
else if (mHour >= (WeatherGlobals::mSunsetTime+WeatherGlobals::mSunsetDuration-fade_duration)) else //if (mHour >= 19)
{ {
// fade out // fade out
float advance = mHour-(WeatherGlobals::mSunsetTime+WeatherGlobals::mSunsetDuration-fade_duration); float advance = mHour-19;
float factor = advance / fade_duration; float factor = advance / 2.f;
result.mFogColor = lerp(current.mFogSunsetColor, current.mFogNightColor); result.mFogColor = lerp(current.mFogSunsetColor, current.mFogNightColor);
result.mAmbientColor = lerp(current.mAmbientSunsetColor, current.mAmbientNightColor); result.mAmbientColor = lerp(current.mAmbientSunsetColor, current.mAmbientNightColor);
result.mSunColor = lerp(current.mSunSunsetColor, current.mSunNightColor); result.mSunColor = lerp(current.mSunSunsetColor, current.mSunNightColor);
result.mSkyColor = lerp(current.mSkySunsetColor, current.mSkyNightColor); result.mSkyColor = lerp(current.mSkySunsetColor, current.mSkyNightColor);
result.mNightFade = factor; result.mNightFade = factor;
} }
else
{
result.mFogColor = current.mFogSunsetColor;
result.mAmbientColor = current.mAmbientSunsetColor;
result.mSunColor = current.mSunSunsetColor;
result.mSkyColor = current.mSkySunsetColor;
}
} }
return result; return result;
@ -468,26 +468,19 @@ WeatherResult WeatherManager::transition(float factor)
result.mSunDiscColor = lerp(current.mSunDiscColor, other.mSunDiscColor); result.mSunDiscColor = lerp(current.mSunDiscColor, other.mSunDiscColor);
result.mFogDepth = lerp(current.mFogDepth, other.mFogDepth); result.mFogDepth = lerp(current.mFogDepth, other.mFogDepth);
result.mWindSpeed = lerp(current.mWindSpeed, other.mWindSpeed); result.mWindSpeed = lerp(current.mWindSpeed, other.mWindSpeed);
result.mCloudSpeed = lerp(current.mCloudSpeed, other.mCloudSpeed); //result.mCloudSpeed = lerp(current.mCloudSpeed, other.mCloudSpeed);
result.mCloudSpeed = current.mCloudSpeed;
result.mCloudOpacity = lerp(current.mCloudOpacity, other.mCloudOpacity); result.mCloudOpacity = lerp(current.mCloudOpacity, other.mCloudOpacity);
result.mGlareView = lerp(current.mGlareView, other.mGlareView); result.mGlareView = lerp(current.mGlareView, other.mGlareView);
result.mNight = current.mNight; result.mNight = current.mNight;
// sound change behaviour:
// if 'other' has a new sound, switch to it after 1/2 of the transition length
if (other.mAmbientLoopSoundID != "")
result.mAmbientLoopSoundID = factor>0.5 ? other.mAmbientLoopSoundID : current.mAmbientLoopSoundID;
// if 'current' has a sound and 'other' does not have a sound, turn off the sound immediately
else if (current.mAmbientLoopSoundID != "")
result.mAmbientLoopSoundID = "";
return result; return result;
} }
void WeatherManager::update(float duration) void WeatherManager::update(float duration)
{ {
mWeatherUpdateTime -= duration; mWeatherUpdateTime -= duration * mEnvironment->mWorld->getTimeScaleFactor();
bool exterior = (mEnvironment->mWorld->isCellExterior() || mEnvironment->mWorld->isCellQuasiExterior()); bool exterior = (mEnvironment->mWorld->isCellExterior() || mEnvironment->mWorld->isCellQuasiExterior());
@ -499,7 +492,7 @@ void WeatherManager::update(float duration)
if (mWeatherUpdateTime <= 0 || regionstr != mCurrentRegion) if (mWeatherUpdateTime <= 0 || regionstr != mCurrentRegion)
{ {
mCurrentRegion = regionstr; mCurrentRegion = regionstr;
mWeatherUpdateTime = WeatherGlobals::mWeatherUpdateTime*60.f; mWeatherUpdateTime = WeatherGlobals::mWeatherUpdateTime*3600;
std::string weather; std::string weather;
@ -518,54 +511,45 @@ void WeatherManager::update(float duration)
float thunder = region->data.thunder/255.f; float thunder = region->data.thunder/255.f;
float ash = region->data.ash/255.f; float ash = region->data.ash/255.f;
float blight = region->data.blight/255.f; float blight = region->data.blight/255.f;
float snow = region->data.a/255.f; //float snow = region->data.a/255.f;
float blizzard = region->data.b/255.f; //float blizzard = region->data.b/255.f;
// re-scale to 100 percent // re-scale to 100 percent
const float total = clear+cloudy+foggy+overcast+rain+thunder+ash+blight+snow+blizzard; const float total = clear+cloudy+foggy+overcast+rain+thunder+ash+blight;//+snow+blizzard;
srand(time(NULL)); srand(time(NULL));
float random = ((rand()%100)/100.f) * total; float random = ((rand()%100)/100.f) * total;
if (random >= snow+blight+ash+thunder+rain+overcast+foggy+cloudy+clear) //if (random > snow+blight+ash+thunder+rain+overcast+foggy+cloudy+clear)
weather = "blizzard"; // weather = "blizzard";
else if (random >= blight+ash+thunder+rain+overcast+foggy+cloudy+clear) //else if (random > blight+ash+thunder+rain+overcast+foggy+cloudy+clear)
weather = "snow"; // weather = "snow";
else if (random >= ash+thunder+rain+overcast+foggy+cloudy+clear) /*else*/ if (random > ash+thunder+rain+overcast+foggy+cloudy+clear)
weather = "blight"; weather = "blight";
else if (random >= thunder+rain+overcast+foggy+cloudy+clear) else if (random > thunder+rain+overcast+foggy+cloudy+clear)
weather = "ashstorm"; weather = "ashstorm";
else if (random >= rain+overcast+foggy+cloudy+clear) else if (random > rain+overcast+foggy+cloudy+clear)
weather = "thunderstorm"; weather = "thunderstorm";
else if (random >= overcast+foggy+cloudy+clear) else if (random > overcast+foggy+cloudy+clear)
weather = "rain"; weather = "rain";
else if (random >= foggy+cloudy+clear) else if (random > foggy+cloudy+clear)
weather = "overcast"; weather = "overcast";
else if (random >= cloudy+clear) else if (random > cloudy+clear)
weather = "foggy"; weather = "foggy";
else if (random >= clear) else if (random > clear)
weather = "cloudy"; weather = "cloudy";
else else
weather = "clear"; weather = "clear";
} }
setWeather(weather, false); setWeather(weather, false);
/*
std::cout << "roll result: " << random << std::endl;
std::cout << regionstr << " weather probabilities: " << clear << " " << cloudy << " " << foggy << " "
<< overcast << " " << rain << " " << thunder << " " << ash << " " << blight << " " << snow << " "
<< blizzard << std::endl;
std::cout << "New weather : " << weather << std::endl;
*/
} }
WeatherResult result; WeatherResult result;
if (mNextWeather != "") if (mNextWeather != "")
{ {
mRemainingTransitionTime -= duration; mRemainingTransitionTime -= duration * mEnvironment->mWorld->getTimeScaleFactor();
if (mRemainingTransitionTime < 0) if (mRemainingTransitionTime < 0)
{ {
mCurrentWeather = mNextWeather; mCurrentWeather = mNextWeather;
@ -574,30 +558,37 @@ void WeatherManager::update(float duration)
} }
if (mNextWeather != "") if (mNextWeather != "")
result = transition(1-(mRemainingTransitionTime/(mWeatherSettings[mCurrentWeather].mTransitionDelta*24.f*60))); result = transition(1-(mRemainingTransitionTime/(mWeatherSettings[mCurrentWeather].mTransitionDelta*24.f*3600)));
else else
result = getResult(mCurrentWeather); result = getResult(mCurrentWeather);
mRendering->configureFog(result.mFogDepth, result.mFogColor); mRendering->configureFog(result.mFogDepth, result.mFogColor);
// disable sun during night // disable sun during night
if (mHour >= WeatherGlobals::mSunsetTime+WeatherGlobals::mSunsetDuration if (mHour >= 20 || mHour <= 6.f)
|| mHour <= WeatherGlobals::mSunriseTime-WeatherGlobals::mSunriseDuration)
mRendering->getSkyManager()->sunDisable(); mRendering->getSkyManager()->sunDisable();
else else
{ mRendering->getSkyManager()->sunEnable();
// during day, calculate sun angle
float height = 1-std::abs(((mHour-13)/7.f)); // sun angle
int facing = mHour > 13.f ? 1 : -1; float height;
// rise at 6, set at 20
if (mHour >= 6 && mHour <= 20)
height = 1-std::abs(((mHour-13)/7.f));
else if (mHour > 20)
height = (mHour-20.f)/4.f;
else //if (mHour > 0 && mHour < 6)
height = 1-(mHour/6.f);
int facing = (mHour > 13.f) ? 1 : -1;
Vector3 final( Vector3 final(
(1-height)*facing, (1-height)*facing,
(1-height)*facing, (1-height)*facing,
height); height);
mRendering->setSunDirection(final); mRendering->setSunDirection(final);
mRendering->getSkyManager()->sunEnable();
}
// moon calculations // moon calculations
float night; float night;
if (mHour >= 14) if (mHour >= 14)
@ -765,15 +756,6 @@ void WeatherManager::update(float duration)
void WeatherManager::setHour(const float hour) void WeatherManager::setHour(const float hour)
{ {
// accelerate a bit for testing
/*
mHour += 0.005;
if (mHour >= 24.f) mHour = 0.f;
std::cout << "hour " << mHour << std::endl;
*/
mHour = hour; mHour = hour;
} }

View file

@ -95,18 +95,18 @@ namespace MWWorld
Script Color=255,20,20 Script Color=255,20,20
*/ */
static const float mSunriseTime = 8; static const float mSunriseTime;
static const float mSunsetTime = 18; static const float mSunsetTime;
static const float mSunriseDuration = 2; static const float mSunriseDuration;
static const float mSunsetDuration = 2; static const float mSunsetDuration;
static const float mWeatherUpdateTime = 20.f; static const float mWeatherUpdateTime;
// morrowind sets these per-weather, but since they are only used by 'thunderstorm' // morrowind sets these per-weather, but since they are only used by 'thunderstorm'
// weather setting anyway, we can just as well set them globally // weather setting anyway, we can just as well set them globally
static const float mThunderFrequency = .4; static const float mThunderFrequency;
static const float mThunderThreshold = 0.6; static const float mThunderThreshold;
static const float mThunderSoundDelay = 0.25; static const float mThunderSoundDelay;
static const std::string mThunderSoundID0; static const std::string mThunderSoundID0;
static const std::string mThunderSoundID1; static const std::string mThunderSoundID1;
static const std::string mThunderSoundID2; static const std::string mThunderSoundID2;

View file

@ -478,7 +478,7 @@ namespace MWWorld
float World::getTimeScaleFactor() const float World::getTimeScaleFactor() const
{ {
return mGlobalVariables->getInt ("timescale"); return mGlobalVariables->getFloat ("timescale");
} }
void World::changeToInteriorCell (const std::string& cellName, const ESM::Position& position) void World::changeToInteriorCell (const std::string& cellName, const ESM::Position& position)

53
cmake/FindCg.cmake Normal file
View file

@ -0,0 +1,53 @@
#-------------------------------------------------------------------
# This file is part of the CMake build system for OGRE
# (Object-oriented Graphics Rendering Engine)
# For the latest info, see http://www.ogre3d.org/
#
# The contents of this file are placed in the public domain. Feel
# free to make use of it in any way you like.
#-------------------------------------------------------------------
# - Try to find Cg
# Once done, this will define
#
# Cg_FOUND - system has Cg
# Cg_INCLUDE_DIRS - the Cg include directories
# Cg_LIBRARIES - link these to use Cg
include(FindPkgMacros)
findpkg_begin(Cg)
# Get path, convert backslashes as ${ENV_${var}}
getenv_path(Cg_HOME)
getenv_path(OGRE_SOURCE)
getenv_path(OGRE_HOME)
# construct search paths
set(Cg_PREFIX_PATH ${Cg_HOME} ${ENV_Cg_HOME}
${OGRE_SOURCE}/Dependencies
${ENV_OGRE_SOURCE}/Dependencies
${OGRE_HOME} ${ENV_OGRE_HOME}
/opt/nvidia-cg-toolkit)
create_search_paths(Cg)
# redo search if prefix path changed
clear_if_changed(Cg_PREFIX_PATH
Cg_LIBRARY_FWK
Cg_LIBRARY_REL
Cg_LIBRARY_DBG
Cg_INCLUDE_DIR
)
set(Cg_LIBRARY_NAMES Cg)
get_debug_names(Cg_LIBRARY_NAMES)
use_pkgconfig(Cg_PKGC Cg)
findpkg_framework(Cg)
find_path(Cg_INCLUDE_DIR NAMES cg.h HINTS ${Cg_FRAMEWORK_INCLUDES} ${Cg_INC_SEARCH_PATH} ${Cg_PKGC_INCLUDE_DIRS} PATH_SUFFIXES Cg)
find_library(Cg_LIBRARY_REL NAMES ${Cg_LIBRARY_NAMES} HINTS ${Cg_LIB_SEARCH_PATH} ${Cg_PKGC_LIBRARY_DIRS} PATH_SUFFIXES "" release relwithdebinfo minsizerel)
find_library(Cg_LIBRARY_DBG NAMES ${Cg_LIBRARY_NAMES_DBG} HINTS ${Cg_LIB_SEARCH_PATH} ${Cg_PKGC_LIBRARY_DIRS} PATH_SUFFIXES "" debug)
make_library_set(Cg_LIBRARY)
findpkg_finish(Cg)
add_parent_dir(Cg_INCLUDE_DIRS Cg_INCLUDE_DIR)

47
cmake/FindFreeImage.cmake Normal file
View file

@ -0,0 +1,47 @@
#-------------------------------------------------------------------
# This file is part of the CMake build system for OGRE
# (Object-oriented Graphics Rendering Engine)
# For the latest info, see http://www.ogre3d.org/
#
# The contents of this file are placed in the public domain. Feel
# free to make use of it in any way you like.
#-------------------------------------------------------------------
# - Try to find FreeImage
# Once done, this will define
#
# FreeImage_FOUND - system has FreeImage
# FreeImage_INCLUDE_DIRS - the FreeImage include directories
# FreeImage_LIBRARIES - link these to use FreeImage
include(FindPkgMacros)
findpkg_begin(FreeImage)
# Get path, convert backslashes as ${ENV_${var}}
getenv_path(FREEIMAGE_HOME)
# construct search paths
set(FreeImage_PREFIX_PATH ${FREEIMAGE_HOME} ${ENV_FREEIMAGE_HOME})
create_search_paths(FreeImage)
# redo search if prefix path changed
clear_if_changed(FreeImage_PREFIX_PATH
FreeImage_LIBRARY_FWK
FreeImage_LIBRARY_REL
FreeImage_LIBRARY_DBG
FreeImage_INCLUDE_DIR
)
set(FreeImage_LIBRARY_NAMES freeimage)
get_debug_names(FreeImage_LIBRARY_NAMES)
use_pkgconfig(FreeImage_PKGC freeimage)
findpkg_framework(FreeImage)
find_path(FreeImage_INCLUDE_DIR NAMES FreeImage.h HINTS ${FreeImage_INC_SEARCH_PATH} ${FreeImage_PKGC_INCLUDE_DIRS})
find_library(FreeImage_LIBRARY_REL NAMES ${FreeImage_LIBRARY_NAMES} HINTS ${FreeImage_LIB_SEARCH_PATH} ${FreeImage_PKGC_LIBRARY_DIRS} PATH_SUFFIXES "" release relwithdebinfo minsizerel)
find_library(FreeImage_LIBRARY_DBG NAMES ${FreeImage_LIBRARY_NAMES_DBG} HINTS ${FreeImage_LIB_SEARCH_PATH} ${FreeImage_PKGC_LIBRARY_DIRS} PATH_SUFFIXES "" debug)
make_library_set(FreeImage_LIBRARY)
findpkg_finish(FreeImage)

View file

@ -28,12 +28,11 @@
# Plugin_BSPSceneManager, Plugin_CgProgramManager, # Plugin_BSPSceneManager, Plugin_CgProgramManager,
# Plugin_OctreeSceneManager, Plugin_OctreeZone, # Plugin_OctreeSceneManager, Plugin_OctreeZone,
# Plugin_ParticleFX, Plugin_PCZSceneManager, # Plugin_ParticleFX, Plugin_PCZSceneManager,
# RenderSystem_GL, RenderSystem_Direct3D9, # RenderSystem_GL, RenderSystem_Direct3D9, RenderSystem_Direct3D10,
# Paging, Terrain # Paging, Terrain
# #
# For each of these components, the following variables are defined: # For each of these components, the following variables are defined:
# #
# OGRE_${COMPONENT}_FOUND - ${COMPONENT} is available # OGRE_${COMPONENT}_FOUND - ${COMPONENT} is available
# OGRE_${COMPONENT}_INCLUDE_DIRS - additional include directories for ${COMPONENT} # OGRE_${COMPONENT}_INCLUDE_DIRS - additional include directories for ${COMPONENT}
# OGRE_${COMPONENT}_LIBRARIES - link these to use ${COMPONENT} # OGRE_${COMPONENT}_LIBRARIES - link these to use ${COMPONENT}
@ -128,7 +127,7 @@ endif ()
set(OGRE_COMPONENTS Paging Terrain set(OGRE_COMPONENTS Paging Terrain
Plugin_BSPSceneManager Plugin_CgProgramManager Plugin_OctreeSceneManager Plugin_BSPSceneManager Plugin_CgProgramManager Plugin_OctreeSceneManager
Plugin_OctreeZone Plugin_PCZSceneManager Plugin_ParticleFX Plugin_OctreeZone Plugin_PCZSceneManager Plugin_ParticleFX
RenderSystem_Direct3D11 RenderSystem_Direct3D9 RenderSystem_GL RenderSystem_GLES RenderSystem_GLES2) RenderSystem_Direct3D10 RenderSystem_Direct3D9 RenderSystem_GL RenderSystem_GLES)
set(OGRE_RESET_VARS set(OGRE_RESET_VARS
OGRE_CONFIG_INCLUDE_DIR OGRE_INCLUDE_DIR OGRE_CONFIG_INCLUDE_DIR OGRE_INCLUDE_DIR
OGRE_LIBRARY_FWK OGRE_LIBRARY_REL OGRE_LIBRARY_DBG OGRE_LIBRARY_FWK OGRE_LIBRARY_REL OGRE_LIBRARY_DBG
@ -145,7 +144,7 @@ clear_if_changed(OGRE_PREFIX_WATCH ${OGRE_RESET_VARS})
# try to locate Ogre via pkg-config # try to locate Ogre via pkg-config
use_pkgconfig(OGRE_PKGC "OGRE${OGRE_LIB_SUFFIX}") use_pkgconfig(OGRE_PKGC "OGRE${OGRE_LIB_SUFFIX}")
if(NOT OGRE_BUILD_PLATFORM_APPLE_IOS) if(NOT OGRE_BUILD_PLATFORM_IPHONE AND APPLE)
# try to find framework on OSX # try to find framework on OSX
findpkg_framework(OGRE) findpkg_framework(OGRE)
else() else()
@ -236,7 +235,6 @@ if (OGRE_STATIC)
find_package(Freetype QUIET) find_package(Freetype QUIET)
find_package(OpenGL QUIET) find_package(OpenGL QUIET)
find_package(OpenGLES QUIET) find_package(OpenGLES QUIET)
find_package(OpenGLES2 QUIET)
find_package(ZLIB QUIET) find_package(ZLIB QUIET)
find_package(ZZip QUIET) find_package(ZZip QUIET)
if (UNIX AND NOT APPLE) if (UNIX AND NOT APPLE)
@ -246,26 +244,24 @@ if (OGRE_STATIC)
set(X11_FOUND FALSE) set(X11_FOUND FALSE)
endif () endif ()
endif () endif ()
if (APPLE AND NOT OGRE_BUILD_PLATFORM_APPLE_IOS) if (APPLE AND NOT OGRE_BUILD_PLATFORM_IPHONE)
find_package(Cocoa QUIET) find_package(Cocoa QUIET)
find_package(Carbon QUIET) find_package(Carbon QUIET)
find_package(CoreVideo QUIET) if (NOT Cocoa_FOUND OR NOT Carbon_FOUND)
if (NOT Cocoa_FOUND OR NOT Carbon_FOUND OR NOT CoreVideo_FOUND)
set(OGRE_DEPS_FOUND FALSE) set(OGRE_DEPS_FOUND FALSE)
endif () endif ()
endif () endif ()
if (APPLE AND OGRE_BUILD_PLATFORM_APPLE_IOS) if (APPLE AND OGRE_BUILD_PLATFORM_IPHONE)
find_package(iPhoneSDK QUIET) find_package(iPhoneSDK QUIET)
if (NOT iPhoneSDK_FOUND) if (NOT iPhoneSDK_FOUND)
set(OGRE_DEPS_FOUND FALSE) set(OGRE_DEPS_FOUND FALSE)
endif () endif ()
endif () endif ()
set(OGRE_LIBRARIES ${OGRE_LIBRARIES} ${ZZip_LIBRARIES} ${ZLIB_LIBRARIES} ${FreeImage_LIBRARIES} ${FREETYPE_LIBRARIES} ) set(OGRE_LIBRARIES ${OGRE_LIBRARIES} ${OGRE_LIBRARY_FWK} ${ZZip_LIBRARIES} ${ZLIB_LIBRARIES}
${FreeImage_LIBRARIES} ${FREETYPE_LIBRARIES}
if (APPLE AND NOT OGRE_BUILD_PLATFORM_APPLE_IOS) ${X11_LIBRARIES} ${X11_Xt_LIBRARIES} ${XAW_LIBRARY} ${X11_Xrandr_LIB}
set(OGRE_LIBRARIES ${OGRE_LIBRARIES} ${X11_LIBRARIES} ${X11_Xt_LIBRARIES} ${XAW_LIBRARY} ${X11_Xrandr_LIB} ${Carbon_LIBRARIES} ${Cocoa_LIBRARIES}) ${Cocoa_LIBRARIES} ${Carbon_LIBRARIES})
endif()
if (NOT ZLIB_FOUND OR NOT ZZip_FOUND) if (NOT ZLIB_FOUND OR NOT ZZip_FOUND)
set(OGRE_DEPS_FOUND FALSE) set(OGRE_DEPS_FOUND FALSE)
@ -409,10 +405,22 @@ macro(ogre_find_plugin PLUGIN HEADER)
set(OGRE_${PLUGIN}_LIBRARY_NAMES "${PLUGIN}${OGRE_LIB_SUFFIX}") set(OGRE_${PLUGIN}_LIBRARY_NAMES "${PLUGIN}${OGRE_LIB_SUFFIX}")
get_debug_names(OGRE_${PLUGIN}_LIBRARY_NAMES) get_debug_names(OGRE_${PLUGIN}_LIBRARY_NAMES)
set(OGRE_${PLUGIN}_LIBRARY_FWK ${OGRE_LIBRARY_FWK}) set(OGRE_${PLUGIN}_LIBRARY_FWK ${OGRE_LIBRARY_FWK})
# Search for release plugins in OGRE dir with version suffix
find_library(OGRE_${PLUGIN}_LIBRARY_REL NAMES ${OGRE_${PLUGIN}_LIBRARY_NAMES}
HINTS ${OGRE_LIBRARY_DIRS} PATH_SUFFIXES "" OGRE-${OGRE_VERSION} opt release release/opt relwithdebinfo relwithdebinfo/opt minsizerel minsizerel/opt)
if(NOT EXISTS "${OGRE_${PLUGIN}_LIBRARY_REL}")
# Search for release plugins in OGRE dir without version suffix
find_library(OGRE_${PLUGIN}_LIBRARY_REL NAMES ${OGRE_${PLUGIN}_LIBRARY_NAMES} find_library(OGRE_${PLUGIN}_LIBRARY_REL NAMES ${OGRE_${PLUGIN}_LIBRARY_NAMES}
HINTS ${OGRE_LIBRARY_DIRS} PATH_SUFFIXES "" OGRE opt release release/opt relwithdebinfo relwithdebinfo/opt minsizerel minsizerel/opt) HINTS ${OGRE_LIBRARY_DIRS} PATH_SUFFIXES "" OGRE opt release release/opt relwithdebinfo relwithdebinfo/opt minsizerel minsizerel/opt)
endif()
# Search for debug plugins in OGRE dir with version suffix
find_library(OGRE_${PLUGIN}_LIBRARY_DBG NAMES ${OGRE_${PLUGIN}_LIBRARY_NAMES_DBG}
HINTS ${OGRE_LIBRARY_DIRS} PATH_SUFFIXES "" OGRE-${OGRE_VERSION} opt debug debug/opt)
if(NOT EXISTS "${OGRE_${PLUGIN}_LIBRARY_DBG}")
# Search for debug plugins in OGRE dir without version suffix
find_library(OGRE_${PLUGIN}_LIBRARY_DBG NAMES ${OGRE_${PLUGIN}_LIBRARY_NAMES_DBG} find_library(OGRE_${PLUGIN}_LIBRARY_DBG NAMES ${OGRE_${PLUGIN}_LIBRARY_NAMES_DBG}
HINTS ${OGRE_LIBRARY_DIRS} PATH_SUFFIXES "" OGRE opt debug debug/opt) HINTS ${OGRE_LIBRARY_DIRS} PATH_SUFFIXES "" OGRE opt debug debug/opt)
endif()
make_library_set(OGRE_${PLUGIN}_LIBRARY) make_library_set(OGRE_${PLUGIN}_LIBRARY)
if (OGRE_${PLUGIN}_LIBRARY OR OGRE_${PLUGIN}_INCLUDE_DIR) if (OGRE_${PLUGIN}_LIBRARY OR OGRE_${PLUGIN}_INCLUDE_DIR)
@ -445,9 +453,13 @@ macro(ogre_find_plugin PLUGIN HEADER)
PATH_SUFFIXES "" bin bin/debug debug) PATH_SUFFIXES "" bin bin/debug debug)
elseif (UNIX) elseif (UNIX)
get_filename_component(OGRE_PLUGIN_DIR_TMP ${OGRE_${PLUGIN}_LIBRARY_REL} PATH) get_filename_component(OGRE_PLUGIN_DIR_TMP ${OGRE_${PLUGIN}_LIBRARY_REL} PATH)
set(OGRE_PLUGIN_DIR_REL ${OGRE_PLUGIN_DIR_TMP} CACHE STRING "Ogre plugin dir (release)" FORCE) # For some reason this fails
#set(OGRE_PLUGIN_DIR_REL ${OGRE_PLUGIN_DIR_TMP} CACHE STRING "Ogre plugin dir (release)")
set(OGRE_PLUGIN_DIR_REL ${OGRE_PLUGIN_DIR_TMP})
get_filename_component(OGRE_PLUGIN_DIR_TMP ${OGRE_${PLUGIN}_LIBRARY_DBG} PATH) get_filename_component(OGRE_PLUGIN_DIR_TMP ${OGRE_${PLUGIN}_LIBRARY_DBG} PATH)
set(OGRE_PLUGIN_DIR_DBG ${OGRE_PLUGIN_DIR_TMP} CACHE STRING "Ogre plugin dir (debug)" FORCE) # Same here
#set(OGRE_PLUGIN_DIR_DBG ${OGRE_PLUGIN_DIR_TMP} CACHE STRING "Ogre plugin dir (debug)")
set(OGRE_PLUGIN_DIR_DBG ${OGRE_PLUGIN_DIR_TMP})
endif () endif ()
endif () endif ()
@ -475,8 +487,8 @@ ogre_find_plugin(Plugin_OctreeSceneManager OgreOctreeSceneManager.h PlugIns/Octr
ogre_find_plugin(Plugin_ParticleFX OgreParticleFXPrerequisites.h PlugIns/ParticleFX/include) ogre_find_plugin(Plugin_ParticleFX OgreParticleFXPrerequisites.h PlugIns/ParticleFX/include)
ogre_find_plugin(RenderSystem_GL OgreGLRenderSystem.h RenderSystems/GL/include) ogre_find_plugin(RenderSystem_GL OgreGLRenderSystem.h RenderSystems/GL/include)
ogre_find_plugin(RenderSystem_GLES OgreGLESRenderSystem.h RenderSystems/GLES/include) ogre_find_plugin(RenderSystem_GLES OgreGLESRenderSystem.h RenderSystems/GLES/include)
ogre_find_plugin(RenderSystem_GLES2 OgreGLES2RenderSystem.h RenderSystems/GLES2/include)
ogre_find_plugin(RenderSystem_Direct3D9 OgreD3D9RenderSystem.h RenderSystems/Direct3D9/include) ogre_find_plugin(RenderSystem_Direct3D9 OgreD3D9RenderSystem.h RenderSystems/Direct3D9/include)
ogre_find_plugin(RenderSystem_Direct3D10 OgreD3D10RenderSystem.h RenderSystems/Direct3D10/include)
ogre_find_plugin(RenderSystem_Direct3D11 OgreD3D11RenderSystem.h RenderSystems/Direct3D11/include) ogre_find_plugin(RenderSystem_Direct3D11 OgreD3D11RenderSystem.h RenderSystems/Direct3D11/include)
if (OGRE_STATIC) if (OGRE_STATIC)
@ -484,18 +496,18 @@ if (OGRE_STATIC)
if (NOT DirectX_FOUND) if (NOT DirectX_FOUND)
set(OGRE_RenderSystem_Direct3D9_FOUND FALSE) set(OGRE_RenderSystem_Direct3D9_FOUND FALSE)
endif () endif ()
if (NOT DirectX_D3D10_FOUND)
set(OGRE_RenderSystem_Direct3D10_FOUND FALSE)
endif ()
if (NOT DirectX_D3D11_FOUND) if (NOT DirectX_D3D11_FOUND)
set(OGRE_RenderSystem_Direct3D11_FOUND FALSE) set(OGRE_RenderSystem_Direct3D11_FOUND FALSE)
endif () endif ()
if (NOT OPENGL_FOUND) if (NOT OPENGL_FOUND)
set(OGRE_RenderSystem_GL_FOUND FALSE) set(OGRE_RenderSystem_GL_FOUND FALSE)
endif () endif ()
if (NOT OPENGLES_FOUND) if (NOT OPENGLES_FOUND AND NOT OPENGLES2_FOUND)
set(OGRE_RenderSystem_GLES_FOUND FALSE) set(OGRE_RenderSystem_GLES_FOUND FALSE)
endif () endif ()
if (NOT OPENGLES2_FOUND)
set(OGRE_RenderSystem_GLES2_FOUND FALSE)
endif ()
if (NOT Cg_FOUND) if (NOT Cg_FOUND)
set(OGRE_Plugin_CgProgramManager_FOUND FALSE) set(OGRE_Plugin_CgProgramManager_FOUND FALSE)
endif () endif ()
@ -503,7 +515,9 @@ if (OGRE_STATIC)
set(OGRE_RenderSystem_Direct3D9_LIBRARIES ${OGRE_RenderSystem_Direct3D9_LIBRARIES} set(OGRE_RenderSystem_Direct3D9_LIBRARIES ${OGRE_RenderSystem_Direct3D9_LIBRARIES}
${DirectX_LIBRARIES} ${DirectX_LIBRARIES}
) )
set(OGRE_RenderSystem_Direct3D10_LIBRARIES ${OGRE_RenderSystem_Direct3D10_LIBRARIES}
${DirectX_D3D10_LIBRARIES}
)
set(OGRE_RenderSystem_Direct3D11_LIBRARIES ${OGRE_RenderSystem_Direct3D11_LIBRARIES} set(OGRE_RenderSystem_Direct3D11_LIBRARIES ${OGRE_RenderSystem_Direct3D11_LIBRARIES}
${DirectX_D3D11_LIBRARIES} ${DirectX_D3D11_LIBRARIES}
) )
@ -513,9 +527,6 @@ if (OGRE_STATIC)
set(OGRE_RenderSystem_GLES_LIBRARIES ${OGRE_RenderSystem_GLES_LIBRARIES} set(OGRE_RenderSystem_GLES_LIBRARIES ${OGRE_RenderSystem_GLES_LIBRARIES}
${OPENGLES_LIBRARIES} ${OPENGLES_LIBRARIES}
) )
set(OGRE_RenderSystem_GLES2_LIBRARIES ${OGRE_RenderSystem_GLES2_LIBRARIES}
${OPENGLES2_LIBRARIES}
)
set(OGRE_Plugin_CgProgramManager_LIBRARIES ${OGRE_Plugin_CgProgramManager_LIBRARIES} set(OGRE_Plugin_CgProgramManager_LIBRARIES ${OGRE_Plugin_CgProgramManager_LIBRARIES}
${Cg_LIBRARIES} ${Cg_LIBRARIES}
) )
@ -540,3 +551,4 @@ set(OGRE_MEDIA_SEARCH_SUFFIX
clear_if_changed(OGRE_PREFIX_WATCH OGRE_MEDIA_DIR) clear_if_changed(OGRE_PREFIX_WATCH OGRE_MEDIA_DIR)
find_path(OGRE_MEDIA_DIR NAMES packs/cubemapsJS.zip HINTS ${OGRE_MEDIA_SEARCH_PATH} find_path(OGRE_MEDIA_DIR NAMES packs/cubemapsJS.zip HINTS ${OGRE_MEDIA_SEARCH_PATH}
PATHS ${OGRE_PREFIX_PATH} PATH_SUFFIXES ${OGRE_MEDIA_SEARCH_SUFFIX}) PATHS ${OGRE_PREFIX_PATH} PATH_SUFFIXES ${OGRE_MEDIA_SEARCH_SUFFIX})

48
cmake/FindZZip.cmake Normal file
View file

@ -0,0 +1,48 @@
#-------------------------------------------------------------------
# This file is part of the CMake build system for OGRE
# (Object-oriented Graphics Rendering Engine)
# For the latest info, see http://www.ogre3d.org/
#
# The contents of this file are placed in the public domain. Feel
# free to make use of it in any way you like.
#-------------------------------------------------------------------
# - Try to find zziplib
# Once done, this will define
#
# ZZip_FOUND - system has ZZip
# ZZip_INCLUDE_DIRS - the ZZip include directories
# ZZip_LIBRARIES - link these to use ZZip
include(FindPkgMacros)
findpkg_begin(ZZip)
# Get path, convert backslashes as ${ENV_${var}}
getenv_path(ZZIP_HOME)
# construct search paths
set(ZZip_PREFIX_PATH ${ZZIP_HOME} ${ENV_ZZIP_HOME})
create_search_paths(ZZip)
# redo search if prefix path changed
clear_if_changed(ZZip_PREFIX_PATH
ZZip_LIBRARY_FWK
ZZip_LIBRARY_REL
ZZip_LIBRARY_DBG
ZZip_INCLUDE_DIR
)
set(ZZip_LIBRARY_NAMES zzip zziplib)
get_debug_names(ZZip_LIBRARY_NAMES)
use_pkgconfig(ZZip_PKGC zziplib)
findpkg_framework(ZZip)
find_path(ZZip_INCLUDE_DIR NAMES zzip/zzip.h HINTS ${ZZip_INC_SEARCH_PATH} ${ZZip_PKGC_INCLUDE_DIRS})
find_library(ZZip_LIBRARY_REL NAMES ${ZZip_LIBRARY_NAMES} HINTS ${ZZip_LIB_SEARCH_PATH} ${ZZip_PKGC_LIBRARY_DIRS} PATH_SUFFIXES "" release relwithdebinfo minsizerel)
find_library(ZZip_LIBRARY_DBG NAMES ${ZZip_LIBRARY_NAMES_DBG} HINTS ${ZZip_LIB_SEARCH_PATH} ${ZZip_PKGC_LIBRARY_DIRS} PATH_SUFFIXES "" debug)
make_library_set(ZZip_LIBRARY)
findpkg_finish(ZZip)

View file

@ -639,7 +639,7 @@ namespace Compiler
std::vector<Interpreter::Type_Code>& code, bool invert) std::vector<Interpreter::Type_Code>& code, bool invert)
{ {
bool optional = false; bool optional = false;
bool optionalCount = 0; int optionalCount = 0;
ExprParser parser (getErrorHandler(), getContext(), mLocals, mLiterals, true); ExprParser parser (getErrorHandler(), getContext(), mLocals, mLiterals, true);
StringParser stringParser (getErrorHandler(), getContext(), mLiterals); StringParser stringParser (getErrorHandler(), getContext(), mLiterals);

View file

@ -77,4 +77,3 @@ namespace Compiler
mOutput.clear(); mOutput.clear();
} }
} }

View file

@ -39,6 +39,11 @@ namespace Compiler
mState = CommaState; mState = CommaState;
return true; return true;
} }
else if (code==Scanner::S_newline && mState==StartState)
{
scanner.putbackSpecial (code, loc);
return false;
}
return Parser::parseSpecial (code, loc, scanner); return Parser::parseSpecial (code, loc, scanner);
} }

View file

@ -54,6 +54,7 @@ configure_file("${SDIR}/openmw_chargen_class_description_layout.xml" "${DDIR}/op
configure_file("${SDIR}/openmw_chargen_birth_layout.xml" "${DDIR}/openmw_chargen_birth_layout.xml" COPYONLY) configure_file("${SDIR}/openmw_chargen_birth_layout.xml" "${DDIR}/openmw_chargen_birth_layout.xml" COPYONLY)
configure_file("${SDIR}/openmw_chargen_review_layout.xml" "${DDIR}/openmw_chargen_review_layout.xml" COPYONLY) configure_file("${SDIR}/openmw_chargen_review_layout.xml" "${DDIR}/openmw_chargen_review_layout.xml" COPYONLY)
configure_file("${SDIR}/openmw_dialogue_window_layout.xml" "${DDIR}/openmw_dialogue_window_layout.xml" COPYONLY) configure_file("${SDIR}/openmw_dialogue_window_layout.xml" "${DDIR}/openmw_dialogue_window_layout.xml" COPYONLY)
configure_file("${SDIR}/openmw_dialogue_window_skin.xml" "${DDIR}/openmw_dialogue_window_skin.xml" COPYONLY)
configure_file("${SDIR}/openmw_inventory_window_layout.xml" "${DDIR}/openmw_inventory_window_layout.xml" COPYONLY) configure_file("${SDIR}/openmw_inventory_window_layout.xml" "${DDIR}/openmw_inventory_window_layout.xml" COPYONLY)
configure_file("${SDIR}/openmw_layers.xml" "${DDIR}/openmw_layers.xml" COPYONLY) configure_file("${SDIR}/openmw_layers.xml" "${DDIR}/openmw_layers.xml" COPYONLY)
configure_file("${SDIR}/openmw_mainmenu_layout.xml" "${DDIR}/openmw_mainmenu_layout.xml" COPYONLY) configure_file("${SDIR}/openmw_mainmenu_layout.xml" "${DDIR}/openmw_mainmenu_layout.xml" COPYONLY)

View file

@ -20,6 +20,7 @@
<List file="openmw_mainmenu_skin.xml" group="General"/> <List file="openmw_mainmenu_skin.xml" group="General"/>
<List file="openmw_console.skin.xml" group="General"/> <List file="openmw_console.skin.xml" group="General"/>
<List file="openmw_journal_skin.xml" group="General"/> <List file="openmw_journal_skin.xml" group="General"/>
<List file="openmw_dialogue_window_skin.xml" group="General"/>
</MyGUI> </MyGUI>
</MyGUI> </MyGUI>

View file

@ -17,8 +17,13 @@
<Property key="Edit_VisibleVScroll" value="1" /> <Property key="Edit_VisibleVScroll" value="1" />
</Widget> </Widget>
<!-- The disposition bar-->
<Widget type="Progress" skin="MW_EnergyBar_Blue" position="432 39 132 18"
align="Right Top" name="Disposition">
<Widget type="Edit" skin="MW_DispositionEdit" position_real = "0.25 0 0.5 1" name = "DispositionText"/>
</Widget>
<!-- The list of topics --> <!-- The list of topics -->
<Widget type="List" skin="MW_List" position="432 39 132 341" name="TopicsList"> <Widget type="List" skin="MW_List" position="432 62 132 318" name="TopicsList">
</Widget> </Widget>
<!-- The Goodbye button --> <!-- The Goodbye button -->

View file

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<MyGUI type="Skin">
<Skin name = "MW_DispEdit" size = "10 10">
<Property key="FontName" value = "MonoFont" />
<Property key="AlignText" value = "Left Top" />
<Property key="Colour" value = "0000FF" />
<!--Property key="Pointer" value = "beam" /-->
<BasisSkin type="EditText" offset = "0 0 10 10" align = "Stretch"/>
</Skin>
<Skin name="MW_DispositionEdit" size="0 0 50 50">
<Property key="WordWrap" value = "true" />
<Child type="Widget" skin="MW_DispEdit" offset="0 0 35 10" align = "ALIGN_STRETCH" name = "Client"/>
<!--Child type="VScroll" skin="VScroll" offset = "35 0 15 50" align = "Right VStretch" name = "VScroll"/-->
</Skin>
</MyGUI>

View file

@ -26,6 +26,31 @@ void OgreRenderer::start()
mRoot->startRendering(); mRoot->startRendering();
} }
bool OgreRenderer::loadPlugins()
{
#ifdef ENABLE_PLUGIN_GL
mGLPlugin = new Ogre::GLPlugin();
mRoot->installPlugin(mGLPlugin);
#endif
#ifdef ENABLE_PLUGIN_Direct3D9
mD3D9Plugin = new Ogre::D3D9Plugin();
mRoot->installPlugin(mD3D9Plugin);
#endif
#ifdef ENABLE_PLUGIN_CgProgramManager
mCgPlugin = new Ogre::CgPlugin();
mRoot->installPlugin(mCgPlugin);
#endif
#ifdef ENABLE_PLUGIN_OctreeSceneManager
mOctreePlugin = new Ogre::OctreePlugin();
mRoot->installPlugin(mOctreePlugin);
#endif
#ifdef ENABLE_PLUGIN_ParticleFX
mParticleFXPlugin = new Ogre::ParticleFXPlugin();
mRoot->installPlugin(mParticleFXPlugin);
#endif
return true;
}
void OgreRenderer::update(float dt) void OgreRenderer::update(float dt)
{ {
mFader->update(dt); mFader->update(dt);
@ -59,7 +84,12 @@ bool OgreRenderer::configure(bool showConfig,
// Disable logging // Disable logging
log->setDebugOutputEnabled(false); log->setDebugOutputEnabled(false);
#if defined(ENABLE_PLUGIN_GL) || defined(ENABLE_PLUGIN_Direct3D9) || defined(ENABLE_PLUGIN_CgProgramManager) || defined(ENABLE_PLUGIN_OctreeSceneManager) || defined(ENABLE_PLUGIN_ParticleFX)
mRoot = new Root("", cfgPath, "");
loadPlugins();
#else
mRoot = new Root(pluginCfg, cfgPath, ""); mRoot = new Root(pluginCfg, cfgPath, "");
#endif
// Show the configuration dialog and initialise the system, if the // Show the configuration dialog and initialise the system, if the
// showConfig parameter is specified. The settings are stored in // showConfig parameter is specified. The settings are stored in

View file

@ -7,6 +7,23 @@
#include <string> #include <string>
// Static plugin headers
#ifdef ENABLE_PLUGIN_CgProgramManager
# include "OgreCgPlugin.h"
#endif
#ifdef ENABLE_PLUGIN_OctreeSceneManager
# include "OgreOctreePlugin.h"
#endif
#ifdef ENABLE_PLUGIN_ParticleFX
# include "OgreParticleFXPlugin.h"
#endif
#ifdef ENABLE_PLUGIN_GL
# include "OgreGLPlugin.h"
#endif
#ifdef ENABLE_PLUGIN_Direct3D9
# include "OgreD3D9Plugin.h"
#endif
namespace Ogre namespace Ogre
{ {
class Root; class Root;
@ -27,6 +44,21 @@ namespace Render
Ogre::SceneManager *mScene; Ogre::SceneManager *mScene;
Ogre::Camera *mCamera; Ogre::Camera *mCamera;
Ogre::Viewport *mView; Ogre::Viewport *mView;
#ifdef ENABLE_PLUGIN_CgProgramManager
Ogre::CgPlugin* mCgPlugin;
#endif
#ifdef ENABLE_PLUGIN_OctreeSceneManager
Ogre::OctreePlugin* mOctreePlugin;
#endif
#ifdef ENABLE_PLUGIN_ParticleFX
Ogre::ParticleFXPlugin* mParticleFXPlugin;
#endif
#ifdef ENABLE_PLUGIN_GL
Ogre::GLPlugin* mGLPlugin;
#endif
#ifdef ENABLE_PLUGIN_Direct3D9
Ogre::D3D9Plugin* mD3D9Plugin;
#endif
Fader* mFader; Fader* mFader;
bool logging; bool logging;
@ -69,6 +101,8 @@ namespace Render
/// Start the main rendering loop /// Start the main rendering loop
void start(); void start();
bool loadPlugins();
void update(float dt); void update(float dt);
/// Write a screenshot to file /// Write a screenshot to file

View file

@ -3,7 +3,7 @@ OpenMW: A reimplementation of The Elder Scrolls III: Morrowind
OpenMW is an attempt at recreating the engine for the popular role-playing game OpenMW is an attempt at recreating the engine for the popular role-playing game
Morrowind by Bethesda Softworks. You need to own and install the original game for OpenMW to work. Morrowind by Bethesda Softworks. You need to own and install the original game for OpenMW to work.
Version: 0.12.0 Version: 0.13.0
License: GPL (see GPL3.txt for more information) License: GPL (see GPL3.txt for more information)
Website: http://www.openmw.org Website: http://www.openmw.org
@ -96,11 +96,15 @@ athile
Cris “Mirceam” Mihalache Cris “Mirceam” Mihalache
gugus / gus gugus / gus
Jacob “Yacoby” Essex Jacob “Yacoby” Essex
Jannik “scrawl” Heller
Jason “jhooks” Hooks Jason “jhooks” Hooks
Karl-Felix “k1ll” Glatzer
Lukasz “lgro” Gromanowski Lukasz “lgro” Gromanowski
Marc “Zini” Zinnschlag Marc “Zini” Zinnschlag
Michael “werdanith” Papageorgiou
Nikolay “corristo” Kasyanov Nikolay “corristo” Kasyanov
Pieter “pvdk” van der Kloet Pieter “pvdk” van der Kloet
Roman "Kromgart" Melnik
Sebastian “swick” Wick Sebastian “swick” Wick
Retired Developers: Retired Developers:
@ -110,7 +114,6 @@ Diggory Hardy
Jan Borsodi Jan Borsodi
Jan-Peter “peppe” Nilsson Jan-Peter “peppe” Nilsson
Josua Grawitter Josua Grawitter
Karl-Felix “k1ll” Glatzer
Nicolay Korslund Nicolay Korslund
sergoz sergoz
Star-Demon Star-Demon
@ -125,6 +128,38 @@ Thanks to Kevin Ryan for kindly providing us with the icon used for the Data Fil
CHANGELOG CHANGELOG
0.13.0
Bug #145: Fixed sound problems after cell change
Bug #179: Pressing space in console triggers activation
Bug #186: CMake doesn't use the debug versions of Ogre libraries on Linux
Bug #189: ASCII 16 character added to console on it's activation on Mac OS X
Bug #190: Case Folding fails with music files
Bug #192: Keypresses write Text into Console no matter which gui element is active
Bug #196: Collision shapes out of place
Bug #202: ESMTool doesn't not work with localised ESM files anymore
Bug #203: Torch lights only visible on short distance
Bug #207: Ogre.log not written
Bug #209: Sounds do not play
Bug #210: Ogre crash at Dren plantation
Bug #214: Unsupported file format version
Feature #9: NPC Dialogue Window
Feature #16/42: New sky/weather implementation
Feature #40: Fading
Feature #48: NPC Dialogue System
Feature #117: Equipping Items (backend only, no GUI yet, no rendering of equipped items yet)
Feature #161: Load REC_PGRD records
Feature #195: Wireframe-mode
Feature #198/199: Various sound effects
Feature #206: Allow picking data path from launcher if non is set
Task #108: Refactor window manager class
Task #172: Sound Manager Cleanup
Task #173: Create OpenEngine systems in the appropriate manager classes
Task #184: Adjust MSVC and gcc warning levels
Task #185: RefData rewrite
Task #201: Workaround for transparency issues
Task #208: silenced esm_reader.hpp warning
0.12.0 0.12.0
Bug #154: FPS Drop Bug #154: FPS Drop