mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-10-30 02:56:44 +00:00 
			
		
		
		
	Post merge
This commit is contained in:
		
						commit
						20288de685
					
				
					 175 changed files with 5612 additions and 1886 deletions
				
			
		|  | @ -1,7 +1,11 @@ | ||||||
|  | #include "graphicspage.hpp" | ||||||
|  | 
 | ||||||
| #include <QtGui> | #include <QtGui> | ||||||
| 
 | 
 | ||||||
| #include "graphicspage.hpp" | #include <boost/lexical_cast.hpp> | ||||||
|  | 
 | ||||||
| #include <components/files/configurationmanager.hpp> | #include <components/files/configurationmanager.hpp> | ||||||
|  | #include <components/settings/settings.hpp> | ||||||
| 
 | 
 | ||||||
| GraphicsPage::GraphicsPage(Files::ConfigurationManager &cfg, QWidget *parent) | GraphicsPage::GraphicsPage(Files::ConfigurationManager &cfg, QWidget *parent) | ||||||
|     : QWidget(parent) |     : QWidget(parent) | ||||||
|  | @ -17,12 +21,9 @@ GraphicsPage::GraphicsPage(Files::ConfigurationManager &cfg, QWidget *parent) | ||||||
|     renderSystemLayout->addWidget(rendererLabel, 0, 0, 1, 1); |     renderSystemLayout->addWidget(rendererLabel, 0, 0, 1, 1); | ||||||
|     renderSystemLayout->addWidget(mRendererComboBox, 0, 1, 1, 1); |     renderSystemLayout->addWidget(mRendererComboBox, 0, 1, 1, 1); | ||||||
| 
 | 
 | ||||||
|     mRendererStackedWidget = new QStackedWidget(rendererGroup); |  | ||||||
| 
 |  | ||||||
|     QVBoxLayout *rendererGroupLayout = new QVBoxLayout(rendererGroup); |     QVBoxLayout *rendererGroupLayout = new QVBoxLayout(rendererGroup); | ||||||
| 
 | 
 | ||||||
|     rendererGroupLayout->addLayout(renderSystemLayout); |     rendererGroupLayout->addLayout(renderSystemLayout); | ||||||
|     rendererGroupLayout->addWidget(mRendererStackedWidget); |  | ||||||
| 
 | 
 | ||||||
|     // Display
 |     // Display
 | ||||||
|     QGroupBox *displayGroup = new QGroupBox(tr("Display"), this); |     QGroupBox *displayGroup = new QGroupBox(tr("Display"), this); | ||||||
|  | @ -52,107 +53,33 @@ GraphicsPage::GraphicsPage(Files::ConfigurationManager &cfg, QWidget *parent) | ||||||
| 
 | 
 | ||||||
| void GraphicsPage::createPages() | void GraphicsPage::createPages() | ||||||
| { | { | ||||||
|     // OpenGL rendering settings
 |     QWidget *main = new QWidget(); | ||||||
|     QWidget *mOGLRendererPage = new QWidget(); |     QGridLayout *grid = new QGridLayout(main); | ||||||
| 
 | 
 | ||||||
|     QLabel *OGLRTTLabel = new QLabel(tr("Preferred RTT Mode:"), mOGLRendererPage); |     mVSyncCheckBox = new QCheckBox(tr("Vertical Sync"), main); | ||||||
|     mOGLRTTComboBox = new QComboBox(mOGLRendererPage); |     grid->addWidget(mVSyncCheckBox, 0, 0, 1, 1); | ||||||
| 
 | 
 | ||||||
|     QLabel *OGLAntiAliasingLabel = new QLabel(tr("Antialiasing:"), mOGLRendererPage); |     mFullScreenCheckBox = new QCheckBox(tr("Full Screen"), main); | ||||||
|     mOGLAntiAliasingComboBox = new QComboBox(mOGLRendererPage); |     grid->addWidget(mFullScreenCheckBox, 1, 0, 1, 1); | ||||||
|  | 
 | ||||||
|  |     QLabel *antiAliasingLabel = new QLabel(tr("Antialiasing:"), main); | ||||||
|  |     mAntiAliasingComboBox = new QComboBox(main); | ||||||
|  |     grid->addWidget(antiAliasingLabel, 2, 0, 1, 1); | ||||||
|  |     grid->addWidget(mAntiAliasingComboBox, 2, 1, 1, 1); | ||||||
|  | 
 | ||||||
|  |     QLabel *resolutionLabel = new QLabel(tr("Resolution:"), main); | ||||||
|  |     mResolutionComboBox = new QComboBox(main); | ||||||
|  |     grid->addWidget(resolutionLabel, 3, 0, 1, 1); | ||||||
|  |     grid->addWidget(mResolutionComboBox, 3, 1, 1, 1); | ||||||
| 
 | 
 | ||||||
|     QGridLayout *OGLRendererLayout = new QGridLayout(mOGLRendererPage); |  | ||||||
|     QSpacerItem *vSpacer1 = new QSpacerItem(20, 10, QSizePolicy::Minimum, QSizePolicy::Expanding); |     QSpacerItem *vSpacer1 = new QSpacerItem(20, 10, QSizePolicy::Minimum, QSizePolicy::Expanding); | ||||||
|  |     grid->addItem(vSpacer1, 4, 0, 1, 1); | ||||||
| 
 | 
 | ||||||
|     OGLRendererLayout->addWidget(OGLRTTLabel, 0, 0, 1, 1); |     mDisplayStackedWidget->addWidget(main); | ||||||
|     OGLRendererLayout->addWidget(mOGLRTTComboBox, 0, 1, 1, 1); |  | ||||||
|     OGLRendererLayout->addWidget(OGLAntiAliasingLabel, 1, 0, 1, 1); |  | ||||||
|     OGLRendererLayout->addWidget(mOGLAntiAliasingComboBox, 1, 1, 1, 1); |  | ||||||
|     OGLRendererLayout->addItem(vSpacer1, 2, 1, 1, 1); |  | ||||||
| 
 |  | ||||||
|     // OpenGL display settings
 |  | ||||||
|     QWidget *mOGLDisplayPage = new QWidget(); |  | ||||||
| 
 |  | ||||||
|     QLabel *OGLResolutionLabel = new QLabel(tr("Resolution:"), mOGLDisplayPage); |  | ||||||
|     mOGLResolutionComboBox = new QComboBox(mOGLDisplayPage); |  | ||||||
| 
 |  | ||||||
|     QLabel *OGLFrequencyLabel = new QLabel(tr("Display Frequency:"), mOGLDisplayPage); |  | ||||||
|     mOGLFrequencyComboBox = new QComboBox(mOGLDisplayPage); |  | ||||||
| 
 |  | ||||||
|     mOGLVSyncCheckBox = new QCheckBox(tr("Vertical Sync"), mOGLDisplayPage); |  | ||||||
|     mOGLFullScreenCheckBox = new QCheckBox(tr("Full Screen"), mOGLDisplayPage); |  | ||||||
| 
 |  | ||||||
|     QGridLayout *OGLDisplayLayout = new QGridLayout(mOGLDisplayPage); |  | ||||||
|     QSpacerItem *vSpacer2 = new QSpacerItem(20, 10, QSizePolicy::Minimum, QSizePolicy::Minimum); |  | ||||||
| 
 |  | ||||||
|     OGLDisplayLayout->addWidget(OGLResolutionLabel, 0, 0, 1, 1); |  | ||||||
|     OGLDisplayLayout->addWidget(mOGLResolutionComboBox, 0, 1, 1, 1); |  | ||||||
|     OGLDisplayLayout->addWidget(OGLFrequencyLabel, 1, 0, 1, 1); |  | ||||||
|     OGLDisplayLayout->addWidget(mOGLFrequencyComboBox, 1, 1, 1, 1); |  | ||||||
| 
 |  | ||||||
|     OGLDisplayLayout->addItem(vSpacer2, 2, 1, 1, 1); |  | ||||||
|     OGLDisplayLayout->addWidget(mOGLVSyncCheckBox, 3, 0, 1, 1); |  | ||||||
|     OGLDisplayLayout->addWidget(mOGLFullScreenCheckBox, 6, 0, 1, 1); |  | ||||||
| 
 |  | ||||||
|     // Direct3D rendering settings
 |  | ||||||
|     QWidget *mD3DRendererPage = new QWidget(); |  | ||||||
| 
 |  | ||||||
|     QLabel *D3DRenderDeviceLabel = new QLabel(tr("Rendering Device:"), mD3DRendererPage); |  | ||||||
|     mD3DRenderDeviceComboBox = new QComboBox(mD3DRendererPage); |  | ||||||
| 
 |  | ||||||
|     QLabel *D3DAntiAliasingLabel = new QLabel(tr("Antialiasing:"), mD3DRendererPage); |  | ||||||
|     mD3DAntiAliasingComboBox = new QComboBox(mD3DRendererPage); |  | ||||||
| 
 |  | ||||||
|     QLabel *D3DFloatingPointLabel = new QLabel(tr("Floating-point Mode:"), mD3DRendererPage); |  | ||||||
|     mD3DFloatingPointComboBox = new QComboBox(mD3DRendererPage); |  | ||||||
| 
 |  | ||||||
|     mD3DNvPerfCheckBox = new QCheckBox(tr("Allow NVPerfHUD"), mD3DRendererPage); |  | ||||||
| 
 |  | ||||||
|     QGridLayout *D3DRendererLayout = new QGridLayout(mD3DRendererPage); |  | ||||||
|     QSpacerItem *vSpacer3 = new QSpacerItem(20, 10, QSizePolicy::Minimum, QSizePolicy::Minimum); |  | ||||||
|     QSpacerItem *vSpacer4 = new QSpacerItem(20, 10, QSizePolicy::Minimum, QSizePolicy::Expanding); |  | ||||||
| 
 |  | ||||||
|     D3DRendererLayout->addWidget(D3DRenderDeviceLabel, 0, 0, 1, 1); |  | ||||||
|     D3DRendererLayout->addWidget(mD3DRenderDeviceComboBox, 0, 1, 1, 1); |  | ||||||
|     D3DRendererLayout->addWidget(D3DAntiAliasingLabel, 1, 0, 1, 1); |  | ||||||
|     D3DRendererLayout->addWidget(mD3DAntiAliasingComboBox, 1, 1, 1, 1); |  | ||||||
|     D3DRendererLayout->addWidget(D3DFloatingPointLabel, 2, 0, 1, 1); |  | ||||||
|     D3DRendererLayout->addWidget(mD3DFloatingPointComboBox, 2, 1, 1, 1); |  | ||||||
|     D3DRendererLayout->addItem(vSpacer3, 3, 1, 1, 1); |  | ||||||
|     D3DRendererLayout->addWidget(mD3DNvPerfCheckBox, 4, 0, 1, 1); |  | ||||||
|     D3DRendererLayout->addItem(vSpacer4, 5, 1, 1, 1); |  | ||||||
| 
 |  | ||||||
|     // Direct3D display settings
 |  | ||||||
|     QWidget *mD3DDisplayPage = new QWidget(); |  | ||||||
| 
 |  | ||||||
|     QLabel *D3DResolutionLabel = new QLabel(tr("Resolution:"), mD3DDisplayPage); |  | ||||||
|     mD3DResolutionComboBox = new QComboBox(mD3DDisplayPage); |  | ||||||
| 
 |  | ||||||
|     mD3DVSyncCheckBox = new QCheckBox(tr("Vertical Sync"), mD3DDisplayPage); |  | ||||||
|     mD3DFullScreenCheckBox = new QCheckBox(tr("Full Screen"), mD3DDisplayPage); |  | ||||||
| 
 |  | ||||||
|     QGridLayout *mD3DDisplayLayout = new QGridLayout(mD3DDisplayPage); |  | ||||||
|     QSpacerItem *vSpacer5 = new QSpacerItem(20, 10, QSizePolicy::Minimum, QSizePolicy::Minimum); |  | ||||||
| 
 |  | ||||||
|     mD3DDisplayLayout->addWidget(D3DResolutionLabel, 0, 0, 1, 1); |  | ||||||
|     mD3DDisplayLayout->addWidget(mD3DResolutionComboBox, 0, 1, 1, 1); |  | ||||||
|     mD3DDisplayLayout->addItem(vSpacer5, 1, 1, 1, 1); |  | ||||||
|     mD3DDisplayLayout->addWidget(mD3DVSyncCheckBox, 2, 0, 1, 1); |  | ||||||
|     mD3DDisplayLayout->addWidget(mD3DFullScreenCheckBox, 5, 0, 1, 1); |  | ||||||
| 
 |  | ||||||
|     // Add the created pages
 |  | ||||||
|     mRendererStackedWidget->addWidget(mOGLRendererPage); |  | ||||||
|     mRendererStackedWidget->addWidget(mD3DRendererPage); |  | ||||||
| 
 |  | ||||||
|     mDisplayStackedWidget->addWidget(mOGLDisplayPage); |  | ||||||
|     mDisplayStackedWidget->addWidget(mD3DDisplayPage); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void GraphicsPage::setupConfig() | void GraphicsPage::setupConfig() | ||||||
| { | { | ||||||
|     QString ogreCfg = mCfgMgr.getOgreConfigPath().string().c_str(); |  | ||||||
|     QFile file(ogreCfg); |  | ||||||
|     mOgreConfig = new QSettings(ogreCfg, QSettings::IniFormat); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void GraphicsPage::setupOgre() | void GraphicsPage::setupOgre() | ||||||
|  | @ -164,32 +91,12 @@ void GraphicsPage::setupOgre() | ||||||
|     Ogre::LogManager* logMgr = OGRE_NEW Ogre::LogManager; |     Ogre::LogManager* logMgr = OGRE_NEW Ogre::LogManager; | ||||||
|     logMgr->createLog((mCfgMgr.getLogPath().string() + "/launcherOgre.log"), true, false, false); |     logMgr->createLog((mCfgMgr.getLogPath().string() + "/launcherOgre.log"), true, false, false); | ||||||
| 
 | 
 | ||||||
|     QString ogreCfg = QString::fromStdString(mCfgMgr.getOgreConfigPath().string()); |  | ||||||
|     file.setFileName(ogreCfg); |  | ||||||
| 
 |  | ||||||
|     //we need to check that the path to the configuration file exists before we
 |  | ||||||
|     //try and create an instance of Ogre::Root otherwise Ogre raises an exception
 |  | ||||||
|     QDir configDir = QFileInfo(file).dir(); |  | ||||||
|     if ( !configDir.exists() && !configDir.mkpath(configDir.path()) ) |  | ||||||
|     { |  | ||||||
|         QMessageBox msgBox; |  | ||||||
|         msgBox.setWindowTitle("Error creating config file"); |  | ||||||
|         msgBox.setIcon(QMessageBox::Critical); |  | ||||||
|         msgBox.setStandardButtons(QMessageBox::Ok); |  | ||||||
|         msgBox.setText(QString(tr("<br><b>Failed to create the configuration file</b><br><br> \
 |  | ||||||
|         Make sure you have write access to<br>%1<br><br>")).arg(configDir.path())); |  | ||||||
|         msgBox.exec(); |  | ||||||
| 
 |  | ||||||
|         qApp->exit(1); |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     try |     try | ||||||
|     { |     { | ||||||
|     #if defined(ENABLE_PLUGIN_GL) || defined(ENABLE_PLUGIN_Direct3D9) |     #if defined(ENABLE_PLUGIN_GL) || defined(ENABLE_PLUGIN_Direct3D9) | ||||||
|         mOgre = new Ogre::Root("", file.fileName().toStdString(), "./launcherOgre.log"); |         mOgre = new Ogre::Root("", "", "./launcherOgre.log"); | ||||||
|     #else |     #else | ||||||
|         mOgre = new Ogre::Root(pluginCfg.toStdString(), file.fileName().toStdString(), "./launcherOgre.log"); |         mOgre = new Ogre::Root(pluginCfg.toStdString(), "", "./launcherOgre.log"); | ||||||
|     #endif |     #endif | ||||||
|     } |     } | ||||||
|     catch(Ogre::Exception &ex) |     catch(Ogre::Exception &ex) | ||||||
|  | @ -228,11 +135,19 @@ void GraphicsPage::setupOgre() | ||||||
|         mRendererComboBox->addItem((*r)->getName().c_str()); |         mRendererComboBox->addItem((*r)->getName().c_str()); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     int index = mRendererComboBox->findText(mOgreConfig->value("Render System").toString()); |     int index = mRendererComboBox->findText(QString::fromStdString(Settings::Manager::getString("render system", "Video"))); | ||||||
| 
 | 
 | ||||||
|     if ( index != -1) { |     if ( index != -1) { | ||||||
|         mRendererComboBox->setCurrentIndex(index); |         mRendererComboBox->setCurrentIndex(index); | ||||||
|     } |     } | ||||||
|  |     else | ||||||
|  |     { | ||||||
|  | #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 | ||||||
|  |         mRendererComboBox->setCurrentIndex(mRendererComboBox->findText("Direct3D9 Rendering Subsystem")); | ||||||
|  | #else | ||||||
|  |         mRendererComboBox->setCurrentIndex(mRendererComboBox->findText("OpenGL Rendering Subsystem")); | ||||||
|  | #endif | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|     // Create separate rendersystems
 |     // Create separate rendersystems
 | ||||||
|     QString openGLName = mRendererComboBox->itemText(mRendererComboBox->findText(QString("OpenGL"), Qt::MatchStartsWith)); |     QString openGLName = mRendererComboBox->itemText(mRendererComboBox->findText(QString("OpenGL"), Qt::MatchStartsWith)); | ||||||
|  | @ -255,217 +170,44 @@ void GraphicsPage::setupOgre() | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // Now fill the GUI elements
 |     // Now fill the GUI elements
 | ||||||
|     // OpenGL
 |     mAntiAliasingComboBox->clear(); | ||||||
|     if (mOpenGLRenderSystem) { |     mResolutionComboBox->clear(); | ||||||
|         mOGLRTTComboBox->addItems(getAvailableOptions(QString("RTT Preferred Mode"), mOpenGLRenderSystem)); |     mAntiAliasingComboBox->addItems(getAvailableOptions(QString("FSAA"), mSelectedRenderSystem)); | ||||||
|         mOGLAntiAliasingComboBox->addItems(getAvailableOptions(QString("FSAA"), mOpenGLRenderSystem)); |     mResolutionComboBox->addItems(getAvailableOptions(QString("Video Mode"), mSelectedRenderSystem)); | ||||||
|         mOGLResolutionComboBox->addItems(getAvailableOptions(QString("Video Mode"), mOpenGLRenderSystem)); |  | ||||||
|         mOGLFrequencyComboBox->addItems(getAvailableOptions(QString("Display Frequency"), mOpenGLRenderSystem)); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     // Direct3D
 |  | ||||||
|     if (mDirect3DRenderSystem) { |  | ||||||
|         mD3DRenderDeviceComboBox->addItems(getAvailableOptions(QString("Rendering Device"), mDirect3DRenderSystem)); |  | ||||||
|         mD3DAntiAliasingComboBox->addItems(getAvailableOptions(QString("FSAA"), mDirect3DRenderSystem)); |  | ||||||
|         mD3DFloatingPointComboBox->addItems(getAvailableOptions(QString("Floating-point mode"), mDirect3DRenderSystem)); |  | ||||||
|         mD3DResolutionComboBox->addItems(getAvailableOptions(QString("Video Mode"), mDirect3DRenderSystem)); |  | ||||||
|     } |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void GraphicsPage::readConfig() | void GraphicsPage::readConfig() | ||||||
| { | { | ||||||
|     // Read the config file settings
 |     if (Settings::Manager::getBool("vsync", "Video")) | ||||||
|     if (mOpenGLRenderSystem) { |         mVSyncCheckBox->setCheckState(Qt::Checked); | ||||||
| 
 | 
 | ||||||
|         int index = mOGLRTTComboBox->findText(getConfigValue("RTT Preferred Mode", mOpenGLRenderSystem)); |     if (Settings::Manager::getBool("fullscreen", "Video")) | ||||||
|         if ( index != -1) { |         mFullScreenCheckBox->setCheckState(Qt::Checked); | ||||||
|             mOGLRTTComboBox->setCurrentIndex(index); |  | ||||||
|         } |  | ||||||
| 
 | 
 | ||||||
|         index = mOGLAntiAliasingComboBox->findText(getConfigValue("FSAA", mOpenGLRenderSystem)); |     int aaIndex = mAntiAliasingComboBox->findText(QString::fromStdString(Settings::Manager::getString("antialiasing", "Video"))); | ||||||
|         if ( index != -1){ |     if (aaIndex != -1) | ||||||
|             mOGLAntiAliasingComboBox->setCurrentIndex(index); |         mAntiAliasingComboBox->setCurrentIndex(aaIndex); | ||||||
|         } |  | ||||||
| 
 | 
 | ||||||
|         index = mOGLResolutionComboBox->findText(getConfigValue("Video Mode", mOpenGLRenderSystem)); |     std::string resolution = boost::lexical_cast<std::string>(Settings::Manager::getInt("resolution x", "Video")) | ||||||
|         if ( index != -1) { |         + " x " + boost::lexical_cast<std::string>(Settings::Manager::getInt("resolution y", "Video")); | ||||||
|             mOGLResolutionComboBox->setCurrentIndex(index); |     int resIndex = mResolutionComboBox->findText(QString::fromStdString(resolution)); | ||||||
|         } |     if (resIndex != -1) | ||||||
| 
 |         mResolutionComboBox->setCurrentIndex(resIndex); | ||||||
|         index = mOGLFrequencyComboBox->findText(getConfigValue("Display Frequency", mOpenGLRenderSystem)); |  | ||||||
|         if ( index != -1) { |  | ||||||
|             mOGLFrequencyComboBox->setCurrentIndex(index); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         // Now we do the same for the checkboxes
 |  | ||||||
|         if (getConfigValue("VSync", mOpenGLRenderSystem) == QLatin1String("Yes")) { |  | ||||||
|             mOGLVSyncCheckBox->setCheckState(Qt::Checked); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         if (getConfigValue("Full Screen", mOpenGLRenderSystem) == QLatin1String("Yes")) { |  | ||||||
|             mOGLFullScreenCheckBox->setCheckState(Qt::Checked); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     if (mDirect3DRenderSystem) { |  | ||||||
| 
 |  | ||||||
|         int index = mD3DRenderDeviceComboBox->findText(getConfigValue("Rendering Device", mDirect3DRenderSystem)); |  | ||||||
|         if ( index != -1) { |  | ||||||
|             mD3DRenderDeviceComboBox->setCurrentIndex(index); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         index = mD3DAntiAliasingComboBox->findText(getConfigValue("FSAA", mDirect3DRenderSystem)); |  | ||||||
|         if ( index != -1) { |  | ||||||
|             mD3DAntiAliasingComboBox->setCurrentIndex(index); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         index = mD3DFloatingPointComboBox->findText(getConfigValue("Floating-point mode", mDirect3DRenderSystem)); |  | ||||||
|         if ( index != -1) { |  | ||||||
|             mD3DFloatingPointComboBox->setCurrentIndex(index); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         index = mD3DResolutionComboBox->findText(getConfigValue("Video Mode", mDirect3DRenderSystem)); |  | ||||||
|         if ( index != -1) { |  | ||||||
|             mD3DResolutionComboBox->setCurrentIndex(index); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         if (getConfigValue("Allow NVPerfHUD", mDirect3DRenderSystem) == QLatin1String("Yes")) { |  | ||||||
|                 mD3DNvPerfCheckBox->setCheckState(Qt::Checked); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         if (getConfigValue("VSync", mDirect3DRenderSystem) == QLatin1String("Yes")) { |  | ||||||
|                 mD3DVSyncCheckBox->setCheckState(Qt::Checked); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         if (getConfigValue("Full Screen", mDirect3DRenderSystem) == QLatin1String("Yes")) { |  | ||||||
|                 mD3DFullScreenCheckBox->setCheckState(Qt::Checked); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void GraphicsPage::writeConfig() | void GraphicsPage::writeConfig() | ||||||
| { | { | ||||||
|     mOgre->setRenderSystem(mSelectedRenderSystem); |     Settings::Manager::setBool("vsync", "Video", mVSyncCheckBox->checkState()); | ||||||
|  |     Settings::Manager::setBool("fullscreen", "Video", mFullScreenCheckBox->checkState()); | ||||||
|  |     Settings::Manager::setString("antialiasing", "Video", mAntiAliasingComboBox->currentText().toStdString()); | ||||||
| 
 | 
 | ||||||
|     if (mDirect3DRenderSystem) { |     std::string resolution = mResolutionComboBox->currentText().toStdString(); | ||||||
|         // Nvidia Performance HUD
 |     // parse resolution x and y from a string like "800 x 600"
 | ||||||
|         if (mD3DNvPerfCheckBox->checkState() == Qt::Checked) { |     size_t xPos = resolution.find("x"); | ||||||
|             mDirect3DRenderSystem->setConfigOption("Allow NVPerfHUD", "Yes"); |     int resX = boost::lexical_cast<int>(resolution.substr(0, xPos-1)); | ||||||
|         } else { |     int resY = boost::lexical_cast<int>(resolution.substr(xPos+2, resolution.size()-(xPos+2))); | ||||||
|             mDirect3DRenderSystem->setConfigOption("Allow NVPerfHUD", "No"); |     Settings::Manager::setInt("resolution x", "Video", resX); | ||||||
|         } |     Settings::Manager::setInt("resolution y", "Video", resY); | ||||||
| 
 |  | ||||||
|         // Antialiasing
 |  | ||||||
|         mDirect3DRenderSystem->setConfigOption("FSAA", mD3DAntiAliasingComboBox->currentText().toStdString()); |  | ||||||
| 
 |  | ||||||
|         // Full screen
 |  | ||||||
|         if (mD3DFullScreenCheckBox->checkState() == Qt::Checked) { |  | ||||||
|             mDirect3DRenderSystem->setConfigOption("Full Screen", "Yes"); |  | ||||||
|         } else { |  | ||||||
|             mDirect3DRenderSystem->setConfigOption("Full Screen", "No"); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         // Rendering device
 |  | ||||||
|         mDirect3DRenderSystem->setConfigOption("Rendering Device", mD3DRenderDeviceComboBox->currentText().toStdString()); |  | ||||||
| 
 |  | ||||||
|         // VSync
 |  | ||||||
|         if (mD3DVSyncCheckBox->checkState() == Qt::Checked) { |  | ||||||
|             mDirect3DRenderSystem->setConfigOption("VSync", "Yes"); |  | ||||||
|         } else { |  | ||||||
|             mDirect3DRenderSystem->setConfigOption("VSync", "No"); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         // Resolution
 |  | ||||||
|         mDirect3DRenderSystem->setConfigOption("Video Mode", mD3DResolutionComboBox->currentText().toStdString()); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     if (mOpenGLRenderSystem) { |  | ||||||
|         // Display Frequency
 |  | ||||||
|         mOpenGLRenderSystem->setConfigOption("Display Frequency", mOGLFrequencyComboBox->currentText().toStdString()); |  | ||||||
| 
 |  | ||||||
|         // Antialiasing
 |  | ||||||
|         mOpenGLRenderSystem->setConfigOption("FSAA", mOGLAntiAliasingComboBox->currentText().toStdString()); |  | ||||||
| 
 |  | ||||||
|         // Full screen
 |  | ||||||
|         if (mOGLFullScreenCheckBox->checkState() == Qt::Checked) { |  | ||||||
|             mOpenGLRenderSystem->setConfigOption("Full Screen", "Yes"); |  | ||||||
|         } else { |  | ||||||
|             mOpenGLRenderSystem->setConfigOption("Full Screen", "No"); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         // RTT mode
 |  | ||||||
|         mOpenGLRenderSystem->setConfigOption("RTT Preferred Mode", mOGLRTTComboBox->currentText().toStdString()); |  | ||||||
| 
 |  | ||||||
|         // VSync
 |  | ||||||
|         if (mOGLVSyncCheckBox->checkState() == Qt::Checked) { |  | ||||||
|             mOpenGLRenderSystem->setConfigOption("VSync", "Yes"); |  | ||||||
|         } else { |  | ||||||
|             mOpenGLRenderSystem->setConfigOption("VSync", "No"); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         // Resolution
 |  | ||||||
|         mOpenGLRenderSystem->setConfigOption("Video Mode", mOGLResolutionComboBox->currentText().toStdString()); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     // Now we validate the options
 |  | ||||||
|     QString ogreError = QString::fromStdString(mSelectedRenderSystem->validateConfigOptions()); |  | ||||||
| 
 |  | ||||||
|     if (!ogreError.isEmpty()) { |  | ||||||
|         QMessageBox msgBox; |  | ||||||
|         msgBox.setWindowTitle("Error validating Ogre configuration"); |  | ||||||
|         msgBox.setIcon(QMessageBox::Critical); |  | ||||||
|         msgBox.setStandardButtons(QMessageBox::Ok); |  | ||||||
|         msgBox.setText(tr("<br><b>A problem occured while validating the graphics options</b><br><br> \
 |  | ||||||
|         The graphics options could not be saved.<br><br> \ |  | ||||||
|         Press \"Show Details...\" for more information.<br>")); |  | ||||||
|         msgBox.setDetailedText(ogreError); |  | ||||||
|         msgBox.exec(); |  | ||||||
| 
 |  | ||||||
|         Ogre::LogManager::getSingletonPtr()->logMessage( "Caught exception in validateConfigOptions"); |  | ||||||
| 
 |  | ||||||
|         qCritical("Error validating configuration"); |  | ||||||
| 
 |  | ||||||
|         qApp->exit(1); |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     // Write the settings to the config file
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|     try |  | ||||||
|     { |  | ||||||
|         mOgre->saveConfig(); |  | ||||||
|     } |  | ||||||
|     catch(Ogre::Exception &ex) |  | ||||||
|     { |  | ||||||
|         QString ogreError = QString::fromStdString(ex.getFullDescription().c_str()); |  | ||||||
|         QMessageBox msgBox; |  | ||||||
|         msgBox.setWindowTitle("Error writing Ogre configuration file"); |  | ||||||
|         msgBox.setIcon(QMessageBox::Critical); |  | ||||||
|         msgBox.setStandardButtons(QMessageBox::Ok); |  | ||||||
|         msgBox.setText(tr("<br><b>Could not write the graphics configuration</b><br><br> \
 |  | ||||||
|         Please make sure you have the right permissions and try again.<br><br> \ |  | ||||||
|         Press \"Show Details...\" for more information.<br>")); |  | ||||||
|         msgBox.setDetailedText(ogreError); |  | ||||||
|         msgBox.exec(); |  | ||||||
| 
 |  | ||||||
|         qCritical("Error saving Ogre configuration, the error reported was:\n %s", qPrintable(ogreError)); |  | ||||||
| 
 |  | ||||||
|         qApp->exit(1); |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| QString GraphicsPage::getConfigValue(const QString &key, Ogre::RenderSystem *renderer) |  | ||||||
| { |  | ||||||
|     QString result; |  | ||||||
| 
 |  | ||||||
|     mOgreConfig->beginGroup(renderer->getName().c_str()); |  | ||||||
|     result = mOgreConfig->value(key).toString(); |  | ||||||
|     mOgreConfig->endGroup(); |  | ||||||
| 
 |  | ||||||
|     return result; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| QStringList GraphicsPage::getAvailableOptions(const QString &key, Ogre::RenderSystem *renderer) | QStringList GraphicsPage::getAvailableOptions(const QString &key, Ogre::RenderSystem *renderer) | ||||||
|  | @ -480,12 +222,17 @@ QStringList GraphicsPage::getAvailableOptions(const QString &key, Ogre::RenderSy | ||||||
|         Ogre::StringVector::iterator opt_it; |         Ogre::StringVector::iterator opt_it; | ||||||
|         uint idx = 0; |         uint idx = 0; | ||||||
|         for (opt_it = i->second.possibleValues.begin (); |         for (opt_it = i->second.possibleValues.begin (); | ||||||
|              opt_it != i->second.possibleValues.end (); opt_it++, idx++) |         opt_it != i->second.possibleValues.end (); opt_it++, idx++) | ||||||
|              { |         { | ||||||
| 
 | 
 | ||||||
|                  if (strcmp (key.toStdString().c_str(), i->first.c_str()) == 0) |             if (strcmp (key.toStdString().c_str(), i->first.c_str()) == 0) | ||||||
|                      result << QString::fromStdString((*opt_it).c_str()).simplified(); |             { | ||||||
|              } |                 if (key == "FSAA" && *opt_it == "0") | ||||||
|  |                     result << QString("none"); | ||||||
|  |                 else | ||||||
|  |                     result << ((key == "FSAA") ? QString("MSAA ") : QString("")) + QString::fromStdString((*opt_it).c_str()).simplified(); | ||||||
|  |             } | ||||||
|  |         } | ||||||
| 
 | 
 | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -494,15 +241,11 @@ QStringList GraphicsPage::getAvailableOptions(const QString &key, Ogre::RenderSy | ||||||
| 
 | 
 | ||||||
| void GraphicsPage::rendererChanged(const QString &renderer) | void GraphicsPage::rendererChanged(const QString &renderer) | ||||||
| { | { | ||||||
|     if (renderer.contains("Direct3D")) { |  | ||||||
|         mRendererStackedWidget->setCurrentIndex(1); |  | ||||||
|         mDisplayStackedWidget->setCurrentIndex(1); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     if (renderer.contains("OpenGL")) { |  | ||||||
|         mRendererStackedWidget->setCurrentIndex(0); |  | ||||||
|         mDisplayStackedWidget->setCurrentIndex(0); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     mSelectedRenderSystem = mOgre->getRenderSystemByName(renderer.toStdString()); |     mSelectedRenderSystem = mOgre->getRenderSystemByName(renderer.toStdString()); | ||||||
|  | 
 | ||||||
|  |     mAntiAliasingComboBox->clear(); | ||||||
|  |     mResolutionComboBox->clear(); | ||||||
|  | 
 | ||||||
|  |     mAntiAliasingComboBox->addItems(getAvailableOptions(QString("FSAA"), mSelectedRenderSystem)); | ||||||
|  |     mResolutionComboBox->addItems(getAvailableOptions(QString("Video Mode"), mSelectedRenderSystem)); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -49,33 +49,15 @@ private: | ||||||
| 
 | 
 | ||||||
|     QComboBox *mRendererComboBox; |     QComboBox *mRendererComboBox; | ||||||
| 
 | 
 | ||||||
|     QStackedWidget *mRendererStackedWidget; |  | ||||||
|     QStackedWidget *mDisplayStackedWidget; |     QStackedWidget *mDisplayStackedWidget; | ||||||
| 
 | 
 | ||||||
|     // OpenGL
 |     QComboBox *mAntiAliasingComboBox; | ||||||
|     QComboBox *mOGLRTTComboBox; |     QComboBox *mResolutionComboBox; | ||||||
|     QComboBox *mOGLAntiAliasingComboBox; |     QCheckBox *mVSyncCheckBox; | ||||||
|     QComboBox *mOGLResolutionComboBox; |     QCheckBox *mFullScreenCheckBox; | ||||||
|     QComboBox *mOGLFrequencyComboBox; |  | ||||||
| 
 |  | ||||||
|     QCheckBox *mOGLVSyncCheckBox; |  | ||||||
|     QCheckBox *mOGLFullScreenCheckBox; |  | ||||||
| 
 |  | ||||||
|     // Direct3D
 |  | ||||||
|     QComboBox *mD3DRenderDeviceComboBox; |  | ||||||
|     QComboBox *mD3DAntiAliasingComboBox; |  | ||||||
|     QComboBox *mD3DFloatingPointComboBox; |  | ||||||
|     QComboBox *mD3DResolutionComboBox; |  | ||||||
| 
 |  | ||||||
|     QCheckBox *mD3DNvPerfCheckBox; |  | ||||||
|     QCheckBox *mD3DVSyncCheckBox; |  | ||||||
|     QCheckBox *mD3DFullScreenCheckBox; |  | ||||||
| 
 |  | ||||||
|     QSettings *mOgreConfig; |  | ||||||
| 
 | 
 | ||||||
|     Files::ConfigurationManager &mCfgMgr; |     Files::ConfigurationManager &mCfgMgr; | ||||||
| 
 | 
 | ||||||
|     QString getConfigValue(const QString &key, Ogre::RenderSystem *renderer); |  | ||||||
|     QStringList getAvailableOptions(const QString &key, Ogre::RenderSystem *renderer); |     QStringList getAvailableOptions(const QString &key, Ogre::RenderSystem *renderer); | ||||||
| 
 | 
 | ||||||
|     void createPages(); |     void createPages(); | ||||||
|  |  | ||||||
|  | @ -7,6 +7,28 @@ | ||||||
| 
 | 
 | ||||||
| MainDialog::MainDialog() | MainDialog::MainDialog() | ||||||
| { | { | ||||||
|  |     // Create the settings manager and load default settings file
 | ||||||
|  |     const std::string localdefault = mCfgMgr.getLocalPath().string() + "/settings-default.cfg"; | ||||||
|  |     const std::string globaldefault = mCfgMgr.getGlobalPath().string() + "/settings-default.cfg"; | ||||||
|  | 
 | ||||||
|  |     // prefer local
 | ||||||
|  |     if (boost::filesystem::exists(localdefault)) | ||||||
|  |         mSettings.loadDefault(localdefault); | ||||||
|  |     else if (boost::filesystem::exists(globaldefault)) | ||||||
|  |         mSettings.loadDefault(globaldefault); | ||||||
|  |     else | ||||||
|  |         throw std::runtime_error ("No default settings file found! Make sure the file \"settings-default.cfg\" was properly installed."); | ||||||
|  | 
 | ||||||
|  |     // load user settings if they exist, otherwise just load the default settings as user settings
 | ||||||
|  |     const std::string settingspath = mCfgMgr.getUserPath().string() + "/settings.cfg"; | ||||||
|  |     if (boost::filesystem::exists(settingspath)) | ||||||
|  |         mSettings.loadUser(settingspath); | ||||||
|  |     else if (boost::filesystem::exists(localdefault)) | ||||||
|  |         mSettings.loadUser(localdefault); | ||||||
|  |     else if (boost::filesystem::exists(globaldefault)) | ||||||
|  |         mSettings.loadUser(globaldefault); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|     mIconWidget = new QListWidget; |     mIconWidget = new QListWidget; | ||||||
|     mIconWidget->setObjectName("IconWidget"); |     mIconWidget->setObjectName("IconWidget"); | ||||||
|     mIconWidget->setViewMode(QListView::IconMode); |     mIconWidget->setViewMode(QListView::IconMode); | ||||||
|  | @ -178,6 +200,11 @@ void MainDialog::closeEvent(QCloseEvent *event) | ||||||
|     // Now write all config files
 |     // Now write all config files
 | ||||||
|     mDataFilesPage->writeConfig(); |     mDataFilesPage->writeConfig(); | ||||||
|     mGraphicsPage->writeConfig(); |     mGraphicsPage->writeConfig(); | ||||||
|  | 
 | ||||||
|  |     // Save user settings
 | ||||||
|  |     const std::string settingspath = mCfgMgr.getUserPath().string() + "/settings.cfg"; | ||||||
|  |     mSettings.saveUser(settingspath); | ||||||
|  | 
 | ||||||
|     event->accept(); |     event->accept(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -4,6 +4,7 @@ | ||||||
| #include <QDialog> | #include <QDialog> | ||||||
| 
 | 
 | ||||||
| #include <components/files/configurationmanager.hpp> | #include <components/files/configurationmanager.hpp> | ||||||
|  | #include <components/settings/settings.hpp> | ||||||
| 
 | 
 | ||||||
| class QListWidget; | class QListWidget; | ||||||
| class QListWidgetItem; | class QListWidgetItem; | ||||||
|  | @ -41,6 +42,7 @@ private: | ||||||
|     DataFilesPage *mDataFilesPage; |     DataFilesPage *mDataFilesPage; | ||||||
| 
 | 
 | ||||||
|     Files::ConfigurationManager mCfgMgr; |     Files::ConfigurationManager mCfgMgr; | ||||||
|  |     Settings::Manager mSettings; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  | @ -8,7 +8,9 @@ | ||||||
| #include <algorithm> | #include <algorithm> | ||||||
| #include <sstream> | #include <sstream> | ||||||
| 
 | 
 | ||||||
| MwIniImporter::MwIniImporter() { | MwIniImporter::MwIniImporter() | ||||||
|  |     : mVerbose(false) | ||||||
|  | { | ||||||
|     const char *map[][2] = |     const char *map[][2] = | ||||||
|     { |     { | ||||||
|         { "fps", "General:Show FPS" }, |         { "fps", "General:Show FPS" }, | ||||||
|  | @ -124,9 +126,9 @@ MwIniImporter::multistrmap MwIniImporter::loadCfgFile(std::string filename) { | ||||||
| void MwIniImporter::merge(multistrmap &cfg, multistrmap &ini) { | void MwIniImporter::merge(multistrmap &cfg, multistrmap &ini) { | ||||||
|     multistrmap::iterator cfgIt; |     multistrmap::iterator cfgIt; | ||||||
|     multistrmap::iterator iniIt; |     multistrmap::iterator iniIt; | ||||||
|     for(strmap::iterator it=mMergeMap.begin(); it!=mMergeMap.end(); it++) { |     for(strmap::iterator it=mMergeMap.begin(); it!=mMergeMap.end(); ++it) { | ||||||
|         if((iniIt = ini.find(it->second)) != ini.end()) { |         if((iniIt = ini.find(it->second)) != ini.end()) { | ||||||
|             for(std::vector<std::string>::iterator vc = iniIt->second.begin(); vc != iniIt->second.end(); vc++) { |             for(std::vector<std::string>::iterator vc = iniIt->second.begin(); vc != iniIt->second.end(); ++vc) { | ||||||
|                 cfg.erase(it->first); |                 cfg.erase(it->first); | ||||||
|                 insertMultistrmap(cfg, it->first, *vc); |                 insertMultistrmap(cfg, it->first, *vc); | ||||||
|             } |             } | ||||||
|  | @ -139,9 +141,9 @@ void MwIniImporter::mergeFallback(multistrmap &cfg, multistrmap &ini) { | ||||||
| 
 | 
 | ||||||
|     multistrmap::iterator cfgIt; |     multistrmap::iterator cfgIt; | ||||||
|     multistrmap::iterator iniIt; |     multistrmap::iterator iniIt; | ||||||
|     for(std::vector<std::string>::iterator it=mMergeFallback.begin(); it!=mMergeFallback.end(); it++) { |     for(std::vector<std::string>::iterator it=mMergeFallback.begin(); it!=mMergeFallback.end(); ++it) { | ||||||
|         if((iniIt = ini.find(*it)) != ini.end()) { |         if((iniIt = ini.find(*it)) != ini.end()) { | ||||||
|             for(std::vector<std::string>::iterator vc = iniIt->second.begin(); vc != iniIt->second.end(); vc++) { |             for(std::vector<std::string>::iterator vc = iniIt->second.begin(); vc != iniIt->second.end(); ++vc) { | ||||||
|                 std::string value(*it); |                 std::string value(*it); | ||||||
|                 std::replace( value.begin(), value.end(), ' ', '_' ); |                 std::replace( value.begin(), value.end(), ' ', '_' ); | ||||||
|                 std::replace( value.begin(), value.end(), ':', '_' ); |                 std::replace( value.begin(), value.end(), ':', '_' ); | ||||||
|  | @ -176,7 +178,7 @@ void MwIniImporter::importGameFiles(multistrmap &cfg, multistrmap &ini) { | ||||||
|             break; |             break; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         for(std::vector<std::string>::iterator entry = it->second.begin(); entry!=it->second.end(); entry++) { |         for(std::vector<std::string>::iterator entry = it->second.begin(); entry!=it->second.end(); ++entry) { | ||||||
|             std::string filetype(entry->substr(entry->length()-4, 3)); |             std::string filetype(entry->substr(entry->length()-4, 3)); | ||||||
|             std::transform(filetype.begin(), filetype.end(), filetype.begin(), ::tolower); |             std::transform(filetype.begin(), filetype.end(), filetype.begin(), ::tolower); | ||||||
| 
 | 
 | ||||||
|  | @ -194,22 +196,22 @@ void MwIniImporter::importGameFiles(multistrmap &cfg, multistrmap &ini) { | ||||||
|     cfg.erase("master"); |     cfg.erase("master"); | ||||||
|     cfg.insert( std::make_pair<std::string, std::vector<std::string> > ("master", std::vector<std::string>() ) ); |     cfg.insert( std::make_pair<std::string, std::vector<std::string> > ("master", std::vector<std::string>() ) ); | ||||||
| 
 | 
 | ||||||
|     for(std::vector<std::string>::iterator it=esmFiles.begin(); it!=esmFiles.end(); it++) { |     for(std::vector<std::string>::iterator it=esmFiles.begin(); it!=esmFiles.end(); ++it) { | ||||||
|         cfg["master"].push_back(*it); |         cfg["master"].push_back(*it); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     cfg.erase("plugin"); |     cfg.erase("plugin"); | ||||||
|     cfg.insert( std::make_pair<std::string, std::vector<std::string> > ("plugin", std::vector<std::string>() ) ); |     cfg.insert( std::make_pair<std::string, std::vector<std::string> > ("plugin", std::vector<std::string>() ) ); | ||||||
| 
 | 
 | ||||||
|     for(std::vector<std::string>::iterator it=espFiles.begin(); it!=espFiles.end(); it++) { |     for(std::vector<std::string>::iterator it=espFiles.begin(); it!=espFiles.end(); ++it) { | ||||||
|         cfg["plugin"].push_back(*it); |         cfg["plugin"].push_back(*it); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void MwIniImporter::writeToFile(boost::iostreams::stream<boost::iostreams::file_sink> &out, multistrmap &cfg) { | void MwIniImporter::writeToFile(boost::iostreams::stream<boost::iostreams::file_sink> &out, multistrmap &cfg) { | ||||||
| 
 | 
 | ||||||
|     for(multistrmap::iterator it=cfg.begin(); it != cfg.end(); it++) { |     for(multistrmap::iterator it=cfg.begin(); it != cfg.end(); ++it) { | ||||||
|         for(std::vector<std::string>::iterator entry=it->second.begin(); entry != it->second.end(); entry++) { |         for(std::vector<std::string>::iterator entry=it->second.begin(); entry != it->second.end(); ++entry) { | ||||||
|             out << (it->first) << "=" << (*entry) << std::endl; |             out << (it->first) << "=" << (*entry) << std::endl; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | @ -27,7 +27,8 @@ add_openmw_dir (mwgui | ||||||
|     text_input widgets race class birth review window_manager console dialogue |     text_input widgets race class birth review window_manager console dialogue | ||||||
|     dialogue_history window_base stats_window messagebox journalwindow charactercreation |     dialogue_history window_base stats_window messagebox journalwindow charactercreation | ||||||
|     map_window window_pinnable_base cursorreplace tooltips scrollwindow bookwindow list |     map_window window_pinnable_base cursorreplace tooltips scrollwindow bookwindow list | ||||||
|     formatting itemwidget inventorywindow container hud countdialog tradewindow |     formatting inventorywindow container hud countdialog tradewindow settingswindow | ||||||
|  |     confirmationdialog alchemywindow referenceinterface spellwindow | ||||||
|     ) |     ) | ||||||
| 
 | 
 | ||||||
| add_openmw_dir (mwdialogue | add_openmw_dir (mwdialogue | ||||||
|  | @ -49,7 +50,7 @@ add_openmw_dir (mwworld | ||||||
|     refdata world physicssystem scene globals class action nullaction actionteleport |     refdata world physicssystem scene globals class action nullaction actionteleport | ||||||
|     containerstore actiontalk actiontake manualref player cellfunctors |     containerstore actiontalk actiontake manualref player cellfunctors | ||||||
|     cells localscripts customdata weather inventorystore ptr actionopen actionread |     cells localscripts customdata weather inventorystore ptr actionopen actionread | ||||||
|     actionequip timestamp |     actionequip timestamp actionalchemy | ||||||
|     ) |     ) | ||||||
| 
 | 
 | ||||||
| add_openmw_dir (mwclass | add_openmw_dir (mwclass | ||||||
|  |  | ||||||
|  | @ -105,7 +105,7 @@ bool OMW::Engine::frameRenderingQueued (const Ogre::FrameEvent& evt) | ||||||
|                                // frame.
 |                                // frame.
 | ||||||
| 
 | 
 | ||||||
|         // passing of time
 |         // passing of time
 | ||||||
|         if (MWBase::Environment::get().getWindowManager()->getMode()==MWGui::GM_Game) |         if (!MWBase::Environment::get().getWindowManager()->isGuiMode()) | ||||||
|             MWBase::Environment::get().getWorld()->advanceTime ( |             MWBase::Environment::get().getWorld()->advanceTime ( | ||||||
|                 mEnvironment.getFrameDuration()*MWBase::Environment::get().getWorld()->getTimeScaleFactor()/3600); |                 mEnvironment.getFrameDuration()*MWBase::Environment::get().getWorld()->getTimeScaleFactor()/3600); | ||||||
| 
 | 
 | ||||||
|  | @ -116,9 +116,9 @@ bool OMW::Engine::frameRenderingQueued (const Ogre::FrameEvent& evt) | ||||||
|         // update actors
 |         // update actors
 | ||||||
|         std::vector<std::pair<std::string, Ogre::Vector3> > movement; |         std::vector<std::pair<std::string, Ogre::Vector3> > movement; | ||||||
|         MWBase::Environment::get().getMechanicsManager()->update (movement, mEnvironment.getFrameDuration(), |         MWBase::Environment::get().getMechanicsManager()->update (movement, mEnvironment.getFrameDuration(), | ||||||
|             MWBase::Environment::get().getWindowManager()->getMode()!=MWGui::GM_Game); |             MWBase::Environment::get().getWindowManager()->isGuiMode()); | ||||||
| 
 | 
 | ||||||
|         if (MWBase::Environment::get().getWindowManager()->getMode()==MWGui::GM_Game) |         if (!MWBase::Environment::get().getWindowManager()->isGuiMode()) | ||||||
|             MWBase::Environment::get().getWorld()->doPhysics (movement, mEnvironment.getFrameDuration()); |             MWBase::Environment::get().getWorld()->doPhysics (movement, mEnvironment.getFrameDuration()); | ||||||
| 
 | 
 | ||||||
|         // update world
 |         // update world
 | ||||||
|  | @ -268,15 +268,6 @@ void OMW::Engine::go() | ||||||
| 
 | 
 | ||||||
|     mOgre = new OEngine::Render::OgreRenderer; |     mOgre = new OEngine::Render::OgreRenderer; | ||||||
| 
 | 
 | ||||||
|     //we need to ensure the path to the configuration exists before creating an
 |  | ||||||
|     //instance of ogre root so that Ogre doesn't raise an exception when trying to
 |  | ||||||
|     //access it
 |  | ||||||
|     const boost::filesystem::path configPath = mCfgMgr.getOgreConfigPath().parent_path(); |  | ||||||
|     if ( !boost::filesystem::exists(configPath) ) |  | ||||||
|     { |  | ||||||
|         boost::filesystem::create_directories(configPath); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     // Create the settings manager and load default settings file
 |     // Create the settings manager and load default settings file
 | ||||||
|     Settings::Manager settings; |     Settings::Manager settings; | ||||||
|     const std::string localdefault = mCfgMgr.getLocalPath().string() + "/settings-default.cfg"; |     const std::string localdefault = mCfgMgr.getLocalPath().string() + "/settings-default.cfg"; | ||||||
|  | @ -308,10 +299,20 @@ void OMW::Engine::go() | ||||||
|     else if (boost::filesystem::exists(mCfgMgr.getGlobalPath().string() + "/transparency-overrides.cfg")) |     else if (boost::filesystem::exists(mCfgMgr.getGlobalPath().string() + "/transparency-overrides.cfg")) | ||||||
|         nifOverrides.loadTransparencyOverrides(mCfgMgr.getGlobalPath().string() + "/transparency-overrides.cfg"); |         nifOverrides.loadTransparencyOverrides(mCfgMgr.getGlobalPath().string() + "/transparency-overrides.cfg"); | ||||||
| 
 | 
 | ||||||
|     mOgre->configure(!boost::filesystem::is_regular_file(mCfgMgr.getOgreConfigPath()), |     std::string renderSystem = settings.getString("render system", "Video"); | ||||||
|         mCfgMgr.getOgreConfigPath().string(), |     if (renderSystem == "") | ||||||
|  |     { | ||||||
|  | #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 | ||||||
|  |         renderSystem = "Direct3D9 Rendering Subsystem"; | ||||||
|  | #else | ||||||
|  |         renderSystem = "OpenGL Rendering Subsystem"; | ||||||
|  | #endif | ||||||
|  |     } | ||||||
|  |     mOgre->configure( | ||||||
|         mCfgMgr.getLogPath().string(), |         mCfgMgr.getLogPath().string(), | ||||||
|         mCfgMgr.getPluginsConfigPath().string(), false); |         mCfgMgr.getPluginsConfigPath().string(), | ||||||
|  |         renderSystem, | ||||||
|  |         false); | ||||||
| 
 | 
 | ||||||
|     // This has to be added BEFORE MyGUI is initialized, as it needs
 |     // This has to be added BEFORE MyGUI is initialized, as it needs
 | ||||||
|     // to find core.xml here.
 |     // to find core.xml here.
 | ||||||
|  | @ -325,7 +326,14 @@ void OMW::Engine::go() | ||||||
|     addZipResource(mResDir / "mygui" / "Obliviontt.zip"); |     addZipResource(mResDir / "mygui" / "Obliviontt.zip"); | ||||||
| 
 | 
 | ||||||
|     // Create the window
 |     // Create the window
 | ||||||
|     mOgre->createWindow("OpenMW"); |     OEngine::Render::WindowSettings windowSettings; | ||||||
|  |     windowSettings.fullscreen = settings.getBool("fullscreen", "Video"); | ||||||
|  |     windowSettings.window_x = settings.getInt("resolution x", "Video"); | ||||||
|  |     windowSettings.window_y = settings.getInt("resolution y", "Video"); | ||||||
|  |     windowSettings.vsync = settings.getBool("vsync", "Video"); | ||||||
|  |     std::string aa = settings.getString("antialiasing", "Video"); | ||||||
|  |     windowSettings.fsaa = (aa.substr(0, 4) == "MSAA") ? aa.substr(5, aa.size()-5) : "0"; | ||||||
|  |     mOgre->createWindow("OpenMW", windowSettings); | ||||||
| 
 | 
 | ||||||
|     loadBSA(); |     loadBSA(); | ||||||
| 
 | 
 | ||||||
|  | @ -413,7 +421,7 @@ void OMW::Engine::go() | ||||||
| 
 | 
 | ||||||
| void OMW::Engine::activate() | void OMW::Engine::activate() | ||||||
| { | { | ||||||
|     if (MWBase::Environment::get().getWindowManager()->getMode()!=MWGui::GM_Game) |     if (MWBase::Environment::get().getWindowManager()->isGuiMode()) | ||||||
|         return; |         return; | ||||||
| 
 | 
 | ||||||
|     std::string handle = MWBase::Environment::get().getWorld()->getFacedHandle(); |     std::string handle = MWBase::Environment::get().getWorld()->getFacedHandle(); | ||||||
|  |  | ||||||
|  | @ -9,6 +9,7 @@ | ||||||
| 
 | 
 | ||||||
| #include "../mwworld/ptr.hpp" | #include "../mwworld/ptr.hpp" | ||||||
| #include "../mwworld/actiontake.hpp" | #include "../mwworld/actiontake.hpp" | ||||||
|  | #include "../mwworld/actionalchemy.hpp" | ||||||
| #include "../mwworld/world.hpp" | #include "../mwworld/world.hpp" | ||||||
| 
 | 
 | ||||||
| #include "../mwrender/objects.hpp" | #include "../mwrender/objects.hpp" | ||||||
|  | @ -140,4 +141,10 @@ namespace MWClass | ||||||
| 
 | 
 | ||||||
|         return info; |         return info; | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     boost::shared_ptr<MWWorld::Action> Apparatus::use (const MWWorld::Ptr& ptr) const | ||||||
|  |     { | ||||||
|  |         return boost::shared_ptr<MWWorld::Action>(new MWWorld::ActionAlchemy()); | ||||||
|  |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -44,6 +44,10 @@ namespace MWClass | ||||||
| 
 | 
 | ||||||
|             virtual std::string getInventoryIcon (const MWWorld::Ptr& ptr) const; |             virtual std::string getInventoryIcon (const MWWorld::Ptr& ptr) const; | ||||||
|             ///< Return name of inventory icon.
 |             ///< Return name of inventory icon.
 | ||||||
|  | 
 | ||||||
|  |             virtual boost::shared_ptr<MWWorld::Action> use (const MWWorld::Ptr& ptr) | ||||||
|  |                 const; | ||||||
|  |             ///< Generate action for using via inventory menu
 | ||||||
|     }; |     }; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -81,24 +81,15 @@ namespace MWClass | ||||||
|         ESMS::LiveCellRef<ESM::Creature, MWWorld::RefData> *ref = |         ESMS::LiveCellRef<ESM::Creature, MWWorld::RefData> *ref = | ||||||
|             ptr.get<ESM::Creature>(); |             ptr.get<ESM::Creature>(); | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
|         const std::string &model = ref->base->model; |         const std::string &model = ref->base->model; | ||||||
|         assert (ref->base != NULL); |         assert (ref->base != NULL); | ||||||
|         if(!model.empty()){ |         if(!model.empty()){ | ||||||
|             physics.insertObjectPhysics(ptr, "meshes\\" + model); |             physics.insertObjectPhysics(ptr, "meshes\\" + model); | ||||||
|         } |         } | ||||||
|     } |  | ||||||
| 
 | 
 | ||||||
|     void Creature::enable (const MWWorld::Ptr& ptr) const |  | ||||||
|     { |  | ||||||
|         MWBase::Environment::get().getMechanicsManager()->addActor (ptr); |         MWBase::Environment::get().getMechanicsManager()->addActor (ptr); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     void Creature::disable (const MWWorld::Ptr& ptr) const |  | ||||||
|     { |  | ||||||
|         MWBase::Environment::get().getMechanicsManager()->removeActor (ptr); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     std::string Creature::getName (const MWWorld::Ptr& ptr) const |     std::string Creature::getName (const MWWorld::Ptr& ptr) const | ||||||
|     { |     { | ||||||
|         ESMS::LiveCellRef<ESM::Creature, MWWorld::RefData> *ref = |         ESMS::LiveCellRef<ESM::Creature, MWWorld::RefData> *ref = | ||||||
|  |  | ||||||
|  | @ -22,12 +22,6 @@ namespace MWClass | ||||||
| 
 | 
 | ||||||
|             virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const; |             virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const; | ||||||
| 
 | 
 | ||||||
|             virtual void enable (const MWWorld::Ptr& ptr) const; |  | ||||||
|             ///< Enable reference; only does the non-rendering part
 |  | ||||||
| 
 |  | ||||||
|             virtual void disable (const MWWorld::Ptr& ptr) const; |  | ||||||
|             ///< Enable reference; only does the non-rendering part
 |  | ||||||
| 
 |  | ||||||
|             virtual std::string getName (const MWWorld::Ptr& ptr) const; |             virtual std::string getName (const MWWorld::Ptr& ptr) const; | ||||||
|             ///< \return name (the one that is to be presented to the user; not the internal one);
 |             ///< \return name (the one that is to be presented to the user; not the internal one);
 | ||||||
|             /// can return an empty string.
 |             /// can return an empty string.
 | ||||||
|  |  | ||||||
|  | @ -135,6 +135,19 @@ namespace MWClass | ||||||
|             text += MWGui::ToolTips::getMiscString(ref->base->script, "Script"); |             text += MWGui::ToolTips::getMiscString(ref->base->script, "Script"); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |         MWGui::Widgets::SpellEffectList list; | ||||||
|  |         for (int i=0; i<4; ++i) | ||||||
|  |         { | ||||||
|  |             if (ref->base->data.effectID[i] < 0) | ||||||
|  |                 continue; | ||||||
|  |             MWGui::Widgets::SpellEffectParams params; | ||||||
|  |             params.mEffectID = ref->base->data.effectID[i]; | ||||||
|  |             params.mAttribute = ref->base->data.attributes[i]; | ||||||
|  |             params.mSkill = ref->base->data.skills[i]; | ||||||
|  |             list.push_back(params); | ||||||
|  |         } | ||||||
|  |         info.effects = list; | ||||||
|  | 
 | ||||||
|         info.text = text; |         info.text = text; | ||||||
| 
 | 
 | ||||||
|         return info; |         return info; | ||||||
|  |  | ||||||
|  | @ -9,6 +9,7 @@ | ||||||
| 
 | 
 | ||||||
| #include "../mwworld/ptr.hpp" | #include "../mwworld/ptr.hpp" | ||||||
| #include "../mwworld/actiontake.hpp" | #include "../mwworld/actiontake.hpp" | ||||||
|  | #include "../mwworld/actionequip.hpp" | ||||||
| #include "../mwworld/nullaction.hpp" | #include "../mwworld/nullaction.hpp" | ||||||
| #include "../mwworld/inventorystore.hpp" | #include "../mwworld/inventorystore.hpp" | ||||||
| #include "../mwworld/world.hpp" | #include "../mwworld/world.hpp" | ||||||
|  | @ -55,12 +56,6 @@ namespace MWClass | ||||||
|         if(!model.empty()){ |         if(!model.empty()){ | ||||||
|             physics.insertObjectPhysics(ptr, "meshes\\" + model); |             physics.insertObjectPhysics(ptr, "meshes\\" + model); | ||||||
|         } |         } | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     void Light::enable (const MWWorld::Ptr& ptr) const |  | ||||||
|     { |  | ||||||
|         ESMS::LiveCellRef<ESM::Light, MWWorld::RefData> *ref = |  | ||||||
|             ptr.get<ESM::Light>(); |  | ||||||
| 
 | 
 | ||||||
|         if (!ref->base->sound.empty()) |         if (!ref->base->sound.empty()) | ||||||
|         { |         { | ||||||
|  | @ -182,4 +177,11 @@ namespace MWClass | ||||||
| 
 | 
 | ||||||
|         return info; |         return info; | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     boost::shared_ptr<MWWorld::Action> Light::use (const MWWorld::Ptr& ptr) const | ||||||
|  |     { | ||||||
|  |         MWBase::Environment::get().getSoundManager()->playSound (getUpSoundId(ptr), 1.0, 1.0); | ||||||
|  | 
 | ||||||
|  |         return boost::shared_ptr<MWWorld::Action>(new MWWorld::ActionEquip(ptr)); | ||||||
|  |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -14,11 +14,6 @@ namespace MWClass | ||||||
| 
 | 
 | ||||||
|             virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const; |             virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const; | ||||||
| 
 | 
 | ||||||
|             virtual void enable (const MWWorld::Ptr& ptr) const; |  | ||||||
|             ///< Enable reference; only does the non-rendering part
 |  | ||||||
|             /// \attention This is not the same as the script instruction with the same name. References
 |  | ||||||
|             /// should only be enabled while in an active cell.
 |  | ||||||
| 
 |  | ||||||
|             virtual std::string getName (const MWWorld::Ptr& ptr) const; |             virtual std::string getName (const MWWorld::Ptr& ptr) const; | ||||||
|             ///< \return name (the one that is to be presented to the user; not the internal one);
 |             ///< \return name (the one that is to be presented to the user; not the internal one);
 | ||||||
|             /// can return an empty string.
 |             /// can return an empty string.
 | ||||||
|  | @ -53,6 +48,10 @@ namespace MWClass | ||||||
| 
 | 
 | ||||||
|             virtual std::string getInventoryIcon (const MWWorld::Ptr& ptr) const; |             virtual std::string getInventoryIcon (const MWWorld::Ptr& ptr) const; | ||||||
|             ///< Return name of inventory icon.
 |             ///< Return name of inventory icon.
 | ||||||
|  | 
 | ||||||
|  |             virtual boost::shared_ptr<MWWorld::Action> use (const MWWorld::Ptr& ptr) | ||||||
|  |                 const; | ||||||
|  |             ///< Generate action for using via inventory menu
 | ||||||
|     }; |     }; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -9,6 +9,7 @@ | ||||||
| 
 | 
 | ||||||
| #include "../mwworld/ptr.hpp" | #include "../mwworld/ptr.hpp" | ||||||
| #include "../mwworld/actiontake.hpp" | #include "../mwworld/actiontake.hpp" | ||||||
|  | #include "../mwworld/actionequip.hpp" | ||||||
| #include "../mwworld/inventorystore.hpp" | #include "../mwworld/inventorystore.hpp" | ||||||
| #include "../mwworld/world.hpp" | #include "../mwworld/world.hpp" | ||||||
| #include "../mwgui/window_manager.hpp" | #include "../mwgui/window_manager.hpp" | ||||||
|  | @ -155,4 +156,11 @@ namespace MWClass | ||||||
| 
 | 
 | ||||||
|         return info; |         return info; | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     boost::shared_ptr<MWWorld::Action> Lockpick::use (const MWWorld::Ptr& ptr) const | ||||||
|  |     { | ||||||
|  |         MWBase::Environment::get().getSoundManager()->playSound (getUpSoundId(ptr), 1.0, 1.0); | ||||||
|  | 
 | ||||||
|  |         return boost::shared_ptr<MWWorld::Action>(new MWWorld::ActionEquip(ptr)); | ||||||
|  |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -48,6 +48,10 @@ namespace MWClass | ||||||
| 
 | 
 | ||||||
|             virtual std::string getInventoryIcon (const MWWorld::Ptr& ptr) const; |             virtual std::string getInventoryIcon (const MWWorld::Ptr& ptr) const; | ||||||
|             ///< Return name of inventory icon.
 |             ///< Return name of inventory icon.
 | ||||||
|  | 
 | ||||||
|  |             virtual boost::shared_ptr<MWWorld::Action> use (const MWWorld::Ptr& ptr) | ||||||
|  |                 const; | ||||||
|  |             ///< Generate action for using via inventory menu
 | ||||||
|     }; |     }; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -110,44 +110,32 @@ namespace MWClass | ||||||
| 
 | 
 | ||||||
|     void Npc::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const |     void Npc::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const | ||||||
|     { |     { | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|         renderingInterface.getActors().insertNPC(ptr, getInventoryStore(ptr)); |         renderingInterface.getActors().insertNPC(ptr, getInventoryStore(ptr)); | ||||||
| 
 |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     void Npc::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const |     void Npc::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const | ||||||
|     { |     { | ||||||
| 
 | 
 | ||||||
|          |  | ||||||
|         ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData> *ref = |         ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData> *ref = | ||||||
|             ptr.get<ESM::NPC>(); |             ptr.get<ESM::NPC>(); | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
|         assert (ref->base != NULL); |         assert (ref->base != NULL); | ||||||
| 		 std::string headID = ref->base->head; |  | ||||||
| 		 std::string bodyRaceID = headID.substr(0, headID.find_last_of("head_") - 4); |  | ||||||
| 		 bool beast = bodyRaceID == "b_n_khajiit_m_" || bodyRaceID == "b_n_khajiit_f_" || bodyRaceID == "b_n_argonian_m_" || bodyRaceID == "b_n_argonian_f_"; |  | ||||||
| 
 | 
 | ||||||
| 		  | 		  | ||||||
|  | 
 | ||||||
|  |         std::string headID = ref->base->head; | ||||||
|  |         std::string bodyRaceID = headID.substr(0, headID.find_last_of("head_") - 4); | ||||||
|  |         bool beast = bodyRaceID == "b_n_khajiit_m_" || bodyRaceID == "b_n_khajiit_f_" || bodyRaceID == "b_n_argonian_m_" || bodyRaceID == "b_n_argonian_f_"; | ||||||
|  | 
 | ||||||
|         std::string smodel = "meshes\\base_anim.nif"; |         std::string smodel = "meshes\\base_anim.nif"; | ||||||
| 		if(beast) |         if(beast) | ||||||
| 			smodel = "meshes\\base_animkna.nif"; |             smodel = "meshes\\base_animkna.nif"; | ||||||
| 		//physics.insertObjectPhysics(ptr, smodel);
 |  | ||||||
|          |          | ||||||
| 
 | 
 | ||||||
|     } |  | ||||||
| 
 | 
 | ||||||
|     void Npc::enable (const MWWorld::Ptr& ptr) const |  | ||||||
|     { |  | ||||||
|         MWBase::Environment::get().getMechanicsManager()->addActor (ptr); |         MWBase::Environment::get().getMechanicsManager()->addActor (ptr); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     void Npc::disable (const MWWorld::Ptr& ptr) const |  | ||||||
|     { |  | ||||||
|         MWBase::Environment::get().getMechanicsManager()->removeActor (ptr); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     std::string Npc::getName (const MWWorld::Ptr& ptr) const |     std::string Npc::getName (const MWWorld::Ptr& ptr) const | ||||||
|     { |     { | ||||||
|         ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData> *ref = |         ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData> *ref = | ||||||
|  |  | ||||||
|  | @ -19,12 +19,6 @@ namespace MWClass | ||||||
| 
 | 
 | ||||||
|             virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const; |             virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const; | ||||||
| 
 | 
 | ||||||
|             virtual void enable (const MWWorld::Ptr& ptr) const; |  | ||||||
|             ///< Enable reference; only does the non-rendering part
 |  | ||||||
| 
 |  | ||||||
|             virtual void disable (const MWWorld::Ptr& ptr) const; |  | ||||||
|             ///< Enable reference; only does the non-rendering part
 |  | ||||||
| 
 |  | ||||||
|             virtual std::string getName (const MWWorld::Ptr& ptr) const; |             virtual std::string getName (const MWWorld::Ptr& ptr) const; | ||||||
|             ///< \return name (the one that is to be presented to the user; not the internal one);
 |             ///< \return name (the one that is to be presented to the user; not the internal one);
 | ||||||
|             /// can return an empty string.
 |             /// can return an empty string.
 | ||||||
|  |  | ||||||
|  | @ -132,7 +132,7 @@ namespace MWClass | ||||||
|         text += "\n" + store.gameSettings.search("sWeight")->str + ": " + MWGui::ToolTips::toString(ref->base->data.weight); |         text += "\n" + store.gameSettings.search("sWeight")->str + ": " + MWGui::ToolTips::toString(ref->base->data.weight); | ||||||
|         text += MWGui::ToolTips::getValueString(ref->base->data.value, store.gameSettings.search("sValue")->str); |         text += MWGui::ToolTips::getValueString(ref->base->data.value, store.gameSettings.search("sValue")->str); | ||||||
| 
 | 
 | ||||||
|         info.effects = &ref->base->effects; |         info.effects = MWGui::Widgets::MWEffectList::effectListFromESM(&ref->base->effects); | ||||||
| 
 | 
 | ||||||
|         if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { |         if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { | ||||||
|             text += MWGui::ToolTips::getMiscString(ref->ref.owner, "Owner"); |             text += MWGui::ToolTips::getMiscString(ref->ref.owner, "Owner"); | ||||||
|  |  | ||||||
|  | @ -9,6 +9,7 @@ | ||||||
| 
 | 
 | ||||||
| #include "../mwworld/ptr.hpp" | #include "../mwworld/ptr.hpp" | ||||||
| #include "../mwworld/actiontake.hpp" | #include "../mwworld/actiontake.hpp" | ||||||
|  | #include "../mwworld/actionequip.hpp" | ||||||
| #include "../mwworld/inventorystore.hpp" | #include "../mwworld/inventorystore.hpp" | ||||||
| #include "../mwworld/world.hpp" | #include "../mwworld/world.hpp" | ||||||
| #include "../mwgui/window_manager.hpp" | #include "../mwgui/window_manager.hpp" | ||||||
|  | @ -154,4 +155,11 @@ namespace MWClass | ||||||
| 
 | 
 | ||||||
|         return info; |         return info; | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     boost::shared_ptr<MWWorld::Action> Probe::use (const MWWorld::Ptr& ptr) const | ||||||
|  |     { | ||||||
|  |         MWBase::Environment::get().getSoundManager()->playSound (getUpSoundId(ptr), 1.0, 1.0); | ||||||
|  | 
 | ||||||
|  |         return boost::shared_ptr<MWWorld::Action>(new MWWorld::ActionEquip(ptr)); | ||||||
|  |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -48,6 +48,10 @@ namespace MWClass | ||||||
| 
 | 
 | ||||||
|             virtual std::string getInventoryIcon (const MWWorld::Ptr& ptr) const; |             virtual std::string getInventoryIcon (const MWWorld::Ptr& ptr) const; | ||||||
|             ///< Return name of inventory icon.
 |             ///< Return name of inventory icon.
 | ||||||
|  | 
 | ||||||
|  |             virtual boost::shared_ptr<MWWorld::Action> use (const MWWorld::Ptr& ptr) | ||||||
|  |                 const; | ||||||
|  |             ///< Generate action for using via inventory menu
 | ||||||
|     }; |     }; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -607,7 +607,7 @@ namespace MWDialogue | ||||||
|     void DialogueManager::parseText(std::string text) |     void DialogueManager::parseText(std::string text) | ||||||
|     { |     { | ||||||
|         std::list<std::string>::iterator it; |         std::list<std::string>::iterator it; | ||||||
|         for(it = actorKnownTopics.begin();it != actorKnownTopics.end();it++) |         for(it = actorKnownTopics.begin();it != actorKnownTopics.end();++it) | ||||||
|         { |         { | ||||||
|             size_t pos = find_str_ci(text,*it,0); |             size_t pos = find_str_ci(text,*it,0); | ||||||
|             if(pos !=std::string::npos) |             if(pos !=std::string::npos) | ||||||
|  | @ -635,7 +635,7 @@ namespace MWDialogue | ||||||
|         actorKnownTopics.clear(); |         actorKnownTopics.clear(); | ||||||
| 
 | 
 | ||||||
|         //initialise the GUI
 |         //initialise the GUI
 | ||||||
|         MWBase::Environment::get().getInputManager()->setGuiMode(MWGui::GM_Dialogue); |         MWBase::Environment::get().getWindowManager()->pushGuiMode(MWGui::GM_Dialogue); | ||||||
|         MWGui::DialogueWindow* win = MWBase::Environment::get().getWindowManager()->getDialogueWindow(); |         MWGui::DialogueWindow* win = MWBase::Environment::get().getWindowManager()->getDialogueWindow(); | ||||||
|         win->startDialogue(actor, MWWorld::Class::get (actor).getName (actor)); |         win->startDialogue(actor, MWWorld::Class::get (actor).getName (actor)); | ||||||
| 
 | 
 | ||||||
|  | @ -843,7 +843,7 @@ namespace MWDialogue | ||||||
| 
 | 
 | ||||||
|     void DialogueManager::goodbyeSelected() |     void DialogueManager::goodbyeSelected() | ||||||
|     { |     { | ||||||
|         MWBase::Environment::get().getInputManager()->setGuiMode(MWGui::GM_Game); |         MWBase::Environment::get().getWindowManager()->popGuiMode(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     void DialogueManager::questionAnswered(std::string answere) |     void DialogueManager::questionAnswered(std::string answere) | ||||||
|  |  | ||||||
							
								
								
									
										512
									
								
								apps/openmw/mwgui/alchemywindow.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										512
									
								
								apps/openmw/mwgui/alchemywindow.cpp
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,512 @@ | ||||||
|  | #include "alchemywindow.hpp" | ||||||
|  | 
 | ||||||
|  | #include <boost/algorithm/string.hpp> | ||||||
|  | 
 | ||||||
|  | #include "../mwbase/environment.hpp" | ||||||
|  | #include "../mwworld/world.hpp" | ||||||
|  | #include "../mwworld/player.hpp" | ||||||
|  | #include "../mwworld/manualref.hpp" | ||||||
|  | #include "../mwworld/containerstore.hpp" | ||||||
|  | #include "../mwsound/soundmanager.hpp" | ||||||
|  | 
 | ||||||
|  | #include "window_manager.hpp" | ||||||
|  | 
 | ||||||
|  | namespace | ||||||
|  | { | ||||||
|  |     std::string getIconPath(MWWorld::Ptr ptr) | ||||||
|  |     { | ||||||
|  |         std::string path = std::string("icons\\"); | ||||||
|  |         path += MWWorld::Class::get(ptr).getInventoryIcon(ptr); | ||||||
|  |         int pos = path.rfind("."); | ||||||
|  |         path.erase(pos); | ||||||
|  |         path.append(".dds"); | ||||||
|  |         return path; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | namespace MWGui | ||||||
|  | { | ||||||
|  |     AlchemyWindow::AlchemyWindow(WindowManager& parWindowManager) | ||||||
|  |         : WindowBase("openmw_alchemy_window_layout.xml", parWindowManager) | ||||||
|  |         , ContainerBase(0) | ||||||
|  |     { | ||||||
|  |         getWidget(mCreateButton, "CreateButton"); | ||||||
|  |         getWidget(mCancelButton, "CancelButton"); | ||||||
|  |         getWidget(mIngredient1, "Ingredient1"); | ||||||
|  |         getWidget(mIngredient2, "Ingredient2"); | ||||||
|  |         getWidget(mIngredient3, "Ingredient3"); | ||||||
|  |         getWidget(mIngredient4, "Ingredient4"); | ||||||
|  |         getWidget(mApparatus1, "Apparatus1"); | ||||||
|  |         getWidget(mApparatus2, "Apparatus2"); | ||||||
|  |         getWidget(mApparatus3, "Apparatus3"); | ||||||
|  |         getWidget(mApparatus4, "Apparatus4"); | ||||||
|  |         getWidget(mEffectsBox, "CreatedEffects"); | ||||||
|  |         getWidget(mNameEdit, "NameEdit"); | ||||||
|  | 
 | ||||||
|  |         mIngredient1->eventMouseButtonClick += MyGUI::newDelegate(this, &AlchemyWindow::onIngredientSelected); | ||||||
|  |         mIngredient2->eventMouseButtonClick += MyGUI::newDelegate(this, &AlchemyWindow::onIngredientSelected); | ||||||
|  |         mIngredient3->eventMouseButtonClick += MyGUI::newDelegate(this, &AlchemyWindow::onIngredientSelected); | ||||||
|  |         mIngredient4->eventMouseButtonClick += MyGUI::newDelegate(this, &AlchemyWindow::onIngredientSelected); | ||||||
|  | 
 | ||||||
|  |         MyGUI::Widget* buttonBox = mCancelButton->getParent(); | ||||||
|  |         int cancelButtonWidth = mCancelButton->getTextSize().width + 24; | ||||||
|  |         mCancelButton->setCoord(buttonBox->getWidth() - cancelButtonWidth, | ||||||
|  |                                 mCancelButton->getTop(), cancelButtonWidth, mCancelButton->getHeight()); | ||||||
|  |         int createButtonWidth = mCreateButton->getTextSize().width + 24; | ||||||
|  |         mCreateButton->setCoord(buttonBox->getWidth() - createButtonWidth - cancelButtonWidth - 4, | ||||||
|  |                                 mCreateButton->getTop(), createButtonWidth, mCreateButton->getHeight()); | ||||||
|  | 
 | ||||||
|  |         mCreateButton->eventMouseButtonClick += MyGUI::newDelegate(this, &AlchemyWindow::onCreateButtonClicked); | ||||||
|  |         mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &AlchemyWindow::onCancelButtonClicked); | ||||||
|  | 
 | ||||||
|  |         MyGUI::ScrollView* itemView; | ||||||
|  |         MyGUI::Widget* containerWidget; | ||||||
|  |         getWidget(containerWidget, "Items"); | ||||||
|  |         getWidget(itemView, "ItemView"); | ||||||
|  |         setWidgets(containerWidget, itemView); | ||||||
|  | 
 | ||||||
|  |         center(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     void AlchemyWindow::onCancelButtonClicked(MyGUI::Widget* _sender) | ||||||
|  |     { | ||||||
|  |         mWindowManager.popGuiMode(); | ||||||
|  |         mWindowManager.popGuiMode(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     void AlchemyWindow::onCreateButtonClicked(MyGUI::Widget* _sender) | ||||||
|  |     { | ||||||
|  |         // check if mortar & pestle is available (always needed)
 | ||||||
|  |         /// \todo check albemic, calcinator, retort (sometimes needed)
 | ||||||
|  |         if (!mApparatus1->isUserString("ToolTipType")) | ||||||
|  |         { | ||||||
|  |             mWindowManager.messageBox("#{sNotifyMessage45}", std::vector<std::string>()); | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         // make sure 2 or more ingredients were selected
 | ||||||
|  |         int numIngreds = 0; | ||||||
|  |         if (mIngredient1->isUserString("ToolTipType")) | ||||||
|  |             ++numIngreds; | ||||||
|  |         if (mIngredient2->isUserString("ToolTipType")) | ||||||
|  |             ++numIngreds; | ||||||
|  |         if (mIngredient3->isUserString("ToolTipType")) | ||||||
|  |             ++numIngreds; | ||||||
|  |         if (mIngredient4->isUserString("ToolTipType")) | ||||||
|  |             ++numIngreds; | ||||||
|  |         if (numIngreds < 2) | ||||||
|  |         { | ||||||
|  |             mWindowManager.messageBox("#{sNotifyMessage6a}", std::vector<std::string>()); | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         // make sure a name was entered
 | ||||||
|  |         std::string name = mNameEdit->getCaption(); | ||||||
|  |         boost::algorithm::trim(name); | ||||||
|  |         if (name == "") | ||||||
|  |         { | ||||||
|  |             mWindowManager.messageBox("#{sNotifyMessage37}", std::vector<std::string>()); | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         // if there are no created effects, the potion will always fail (but the ingredients won't be destroyed)
 | ||||||
|  |         if (mEffects.empty()) | ||||||
|  |         { | ||||||
|  |             mWindowManager.messageBox("#{sNotifyMessage8}", std::vector<std::string>()); | ||||||
|  |             MWBase::Environment::get().getSoundManager()->playSound("potion fail", 1.f, 1.f); | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         if (rand() % 2 == 0) /// \todo
 | ||||||
|  |         { | ||||||
|  |             ESM::Potion newPotion; | ||||||
|  |             newPotion.name = mNameEdit->getCaption(); | ||||||
|  |             ESM::EffectList effects; | ||||||
|  |             for (unsigned int i=0; i<4; ++i) | ||||||
|  |             { | ||||||
|  |                 if (mEffects.size() >= i+1) | ||||||
|  |                 { | ||||||
|  |                     ESM::ENAMstruct effect; | ||||||
|  |                     effect.effectID = mEffects[i].mEffectID; | ||||||
|  |                     effect.area = 0; | ||||||
|  |                     effect.range = ESM::RT_Self; | ||||||
|  |                     effect.skill = mEffects[i].mSkill; | ||||||
|  |                     effect.attribute = mEffects[i].mAttribute; | ||||||
|  |                     effect.magnMin = 1; /// \todo
 | ||||||
|  |                     effect.magnMax = 10; /// \todo
 | ||||||
|  |                     effect.duration = 60; /// \todo
 | ||||||
|  |                     effects.list.push_back(effect); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             // UESP Wiki / Morrowind:Alchemy
 | ||||||
|  |             // "The weight of a potion is an average of the weight of the ingredients, rounded down."
 | ||||||
|  |             // note by scrawl: not rounding down here, I can't imagine a created potion to
 | ||||||
|  |             // have 0 weight when using ingredients with 0.1 weight respectively
 | ||||||
|  |             float weight = 0; | ||||||
|  |             if (mIngredient1->isUserString("ToolTipType")) | ||||||
|  |                 weight += mIngredient1->getUserData<MWWorld::Ptr>()->get<ESM::Ingredient>()->base->data.weight; | ||||||
|  |             if (mIngredient2->isUserString("ToolTipType")) | ||||||
|  |                 weight += mIngredient2->getUserData<MWWorld::Ptr>()->get<ESM::Ingredient>()->base->data.weight; | ||||||
|  |             if (mIngredient3->isUserString("ToolTipType")) | ||||||
|  |                 weight += mIngredient3->getUserData<MWWorld::Ptr>()->get<ESM::Ingredient>()->base->data.weight; | ||||||
|  |             if (mIngredient4->isUserString("ToolTipType")) | ||||||
|  |                 weight += mIngredient4->getUserData<MWWorld::Ptr>()->get<ESM::Ingredient>()->base->data.weight; | ||||||
|  |             newPotion.data.weight = weight / float(numIngreds); | ||||||
|  | 
 | ||||||
|  |             newPotion.data.value = 100; /// \todo
 | ||||||
|  |             newPotion.effects = effects; | ||||||
|  |             // pick a random mesh and icon
 | ||||||
|  |             std::vector<std::string> names; | ||||||
|  |             /// \todo is the mesh/icon dependent on alchemy skill?
 | ||||||
|  |             names.push_back("standard"); | ||||||
|  |             names.push_back("bargain"); | ||||||
|  |             names.push_back("cheap"); | ||||||
|  |             names.push_back("fresh"); | ||||||
|  |             names.push_back("exclusive"); | ||||||
|  |             names.push_back("quality"); | ||||||
|  |             int random = rand() % names.size(); | ||||||
|  |             newPotion.model = "m\\misc_potion_" + names[random ] + "_01.nif"; | ||||||
|  |             newPotion.icon = "m\\tx_potion_" + names[random ] + "_01.dds"; | ||||||
|  | 
 | ||||||
|  |             // check if a similiar potion record exists already
 | ||||||
|  |             bool found = false; | ||||||
|  |             std::string objectId; | ||||||
|  |             typedef std::map<std::string, ESM::Potion> PotionMap; | ||||||
|  |             PotionMap potions = MWBase::Environment::get().getWorld()->getStore().potions.list; | ||||||
|  |             for (PotionMap::const_iterator it = potions.begin(); it != potions.end(); ++it) | ||||||
|  |             { | ||||||
|  |                 if (found) break; | ||||||
|  | 
 | ||||||
|  |                 if (it->second.data.value == newPotion.data.value | ||||||
|  |                     && it->second.data.weight == newPotion.data.weight | ||||||
|  |                     && it->second.name == newPotion.name | ||||||
|  |                     && it->second.effects.list.size() == newPotion.effects.list.size()) | ||||||
|  |                 { | ||||||
|  |                     // check effects
 | ||||||
|  |                     for (unsigned int i=0; i < it->second.effects.list.size(); ++i) | ||||||
|  |                     { | ||||||
|  |                         const ESM::ENAMstruct& a = it->second.effects.list[i]; | ||||||
|  |                         const ESM::ENAMstruct& b = newPotion.effects.list[i]; | ||||||
|  |                         if (a.effectID == b.effectID | ||||||
|  |                             && a.area == b.area | ||||||
|  |                             && a.range == b.range | ||||||
|  |                             && a.skill == b.skill | ||||||
|  |                             && a.attribute == b.attribute | ||||||
|  |                             && a.magnMin == b.magnMin | ||||||
|  |                             && a.magnMax == b.magnMax | ||||||
|  |                             && a.duration == b.duration) | ||||||
|  |                         { | ||||||
|  |                             found = true; | ||||||
|  |                             objectId = it->first; | ||||||
|  |                             break; | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             if (!found) | ||||||
|  |             { | ||||||
|  |                 std::pair<std::string, const ESM::Potion*> result = MWBase::Environment::get().getWorld()->createRecord(newPotion); | ||||||
|  |                 objectId = result.first; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             // create a reference and add it to player inventory
 | ||||||
|  |             MWWorld::ManualRef ref(MWBase::Environment::get().getWorld()->getStore(), objectId); | ||||||
|  |             MWWorld::ContainerStore& store = MWWorld::Class::get(mPtr).getContainerStore(mPtr); | ||||||
|  |             ref.getPtr().getRefData().setCount(1); | ||||||
|  |             store.add(ref.getPtr()); | ||||||
|  | 
 | ||||||
|  |             mWindowManager.messageBox("#{sPotionSuccess}", std::vector<std::string>()); | ||||||
|  |             MWBase::Environment::get().getSoundManager()->playSound("potion success", 1.f, 1.f); | ||||||
|  |         } | ||||||
|  |         else | ||||||
|  |         { | ||||||
|  |             // potion failed
 | ||||||
|  |             mWindowManager.messageBox("#{sNotifyMessage8}", std::vector<std::string>()); | ||||||
|  |             MWBase::Environment::get().getSoundManager()->playSound("potion fail", 1.f, 1.f); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         // reduce count of the ingredients
 | ||||||
|  |         if (mIngredient1->isUserString("ToolTipType")) | ||||||
|  |         { | ||||||
|  |             MWWorld::Ptr ingred = *mIngredient1->getUserData<MWWorld::Ptr>(); | ||||||
|  |             ingred.getRefData().setCount(ingred.getRefData().getCount()-1); | ||||||
|  |             if (ingred.getRefData().getCount() == 0) | ||||||
|  |                 removeIngredient(mIngredient1); | ||||||
|  |         } | ||||||
|  |         if (mIngredient2->isUserString("ToolTipType")) | ||||||
|  |         { | ||||||
|  |             MWWorld::Ptr ingred = *mIngredient2->getUserData<MWWorld::Ptr>(); | ||||||
|  |             ingred.getRefData().setCount(ingred.getRefData().getCount()-1); | ||||||
|  |             if (ingred.getRefData().getCount() == 0) | ||||||
|  |                 removeIngredient(mIngredient2); | ||||||
|  |         } | ||||||
|  |         if (mIngredient3->isUserString("ToolTipType")) | ||||||
|  |         { | ||||||
|  |             MWWorld::Ptr ingred = *mIngredient3->getUserData<MWWorld::Ptr>(); | ||||||
|  |             ingred.getRefData().setCount(ingred.getRefData().getCount()-1); | ||||||
|  |             if (ingred.getRefData().getCount() == 0) | ||||||
|  |                 removeIngredient(mIngredient3); | ||||||
|  |         } | ||||||
|  |         if (mIngredient4->isUserString("ToolTipType")) | ||||||
|  |         { | ||||||
|  |             MWWorld::Ptr ingred = *mIngredient4->getUserData<MWWorld::Ptr>(); | ||||||
|  |             ingred.getRefData().setCount(ingred.getRefData().getCount()-1); | ||||||
|  |             if (ingred.getRefData().getCount() == 0) | ||||||
|  |                 removeIngredient(mIngredient4); | ||||||
|  |         } | ||||||
|  |         update(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     void AlchemyWindow::open() | ||||||
|  |     { | ||||||
|  |         openContainer(MWBase::Environment::get().getWorld()->getPlayer().getPlayer()); | ||||||
|  |         setFilter(ContainerBase::Filter_Ingredients); | ||||||
|  | 
 | ||||||
|  |         // pick the best available apparatus
 | ||||||
|  |         MWWorld::ContainerStore& store = MWWorld::Class::get(mPtr).getContainerStore(mPtr); | ||||||
|  | 
 | ||||||
|  |         MWWorld::Ptr bestAlbemic; | ||||||
|  |         MWWorld::Ptr bestMortarPestle; | ||||||
|  |         MWWorld::Ptr bestCalcinator; | ||||||
|  |         MWWorld::Ptr bestRetort; | ||||||
|  | 
 | ||||||
|  |         for (MWWorld::ContainerStoreIterator it(store.begin(MWWorld::ContainerStore::Type_Apparatus)); | ||||||
|  |             it != store.end(); ++it) | ||||||
|  |         { | ||||||
|  |             ESMS::LiveCellRef<ESM::Apparatus, MWWorld::RefData>* ref = it->get<ESM::Apparatus>(); | ||||||
|  |             if (ref->base->data.type == ESM::Apparatus::Albemic | ||||||
|  |             && (bestAlbemic.isEmpty() || ref->base->data.quality > bestAlbemic.get<ESM::Apparatus>()->base->data.quality)) | ||||||
|  |                 bestAlbemic = *it; | ||||||
|  |             else if (ref->base->data.type == ESM::Apparatus::MortarPestle | ||||||
|  |             && (bestMortarPestle.isEmpty() || ref->base->data.quality > bestMortarPestle.get<ESM::Apparatus>()->base->data.quality)) | ||||||
|  |                 bestMortarPestle = *it; | ||||||
|  |             else if (ref->base->data.type == ESM::Apparatus::Calcinator | ||||||
|  |             && (bestCalcinator.isEmpty() || ref->base->data.quality > bestCalcinator.get<ESM::Apparatus>()->base->data.quality)) | ||||||
|  |                 bestCalcinator = *it; | ||||||
|  |             else if (ref->base->data.type == ESM::Apparatus::Retort | ||||||
|  |             && (bestRetort.isEmpty() || ref->base->data.quality > bestRetort.get<ESM::Apparatus>()->base->data.quality)) | ||||||
|  |                 bestRetort = *it; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         if (!bestMortarPestle.isEmpty()) | ||||||
|  |         { | ||||||
|  |             mApparatus1->setUserString("ToolTipType", "ItemPtr"); | ||||||
|  |             mApparatus1->setUserData(bestMortarPestle); | ||||||
|  |             mApparatus1->setImageTexture(getIconPath(bestMortarPestle)); | ||||||
|  |         } | ||||||
|  |         if (!bestAlbemic.isEmpty()) | ||||||
|  |         { | ||||||
|  |             mApparatus2->setUserString("ToolTipType", "ItemPtr"); | ||||||
|  |             mApparatus2->setUserData(bestAlbemic); | ||||||
|  |             mApparatus2->setImageTexture(getIconPath(bestAlbemic)); | ||||||
|  |         } | ||||||
|  |         if (!bestCalcinator.isEmpty()) | ||||||
|  |         { | ||||||
|  |             mApparatus3->setUserString("ToolTipType", "ItemPtr"); | ||||||
|  |             mApparatus3->setUserData(bestCalcinator); | ||||||
|  |             mApparatus3->setImageTexture(getIconPath(bestCalcinator)); | ||||||
|  |         } | ||||||
|  |         if (!bestRetort.isEmpty()) | ||||||
|  |         { | ||||||
|  |             mApparatus4->setUserString("ToolTipType", "ItemPtr"); | ||||||
|  |             mApparatus4->setUserData(bestRetort); | ||||||
|  |             mApparatus4->setImageTexture(getIconPath(bestRetort)); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     void AlchemyWindow::onIngredientSelected(MyGUI::Widget* _sender) | ||||||
|  |     { | ||||||
|  |         removeIngredient(_sender); | ||||||
|  |         drawItems(); | ||||||
|  |         update(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     void AlchemyWindow::onSelectedItemImpl(MWWorld::Ptr item) | ||||||
|  |     { | ||||||
|  |         MyGUI::ImageBox* add = NULL; | ||||||
|  | 
 | ||||||
|  |         // don't allow to add an ingredient that is already added
 | ||||||
|  |         // (which could happen if two similiar ingredients don't stack because of script / owner)
 | ||||||
|  |         bool alreadyAdded = false; | ||||||
|  |         std::string name = MWWorld::Class::get(item).getName(item); | ||||||
|  |         if (mIngredient1->isUserString("ToolTipType")) | ||||||
|  |         { | ||||||
|  |             MWWorld::Ptr item2 = *mIngredient1->getUserData<MWWorld::Ptr>(); | ||||||
|  |             std::string name2 = MWWorld::Class::get(item2).getName(item2); | ||||||
|  |             if (name == name2) | ||||||
|  |                 alreadyAdded = true; | ||||||
|  |         } | ||||||
|  |         if (mIngredient2->isUserString("ToolTipType")) | ||||||
|  |         { | ||||||
|  |             MWWorld::Ptr item2 = *mIngredient2->getUserData<MWWorld::Ptr>(); | ||||||
|  |             std::string name2 = MWWorld::Class::get(item2).getName(item2); | ||||||
|  |             if (name == name2) | ||||||
|  |                 alreadyAdded = true; | ||||||
|  |         } | ||||||
|  |         if (mIngredient3->isUserString("ToolTipType")) | ||||||
|  |         { | ||||||
|  |             MWWorld::Ptr item2 = *mIngredient3->getUserData<MWWorld::Ptr>(); | ||||||
|  |             std::string name2 = MWWorld::Class::get(item2).getName(item2); | ||||||
|  |             if (name == name2) | ||||||
|  |                 alreadyAdded = true; | ||||||
|  |         } | ||||||
|  |         if (mIngredient4->isUserString("ToolTipType")) | ||||||
|  |         { | ||||||
|  |             MWWorld::Ptr item2 = *mIngredient4->getUserData<MWWorld::Ptr>(); | ||||||
|  |             std::string name2 = MWWorld::Class::get(item2).getName(item2); | ||||||
|  |             if (name == name2) | ||||||
|  |                 alreadyAdded = true; | ||||||
|  |         } | ||||||
|  |         if (alreadyAdded) | ||||||
|  |             return; | ||||||
|  | 
 | ||||||
|  |         if (!mIngredient1->isUserString("ToolTipType")) | ||||||
|  |             add = mIngredient1; | ||||||
|  |         if (add == NULL  && !mIngredient2->isUserString("ToolTipType")) | ||||||
|  |             add = mIngredient2; | ||||||
|  |         if (add == NULL  && !mIngredient3->isUserString("ToolTipType")) | ||||||
|  |             add = mIngredient3; | ||||||
|  |         if (add == NULL  && !mIngredient4->isUserString("ToolTipType")) | ||||||
|  |             add = mIngredient4; | ||||||
|  | 
 | ||||||
|  |         if (add != NULL) | ||||||
|  |         { | ||||||
|  |             add->setUserString("ToolTipType", "ItemPtr"); | ||||||
|  |             add->setUserData(item); | ||||||
|  |             add->setImageTexture(getIconPath(item)); | ||||||
|  |             drawItems(); | ||||||
|  |             update(); | ||||||
|  | 
 | ||||||
|  |             std::string sound = MWWorld::Class::get(item).getUpSoundId(item); | ||||||
|  |             MWBase::Environment::get().getSoundManager()->playSound (sound, 1.0, 1.0); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     std::vector<MWWorld::Ptr> AlchemyWindow::itemsToIgnore() | ||||||
|  |     { | ||||||
|  |         std::vector<MWWorld::Ptr> ignore; | ||||||
|  |         // don't show ingredients that are currently selected in the "available ingredients" box.
 | ||||||
|  |         if (mIngredient1->isUserString("ToolTipType")) | ||||||
|  |             ignore.push_back(*mIngredient1->getUserData<MWWorld::Ptr>()); | ||||||
|  |         if (mIngredient2->isUserString("ToolTipType")) | ||||||
|  |             ignore.push_back(*mIngredient2->getUserData<MWWorld::Ptr>()); | ||||||
|  |         if (mIngredient3->isUserString("ToolTipType")) | ||||||
|  |             ignore.push_back(*mIngredient3->getUserData<MWWorld::Ptr>()); | ||||||
|  |         if (mIngredient4->isUserString("ToolTipType")) | ||||||
|  |             ignore.push_back(*mIngredient4->getUserData<MWWorld::Ptr>()); | ||||||
|  | 
 | ||||||
|  |         return ignore; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     void AlchemyWindow::update() | ||||||
|  |     { | ||||||
|  |         Widgets::SpellEffectList effects; | ||||||
|  | 
 | ||||||
|  |         for (int i=0; i<4; ++i) | ||||||
|  |         { | ||||||
|  |             MyGUI::ImageBox* ingredient; | ||||||
|  |             if (i==0) | ||||||
|  |                 ingredient = mIngredient1; | ||||||
|  |             else if (i==1) | ||||||
|  |                 ingredient = mIngredient2; | ||||||
|  |             else if (i==2) | ||||||
|  |                 ingredient = mIngredient3; | ||||||
|  |             else if (i==3) | ||||||
|  |                 ingredient = mIngredient4; | ||||||
|  | 
 | ||||||
|  |             if (!ingredient->isUserString("ToolTipType")) | ||||||
|  |                 continue; | ||||||
|  | 
 | ||||||
|  |             // add the effects of this ingredient to list of effects
 | ||||||
|  |             ESMS::LiveCellRef<ESM::Ingredient, MWWorld::RefData>* ref = ingredient->getUserData<MWWorld::Ptr>()->get<ESM::Ingredient>(); | ||||||
|  |             for (int i=0; i<4; ++i) | ||||||
|  |             { | ||||||
|  |                 if (ref->base->data.effectID[i] < 0) | ||||||
|  |                     continue; | ||||||
|  |                 MWGui::Widgets::SpellEffectParams params; | ||||||
|  |                 params.mEffectID = ref->base->data.effectID[i]; | ||||||
|  |                 params.mAttribute = ref->base->data.attributes[i]; | ||||||
|  |                 params.mSkill = ref->base->data.skills[i]; | ||||||
|  |                 effects.push_back(params); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             // update ingredient count labels
 | ||||||
|  |             if (ingredient->getChildCount()) | ||||||
|  |                 MyGUI::Gui::getInstance().destroyWidget(ingredient->getChildAt(0)); | ||||||
|  | 
 | ||||||
|  |             MyGUI::TextBox* text = ingredient->createWidget<MyGUI::TextBox>("SandBrightText", MyGUI::IntCoord(0, 14, 32, 18), MyGUI::Align::Default, std::string("Label")); | ||||||
|  |             text->setTextAlign(MyGUI::Align::Right); | ||||||
|  |             text->setNeedMouseFocus(false); | ||||||
|  |             text->setTextShadow(true); | ||||||
|  |             text->setTextShadowColour(MyGUI::Colour(0,0,0)); | ||||||
|  |             text->setCaption(getCountString(ingredient->getUserData<MWWorld::Ptr>()->getRefData().getCount())); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         // now remove effects that are only present once
 | ||||||
|  |         Widgets::SpellEffectList::iterator it = effects.begin(); | ||||||
|  |         while (it != effects.end()) | ||||||
|  |         { | ||||||
|  |             Widgets::SpellEffectList::iterator next = it; | ||||||
|  |             ++next; | ||||||
|  |             bool found = false; | ||||||
|  |             for (; next != effects.end(); ++next) | ||||||
|  |             { | ||||||
|  |                 if (*next == *it) | ||||||
|  |                     found = true; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             if (!found) | ||||||
|  |                 it = effects.erase(it); | ||||||
|  |             else | ||||||
|  |                 ++it; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         // now remove duplicates, and don't allow more than 4 effects
 | ||||||
|  |         Widgets::SpellEffectList old = effects; | ||||||
|  |         effects.clear(); | ||||||
|  |         int i=0; | ||||||
|  |         for (Widgets::SpellEffectList::iterator it = old.begin(); | ||||||
|  |             it != old.end(); ++it) | ||||||
|  |         { | ||||||
|  |             bool found = false; | ||||||
|  |             for (Widgets::SpellEffectList::iterator it2 = effects.begin(); | ||||||
|  |                 it2 != effects.end(); ++it2) | ||||||
|  |             { | ||||||
|  |                 // MW considers all "foritfy attribute" effects as the same effect. See the
 | ||||||
|  |                 // "Can't create multi-state boost potions" discussion on http://www.uesp.net/wiki/Morrowind_talk:Alchemy
 | ||||||
|  |                 // thus, we are only checking effectID here and not attribute or skill
 | ||||||
|  |                 if (it2->mEffectID == it->mEffectID) | ||||||
|  |                     found = true; | ||||||
|  |             } | ||||||
|  |             if (!found && i<4) | ||||||
|  |             { | ||||||
|  |                 ++i; | ||||||
|  |                 effects.push_back(*it); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         mEffects = effects; | ||||||
|  | 
 | ||||||
|  |         while (mEffectsBox->getChildCount()) | ||||||
|  |             MyGUI::Gui::getInstance().destroyWidget(mEffectsBox->getChildAt(0)); | ||||||
|  | 
 | ||||||
|  |         MyGUI::IntCoord coord(0, 0, mEffectsBox->getWidth(), 24); | ||||||
|  |         Widgets::MWEffectListPtr effectsWidget = mEffectsBox->createWidget<Widgets::MWEffectList> | ||||||
|  |             ("MW_StatName", coord, Align::Left | Align::Top); | ||||||
|  |         effectsWidget->setWindowManager(&mWindowManager); | ||||||
|  |         effectsWidget->setEffectList(effects); | ||||||
|  | 
 | ||||||
|  |         std::vector<MyGUI::WidgetPtr> effectItems; | ||||||
|  |         effectsWidget->createEffectWidgets(effectItems, mEffectsBox, coord, false, 0); | ||||||
|  |         effectsWidget->setCoord(coord); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     void AlchemyWindow::removeIngredient(MyGUI::Widget* ingredient) | ||||||
|  |     { | ||||||
|  |         ingredient->clearUserStrings(); | ||||||
|  |         static_cast<MyGUI::ImageBox*>(ingredient)->setImageTexture(""); | ||||||
|  |         if (ingredient->getChildCount()) | ||||||
|  |             MyGUI::Gui::getInstance().destroyWidget(ingredient->getChildAt(0)); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										51
									
								
								apps/openmw/mwgui/alchemywindow.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								apps/openmw/mwgui/alchemywindow.hpp
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,51 @@ | ||||||
|  | #ifndef MWGUI_ALCHEMY_H | ||||||
|  | #define MWGUI_ALCHEMY_H | ||||||
|  | 
 | ||||||
|  | #include "window_base.hpp" | ||||||
|  | #include "container.hpp" | ||||||
|  | 
 | ||||||
|  | namespace MWGui | ||||||
|  | { | ||||||
|  |     class AlchemyWindow : public WindowBase, public ContainerBase | ||||||
|  |     { | ||||||
|  |     public: | ||||||
|  |         AlchemyWindow(WindowManager& parWindowManager); | ||||||
|  | 
 | ||||||
|  |         virtual void open(); | ||||||
|  | 
 | ||||||
|  |     protected: | ||||||
|  |         MyGUI::Button* mCreateButton; | ||||||
|  |         MyGUI::Button* mCancelButton; | ||||||
|  | 
 | ||||||
|  |         MyGUI::ImageBox* mIngredient1; | ||||||
|  |         MyGUI::ImageBox* mIngredient2; | ||||||
|  |         MyGUI::ImageBox* mIngredient3; | ||||||
|  |         MyGUI::ImageBox* mIngredient4; | ||||||
|  | 
 | ||||||
|  |         MyGUI::ImageBox* mApparatus1; | ||||||
|  |         MyGUI::ImageBox* mApparatus2; | ||||||
|  |         MyGUI::ImageBox* mApparatus3; | ||||||
|  |         MyGUI::ImageBox* mApparatus4; | ||||||
|  | 
 | ||||||
|  |         MyGUI::Widget* mEffectsBox; | ||||||
|  | 
 | ||||||
|  |         MyGUI::EditBox* mNameEdit; | ||||||
|  | 
 | ||||||
|  |         Widgets::SpellEffectList mEffects; // effects of created potion
 | ||||||
|  | 
 | ||||||
|  |         void onCancelButtonClicked(MyGUI::Widget* _sender); | ||||||
|  |         void onCreateButtonClicked(MyGUI::Widget* _sender); | ||||||
|  |         void onIngredientSelected(MyGUI::Widget* _sender); | ||||||
|  | 
 | ||||||
|  |         virtual void onSelectedItemImpl(MWWorld::Ptr item); | ||||||
|  |         virtual std::vector<MWWorld::Ptr> itemsToIgnore(); | ||||||
|  | 
 | ||||||
|  |         void removeIngredient(MyGUI::Widget* ingredient); | ||||||
|  | 
 | ||||||
|  |         virtual void onReferenceUnavailable() { ; } | ||||||
|  | 
 | ||||||
|  |         void update(); | ||||||
|  |     }; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
|  | @ -1,13 +1,14 @@ | ||||||
| #include "bookwindow.hpp" | #include "bookwindow.hpp" | ||||||
| 
 | 
 | ||||||
| #include "formatting.hpp" | #include <boost/lexical_cast.hpp> | ||||||
| 
 | 
 | ||||||
| #include "../mwbase/environment.hpp" | #include "../mwbase/environment.hpp" | ||||||
| #include "../mwinput/inputmanager.hpp" | #include "../mwinput/inputmanager.hpp" | ||||||
| #include "../mwsound/soundmanager.hpp" | #include "../mwsound/soundmanager.hpp" | ||||||
| #include "../mwworld/actiontake.hpp" | #include "../mwworld/actiontake.hpp" | ||||||
| 
 | 
 | ||||||
| #include <boost/lexical_cast.hpp> | #include "formatting.hpp" | ||||||
|  | #include "window_manager.hpp" | ||||||
| 
 | 
 | ||||||
| using namespace MWGui; | using namespace MWGui; | ||||||
| 
 | 
 | ||||||
|  | @ -91,7 +92,7 @@ void BookWindow::onCloseButtonClicked (MyGUI::Widget* _sender) | ||||||
|     // no 3d sounds because the object could be in a container.
 |     // no 3d sounds because the object could be in a container.
 | ||||||
|     MWBase::Environment::get().getSoundManager()->playSound ("book close", 1.0, 1.0); |     MWBase::Environment::get().getSoundManager()->playSound ("book close", 1.0, 1.0); | ||||||
| 
 | 
 | ||||||
|     MWBase::Environment::get().getInputManager()->setGuiMode(MWGui::GM_Game); |     mWindowManager.popGuiMode(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void BookWindow::onTakeButtonClicked (MyGUI::Widget* _sender) | void BookWindow::onTakeButtonClicked (MyGUI::Widget* _sender) | ||||||
|  | @ -101,7 +102,7 @@ void BookWindow::onTakeButtonClicked (MyGUI::Widget* _sender) | ||||||
|     MWWorld::ActionTake take(mBook); |     MWWorld::ActionTake take(mBook); | ||||||
|     take.execute(); |     take.execute(); | ||||||
| 
 | 
 | ||||||
|     MWBase::Environment::get().getInputManager()->setGuiMode (GM_Game); |     mWindowManager.popGuiMode(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void BookWindow::onNextPageButtonClicked (MyGUI::Widget* _sender) | void BookWindow::onNextPageButtonClicked (MyGUI::Widget* _sender) | ||||||
|  |  | ||||||
|  | @ -110,7 +110,6 @@ using namespace MWGui; | ||||||
| CharacterCreation::CharacterCreation(WindowManager* _wm) | CharacterCreation::CharacterCreation(WindowManager* _wm) | ||||||
|     : mNameDialog(0) |     : mNameDialog(0) | ||||||
|     , mRaceDialog(0) |     , mRaceDialog(0) | ||||||
|     , mDialogueWindow(0) |  | ||||||
|     , mClassChoiceDialog(0) |     , mClassChoiceDialog(0) | ||||||
|     , mGenerateClassQuestionDialog(0) |     , mGenerateClassQuestionDialog(0) | ||||||
|     , mGenerateClassResultDialog(0) |     , mGenerateClassResultDialog(0) | ||||||
|  | @ -118,11 +117,62 @@ CharacterCreation::CharacterCreation(WindowManager* _wm) | ||||||
|     , mCreateClassDialog(0) |     , mCreateClassDialog(0) | ||||||
|     , mBirthSignDialog(0) |     , mBirthSignDialog(0) | ||||||
|     , mReviewDialog(0) |     , mReviewDialog(0) | ||||||
|  |     , mGenerateClassStep(0) | ||||||
|     , mWM(_wm) |     , mWM(_wm) | ||||||
| { | { | ||||||
|     mCreationStage = CSE_NotStarted; |     mCreationStage = CSE_NotStarted; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void CharacterCreation::setValue (const std::string& id, const MWMechanics::Stat<int>& value) | ||||||
|  | { | ||||||
|  |     if (mReviewDialog) | ||||||
|  |     { | ||||||
|  |        static const char *ids[] = | ||||||
|  |         { | ||||||
|  |             "AttribVal1", "AttribVal2", "AttribVal3", "AttribVal4", "AttribVal5", | ||||||
|  |             "AttribVal6", "AttribVal7", "AttribVal8", | ||||||
|  |             0 | ||||||
|  |         }; | ||||||
|  | 
 | ||||||
|  |         for (int i=0; ids[i]; ++i) | ||||||
|  |         { | ||||||
|  |             if (ids[i]==id) | ||||||
|  |                 mReviewDialog->setAttribute(ESM::Attribute::AttributeID(i), value); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void CharacterCreation::setValue (const std::string& id, const MWMechanics::DynamicStat<int>& value) | ||||||
|  | { | ||||||
|  |     if (mReviewDialog) | ||||||
|  |     { | ||||||
|  |         if (id == "HBar") | ||||||
|  |         { | ||||||
|  |             mReviewDialog->setHealth (value); | ||||||
|  |         } | ||||||
|  |         else if (id == "MBar") | ||||||
|  |         { | ||||||
|  |             mReviewDialog->setMagicka (value); | ||||||
|  |         } | ||||||
|  |         else if (id == "FBar") | ||||||
|  |         { | ||||||
|  |             mReviewDialog->setFatigue (value); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void CharacterCreation::setValue(const ESM::Skill::SkillEnum parSkill, const MWMechanics::Stat<float>& value) | ||||||
|  | { | ||||||
|  |     if (mReviewDialog) | ||||||
|  |         mReviewDialog->setSkillValue(parSkill, value); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void CharacterCreation::configureSkills (const SkillList& major, const SkillList& minor) | ||||||
|  | { | ||||||
|  |     if (mReviewDialog) | ||||||
|  |         mReviewDialog->configureSkills(major, minor); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void CharacterCreation::spawnDialog(const char id) | void CharacterCreation::spawnDialog(const char id) | ||||||
| { | { | ||||||
|     switch (id) |     switch (id) | ||||||
|  | @ -209,20 +259,22 @@ void CharacterCreation::spawnDialog(const char id) | ||||||
|             mReviewDialog->setFatigue(mPlayerFatigue); |             mReviewDialog->setFatigue(mPlayerFatigue); | ||||||
| 
 | 
 | ||||||
|             { |             { | ||||||
|                 std::map<ESM::Attribute::AttributeID, MWMechanics::Stat<int> >::iterator end = mPlayerAttributes.end(); |                 std::map<ESM::Attribute::AttributeID, MWMechanics::Stat<int> > attributes = mWM->getPlayerAttributeValues(); | ||||||
|                 for (std::map<ESM::Attribute::AttributeID, MWMechanics::Stat<int> >::iterator it = mPlayerAttributes.begin(); it != end; ++it) |                 for (std::map<ESM::Attribute::AttributeID, MWMechanics::Stat<int> >::iterator it = attributes.begin(); | ||||||
|  |                     it != attributes.end(); ++it) | ||||||
|                 { |                 { | ||||||
|                     mReviewDialog->setAttribute(it->first, it->second); |                     mReviewDialog->setAttribute(it->first, it->second); | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             { |             { | ||||||
|                 std::map<ESM::Skill::SkillEnum, MWMechanics::Stat<float> >::iterator end = mPlayerSkillValues.end(); |                 std::map<ESM::Skill::SkillEnum, MWMechanics::Stat<float> > skills = mWM->getPlayerSkillValues(); | ||||||
|                 for (std::map<ESM::Skill::SkillEnum, MWMechanics::Stat<float> >::iterator it = mPlayerSkillValues.begin(); it != end; ++it) |                 for (std::map<ESM::Skill::SkillEnum, MWMechanics::Stat<float> >::iterator it = skills.begin(); | ||||||
|  |                     it != skills.end(); ++it) | ||||||
|                 { |                 { | ||||||
|                     mReviewDialog->setSkillValue(it->first, it->second); |                     mReviewDialog->setSkillValue(it->first, it->second); | ||||||
|                 } |                 } | ||||||
|                 mReviewDialog->configureSkills(mPlayerMajorSkills, mPlayerMinorSkills); |                 mReviewDialog->configureSkills(mWM->getPlayerMajorSkills(), mWM->getPlayerMinorSkills()); | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             mReviewDialog->eventDone += MyGUI::newDelegate(this, &CharacterCreation::onReviewDialogDone); |             mReviewDialog->eventDone += MyGUI::newDelegate(this, &CharacterCreation::onReviewDialogDone); | ||||||
|  | @ -253,7 +305,7 @@ void CharacterCreation::onReviewDialogDone(WindowBase* parWindow) | ||||||
|     if (mReviewDialog) |     if (mReviewDialog) | ||||||
|         mWM->removeDialog(mReviewDialog); |         mWM->removeDialog(mReviewDialog); | ||||||
| 
 | 
 | ||||||
|     mWM->setGuiMode(GM_Game); |     mWM->popGuiMode(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void CharacterCreation::onReviewDialogBack() | void CharacterCreation::onReviewDialogBack() | ||||||
|  | @ -261,7 +313,7 @@ void CharacterCreation::onReviewDialogBack() | ||||||
|     if (mReviewDialog) |     if (mReviewDialog) | ||||||
|         mWM->removeDialog(mReviewDialog); |         mWM->removeDialog(mReviewDialog); | ||||||
| 
 | 
 | ||||||
|     mWM->setGuiMode(GM_Birth); |     mWM->pushGuiMode(GM_Birth); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void CharacterCreation::onReviewActivateDialog(int parDialog) | void CharacterCreation::onReviewActivateDialog(int parDialog) | ||||||
|  | @ -270,19 +322,21 @@ void CharacterCreation::onReviewActivateDialog(int parDialog) | ||||||
|         mWM->removeDialog(mReviewDialog); |         mWM->removeDialog(mReviewDialog); | ||||||
|     mCreationStage = CSE_ReviewNext; |     mCreationStage = CSE_ReviewNext; | ||||||
| 
 | 
 | ||||||
|  |     mWM->popGuiMode(); | ||||||
|  | 
 | ||||||
|     switch(parDialog) |     switch(parDialog) | ||||||
|     { |     { | ||||||
|         case ReviewDialog::NAME_DIALOG: |         case ReviewDialog::NAME_DIALOG: | ||||||
|             mWM->setGuiMode(GM_Name); |             mWM->pushGuiMode(GM_Name); | ||||||
|             break; |             break; | ||||||
|         case ReviewDialog::RACE_DIALOG: |         case ReviewDialog::RACE_DIALOG: | ||||||
|             mWM->setGuiMode(GM_Race); |             mWM->pushGuiMode(GM_Race); | ||||||
|             break; |             break; | ||||||
|         case ReviewDialog::CLASS_DIALOG: |         case ReviewDialog::CLASS_DIALOG: | ||||||
|             mWM->setGuiMode(GM_Class); |             mWM->pushGuiMode(GM_Class); | ||||||
|             break; |             break; | ||||||
|         case ReviewDialog::BIRTHSIGN_DIALOG: |         case ReviewDialog::BIRTHSIGN_DIALOG: | ||||||
|             mWM->setGuiMode(GM_Birth); |             mWM->pushGuiMode(GM_Birth); | ||||||
|     }; |     }; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -304,13 +358,19 @@ void CharacterCreation::onPickClassDialogDone(WindowBase* parWindow) | ||||||
| 
 | 
 | ||||||
|     //TODO This bit gets repeated a few times; wrap it in a function
 |     //TODO This bit gets repeated a few times; wrap it in a function
 | ||||||
|     if (mCreationStage == CSE_ReviewNext) |     if (mCreationStage == CSE_ReviewNext) | ||||||
|         mWM->setGuiMode(GM_Review); |     { | ||||||
|  |         mWM->popGuiMode(); | ||||||
|  |         mWM->pushGuiMode(GM_Review); | ||||||
|  |     } | ||||||
|     else if (mCreationStage >= CSE_ClassChosen) |     else if (mCreationStage >= CSE_ClassChosen) | ||||||
|         mWM->setGuiMode(GM_Birth); |     { | ||||||
|  |         mWM->popGuiMode(); | ||||||
|  |         mWM->pushGuiMode(GM_Birth); | ||||||
|  |     } | ||||||
|     else |     else | ||||||
|     { |     { | ||||||
|         mCreationStage = CSE_ClassChosen; |         mCreationStage = CSE_ClassChosen; | ||||||
|         mWM->setGuiMode(GM_Game); |         mWM->popGuiMode(); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -324,7 +384,8 @@ void CharacterCreation::onPickClassDialogBack() | ||||||
|         mWM->removeDialog(mPickClassDialog); |         mWM->removeDialog(mPickClassDialog); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     mWM->setGuiMode(GM_Class); |     mWM->popGuiMode(); | ||||||
|  |     mWM->pushGuiMode(GM_Class); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void CharacterCreation::onClassChoice(int _index) | void CharacterCreation::onClassChoice(int _index) | ||||||
|  | @ -334,19 +395,21 @@ void CharacterCreation::onClassChoice(int _index) | ||||||
|         mWM->removeDialog(mClassChoiceDialog); |         mWM->removeDialog(mClassChoiceDialog); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     mWM->popGuiMode(); | ||||||
|  | 
 | ||||||
|     switch(_index) |     switch(_index) | ||||||
|     { |     { | ||||||
|         case ClassChoiceDialog::Class_Generate: |         case ClassChoiceDialog::Class_Generate: | ||||||
|             mWM->setGuiMode(GM_ClassGenerate); |             mWM->pushGuiMode(GM_ClassGenerate); | ||||||
|             break; |             break; | ||||||
|         case ClassChoiceDialog::Class_Pick: |         case ClassChoiceDialog::Class_Pick: | ||||||
|             mWM->setGuiMode(GM_ClassPick); |             mWM->pushGuiMode(GM_ClassPick); | ||||||
|             break; |             break; | ||||||
|         case ClassChoiceDialog::Class_Create: |         case ClassChoiceDialog::Class_Create: | ||||||
|             mWM->setGuiMode(GM_ClassCreate); |             mWM->pushGuiMode(GM_ClassCreate); | ||||||
|             break; |             break; | ||||||
|         case ClassChoiceDialog::Class_Back: |         case ClassChoiceDialog::Class_Back: | ||||||
|             mWM->setGuiMode(GM_Race); |             mWM->pushGuiMode(GM_Race); | ||||||
|             break; |             break; | ||||||
| 
 | 
 | ||||||
|     }; |     }; | ||||||
|  | @ -363,13 +426,19 @@ void CharacterCreation::onNameDialogDone(WindowBase* parWindow) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (mCreationStage == CSE_ReviewNext) |     if (mCreationStage == CSE_ReviewNext) | ||||||
|         mWM->setGuiMode(GM_Review); |     { | ||||||
|  |         mWM->popGuiMode(); | ||||||
|  |         mWM->pushGuiMode(GM_Review); | ||||||
|  |     } | ||||||
|     else if (mCreationStage >= CSE_NameChosen) |     else if (mCreationStage >= CSE_NameChosen) | ||||||
|         mWM->setGuiMode(GM_Race); |     { | ||||||
|  |         mWM->popGuiMode(); | ||||||
|  |         mWM->pushGuiMode(GM_Race); | ||||||
|  |     } | ||||||
|     else |     else | ||||||
|     { |     { | ||||||
|         mCreationStage = CSE_NameChosen; |         mCreationStage = CSE_NameChosen; | ||||||
|         mWM->setGuiMode(GM_Game); |         mWM->popGuiMode(); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -383,7 +452,8 @@ void CharacterCreation::onRaceDialogBack() | ||||||
|         mWM->removeDialog(mRaceDialog); |         mWM->removeDialog(mRaceDialog); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     mWM->setGuiMode(GM_Name); |     mWM->popGuiMode(); | ||||||
|  |     mWM->pushGuiMode(GM_Name); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void CharacterCreation::onRaceDialogDone(WindowBase* parWindow) | void CharacterCreation::onRaceDialogDone(WindowBase* parWindow) | ||||||
|  | @ -398,13 +468,19 @@ void CharacterCreation::onRaceDialogDone(WindowBase* parWindow) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (mCreationStage == CSE_ReviewNext) |     if (mCreationStage == CSE_ReviewNext) | ||||||
|         mWM->setGuiMode(GM_Review); |     { | ||||||
|     else if(mCreationStage >= CSE_RaceChosen) |         mWM->popGuiMode(); | ||||||
|         mWM->setGuiMode(GM_Class); |         mWM->pushGuiMode(GM_Review); | ||||||
|  |     } | ||||||
|  |     else if (mCreationStage >= CSE_RaceChosen) | ||||||
|  |     { | ||||||
|  |         mWM->popGuiMode(); | ||||||
|  |         mWM->pushGuiMode(GM_Class); | ||||||
|  |     } | ||||||
|     else |     else | ||||||
|     { |     { | ||||||
|         mCreationStage = CSE_RaceChosen; |         mCreationStage = CSE_RaceChosen; | ||||||
|         mWM->setGuiMode(GM_Game); |         mWM->popGuiMode(); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -419,11 +495,14 @@ void CharacterCreation::onBirthSignDialogDone(WindowBase* parWindow) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (mCreationStage >= CSE_BirthSignChosen) |     if (mCreationStage >= CSE_BirthSignChosen) | ||||||
|         mWM->setGuiMode(GM_Review); |     { | ||||||
|  |         mWM->popGuiMode(); | ||||||
|  |         mWM->pushGuiMode(GM_Review); | ||||||
|  |     } | ||||||
|     else |     else | ||||||
|     { |     { | ||||||
|         mCreationStage = CSE_BirthSignChosen; |         mCreationStage = CSE_BirthSignChosen; | ||||||
|         mWM->setGuiMode(GM_Game); |         mWM->popGuiMode(); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -435,7 +514,8 @@ void CharacterCreation::onBirthSignDialogBack() | ||||||
|         mWM->removeDialog(mBirthSignDialog); |         mWM->removeDialog(mBirthSignDialog); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     mWM->setGuiMode(GM_Class); |     mWM->popGuiMode(); | ||||||
|  |     mWM->pushGuiMode(GM_Class); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void CharacterCreation::onCreateClassDialogDone(WindowBase* parWindow) | void CharacterCreation::onCreateClassDialogDone(WindowBase* parWindow) | ||||||
|  | @ -470,13 +550,19 @@ void CharacterCreation::onCreateClassDialogDone(WindowBase* parWindow) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (mCreationStage == CSE_ReviewNext) |     if (mCreationStage == CSE_ReviewNext) | ||||||
|         mWM->setGuiMode(GM_Review); |     { | ||||||
|  |         mWM->popGuiMode(); | ||||||
|  |         mWM->pushGuiMode(GM_Review); | ||||||
|  |     } | ||||||
|     else if (mCreationStage >= CSE_ClassChosen) |     else if (mCreationStage >= CSE_ClassChosen) | ||||||
|         mWM->setGuiMode(GM_Birth); |     { | ||||||
|  |         mWM->popGuiMode(); | ||||||
|  |         mWM->pushGuiMode(GM_Birth); | ||||||
|  |     } | ||||||
|     else |     else | ||||||
|     { |     { | ||||||
|         mCreationStage = CSE_ClassChosen; |         mCreationStage = CSE_ClassChosen; | ||||||
|         mWM->setGuiMode(GM_Game); |         mWM->popGuiMode(); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -485,7 +571,8 @@ void CharacterCreation::onCreateClassDialogBack() | ||||||
|     if (mCreateClassDialog) |     if (mCreateClassDialog) | ||||||
|         mWM->removeDialog(mCreateClassDialog); |         mWM->removeDialog(mCreateClassDialog); | ||||||
| 
 | 
 | ||||||
|     mWM->setGuiMode(GM_Class); |     mWM->popGuiMode(); | ||||||
|  |     mWM->pushGuiMode(GM_Class); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void CharacterCreation::onClassQuestionChosen(int _index) | void CharacterCreation::onClassQuestionChosen(int _index) | ||||||
|  | @ -496,7 +583,8 @@ void CharacterCreation::onClassQuestionChosen(int _index) | ||||||
|         mWM->removeDialog(mGenerateClassQuestionDialog); |         mWM->removeDialog(mGenerateClassQuestionDialog); | ||||||
|     if (_index < 0 || _index >= 3) |     if (_index < 0 || _index >= 3) | ||||||
|     { |     { | ||||||
|         mWM->setGuiMode(GM_Class); |         mWM->popGuiMode(); | ||||||
|  |         mWM->pushGuiMode(GM_Class); | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -581,7 +669,8 @@ void CharacterCreation::showClassQuestionDialog() | ||||||
| 
 | 
 | ||||||
|     if (mGenerateClassStep > sGenerateClassSteps.size()) |     if (mGenerateClassStep > sGenerateClassSteps.size()) | ||||||
|     { |     { | ||||||
|         mWM->setGuiMode(GM_Class); |         mWM->popGuiMode(); | ||||||
|  |         mWM->pushGuiMode(GM_Class); | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -610,7 +699,8 @@ void CharacterCreation::onGenerateClassBack() | ||||||
|         mWM->removeDialog(mGenerateClassResultDialog); |         mWM->removeDialog(mGenerateClassResultDialog); | ||||||
|     MWBase::Environment::get().getMechanicsManager()->setPlayerClass(mGenerateClass); |     MWBase::Environment::get().getMechanicsManager()->setPlayerClass(mGenerateClass); | ||||||
| 
 | 
 | ||||||
|     mWM->setGuiMode(GM_Class); |     mWM->popGuiMode(); | ||||||
|  |     mWM->pushGuiMode(GM_Class); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void CharacterCreation::onGenerateClassDone(WindowBase* parWindow) | void CharacterCreation::onGenerateClassDone(WindowBase* parWindow) | ||||||
|  | @ -620,13 +710,19 @@ void CharacterCreation::onGenerateClassDone(WindowBase* parWindow) | ||||||
|     MWBase::Environment::get().getMechanicsManager()->setPlayerClass(mGenerateClass); |     MWBase::Environment::get().getMechanicsManager()->setPlayerClass(mGenerateClass); | ||||||
| 
 | 
 | ||||||
|     if (mCreationStage == CSE_ReviewNext) |     if (mCreationStage == CSE_ReviewNext) | ||||||
|         mWM->setGuiMode(GM_Review); |     { | ||||||
|  |         mWM->popGuiMode(); | ||||||
|  |         mWM->pushGuiMode(GM_Review); | ||||||
|  |     } | ||||||
|     else if (mCreationStage >= CSE_ClassChosen) |     else if (mCreationStage >= CSE_ClassChosen) | ||||||
|         mWM->setGuiMode(GM_Birth); |     { | ||||||
|  |         mWM->popGuiMode(); | ||||||
|  |         mWM->pushGuiMode(GM_Birth); | ||||||
|  |     } | ||||||
|     else |     else | ||||||
|     { |     { | ||||||
|         mCreationStage = CSE_ClassChosen; |         mCreationStage = CSE_ClassChosen; | ||||||
|         mWM->setGuiMode(GM_Game); |         mWM->popGuiMode(); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -634,7 +730,6 @@ CharacterCreation::~CharacterCreation() | ||||||
| { | { | ||||||
|     delete mNameDialog; |     delete mNameDialog; | ||||||
|     delete mRaceDialog; |     delete mRaceDialog; | ||||||
|     delete mDialogueWindow; |  | ||||||
|     delete mClassChoiceDialog; |     delete mClassChoiceDialog; | ||||||
|     delete mGenerateClassQuestionDialog; |     delete mGenerateClassQuestionDialog; | ||||||
|     delete mGenerateClassResultDialog; |     delete mGenerateClassResultDialog; | ||||||
|  |  | ||||||
|  | @ -42,11 +42,15 @@ namespace MWGui | ||||||
| 
 | 
 | ||||||
|     void setPlayerFatigue (const MWMechanics::DynamicStat<int>& value); |     void setPlayerFatigue (const MWMechanics::DynamicStat<int>& value); | ||||||
| 
 | 
 | ||||||
|  |     void setValue (const std::string& id, const MWMechanics::Stat<int>& value); | ||||||
|  |     void setValue (const std::string& id, const MWMechanics::DynamicStat<int>& value); | ||||||
|  |     void setValue(const ESM::Skill::SkillEnum parSkill, const MWMechanics::Stat<float>& value); | ||||||
|  |     void configureSkills (const SkillList& major, const SkillList& minor); | ||||||
|  | 
 | ||||||
|     private: |     private: | ||||||
|     //Dialogs
 |     //Dialogs
 | ||||||
|     TextInputDialog* mNameDialog; |     TextInputDialog* mNameDialog; | ||||||
|     RaceDialog* mRaceDialog; |     RaceDialog* mRaceDialog; | ||||||
|     DialogueWindow* mDialogueWindow; |  | ||||||
|     ClassChoiceDialog* mClassChoiceDialog; |     ClassChoiceDialog* mClassChoiceDialog; | ||||||
|     InfoBoxDialog* mGenerateClassQuestionDialog; |     InfoBoxDialog* mGenerateClassQuestionDialog; | ||||||
|     GenerateClassResultDialog* mGenerateClassResultDialog; |     GenerateClassResultDialog* mGenerateClassResultDialog; | ||||||
|  | @ -62,9 +66,6 @@ namespace MWGui | ||||||
|     std::string mPlayerRaceId; |     std::string mPlayerRaceId; | ||||||
|     std::string mPlayerBirthSignId; |     std::string mPlayerBirthSignId; | ||||||
|     ESM::Class mPlayerClass; |     ESM::Class mPlayerClass; | ||||||
|     std::map<ESM::Attribute::AttributeID, MWMechanics::Stat<int> > mPlayerAttributes; |  | ||||||
|     SkillList mPlayerMajorSkills, mPlayerMinorSkills; |  | ||||||
|     std::map<ESM::Skill::SkillEnum, MWMechanics::Stat<float> > mPlayerSkillValues; |  | ||||||
|     MWMechanics::DynamicStat<int> mPlayerHealth; |     MWMechanics::DynamicStat<int> mPlayerHealth; | ||||||
|     MWMechanics::DynamicStat<int> mPlayerMagicka; |     MWMechanics::DynamicStat<int> mPlayerMagicka; | ||||||
|     MWMechanics::DynamicStat<int> mPlayerFatigue; |     MWMechanics::DynamicStat<int> mPlayerFatigue; | ||||||
|  |  | ||||||
|  | @ -1,6 +1,4 @@ | ||||||
| #include "class.hpp" | #include "class.hpp" | ||||||
| #include "window_manager.hpp" |  | ||||||
| #include "components/esm_store/store.hpp" |  | ||||||
| 
 | 
 | ||||||
| #include <assert.h> | #include <assert.h> | ||||||
| #include <iterator> | #include <iterator> | ||||||
|  | @ -8,6 +6,11 @@ | ||||||
| #include <boost/algorithm/string.hpp> | #include <boost/algorithm/string.hpp> | ||||||
| #include <boost/lexical_cast.hpp> | #include <boost/lexical_cast.hpp> | ||||||
| 
 | 
 | ||||||
|  | #include <components/esm_store/store.hpp> | ||||||
|  | 
 | ||||||
|  | #include "window_manager.hpp" | ||||||
|  | #include "tooltips.hpp" | ||||||
|  | 
 | ||||||
| #undef min | #undef min | ||||||
| #undef max | #undef max | ||||||
| 
 | 
 | ||||||
|  | @ -79,17 +82,13 @@ PickClassDialog::PickClassDialog(WindowManager& parWindowManager) | ||||||
|     // Centre dialog
 |     // Centre dialog
 | ||||||
|     center(); |     center(); | ||||||
| 
 | 
 | ||||||
|     setText("SpecializationT", mWindowManager.getGameSettingString("sChooseClassMenu1", "Specialization")); |  | ||||||
|     getWidget(specializationName, "SpecializationName"); |     getWidget(specializationName, "SpecializationName"); | ||||||
| 
 | 
 | ||||||
|     setText("FavoriteAttributesT", mWindowManager.getGameSettingString("sChooseClassMenu2", "Favorite Attributes:")); |  | ||||||
|     getWidget(favoriteAttribute[0], "FavoriteAttribute0"); |     getWidget(favoriteAttribute[0], "FavoriteAttribute0"); | ||||||
|     getWidget(favoriteAttribute[1], "FavoriteAttribute1"); |     getWidget(favoriteAttribute[1], "FavoriteAttribute1"); | ||||||
|     favoriteAttribute[0]->setWindowManager(&mWindowManager); |     favoriteAttribute[0]->setWindowManager(&mWindowManager); | ||||||
|     favoriteAttribute[1]->setWindowManager(&mWindowManager); |     favoriteAttribute[1]->setWindowManager(&mWindowManager); | ||||||
| 
 | 
 | ||||||
|     setText("MajorSkillT", mWindowManager.getGameSettingString("sChooseClassMenu3", "Major Skills:")); |  | ||||||
|     setText("MinorSkillT", mWindowManager.getGameSettingString("sChooseClassMenu4", "Minor Skills:")); |  | ||||||
|     for(int i = 0; i < 5; i++) |     for(int i = 0; i < 5; i++) | ||||||
|     { |     { | ||||||
|         char theIndex = '0'+i; |         char theIndex = '0'+i; | ||||||
|  | @ -231,15 +230,21 @@ void PickClassDialog::updateStats() | ||||||
|         "sSpecializationMagic", |         "sSpecializationMagic", | ||||||
|         "sSpecializationStealth" |         "sSpecializationStealth" | ||||||
|     }; |     }; | ||||||
|     specializationName->setCaption(mWindowManager.getGameSettingString(specIds[specialization], specIds[specialization])); |     std::string specName = mWindowManager.getGameSettingString(specIds[specialization], specIds[specialization]); | ||||||
|  |     specializationName->setCaption(specName); | ||||||
|  |     ToolTips::createSpecializationToolTip(specializationName, specName, specialization); | ||||||
| 
 | 
 | ||||||
|     favoriteAttribute[0]->setAttributeId(klass->data.attribute[0]); |     favoriteAttribute[0]->setAttributeId(klass->data.attribute[0]); | ||||||
|     favoriteAttribute[1]->setAttributeId(klass->data.attribute[1]); |     favoriteAttribute[1]->setAttributeId(klass->data.attribute[1]); | ||||||
|  |     ToolTips::createAttributeToolTip(favoriteAttribute[0], favoriteAttribute[0]->getAttributeId()); | ||||||
|  |     ToolTips::createAttributeToolTip(favoriteAttribute[1], favoriteAttribute[1]->getAttributeId()); | ||||||
| 
 | 
 | ||||||
|     for (int i = 0; i < 5; ++i) |     for (int i = 0; i < 5; ++i) | ||||||
|     { |     { | ||||||
|         majorSkill[i]->setSkillNumber(klass->data.skills[i][0]); |         minorSkill[i]->setSkillNumber(klass->data.skills[i][0]); | ||||||
|         minorSkill[i]->setSkillNumber(klass->data.skills[i][1]); |         majorSkill[i]->setSkillNumber(klass->data.skills[i][1]); | ||||||
|  |         ToolTips::createSkillToolTip(minorSkill[i], klass->data.skills[i][0]); | ||||||
|  |         ToolTips::createSkillToolTip(majorSkill[i], klass->data.skills[i][1]); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     classImage->setImageTexture(std::string("textures\\levelup\\") + currentClassId + ".dds"); |     classImage->setImageTexture(std::string("textures\\levelup\\") + currentClassId + ".dds"); | ||||||
|  | @ -387,7 +392,6 @@ CreateClassDialog::CreateClassDialog(WindowManager& parWindowManager) | ||||||
| 
 | 
 | ||||||
|     setText("SpecializationT", mWindowManager.getGameSettingString("sChooseClassMenu1", "Specialization")); |     setText("SpecializationT", mWindowManager.getGameSettingString("sChooseClassMenu1", "Specialization")); | ||||||
|     getWidget(specializationName, "SpecializationName"); |     getWidget(specializationName, "SpecializationName"); | ||||||
|     specializationName->setCaption(mWindowManager.getGameSettingString(ESM::Class::gmstSpecializationIds[ESM::Class::Combat], "")); |  | ||||||
|     specializationName->eventMouseButtonClick += MyGUI::newDelegate(this, &CreateClassDialog::onSpecializationClicked); |     specializationName->eventMouseButtonClick += MyGUI::newDelegate(this, &CreateClassDialog::onSpecializationClicked); | ||||||
| 
 | 
 | ||||||
|     setText("FavoriteAttributesT", mWindowManager.getGameSettingString("sChooseClassMenu2", "Favorite Attributes:")); |     setText("FavoriteAttributesT", mWindowManager.getGameSettingString("sChooseClassMenu2", "Favorite Attributes:")); | ||||||
|  | @ -451,6 +455,9 @@ CreateClassDialog::CreateClassDialog(WindowManager& parWindowManager) | ||||||
|     minorSkill[2]->setSkillId(ESM::Skill::Spear); |     minorSkill[2]->setSkillId(ESM::Skill::Spear); | ||||||
|     minorSkill[3]->setSkillId(ESM::Skill::Athletics); |     minorSkill[3]->setSkillId(ESM::Skill::Athletics); | ||||||
|     minorSkill[4]->setSkillId(ESM::Skill::Enchant); |     minorSkill[4]->setSkillId(ESM::Skill::Enchant); | ||||||
|  | 
 | ||||||
|  |     setSpecialization(0); | ||||||
|  |     update(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| CreateClassDialog::~CreateClassDialog() | CreateClassDialog::~CreateClassDialog() | ||||||
|  | @ -461,6 +468,18 @@ CreateClassDialog::~CreateClassDialog() | ||||||
|     delete descDialog; |     delete descDialog; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void CreateClassDialog::update() | ||||||
|  | { | ||||||
|  |     for (int i = 0; i < 5; ++i) | ||||||
|  |     { | ||||||
|  |         ToolTips::createSkillToolTip(majorSkill[i], majorSkill[i]->getSkillId()); | ||||||
|  |         ToolTips::createSkillToolTip(minorSkill[i], minorSkill[i]->getSkillId()); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     ToolTips::createAttributeToolTip(favoriteAttribute0, favoriteAttribute0->getAttributeId()); | ||||||
|  |     ToolTips::createAttributeToolTip(favoriteAttribute1, favoriteAttribute1->getAttributeId()); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| std::string CreateClassDialog::getName() const | std::string CreateClassDialog::getName() const | ||||||
| { | { | ||||||
|     return editName->getOnlyText(); |     return editName->getOnlyText(); | ||||||
|  | @ -499,7 +518,7 @@ std::vector<ESM::Skill::SkillEnum> CreateClassDialog::getMinorSkills() const | ||||||
|     std::vector<ESM::Skill::SkillEnum> v; |     std::vector<ESM::Skill::SkillEnum> v; | ||||||
|     for(int i=0; i < 5; i++) |     for(int i=0; i < 5; i++) | ||||||
|     { |     { | ||||||
|         v.push_back(majorSkill[i]->getSkillId()); |         v.push_back(minorSkill[i]->getSkillId()); | ||||||
|     } |     } | ||||||
|     return v; |     return v; | ||||||
| } | } | ||||||
|  | @ -539,20 +558,30 @@ void CreateClassDialog::open() | ||||||
| void CreateClassDialog::onDialogCancel() | void CreateClassDialog::onDialogCancel() | ||||||
| { | { | ||||||
|     if (specDialog) |     if (specDialog) | ||||||
|         specDialog->setVisible(false); |     { | ||||||
|  |         mWindowManager.removeDialog(specDialog); | ||||||
|  |         specDialog = 0; | ||||||
|  |     } | ||||||
|     if (attribDialog) |     if (attribDialog) | ||||||
|         attribDialog->setVisible(false); |     { | ||||||
|  |         mWindowManager.removeDialog(attribDialog); | ||||||
|  |         attribDialog = 0; | ||||||
|  |     } | ||||||
|     if (skillDialog) |     if (skillDialog) | ||||||
|         skillDialog->setVisible(false); |     { | ||||||
|  |         mWindowManager.removeDialog(skillDialog); | ||||||
|  |         skillDialog = 0; | ||||||
|  |     } | ||||||
|     if (descDialog) |     if (descDialog) | ||||||
|         descDialog->setVisible(false); |     { | ||||||
|     // TODO: Delete dialogs here
 |         mWindowManager.removeDialog(descDialog); | ||||||
|  |         descDialog = 0; | ||||||
|  |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void CreateClassDialog::onSpecializationClicked(MyGUI::WidgetPtr _sender) | void CreateClassDialog::onSpecializationClicked(MyGUI::WidgetPtr _sender) | ||||||
| { | { | ||||||
|     if (specDialog) |     delete specDialog; | ||||||
|         delete specDialog; |  | ||||||
|     specDialog = new SelectSpecializationDialog(mWindowManager); |     specDialog = new SelectSpecializationDialog(mWindowManager); | ||||||
|     specDialog->eventCancel += MyGUI::newDelegate(this, &CreateClassDialog::onDialogCancel); |     specDialog->eventCancel += MyGUI::newDelegate(this, &CreateClassDialog::onDialogCancel); | ||||||
|     specDialog->eventItemSelected += MyGUI::newDelegate(this, &CreateClassDialog::onSpecializationSelected); |     specDialog->eventItemSelected += MyGUI::newDelegate(this, &CreateClassDialog::onSpecializationSelected); | ||||||
|  | @ -562,14 +591,28 @@ void CreateClassDialog::onSpecializationClicked(MyGUI::WidgetPtr _sender) | ||||||
| void CreateClassDialog::onSpecializationSelected() | void CreateClassDialog::onSpecializationSelected() | ||||||
| { | { | ||||||
|     specializationId = specDialog->getSpecializationId(); |     specializationId = specDialog->getSpecializationId(); | ||||||
|     specializationName->setCaption(mWindowManager.getGameSettingString(ESM::Class::gmstSpecializationIds[specializationId], "")); |     setSpecialization(specializationId); | ||||||
|     specDialog->setVisible(false); | 
 | ||||||
|  |     mWindowManager.removeDialog(specDialog); | ||||||
|  |     specDialog = 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void CreateClassDialog::setSpecialization(int id) | ||||||
|  | { | ||||||
|  |     specializationId = (ESM::Class::Specialization) id; | ||||||
|  |     static const char *specIds[3] = { | ||||||
|  |         "sSpecializationCombat", | ||||||
|  |         "sSpecializationMagic", | ||||||
|  |         "sSpecializationStealth" | ||||||
|  |     }; | ||||||
|  |     std::string specName = mWindowManager.getGameSettingString(specIds[specializationId], specIds[specializationId]); | ||||||
|  |     specializationName->setCaption(specName); | ||||||
|  |     ToolTips::createSpecializationToolTip(specializationName, specName, specializationId); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void CreateClassDialog::onAttributeClicked(Widgets::MWAttributePtr _sender) | void CreateClassDialog::onAttributeClicked(Widgets::MWAttributePtr _sender) | ||||||
| { | { | ||||||
|     if (attribDialog) |     delete attribDialog; | ||||||
|         delete attribDialog; |  | ||||||
|     attribDialog = new SelectAttributeDialog(mWindowManager); |     attribDialog = new SelectAttributeDialog(mWindowManager); | ||||||
|     attribDialog->setAffectedWidget(_sender); |     attribDialog->setAffectedWidget(_sender); | ||||||
|     attribDialog->eventCancel += MyGUI::newDelegate(this, &CreateClassDialog::onDialogCancel); |     attribDialog->eventCancel += MyGUI::newDelegate(this, &CreateClassDialog::onDialogCancel); | ||||||
|  | @ -592,13 +635,15 @@ void CreateClassDialog::onAttributeSelected() | ||||||
|             favoriteAttribute0->setAttributeId(favoriteAttribute1->getAttributeId()); |             favoriteAttribute0->setAttributeId(favoriteAttribute1->getAttributeId()); | ||||||
|     } |     } | ||||||
|     attribute->setAttributeId(id); |     attribute->setAttributeId(id); | ||||||
|     attribDialog->setVisible(false); |     mWindowManager.removeDialog(attribDialog); | ||||||
|  |     attribDialog = 0; | ||||||
|  | 
 | ||||||
|  |     update(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void CreateClassDialog::onSkillClicked(Widgets::MWSkillPtr _sender) | void CreateClassDialog::onSkillClicked(Widgets::MWSkillPtr _sender) | ||||||
| { | { | ||||||
|     if (skillDialog) |     delete skillDialog; | ||||||
|         delete skillDialog; |  | ||||||
|     skillDialog = new SelectSkillDialog(mWindowManager); |     skillDialog = new SelectSkillDialog(mWindowManager); | ||||||
|     skillDialog->setAffectedWidget(_sender); |     skillDialog->setAffectedWidget(_sender); | ||||||
|     skillDialog->eventCancel += MyGUI::newDelegate(this, &CreateClassDialog::onDialogCancel); |     skillDialog->eventCancel += MyGUI::newDelegate(this, &CreateClassDialog::onDialogCancel); | ||||||
|  | @ -625,7 +670,9 @@ void CreateClassDialog::onSkillSelected() | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     skill->setSkillId(skillDialog->getSkillId()); |     skill->setSkillId(skillDialog->getSkillId()); | ||||||
|     skillDialog->setVisible(false); |     mWindowManager.removeDialog(skillDialog); | ||||||
|  |     skillDialog = 0; | ||||||
|  |     update(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void CreateClassDialog::onDescriptionClicked(MyGUI::Widget* _sender) | void CreateClassDialog::onDescriptionClicked(MyGUI::Widget* _sender) | ||||||
|  | @ -640,6 +687,7 @@ void CreateClassDialog::onDescriptionEntered(WindowBase* parWindow) | ||||||
| { | { | ||||||
|     description = descDialog->getTextInput(); |     description = descDialog->getTextInput(); | ||||||
|     mWindowManager.removeDialog(descDialog); |     mWindowManager.removeDialog(descDialog); | ||||||
|  |     descDialog = 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void CreateClassDialog::onOkClicked(MyGUI::Widget* _sender) | void CreateClassDialog::onOkClicked(MyGUI::Widget* _sender) | ||||||
|  | @ -665,20 +713,35 @@ SelectSpecializationDialog::SelectSpecializationDialog(WindowManager& parWindowM | ||||||
|     getWidget(specialization0, "Specialization0"); |     getWidget(specialization0, "Specialization0"); | ||||||
|     getWidget(specialization1, "Specialization1"); |     getWidget(specialization1, "Specialization1"); | ||||||
|     getWidget(specialization2, "Specialization2"); |     getWidget(specialization2, "Specialization2"); | ||||||
|     specialization0->setCaption(mWindowManager.getGameSettingString(ESM::Class::gmstSpecializationIds[ESM::Class::Combat], "")); |     std::string combat = mWindowManager.getGameSettingString(ESM::Class::gmstSpecializationIds[ESM::Class::Combat], ""); | ||||||
|  |     std::string magic = mWindowManager.getGameSettingString(ESM::Class::gmstSpecializationIds[ESM::Class::Magic], ""); | ||||||
|  |     std::string stealth = mWindowManager.getGameSettingString(ESM::Class::gmstSpecializationIds[ESM::Class::Stealth], ""); | ||||||
|  | 
 | ||||||
|  |     specialization0->setCaption(combat); | ||||||
|     specialization0->eventMouseButtonClick += MyGUI::newDelegate(this, &SelectSpecializationDialog::onSpecializationClicked); |     specialization0->eventMouseButtonClick += MyGUI::newDelegate(this, &SelectSpecializationDialog::onSpecializationClicked); | ||||||
|     specialization1->setCaption(mWindowManager.getGameSettingString(ESM::Class::gmstSpecializationIds[ESM::Class::Magic], "")); |     specialization1->setCaption(magic); | ||||||
|     specialization1->eventMouseButtonClick += MyGUI::newDelegate(this, &SelectSpecializationDialog::onSpecializationClicked); |     specialization1->eventMouseButtonClick += MyGUI::newDelegate(this, &SelectSpecializationDialog::onSpecializationClicked); | ||||||
|     specialization2->setCaption(mWindowManager.getGameSettingString(ESM::Class::gmstSpecializationIds[ESM::Class::Stealth], "")); |     specialization2->setCaption(stealth); | ||||||
|     specialization2->eventMouseButtonClick += MyGUI::newDelegate(this, &SelectSpecializationDialog::onSpecializationClicked); |     specialization2->eventMouseButtonClick += MyGUI::newDelegate(this, &SelectSpecializationDialog::onSpecializationClicked); | ||||||
|     specializationId = ESM::Class::Combat; |     specializationId = ESM::Class::Combat; | ||||||
| 
 | 
 | ||||||
|  |     ToolTips::createSpecializationToolTip(specialization0, combat, ESM::Class::Combat); | ||||||
|  |     ToolTips::createSpecializationToolTip(specialization1, magic, ESM::Class::Magic); | ||||||
|  |     ToolTips::createSpecializationToolTip(specialization2, stealth, ESM::Class::Stealth); | ||||||
|  | 
 | ||||||
|     MyGUI::ButtonPtr cancelButton; |     MyGUI::ButtonPtr cancelButton; | ||||||
|     getWidget(cancelButton, "CancelButton"); |     getWidget(cancelButton, "CancelButton"); | ||||||
|     cancelButton->setCaption(mWindowManager.getGameSettingString("sCancel", "")); |     cancelButton->setCaption(mWindowManager.getGameSettingString("sCancel", "")); | ||||||
|     cancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SelectSpecializationDialog::onCancelClicked); |     cancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SelectSpecializationDialog::onCancelClicked); | ||||||
|     int buttonWidth = cancelButton->getTextSize().width + 24; |     int buttonWidth = cancelButton->getTextSize().width + 24; | ||||||
|     cancelButton->setCoord(216 - buttonWidth, 90, buttonWidth, 21); |     cancelButton->setCoord(216 - buttonWidth, 90, buttonWidth, 21); | ||||||
|  | 
 | ||||||
|  |     MyGUI::InputManager::getInstance().addWidgetModal(mMainWidget); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | SelectSpecializationDialog::~SelectSpecializationDialog() | ||||||
|  | { | ||||||
|  |     MyGUI::InputManager::getInstance().removeWidgetModal(mMainWidget); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // widget controls
 | // widget controls
 | ||||||
|  | @ -721,6 +784,7 @@ SelectAttributeDialog::SelectAttributeDialog(WindowManager& parWindowManager) | ||||||
|         attribute->setWindowManager(&parWindowManager); |         attribute->setWindowManager(&parWindowManager); | ||||||
|         attribute->setAttributeId(ESM::Attribute::attributeIds[i]); |         attribute->setAttributeId(ESM::Attribute::attributeIds[i]); | ||||||
|         attribute->eventClicked += MyGUI::newDelegate(this, &SelectAttributeDialog::onAttributeClicked); |         attribute->eventClicked += MyGUI::newDelegate(this, &SelectAttributeDialog::onAttributeClicked); | ||||||
|  |         ToolTips::createAttributeToolTip(attribute, attribute->getAttributeId()); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     MyGUI::ButtonPtr cancelButton; |     MyGUI::ButtonPtr cancelButton; | ||||||
|  | @ -729,6 +793,13 @@ SelectAttributeDialog::SelectAttributeDialog(WindowManager& parWindowManager) | ||||||
|     cancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SelectAttributeDialog::onCancelClicked); |     cancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SelectAttributeDialog::onCancelClicked); | ||||||
|     int buttonWidth = cancelButton->getTextSize().width + 24; |     int buttonWidth = cancelButton->getTextSize().width + 24; | ||||||
|     cancelButton->setCoord(186 - buttonWidth, 180, buttonWidth, 21); |     cancelButton->setCoord(186 - buttonWidth, 180, buttonWidth, 21); | ||||||
|  | 
 | ||||||
|  |     MyGUI::InputManager::getInstance().addWidgetModal(mMainWidget); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | SelectAttributeDialog::~SelectAttributeDialog() | ||||||
|  | { | ||||||
|  |     MyGUI::InputManager::getInstance().removeWidgetModal(mMainWidget); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // widget controls
 | // widget controls
 | ||||||
|  | @ -810,6 +881,7 @@ SelectSkillDialog::SelectSkillDialog(WindowManager& parWindowManager) | ||||||
|             skills[spec][i].widget->setWindowManager(&mWindowManager); |             skills[spec][i].widget->setWindowManager(&mWindowManager); | ||||||
|             skills[spec][i].widget->setSkillId(skills[spec][i].skillId); |             skills[spec][i].widget->setSkillId(skills[spec][i].skillId); | ||||||
|             skills[spec][i].widget->eventClicked += MyGUI::newDelegate(this, &SelectSkillDialog::onSkillClicked); |             skills[spec][i].widget->eventClicked += MyGUI::newDelegate(this, &SelectSkillDialog::onSkillClicked); | ||||||
|  |             ToolTips::createSkillToolTip(skills[spec][i].widget, skills[spec][i].widget->getSkillId()); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -819,6 +891,13 @@ SelectSkillDialog::SelectSkillDialog(WindowManager& parWindowManager) | ||||||
|     cancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SelectSkillDialog::onCancelClicked); |     cancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SelectSkillDialog::onCancelClicked); | ||||||
|     int buttonWidth = cancelButton->getTextSize().width + 24; |     int buttonWidth = cancelButton->getTextSize().width + 24; | ||||||
|     cancelButton->setCoord(447 - buttonWidth, 218, buttonWidth, 21); |     cancelButton->setCoord(447 - buttonWidth, 218, buttonWidth, 21); | ||||||
|  | 
 | ||||||
|  |     MyGUI::InputManager::getInstance().addWidgetModal(mMainWidget); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | SelectSkillDialog::~SelectSkillDialog() | ||||||
|  | { | ||||||
|  |     MyGUI::InputManager::getInstance().removeWidgetModal(mMainWidget); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // widget controls
 | // widget controls
 | ||||||
|  | @ -853,6 +932,13 @@ DescriptionDialog::DescriptionDialog(WindowManager& parWindowManager) | ||||||
| 
 | 
 | ||||||
|     // Make sure the edit box has focus
 |     // Make sure the edit box has focus
 | ||||||
|     MyGUI::InputManager::getInstance().setKeyFocusWidget(textEdit); |     MyGUI::InputManager::getInstance().setKeyFocusWidget(textEdit); | ||||||
|  | 
 | ||||||
|  |     MyGUI::InputManager::getInstance().addWidgetModal(mMainWidget); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | DescriptionDialog::~DescriptionDialog() | ||||||
|  | { | ||||||
|  |     MyGUI::InputManager::getInstance().removeWidgetModal(mMainWidget); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // widget controls
 | // widget controls
 | ||||||
|  |  | ||||||
|  | @ -139,6 +139,7 @@ namespace MWGui | ||||||
|     { |     { | ||||||
|     public: |     public: | ||||||
|         SelectSpecializationDialog(WindowManager& parWindowManager); |         SelectSpecializationDialog(WindowManager& parWindowManager); | ||||||
|  |         ~SelectSpecializationDialog(); | ||||||
| 
 | 
 | ||||||
|         ESM::Class::Specialization getSpecializationId() const { return specializationId; } |         ESM::Class::Specialization getSpecializationId() const { return specializationId; } | ||||||
| 
 | 
 | ||||||
|  | @ -169,6 +170,7 @@ namespace MWGui | ||||||
|     { |     { | ||||||
|     public: |     public: | ||||||
|         SelectAttributeDialog(WindowManager& parWindowManager); |         SelectAttributeDialog(WindowManager& parWindowManager); | ||||||
|  |         ~SelectAttributeDialog(); | ||||||
| 
 | 
 | ||||||
|         ESM::Attribute::AttributeID getAttributeId() const { return attributeId; } |         ESM::Attribute::AttributeID getAttributeId() const { return attributeId; } | ||||||
|         Widgets::MWAttributePtr getAffectedWidget() const { return affectedWidget; } |         Widgets::MWAttributePtr getAffectedWidget() const { return affectedWidget; } | ||||||
|  | @ -201,6 +203,7 @@ namespace MWGui | ||||||
|     { |     { | ||||||
|     public: |     public: | ||||||
|         SelectSkillDialog(WindowManager& parWindowManager); |         SelectSkillDialog(WindowManager& parWindowManager); | ||||||
|  |         ~SelectSkillDialog(); | ||||||
| 
 | 
 | ||||||
|         ESM::Skill::SkillEnum getSkillId() const { return skillId; } |         ESM::Skill::SkillEnum getSkillId() const { return skillId; } | ||||||
|         Widgets::MWSkillPtr getAffectedWidget() const { return affectedWidget; } |         Widgets::MWSkillPtr getAffectedWidget() const { return affectedWidget; } | ||||||
|  | @ -236,6 +239,7 @@ namespace MWGui | ||||||
|     { |     { | ||||||
|     public: |     public: | ||||||
|         DescriptionDialog(WindowManager& parWindowManager); |         DescriptionDialog(WindowManager& parWindowManager); | ||||||
|  |         ~DescriptionDialog(); | ||||||
| 
 | 
 | ||||||
|         std::string getTextInput() const { return textEdit ? textEdit->getOnlyText() : ""; } |         std::string getTextInput() const { return textEdit ? textEdit->getOnlyText() : ""; } | ||||||
|         void setTextInput(const std::string &text) { if (textEdit) textEdit->setOnlyText(text); } |         void setTextInput(const std::string &text) { if (textEdit) textEdit->setOnlyText(text); } | ||||||
|  | @ -285,6 +289,10 @@ namespace MWGui | ||||||
|         void onDescriptionEntered(WindowBase* parWindow); |         void onDescriptionEntered(WindowBase* parWindow); | ||||||
|         void onDialogCancel(); |         void onDialogCancel(); | ||||||
| 
 | 
 | ||||||
|  |         void setSpecialization(int id); | ||||||
|  | 
 | ||||||
|  |         void update(); | ||||||
|  | 
 | ||||||
|     private: |     private: | ||||||
|         MyGUI::EditPtr          editName; |         MyGUI::EditPtr          editName; | ||||||
|         MyGUI::TextBox*    specializationName; |         MyGUI::TextBox*    specializationName; | ||||||
|  |  | ||||||
							
								
								
									
										70
									
								
								apps/openmw/mwgui/confirmationdialog.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								apps/openmw/mwgui/confirmationdialog.cpp
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,70 @@ | ||||||
|  | #include "confirmationdialog.hpp" | ||||||
|  | 
 | ||||||
|  | #include <boost/lexical_cast.hpp> | ||||||
|  | 
 | ||||||
|  | #include "../mwbase/environment.hpp" | ||||||
|  | #include "../mwworld/world.hpp" | ||||||
|  | 
 | ||||||
|  | namespace MWGui | ||||||
|  | { | ||||||
|  |     ConfirmationDialog::ConfirmationDialog(WindowManager& parWindowManager) : | ||||||
|  |         WindowBase("openmw_confirmation_dialog_layout.xml", parWindowManager) | ||||||
|  |     { | ||||||
|  |         getWidget(mMessage, "Message"); | ||||||
|  |         getWidget(mOkButton, "OkButton"); | ||||||
|  |         getWidget(mCancelButton, "CancelButton"); | ||||||
|  | 
 | ||||||
|  |         mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &ConfirmationDialog::onCancelButtonClicked); | ||||||
|  |         mOkButton->eventMouseButtonClick += MyGUI::newDelegate(this, &ConfirmationDialog::onOkButtonClicked); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     void ConfirmationDialog::open(const std::string& message) | ||||||
|  |     { | ||||||
|  |         setVisible(true); | ||||||
|  | 
 | ||||||
|  |         mMessage->setCaptionWithReplacing(message); | ||||||
|  | 
 | ||||||
|  |         int height = mMessage->getTextSize().height + 72; | ||||||
|  | 
 | ||||||
|  |         mMainWidget->setSize(mMainWidget->getWidth(), height); | ||||||
|  | 
 | ||||||
|  |         mMessage->setSize(mMessage->getWidth(), mMessage->getTextSize().height+24); | ||||||
|  | 
 | ||||||
|  |         center(); | ||||||
|  | 
 | ||||||
|  |         // make other gui elements inaccessible while this dialog is open
 | ||||||
|  |         MyGUI::InputManager::getInstance().addWidgetModal(mMainWidget); | ||||||
|  | 
 | ||||||
|  |         int okButtonWidth = mOkButton->getTextSize().width + 24; | ||||||
|  |         mOkButton->setCoord(mMainWidget->getWidth() - 30 - okButtonWidth, | ||||||
|  |                             mOkButton->getTop(), | ||||||
|  |                             okButtonWidth, | ||||||
|  |                             mOkButton->getHeight()); | ||||||
|  | 
 | ||||||
|  |         int cancelButtonWidth = mCancelButton->getTextSize().width + 24; | ||||||
|  |         mCancelButton->setCoord(mMainWidget->getWidth() - 30 - okButtonWidth - cancelButtonWidth - 8, | ||||||
|  |                             mCancelButton->getTop(), | ||||||
|  |                             cancelButtonWidth, | ||||||
|  |                             mCancelButton->getHeight()); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     void ConfirmationDialog::onCancelButtonClicked(MyGUI::Widget* _sender) | ||||||
|  |     { | ||||||
|  |         eventCancelClicked(); | ||||||
|  | 
 | ||||||
|  |         close(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     void ConfirmationDialog::onOkButtonClicked(MyGUI::Widget* _sender) | ||||||
|  |     { | ||||||
|  |         eventOkClicked(); | ||||||
|  | 
 | ||||||
|  |         close(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     void ConfirmationDialog::close() | ||||||
|  |     { | ||||||
|  |         setVisible(false); | ||||||
|  |         MyGUI::InputManager::getInstance().removeWidgetModal(mMainWidget); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										35
									
								
								apps/openmw/mwgui/confirmationdialog.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								apps/openmw/mwgui/confirmationdialog.hpp
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,35 @@ | ||||||
|  | #ifndef MWGUI_CONFIRMATIONDIALOG_H | ||||||
|  | #define MWGUI_CONFIRMATIONDIALOG_H | ||||||
|  | 
 | ||||||
|  | #include "window_base.hpp" | ||||||
|  | 
 | ||||||
|  | namespace MWGui | ||||||
|  | { | ||||||
|  |     class ConfirmationDialog : public WindowBase | ||||||
|  |     { | ||||||
|  |         public: | ||||||
|  |             ConfirmationDialog(WindowManager& parWindowManager); | ||||||
|  |             void open(const std::string& message); | ||||||
|  | 
 | ||||||
|  |             typedef MyGUI::delegates::CMultiDelegate0 EventHandle_Void; | ||||||
|  | 
 | ||||||
|  |             /** Event : Ok button was clicked.\n
 | ||||||
|  |                 signature : void method()\n | ||||||
|  |             */ | ||||||
|  |             EventHandle_Void eventOkClicked; | ||||||
|  |             EventHandle_Void eventCancelClicked; | ||||||
|  | 
 | ||||||
|  |         private: | ||||||
|  |             MyGUI::EditBox* mMessage; | ||||||
|  |             MyGUI::Button* mOkButton; | ||||||
|  |             MyGUI::Button* mCancelButton; | ||||||
|  | 
 | ||||||
|  |             void onCancelButtonClicked(MyGUI::Widget* _sender); | ||||||
|  |             void onOkButtonClicked(MyGUI::Widget* _sender); | ||||||
|  | 
 | ||||||
|  |             void close(); | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
|  | @ -138,6 +138,7 @@ namespace MWGui | ||||||
|     void Console::disable() |     void Console::disable() | ||||||
|     { |     { | ||||||
|         setVisible(false); |         setVisible(false); | ||||||
|  |         setSelectedObject(MWWorld::Ptr()); | ||||||
|         // Remove keyboard focus from the console input whenever the
 |         // Remove keyboard focus from the console input whenever the
 | ||||||
|         // console is turned off
 |         // console is turned off
 | ||||||
|         MyGUI::InputManager::getInstance().setKeyFocusWidget(NULL); |         MyGUI::InputManager::getInstance().setKeyFocusWidget(NULL); | ||||||
|  | @ -240,7 +241,7 @@ namespace MWGui | ||||||
|         { |         { | ||||||
|             try |             try | ||||||
|             { |             { | ||||||
|                 ConsoleInterpreterContext interpreterContext (*this, MWWorld::Ptr()); |                 ConsoleInterpreterContext interpreterContext (*this, mPtr); | ||||||
|                 Interpreter::Interpreter interpreter; |                 Interpreter::Interpreter interpreter; | ||||||
|                 MWScript::installOpcodes (interpreter); |                 MWScript::installOpcodes (interpreter); | ||||||
|                 std::vector<Interpreter::Type_Code> code; |                 std::vector<Interpreter::Type_Code> code; | ||||||
|  | @ -267,7 +268,7 @@ namespace MWGui | ||||||
|         /* Are there quotation marks? */ |         /* Are there quotation marks? */ | ||||||
|         if( tmp.find('"') != string::npos ) { |         if( tmp.find('"') != string::npos ) { | ||||||
|             int numquotes=0; |             int numquotes=0; | ||||||
|             for(string::iterator it=tmp.begin(); it < tmp.end(); it++) { |             for(string::iterator it=tmp.begin(); it < tmp.end(); ++it) { | ||||||
|                 if( *it == '"' ) |                 if( *it == '"' ) | ||||||
|                     numquotes++; |                     numquotes++; | ||||||
|             } |             } | ||||||
|  | @ -310,7 +311,7 @@ namespace MWGui | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         /* Iterate through the vector. */ |         /* Iterate through the vector. */ | ||||||
|         for(vector<string>::iterator it=mNames.begin(); it < mNames.end();it++) { |         for(vector<string>::iterator it=mNames.begin(); it < mNames.end();++it) { | ||||||
|             bool string_different=false; |             bool string_different=false; | ||||||
| 
 | 
 | ||||||
|             /* Is the string shorter than the input string? If yes skip it. */ |             /* Is the string shorter than the input string? If yes skip it. */ | ||||||
|  | @ -358,7 +359,7 @@ namespace MWGui | ||||||
|         int i = tmp.length(); |         int i = tmp.length(); | ||||||
| 
 | 
 | ||||||
|         for(string::iterator iter=matches.front().begin()+tmp.length(); iter < matches.front().end(); iter++, i++) { |         for(string::iterator iter=matches.front().begin()+tmp.length(); iter < matches.front().end(); iter++, i++) { | ||||||
|             for(vector<string>::iterator it=matches.begin(); it < matches.end();it++) { |             for(vector<string>::iterator it=matches.begin(); it < matches.end();++it) { | ||||||
|                 if( tolower((*it)[i]) != tolower(*iter) ) { |                 if( tolower((*it)[i]) != tolower(*iter) ) { | ||||||
|                     /* Append the longest match to the end of the output string*/ |                     /* Append the longest match to the end of the output string*/ | ||||||
|                     output.append(matches.front().substr( 0, i)); |                     output.append(matches.front().substr( 0, i)); | ||||||
|  | @ -370,4 +371,24 @@ namespace MWGui | ||||||
|         /* All keywords match with the shortest. Append it to the output string and return it. */ |         /* All keywords match with the shortest. Append it to the output string and return it. */ | ||||||
|         return output.append(matches.front()); |         return output.append(matches.front()); | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     void Console::onResChange(int width, int height) | ||||||
|  |     { | ||||||
|  |         setCoord(10,10, width-10, height/2); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     void Console::setSelectedObject(const MWWorld::Ptr& object) | ||||||
|  |     { | ||||||
|  |         mPtr = object; | ||||||
|  |         if (!mPtr.isEmpty()) | ||||||
|  |             setTitle("#{sConsoleTitle} (" + mPtr.getCellRef().refID + ")"); | ||||||
|  |         else | ||||||
|  |             setTitle("#{sConsoleTitle}"); | ||||||
|  |         MyGUI::InputManager::getInstance().setKeyFocusWidget(command); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     void Console::onReferenceUnavailable() | ||||||
|  |     { | ||||||
|  |         setSelectedObject(MWWorld::Ptr()); | ||||||
|  |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -16,9 +16,11 @@ | ||||||
| #include "../mwscript/compilercontext.hpp" | #include "../mwscript/compilercontext.hpp" | ||||||
| #include "../mwscript/interpretercontext.hpp" | #include "../mwscript/interpretercontext.hpp" | ||||||
| 
 | 
 | ||||||
|  | #include "referenceinterface.hpp" | ||||||
|  | 
 | ||||||
| namespace MWGui | namespace MWGui | ||||||
| { | { | ||||||
|   class Console : private OEngine::GUI::Layout, private Compiler::ErrorHandler |   class Console : private OEngine::GUI::Layout, private Compiler::ErrorHandler, public ReferenceInterface | ||||||
|   { |   { | ||||||
|     private: |     private: | ||||||
| 
 | 
 | ||||||
|  | @ -39,7 +41,17 @@ namespace MWGui | ||||||
|         /// \note The list may contain duplicates (if a name is a keyword and an identifier at the same
 |         /// \note The list may contain duplicates (if a name is a keyword and an identifier at the same
 | ||||||
|         /// time).
 |         /// time).
 | ||||||
| 
 | 
 | ||||||
|   public: |     public: | ||||||
|  | 
 | ||||||
|  |         void setSelectedObject(const MWWorld::Ptr& object); | ||||||
|  |         ///< Set the implicit object for script execution
 | ||||||
|  | 
 | ||||||
|  |     protected: | ||||||
|  | 
 | ||||||
|  |         virtual void onReferenceUnavailable(); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     public: | ||||||
|     MyGUI::EditPtr command; |     MyGUI::EditPtr command; | ||||||
|     MyGUI::EditPtr history; |     MyGUI::EditPtr history; | ||||||
| 
 | 
 | ||||||
|  | @ -58,6 +70,8 @@ namespace MWGui | ||||||
| 
 | 
 | ||||||
|     void setFont(const std::string &fntName); |     void setFont(const std::string &fntName); | ||||||
| 
 | 
 | ||||||
|  |     void onResChange(int width, int height); | ||||||
|  | 
 | ||||||
|     void clearHistory(); |     void clearHistory(); | ||||||
| 
 | 
 | ||||||
|     // Print a message to the console. Messages may contain color
 |     // Print a message to the console. Messages may contain color
 | ||||||
|  |  | ||||||
|  | @ -119,7 +119,7 @@ void ContainerBase::onSelectedItem(MyGUI::Widget* _sender) | ||||||
|         else |         else | ||||||
|             onContainerClicked(mContainerWidget); |             onContainerClicked(mContainerWidget); | ||||||
|     } |     } | ||||||
|     else |     else if (isTrading()) | ||||||
|     { |     { | ||||||
|         MWWorld::Ptr object = (*_sender->getUserData<MWWorld::Ptr>()); |         MWWorld::Ptr object = (*_sender->getUserData<MWWorld::Ptr>()); | ||||||
|         int count = object.getRefData().getCount(); |         int count = object.getRefData().getCount(); | ||||||
|  | @ -179,6 +179,10 @@ void ContainerBase::onSelectedItem(MyGUI::Widget* _sender) | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |     else | ||||||
|  |     { | ||||||
|  |         onSelectedItemImpl(*_sender->getUserData<MWWorld::Ptr>()); | ||||||
|  |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void ContainerBase::sellAlreadyBoughtItem(MyGUI::Widget* _sender, int count) | void ContainerBase::sellAlreadyBoughtItem(MyGUI::Widget* _sender, int count) | ||||||
|  | @ -260,16 +264,16 @@ void ContainerBase::onContainerClicked(MyGUI::Widget* _sender) | ||||||
|     if(mDragAndDrop->mIsOnDragAndDrop) //drop item here
 |     if(mDragAndDrop->mIsOnDragAndDrop) //drop item here
 | ||||||
|     { |     { | ||||||
|         MWWorld::Ptr object = *mDragAndDrop->mDraggedWidget->getUserData<MWWorld::Ptr>(); |         MWWorld::Ptr object = *mDragAndDrop->mDraggedWidget->getUserData<MWWorld::Ptr>(); | ||||||
|         MWWorld::ContainerStore& containerStore = MWWorld::Class::get(mContainer).getContainerStore(mContainer); |         MWWorld::ContainerStore& containerStore = MWWorld::Class::get(mPtr).getContainerStore(mPtr); | ||||||
| 
 | 
 | ||||||
|         if (mDragAndDrop->mDraggedFrom != this) |         if (mDragAndDrop->mDraggedFrom != this) | ||||||
|         { |         { | ||||||
|             assert(object.getContainerStore() && "Item is not in a container!"); |             assert(object.getContainerStore() && "Item is not in a container!"); | ||||||
| 
 | 
 | ||||||
|             // check the container's Organic flag (if this is a container). container with Organic flag doesn't allow putting items inside
 |             // check the container's Organic flag (if this is a container). container with Organic flag doesn't allow putting items inside
 | ||||||
|             if (mContainer.getTypeName() == typeid(ESM::Container).name()) |             if (mPtr.getTypeName() == typeid(ESM::Container).name()) | ||||||
|             { |             { | ||||||
|                 ESMS::LiveCellRef<ESM::Container, MWWorld::RefData>* ref = mContainer.get<ESM::Container>(); |                 ESMS::LiveCellRef<ESM::Container, MWWorld::RefData>* ref = mPtr.get<ESM::Container>(); | ||||||
|                 if (ref->base->flags & ESM::Container::Organic) |                 if (ref->base->flags & ESM::Container::Organic) | ||||||
|                 { |                 { | ||||||
|                     // user notification
 |                     // user notification
 | ||||||
|  | @ -284,13 +288,13 @@ void ContainerBase::onContainerClicked(MyGUI::Widget* _sender) | ||||||
|             // check that we don't exceed the allowed weight (only for containers, not for inventory)
 |             // check that we don't exceed the allowed weight (only for containers, not for inventory)
 | ||||||
|             if (!isInventory()) |             if (!isInventory()) | ||||||
|             { |             { | ||||||
|                 float capacity = MWWorld::Class::get(mContainer).getCapacity(mContainer); |                 float capacity = MWWorld::Class::get(mPtr).getCapacity(mPtr); | ||||||
| 
 | 
 | ||||||
|                 // try adding the item, and if weight is exceeded, just remove it again.
 |                 // try adding the item, and if weight is exceeded, just remove it again.
 | ||||||
|                 object.getRefData().setCount(mDragAndDrop->mDraggedCount); |                 object.getRefData().setCount(mDragAndDrop->mDraggedCount); | ||||||
|                 MWWorld::ContainerStoreIterator it = containerStore.add(object); |                 MWWorld::ContainerStoreIterator it = containerStore.add(object); | ||||||
| 
 | 
 | ||||||
|                 float curWeight = MWWorld::Class::get(mContainer).getEncumbrance(mContainer); |                 float curWeight = MWWorld::Class::get(mPtr).getEncumbrance(mPtr); | ||||||
|                 if (curWeight > capacity) |                 if (curWeight > capacity) | ||||||
|                 { |                 { | ||||||
|                     it->getRefData().setCount(0); |                     it->getRefData().setCount(0); | ||||||
|  | @ -342,8 +346,7 @@ void ContainerBase::setFilter(ContainerBase::Filter filter) | ||||||
| 
 | 
 | ||||||
| void ContainerBase::openContainer(MWWorld::Ptr container) | void ContainerBase::openContainer(MWWorld::Ptr container) | ||||||
| { | { | ||||||
|     mContainer = container; |     mPtr = container; | ||||||
|     drawItems(); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void ContainerBase::drawItems() | void ContainerBase::drawItems() | ||||||
|  | @ -352,15 +355,12 @@ void ContainerBase::drawItems() | ||||||
|     { |     { | ||||||
|         MyGUI::Gui::getInstance().destroyWidget(mContainerWidget->getChildAt(0)); |         MyGUI::Gui::getInstance().destroyWidget(mContainerWidget->getChildAt(0)); | ||||||
|     } |     } | ||||||
|     MWWorld::ContainerStore& containerStore = MWWorld::Class::get(mContainer).getContainerStore(mContainer); |     MWWorld::ContainerStore& containerStore = MWWorld::Class::get(mPtr).getContainerStore(mPtr); | ||||||
| 
 | 
 | ||||||
|     int x = 0; |     int x = 0; | ||||||
|     int y = 0; |     int y = 0; | ||||||
|     int maxHeight = mItemView->getSize().height - 58; |     int maxHeight = mItemView->getSize().height - 58; | ||||||
| 
 | 
 | ||||||
|     int index = 0; |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|     bool onlyMagic = false; |     bool onlyMagic = false; | ||||||
|     int categories; |     int categories; | ||||||
|     if (mFilter == Filter_All) |     if (mFilter == Filter_All) | ||||||
|  | @ -381,8 +381,10 @@ void ContainerBase::drawItems() | ||||||
|         categories = MWWorld::ContainerStore::Type_Miscellaneous + MWWorld::ContainerStore::Type_Book |         categories = MWWorld::ContainerStore::Type_Miscellaneous + MWWorld::ContainerStore::Type_Book | ||||||
|                     + MWWorld::ContainerStore::Type_Ingredient + MWWorld::ContainerStore::Type_Repair |                     + MWWorld::ContainerStore::Type_Ingredient + MWWorld::ContainerStore::Type_Repair | ||||||
|                     + MWWorld::ContainerStore::Type_Lockpick + MWWorld::ContainerStore::Type_Light |                     + MWWorld::ContainerStore::Type_Lockpick + MWWorld::ContainerStore::Type_Light | ||||||
|                     + MWWorld::ContainerStore::Type_Apparatus; |                     + MWWorld::ContainerStore::Type_Apparatus + MWWorld::ContainerStore::Type_Probe; | ||||||
|     } |     } | ||||||
|  |     else if (mFilter == Filter_Ingredients) | ||||||
|  |         categories = MWWorld::ContainerStore::Type_Ingredient; | ||||||
| 
 | 
 | ||||||
|     /// \todo performance improvement: don't create/destroy all the widgets everytime the container window changes size, only reposition them
 |     /// \todo performance improvement: don't create/destroy all the widgets everytime the container window changes size, only reposition them
 | ||||||
| 
 | 
 | ||||||
|  | @ -454,7 +456,6 @@ void ContainerBase::drawItems() | ||||||
|     for (std::vector< std::pair<MWWorld::Ptr, ItemState> >::const_iterator it=items.begin(); |     for (std::vector< std::pair<MWWorld::Ptr, ItemState> >::const_iterator it=items.begin(); | ||||||
|         it != items.end(); ++it) |         it != items.end(); ++it) | ||||||
|     { |     { | ||||||
|         index++; |  | ||||||
|         const MWWorld::Ptr* iter = &((*it).first); |         const MWWorld::Ptr* iter = &((*it).first); | ||||||
| 
 | 
 | ||||||
|         int displayCount = iter->getRefData().getCount(); |         int displayCount = iter->getRefData().getCount(); | ||||||
|  | @ -465,7 +466,7 @@ void ContainerBase::drawItems() | ||||||
|         if(displayCount > 0 && !(onlyMagic && it->second != ItemState_Barter && MWWorld::Class::get(*iter).getEnchantment(*iter) == "" && iter->getTypeName() != typeid(ESM::Potion).name())) |         if(displayCount > 0 && !(onlyMagic && it->second != ItemState_Barter && MWWorld::Class::get(*iter).getEnchantment(*iter) == "" && iter->getTypeName() != typeid(ESM::Potion).name())) | ||||||
|         { |         { | ||||||
|             std::string path = std::string("icons\\"); |             std::string path = std::string("icons\\"); | ||||||
|             path+=MWWorld::Class::get(*iter).getInventoryIcon(*iter); |             path += MWWorld::Class::get(*iter).getInventoryIcon(*iter); | ||||||
| 
 | 
 | ||||||
|             // background widget (for the "equipped" frame and magic item background image)
 |             // background widget (for the "equipped" frame and magic item background image)
 | ||||||
|             bool isMagic = (MWWorld::Class::get(*iter).getEnchantment(*iter) != ""); |             bool isMagic = (MWWorld::Class::get(*iter).getEnchantment(*iter) != ""); | ||||||
|  | @ -514,6 +515,7 @@ void ContainerBase::drawItems() | ||||||
|             text->setNeedMouseFocus(false); |             text->setNeedMouseFocus(false); | ||||||
|             text->setTextShadow(true); |             text->setTextShadow(true); | ||||||
|             text->setTextShadowColour(MyGUI::Colour(0,0,0)); |             text->setTextShadowColour(MyGUI::Colour(0,0,0)); | ||||||
|  |             text->setCaption(getCountString(displayCount)); | ||||||
| 
 | 
 | ||||||
|             y += 42; |             y += 42; | ||||||
|             if (y > maxHeight) |             if (y > maxHeight) | ||||||
|  | @ -522,13 +524,14 @@ void ContainerBase::drawItems() | ||||||
|                 y = 0; |                 y = 0; | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             text->setCaption(getCountString(displayCount)); |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     MyGUI::IntSize size = MyGUI::IntSize(std::max(mItemView->getSize().width, x+42), mItemView->getSize().height); |     MyGUI::IntSize size = MyGUI::IntSize(std::max(mItemView->getSize().width, x+42), mItemView->getSize().height); | ||||||
|     mItemView->setCanvasSize(size); |     mItemView->setCanvasSize(size); | ||||||
|     mContainerWidget->setSize(size); |     mContainerWidget->setSize(size); | ||||||
|  | 
 | ||||||
|  |     notifyContentChanged(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| std::string ContainerBase::getCountString(const int count) | std::string ContainerBase::getCountString(const int count) | ||||||
|  | @ -551,7 +554,7 @@ void ContainerBase::addBarteredItem(MWWorld::Ptr item, int count) | ||||||
| 
 | 
 | ||||||
| void ContainerBase::addItem(MWWorld::Ptr item, int count) | void ContainerBase::addItem(MWWorld::Ptr item, int count) | ||||||
| { | { | ||||||
|     MWWorld::ContainerStore& containerStore = MWWorld::Class::get(mContainer).getContainerStore(mContainer); |     MWWorld::ContainerStore& containerStore = MWWorld::Class::get(mPtr).getContainerStore(mPtr); | ||||||
| 
 | 
 | ||||||
|     int origCount = item.getRefData().getCount();     |     int origCount = item.getRefData().getCount();     | ||||||
| 
 | 
 | ||||||
|  | @ -563,7 +566,7 @@ void ContainerBase::addItem(MWWorld::Ptr item, int count) | ||||||
| 
 | 
 | ||||||
| void ContainerBase::transferBoughtItems() | void ContainerBase::transferBoughtItems() | ||||||
| { | { | ||||||
|     MWWorld::ContainerStore& containerStore = MWWorld::Class::get(mContainer).getContainerStore(mContainer); |     MWWorld::ContainerStore& containerStore = MWWorld::Class::get(mPtr).getContainerStore(mPtr); | ||||||
| 
 | 
 | ||||||
|     for (MWWorld::ContainerStoreIterator it(mBoughtItems.begin()); it != mBoughtItems.end(); ++it) |     for (MWWorld::ContainerStoreIterator it(mBoughtItems.begin()); it != mBoughtItems.end(); ++it) | ||||||
|     { |     { | ||||||
|  | @ -581,7 +584,7 @@ void ContainerBase::returnBoughtItems(MWWorld::ContainerStore& store) | ||||||
| 
 | 
 | ||||||
| MWWorld::ContainerStore& ContainerBase::getContainerStore() | MWWorld::ContainerStore& ContainerBase::getContainerStore() | ||||||
| { | { | ||||||
|     MWWorld::ContainerStore& store = MWWorld::Class::get(mContainer).getContainerStore(mContainer); |     MWWorld::ContainerStore& store = MWWorld::Class::get(mPtr).getContainerStore(mPtr); | ||||||
|     return store; |     return store; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -630,13 +633,14 @@ void ContainerWindow::open(MWWorld::Ptr container) | ||||||
| { | { | ||||||
|     openContainer(container); |     openContainer(container); | ||||||
|     setTitle(MWWorld::Class::get(container).getName(container)); |     setTitle(MWWorld::Class::get(container).getName(container)); | ||||||
|  |     drawItems(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void ContainerWindow::onCloseButtonClicked(MyGUI::Widget* _sender) | void ContainerWindow::onCloseButtonClicked(MyGUI::Widget* _sender) | ||||||
| { | { | ||||||
|     if(mDragAndDrop == NULL || !mDragAndDrop->mIsOnDragAndDrop) |     if(mDragAndDrop == NULL || !mDragAndDrop->mIsOnDragAndDrop) | ||||||
|     { |     { | ||||||
|         MWBase::Environment::get().getWindowManager()->setGuiMode(GM_Game); |         MWBase::Environment::get().getWindowManager()->popGuiMode(); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -645,7 +649,7 @@ void ContainerWindow::onTakeAllButtonClicked(MyGUI::Widget* _sender) | ||||||
|     if(mDragAndDrop == NULL || !mDragAndDrop->mIsOnDragAndDrop) |     if(mDragAndDrop == NULL || !mDragAndDrop->mIsOnDragAndDrop) | ||||||
|     { |     { | ||||||
|         // transfer everything into the player's inventory
 |         // transfer everything into the player's inventory
 | ||||||
|         MWWorld::ContainerStore& containerStore = MWWorld::Class::get(mContainer).getContainerStore(mContainer); |         MWWorld::ContainerStore& containerStore = MWWorld::Class::get(mPtr).getContainerStore(mPtr); | ||||||
| 
 | 
 | ||||||
|         MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); |         MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); | ||||||
|         MWWorld::ContainerStore& playerStore = MWWorld::Class::get(player).getContainerStore(player); |         MWWorld::ContainerStore& playerStore = MWWorld::Class::get(player).getContainerStore(player); | ||||||
|  | @ -667,6 +671,11 @@ void ContainerWindow::onTakeAllButtonClicked(MyGUI::Widget* _sender) | ||||||
| 
 | 
 | ||||||
|         containerStore.clear(); |         containerStore.clear(); | ||||||
| 
 | 
 | ||||||
|         MWBase::Environment::get().getWindowManager()->setGuiMode(GM_Game); |         MWBase::Environment::get().getWindowManager()->popGuiMode(); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | void ContainerWindow::onReferenceUnavailable() | ||||||
|  | { | ||||||
|  |     MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Container); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ -2,15 +2,14 @@ | ||||||
| #define MGUI_CONTAINER_H | #define MGUI_CONTAINER_H | ||||||
| 
 | 
 | ||||||
| #include <components/esm_store/store.hpp> | #include <components/esm_store/store.hpp> | ||||||
| #include "../mwclass/container.hpp" | 
 | ||||||
| #include <sstream> |  | ||||||
| #include <set> |  | ||||||
| #include <string> |  | ||||||
| #include <utility> |  | ||||||
| #include "window_base.hpp" | #include "window_base.hpp" | ||||||
|  | #include "referenceinterface.hpp" | ||||||
|  | 
 | ||||||
|  | #include "../mwclass/container.hpp" | ||||||
| #include "../mwworld/ptr.hpp" | #include "../mwworld/ptr.hpp" | ||||||
| #include "../mwworld/containerstore.hpp" | #include "../mwworld/containerstore.hpp" | ||||||
| #include <vector> | 
 | ||||||
| 
 | 
 | ||||||
| namespace MWWorld | namespace MWWorld | ||||||
| { | { | ||||||
|  | @ -43,7 +42,7 @@ namespace MWGui | ||||||
|         int mDraggedCount; |         int mDraggedCount; | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     class ContainerBase |     class ContainerBase : public ReferenceInterface | ||||||
|     { |     { | ||||||
|     public: |     public: | ||||||
|         ContainerBase(DragAndDrop* dragAndDrop); |         ContainerBase(DragAndDrop* dragAndDrop); | ||||||
|  | @ -55,7 +54,9 @@ namespace MWGui | ||||||
|             Filter_Weapon = 0x02, |             Filter_Weapon = 0x02, | ||||||
|             Filter_Apparel = 0x03, |             Filter_Apparel = 0x03, | ||||||
|             Filter_Magic = 0x04, |             Filter_Magic = 0x04, | ||||||
|             Filter_Misc = 0x05 |             Filter_Misc = 0x05, | ||||||
|  | 
 | ||||||
|  |             Filter_Ingredients = 0x06 | ||||||
|         }; |         }; | ||||||
| 
 | 
 | ||||||
|         enum ItemState |         enum ItemState | ||||||
|  | @ -87,7 +88,6 @@ namespace MWGui | ||||||
|         MyGUI::Widget* mSelectedItem; |         MyGUI::Widget* mSelectedItem; | ||||||
| 
 | 
 | ||||||
|         DragAndDrop* mDragAndDrop; |         DragAndDrop* mDragAndDrop; | ||||||
|         MWWorld::Ptr mContainer; |  | ||||||
| 
 | 
 | ||||||
|         Filter mFilter; |         Filter mFilter; | ||||||
| 
 | 
 | ||||||
|  | @ -116,8 +116,12 @@ namespace MWGui | ||||||
| 
 | 
 | ||||||
|         virtual bool isTrading() { return false; } |         virtual bool isTrading() { return false; } | ||||||
| 
 | 
 | ||||||
|  |         virtual void onSelectedItemImpl(MWWorld::Ptr item) { ; } | ||||||
|  | 
 | ||||||
|         virtual bool ignoreEquippedItems() { return false; } |         virtual bool ignoreEquippedItems() { return false; } | ||||||
|         virtual std::vector<MWWorld::Ptr> itemsToIgnore() { return std::vector<MWWorld::Ptr>(); } |         virtual std::vector<MWWorld::Ptr> itemsToIgnore() { return std::vector<MWWorld::Ptr>(); } | ||||||
|  | 
 | ||||||
|  |         virtual void notifyContentChanged() { ; } | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     class ContainerWindow : public ContainerBase, public WindowBase |     class ContainerWindow : public ContainerBase, public WindowBase | ||||||
|  | @ -136,6 +140,8 @@ namespace MWGui | ||||||
|         void onWindowResize(MyGUI::Window* window); |         void onWindowResize(MyGUI::Window* window); | ||||||
|         void onCloseButtonClicked(MyGUI::Widget* _sender); |         void onCloseButtonClicked(MyGUI::Widget* _sender); | ||||||
|         void onTakeAllButtonClicked(MyGUI::Widget* _sender); |         void onTakeAllButtonClicked(MyGUI::Widget* _sender); | ||||||
|  | 
 | ||||||
|  |         virtual void onReferenceUnavailable(); | ||||||
|     }; |     }; | ||||||
| } | } | ||||||
| #endif // CONTAINER_H
 | #endif // CONTAINER_H
 | ||||||
|  |  | ||||||
|  | @ -17,9 +17,6 @@ namespace MWGui | ||||||
|         getWidget(mOkButton, "OkButton"); |         getWidget(mOkButton, "OkButton"); | ||||||
|         getWidget(mCancelButton, "CancelButton"); |         getWidget(mCancelButton, "CancelButton"); | ||||||
| 
 | 
 | ||||||
|         mOkButton->setCaption(MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sOk")->str); |  | ||||||
|         mCancelButton->setCaption(MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sCancel")->str); |  | ||||||
| 
 |  | ||||||
|         mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &CountDialog::onCancelButtonClicked); |         mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &CountDialog::onCancelButtonClicked); | ||||||
|         mOkButton->eventMouseButtonClick += MyGUI::newDelegate(this, &CountDialog::onOkButtonClicked); |         mOkButton->eventMouseButtonClick += MyGUI::newDelegate(this, &CountDialog::onOkButtonClicked); | ||||||
|         mItemEdit->eventEditTextChange += MyGUI::newDelegate(this, &CountDialog::onEditTextChange); |         mItemEdit->eventEditTextChange += MyGUI::newDelegate(this, &CountDialog::onEditTextChange); | ||||||
|  |  | ||||||
|  | @ -112,15 +112,6 @@ void DialogueWindow::onMouseWheel(MyGUI::Widget* _sender, int _rel) | ||||||
|         history->setVScrollPosition(history->getVScrollPosition() - _rel*0.3); |         history->setVScrollPosition(history->getVScrollPosition() - _rel*0.3); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void DialogueWindow::open() |  | ||||||
| { |  | ||||||
|     topicsList->clear(); |  | ||||||
|     pTopicsText.clear(); |  | ||||||
|     history->eraseText(0,history->getTextLength()); |  | ||||||
|     updateOptions(); |  | ||||||
|     setVisible(true); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void DialogueWindow::onByeClicked(MyGUI::Widget* _sender) | void DialogueWindow::onByeClicked(MyGUI::Widget* _sender) | ||||||
| { | { | ||||||
|     MWBase::Environment::get().getDialogueManager()->goodbyeSelected(); |     MWBase::Environment::get().getDialogueManager()->goodbyeSelected(); | ||||||
|  | @ -133,8 +124,8 @@ void DialogueWindow::onSelectTopic(std::string topic) | ||||||
|     if (topic == MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sBarter")->str) |     if (topic == MWBase::Environment::get().getWorld()->getStore().gameSettings.search("sBarter")->str) | ||||||
|     { |     { | ||||||
|         /// \todo check if the player is allowed to trade with this actor (e.g. faction rank high enough)?
 |         /// \todo check if the player is allowed to trade with this actor (e.g. faction rank high enough)?
 | ||||||
|         mWindowManager.setGuiMode(GM_Barter); |         mWindowManager.pushGuiMode(GM_Barter); | ||||||
|         mWindowManager.getTradeWindow()->startTrade(mActor); |         mWindowManager.getTradeWindow()->startTrade(mPtr); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     else |     else | ||||||
|  | @ -144,9 +135,13 @@ void DialogueWindow::onSelectTopic(std::string topic) | ||||||
| void DialogueWindow::startDialogue(MWWorld::Ptr actor, std::string npcName) | void DialogueWindow::startDialogue(MWWorld::Ptr actor, std::string npcName) | ||||||
| { | { | ||||||
|     mEnabled = true; |     mEnabled = true; | ||||||
|     mActor = actor; |     mPtr = actor; | ||||||
|     topicsList->setEnabled(true); |     topicsList->setEnabled(true); | ||||||
|     setTitle(npcName); |     setTitle(npcName); | ||||||
|  | 
 | ||||||
|  |     topicsList->clear(); | ||||||
|  |     history->eraseText(0,history->getTextLength()); | ||||||
|  |     updateOptions(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void DialogueWindow::setKeywords(std::list<std::string> keyWords) | void DialogueWindow::setKeywords(std::list<std::string> keyWords) | ||||||
|  | @ -161,7 +156,7 @@ void DialogueWindow::setKeywords(std::list<std::string> keyWords) | ||||||
|     if (anyService) |     if (anyService) | ||||||
|         topicsList->addSeparator(); |         topicsList->addSeparator(); | ||||||
| 
 | 
 | ||||||
|     for(std::list<std::string>::iterator it = keyWords.begin(); it != keyWords.end(); it++) |     for(std::list<std::string>::iterator it = keyWords.begin(); it != keyWords.end(); ++it) | ||||||
|     { |     { | ||||||
|         topicsList->addItem(*it); |         topicsList->addItem(*it); | ||||||
|     } |     } | ||||||
|  | @ -173,7 +168,6 @@ void DialogueWindow::removeKeyword(std::string keyWord) | ||||||
|     if(topicsList->hasItem(keyWord)) |     if(topicsList->hasItem(keyWord)) | ||||||
|     { |     { | ||||||
|         topicsList->removeItem(keyWord); |         topicsList->removeItem(keyWord); | ||||||
|         pTopicsText.erase(keyWord); |  | ||||||
|     } |     } | ||||||
|     topicsList->adjustSize(); |     topicsList->adjustSize(); | ||||||
| } | } | ||||||
|  | @ -249,7 +243,6 @@ void DialogueWindow::updateOptions() | ||||||
| { | { | ||||||
|     //Clear the list of topics
 |     //Clear the list of topics
 | ||||||
|     topicsList->clear(); |     topicsList->clear(); | ||||||
|     pTopicsText.clear(); |  | ||||||
|     history->eraseText(0,history->getTextLength()); |     history->eraseText(0,history->getTextLength()); | ||||||
| 
 | 
 | ||||||
|     pDispositionBar->setProgressRange(100); |     pDispositionBar->setProgressRange(100); | ||||||
|  | @ -264,3 +257,8 @@ void DialogueWindow::goodbye() | ||||||
|     topicsList->setEnabled(false); |     topicsList->setEnabled(false); | ||||||
|     mEnabled = false; |     mEnabled = false; | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | void DialogueWindow::onReferenceUnavailable() | ||||||
|  | { | ||||||
|  |     mWindowManager.removeGuiMode(GM_Dialogue); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ -2,6 +2,7 @@ | ||||||
| #define MWGUI_DIALOGE_H | #define MWGUI_DIALOGE_H | ||||||
| 
 | 
 | ||||||
| #include "window_base.hpp" | #include "window_base.hpp" | ||||||
|  | #include "referenceinterface.hpp" | ||||||
| #include <boost/array.hpp> | #include <boost/array.hpp> | ||||||
| 
 | 
 | ||||||
| #include "../mwworld/ptr.hpp" | #include "../mwworld/ptr.hpp" | ||||||
|  | @ -25,13 +26,11 @@ namespace MWGui | ||||||
| { | { | ||||||
|     class DialogueHistory; |     class DialogueHistory; | ||||||
| 
 | 
 | ||||||
|     class DialogueWindow: public WindowBase |     class DialogueWindow: public WindowBase, public ReferenceInterface | ||||||
|     { |     { | ||||||
|     public: |     public: | ||||||
|         DialogueWindow(WindowManager& parWindowManager); |         DialogueWindow(WindowManager& parWindowManager); | ||||||
| 
 | 
 | ||||||
|         void open(); |  | ||||||
| 
 |  | ||||||
|         // Events
 |         // Events
 | ||||||
|         typedef MyGUI::delegates::CMultiDelegate0 EventHandle_Void; |         typedef MyGUI::delegates::CMultiDelegate0 EventHandle_Void; | ||||||
| 
 | 
 | ||||||
|  | @ -60,6 +59,8 @@ namespace MWGui | ||||||
|         void onMouseWheel(MyGUI::Widget* _sender, int _rel); |         void onMouseWheel(MyGUI::Widget* _sender, int _rel); | ||||||
|         void onWindowResize(MyGUI::Window* _sender); |         void onWindowResize(MyGUI::Window* _sender); | ||||||
| 
 | 
 | ||||||
|  |         virtual void onReferenceUnavailable(); | ||||||
|  | 
 | ||||||
|     private: |     private: | ||||||
|         void updateOptions(); |         void updateOptions(); | ||||||
|         /**
 |         /**
 | ||||||
|  | @ -72,13 +73,10 @@ namespace MWGui | ||||||
| 
 | 
 | ||||||
|         bool mEnabled; |         bool mEnabled; | ||||||
| 
 | 
 | ||||||
|         MWWorld::Ptr mActor; // actor being talked to
 |  | ||||||
| 
 |  | ||||||
|         DialogueHistory*     history; |         DialogueHistory*     history; | ||||||
|         Widgets::MWList*      topicsList; |         Widgets::MWList*      topicsList; | ||||||
|         MyGUI::ProgressPtr pDispositionBar; |         MyGUI::ProgressPtr pDispositionBar; | ||||||
|         MyGUI::EditPtr pDispositionText; |         MyGUI::EditPtr pDispositionText; | ||||||
|         std::map<std::string,std::string> pTopicsText;// this map links keyword and "real" text.
 |  | ||||||
|     }; |     }; | ||||||
| } | } | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  | @ -12,8 +12,10 @@ | ||||||
| #include "../mwworld/world.hpp" | #include "../mwworld/world.hpp" | ||||||
| #include "../mwworld/player.hpp" | #include "../mwworld/player.hpp" | ||||||
| 
 | 
 | ||||||
|  | #include "inventorywindow.hpp" | ||||||
| #include "window_manager.hpp" | #include "window_manager.hpp" | ||||||
| #include "container.hpp" | #include "container.hpp" | ||||||
|  | #include "console.hpp" | ||||||
| 
 | 
 | ||||||
| using namespace MWGui; | using namespace MWGui; | ||||||
| 
 | 
 | ||||||
|  | @ -41,35 +43,60 @@ HUD::HUD(int width, int height, int fpsLevel, DragAndDrop* dragAndDrop) | ||||||
|     , effectBoxBaseRight(0) |     , effectBoxBaseRight(0) | ||||||
|     , minimapBoxBaseRight(0) |     , minimapBoxBaseRight(0) | ||||||
|     , mDragAndDrop(dragAndDrop) |     , mDragAndDrop(dragAndDrop) | ||||||
|  |     , mCellNameTimer(0.0f) | ||||||
|  |     , mCellNameBox(NULL) | ||||||
|  |     , mMapVisible(true) | ||||||
|  |     , mWeaponVisible(true) | ||||||
|  |     , mSpellVisible(true) | ||||||
|  |     , mWorldMouseOver(false) | ||||||
| { | { | ||||||
|     setCoord(0,0, width, height); |     setCoord(0,0, width, height); | ||||||
| 
 | 
 | ||||||
|     // Energy bars
 |     // Energy bars
 | ||||||
|  |     getWidget(mHealthFrame, "HealthFrame"); | ||||||
|     getWidget(health, "Health"); |     getWidget(health, "Health"); | ||||||
|     getWidget(magicka, "Magicka"); |     getWidget(magicka, "Magicka"); | ||||||
|     getWidget(stamina, "Stamina"); |     getWidget(stamina, "Stamina"); | ||||||
|     hmsBaseLeft = health->getLeft(); | 
 | ||||||
|  |     hmsBaseLeft = mHealthFrame->getLeft(); | ||||||
|  | 
 | ||||||
|  |     MyGUI::Widget *healthFrame, *magickaFrame, *fatigueFrame; | ||||||
|  |     getWidget(healthFrame, "HealthFrame"); | ||||||
|  |     getWidget(magickaFrame, "MagickaFrame"); | ||||||
|  |     getWidget(fatigueFrame, "FatigueFrame"); | ||||||
|  |     healthFrame->eventMouseButtonClick += MyGUI::newDelegate(this, &HUD::onHMSClicked); | ||||||
|  |     magickaFrame->eventMouseButtonClick += MyGUI::newDelegate(this, &HUD::onHMSClicked); | ||||||
|  |     fatigueFrame->eventMouseButtonClick += MyGUI::newDelegate(this, &HUD::onHMSClicked); | ||||||
|  | 
 | ||||||
|  |     const MyGUI::IntSize& viewSize = MyGUI::RenderManager::getInstance().getViewSize(); | ||||||
| 
 | 
 | ||||||
|     // Item and spell images and status bars
 |     // Item and spell images and status bars
 | ||||||
|     getWidget(weapBox, "WeapBox"); |     getWidget(weapBox, "WeapBox"); | ||||||
|     getWidget(weapImage, "WeapImage"); |     getWidget(weapImage, "WeapImage"); | ||||||
|     getWidget(weapStatus, "WeapStatus"); |     getWidget(weapStatus, "WeapStatus"); | ||||||
|     weapBoxBaseLeft = weapBox->getLeft(); |     weapBoxBaseLeft = weapBox->getLeft(); | ||||||
|  |     weapBox->eventMouseButtonClick += MyGUI::newDelegate(this, &HUD::onWeaponClicked); | ||||||
| 
 | 
 | ||||||
|     getWidget(spellBox, "SpellBox"); |     getWidget(spellBox, "SpellBox"); | ||||||
|     getWidget(spellImage, "SpellImage"); |     getWidget(spellImage, "SpellImage"); | ||||||
|     getWidget(spellStatus, "SpellStatus"); |     getWidget(spellStatus, "SpellStatus"); | ||||||
|     spellBoxBaseLeft = spellBox->getLeft(); |     spellBoxBaseLeft = spellBox->getLeft(); | ||||||
|  |     spellBox->eventMouseButtonClick += MyGUI::newDelegate(this, &HUD::onMagicClicked); | ||||||
| 
 | 
 | ||||||
|     getWidget(effectBox, "EffectBox"); |     getWidget(effectBox, "EffectBox"); | ||||||
|     getWidget(effect1, "Effect1"); |     getWidget(effect1, "Effect1"); | ||||||
|     effectBoxBaseRight = effectBox->getRight(); |     effectBoxBaseRight = viewSize.width - effectBox->getRight(); | ||||||
|  |     effectBox->eventMouseButtonClick += MyGUI::newDelegate(this, &HUD::onMagicClicked); | ||||||
| 
 | 
 | ||||||
|     getWidget(minimapBox, "MiniMapBox"); |     getWidget(minimapBox, "MiniMapBox"); | ||||||
|     minimapBoxBaseRight = minimapBox->getRight(); |     minimapBoxBaseRight = viewSize.width - minimapBox->getRight(); | ||||||
|  |     minimapBox->eventMouseButtonClick += MyGUI::newDelegate(this, &HUD::onMapClicked); | ||||||
|     getWidget(minimap, "MiniMap"); |     getWidget(minimap, "MiniMap"); | ||||||
|     getWidget(compass, "Compass"); |     getWidget(compass, "Compass"); | ||||||
| 
 | 
 | ||||||
|  |     getWidget(mCellNameBox, "CellName"); | ||||||
|  |     getWidget(mWeaponSpellBox, "WeaponSpellName"); | ||||||
|  | 
 | ||||||
|     getWidget(crosshair, "Crosshair"); |     getWidget(crosshair, "Crosshair"); | ||||||
| 
 | 
 | ||||||
|     setFpsLevel(fpsLevel); |     setFpsLevel(fpsLevel); | ||||||
|  | @ -77,15 +104,9 @@ HUD::HUD(int width, int height, int fpsLevel, DragAndDrop* dragAndDrop) | ||||||
|     getWidget(trianglecounter, "TriangleCounter"); |     getWidget(trianglecounter, "TriangleCounter"); | ||||||
|     getWidget(batchcounter, "BatchCounter"); |     getWidget(batchcounter, "BatchCounter"); | ||||||
| 
 | 
 | ||||||
|     // These are just demo values, you should replace these with
 |  | ||||||
|     // real calls from outside the class later.
 |  | ||||||
|     setWeapIcon("icons\\w\\tx_knife_iron.dds"); |  | ||||||
|     setWeapStatus(90, 100); |  | ||||||
|     setSpellIcon("icons\\s\\b_tx_s_rstor_health.dds"); |  | ||||||
|     setSpellStatus(65, 100); |  | ||||||
|     setEffect("icons\\s\\tx_s_chameleon.dds"); |     setEffect("icons\\s\\tx_s_chameleon.dds"); | ||||||
| 
 | 
 | ||||||
|     LocalMapBase::init(minimap, this); |     LocalMapBase::init(minimap, compass, this); | ||||||
| 
 | 
 | ||||||
|     mMainWidget->eventMouseButtonClick += MyGUI::newDelegate(this, &HUD::onWorldClicked); |     mMainWidget->eventMouseButtonClick += MyGUI::newDelegate(this, &HUD::onWorldClicked); | ||||||
|     mMainWidget->eventMouseMove += MyGUI::newDelegate(this, &HUD::onWorldMouseOver); |     mMainWidget->eventMouseMove += MyGUI::newDelegate(this, &HUD::onWorldMouseOver); | ||||||
|  | @ -94,6 +115,8 @@ HUD::HUD(int width, int height, int fpsLevel, DragAndDrop* dragAndDrop) | ||||||
| 
 | 
 | ||||||
| void HUD::setFpsLevel(int level) | void HUD::setFpsLevel(int level) | ||||||
| { | { | ||||||
|  |     fpscounter = 0; | ||||||
|  | 
 | ||||||
|     MyGUI::Widget* fps; |     MyGUI::Widget* fps; | ||||||
|     getWidget(fps, "FPSBoxAdv"); |     getWidget(fps, "FPSBoxAdv"); | ||||||
|     fps->setVisible(false); |     fps->setVisible(false); | ||||||
|  | @ -116,7 +139,8 @@ void HUD::setFpsLevel(int level) | ||||||
| 
 | 
 | ||||||
| void HUD::setFPS(float fps) | void HUD::setFPS(float fps) | ||||||
| { | { | ||||||
|     fpscounter->setCaption(boost::lexical_cast<std::string>((int)fps)); |     if (fpscounter) | ||||||
|  |         fpscounter->setCaption(boost::lexical_cast<std::string>((int)fps)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void HUD::setTriangleCount(size_t count) | void HUD::setTriangleCount(size_t count) | ||||||
|  | @ -129,28 +153,6 @@ void HUD::setBatchCount(size_t count) | ||||||
|     batchcounter->setCaption(boost::lexical_cast<std::string>(count)); |     batchcounter->setCaption(boost::lexical_cast<std::string>(count)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void HUD::setWeapIcon(const char *str) |  | ||||||
| { |  | ||||||
|     weapImage->setImageTexture(str); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void HUD::setSpellIcon(const char *str) |  | ||||||
| { |  | ||||||
|     spellImage->setImageTexture(str); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void HUD::setWeapStatus(int s, int smax) |  | ||||||
| { |  | ||||||
|     weapStatus->setProgressRange(smax); |  | ||||||
|     weapStatus->setProgressPosition(s); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void HUD::setSpellStatus(int s, int smax) |  | ||||||
| { |  | ||||||
|     spellStatus->setProgressRange(smax); |  | ||||||
|     spellStatus->setProgressPosition(s); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void HUD::setEffect(const char *img) | void HUD::setEffect(const char *img) | ||||||
| { | { | ||||||
|     effect1->setImageTexture(img); |     effect1->setImageTexture(img); | ||||||
|  | @ -192,35 +194,6 @@ void HUD::setValue(const std::string& id, const MWMechanics::DynamicStat<int>& v | ||||||
|         } |         } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void HUD::setPlayerDir(const float x, const float y) |  | ||||||
| { |  | ||||||
|     if (!minimapBox->getVisible() || (x == mLastPositionX && y == mLastPositionY)) return; |  | ||||||
| 
 |  | ||||||
|     MyGUI::ISubWidget* main = compass->getSubWidgetMain(); |  | ||||||
|     MyGUI::RotatingSkin* rotatingSubskin = main->castType<MyGUI::RotatingSkin>(); |  | ||||||
|     rotatingSubskin->setCenter(MyGUI::IntPoint(16,16)); |  | ||||||
|     float angle = std::atan2(x,y); |  | ||||||
|     rotatingSubskin->setAngle(angle); |  | ||||||
|     mLastPositionX = x; |  | ||||||
|     mLastPositionY = y; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void HUD::setPlayerPos(const float x, const float y) |  | ||||||
| { |  | ||||||
|     if (!minimapBox->getVisible() || (x == mLastDirectionX && y == mLastDirectionY)) return; |  | ||||||
| 
 |  | ||||||
|     MyGUI::IntSize size = minimap->getCanvasSize(); |  | ||||||
|     MyGUI::IntPoint middle = MyGUI::IntPoint((1/3.f + x/3.f)*size.width,(1/3.f + y/3.f)*size.height); |  | ||||||
|     MyGUI::IntCoord viewsize = minimap->getCoord(); |  | ||||||
|     MyGUI::IntPoint pos(0.5*viewsize.width - middle.left, 0.5*viewsize.height - middle.top); |  | ||||||
| 
 |  | ||||||
|     minimap->setViewOffset(pos); |  | ||||||
|     compass->setPosition(MyGUI::IntPoint(x*512-16, y*512-16)); |  | ||||||
| 
 |  | ||||||
|     mLastDirectionX = x; |  | ||||||
|     mLastDirectionY = y; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void HUD::setBottomLeftVisibility(bool hmsVisible, bool weapVisible, bool spellVisible) | void HUD::setBottomLeftVisibility(bool hmsVisible, bool weapVisible, bool spellVisible) | ||||||
| { | { | ||||||
|     int weapDx = 0, spellDx = 0; |     int weapDx = 0, spellDx = 0; | ||||||
|  | @ -228,7 +201,12 @@ void HUD::setBottomLeftVisibility(bool hmsVisible, bool weapVisible, bool spellV | ||||||
|         spellDx = weapDx = weapBoxBaseLeft - hmsBaseLeft; |         spellDx = weapDx = weapBoxBaseLeft - hmsBaseLeft; | ||||||
| 
 | 
 | ||||||
|     if (!weapVisible) |     if (!weapVisible) | ||||||
|         spellDx -= spellBoxBaseLeft - weapBoxBaseLeft; |         spellDx += spellBoxBaseLeft - weapBoxBaseLeft; | ||||||
|  | 
 | ||||||
|  |     mWeaponVisible = weapVisible; | ||||||
|  |     mSpellVisible = spellVisible; | ||||||
|  |     if (!mWeaponVisible && !mSpellVisible) | ||||||
|  |         mWeaponSpellBox->setVisible(false); | ||||||
| 
 | 
 | ||||||
|     health->setVisible(hmsVisible); |     health->setVisible(hmsVisible); | ||||||
|     stamina->setVisible(hmsVisible); |     stamina->setVisible(hmsVisible); | ||||||
|  | @ -241,13 +219,16 @@ void HUD::setBottomLeftVisibility(bool hmsVisible, bool weapVisible, bool spellV | ||||||
| 
 | 
 | ||||||
| void HUD::setBottomRightVisibility(bool effectBoxVisible, bool minimapBoxVisible) | void HUD::setBottomRightVisibility(bool effectBoxVisible, bool minimapBoxVisible) | ||||||
| { | { | ||||||
|  |     const MyGUI::IntSize& viewSize = MyGUI::RenderManager::getInstance().getViewSize(); | ||||||
|  | 
 | ||||||
|     // effect box can have variable width -> variable left coordinate
 |     // effect box can have variable width -> variable left coordinate
 | ||||||
|     int effectsDx = 0; |     int effectsDx = 0; | ||||||
|     if (!minimapBoxVisible) |     if (!minimapBoxVisible) | ||||||
|         effectsDx = minimapBoxBaseRight - effectBoxBaseRight; |         effectsDx = (viewSize.width - minimapBoxBaseRight) - (viewSize.width - effectBoxBaseRight); | ||||||
| 
 | 
 | ||||||
|  |     mMapVisible = minimapBoxVisible; | ||||||
|     minimapBox->setVisible(minimapBoxVisible); |     minimapBox->setVisible(minimapBoxVisible); | ||||||
|     effectBox->setPosition(effectBoxBaseRight - effectBox->getWidth() + effectsDx, effectBox->getTop()); |     effectBox->setPosition((viewSize.width - effectBoxBaseRight) - effectBox->getWidth() + effectsDx, effectBox->getTop()); | ||||||
|     effectBox->setVisible(effectBoxVisible); |     effectBox->setVisible(effectBoxVisible); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -286,6 +267,33 @@ void HUD::onWorldClicked(MyGUI::Widget* _sender) | ||||||
|         mDragAndDrop->mDraggedWidget = 0; |         mDragAndDrop->mDraggedWidget = 0; | ||||||
| 
 | 
 | ||||||
|         MWBase::Environment::get().getWindowManager()->setDragDrop(false); |         MWBase::Environment::get().getWindowManager()->setDragDrop(false); | ||||||
|  |         MWBase::Environment::get().getWindowManager()->getInventoryWindow()->drawItems(); | ||||||
|  |     } | ||||||
|  |     else | ||||||
|  |     { | ||||||
|  |         GuiMode mode = MWBase::Environment::get().getWindowManager()->getMode(); | ||||||
|  | 
 | ||||||
|  |         if ( (mode != GM_Console) && (mode != GM_Container) && (mode != GM_Inventory) ) | ||||||
|  |             return; | ||||||
|  | 
 | ||||||
|  |         std::string handle = MWBase::Environment::get().getWorld()->getFacedHandle(); | ||||||
|  |         MWWorld::Ptr object; | ||||||
|  |         try | ||||||
|  |         { | ||||||
|  |             object = MWBase::Environment::get().getWorld()->getPtrViaHandle(handle); | ||||||
|  |         } | ||||||
|  |         catch (std::exception& e) | ||||||
|  |         { | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         if (mode == GM_Console) | ||||||
|  |             MWBase::Environment::get().getWindowManager()->getConsole()->setSelectedObject(object); | ||||||
|  |         else if ((mode == GM_Container) || (mode == GM_Inventory)) | ||||||
|  |         { | ||||||
|  |             // pick up object
 | ||||||
|  |             MWBase::Environment::get().getWindowManager()->getInventoryWindow()->pickUpObject(object); | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -293,6 +301,8 @@ void HUD::onWorldMouseOver(MyGUI::Widget* _sender, int x, int y) | ||||||
| { | { | ||||||
|     if (mDragAndDrop->mIsOnDragAndDrop) |     if (mDragAndDrop->mIsOnDragAndDrop) | ||||||
|     { |     { | ||||||
|  |         mWorldMouseOver = false; | ||||||
|  | 
 | ||||||
|         MyGUI::IntSize viewSize = MyGUI::RenderManager::getInstance().getViewSize(); |         MyGUI::IntSize viewSize = MyGUI::RenderManager::getInstance().getViewSize(); | ||||||
|         MyGUI::IntPoint cursorPosition = MyGUI::InputManager::getInstance().getMousePosition(); |         MyGUI::IntPoint cursorPosition = MyGUI::InputManager::getInstance().getMousePosition(); | ||||||
|         float mouseX = cursorPosition.left / float(viewSize.width); |         float mouseX = cursorPosition.left / float(viewSize.width); | ||||||
|  | @ -312,11 +322,195 @@ void HUD::onWorldMouseOver(MyGUI::Widget* _sender, int x, int y) | ||||||
|     else |     else | ||||||
|     { |     { | ||||||
|         MyGUI::PointerManager::getInstance().setPointer("arrow"); |         MyGUI::PointerManager::getInstance().setPointer("arrow"); | ||||||
|         /// \todo make it possible to pick up objects with the mouse, if inventory or container window is open
 |         mWorldMouseOver = true; | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void HUD::onWorldMouseLostFocus(MyGUI::Widget* _sender, MyGUI::Widget* _new) | void HUD::onWorldMouseLostFocus(MyGUI::Widget* _sender, MyGUI::Widget* _new) | ||||||
| { | { | ||||||
|     MyGUI::PointerManager::getInstance().setPointer("arrow"); |     MyGUI::PointerManager::getInstance().setPointer("arrow"); | ||||||
|  |     mWorldMouseOver = false; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void HUD::onHMSClicked(MyGUI::Widget* _sender) | ||||||
|  | { | ||||||
|  |     MWBase::Environment::get().getWindowManager()->toggleVisible(GW_Stats); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void HUD::onMapClicked(MyGUI::Widget* _sender) | ||||||
|  | { | ||||||
|  |     MWBase::Environment::get().getWindowManager()->toggleVisible(GW_Map); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void HUD::onWeaponClicked(MyGUI::Widget* _sender) | ||||||
|  | { | ||||||
|  |     MWBase::Environment::get().getWindowManager()->toggleVisible(GW_Inventory); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void HUD::onMagicClicked(MyGUI::Widget* _sender) | ||||||
|  | { | ||||||
|  |     MWBase::Environment::get().getWindowManager()->toggleVisible(GW_Magic); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void HUD::setCellName(const std::string& cellName) | ||||||
|  | { | ||||||
|  |     if (mCellName != cellName) | ||||||
|  |     { | ||||||
|  |         mCellNameTimer = 5.0f; | ||||||
|  |         mCellName = cellName; | ||||||
|  | 
 | ||||||
|  |         mCellNameBox->setCaption(mCellName); | ||||||
|  |         mCellNameBox->setVisible(mMapVisible); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void HUD::onFrame(float dt) | ||||||
|  | { | ||||||
|  |     mCellNameTimer -= dt; | ||||||
|  |     mWeaponSpellTimer -= dt; | ||||||
|  |     if (mCellNameTimer < 0) | ||||||
|  |         mCellNameBox->setVisible(false); | ||||||
|  |     if (mWeaponSpellTimer < 0) | ||||||
|  |         mWeaponSpellBox->setVisible(false); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void HUD::onResChange(int width, int height) | ||||||
|  | { | ||||||
|  |     setCoord(0, 0, width, height); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void HUD::setSelectedSpell(const std::string& spellId, int successChancePercent) | ||||||
|  | { | ||||||
|  |     const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().spells.find(spellId); | ||||||
|  |     std::string spellName = spell->name; | ||||||
|  |     if (spellName != mSpellName && mSpellVisible) | ||||||
|  |     { | ||||||
|  |         mWeaponSpellTimer = 5.0f; | ||||||
|  |         mSpellName = spellName; | ||||||
|  |         mWeaponSpellBox->setCaption(mSpellName); | ||||||
|  |         mWeaponSpellBox->setVisible(true); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     spellStatus->setProgressRange(100); | ||||||
|  |     spellStatus->setProgressPosition(successChancePercent); | ||||||
|  | 
 | ||||||
|  |     if (spellImage->getChildCount()) | ||||||
|  |         MyGUI::Gui::getInstance().destroyWidget(spellImage->getChildAt(0)); | ||||||
|  | 
 | ||||||
|  |     spellBox->setUserString("ToolTipType", "Spell"); | ||||||
|  |     spellBox->setUserString("Spell", spellId); | ||||||
|  | 
 | ||||||
|  |     // use the icon of the first effect
 | ||||||
|  |     const ESM::MagicEffect* effect = MWBase::Environment::get().getWorld()->getStore().magicEffects.find(spell->effects.list.front().effectID); | ||||||
|  |     std::string icon = effect->icon; | ||||||
|  |     int slashPos = icon.find("\\"); | ||||||
|  |     icon.insert(slashPos+1, "b_"); | ||||||
|  |     icon = std::string("icons\\") + icon; | ||||||
|  |     Widgets::fixTexturePath(icon); | ||||||
|  |     spellImage->setImageTexture(icon); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void HUD::setSelectedEnchantItem(const MWWorld::Ptr& item, int chargePercent) | ||||||
|  | { | ||||||
|  |     std::string itemName = MWWorld::Class::get(item).getName(item); | ||||||
|  |     if (itemName != mSpellName && mSpellVisible) | ||||||
|  |     { | ||||||
|  |         mWeaponSpellTimer = 5.0f; | ||||||
|  |         mSpellName = itemName; | ||||||
|  |         mWeaponSpellBox->setCaption(mSpellName); | ||||||
|  |         mWeaponSpellBox->setVisible(true); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     spellStatus->setProgressRange(100); | ||||||
|  |     spellStatus->setProgressPosition(chargePercent); | ||||||
|  | 
 | ||||||
|  |     if (spellImage->getChildCount()) | ||||||
|  |         MyGUI::Gui::getInstance().destroyWidget(spellImage->getChildAt(0)); | ||||||
|  | 
 | ||||||
|  |     spellBox->setUserString("ToolTipType", "ItemPtr"); | ||||||
|  |     spellBox->setUserData(item); | ||||||
|  | 
 | ||||||
|  |     spellImage->setImageTexture("textures\\menu_icon_magic_mini.dds"); | ||||||
|  |     MyGUI::ImageBox* itemBox = spellImage->createWidgetReal<MyGUI::ImageBox>("ImageBox", MyGUI::FloatCoord(0,0,1,1) | ||||||
|  |         , MyGUI::Align::Stretch); | ||||||
|  | 
 | ||||||
|  |     std::string path = std::string("icons\\"); | ||||||
|  |     path+=MWWorld::Class::get(item).getInventoryIcon(item); | ||||||
|  |     Widgets::fixTexturePath(path); | ||||||
|  |     itemBox->setImageTexture(path); | ||||||
|  |     itemBox->setNeedMouseFocus(false); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void HUD::setSelectedWeapon(const MWWorld::Ptr& item, int durabilityPercent) | ||||||
|  | { | ||||||
|  |     std::string itemName = MWWorld::Class::get(item).getName(item); | ||||||
|  |     if (itemName != mWeaponName && mWeaponVisible) | ||||||
|  |     { | ||||||
|  |         mWeaponSpellTimer = 5.0f; | ||||||
|  |         mWeaponName = itemName; | ||||||
|  |         mWeaponSpellBox->setCaption(mWeaponName); | ||||||
|  |         mWeaponSpellBox->setVisible(true); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     weapBox->setUserString("ToolTipType", "ItemPtr"); | ||||||
|  |     weapBox->setUserData(item); | ||||||
|  | 
 | ||||||
|  |     weapStatus->setProgressRange(100); | ||||||
|  |     weapStatus->setProgressPosition(durabilityPercent); | ||||||
|  | 
 | ||||||
|  |     if (weapImage->getChildCount()) | ||||||
|  |         MyGUI::Gui::getInstance().destroyWidget(weapImage->getChildAt(0)); | ||||||
|  | 
 | ||||||
|  |     std::string path = std::string("icons\\"); | ||||||
|  |     path+=MWWorld::Class::get(item).getInventoryIcon(item); | ||||||
|  |     Widgets::fixTexturePath(path); | ||||||
|  | 
 | ||||||
|  |     if (MWWorld::Class::get(item).getEnchantment(item) != "") | ||||||
|  |     { | ||||||
|  |         weapImage->setImageTexture("textures\\menu_icon_magic_mini.dds"); | ||||||
|  |         MyGUI::ImageBox* itemBox = weapImage->createWidgetReal<MyGUI::ImageBox>("ImageBox", MyGUI::FloatCoord(0,0,1,1) | ||||||
|  |             , MyGUI::Align::Stretch); | ||||||
|  |         itemBox->setImageTexture(path); | ||||||
|  |         itemBox->setNeedMouseFocus(false); | ||||||
|  |     } | ||||||
|  |     else | ||||||
|  |         weapImage->setImageTexture(path); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void HUD::unsetSelectedSpell() | ||||||
|  | { | ||||||
|  |     std::string spellName = "#{sNone}"; | ||||||
|  |     if (spellName != mSpellName && mSpellVisible) | ||||||
|  |     { | ||||||
|  |         mWeaponSpellTimer = 5.0f; | ||||||
|  |         mSpellName = spellName; | ||||||
|  |         mWeaponSpellBox->setCaptionWithReplacing(mSpellName); | ||||||
|  |         mWeaponSpellBox->setVisible(true); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (spellImage->getChildCount()) | ||||||
|  |         MyGUI::Gui::getInstance().destroyWidget(spellImage->getChildAt(0)); | ||||||
|  |     spellStatus->setProgressRange(100); | ||||||
|  |     spellStatus->setProgressPosition(0); | ||||||
|  |     spellImage->setImageTexture(""); | ||||||
|  |     spellBox->clearUserStrings(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void HUD::unsetSelectedWeapon() | ||||||
|  | { | ||||||
|  |     std::string itemName = "#{sSkillHandtohand}"; | ||||||
|  |     if (itemName != mWeaponName && mWeaponVisible) | ||||||
|  |     { | ||||||
|  |         mWeaponSpellTimer = 5.0f; | ||||||
|  |         mWeaponName = itemName; | ||||||
|  |         mWeaponSpellBox->setCaptionWithReplacing(mWeaponName); | ||||||
|  |         mWeaponSpellBox->setVisible(true); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (weapImage->getChildCount()) | ||||||
|  |         MyGUI::Gui::getInstance().destroyWidget(weapImage->getChildAt(0)); | ||||||
|  |     weapStatus->setProgressRange(100); | ||||||
|  |     weapStatus->setProgressPosition(0); | ||||||
|  |     weapImage->setImageTexture("icons\\k\\stealth_handtohand.dds"); | ||||||
|  |     weapBox->clearUserStrings(); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -3,6 +3,7 @@ | ||||||
| #include <openengine/gui/layout.hpp> | #include <openengine/gui/layout.hpp> | ||||||
| 
 | 
 | ||||||
| #include "../mwmechanics/stat.hpp" | #include "../mwmechanics/stat.hpp" | ||||||
|  | #include "../mwworld/ptr.hpp" | ||||||
| 
 | 
 | ||||||
| namespace MWGui | namespace MWGui | ||||||
| { | { | ||||||
|  | @ -12,22 +13,30 @@ namespace MWGui | ||||||
|     { |     { | ||||||
|     public: |     public: | ||||||
|         HUD(int width, int height, int fpsLevel, DragAndDrop* dragAndDrop); |         HUD(int width, int height, int fpsLevel, DragAndDrop* dragAndDrop); | ||||||
|         void setWeapIcon(const char *str); |  | ||||||
|         void setSpellIcon(const char *str); |  | ||||||
|         void setWeapStatus(int s, int smax); |  | ||||||
|         void setSpellStatus(int s, int smax); |  | ||||||
|         void setEffect(const char *img); |         void setEffect(const char *img); | ||||||
|         void setValue (const std::string& id, const MWMechanics::DynamicStat<int>& value); |         void setValue (const std::string& id, const MWMechanics::DynamicStat<int>& value); | ||||||
|         void setFPS(float fps); |         void setFPS(float fps); | ||||||
|         void setTriangleCount(size_t count); |         void setTriangleCount(size_t count); | ||||||
|         void setBatchCount(size_t count); |         void setBatchCount(size_t count); | ||||||
|         void setPlayerDir(const float x, const float y); |  | ||||||
|         void setPlayerPos(const float x, const float y); |  | ||||||
|         void setBottomLeftVisibility(bool hmsVisible, bool weapVisible, bool spellVisible); |         void setBottomLeftVisibility(bool hmsVisible, bool weapVisible, bool spellVisible); | ||||||
|         void setBottomRightVisibility(bool effectBoxVisible, bool minimapVisible); |         void setBottomRightVisibility(bool effectBoxVisible, bool minimapVisible); | ||||||
|         void setFpsLevel(const int level); |         void setFpsLevel(const int level); | ||||||
| 
 | 
 | ||||||
|  |         void setSelectedSpell(const std::string& spellId, int successChancePercent); | ||||||
|  |         void setSelectedEnchantItem(const MWWorld::Ptr& item, int chargePercent); | ||||||
|  |         void setSelectedWeapon(const MWWorld::Ptr& item, int durabilityPercent); | ||||||
|  |         void unsetSelectedSpell(); | ||||||
|  |         void unsetSelectedWeapon(); | ||||||
|  | 
 | ||||||
|  |         void onFrame(float dt); | ||||||
|  |         void onResChange(int width, int height); | ||||||
|  | 
 | ||||||
|  |         void setCellName(const std::string& cellName); | ||||||
|  | 
 | ||||||
|  |         bool getWorldMouseOver() { return mWorldMouseOver; } | ||||||
|  | 
 | ||||||
|         MyGUI::ProgressPtr health, magicka, stamina; |         MyGUI::ProgressPtr health, magicka, stamina; | ||||||
|  |         MyGUI::Widget* mHealthFrame; | ||||||
|         MyGUI::Widget *weapBox, *spellBox; |         MyGUI::Widget *weapBox, *spellBox; | ||||||
|         MyGUI::ImageBox *weapImage, *spellImage; |         MyGUI::ImageBox *weapImage, *spellImage; | ||||||
|         MyGUI::ProgressPtr weapStatus, spellStatus; |         MyGUI::ProgressPtr weapStatus, spellStatus; | ||||||
|  | @ -36,6 +45,8 @@ namespace MWGui | ||||||
|         MyGUI::ScrollView* minimap; |         MyGUI::ScrollView* minimap; | ||||||
|         MyGUI::ImageBox* compass; |         MyGUI::ImageBox* compass; | ||||||
|         MyGUI::ImageBox* crosshair; |         MyGUI::ImageBox* crosshair; | ||||||
|  |         MyGUI::TextBox* mCellNameBox; | ||||||
|  |         MyGUI::TextBox* mWeaponSpellBox; | ||||||
| 
 | 
 | ||||||
|         MyGUI::WidgetPtr fpsbox; |         MyGUI::WidgetPtr fpsbox; | ||||||
|         MyGUI::TextBox* fpscounter; |         MyGUI::TextBox* fpscounter; | ||||||
|  | @ -50,8 +61,25 @@ namespace MWGui | ||||||
| 
 | 
 | ||||||
|         DragAndDrop* mDragAndDrop; |         DragAndDrop* mDragAndDrop; | ||||||
| 
 | 
 | ||||||
|  |         std::string mCellName; | ||||||
|  |         float mCellNameTimer; | ||||||
|  | 
 | ||||||
|  |         std::string mWeaponName; | ||||||
|  |         std::string mSpellName; | ||||||
|  |         float mWeaponSpellTimer; | ||||||
|  | 
 | ||||||
|  |         bool mMapVisible; | ||||||
|  |         bool mWeaponVisible; | ||||||
|  |         bool mSpellVisible; | ||||||
|  | 
 | ||||||
|  |         bool mWorldMouseOver; | ||||||
|  | 
 | ||||||
|         void onWorldClicked(MyGUI::Widget* _sender); |         void onWorldClicked(MyGUI::Widget* _sender); | ||||||
|         void onWorldMouseOver(MyGUI::Widget* _sender, int x, int y); |         void onWorldMouseOver(MyGUI::Widget* _sender, int x, int y); | ||||||
|         void onWorldMouseLostFocus(MyGUI::Widget* _sender, MyGUI::Widget* _new); |         void onWorldMouseLostFocus(MyGUI::Widget* _sender, MyGUI::Widget* _new); | ||||||
|  |         void onHMSClicked(MyGUI::Widget* _sender); | ||||||
|  |         void onWeaponClicked(MyGUI::Widget* _sender); | ||||||
|  |         void onMagicClicked(MyGUI::Widget* _sender); | ||||||
|  |         void onMapClicked(MyGUI::Widget* _sender); | ||||||
|     }; |     }; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -15,11 +15,14 @@ | ||||||
| #include "../mwworld/player.hpp" | #include "../mwworld/player.hpp" | ||||||
| #include "../mwbase/environment.hpp" | #include "../mwbase/environment.hpp" | ||||||
| #include "../mwworld/manualref.hpp" | #include "../mwworld/manualref.hpp" | ||||||
|  | #include "../mwworld/actiontake.hpp" | ||||||
|  | #include "../mwsound/soundmanager.hpp" | ||||||
| 
 | 
 | ||||||
| #include "window_manager.hpp" | #include "window_manager.hpp" | ||||||
| #include "widgets.hpp" | #include "widgets.hpp" | ||||||
| #include "bookwindow.hpp" | #include "bookwindow.hpp" | ||||||
| #include "scrollwindow.hpp" | #include "scrollwindow.hpp" | ||||||
|  | #include "spellwindow.hpp" | ||||||
| 
 | 
 | ||||||
| namespace | namespace | ||||||
| { | { | ||||||
|  | @ -91,13 +94,13 @@ namespace MWGui | ||||||
| 
 | 
 | ||||||
|         mFilterAll->setStateSelected(true); |         mFilterAll->setStateSelected(true); | ||||||
| 
 | 
 | ||||||
|         setCoord(0, 342, 600, 258); |         setCoord(0, 342, 498, 258); | ||||||
| 
 | 
 | ||||||
|         MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); |         MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); | ||||||
|         openContainer(player); |         openContainer(player); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     void InventoryWindow::openInventory() |     void InventoryWindow::open() | ||||||
|     { |     { | ||||||
|         updateEncumbranceBar(); |         updateEncumbranceBar(); | ||||||
| 
 | 
 | ||||||
|  | @ -155,7 +158,7 @@ namespace MWGui | ||||||
|             if (mDragAndDrop->mDraggedFrom != this) |             if (mDragAndDrop->mDraggedFrom != this) | ||||||
|             { |             { | ||||||
|                 // add item to the player's inventory
 |                 // add item to the player's inventory
 | ||||||
|                 MWWorld::ContainerStore& invStore = MWWorld::Class::get(mContainer).getContainerStore(mContainer); |                 MWWorld::ContainerStore& invStore = MWWorld::Class::get(mPtr).getContainerStore(mPtr); | ||||||
|                 MWWorld::ContainerStoreIterator it = invStore.begin(); |                 MWWorld::ContainerStoreIterator it = invStore.begin(); | ||||||
| 
 | 
 | ||||||
|                 int origCount = ptr.getRefData().getCount(); |                 int origCount = ptr.getRefData().getCount(); | ||||||
|  | @ -187,12 +190,21 @@ namespace MWGui | ||||||
|             mWindowManager.setDragDrop(false); |             mWindowManager.setDragDrop(false); | ||||||
| 
 | 
 | ||||||
|             drawItems(); |             drawItems(); | ||||||
|  | 
 | ||||||
|  |             // update selected weapon icon
 | ||||||
|  |             MWWorld::InventoryStore& invStore = MWWorld::Class::get(mPtr).getInventoryStore(mPtr); | ||||||
|  |             MWWorld::ContainerStoreIterator weaponSlot = invStore.getSlot(MWWorld::InventoryStore::Slot_CarriedRight); | ||||||
|  |             if (weaponSlot == invStore.end()) | ||||||
|  |                 mWindowManager.unsetSelectedWeapon(); | ||||||
|  |             else | ||||||
|  |                 mWindowManager.setSelectedWeapon(*weaponSlot, 100); /// \todo track weapon durability
 | ||||||
|  | 
 | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     std::vector<MWWorld::Ptr> InventoryWindow::getEquippedItems() |     std::vector<MWWorld::Ptr> InventoryWindow::getEquippedItems() | ||||||
|     { |     { | ||||||
|         MWWorld::InventoryStore& invStore = MWWorld::Class::get(mContainer).getInventoryStore(mContainer); |         MWWorld::InventoryStore& invStore = MWWorld::Class::get(mPtr).getInventoryStore(mPtr); | ||||||
| 
 | 
 | ||||||
|         std::vector<MWWorld::Ptr> items; |         std::vector<MWWorld::Ptr> items; | ||||||
| 
 | 
 | ||||||
|  | @ -210,7 +222,7 @@ namespace MWGui | ||||||
| 
 | 
 | ||||||
|     void InventoryWindow::_unequipItem(MWWorld::Ptr item) |     void InventoryWindow::_unequipItem(MWWorld::Ptr item) | ||||||
|     { |     { | ||||||
|         MWWorld::InventoryStore& invStore = MWWorld::Class::get(mContainer).getInventoryStore(mContainer); |         MWWorld::InventoryStore& invStore = MWWorld::Class::get(mPtr).getInventoryStore(mPtr); | ||||||
| 
 | 
 | ||||||
|         for (int slot=0; slot < MWWorld::InventoryStore::Slots; ++slot) |         for (int slot=0; slot < MWWorld::InventoryStore::Slots; ++slot) | ||||||
|         { |         { | ||||||
|  | @ -244,7 +256,7 @@ namespace MWGui | ||||||
| 
 | 
 | ||||||
|     int InventoryWindow::getPlayerGold() |     int InventoryWindow::getPlayerGold() | ||||||
|     { |     { | ||||||
|         MWWorld::InventoryStore& invStore = MWWorld::Class::get(mContainer).getInventoryStore(mContainer); |         MWWorld::InventoryStore& invStore = MWWorld::Class::get(mPtr).getInventoryStore(mPtr); | ||||||
| 
 | 
 | ||||||
|         for (MWWorld::ContainerStoreIterator it = invStore.begin(); |         for (MWWorld::ContainerStoreIterator it = invStore.begin(); | ||||||
|                 it != invStore.end(); ++it) |                 it != invStore.end(); ++it) | ||||||
|  | @ -259,4 +271,79 @@ namespace MWGui | ||||||
|     { |     { | ||||||
|         mTrading = true; |         mTrading = true; | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     void InventoryWindow::notifyContentChanged() | ||||||
|  |     { | ||||||
|  |         // update the spell window just in case new enchanted items were added to inventory
 | ||||||
|  |         if (mWindowManager.getSpellWindow()) | ||||||
|  |             mWindowManager.getSpellWindow()->updateSpells(); | ||||||
|  | 
 | ||||||
|  |         // update selected weapon icon
 | ||||||
|  |         MWWorld::InventoryStore& invStore = MWWorld::Class::get(mPtr).getInventoryStore(mPtr); | ||||||
|  |         MWWorld::ContainerStoreIterator weaponSlot = invStore.getSlot(MWWorld::InventoryStore::Slot_CarriedRight); | ||||||
|  |         if (weaponSlot == invStore.end()) | ||||||
|  |             mWindowManager.unsetSelectedWeapon(); | ||||||
|  |         else | ||||||
|  |             mWindowManager.setSelectedWeapon(*weaponSlot, 100); /// \todo track weapon durability
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     void InventoryWindow::pickUpObject (MWWorld::Ptr object) | ||||||
|  |     { | ||||||
|  |         /// \todo scripts
 | ||||||
|  | 
 | ||||||
|  |         // make sure the object is of a type that can be picked up
 | ||||||
|  |         std::string type = object.getTypeName(); | ||||||
|  |         if ( (type != typeid(ESM::Apparatus).name()) | ||||||
|  |             && (type != typeid(ESM::Armor).name()) | ||||||
|  |             && (type != typeid(ESM::Book).name()) | ||||||
|  |             && (type != typeid(ESM::Clothing).name()) | ||||||
|  |             && (type != typeid(ESM::Ingredient).name()) | ||||||
|  |             && (type != typeid(ESM::Light).name()) | ||||||
|  |             && (type != typeid(ESM::Miscellaneous).name()) | ||||||
|  |             && (type != typeid(ESM::Tool).name()) | ||||||
|  |             && (type != typeid(ESM::Probe).name()) | ||||||
|  |             && (type != typeid(ESM::Repair).name()) | ||||||
|  |             && (type != typeid(ESM::Weapon).name()) | ||||||
|  |             && (type != typeid(ESM::Potion).name())) | ||||||
|  |             return; | ||||||
|  | 
 | ||||||
|  |         // sound
 | ||||||
|  |         std::string sound = MWWorld::Class::get(object).getUpSoundId(object); | ||||||
|  |         MWBase::Environment::get().getSoundManager()->playSound(sound, 1, 1); | ||||||
|  | 
 | ||||||
|  |         int count = object.getRefData().getCount(); | ||||||
|  | 
 | ||||||
|  |         // add to player inventory
 | ||||||
|  |         // can't use ActionTake here because we need an MWWorld::Ptr to the newly inserted object
 | ||||||
|  |         MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); | ||||||
|  |         MWWorld::Ptr newObject = *MWWorld::Class::get (player).getContainerStore (player).add (object); | ||||||
|  |         // remove from world
 | ||||||
|  |         MWBase::Environment::get().getWorld()->deleteObject (object); | ||||||
|  | 
 | ||||||
|  |         mDragAndDrop->mIsOnDragAndDrop = true; | ||||||
|  |         mDragAndDrop->mDraggedCount = count; | ||||||
|  | 
 | ||||||
|  |         std::string path = std::string("icons\\"); | ||||||
|  |         path += MWWorld::Class::get(newObject).getInventoryIcon(newObject); | ||||||
|  |         MyGUI::ImageBox* baseWidget = mContainerWidget->createWidget<ImageBox>("ImageBox", MyGUI::IntCoord(0, 0, 42, 42), MyGUI::Align::Default); | ||||||
|  |         baseWidget->detachFromWidget(); | ||||||
|  |         baseWidget->attachToWidget(mDragAndDrop->mDragAndDropWidget); | ||||||
|  |         baseWidget->setUserData(newObject); | ||||||
|  |         mDragAndDrop->mDraggedWidget = baseWidget; | ||||||
|  |         ImageBox* image = baseWidget->createWidget<ImageBox>("ImageBox", MyGUI::IntCoord(5, 5, 32, 32), MyGUI::Align::Default); | ||||||
|  |         int pos = path.rfind("."); | ||||||
|  |         path.erase(pos); | ||||||
|  |         path.append(".dds"); | ||||||
|  |         image->setImageTexture(path); | ||||||
|  |         image->setNeedMouseFocus(false); | ||||||
|  | 
 | ||||||
|  |         // text widget that shows item count
 | ||||||
|  |         MyGUI::TextBox* text = image->createWidget<MyGUI::TextBox>("SandBrightText", MyGUI::IntCoord(0, 14, 32, 18), MyGUI::Align::Default, std::string("Label")); | ||||||
|  |         text->setTextAlign(MyGUI::Align::Right); | ||||||
|  |         text->setNeedMouseFocus(false); | ||||||
|  |         text->setTextShadow(true); | ||||||
|  |         text->setTextShadowColour(MyGUI::Colour(0,0,0)); | ||||||
|  |         text->setCaption(getCountString(count)); | ||||||
|  |         mDragAndDrop->mDraggedFrom = this; | ||||||
|  |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -11,13 +11,15 @@ namespace MWGui | ||||||
|         public: |         public: | ||||||
|             InventoryWindow(WindowManager& parWindowManager,DragAndDrop* dragAndDrop); |             InventoryWindow(WindowManager& parWindowManager,DragAndDrop* dragAndDrop); | ||||||
| 
 | 
 | ||||||
|             void openInventory(); |             virtual void open(); | ||||||
| 
 | 
 | ||||||
|             /// start trading, disables item drag&drop
 |             /// start trading, disables item drag&drop
 | ||||||
|             void startTrade(); |             void startTrade(); | ||||||
| 
 | 
 | ||||||
|             void onFrame(); |             void onFrame(); | ||||||
| 
 | 
 | ||||||
|  |             void pickUpObject (MWWorld::Ptr object); | ||||||
|  | 
 | ||||||
|             int getPlayerGold(); |             int getPlayerGold(); | ||||||
| 
 | 
 | ||||||
|         protected: |         protected: | ||||||
|  | @ -48,6 +50,10 @@ namespace MWGui | ||||||
|             virtual bool isInventory() { return true; } |             virtual bool isInventory() { return true; } | ||||||
|             virtual std::vector<MWWorld::Ptr> getEquippedItems(); |             virtual std::vector<MWWorld::Ptr> getEquippedItems(); | ||||||
|             virtual void _unequipItem(MWWorld::Ptr item); |             virtual void _unequipItem(MWWorld::Ptr item); | ||||||
|  | 
 | ||||||
|  |             virtual void onReferenceUnavailable() { ; } | ||||||
|  | 
 | ||||||
|  |             virtual void notifyContentChanged(); | ||||||
|     }; |     }; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -131,7 +131,7 @@ void MWGui::JournalWindow::open() | ||||||
|         book journal; |         book journal; | ||||||
|         journal.endLine = 0; |         journal.endLine = 0; | ||||||
| 
 | 
 | ||||||
|         for(std::deque<MWDialogue::StampedJournalEntry>::const_iterator it = MWBase::Environment::get().getJournal()->begin();it!=MWBase::Environment::get().getJournal()->end();it++) |         for(std::deque<MWDialogue::StampedJournalEntry>::const_iterator it = MWBase::Environment::get().getJournal()->begin();it!=MWBase::Environment::get().getJournal()->end();++it) | ||||||
|         { |         { | ||||||
|             std::string a = it->getText(MWBase::Environment::get().getWorld()->getStore()); |             std::string a = it->getText(MWBase::Environment::get().getWorld()->getStore()); | ||||||
|             journal = formatText(a,journal,10,17); |             journal = formatText(a,journal,10,17); | ||||||
|  | @ -141,7 +141,7 @@ void MWGui::JournalWindow::open() | ||||||
|         //std::string a = MWBase::Environment::get().getJournal()->begin()->getText(MWBase::Environment::get().getWorld()->getStore());
 |         //std::string a = MWBase::Environment::get().getJournal()->begin()->getText(MWBase::Environment::get().getWorld()->getStore());
 | ||||||
|         //std::list<std::string> journal = formatText(a,10,20,1);
 |         //std::list<std::string> journal = formatText(a,10,20,1);
 | ||||||
|         bool left = true; |         bool left = true; | ||||||
|         for(std::list<std::string>::iterator it = journal.pages.begin(); it != journal.pages.end();it++) |         for(std::list<std::string>::iterator it = journal.pages.begin(); it != journal.pages.end();++it) | ||||||
|         { |         { | ||||||
|             if(left) |             if(left) | ||||||
|             { |             { | ||||||
|  |  | ||||||
|  | @ -11,6 +11,7 @@ LocalMapBase::LocalMapBase() | ||||||
|     , mInterior(false) |     , mInterior(false) | ||||||
|     , mFogOfWar(true) |     , mFogOfWar(true) | ||||||
|     , mLocalMap(NULL) |     , mLocalMap(NULL) | ||||||
|  |     , mMapDragAndDrop(false) | ||||||
|     , mPrefix() |     , mPrefix() | ||||||
|     , mChanged(true) |     , mChanged(true) | ||||||
|     , mLayout(NULL) |     , mLayout(NULL) | ||||||
|  | @ -18,13 +19,41 @@ LocalMapBase::LocalMapBase() | ||||||
|     , mLastPositionY(0.0f) |     , mLastPositionY(0.0f) | ||||||
|     , mLastDirectionX(0.0f) |     , mLastDirectionX(0.0f) | ||||||
|     , mLastDirectionY(0.0f) |     , mLastDirectionY(0.0f) | ||||||
|  |     , mCompass(NULL) | ||||||
| { | { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void LocalMapBase::init(MyGUI::ScrollView* widget, OEngine::GUI::Layout* layout) | void LocalMapBase::init(MyGUI::ScrollView* widget, MyGUI::ImageBox* compass, OEngine::GUI::Layout* layout, bool mapDragAndDrop) | ||||||
| { | { | ||||||
|     mLocalMap = widget; |     mLocalMap = widget; | ||||||
|     mLayout = layout; |     mLayout = layout; | ||||||
|  |     mMapDragAndDrop = mapDragAndDrop; | ||||||
|  |     mCompass = compass; | ||||||
|  | 
 | ||||||
|  |     // create 3x3 map widgets, 512x512 each, holding a 1024x1024 texture each
 | ||||||
|  |     const int widgetSize = 512; | ||||||
|  |     for (int mx=0; mx<3; ++mx) | ||||||
|  |     { | ||||||
|  |         for (int my=0; my<3; ++my) | ||||||
|  |         { | ||||||
|  |             MyGUI::ImageBox* map = mLocalMap->createWidget<MyGUI::ImageBox>("ImageBox", | ||||||
|  |                 MyGUI::IntCoord(mx*widgetSize, my*widgetSize, widgetSize, widgetSize), | ||||||
|  |                 MyGUI::Align::Top | MyGUI::Align::Left, "Map_" + boost::lexical_cast<std::string>(mx) + "_" + boost::lexical_cast<std::string>(my)); | ||||||
|  | 
 | ||||||
|  |             MyGUI::ImageBox* fog = map->createWidget<MyGUI::ImageBox>("ImageBox", | ||||||
|  |                 MyGUI::IntCoord(0, 0, widgetSize, widgetSize), | ||||||
|  |                 MyGUI::Align::Top | MyGUI::Align::Left, "Map_" + boost::lexical_cast<std::string>(mx) + "_" + boost::lexical_cast<std::string>(my) + "_fog"); | ||||||
|  | 
 | ||||||
|  |             if (!mMapDragAndDrop) | ||||||
|  |             { | ||||||
|  |                 map->setNeedMouseFocus(false); | ||||||
|  |                 fog->setNeedMouseFocus(false); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             mMapWidgets.push_back(map); | ||||||
|  |             mFogWidgets.push_back(fog); | ||||||
|  |         } | ||||||
|  |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void LocalMapBase::setCellPrefix(const std::string& prefix) | void LocalMapBase::setCellPrefix(const std::string& prefix) | ||||||
|  | @ -47,10 +76,10 @@ void LocalMapBase::applyFogOfWar() | ||||||
|         { |         { | ||||||
|             std::string name = "Map_" + boost::lexical_cast<std::string>(mx) + "_" |             std::string name = "Map_" + boost::lexical_cast<std::string>(mx) + "_" | ||||||
|                     + boost::lexical_cast<std::string>(my); |                     + boost::lexical_cast<std::string>(my); | ||||||
|  | 
 | ||||||
|             std::string image = mPrefix+"_"+ boost::lexical_cast<std::string>(mCurX + (mx-1)) + "_" |             std::string image = mPrefix+"_"+ boost::lexical_cast<std::string>(mCurX + (mx-1)) + "_" | ||||||
|                     + boost::lexical_cast<std::string>(mCurY + (mInterior ? (my-1) : -1*(my-1))); |                     + boost::lexical_cast<std::string>(mCurY + (mInterior ? (my-1) : -1*(my-1))); | ||||||
|             MyGUI::ImageBox* fog; |             MyGUI::ImageBox* fog = mFogWidgets[my + 3*mx]; | ||||||
|             mLayout->getWidget(fog, name+"_fog"); |  | ||||||
|             fog->setImageTexture(mFogOfWar ? |             fog->setImageTexture(mFogOfWar ? | ||||||
|                 ((MyGUI::RenderManager::getInstance().getTexture(image+"_fog") != 0) ? image+"_fog" |                 ((MyGUI::RenderManager::getInstance().getTexture(image+"_fog") != 0) ? image+"_fog" | ||||||
|                 : "black.png" ) |                 : "black.png" ) | ||||||
|  | @ -66,14 +95,13 @@ void LocalMapBase::setActiveCell(const int x, const int y, bool interior) | ||||||
|     { |     { | ||||||
|         for (int my=0; my<3; ++my) |         for (int my=0; my<3; ++my) | ||||||
|         { |         { | ||||||
|             std::string name = "Map_" + boost::lexical_cast<std::string>(mx) + "_" |  | ||||||
|                     + boost::lexical_cast<std::string>(my); |  | ||||||
| 
 |  | ||||||
|             std::string image = mPrefix+"_"+ boost::lexical_cast<std::string>(x + (mx-1)) + "_" |             std::string image = mPrefix+"_"+ boost::lexical_cast<std::string>(x + (mx-1)) + "_" | ||||||
|                     + boost::lexical_cast<std::string>(y + (interior ? (my-1) : -1*(my-1))); |                     + boost::lexical_cast<std::string>(y + (interior ? (my-1) : -1*(my-1))); | ||||||
| 
 | 
 | ||||||
|             MyGUI::ImageBox* box; |             std::string name = "Map_" + boost::lexical_cast<std::string>(mx) + "_" | ||||||
|             mLayout->getWidget(box, name); |                     + boost::lexical_cast<std::string>(my); | ||||||
|  | 
 | ||||||
|  |             MyGUI::ImageBox* box = mMapWidgets[my + 3*mx]; | ||||||
| 
 | 
 | ||||||
|             if (MyGUI::RenderManager::getInstance().getTexture(image) != 0) |             if (MyGUI::RenderManager::getInstance().getTexture(image) != 0) | ||||||
|                 box->setImageTexture(image); |                 box->setImageTexture(image); | ||||||
|  | @ -86,6 +114,42 @@ void LocalMapBase::setActiveCell(const int x, const int y, bool interior) | ||||||
|     mCurY = y; |     mCurY = y; | ||||||
|     mChanged = false; |     mChanged = false; | ||||||
|     applyFogOfWar(); |     applyFogOfWar(); | ||||||
|  | 
 | ||||||
|  |     // set the compass texture again, because MyGUI determines sorting of ImageBox widgets
 | ||||||
|  |     // based on the last setImageTexture call
 | ||||||
|  |     std::string tex = "textures\\compass.dds"; | ||||||
|  |     mCompass->setImageTexture(""); | ||||||
|  |     mCompass->setImageTexture(tex); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | void LocalMapBase::setPlayerPos(const float x, const float y) | ||||||
|  | { | ||||||
|  |     if (x == mLastPositionX && y == mLastPositionY) | ||||||
|  |         return; | ||||||
|  |     MyGUI::IntSize size = mLocalMap->getCanvasSize(); | ||||||
|  |     MyGUI::IntPoint middle = MyGUI::IntPoint((1/3.f + x/3.f)*size.width,(1/3.f + y/3.f)*size.height); | ||||||
|  |     MyGUI::IntCoord viewsize = mLocalMap->getCoord(); | ||||||
|  |     MyGUI::IntPoint pos(0.5*viewsize.width - middle.left, 0.5*viewsize.height - middle.top); | ||||||
|  |     mLocalMap->setViewOffset(pos); | ||||||
|  | 
 | ||||||
|  |     mCompass->setPosition(MyGUI::IntPoint(512+x*512-16, 512+y*512-16)); | ||||||
|  |     mLastPositionX = x; | ||||||
|  |     mLastPositionY = y; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void LocalMapBase::setPlayerDir(const float x, const float y) | ||||||
|  | { | ||||||
|  |     if (x == mLastDirectionX && y == mLastDirectionY) | ||||||
|  |         return; | ||||||
|  |     MyGUI::ISubWidget* main = mCompass->getSubWidgetMain(); | ||||||
|  |     MyGUI::RotatingSkin* rotatingSubskin = main->castType<MyGUI::RotatingSkin>(); | ||||||
|  |     rotatingSubskin->setCenter(MyGUI::IntPoint(16,16)); | ||||||
|  |     float angle = std::atan2(x,y); | ||||||
|  |     rotatingSubskin->setAngle(angle); | ||||||
|  | 
 | ||||||
|  |     mLastDirectionX = x; | ||||||
|  |     mLastDirectionY = y; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // ------------------------------------------------------------------------------------------
 | // ------------------------------------------------------------------------------------------
 | ||||||
|  | @ -102,7 +166,7 @@ MapWindow::MapWindow(WindowManager& parWindowManager) : | ||||||
| 
 | 
 | ||||||
|     getWidget(mButton, "WorldButton"); |     getWidget(mButton, "WorldButton"); | ||||||
|     mButton->eventMouseButtonClick += MyGUI::newDelegate(this, &MapWindow::onWorldButtonClicked); |     mButton->eventMouseButtonClick += MyGUI::newDelegate(this, &MapWindow::onWorldButtonClicked); | ||||||
|     mButton->setCaption(mWindowManager.getGameSettingString("sWorld", "")); |     mButton->setCaptionWithReplacing("#{sWorld}"); | ||||||
|     int width = mButton->getTextSize().width + 24; |     int width = mButton->getTextSize().width + 24; | ||||||
|     mButton->setCoord(mMainWidget->getSize().width - width - 22, mMainWidget->getSize().height - 64, width, 22); |     mButton->setCoord(mMainWidget->getSize().width - width - 22, mMainWidget->getSize().height - 64, width, 22); | ||||||
| 
 | 
 | ||||||
|  | @ -111,7 +175,7 @@ MapWindow::MapWindow(WindowManager& parWindowManager) : | ||||||
|     eventbox->eventMouseDrag += MyGUI::newDelegate(this, &MapWindow::onMouseDrag); |     eventbox->eventMouseDrag += MyGUI::newDelegate(this, &MapWindow::onMouseDrag); | ||||||
|     eventbox->eventMouseButtonPressed += MyGUI::newDelegate(this, &MapWindow::onDragStart); |     eventbox->eventMouseButtonPressed += MyGUI::newDelegate(this, &MapWindow::onDragStart); | ||||||
| 
 | 
 | ||||||
|     LocalMapBase::init(mLocalMap, this); |     LocalMapBase::init(mLocalMap, mPlayerArrow, this); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void MapWindow::setCellName(const std::string& cellName) | void MapWindow::setCellName(const std::string& cellName) | ||||||
|  | @ -119,33 +183,6 @@ void MapWindow::setCellName(const std::string& cellName) | ||||||
|     setTitle(cellName); |     setTitle(cellName); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void MapWindow::setPlayerPos(const float x, const float y) |  | ||||||
| { |  | ||||||
|     if (mGlobal || !mVisible || (x == mLastPositionX && y == mLastPositionY)) return; |  | ||||||
|     MyGUI::IntSize size = mLocalMap->getCanvasSize(); |  | ||||||
|     MyGUI::IntPoint middle = MyGUI::IntPoint((1/3.f + x/3.f)*size.width,(1/3.f + y/3.f)*size.height); |  | ||||||
|     MyGUI::IntCoord viewsize = mLocalMap->getCoord(); |  | ||||||
|     MyGUI::IntPoint pos(0.5*viewsize.width - middle.left, 0.5*viewsize.height - middle.top); |  | ||||||
|     mLocalMap->setViewOffset(pos); |  | ||||||
| 
 |  | ||||||
|     mPlayerArrow->setPosition(MyGUI::IntPoint(x*512-16, y*512-16)); |  | ||||||
|     mLastPositionX = x; |  | ||||||
|     mLastPositionY = y; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void MapWindow::setPlayerDir(const float x, const float y) |  | ||||||
| { |  | ||||||
|     if (!mVisible || (x == mLastDirectionX && y == mLastDirectionY)) return; |  | ||||||
|     MyGUI::ISubWidget* main = mPlayerArrow->getSubWidgetMain(); |  | ||||||
|     MyGUI::RotatingSkin* rotatingSubskin = main->castType<MyGUI::RotatingSkin>(); |  | ||||||
|     rotatingSubskin->setCenter(MyGUI::IntPoint(16,16)); |  | ||||||
|     float angle = std::atan2(x,y); |  | ||||||
|     rotatingSubskin->setAngle(angle); |  | ||||||
| 
 |  | ||||||
|     mLastDirectionX = x; |  | ||||||
|     mLastDirectionY = y; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void MapWindow::onDragStart(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id) | void MapWindow::onDragStart(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id) | ||||||
| { | { | ||||||
|     if (_id!=MyGUI::MouseButton::Left) return; |     if (_id!=MyGUI::MouseButton::Left) return; | ||||||
|  | @ -172,8 +209,8 @@ void MapWindow::onWorldButtonClicked(MyGUI::Widget* _sender) | ||||||
|     mGlobalMap->setVisible(mGlobal); |     mGlobalMap->setVisible(mGlobal); | ||||||
|     mLocalMap->setVisible(!mGlobal); |     mLocalMap->setVisible(!mGlobal); | ||||||
| 
 | 
 | ||||||
|     mButton->setCaption( mGlobal ? mWindowManager.getGameSettingString("sWorld", "") : |     mButton->setCaptionWithReplacing( mGlobal ? "#{sLocal}" : | ||||||
|             mWindowManager.getGameSettingString("sLocal", "")); |             "#{sWorld}"); | ||||||
|     int width = mButton->getTextSize().width + 24; |     int width = mButton->getTextSize().width + 24; | ||||||
|     mButton->setCoord(mMainWidget->getSize().width - width - 22, mMainWidget->getSize().height - 64, width, 22); |     mButton->setCoord(mMainWidget->getSize().width - width - 22, mMainWidget->getSize().height - 64, width, 22); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -9,10 +9,12 @@ namespace MWGui | ||||||
|     { |     { | ||||||
|     public: |     public: | ||||||
|         LocalMapBase(); |         LocalMapBase(); | ||||||
|         void init(MyGUI::ScrollView* widget, OEngine::GUI::Layout* layout); |         void init(MyGUI::ScrollView* widget, MyGUI::ImageBox* compass, OEngine::GUI::Layout* layout, bool mapDragAndDrop=false); | ||||||
| 
 | 
 | ||||||
|         void setCellPrefix(const std::string& prefix); |         void setCellPrefix(const std::string& prefix); | ||||||
|         void setActiveCell(const int x, const int y, bool interior=false); |         void setActiveCell(const int x, const int y, bool interior=false); | ||||||
|  |         void setPlayerDir(const float x, const float y); | ||||||
|  |         void setPlayerPos(const float x, const float y); | ||||||
| 
 | 
 | ||||||
|         void toggleFogOfWar(); |         void toggleFogOfWar(); | ||||||
| 
 | 
 | ||||||
|  | @ -20,14 +22,20 @@ namespace MWGui | ||||||
|         int mCurX, mCurY; |         int mCurX, mCurY; | ||||||
|         bool mInterior; |         bool mInterior; | ||||||
|         MyGUI::ScrollView* mLocalMap; |         MyGUI::ScrollView* mLocalMap; | ||||||
|  |         MyGUI::ImageBox* mCompass; | ||||||
|         std::string mPrefix; |         std::string mPrefix; | ||||||
|         bool mChanged; |         bool mChanged; | ||||||
|         bool mFogOfWar; |         bool mFogOfWar; | ||||||
| 
 | 
 | ||||||
|  |         std::vector<MyGUI::ImageBox*> mMapWidgets; | ||||||
|  |         std::vector<MyGUI::ImageBox*> mFogWidgets; | ||||||
|  | 
 | ||||||
|         void applyFogOfWar(); |         void applyFogOfWar(); | ||||||
| 
 | 
 | ||||||
|         OEngine::GUI::Layout* mLayout; |         OEngine::GUI::Layout* mLayout; | ||||||
| 
 | 
 | ||||||
|  |         bool mMapDragAndDrop; | ||||||
|  | 
 | ||||||
|         float mLastPositionX; |         float mLastPositionX; | ||||||
|         float mLastPositionY; |         float mLastPositionY; | ||||||
|         float mLastDirectionX; |         float mLastDirectionX; | ||||||
|  | @ -40,8 +48,6 @@ namespace MWGui | ||||||
|         MapWindow(WindowManager& parWindowManager); |         MapWindow(WindowManager& parWindowManager); | ||||||
|         virtual ~MapWindow(){} |         virtual ~MapWindow(){} | ||||||
| 
 | 
 | ||||||
|         void setPlayerPos(const float x, const float y); |  | ||||||
|         void setPlayerDir(const float x, const float y); |  | ||||||
|         void setCellName(const std::string& cellName); |         void setCellName(const std::string& cellName); | ||||||
|    |    | ||||||
|     private: |     private: | ||||||
|  |  | ||||||
|  | @ -58,7 +58,7 @@ void MessageBoxManager::onFrame (float frameDuration) | ||||||
|     if(mInterMessageBoxe != NULL && mInterMessageBoxe->mMarkedToDelete) { |     if(mInterMessageBoxe != NULL && mInterMessageBoxe->mMarkedToDelete) { | ||||||
|         delete mInterMessageBoxe; |         delete mInterMessageBoxe; | ||||||
|         mInterMessageBoxe = NULL; |         mInterMessageBoxe = NULL; | ||||||
|         mWindowManager->setNextMode(GM_Game); |         mWindowManager->popGuiMode(); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -161,7 +161,7 @@ MessageBox::MessageBox(MessageBoxManager& parMessageBoxManager, const std::strin | ||||||
|     getWidget(mMessageWidget, "message"); |     getWidget(mMessageWidget, "message"); | ||||||
| 
 | 
 | ||||||
|     mMessageWidget->setOverflowToTheLeft(true); |     mMessageWidget->setOverflowToTheLeft(true); | ||||||
|     mMessageWidget->addText(cMessage); |     mMessageWidget->setCaptionWithReplacing(cMessage); | ||||||
| 
 | 
 | ||||||
|     MyGUI::IntSize size; |     MyGUI::IntSize size; | ||||||
|     size.width = mFixedWidth; |     size.width = mFixedWidth; | ||||||
|  |  | ||||||
|  | @ -5,7 +5,7 @@ namespace MWGui | ||||||
| { | { | ||||||
|   enum GuiMode |   enum GuiMode | ||||||
|     { |     { | ||||||
|       GM_Game,          // Game mode, only HUD
 |       GM_Settings,      // Settings window
 | ||||||
|       GM_Inventory,     // Inventory mode
 |       GM_Inventory,     // Inventory mode
 | ||||||
|       GM_Container, |       GM_Container, | ||||||
|       GM_MainMenu,      // Main menu mode
 |       GM_MainMenu,      // Main menu mode
 | ||||||
|  | @ -15,6 +15,7 @@ namespace MWGui | ||||||
| 
 | 
 | ||||||
|       GM_Scroll,        // Read scroll
 |       GM_Scroll,        // Read scroll
 | ||||||
|       GM_Book,          // Read book
 |       GM_Book,          // Read book
 | ||||||
|  |       GM_Alchemy,       // Make potions
 | ||||||
| 
 | 
 | ||||||
|       GM_Dialogue,      // NPC interaction
 |       GM_Dialogue,      // NPC interaction
 | ||||||
|       GM_Barter, |       GM_Barter, | ||||||
|  |  | ||||||
|  | @ -1,7 +1,4 @@ | ||||||
| #include "race.hpp" | #include "race.hpp" | ||||||
| #include "window_manager.hpp" |  | ||||||
| #include "widgets.hpp" |  | ||||||
| #include "components/esm_store/store.hpp" |  | ||||||
| 
 | 
 | ||||||
| #include <assert.h> | #include <assert.h> | ||||||
| #include <iostream> | #include <iostream> | ||||||
|  | @ -10,6 +7,12 @@ | ||||||
| #include <boost/algorithm/string.hpp> | #include <boost/algorithm/string.hpp> | ||||||
| #include <boost/lexical_cast.hpp> | #include <boost/lexical_cast.hpp> | ||||||
| 
 | 
 | ||||||
|  | #include <components/esm_store/store.hpp> | ||||||
|  | 
 | ||||||
|  | #include "window_manager.hpp" | ||||||
|  | #include "widgets.hpp" | ||||||
|  | #include "tooltips.hpp" | ||||||
|  | 
 | ||||||
| using namespace MWGui; | using namespace MWGui; | ||||||
| using namespace Widgets; | using namespace Widgets; | ||||||
| 
 | 
 | ||||||
|  | @ -51,7 +54,7 @@ RaceDialog::RaceDialog(WindowManager& parWindowManager) | ||||||
|     prevButton->eventMouseButtonClick += MyGUI::newDelegate(this, &RaceDialog::onSelectPreviousFace); |     prevButton->eventMouseButtonClick += MyGUI::newDelegate(this, &RaceDialog::onSelectPreviousFace); | ||||||
|     nextButton->eventMouseButtonClick += MyGUI::newDelegate(this, &RaceDialog::onSelectNextFace); |     nextButton->eventMouseButtonClick += MyGUI::newDelegate(this, &RaceDialog::onSelectNextFace); | ||||||
| 
 | 
 | ||||||
|     setText("HairChoiceT", mWindowManager.getGameSettingString("sRaceMenu3", "Change Hair")); |     setText("HairChoiceT", mWindowManager.getGameSettingString("sRaceMenu4", "Change Hair")); | ||||||
|     getWidget(prevButton, "PrevHairButton"); |     getWidget(prevButton, "PrevHairButton"); | ||||||
|     getWidget(nextButton, "NextHairButton"); |     getWidget(nextButton, "NextHairButton"); | ||||||
|     prevButton->eventMouseButtonClick += MyGUI::newDelegate(this, &RaceDialog::onSelectPreviousHair); |     prevButton->eventMouseButtonClick += MyGUI::newDelegate(this, &RaceDialog::onSelectPreviousHair); | ||||||
|  | @ -255,6 +258,8 @@ void RaceDialog::updateSkills() | ||||||
|         skillWidget->setWindowManager(&mWindowManager); |         skillWidget->setWindowManager(&mWindowManager); | ||||||
|         skillWidget->setSkillNumber(skillId); |         skillWidget->setSkillNumber(skillId); | ||||||
|         skillWidget->setSkillValue(MWSkill::SkillValue(race->data.bonus[i].bonus)); |         skillWidget->setSkillValue(MWSkill::SkillValue(race->data.bonus[i].bonus)); | ||||||
|  |         ToolTips::createSkillToolTip(skillWidget, skillId); | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
|         skillItems.push_back(skillWidget); |         skillItems.push_back(skillWidget); | ||||||
| 
 | 
 | ||||||
|  | @ -288,6 +293,8 @@ void RaceDialog::updateSpellPowers() | ||||||
|         spellPowerWidget = spellPowerList->createWidget<MWSpell>("MW_StatName", coord, MyGUI::Align::Default, std::string("SpellPower") + boost::lexical_cast<std::string>(i)); |         spellPowerWidget = spellPowerList->createWidget<MWSpell>("MW_StatName", coord, MyGUI::Align::Default, std::string("SpellPower") + boost::lexical_cast<std::string>(i)); | ||||||
|         spellPowerWidget->setWindowManager(&mWindowManager); |         spellPowerWidget->setWindowManager(&mWindowManager); | ||||||
|         spellPowerWidget->setSpellId(spellpower); |         spellPowerWidget->setSpellId(spellpower); | ||||||
|  |         spellPowerWidget->setUserString("ToolTipType", "Spell"); | ||||||
|  |         spellPowerWidget->setUserString("Spell", spellpower); | ||||||
| 
 | 
 | ||||||
|         spellPowerItems.push_back(spellPowerWidget); |         spellPowerItems.push_back(spellPowerWidget); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
							
								
								
									
										28
									
								
								apps/openmw/mwgui/referenceinterface.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								apps/openmw/mwgui/referenceinterface.cpp
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,28 @@ | ||||||
|  | #include "referenceinterface.hpp" | ||||||
|  | 
 | ||||||
|  | #include "../mwworld/player.hpp" | ||||||
|  | #include "../mwworld/world.hpp" | ||||||
|  | #include "../mwbase/environment.hpp" | ||||||
|  | 
 | ||||||
|  | namespace MWGui | ||||||
|  | { | ||||||
|  |     ReferenceInterface::ReferenceInterface() | ||||||
|  |         : mCurrentPlayerCell(NULL) | ||||||
|  |     { | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     void ReferenceInterface::checkReferenceAvailable() | ||||||
|  |     { | ||||||
|  |         if (mPtr.isEmpty()) | ||||||
|  |             return; | ||||||
|  | 
 | ||||||
|  |         MWWorld::Ptr::CellStore* playerCell = MWBase::Environment::get().getWorld()->getPlayer().getPlayer().getCell(); | ||||||
|  | 
 | ||||||
|  |         // check if player has changed cell, or count of the reference has become 0
 | ||||||
|  |         if ((playerCell != mCurrentPlayerCell && mCurrentPlayerCell != NULL) | ||||||
|  |             || mPtr.getRefData().getCount() == 0) | ||||||
|  |             onReferenceUnavailable(); | ||||||
|  | 
 | ||||||
|  |         mCurrentPlayerCell = playerCell; | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										29
									
								
								apps/openmw/mwgui/referenceinterface.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								apps/openmw/mwgui/referenceinterface.hpp
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,29 @@ | ||||||
|  | #ifndef MWGUI_REFERENCEINTERFACE_H | ||||||
|  | #define MWGUI_REFERENCEINTERFACE_H | ||||||
|  | 
 | ||||||
|  | #include "../mwworld/ptr.hpp" | ||||||
|  | 
 | ||||||
|  | namespace MWGui | ||||||
|  | { | ||||||
|  |     /// \brief this class is intended for GUI interfaces that access an MW-Reference
 | ||||||
|  |     /// for example dialogue window accesses an NPC, or Container window accesses a Container
 | ||||||
|  |     /// these classes have to be automatically closed if the reference becomes unavailable
 | ||||||
|  |     /// make sure that checkReferenceAvailable() is called every frame and that onReferenceUnavailable() has been overridden
 | ||||||
|  |     class ReferenceInterface | ||||||
|  |     { | ||||||
|  |     public: | ||||||
|  |         ReferenceInterface(); | ||||||
|  | 
 | ||||||
|  |         void checkReferenceAvailable(); ///< closes the window, if the MW-reference has become unavailable
 | ||||||
|  | 
 | ||||||
|  |     protected: | ||||||
|  |         virtual void onReferenceUnavailable() = 0; ///< called when reference has become unavailable
 | ||||||
|  | 
 | ||||||
|  |         MWWorld::Ptr mPtr; | ||||||
|  | 
 | ||||||
|  |     private: | ||||||
|  |         MWWorld::Ptr::CellStore* mCurrentPlayerCell; | ||||||
|  |     }; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
|  | @ -1,12 +1,15 @@ | ||||||
| #include "review.hpp" | #include "review.hpp" | ||||||
| #include "window_manager.hpp" | 
 | ||||||
| #include "widgets.hpp" | #include <cmath> | ||||||
| #include "components/esm_store/store.hpp" |  | ||||||
| 
 | 
 | ||||||
| #include <boost/algorithm/string.hpp> | #include <boost/algorithm/string.hpp> | ||||||
| #include <boost/lexical_cast.hpp> | #include <boost/lexical_cast.hpp> | ||||||
| 
 | 
 | ||||||
| #include <cmath> | #include <components/esm_store/store.hpp> | ||||||
|  | 
 | ||||||
|  | #include "window_manager.hpp" | ||||||
|  | #include "widgets.hpp" | ||||||
|  | #include "tooltips.hpp" | ||||||
| 
 | 
 | ||||||
| #undef min | #undef min | ||||||
| #undef max | #undef max | ||||||
|  | @ -74,7 +77,7 @@ ReviewDialog::ReviewDialog(WindowManager& parWindowManager) | ||||||
|     getWidget(skillAreaWidget, "Skills"); |     getWidget(skillAreaWidget, "Skills"); | ||||||
|     getWidget(skillClientWidget, "SkillClient"); |     getWidget(skillClientWidget, "SkillClient"); | ||||||
|     getWidget(skillScrollerWidget, "SkillScroller"); |     getWidget(skillScrollerWidget, "SkillScroller"); | ||||||
| 
 |     skillClientWidget->eventMouseWheel += MyGUI::newDelegate(this, &ReviewDialog::onMouseWheel); | ||||||
|     skillScrollerWidget->eventScrollChangePosition += MyGUI::newDelegate(this, &ReviewDialog::onScrollChangePosition); |     skillScrollerWidget->eventScrollChangePosition += MyGUI::newDelegate(this, &ReviewDialog::onScrollChangePosition); | ||||||
|     updateScroller(); |     updateScroller(); | ||||||
| 
 | 
 | ||||||
|  | @ -137,13 +140,17 @@ void ReviewDialog::setRace(const std::string &raceId_) | ||||||
|     raceId = raceId_; |     raceId = raceId_; | ||||||
|     const ESM::Race *race = mWindowManager.getStore().races.search(raceId); |     const ESM::Race *race = mWindowManager.getStore().races.search(raceId); | ||||||
|     if (race) |     if (race) | ||||||
|  |     { | ||||||
|  |         ToolTips::createRaceToolTip(raceWidget, race); | ||||||
|         raceWidget->setCaption(race->name); |         raceWidget->setCaption(race->name); | ||||||
|  |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void ReviewDialog::setClass(const ESM::Class& class_) | void ReviewDialog::setClass(const ESM::Class& class_) | ||||||
| { | { | ||||||
|     klass = class_; |     klass = class_; | ||||||
|     classWidget->setCaption(klass.name); |     classWidget->setCaption(klass.name); | ||||||
|  |     ToolTips::createClassToolTip(classWidget, klass); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void ReviewDialog::setBirthSign(const std::string& signId) | void ReviewDialog::setBirthSign(const std::string& signId) | ||||||
|  | @ -151,22 +158,31 @@ void ReviewDialog::setBirthSign(const std::string& signId) | ||||||
|     birthSignId = signId; |     birthSignId = signId; | ||||||
|     const ESM::BirthSign *sign = mWindowManager.getStore().birthSigns.search(birthSignId); |     const ESM::BirthSign *sign = mWindowManager.getStore().birthSigns.search(birthSignId); | ||||||
|     if (sign) |     if (sign) | ||||||
|  |     { | ||||||
|         birthSignWidget->setCaption(sign->name); |         birthSignWidget->setCaption(sign->name); | ||||||
|  |         ToolTips::createBirthsignToolTip(birthSignWidget, birthSignId); | ||||||
|  |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void ReviewDialog::setHealth(const MWMechanics::DynamicStat<int>& value) | void ReviewDialog::setHealth(const MWMechanics::DynamicStat<int>& value) | ||||||
| { | { | ||||||
|     health->setValue(value.getCurrent(), value.getModified()); |     health->setValue(value.getCurrent(), value.getModified()); | ||||||
|  |     std::string valStr =  boost::lexical_cast<std::string>(value.getCurrent()) + "/" + boost::lexical_cast<std::string>(value.getModified()); | ||||||
|  |     health->setUserString("Caption_HealthDescription", "#{sHealthDesc}\n" + valStr); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void ReviewDialog::setMagicka(const MWMechanics::DynamicStat<int>& value) | void ReviewDialog::setMagicka(const MWMechanics::DynamicStat<int>& value) | ||||||
| { | { | ||||||
|     magicka->setValue(value.getCurrent(), value.getModified()); |     magicka->setValue(value.getCurrent(), value.getModified()); | ||||||
|  |     std::string valStr =  boost::lexical_cast<std::string>(value.getCurrent()) + "/" + boost::lexical_cast<std::string>(value.getModified()); | ||||||
|  |     magicka->setUserString("Caption_HealthDescription", "#{sIntDesc}\n" + valStr); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void ReviewDialog::setFatigue(const MWMechanics::DynamicStat<int>& value) | void ReviewDialog::setFatigue(const MWMechanics::DynamicStat<int>& value) | ||||||
| { | { | ||||||
|     fatigue->setValue(value.getCurrent(), value.getModified()); |     fatigue->setValue(value.getCurrent(), value.getModified()); | ||||||
|  |     std::string valStr =  boost::lexical_cast<std::string>(value.getCurrent()) + "/" + boost::lexical_cast<std::string>(value.getModified()); | ||||||
|  |     fatigue->setUserString("Caption_HealthDescription", "#{sFatDesc}\n" + valStr); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void ReviewDialog::setAttribute(ESM::Attribute::AttributeID attributeId, const MWMechanics::Stat<int>& value) | void ReviewDialog::setAttribute(ESM::Attribute::AttributeID attributeId, const MWMechanics::Stat<int>& value) | ||||||
|  | @ -195,6 +211,7 @@ void ReviewDialog::setSkillValue(ESM::Skill::SkillEnum skillId, const MWMechanic | ||||||
|         widget->setCaption(text); |         widget->setCaption(text); | ||||||
|         widget->_setWidgetState(state); |         widget->_setWidgetState(state); | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void ReviewDialog::configureSkills(const std::vector<int>& major, const std::vector<int>& minor) | void ReviewDialog::configureSkills(const std::vector<int>& major, const std::vector<int>& minor) | ||||||
|  | @ -214,11 +231,15 @@ void ReviewDialog::configureSkills(const std::vector<int>& major, const std::vec | ||||||
|         if (skillSet.find(skill) == skillSet.end()) |         if (skillSet.find(skill) == skillSet.end()) | ||||||
|             miscSkills.push_back(skill); |             miscSkills.push_back(skill); | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     updateSkillArea(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void ReviewDialog::addSeparator(MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2) | void ReviewDialog::addSeparator(MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2) | ||||||
| { | { | ||||||
|     MyGUI::ImageBox* separator = skillClientWidget->createWidget<MyGUI::ImageBox>("MW_HLine", MyGUI::IntCoord(10, coord1.top, coord1.width + coord2.width - 4, 18), MyGUI::Align::Default); |     MyGUI::ImageBox* separator = skillClientWidget->createWidget<MyGUI::ImageBox>("MW_HLine", MyGUI::IntCoord(10, coord1.top, coord1.width + coord2.width - 4, 18), MyGUI::Align::Default); | ||||||
|  |     separator->eventMouseWheel += MyGUI::newDelegate(this, &ReviewDialog::onMouseWheel); | ||||||
|  | 
 | ||||||
|     skillWidgets.push_back(separator); |     skillWidgets.push_back(separator); | ||||||
| 
 | 
 | ||||||
|     coord1.top += separator->getHeight(); |     coord1.top += separator->getHeight(); | ||||||
|  | @ -228,6 +249,7 @@ void ReviewDialog::addSeparator(MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2 | ||||||
| void ReviewDialog::addGroup(const std::string &label, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2) | void ReviewDialog::addGroup(const std::string &label, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2) | ||||||
| { | { | ||||||
|     MyGUI::TextBox* groupWidget = skillClientWidget->createWidget<MyGUI::TextBox>("SandBrightText", MyGUI::IntCoord(0, coord1.top, coord1.width + coord2.width, coord1.height), MyGUI::Align::Default); |     MyGUI::TextBox* groupWidget = skillClientWidget->createWidget<MyGUI::TextBox>("SandBrightText", MyGUI::IntCoord(0, coord1.top, coord1.width + coord2.width, coord1.height), MyGUI::Align::Default); | ||||||
|  |     groupWidget->eventMouseWheel += MyGUI::newDelegate(this, &ReviewDialog::onMouseWheel); | ||||||
|     groupWidget->setCaption(label); |     groupWidget->setCaption(label); | ||||||
|     skillWidgets.push_back(groupWidget); |     skillWidgets.push_back(groupWidget); | ||||||
| 
 | 
 | ||||||
|  | @ -235,17 +257,19 @@ void ReviewDialog::addGroup(const std::string &label, MyGUI::IntCoord &coord1, M | ||||||
|     coord2.top += lineHeight; |     coord2.top += lineHeight; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| MyGUI::TextBox* ReviewDialog::addValueItem(const std::string text, const std::string &value, const std::string& state, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2) | MyGUI::TextBox* ReviewDialog::addValueItem(const std::string& text, const std::string &value, const std::string& state, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2) | ||||||
| { | { | ||||||
|     MyGUI::TextBox* skillNameWidget; |     MyGUI::TextBox* skillNameWidget; | ||||||
|     MyGUI::TextBox* skillValueWidget; |     MyGUI::TextBox* skillValueWidget; | ||||||
| 
 | 
 | ||||||
|     skillNameWidget = skillClientWidget->createWidget<MyGUI::TextBox>("SandText", coord1, MyGUI::Align::Default); |     skillNameWidget = skillClientWidget->createWidget<MyGUI::TextBox>("SandText", coord1, MyGUI::Align::Default); | ||||||
|     skillNameWidget->setCaption(text); |     skillNameWidget->setCaption(text); | ||||||
|  |     skillNameWidget->eventMouseWheel += MyGUI::newDelegate(this, &ReviewDialog::onMouseWheel); | ||||||
| 
 | 
 | ||||||
|     skillValueWidget = skillClientWidget->createWidget<MyGUI::TextBox>("SandTextRight", coord2, MyGUI::Align::Top | MyGUI::Align::Right); |     skillValueWidget = skillClientWidget->createWidget<MyGUI::TextBox>("SandTextRight", coord2, MyGUI::Align::Top | MyGUI::Align::Right); | ||||||
|     skillValueWidget->setCaption(value); |     skillValueWidget->setCaption(value); | ||||||
|     skillValueWidget->_setWidgetState(state); |     skillValueWidget->_setWidgetState(state); | ||||||
|  |     skillValueWidget->eventMouseWheel += MyGUI::newDelegate(this, &ReviewDialog::onMouseWheel); | ||||||
| 
 | 
 | ||||||
|     skillWidgets.push_back(skillNameWidget); |     skillWidgets.push_back(skillNameWidget); | ||||||
|     skillWidgets.push_back(skillValueWidget); |     skillWidgets.push_back(skillValueWidget); | ||||||
|  | @ -256,12 +280,13 @@ MyGUI::TextBox* ReviewDialog::addValueItem(const std::string text, const std::st | ||||||
|     return skillValueWidget; |     return skillValueWidget; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void ReviewDialog::addItem(const std::string text, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2) | void ReviewDialog::addItem(const std::string& text, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2) | ||||||
| { | { | ||||||
|     MyGUI::TextBox* skillNameWidget; |     MyGUI::TextBox* skillNameWidget; | ||||||
| 
 | 
 | ||||||
|     skillNameWidget = skillClientWidget->createWidget<MyGUI::TextBox>("SandText", coord1 + MyGUI::IntSize(coord2.width, 0), MyGUI::Align::Default); |     skillNameWidget = skillClientWidget->createWidget<MyGUI::TextBox>("SandText", coord1 + MyGUI::IntSize(coord2.width, 0), MyGUI::Align::Default); | ||||||
|     skillNameWidget->setCaption(text); |     skillNameWidget->setCaption(text); | ||||||
|  |     skillNameWidget->eventMouseWheel += MyGUI::newDelegate(this, &ReviewDialog::onMouseWheel); | ||||||
| 
 | 
 | ||||||
|     skillWidgets.push_back(skillNameWidget); |     skillWidgets.push_back(skillNameWidget); | ||||||
| 
 | 
 | ||||||
|  | @ -297,6 +322,12 @@ void ReviewDialog::addSkills(const SkillList &skills, const std::string &titleId | ||||||
|         else if (modified < base) |         else if (modified < base) | ||||||
|             state = "decreased"; |             state = "decreased"; | ||||||
|         MyGUI::TextBox* widget = addValueItem(mWindowManager.getGameSettingString(skillNameId, skillNameId), boost::lexical_cast<std::string>(static_cast<int>(modified)), state, coord1, coord2); |         MyGUI::TextBox* widget = addValueItem(mWindowManager.getGameSettingString(skillNameId, skillNameId), boost::lexical_cast<std::string>(static_cast<int>(modified)), state, coord1, coord2); | ||||||
|  | 
 | ||||||
|  |         for (int i=0; i<2; ++i) | ||||||
|  |         { | ||||||
|  |             ToolTips::createSkillToolTip(skillWidgets[skillWidgets.size()-1-i], skillId); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|         skillWidgetMap[skillId] = widget; |         skillWidgetMap[skillId] = widget; | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | @ -330,6 +361,8 @@ void ReviewDialog::updateScroller() | ||||||
| { | { | ||||||
|     skillScrollerWidget->setScrollRange(std::max(clientHeight - skillClientWidget->getHeight(), 0)); |     skillScrollerWidget->setScrollRange(std::max(clientHeight - skillClientWidget->getHeight(), 0)); | ||||||
|     skillScrollerWidget->setScrollPage(std::max(skillClientWidget->getHeight() - lineHeight, 0)); |     skillScrollerWidget->setScrollPage(std::max(skillClientWidget->getHeight() - lineHeight, 0)); | ||||||
|  |     if (clientHeight != 0) | ||||||
|  |         skillScrollerWidget->setTrackSize( (skillAreaWidget->getHeight() / float(clientHeight)) * skillScrollerWidget->getLineSize() ); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // widget controls
 | // widget controls
 | ||||||
|  | @ -363,3 +396,15 @@ void ReviewDialog::onBirthSignClicked(MyGUI::Widget* _sender) | ||||||
| { | { | ||||||
|     eventActivateDialog(BIRTHSIGN_DIALOG); |     eventActivateDialog(BIRTHSIGN_DIALOG); | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | void ReviewDialog::onMouseWheel(MyGUI::Widget* _sender, int _rel) | ||||||
|  | { | ||||||
|  |     if (skillScrollerWidget->getScrollPosition() - _rel*0.3 < 0) | ||||||
|  |         skillScrollerWidget->setScrollPosition(0); | ||||||
|  |     else if (skillScrollerWidget->getScrollPosition() - _rel*0.3 > skillScrollerWidget->getScrollRange()-1) | ||||||
|  |         skillScrollerWidget->setScrollPosition(skillScrollerWidget->getScrollRange()-1); | ||||||
|  |     else | ||||||
|  |         skillScrollerWidget->setScrollPosition(skillScrollerWidget->getScrollPosition() - _rel*0.3); | ||||||
|  | 
 | ||||||
|  |     onScrollChangePosition(skillScrollerWidget, skillScrollerWidget->getScrollPosition()); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ -68,12 +68,14 @@ namespace MWGui | ||||||
|         void onClassClicked(MyGUI::Widget* _sender); |         void onClassClicked(MyGUI::Widget* _sender); | ||||||
|         void onBirthSignClicked(MyGUI::Widget* _sender); |         void onBirthSignClicked(MyGUI::Widget* _sender); | ||||||
| 
 | 
 | ||||||
|  |         void onMouseWheel(MyGUI::Widget* _sender, int _rel); | ||||||
|  | 
 | ||||||
|     private: |     private: | ||||||
|         void addSkills(const SkillList &skills, const std::string &titleId, const std::string &titleDefault, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2); |         void addSkills(const SkillList &skills, const std::string &titleId, const std::string &titleDefault, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2); | ||||||
|         void addSeparator(MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2); |         void addSeparator(MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2); | ||||||
|         void addGroup(const std::string &label, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2); |         void addGroup(const std::string &label, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2); | ||||||
|         MyGUI::TextBox* addValueItem(const std::string text, const std::string &value, const std::string& state, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2); |         MyGUI::TextBox* addValueItem(const std::string& text, const std::string &value, const std::string& state, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2); | ||||||
|         void addItem(const std::string text, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2); |         void addItem(const std::string& text, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2); | ||||||
|         void updateScroller(); |         void updateScroller(); | ||||||
|         void updateSkillArea(); |         void updateSkillArea(); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,12 +1,13 @@ | ||||||
| #include "scrollwindow.hpp" | #include "scrollwindow.hpp" | ||||||
| 
 | 
 | ||||||
| #include "formatting.hpp" |  | ||||||
| 
 |  | ||||||
| #include "../mwbase/environment.hpp" | #include "../mwbase/environment.hpp" | ||||||
| #include "../mwinput/inputmanager.hpp" | #include "../mwinput/inputmanager.hpp" | ||||||
| #include "../mwworld/actiontake.hpp" | #include "../mwworld/actiontake.hpp" | ||||||
| #include "../mwsound/soundmanager.hpp" | #include "../mwsound/soundmanager.hpp" | ||||||
| 
 | 
 | ||||||
|  | #include "formatting.hpp" | ||||||
|  | #include "window_manager.hpp" | ||||||
|  | 
 | ||||||
| using namespace MWGui; | using namespace MWGui; | ||||||
| 
 | 
 | ||||||
| ScrollWindow::ScrollWindow (WindowManager& parWindowManager) : | ScrollWindow::ScrollWindow (WindowManager& parWindowManager) : | ||||||
|  | @ -55,7 +56,7 @@ void ScrollWindow::onCloseButtonClicked (MyGUI::Widget* _sender) | ||||||
| { | { | ||||||
|     MWBase::Environment::get().getSoundManager()->playSound ("scroll", 1.0, 1.0); |     MWBase::Environment::get().getSoundManager()->playSound ("scroll", 1.0, 1.0); | ||||||
| 
 | 
 | ||||||
|     MWBase::Environment::get().getInputManager()->setGuiMode (GM_Game); |     mWindowManager.popGuiMode(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void ScrollWindow::onTakeButtonClicked (MyGUI::Widget* _sender) | void ScrollWindow::onTakeButtonClicked (MyGUI::Widget* _sender) | ||||||
|  | @ -65,5 +66,5 @@ void ScrollWindow::onTakeButtonClicked (MyGUI::Widget* _sender) | ||||||
|     MWWorld::ActionTake take(mScroll); |     MWWorld::ActionTake take(mScroll); | ||||||
|     take.execute(); |     take.execute(); | ||||||
| 
 | 
 | ||||||
|     MWBase::Environment::get().getInputManager()->setGuiMode (GM_Game); |     mWindowManager.popGuiMode(); | ||||||
| } | } | ||||||
|  |  | ||||||
							
								
								
									
										342
									
								
								apps/openmw/mwgui/settingswindow.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										342
									
								
								apps/openmw/mwgui/settingswindow.cpp
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,342 @@ | ||||||
|  | #include "settingswindow.hpp" | ||||||
|  | 
 | ||||||
|  | #include <OgreRoot.h> | ||||||
|  | #include <OgreRenderSystem.h> | ||||||
|  | #include <OgreString.h> | ||||||
|  | 
 | ||||||
|  | #include <boost/lexical_cast.hpp> | ||||||
|  | 
 | ||||||
|  | #include <components/settings/settings.hpp> | ||||||
|  | 
 | ||||||
|  | #include "../mwbase/environment.hpp" | ||||||
|  | #include "../mwworld/world.hpp" | ||||||
|  | #include "../mwsound/soundmanager.hpp" | ||||||
|  | #include "../mwinput/inputmanager.hpp" | ||||||
|  | 
 | ||||||
|  | #include "window_manager.hpp" | ||||||
|  | #include "confirmationdialog.hpp" | ||||||
|  | 
 | ||||||
|  | namespace | ||||||
|  | { | ||||||
|  |     std::string fpsLevelToStr(int level) | ||||||
|  |     { | ||||||
|  |         if (level == 0) | ||||||
|  |             return "#{sOff}"; | ||||||
|  |         else if (level == 1) | ||||||
|  |             return "Basic"; | ||||||
|  |         else | ||||||
|  |             return "Detailed"; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     std::string textureFilteringToStr(const std::string& val) | ||||||
|  |     { | ||||||
|  |         if (val == "none") | ||||||
|  |             return "None"; | ||||||
|  |         else if (val == "anisotropic") | ||||||
|  |             return "Anisotropic"; | ||||||
|  |         else if (val == "bilinear") | ||||||
|  |             return "Bilinear"; | ||||||
|  |         else | ||||||
|  |             return "Trilinear"; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | namespace MWGui | ||||||
|  | { | ||||||
|  |     SettingsWindow::SettingsWindow(WindowManager& parWindowManager) : | ||||||
|  |         WindowBase("openmw_settings_window_layout.xml", parWindowManager) | ||||||
|  |     { | ||||||
|  |         getWidget(mOkButton, "OkButton"); | ||||||
|  |         getWidget(mResolutionList, "ResolutionList"); | ||||||
|  |         getWidget(mMenuTransparencySlider, "MenuTransparencySlider"); | ||||||
|  |         getWidget(mToolTipDelaySlider, "ToolTipDelaySlider"); | ||||||
|  |         getWidget(mViewDistanceSlider, "ViewDistanceSlider"); | ||||||
|  |         getWidget(mFullscreenButton, "FullscreenButton"); | ||||||
|  |         getWidget(mVSyncButton, "VSyncButton"); | ||||||
|  |         getWidget(mFPSButton, "FPSButton"); | ||||||
|  |         getWidget(mFOVSlider, "FOVSlider"); | ||||||
|  |         getWidget(mMasterVolumeSlider, "MasterVolume"); | ||||||
|  |         getWidget(mVoiceVolumeSlider, "VoiceVolume"); | ||||||
|  |         getWidget(mEffectsVolumeSlider, "EffectsVolume"); | ||||||
|  |         getWidget(mFootstepsVolumeSlider, "FootstepsVolume"); | ||||||
|  |         getWidget(mMusicVolumeSlider, "MusicVolume"); | ||||||
|  |         getWidget(mAnisotropySlider, "AnisotropySlider"); | ||||||
|  |         getWidget(mTextureFilteringButton, "TextureFilteringButton"); | ||||||
|  |         getWidget(mAnisotropyLabel, "AnisotropyLabel"); | ||||||
|  |         getWidget(mAnisotropyBox, "AnisotropyBox"); | ||||||
|  |         getWidget(mWaterShaderButton, "WaterShaderButton"); | ||||||
|  |         getWidget(mReflectObjectsButton, "ReflectObjectsButton"); | ||||||
|  |         getWidget(mReflectActorsButton, "ReflectActorsButton"); | ||||||
|  |         getWidget(mReflectTerrainButton, "ReflectTerrainButton"); | ||||||
|  | 
 | ||||||
|  |         mOkButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onOkButtonClicked); | ||||||
|  |         mFullscreenButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled); | ||||||
|  |         mWaterShaderButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled); | ||||||
|  |         mReflectObjectsButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled); | ||||||
|  |         mReflectTerrainButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled); | ||||||
|  |         mReflectActorsButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled); | ||||||
|  |         mTextureFilteringButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onTextureFilteringToggled); | ||||||
|  |         mVSyncButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled); | ||||||
|  |         mFPSButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onFpsToggled); | ||||||
|  |         mMenuTransparencySlider->eventScrollChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onSliderChangePosition); | ||||||
|  |         mFOVSlider->eventScrollChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onSliderChangePosition); | ||||||
|  |         mToolTipDelaySlider->eventScrollChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onSliderChangePosition); | ||||||
|  |         mViewDistanceSlider->eventScrollChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onSliderChangePosition); | ||||||
|  |         mResolutionList->eventListChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onResolutionSelected); | ||||||
|  |         mAnisotropySlider->eventScrollChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onSliderChangePosition); | ||||||
|  | 
 | ||||||
|  |         mMasterVolumeSlider->eventScrollChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onSliderChangePosition); | ||||||
|  |         mVoiceVolumeSlider->eventScrollChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onSliderChangePosition); | ||||||
|  |         mEffectsVolumeSlider->eventScrollChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onSliderChangePosition); | ||||||
|  |         mFootstepsVolumeSlider->eventScrollChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onSliderChangePosition); | ||||||
|  |         mMusicVolumeSlider->eventScrollChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onSliderChangePosition); | ||||||
|  | 
 | ||||||
|  |         center(); | ||||||
|  | 
 | ||||||
|  |         int okSize = mOkButton->getTextSize().width + 24; | ||||||
|  |         mOkButton->setCoord(mMainWidget->getWidth()-16-okSize, mOkButton->getTop(), | ||||||
|  |                             okSize, mOkButton->getHeight()); | ||||||
|  | 
 | ||||||
|  |         // fill resolution list
 | ||||||
|  |         Ogre::RenderSystem* rs = Ogre::Root::getSingleton().getRenderSystem(); | ||||||
|  |         const Ogre::StringVector& videoModes = rs->getConfigOptions()["Video Mode"].possibleValues; | ||||||
|  |         for (Ogre::StringVector::const_iterator it=videoModes.begin(); | ||||||
|  |             it!=videoModes.end(); ++it) | ||||||
|  |         { | ||||||
|  |             mResolutionList->addItem(*it); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         // read settings
 | ||||||
|  |         int menu_transparency = (mMenuTransparencySlider->getScrollRange()-1) * Settings::Manager::getFloat("menu transparency", "GUI"); | ||||||
|  |         mMenuTransparencySlider->setScrollPosition(menu_transparency); | ||||||
|  |         int tooltip_delay = (mToolTipDelaySlider->getScrollRange()-1) * Settings::Manager::getFloat("tooltip delay", "GUI"); | ||||||
|  |         mToolTipDelaySlider->setScrollPosition(tooltip_delay); | ||||||
|  | 
 | ||||||
|  |         float fovVal = (Settings::Manager::getFloat("field of view", "General")-sFovMin)/(sFovMax-sFovMin); | ||||||
|  |         mFOVSlider->setScrollPosition(fovVal * (mFOVSlider->getScrollRange()-1)); | ||||||
|  |         MyGUI::TextBox* fovText; | ||||||
|  |         getWidget(fovText, "FovText"); | ||||||
|  |         fovText->setCaption("Field of View (" + boost::lexical_cast<std::string>(int(Settings::Manager::getFloat("field of view", "General"))) + ")"); | ||||||
|  | 
 | ||||||
|  |         float anisotropyVal = Settings::Manager::getInt("anisotropy", "General") / 16.0; | ||||||
|  |         mAnisotropySlider->setScrollPosition(anisotropyVal * (mAnisotropySlider->getScrollRange()-1)); | ||||||
|  |         std::string tf = Settings::Manager::getString("texture filtering", "General"); | ||||||
|  |         mTextureFilteringButton->setCaption(textureFilteringToStr(tf)); | ||||||
|  |         mAnisotropyLabel->setCaption("Anisotropy (" + boost::lexical_cast<std::string>(Settings::Manager::getInt("anisotropy", "General")) + ")"); | ||||||
|  |         mAnisotropyBox->setVisible(tf == "anisotropic"); | ||||||
|  | 
 | ||||||
|  |         float val = (Settings::Manager::getFloat("max viewing distance", "Viewing distance")-sViewDistMin)/(sViewDistMax-sViewDistMin); | ||||||
|  |         int viewdist = (mViewDistanceSlider->getScrollRange()-1) * val; | ||||||
|  |         mViewDistanceSlider->setScrollPosition(viewdist); | ||||||
|  | 
 | ||||||
|  |         mMasterVolumeSlider->setScrollPosition(Settings::Manager::getFloat("master volume", "Sound") * (mMasterVolumeSlider->getScrollRange()-1)); | ||||||
|  |         mMusicVolumeSlider->setScrollPosition(Settings::Manager::getFloat("music volume", "Sound") * (mMusicVolumeSlider->getScrollRange()-1)); | ||||||
|  |         mEffectsVolumeSlider->setScrollPosition(Settings::Manager::getFloat("sfx volume", "Sound") * (mEffectsVolumeSlider->getScrollRange()-1)); | ||||||
|  |         mFootstepsVolumeSlider->setScrollPosition(Settings::Manager::getFloat("footsteps volume", "Sound") * (mFootstepsVolumeSlider->getScrollRange()-1)); | ||||||
|  |         mVoiceVolumeSlider->setScrollPosition(Settings::Manager::getFloat("voice volume", "Sound") * (mVoiceVolumeSlider->getScrollRange()-1)); | ||||||
|  | 
 | ||||||
|  |         mWaterShaderButton->setCaptionWithReplacing(Settings::Manager::getBool("shader", "Water") ? "#{sOn}" : "#{sOff}"); | ||||||
|  |         mReflectObjectsButton->setCaptionWithReplacing(Settings::Manager::getBool("reflect objects", "Water") ? "#{sOn}" : "#{sOff}"); | ||||||
|  |         mReflectActorsButton->setCaptionWithReplacing(Settings::Manager::getBool("reflect actors", "Water") ? "#{sOn}" : "#{sOff}"); | ||||||
|  |         mReflectTerrainButton->setCaptionWithReplacing(Settings::Manager::getBool("reflect terrain", "Water") ? "#{sOn}" : "#{sOff}"); | ||||||
|  | 
 | ||||||
|  |         if (!MWRender::RenderingManager::waterShaderSupported()) | ||||||
|  |         { | ||||||
|  |             mWaterShaderButton->setEnabled(false); | ||||||
|  |             mReflectObjectsButton->setEnabled(false); | ||||||
|  |             mReflectActorsButton->setEnabled(false); | ||||||
|  |             mReflectTerrainButton->setEnabled(false); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         mFullscreenButton->setCaptionWithReplacing(Settings::Manager::getBool("fullscreen", "Video") ? "#{sOn}" : "#{sOff}"); | ||||||
|  |         mVSyncButton->setCaptionWithReplacing(Settings::Manager::getBool("vsync", "Video") ? "#{sOn}": "#{sOff}"); | ||||||
|  |         mFPSButton->setCaptionWithReplacing(fpsLevelToStr(Settings::Manager::getInt("fps", "HUD"))); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     void SettingsWindow::onOkButtonClicked(MyGUI::Widget* _sender) | ||||||
|  |     { | ||||||
|  |         mWindowManager.popGuiMode(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     void SettingsWindow::onResolutionSelected(MyGUI::ListBox* _sender, size_t index) | ||||||
|  |     { | ||||||
|  |         if (index == MyGUI::ITEM_NONE) | ||||||
|  |             return; | ||||||
|  | 
 | ||||||
|  |         ConfirmationDialog* dialog = mWindowManager.getConfirmationDialog(); | ||||||
|  |         dialog->open("#{sNotifyMessage67}"); | ||||||
|  |         dialog->eventOkClicked.clear(); | ||||||
|  |         dialog->eventOkClicked += MyGUI::newDelegate(this, &SettingsWindow::onResolutionAccept); | ||||||
|  |         dialog->eventCancelClicked.clear(); | ||||||
|  |         dialog->eventCancelClicked += MyGUI::newDelegate(this, &SettingsWindow::onResolutionAccept); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     void SettingsWindow::onResolutionAccept() | ||||||
|  |     { | ||||||
|  |         std::string resStr = mResolutionList->getItemNameAt(mResolutionList->getIndexSelected()); | ||||||
|  |         size_t xPos = resStr.find("x"); | ||||||
|  |         std::string resXStr = resStr.substr(0, xPos-1); | ||||||
|  |         Ogre::StringUtil::trim(resXStr); | ||||||
|  |         std::string resYStr = resStr.substr(xPos+2, resStr.size()-(xPos+2)); | ||||||
|  |         Ogre::StringUtil::trim(resYStr); | ||||||
|  |         int resX = boost::lexical_cast<int>(resXStr); | ||||||
|  |         int resY = boost::lexical_cast<int>(resYStr); | ||||||
|  | 
 | ||||||
|  |         Settings::Manager::setInt("resolution x", "Video", resX); | ||||||
|  |         Settings::Manager::setInt("resolution y", "Video", resY); | ||||||
|  | 
 | ||||||
|  |         apply(); | ||||||
|  |         mResolutionList->setIndexSelected(MyGUI::ITEM_NONE); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     void SettingsWindow::onResolutionCancel() | ||||||
|  |     { | ||||||
|  |         mResolutionList->setIndexSelected(MyGUI::ITEM_NONE); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     void SettingsWindow::onButtonToggled(MyGUI::Widget* _sender) | ||||||
|  |     { | ||||||
|  |         std::string on = mWindowManager.getGameSettingString("sOn", "On"); | ||||||
|  |         std::string off = mWindowManager.getGameSettingString("sOff", "On"); | ||||||
|  |         bool newState; | ||||||
|  |         if (_sender->castType<MyGUI::Button>()->getCaption() == on) | ||||||
|  |         { | ||||||
|  |             _sender->castType<MyGUI::Button>()->setCaption(off); | ||||||
|  |             newState = false; | ||||||
|  |         } | ||||||
|  |         else | ||||||
|  |         { | ||||||
|  |             _sender->castType<MyGUI::Button>()->setCaption(on); | ||||||
|  |             newState = true; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         if (_sender == mFullscreenButton) | ||||||
|  |         { | ||||||
|  |             // check if this resolution is supported in fullscreen
 | ||||||
|  |             bool supported = false; | ||||||
|  |             for (unsigned int i=0; i<mResolutionList->getItemCount(); ++i) | ||||||
|  |             { | ||||||
|  |                 std::string resStr = mResolutionList->getItemNameAt(i); | ||||||
|  |                 size_t xPos = resStr.find("x"); | ||||||
|  |                 std::string resXStr = resStr.substr(0, xPos-1); | ||||||
|  |                 Ogre::StringUtil::trim(resXStr); | ||||||
|  |                 std::string resYStr = resStr.substr(xPos+2, resStr.size()-(xPos+2)); | ||||||
|  |                 Ogre::StringUtil::trim(resYStr); | ||||||
|  |                 int resX = boost::lexical_cast<int>(resXStr); | ||||||
|  |                 int resY = boost::lexical_cast<int>(resYStr); | ||||||
|  | 
 | ||||||
|  |                 if (resX == Settings::Manager::getInt("resolution x", "Video") | ||||||
|  |                     && resY  == Settings::Manager::getInt("resolution y", "Video")) | ||||||
|  |                     supported = true; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             if (!supported) | ||||||
|  |             { | ||||||
|  |                 std::string msg = "This resolution is not supported in Fullscreen mode. Please select a resolution from the list."; | ||||||
|  |                 MWBase::Environment::get().getWindowManager()-> | ||||||
|  |                     messageBox(msg, std::vector<std::string>()); | ||||||
|  |                 _sender->castType<MyGUI::Button>()->setCaption(off); | ||||||
|  |             } | ||||||
|  |             else | ||||||
|  |             { | ||||||
|  |                 Settings::Manager::setBool("fullscreen", "Video", newState); | ||||||
|  |                 apply(); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         else if (_sender == mVSyncButton) | ||||||
|  |         { | ||||||
|  |             Settings::Manager::setBool("vsync", "Video", newState); | ||||||
|  |             MWBase::Environment::get().getWindowManager()-> | ||||||
|  |                 messageBox("VSync will be applied after a restart", std::vector<std::string>()); | ||||||
|  |         } | ||||||
|  |         else | ||||||
|  |         { | ||||||
|  |             if (_sender == mWaterShaderButton) | ||||||
|  |                 Settings::Manager::setBool("shader", "Water", newState); | ||||||
|  |             else if (_sender == mReflectObjectsButton) | ||||||
|  |             { | ||||||
|  |                 Settings::Manager::setBool("reflect misc", "Water", newState); | ||||||
|  |                 Settings::Manager::setBool("reflect statics", "Water", newState); | ||||||
|  |                 Settings::Manager::setBool("reflect statics small", "Water", newState); | ||||||
|  |             } | ||||||
|  |             else if (_sender == mReflectActorsButton) | ||||||
|  |                 Settings::Manager::setBool("reflect actors", "Water", newState); | ||||||
|  |             else if (_sender == mReflectTerrainButton) | ||||||
|  |                 Settings::Manager::setBool("reflect terrain", "Water", newState); | ||||||
|  | 
 | ||||||
|  |             apply(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     void SettingsWindow::onFpsToggled(MyGUI::Widget* _sender) | ||||||
|  |     { | ||||||
|  |         int newLevel = (Settings::Manager::getInt("fps", "HUD") + 1) % 3; | ||||||
|  |         Settings::Manager::setInt("fps", "HUD", newLevel); | ||||||
|  |         mFPSButton->setCaptionWithReplacing(fpsLevelToStr(newLevel)); | ||||||
|  |         apply(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     void SettingsWindow::onTextureFilteringToggled(MyGUI::Widget* _sender) | ||||||
|  |     { | ||||||
|  |         std::string current = Settings::Manager::getString("texture filtering", "General"); | ||||||
|  |         std::string next; | ||||||
|  |         if (current == "none") | ||||||
|  |             next = "bilinear"; | ||||||
|  |         else if (current == "bilinear") | ||||||
|  |             next = "trilinear"; | ||||||
|  |         else if (current == "trilinear") | ||||||
|  |             next = "anisotropic"; | ||||||
|  |         else | ||||||
|  |             next = "none"; | ||||||
|  | 
 | ||||||
|  |         mTextureFilteringButton->setCaption(textureFilteringToStr(next)); | ||||||
|  |         mAnisotropyBox->setVisible(next == "anisotropic"); | ||||||
|  | 
 | ||||||
|  |         Settings::Manager::setString("texture filtering", "General", next); | ||||||
|  |         apply(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     void SettingsWindow::onSliderChangePosition(MyGUI::ScrollBar* scroller, size_t pos) | ||||||
|  |     { | ||||||
|  |         float val = pos / float(scroller->getScrollRange()-1); | ||||||
|  |         if (scroller == mMenuTransparencySlider) | ||||||
|  |             Settings::Manager::setFloat("menu transparency", "GUI", val); | ||||||
|  |         else if (scroller == mToolTipDelaySlider) | ||||||
|  |             Settings::Manager::setFloat("tooltip delay", "GUI", val); | ||||||
|  |         else if (scroller == mViewDistanceSlider) | ||||||
|  |             Settings::Manager::setFloat("max viewing distance", "Viewing distance", (1-val) * sViewDistMin + val * sViewDistMax); | ||||||
|  |         else if (scroller == mFOVSlider) | ||||||
|  |         { | ||||||
|  |             MyGUI::TextBox* fovText; | ||||||
|  |             getWidget(fovText, "FovText"); | ||||||
|  |             fovText->setCaption("Field of View (" + boost::lexical_cast<std::string>(int((1-val) * sFovMin + val * sFovMax)) + ")"); | ||||||
|  |             Settings::Manager::setFloat("field of view", "General", (1-val) * sFovMin + val * sFovMax); | ||||||
|  |         } | ||||||
|  |         else if (scroller == mAnisotropySlider) | ||||||
|  |         { | ||||||
|  |             mAnisotropyLabel->setCaption("Anisotropy (" + boost::lexical_cast<std::string>(int(val*16)) + ")"); | ||||||
|  |             Settings::Manager::setInt("anisotropy", "General", val * 16); | ||||||
|  |         } | ||||||
|  |         else if (scroller == mMasterVolumeSlider) | ||||||
|  |             Settings::Manager::setFloat("master volume", "Sound", val); | ||||||
|  |         else if (scroller == mVoiceVolumeSlider) | ||||||
|  |             Settings::Manager::setFloat("voice volume", "Sound", val); | ||||||
|  |         else if (scroller == mEffectsVolumeSlider) | ||||||
|  |             Settings::Manager::setFloat("sfx volume", "Sound", val); | ||||||
|  |         else if (scroller == mFootstepsVolumeSlider) | ||||||
|  |             Settings::Manager::setFloat("footsteps volume", "Sound", val); | ||||||
|  |         else if (scroller == mMusicVolumeSlider) | ||||||
|  |             Settings::Manager::setFloat("music volume", "Sound", val); | ||||||
|  | 
 | ||||||
|  |         apply(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     void SettingsWindow::apply() | ||||||
|  |     { | ||||||
|  |         const Settings::CategorySettingVector changed = Settings::Manager::apply(); | ||||||
|  |         MWBase::Environment::get().getWorld()->processChangedSettings(changed); | ||||||
|  |         MWBase::Environment::get().getSoundManager()->processChangedSettings(changed); | ||||||
|  |         MWBase::Environment::get().getWindowManager()->processChangedSettings(changed); | ||||||
|  |         MWBase::Environment::get().getInputManager()->processChangedSettings(changed); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										67
									
								
								apps/openmw/mwgui/settingswindow.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								apps/openmw/mwgui/settingswindow.hpp
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,67 @@ | ||||||
|  | #ifndef MWGUI_SETTINGS_H | ||||||
|  | #define MWGUI_SETTINGS_H | ||||||
|  | 
 | ||||||
|  | #include "window_base.hpp" | ||||||
|  | 
 | ||||||
|  | namespace MWGui | ||||||
|  | { | ||||||
|  |     class WindowManager; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | namespace MWGui | ||||||
|  | { | ||||||
|  |     class SettingsWindow : public WindowBase | ||||||
|  |     { | ||||||
|  |         public: | ||||||
|  |             SettingsWindow(WindowManager& parWindowManager); | ||||||
|  | 
 | ||||||
|  |         private: | ||||||
|  |             static int const sFovMin = 30; | ||||||
|  |             static int const sFovMax = 140; | ||||||
|  |             static int const sViewDistMin = 2000; | ||||||
|  |             static int const sViewDistMax = 5600; | ||||||
|  | 
 | ||||||
|  |         protected: | ||||||
|  |             MyGUI::Button* mOkButton; | ||||||
|  | 
 | ||||||
|  |             MyGUI::ScrollBar* mMenuTransparencySlider; | ||||||
|  |             MyGUI::ScrollBar* mToolTipDelaySlider; | ||||||
|  | 
 | ||||||
|  |             // graphics
 | ||||||
|  |             MyGUI::ListBox* mResolutionList; | ||||||
|  |             MyGUI::Button* mFullscreenButton; | ||||||
|  |             MyGUI::Button* mVSyncButton; | ||||||
|  |             MyGUI::Button* mFPSButton; | ||||||
|  |             MyGUI::ScrollBar* mViewDistanceSlider; | ||||||
|  |             MyGUI::ScrollBar* mFOVSlider; | ||||||
|  |             MyGUI::ScrollBar* mAnisotropySlider; | ||||||
|  |             MyGUI::Button* mTextureFilteringButton; | ||||||
|  |             MyGUI::TextBox* mAnisotropyLabel; | ||||||
|  |             MyGUI::Widget* mAnisotropyBox; | ||||||
|  |             MyGUI::Button* mWaterShaderButton; | ||||||
|  |             MyGUI::Button* mReflectObjectsButton; | ||||||
|  |             MyGUI::Button* mReflectActorsButton; | ||||||
|  |             MyGUI::Button* mReflectTerrainButton; | ||||||
|  | 
 | ||||||
|  |             // audio
 | ||||||
|  |             MyGUI::ScrollBar* mMasterVolumeSlider; | ||||||
|  |             MyGUI::ScrollBar* mVoiceVolumeSlider; | ||||||
|  |             MyGUI::ScrollBar* mEffectsVolumeSlider; | ||||||
|  |             MyGUI::ScrollBar* mFootstepsVolumeSlider; | ||||||
|  |             MyGUI::ScrollBar* mMusicVolumeSlider; | ||||||
|  | 
 | ||||||
|  |             void onOkButtonClicked(MyGUI::Widget* _sender); | ||||||
|  |             void onFpsToggled(MyGUI::Widget* _sender); | ||||||
|  |             void onTextureFilteringToggled(MyGUI::Widget* _sender); | ||||||
|  |             void onSliderChangePosition(MyGUI::ScrollBar* scroller, size_t pos); | ||||||
|  |             void onButtonToggled(MyGUI::Widget* _sender); | ||||||
|  |             void onResolutionSelected(MyGUI::ListBox* _sender, size_t index); | ||||||
|  |             void onResolutionAccept(); | ||||||
|  |             void onResolutionCancel(); | ||||||
|  | 
 | ||||||
|  |             void apply(); | ||||||
|  |     }; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
							
								
								
									
										459
									
								
								apps/openmw/mwgui/spellwindow.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										459
									
								
								apps/openmw/mwgui/spellwindow.cpp
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,459 @@ | ||||||
|  | #include "spellwindow.hpp" | ||||||
|  | 
 | ||||||
|  | #include <boost/algorithm/string.hpp> | ||||||
|  | #include <boost/lexical_cast.hpp> | ||||||
|  | #include <boost/format.hpp> | ||||||
|  | 
 | ||||||
|  | #include "../mwworld/world.hpp" | ||||||
|  | #include "../mwworld/player.hpp" | ||||||
|  | #include "../mwworld/inventorystore.hpp" | ||||||
|  | #include "../mwbase/environment.hpp" | ||||||
|  | #include "../mwmechanics/spells.hpp" | ||||||
|  | #include "../mwmechanics/creaturestats.hpp" | ||||||
|  | #include "../mwmechanics/spellsuccess.hpp" | ||||||
|  | #include "../mwsound/soundmanager.hpp" | ||||||
|  | 
 | ||||||
|  | #include "window_manager.hpp" | ||||||
|  | #include "inventorywindow.hpp" | ||||||
|  | #include "confirmationdialog.hpp" | ||||||
|  | 
 | ||||||
|  | namespace | ||||||
|  | { | ||||||
|  |     bool sortSpells(const std::string& left, const std::string& right) | ||||||
|  |     { | ||||||
|  |         const ESM::Spell* a = MWBase::Environment::get().getWorld()->getStore().spells.find(left); | ||||||
|  |         const ESM::Spell* b = MWBase::Environment::get().getWorld()->getStore().spells.find(right); | ||||||
|  | 
 | ||||||
|  |         int cmp = a->name.compare(b->name); | ||||||
|  |         return cmp < 0; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     bool sortItems(const MWWorld::Ptr& left, const MWWorld::Ptr& right) | ||||||
|  |     { | ||||||
|  |         int cmp = MWWorld::Class::get(left).getName(left).compare( | ||||||
|  |                     MWWorld::Class::get(right).getName(right)); | ||||||
|  |         return cmp < 0; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | namespace MWGui | ||||||
|  | { | ||||||
|  |     SpellWindow::SpellWindow(WindowManager& parWindowManager) | ||||||
|  |         : WindowPinnableBase("openmw_spell_window_layout.xml", parWindowManager) | ||||||
|  |         , mHeight(0) | ||||||
|  |         , mWidth(0) | ||||||
|  |     { | ||||||
|  |         getWidget(mSpellView, "SpellView"); | ||||||
|  |         getWidget(mEffectBox, "EffectsBox"); | ||||||
|  | 
 | ||||||
|  |         setCoord(498, 300, 302, 300); | ||||||
|  | 
 | ||||||
|  |         updateSpells(); | ||||||
|  | 
 | ||||||
|  |         mMainWidget->castType<MyGUI::Window>()->eventWindowChangeCoord += MyGUI::newDelegate(this, &SpellWindow::onWindowResize); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     void SpellWindow::onPinToggled() | ||||||
|  |     { | ||||||
|  |         mWindowManager.setSpellVisibility(!mPinned); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     void SpellWindow::open() | ||||||
|  |     { | ||||||
|  |         updateSpells(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     void SpellWindow::updateSpells() | ||||||
|  |     { | ||||||
|  |         const int spellHeight = 18; | ||||||
|  | 
 | ||||||
|  |         mHeight = 0; | ||||||
|  |         while (mSpellView->getChildCount()) | ||||||
|  |             MyGUI::Gui::getInstance().destroyWidget(mSpellView->getChildAt(0)); | ||||||
|  | 
 | ||||||
|  |         // retrieve all player spells, divide them into Powers and Spells and sort them
 | ||||||
|  |         std::vector<std::string> spellList; | ||||||
|  |         MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); | ||||||
|  |         MWWorld::InventoryStore& store = MWWorld::Class::get(player).getInventoryStore(player); | ||||||
|  |         MWMechanics::CreatureStats& stats = MWWorld::Class::get(player).getCreatureStats(player); | ||||||
|  |         MWMechanics::Spells& spells = stats.mSpells; | ||||||
|  | 
 | ||||||
|  |         // the following code switches between selected enchanted item and selected spell (only one of these
 | ||||||
|  |         // can be active at a time)
 | ||||||
|  |         std::string selectedSpell = spells.getSelectedSpell(); | ||||||
|  |         MWWorld::Ptr selectedItem; | ||||||
|  |         if (store.getSelectedEnchantItem() != store.end()) | ||||||
|  |         { | ||||||
|  |             selectedSpell = ""; | ||||||
|  |             selectedItem = *store.getSelectedEnchantItem(); | ||||||
|  | 
 | ||||||
|  |             bool allowSelectedItem = true; | ||||||
|  | 
 | ||||||
|  |             // make sure that the item is still in the player inventory, otherwise it can't be selected
 | ||||||
|  |             bool found = false; | ||||||
|  |             for (MWWorld::ContainerStoreIterator it(store.begin()); it != store.end(); ++it) | ||||||
|  |             { | ||||||
|  |                 if (*it == selectedItem) | ||||||
|  |                     found = true; | ||||||
|  |             } | ||||||
|  |             if (!found) | ||||||
|  |                 allowSelectedItem = false; | ||||||
|  | 
 | ||||||
|  |             // if the selected item can be equipped, make sure that it actually is equipped
 | ||||||
|  |             std::pair<std::vector<int>, bool> slots; | ||||||
|  |             slots = MWWorld::Class::get(selectedItem).getEquipmentSlots(selectedItem); | ||||||
|  |             if (!slots.first.empty()) | ||||||
|  |             { | ||||||
|  |                 bool equipped = false; | ||||||
|  |                 for (int i=0; i < MWWorld::InventoryStore::Slots; ++i) | ||||||
|  |                 { | ||||||
|  |                     if (store.getSlot(i) != store.end() && *store.getSlot(i) == selectedItem) | ||||||
|  |                     { | ||||||
|  |                         equipped = true; | ||||||
|  |                         break; | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 if (!equipped) | ||||||
|  |                     allowSelectedItem = false; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             if (!allowSelectedItem) | ||||||
|  |             { | ||||||
|  |                 store.setSelectedEnchantItem(store.end()); | ||||||
|  |                 spells.setSelectedSpell(""); | ||||||
|  |                 mWindowManager.unsetSelectedSpell(); | ||||||
|  |                 selectedItem = MWWorld::Ptr(); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |         for (MWMechanics::Spells::TIterator it = spells.begin(); it != spells.end(); ++it) | ||||||
|  |         { | ||||||
|  |             spellList.push_back(*it); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         std::vector<std::string> powers; | ||||||
|  |         std::vector<std::string>::iterator it = spellList.begin(); | ||||||
|  |         while (it != spellList.end()) | ||||||
|  |         { | ||||||
|  |             const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().spells.find(*it); | ||||||
|  |             if (spell->data.type == ESM::Spell::ST_Power) | ||||||
|  |             { | ||||||
|  |                 powers.push_back(*it); | ||||||
|  |                 it = spellList.erase(it); | ||||||
|  |             } | ||||||
|  |             else if (spell->data.type == ESM::Spell::ST_Ability) | ||||||
|  |             { | ||||||
|  |                 // abilities are always active and don't show in the spell window.
 | ||||||
|  |                 it = spellList.erase(it); | ||||||
|  |             } | ||||||
|  |             else | ||||||
|  |                 ++it; | ||||||
|  |         } | ||||||
|  |         std::sort(powers.begin(), powers.end(), sortSpells); | ||||||
|  |         std::sort(spellList.begin(), spellList.end(), sortSpells); | ||||||
|  | 
 | ||||||
|  |         // retrieve player's enchanted items
 | ||||||
|  |         std::vector<MWWorld::Ptr> items; | ||||||
|  |         for (MWWorld::ContainerStoreIterator it(store.begin()); it != store.end(); ++it) | ||||||
|  |         { | ||||||
|  |             std::string enchantId = MWWorld::Class::get(*it).getEnchantment(*it); | ||||||
|  |             if (enchantId != "") | ||||||
|  |             { | ||||||
|  |                 // only add items with "Cast once" or "Cast on use"
 | ||||||
|  |                 const ESM::Enchantment* enchant = MWBase::Environment::get().getWorld()->getStore().enchants.find(enchantId); | ||||||
|  |                 int type = enchant->data.type; | ||||||
|  |                 if (type != ESM::Enchantment::CastOnce | ||||||
|  |                     && type != ESM::Enchantment::WhenUsed) | ||||||
|  |                     continue; | ||||||
|  | 
 | ||||||
|  |                 items.push_back(*it); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         std::sort(items.begin(), items.end(), sortItems); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |         int height = estimateHeight(items.size() + powers.size() + spellList.size()); | ||||||
|  |         bool scrollVisible = height > mSpellView->getHeight(); | ||||||
|  |         mWidth = mSpellView->getWidth() - (scrollVisible ? 18 : 0); | ||||||
|  | 
 | ||||||
|  |         // powers
 | ||||||
|  |         addGroup("#{sPowers}", ""); | ||||||
|  | 
 | ||||||
|  |         for (std::vector<std::string>::const_iterator it = powers.begin(); it != powers.end(); ++it) | ||||||
|  |         { | ||||||
|  |             const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().spells.find(*it); | ||||||
|  |             MyGUI::Button* t = mSpellView->createWidget<MyGUI::Button>("SpellText", | ||||||
|  |                 MyGUI::IntCoord(4, mHeight, mWidth-8, spellHeight), MyGUI::Align::Left | MyGUI::Align::Top); | ||||||
|  |             t->setCaption(spell->name); | ||||||
|  |             t->setTextAlign(MyGUI::Align::Left); | ||||||
|  |             t->setUserString("ToolTipType", "Spell"); | ||||||
|  |             t->setUserString("Spell", *it); | ||||||
|  |             t->eventMouseWheel += MyGUI::newDelegate(this, &SpellWindow::onMouseWheel); | ||||||
|  |             t->eventMouseButtonClick += MyGUI::newDelegate(this, &SpellWindow::onSpellSelected); | ||||||
|  | 
 | ||||||
|  |             if (*it == selectedSpell) | ||||||
|  |                 t->setStateSelected(true); | ||||||
|  | 
 | ||||||
|  |             mHeight += spellHeight; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         // other spells
 | ||||||
|  |         addGroup("#{sSpells}", "#{sCostChance}"); | ||||||
|  |         for (std::vector<std::string>::const_iterator it = spellList.begin(); it != spellList.end(); ++it) | ||||||
|  |         { | ||||||
|  |             const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().spells.find(*it); | ||||||
|  |             MyGUI::Button* t = mSpellView->createWidget<MyGUI::Button>("SpellText", | ||||||
|  |                 MyGUI::IntCoord(4, mHeight, mWidth-8, spellHeight), MyGUI::Align::Left | MyGUI::Align::Top); | ||||||
|  |             t->setCaption(spell->name); | ||||||
|  |             t->setTextAlign(MyGUI::Align::Left); | ||||||
|  |             t->setUserString("ToolTipType", "Spell"); | ||||||
|  |             t->setUserString("Spell", *it); | ||||||
|  |             t->eventMouseWheel += MyGUI::newDelegate(this, &SpellWindow::onMouseWheel); | ||||||
|  |             t->eventMouseButtonClick += MyGUI::newDelegate(this, &SpellWindow::onSpellSelected); | ||||||
|  |             t->setStateSelected(*it == selectedSpell); | ||||||
|  | 
 | ||||||
|  |             // cost / success chance
 | ||||||
|  |             MyGUI::Button* costChance = mSpellView->createWidget<MyGUI::Button>("SpellText", | ||||||
|  |                 MyGUI::IntCoord(4, mHeight, mWidth-8, spellHeight), MyGUI::Align::Left | MyGUI::Align::Top); | ||||||
|  |             std::string cost = boost::lexical_cast<std::string>(spell->data.cost); | ||||||
|  |             std::string chance = boost::lexical_cast<std::string>(int(MWMechanics::getSpellSuccessChance(*it, player))); | ||||||
|  |             costChance->setCaption(cost + "/" + chance); | ||||||
|  |             costChance->setTextAlign(MyGUI::Align::Right); | ||||||
|  |             costChance->setNeedMouseFocus(false); | ||||||
|  |             costChance->setStateSelected(*it == selectedSpell); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |             mHeight += spellHeight; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |         // enchanted items
 | ||||||
|  |         addGroup("#{sMagicItem}", "#{sCostCharge}"); | ||||||
|  | 
 | ||||||
|  |         for (std::vector<MWWorld::Ptr>::const_iterator it = items.begin(); it != items.end(); ++it) | ||||||
|  |         { | ||||||
|  |             MWWorld::Ptr item = *it; | ||||||
|  | 
 | ||||||
|  |             const ESM::Enchantment* enchant = MWBase::Environment::get().getWorld()->getStore().enchants.find(MWWorld::Class::get(item).getEnchantment(item)); | ||||||
|  | 
 | ||||||
|  |             // check if the item is currently equipped (will display in a different color)
 | ||||||
|  |             bool equipped = false; | ||||||
|  |             for (int i=0; i < MWWorld::InventoryStore::Slots; ++i) | ||||||
|  |             { | ||||||
|  |                 if (store.getSlot(i) != store.end() && *store.getSlot(i) == item) | ||||||
|  |                 { | ||||||
|  |                     equipped = true; | ||||||
|  |                     break; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             MyGUI::Button* t = mSpellView->createWidget<MyGUI::Button>(equipped ? "SpellText" : "SpellTextUnequipped", | ||||||
|  |                 MyGUI::IntCoord(4, mHeight, mWidth-8, spellHeight), MyGUI::Align::Left | MyGUI::Align::Top); | ||||||
|  |             t->setCaption(MWWorld::Class::get(item).getName(item)); | ||||||
|  |             t->setTextAlign(MyGUI::Align::Left); | ||||||
|  |             t->setUserData(item); | ||||||
|  |             t->setUserString("ToolTipType", "ItemPtr"); | ||||||
|  |             t->setUserString("Equipped", equipped ? "true" : "false"); | ||||||
|  |             t->eventMouseButtonClick += MyGUI::newDelegate(this, &SpellWindow::onEnchantedItemSelected); | ||||||
|  |             t->eventMouseWheel += MyGUI::newDelegate(this, &SpellWindow::onMouseWheel); | ||||||
|  |             t->setStateSelected(item == selectedItem); | ||||||
|  | 
 | ||||||
|  |             // cost / charge
 | ||||||
|  |             MyGUI::Button* costCharge = mSpellView->createWidget<MyGUI::Button>(equipped ? "SpellText" : "SpellTextUnequipped", | ||||||
|  |                 MyGUI::IntCoord(4, mHeight, mWidth-8, spellHeight), MyGUI::Align::Left | MyGUI::Align::Top); | ||||||
|  | 
 | ||||||
|  |             std::string cost = boost::lexical_cast<std::string>(enchant->data.cost); | ||||||
|  |             std::string charge = boost::lexical_cast<std::string>(enchant->data.charge); /// \todo track current charge
 | ||||||
|  |             if (enchant->data.type == ESM::Enchantment::CastOnce) | ||||||
|  |             { | ||||||
|  |                 // this is Morrowind behaviour
 | ||||||
|  |                 cost = "100"; | ||||||
|  |                 charge = "100"; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             costCharge->setCaption(cost + "/" + charge); | ||||||
|  |             costCharge->setTextAlign(MyGUI::Align::Right); | ||||||
|  |             costCharge->setNeedMouseFocus(false); | ||||||
|  |             costCharge->setStateSelected(item == selectedItem); | ||||||
|  | 
 | ||||||
|  |             mHeight += spellHeight; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         mSpellView->setCanvasSize(mSpellView->getWidth(), std::max(mSpellView->getHeight(), mHeight)); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     void SpellWindow::addGroup(const std::string &label, const std::string& label2) | ||||||
|  |     { | ||||||
|  |         if (mSpellView->getChildCount() > 0) | ||||||
|  |         { | ||||||
|  |             MyGUI::ImageBox* separator = mSpellView->createWidget<MyGUI::ImageBox>("MW_HLine", | ||||||
|  |                 MyGUI::IntCoord(4, mHeight, mWidth-8, 18), | ||||||
|  |                 MyGUI::Align::Left | MyGUI::Align::Top); | ||||||
|  |             separator->setNeedMouseFocus(false); | ||||||
|  |             mHeight += 18; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         MyGUI::TextBox* groupWidget = mSpellView->createWidget<MyGUI::TextBox>("SandBrightText", | ||||||
|  |             MyGUI::IntCoord(0, mHeight, mWidth, 24), | ||||||
|  |             MyGUI::Align::Left | MyGUI::Align::Top | MyGUI::Align::HStretch); | ||||||
|  |         groupWidget->setCaptionWithReplacing(label); | ||||||
|  |         groupWidget->setTextAlign(MyGUI::Align::Left); | ||||||
|  |         groupWidget->setNeedMouseFocus(false); | ||||||
|  | 
 | ||||||
|  |         if (label2 != "") | ||||||
|  |         { | ||||||
|  |             MyGUI::TextBox* groupWidget2 = mSpellView->createWidget<MyGUI::TextBox>("SandBrightText", | ||||||
|  |                 MyGUI::IntCoord(0, mHeight, mWidth-4, 24), | ||||||
|  |                 MyGUI::Align::Left | MyGUI::Align::Top); | ||||||
|  |             groupWidget2->setCaptionWithReplacing(label2); | ||||||
|  |             groupWidget2->setTextAlign(MyGUI::Align::Right); | ||||||
|  |             groupWidget2->setNeedMouseFocus(false); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         mHeight += 24; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     void SpellWindow::onWindowResize(MyGUI::Window* _sender) | ||||||
|  |     { | ||||||
|  |         updateSpells(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     void SpellWindow::onEnchantedItemSelected(MyGUI::Widget* _sender) | ||||||
|  |     { | ||||||
|  |         MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); | ||||||
|  |         MWMechanics::CreatureStats& stats = MWWorld::Class::get(player).getCreatureStats(player); | ||||||
|  |         MWWorld::InventoryStore& store = MWWorld::Class::get(player).getInventoryStore(player); | ||||||
|  |         MWMechanics::Spells& spells = stats.mSpells; | ||||||
|  |         MWWorld::Ptr item = *_sender->getUserData<MWWorld::Ptr>(); | ||||||
|  | 
 | ||||||
|  |         // retrieve ContainerStoreIterator to the item
 | ||||||
|  |         MWWorld::ContainerStoreIterator it = store.begin(); | ||||||
|  |         for (; it != store.end(); ++it) | ||||||
|  |         { | ||||||
|  |             if (*it == item) | ||||||
|  |             { | ||||||
|  |                 break; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         assert(it != store.end()); | ||||||
|  | 
 | ||||||
|  |         // equip, if it can be equipped and is not already equipped
 | ||||||
|  |         if (_sender->getUserString("Equipped") == "false" | ||||||
|  |             && !MWWorld::Class::get(item).getEquipmentSlots(item).first.empty()) | ||||||
|  |         { | ||||||
|  |             // sound
 | ||||||
|  |             MWBase::Environment::get().getSoundManager()->playSound(MWWorld::Class::get(item).getUpSoundId(item), 1.0, 1.0); | ||||||
|  | 
 | ||||||
|  |             // Note: can't use Class::use here because enchanted scrolls for example would then open the scroll window instead of equipping
 | ||||||
|  | 
 | ||||||
|  |             /// \todo the following code is pretty much copy&paste from ActionEquip, put it in a function?
 | ||||||
|  |             // slots that this item can be equipped in
 | ||||||
|  |             std::pair<std::vector<int>, bool> slots = MWWorld::Class::get(item).getEquipmentSlots(item); | ||||||
|  | 
 | ||||||
|  |             // equip the item in the first free slot
 | ||||||
|  |             for (std::vector<int>::const_iterator slot=slots.first.begin(); | ||||||
|  |                 slot!=slots.first.end(); ++slot) | ||||||
|  |             { | ||||||
|  |                 // if all slots are occupied, replace the last slot
 | ||||||
|  |                 if (slot == --slots.first.end()) | ||||||
|  |                 { | ||||||
|  |                     store.equip(*slot, it); | ||||||
|  |                     break; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 if (store.getSlot(*slot) == store.end()) | ||||||
|  |                 { | ||||||
|  |                     // slot is not occupied
 | ||||||
|  |                     store.equip(*slot, it); | ||||||
|  |                     break; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             /// \todo scripts?
 | ||||||
|  | 
 | ||||||
|  |             // since we changed equipping status, update the inventory window
 | ||||||
|  |             mWindowManager.getInventoryWindow()->drawItems(); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         store.setSelectedEnchantItem(it); | ||||||
|  |         spells.setSelectedSpell(""); | ||||||
|  |         mWindowManager.setSelectedEnchantItem(item, 100); /// \todo track charge %
 | ||||||
|  | 
 | ||||||
|  |         updateSpells(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     void SpellWindow::onSpellSelected(MyGUI::Widget* _sender) | ||||||
|  |     { | ||||||
|  |         std::string spellId = _sender->getUserString("Spell"); | ||||||
|  |         MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); | ||||||
|  |         MWMechanics::CreatureStats& stats = MWWorld::Class::get(player).getCreatureStats(player); | ||||||
|  |         MWWorld::InventoryStore& store = MWWorld::Class::get(player).getInventoryStore(player); | ||||||
|  |         MWMechanics::Spells& spells = stats.mSpells; | ||||||
|  | 
 | ||||||
|  |         if (MyGUI::InputManager::getInstance().isShiftPressed()) | ||||||
|  |         { | ||||||
|  |             // delete spell, if allowed
 | ||||||
|  |             const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().spells.find(spellId); | ||||||
|  |             if (spell->data.flags & ESM::Spell::F_Always | ||||||
|  |                 || spell->data.type == ESM::Spell::ST_Power) | ||||||
|  |             { | ||||||
|  |                 mWindowManager.messageBox("#{sDeleteSpellError}", std::vector<std::string>()); | ||||||
|  |             } | ||||||
|  |             else | ||||||
|  |             { | ||||||
|  |                 // ask for confirmation
 | ||||||
|  |                 mSpellToDelete = spellId; | ||||||
|  |                 ConfirmationDialog* dialog = mWindowManager.getConfirmationDialog(); | ||||||
|  |                 std::string question = mWindowManager.getGameSettingString("sQuestionDeleteSpell", "Delete %s?"); | ||||||
|  |                 question = boost::str(boost::format(question) % spell->name); | ||||||
|  |                 dialog->open(question); | ||||||
|  |                 dialog->eventOkClicked.clear(); | ||||||
|  |                 dialog->eventOkClicked += MyGUI::newDelegate(this, &SpellWindow::onDeleteSpellAccept); | ||||||
|  |                 dialog->eventCancelClicked.clear(); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         else | ||||||
|  |         { | ||||||
|  |             spells.setSelectedSpell(spellId); | ||||||
|  |             store.setSelectedEnchantItem(store.end()); | ||||||
|  |             mWindowManager.setSelectedSpell(spellId, int(MWMechanics::getSpellSuccessChance(spellId, player))); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         updateSpells(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     int SpellWindow::estimateHeight(int numSpells) const | ||||||
|  |     { | ||||||
|  |         int height = 0; | ||||||
|  |         height += 24 * 3 + 18 * 2; // group headings
 | ||||||
|  |         height += numSpells * 18; | ||||||
|  |         return height; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     void SpellWindow::onMouseWheel(MyGUI::Widget* _sender, int _rel) | ||||||
|  |     { | ||||||
|  |         if (mSpellView->getViewOffset().top + _rel*0.3 > 0) | ||||||
|  |             mSpellView->setViewOffset(MyGUI::IntPoint(0, 0)); | ||||||
|  |         else | ||||||
|  |             mSpellView->setViewOffset(MyGUI::IntPoint(0, mSpellView->getViewOffset().top + _rel*0.3)); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     void SpellWindow::onDeleteSpellAccept() | ||||||
|  |     { | ||||||
|  |         MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); | ||||||
|  |         MWMechanics::CreatureStats& stats = MWWorld::Class::get(player).getCreatureStats(player); | ||||||
|  |         MWMechanics::Spells& spells = stats.mSpells; | ||||||
|  | 
 | ||||||
|  |         if (spells.getSelectedSpell() == mSpellToDelete) | ||||||
|  |         { | ||||||
|  |             spells.setSelectedSpell(""); | ||||||
|  |             mWindowManager.unsetSelectedSpell(); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         spells.remove(mSpellToDelete); | ||||||
|  | 
 | ||||||
|  |         updateSpells(); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										39
									
								
								apps/openmw/mwgui/spellwindow.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								apps/openmw/mwgui/spellwindow.hpp
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,39 @@ | ||||||
|  | #ifndef MWGUI_SPELLWINDOW_H | ||||||
|  | #define MWGUI_SPELLWINDOW_H | ||||||
|  | 
 | ||||||
|  | #include "window_pinnable_base.hpp" | ||||||
|  | 
 | ||||||
|  | namespace MWGui | ||||||
|  | { | ||||||
|  |     class SpellWindow : public WindowPinnableBase | ||||||
|  |     { | ||||||
|  |     public: | ||||||
|  |         SpellWindow(WindowManager& parWindowManager); | ||||||
|  | 
 | ||||||
|  |         void updateSpells(); | ||||||
|  | 
 | ||||||
|  |     protected: | ||||||
|  |         MyGUI::ScrollView* mSpellView; | ||||||
|  |         MyGUI::Widget* mEffectBox; | ||||||
|  | 
 | ||||||
|  |         int mHeight; | ||||||
|  |         int mWidth; | ||||||
|  | 
 | ||||||
|  |         std::string mSpellToDelete; | ||||||
|  | 
 | ||||||
|  |         void addGroup(const std::string& label, const std::string& label2); | ||||||
|  | 
 | ||||||
|  |         int estimateHeight(int numSpells) const; | ||||||
|  | 
 | ||||||
|  |         void onWindowResize(MyGUI::Window* _sender); | ||||||
|  |         void onEnchantedItemSelected(MyGUI::Widget* _sender); | ||||||
|  |         void onSpellSelected(MyGUI::Widget* _sender); | ||||||
|  |         void onMouseWheel(MyGUI::Widget* _sender, int _rel); | ||||||
|  |         void onDeleteSpellAccept(); | ||||||
|  | 
 | ||||||
|  |         virtual void onPinToggled(); | ||||||
|  |         virtual void open(); | ||||||
|  |     }; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
|  | @ -12,6 +12,7 @@ | ||||||
| #include "../mwbase/environment.hpp" | #include "../mwbase/environment.hpp" | ||||||
| 
 | 
 | ||||||
| #include "window_manager.hpp" | #include "window_manager.hpp" | ||||||
|  | #include "tooltips.hpp" | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| using namespace MWGui; | using namespace MWGui; | ||||||
|  | @ -77,8 +78,6 @@ StatsWindow::StatsWindow (WindowManager& parWindowManager) | ||||||
| 
 | 
 | ||||||
|     MyGUI::WindowPtr t = static_cast<MyGUI::WindowPtr>(mMainWidget); |     MyGUI::WindowPtr t = static_cast<MyGUI::WindowPtr>(mMainWidget); | ||||||
|     t->eventWindowChangeCoord += MyGUI::newDelegate(this, &StatsWindow::onWindowResize); |     t->eventWindowChangeCoord += MyGUI::newDelegate(this, &StatsWindow::onWindowResize); | ||||||
| 
 |  | ||||||
|     setupToolTips(); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void StatsWindow::onScrollChangePosition(MyGUI::ScrollBar* scroller, size_t pos) | void StatsWindow::onScrollChangePosition(MyGUI::ScrollBar* scroller, size_t pos) | ||||||
|  | @ -256,6 +255,8 @@ void StatsWindow::configureSkills (const std::vector<int>& major, const std::vec | ||||||
|         if (skillSet.find(skill) == skillSet.end()) |         if (skillSet.find(skill) == skillSet.end()) | ||||||
|             miscSkills.push_back(skill); |             miscSkills.push_back(skill); | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     updateSkillArea(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void StatsWindow::onFrame () | void StatsWindow::onFrame () | ||||||
|  | @ -339,7 +340,7 @@ MyGUI::TextBox* StatsWindow::addValueItem(const std::string& text, const std::st | ||||||
|     return skillValueWidget; |     return skillValueWidget; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| MyGUI::Widget* StatsWindow::addItem(const std::string text, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2) | MyGUI::Widget* StatsWindow::addItem(const std::string& text, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2) | ||||||
| { | { | ||||||
|     MyGUI::TextBox* skillNameWidget; |     MyGUI::TextBox* skillNameWidget; | ||||||
| 
 | 
 | ||||||
|  | @ -444,32 +445,17 @@ void StatsWindow::updateSkillArea() | ||||||
|     const ESM::Race* playerRace =  store.races.find (MWBase::Environment::get().getWorld()->getPlayer().getRace()); |     const ESM::Race* playerRace =  store.races.find (MWBase::Environment::get().getWorld()->getPlayer().getRace()); | ||||||
|     MyGUI::Widget* raceWidget; |     MyGUI::Widget* raceWidget; | ||||||
|     getWidget(raceWidget, "RaceText"); |     getWidget(raceWidget, "RaceText"); | ||||||
|     raceWidget->setUserString("Caption_CenteredCaption", playerRace->name); |     ToolTips::createRaceToolTip(raceWidget, playerRace); | ||||||
|     raceWidget->setUserString("Caption_CenteredCaptionText", playerRace->description); |  | ||||||
|     getWidget(raceWidget, "Race_str"); |     getWidget(raceWidget, "Race_str"); | ||||||
|     raceWidget->setUserString("Caption_CenteredCaption", playerRace->name); |     ToolTips::createRaceToolTip(raceWidget, playerRace); | ||||||
|     raceWidget->setUserString("Caption_CenteredCaptionText", playerRace->description); |  | ||||||
| 
 | 
 | ||||||
|     // class tooltip
 |     // class tooltip
 | ||||||
|     MyGUI::Widget* classWidget; |     MyGUI::Widget* classWidget; | ||||||
|     const ESM::Class& playerClass = MWBase::Environment::get().getWorld()->getPlayer().getClass(); |     const ESM::Class& playerClass = MWBase::Environment::get().getWorld()->getPlayer().getClass(); | ||||||
|     int spec = playerClass.data.specialization; |  | ||||||
|     std::string specStr; |  | ||||||
|     if (spec == 0) |  | ||||||
|         specStr = "#{sSpecializationCombat}"; |  | ||||||
|     else if (spec == 1) |  | ||||||
|         specStr = "#{sSpecializationMagic}"; |  | ||||||
|     else if (spec == 2) |  | ||||||
|         specStr = "#{sSpecializationStealth}"; |  | ||||||
| 
 |  | ||||||
|     getWidget(classWidget, "ClassText"); |     getWidget(classWidget, "ClassText"); | ||||||
|     classWidget->setUserString("Caption_ClassName", playerClass.name); |     ToolTips::createClassToolTip(classWidget, playerClass); | ||||||
|     classWidget->setUserString("Caption_ClassDescription", playerClass.description); |  | ||||||
|     classWidget->setUserString("Caption_ClassSpecialisation", "#{sSpecialization}: " + specStr); |  | ||||||
|     getWidget(classWidget, "Class_str"); |     getWidget(classWidget, "Class_str"); | ||||||
|     classWidget->setUserString("Caption_ClassName", playerClass.name); |     ToolTips::createClassToolTip(classWidget, playerClass); | ||||||
|     classWidget->setUserString("Caption_ClassDescription", playerClass.description); |  | ||||||
|     classWidget->setUserString("Caption_ClassSpecialisation", "#{sSpecialization}: " + specStr); |  | ||||||
| 
 | 
 | ||||||
|     if (!mFactions.empty()) |     if (!mFactions.empty()) | ||||||
|     { |     { | ||||||
|  | @ -536,61 +522,8 @@ void StatsWindow::updateSkillArea() | ||||||
|         addGroup(mWindowManager.getGameSettingString("sBirthSign", "Sign"), coord1, coord2); |         addGroup(mWindowManager.getGameSettingString("sBirthSign", "Sign"), coord1, coord2); | ||||||
|         const ESM::BirthSign *sign = store.birthSigns.find(birthSignId); |         const ESM::BirthSign *sign = store.birthSigns.find(birthSignId); | ||||||
|         MyGUI::Widget* w = addItem(sign->name, coord1, coord2); |         MyGUI::Widget* w = addItem(sign->name, coord1, coord2); | ||||||
|         w->setUserString("ToolTipType", "Layout"); |  | ||||||
|         w->setUserString("ToolTipLayout", "BirthSignToolTip"); |  | ||||||
|         std::string image = sign->texture; |  | ||||||
|         image.replace(image.size()-3, 3, "dds"); |  | ||||||
|         w->setUserString("ImageTexture_BirthSignImage", "textures\\" + image); |  | ||||||
|         std::string text; |  | ||||||
| 
 | 
 | ||||||
|         text += sign->name; |         ToolTips::createBirthsignToolTip(w, birthSignId); | ||||||
|         text += "\n#BF9959" + sign->description; |  | ||||||
| 
 |  | ||||||
|         std::vector<std::string> abilities, powers, spells; |  | ||||||
| 
 |  | ||||||
|         std::vector<std::string>::const_iterator it = sign->powers.list.begin(); |  | ||||||
|         std::vector<std::string>::const_iterator end = sign->powers.list.end(); |  | ||||||
|         for (; it != end; ++it) |  | ||||||
|         { |  | ||||||
|             const std::string &spellId = *it; |  | ||||||
|             const ESM::Spell *spell = store.spells.search(spellId); |  | ||||||
|             if (!spell) |  | ||||||
|                 continue; // Skip spells which cannot be found
 |  | ||||||
|             ESM::Spell::SpellType type = static_cast<ESM::Spell::SpellType>(spell->data.type); |  | ||||||
|             if (type != ESM::Spell::ST_Spell && type != ESM::Spell::ST_Ability && type != ESM::Spell::ST_Power) |  | ||||||
|                 continue; // We only want spell, ability and powers.
 |  | ||||||
| 
 |  | ||||||
|             if (type == ESM::Spell::ST_Ability) |  | ||||||
|                 abilities.push_back(spellId); |  | ||||||
|             else if (type == ESM::Spell::ST_Power) |  | ||||||
|                 powers.push_back(spellId); |  | ||||||
|             else if (type == ESM::Spell::ST_Spell) |  | ||||||
|                 spells.push_back(spellId); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         struct{ const std::vector<std::string> &spells; std::string label; } categories[3] = { |  | ||||||
|             {abilities, "sBirthsignmenu1"}, |  | ||||||
|             {powers,    "sPowers"}, |  | ||||||
|             {spells,    "sBirthsignmenu2"} |  | ||||||
|         }; |  | ||||||
| 
 |  | ||||||
|         for (int category = 0; category < 3; ++category) |  | ||||||
|         { |  | ||||||
|             for (std::vector<std::string>::const_iterator it = categories[category].spells.begin(); it != categories[category].spells.end(); ++it) |  | ||||||
|             { |  | ||||||
|                 if (it == categories[category].spells.begin()) |  | ||||||
|                 { |  | ||||||
|                     text += std::string("\n#DDC79E") + std::string("#{") + categories[category].label + "}"; |  | ||||||
|                 } |  | ||||||
| 
 |  | ||||||
|                 const std::string &spellId = *it; |  | ||||||
| 
 |  | ||||||
|                 const ESM::Spell *spell = store.spells.search(spellId); |  | ||||||
|                 text += "\n#BF9959" + spell->name; |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         w->setUserString("Caption_BirthSignText", text); |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // Add a line separator if there are items above
 |     // Add a line separator if there are items above
 | ||||||
|  | @ -633,116 +566,3 @@ void StatsWindow::onPinToggled() | ||||||
| { | { | ||||||
|     mWindowManager.setHMSVisibility(!mPinned); |     mWindowManager.setHMSVisibility(!mPinned); | ||||||
| } | } | ||||||
| 
 |  | ||||||
| void StatsWindow::setupToolTips() |  | ||||||
| { |  | ||||||
| 
 |  | ||||||
|     const ESMS::ESMStore &store = mWindowManager.getStore(); |  | ||||||
|     MyGUI::Widget* widget; |  | ||||||
| 
 |  | ||||||
|     /// \todo move this into the .layout file!
 |  | ||||||
| 
 |  | ||||||
|     getWidget(widget, "Attrib1"); |  | ||||||
|     widget->setUserString("ToolTipType", "Layout"); |  | ||||||
|     widget->setUserString("ToolTipLayout", "AttributeToolTip"); |  | ||||||
|     widget->setUserString("Caption_AttributeName", store.gameSettings.find ("sAttributeStrength")->str); |  | ||||||
|     widget->setUserString("Caption_AttributeDescription", store.gameSettings.find ("sStrDesc")->str); |  | ||||||
|     widget->setUserString("ImageTexture_AttributeImage", "icons\\k\\attribute_strength.dds"); |  | ||||||
|     getWidget(widget, "AttribVal1"); |  | ||||||
|     widget->setUserString("ToolTipType", "Layout"); |  | ||||||
|     widget->setUserString("ToolTipLayout", "AttributeToolTip"); |  | ||||||
|     widget->setUserString("Caption_AttributeName", store.gameSettings.find ("sAttributeStrength")->str); |  | ||||||
|     widget->setUserString("Caption_AttributeDescription", store.gameSettings.find ("sStrDesc")->str); |  | ||||||
|     widget->setUserString("ImageTexture_AttributeImage", "icons\\k\\attribute_strength.dds"); |  | ||||||
| 
 |  | ||||||
|     getWidget(widget, "Attrib2"); |  | ||||||
|     widget->setUserString("ToolTipType", "Layout"); |  | ||||||
|     widget->setUserString("ToolTipLayout", "AttributeToolTip"); |  | ||||||
|     widget->setUserString("Caption_AttributeName", store.gameSettings.find ("sAttributeIntelligence")->str); |  | ||||||
|     widget->setUserString("Caption_AttributeDescription", store.gameSettings.find ("sIntDesc")->str); |  | ||||||
|     widget->setUserString("ImageTexture_AttributeImage", "icons\\k\\attribute_int.dds"); |  | ||||||
|     getWidget(widget, "AttribVal2"); |  | ||||||
|     widget->setUserString("ToolTipType", "Layout"); |  | ||||||
|     widget->setUserString("ToolTipLayout", "AttributeToolTip"); |  | ||||||
|     widget->setUserString("Caption_AttributeName", store.gameSettings.find ("sAttributeIntelligence")->str); |  | ||||||
|     widget->setUserString("Caption_AttributeDescription", store.gameSettings.find ("sIntDesc")->str); |  | ||||||
|     widget->setUserString("ImageTexture_AttributeImage", "icons\\k\\attribute_int.dds"); |  | ||||||
| 
 |  | ||||||
|     getWidget(widget, "Attrib3"); |  | ||||||
|     widget->setUserString("ToolTipType", "Layout"); |  | ||||||
|     widget->setUserString("ToolTipLayout", "AttributeToolTip"); |  | ||||||
|     widget->setUserString("Caption_AttributeName", store.gameSettings.find ("sAttributeWillpower")->str); |  | ||||||
|     widget->setUserString("Caption_AttributeDescription", store.gameSettings.find ("sWilDesc")->str); |  | ||||||
|     widget->setUserString("ImageTexture_AttributeImage", "icons\\k\\attribute_wilpower.dds"); |  | ||||||
|     getWidget(widget, "AttribVal3"); |  | ||||||
|     widget->setUserString("ToolTipType", "Layout"); |  | ||||||
|     widget->setUserString("ToolTipLayout", "AttributeToolTip"); |  | ||||||
|     widget->setUserString("Caption_AttributeName", store.gameSettings.find ("sAttributeWillpower")->str); |  | ||||||
|     widget->setUserString("Caption_AttributeDescription", store.gameSettings.find ("sWilDesc")->str); |  | ||||||
|     widget->setUserString("ImageTexture_AttributeImage", "icons\\k\\attribute_wilpower.dds"); |  | ||||||
| 
 |  | ||||||
|     getWidget(widget, "Attrib4"); |  | ||||||
|     widget->setUserString("ToolTipType", "Layout"); |  | ||||||
|     widget->setUserString("ToolTipLayout", "AttributeToolTip"); |  | ||||||
|     widget->setUserString("Caption_AttributeName", store.gameSettings.find ("sAttributeAgility")->str); |  | ||||||
|     widget->setUserString("Caption_AttributeDescription", store.gameSettings.find ("sAgiDesc")->str); |  | ||||||
|     widget->setUserString("ImageTexture_AttributeImage", "icons\\k\\attribute_agility.dds"); |  | ||||||
|     getWidget(widget, "AttribVal4"); |  | ||||||
|     widget->setUserString("ToolTipType", "Layout"); |  | ||||||
|     widget->setUserString("ToolTipLayout", "AttributeToolTip"); |  | ||||||
|     widget->setUserString("Caption_AttributeName", store.gameSettings.find ("sAttributeAgility")->str); |  | ||||||
|     widget->setUserString("Caption_AttributeDescription", store.gameSettings.find ("sAgiDesc")->str); |  | ||||||
|     widget->setUserString("ImageTexture_AttributeImage", "icons\\k\\attribute_agility.dds"); |  | ||||||
| 
 |  | ||||||
|     getWidget(widget, "Attrib5"); |  | ||||||
|     widget->setUserString("ToolTipType", "Layout"); |  | ||||||
|     widget->setUserString("ToolTipLayout", "AttributeToolTip"); |  | ||||||
|     widget->setUserString("Caption_AttributeName", store.gameSettings.find ("sAttributeSpeed")->str); |  | ||||||
|     widget->setUserString("Caption_AttributeDescription", store.gameSettings.find ("sSpdDesc")->str); |  | ||||||
|     widget->setUserString("ImageTexture_AttributeImage", "icons\\k\\attribute_speed.dds"); |  | ||||||
|     getWidget(widget, "AttribVal5"); |  | ||||||
|     widget->setUserString("ToolTipType", "Layout"); |  | ||||||
|     widget->setUserString("ToolTipLayout", "AttributeToolTip"); |  | ||||||
|     widget->setUserString("Caption_AttributeName", store.gameSettings.find ("sAttributeSpeed")->str); |  | ||||||
|     widget->setUserString("Caption_AttributeDescription", store.gameSettings.find ("sSpdDesc")->str); |  | ||||||
|     widget->setUserString("ImageTexture_AttributeImage", "icons\\k\\attribute_speed.dds"); |  | ||||||
| 
 |  | ||||||
|     getWidget(widget, "Attrib6"); |  | ||||||
|     widget->setUserString("ToolTipType", "Layout"); |  | ||||||
|     widget->setUserString("ToolTipLayout", "AttributeToolTip"); |  | ||||||
|     widget->setUserString("Caption_AttributeName", store.gameSettings.find ("sAttributeEndurance")->str); |  | ||||||
|     widget->setUserString("Caption_AttributeDescription", store.gameSettings.find ("sEndDesc")->str); |  | ||||||
|     widget->setUserString("ImageTexture_AttributeImage", "icons\\k\\attribute_endurance.dds"); |  | ||||||
|     getWidget(widget, "AttribVal6"); |  | ||||||
|     widget->setUserString("ToolTipType", "Layout"); |  | ||||||
|     widget->setUserString("ToolTipLayout", "AttributeToolTip"); |  | ||||||
|     widget->setUserString("Caption_AttributeName", store.gameSettings.find ("sAttributeEndurance")->str); |  | ||||||
|     widget->setUserString("Caption_AttributeDescription", store.gameSettings.find ("sEndDesc")->str); |  | ||||||
|     widget->setUserString("ImageTexture_AttributeImage", "icons\\k\\attribute_endurance.dds"); |  | ||||||
| 
 |  | ||||||
|     getWidget(widget, "Attrib7"); |  | ||||||
|     widget->setUserString("ToolTipType", "Layout"); |  | ||||||
|     widget->setUserString("ToolTipLayout", "AttributeToolTip"); |  | ||||||
|     widget->setUserString("Caption_AttributeName", store.gameSettings.find ("sAttributePersonality")->str); |  | ||||||
|     widget->setUserString("Caption_AttributeDescription", store.gameSettings.find ("sPerDesc")->str); |  | ||||||
|     widget->setUserString("ImageTexture_AttributeImage", "icons\\k\\attribute_personality.dds"); |  | ||||||
|     getWidget(widget, "AttribVal7"); |  | ||||||
|     widget->setUserString("ToolTipType", "Layout"); |  | ||||||
|     widget->setUserString("ToolTipLayout", "AttributeToolTip"); |  | ||||||
|     widget->setUserString("Caption_AttributeName", store.gameSettings.find ("sAttributePersonality")->str); |  | ||||||
|     widget->setUserString("Caption_AttributeDescription", store.gameSettings.find ("sPerDesc")->str); |  | ||||||
|     widget->setUserString("ImageTexture_AttributeImage", "icons\\k\\attribute_personality.dds"); |  | ||||||
| 
 |  | ||||||
|     getWidget(widget, "Attrib8"); |  | ||||||
|     widget->setUserString("ToolTipType", "Layout"); |  | ||||||
|     widget->setUserString("ToolTipLayout", "AttributeToolTip"); |  | ||||||
|     widget->setUserString("Caption_AttributeName", store.gameSettings.find ("sAttributeLuck")->str); |  | ||||||
|     widget->setUserString("Caption_AttributeDescription", store.gameSettings.find ("sLucDesc")->str); |  | ||||||
|     widget->setUserString("ImageTexture_AttributeImage", "icons\\k\\attribute_luck.dds"); |  | ||||||
|     getWidget(widget, "AttribVal8"); |  | ||||||
|     widget->setUserString("ToolTipType", "Layout"); |  | ||||||
|     widget->setUserString("ToolTipLayout", "AttributeToolTip"); |  | ||||||
|     widget->setUserString("Caption_AttributeName", store.gameSettings.find ("sAttributeLuck")->str); |  | ||||||
|     widget->setUserString("Caption_AttributeDescription", store.gameSettings.find ("sLucDesc")->str); |  | ||||||
|     widget->setUserString("ImageTexture_AttributeImage", "icons\\k\\attribute_luck.dds"); |  | ||||||
| } |  | ||||||
|  |  | ||||||
|  | @ -47,11 +47,9 @@ namespace MWGui | ||||||
|             void addSeparator(MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2); |             void addSeparator(MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2); | ||||||
|             void addGroup(const std::string &label, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2); |             void addGroup(const std::string &label, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2); | ||||||
|             MyGUI::TextBox* addValueItem(const std::string& text, const std::string &value, const std::string& state, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2); |             MyGUI::TextBox* addValueItem(const std::string& text, const std::string &value, const std::string& state, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2); | ||||||
|             MyGUI::Widget* addItem(const std::string text, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2); |             MyGUI::Widget* addItem(const std::string& text, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2); | ||||||
|             void updateScroller(); |             void updateScroller(); | ||||||
| 
 | 
 | ||||||
|             void setupToolTips(); |  | ||||||
| 
 |  | ||||||
|             void setFactions (const FactionList& factions); |             void setFactions (const FactionList& factions); | ||||||
|             void setBirthSign (const std::string &signId); |             void setBirthSign (const std::string &signId); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -8,6 +8,8 @@ | ||||||
| 
 | 
 | ||||||
| #include <boost/lexical_cast.hpp> | #include <boost/lexical_cast.hpp> | ||||||
| 
 | 
 | ||||||
|  | #include <components/settings/settings.hpp> | ||||||
|  | 
 | ||||||
| using namespace MWGui; | using namespace MWGui; | ||||||
| using namespace MyGUI; | using namespace MyGUI; | ||||||
| 
 | 
 | ||||||
|  | @ -19,6 +21,10 @@ ToolTips::ToolTips(WindowManager* windowManager) : | ||||||
|     , mEnabled(true) |     , mEnabled(true) | ||||||
|     , mFocusToolTipX(0.0) |     , mFocusToolTipX(0.0) | ||||||
|     , mFocusToolTipY(0.0) |     , mFocusToolTipY(0.0) | ||||||
|  |     , mDelay(0.0) | ||||||
|  |     , mRemainingDelay(0.0) | ||||||
|  |     , mLastMouseX(0) | ||||||
|  |     , mLastMouseY(0) | ||||||
| { | { | ||||||
|     getWidget(mDynamicToolTipBox, "DynamicToolTipBox"); |     getWidget(mDynamicToolTipBox, "DynamicToolTipBox"); | ||||||
| 
 | 
 | ||||||
|  | @ -28,6 +34,9 @@ ToolTips::ToolTips(WindowManager* windowManager) : | ||||||
|     // even if the mouse is over the tooltip
 |     // even if the mouse is over the tooltip
 | ||||||
|     mDynamicToolTipBox->setNeedMouseFocus(false); |     mDynamicToolTipBox->setNeedMouseFocus(false); | ||||||
|     mMainWidget->setNeedMouseFocus(false); |     mMainWidget->setNeedMouseFocus(false); | ||||||
|  | 
 | ||||||
|  |     mDelay = Settings::Manager::getFloat("tooltip delay", "GUI"); | ||||||
|  |     mRemainingDelay = mDelay; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void ToolTips::setEnabled(bool enabled) | void ToolTips::setEnabled(bool enabled) | ||||||
|  | @ -37,10 +46,10 @@ void ToolTips::setEnabled(bool enabled) | ||||||
| 
 | 
 | ||||||
| void ToolTips::onFrame(float frameDuration) | void ToolTips::onFrame(float frameDuration) | ||||||
| { | { | ||||||
|     MyGUI::Gui::getInstance().destroyWidget(mDynamicToolTipBox); |     while (mDynamicToolTipBox->getChildCount()) | ||||||
|     mDynamicToolTipBox = mMainWidget->createWidget<Widget>("HUD_Box", |     { | ||||||
|         IntCoord(0, 0, mMainWidget->getCoord().width, mMainWidget->getCoord().height), |         MyGUI::Gui::getInstance().destroyWidget(mDynamicToolTipBox->getChildAt(0)); | ||||||
|         Align::Stretch, "DynamicToolTipBox"); |     } | ||||||
| 
 | 
 | ||||||
|     // start by hiding everything
 |     // start by hiding everything
 | ||||||
|     for (unsigned int i=0; i < mMainWidget->getChildCount(); ++i) |     for (unsigned int i=0; i < mMainWidget->getChildCount(); ++i) | ||||||
|  | @ -57,105 +66,193 @@ void ToolTips::onFrame(float frameDuration) | ||||||
| 
 | 
 | ||||||
|     if (!mGameMode) |     if (!mGameMode) | ||||||
|     { |     { | ||||||
|         Widget* focus = InputManager::getInstance().getMouseFocusWidget(); |         const MyGUI::IntPoint& mousePos = InputManager::getInstance().getMousePosition(); | ||||||
|         if (focus == 0) |  | ||||||
|         { |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
| 
 | 
 | ||||||
|         IntSize tooltipSize; |         if (mWindowManager->getWorldMouseOver() && ((mWindowManager->getMode() == GM_Console) | ||||||
| 
 |             || (mWindowManager->getMode() == GM_Container) | ||||||
|         std::string type = focus->getUserString("ToolTipType"); |             || (mWindowManager->getMode() == GM_Inventory))) | ||||||
|         std::string text = focus->getUserString("ToolTipText"); |  | ||||||
| 
 |  | ||||||
|         ToolTipInfo info; |  | ||||||
|         if (type == "") |  | ||||||
|         { |         { | ||||||
|             return; |             std::string handle = MWBase::Environment::get().getWorld()->getFacedHandle(); | ||||||
|         } |             try | ||||||
|         else if (type == "ItemPtr") |  | ||||||
|         { |  | ||||||
|             mFocusObject = *focus->getUserData<MWWorld::Ptr>(); |  | ||||||
|             tooltipSize = getToolTipViaPtr(false); |  | ||||||
|         } |  | ||||||
|         else if (type == "Layout") |  | ||||||
|         { |  | ||||||
|             // tooltip defined in the layout
 |  | ||||||
|             MyGUI::Widget* tooltip; |  | ||||||
|             getWidget(tooltip, focus->getUserString("ToolTipLayout")); |  | ||||||
| 
 |  | ||||||
|             tooltip->setVisible(true); |  | ||||||
|             if (!tooltip->isUserString("DontResize")) |  | ||||||
|             { |             { | ||||||
|                 tooltip->setCoord(0, 0, 450, 300); // this is the maximum width of the tooltip before it starts word-wrapping
 |                 mFocusObject = MWBase::Environment::get().getWorld()->getPtrViaHandle(handle); | ||||||
|  |             } | ||||||
|  |             catch (std::exception& e) | ||||||
|  |             { | ||||||
|  |                 return; | ||||||
|  |             } | ||||||
| 
 | 
 | ||||||
|                 tooltipSize = MyGUI::IntSize(0, tooltip->getSize().height); |             MyGUI::IntSize tooltipSize = getToolTipViaPtr(true); | ||||||
|  | 
 | ||||||
|  |             IntPoint tooltipPosition = InputManager::getInstance().getMousePosition() + IntPoint(0, 24); | ||||||
|  | 
 | ||||||
|  |             // make the tooltip stay completely in the viewport
 | ||||||
|  |             if ((tooltipPosition.left + tooltipSize.width) > viewSize.width) | ||||||
|  |             { | ||||||
|  |                 tooltipPosition.left = viewSize.width - tooltipSize.width; | ||||||
|  |             } | ||||||
|  |             if ((tooltipPosition.top + tooltipSize.height) > viewSize.height) | ||||||
|  |             { | ||||||
|  |                 tooltipPosition.top = viewSize.height - tooltipSize.height; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             setCoord(tooltipPosition.left, tooltipPosition.top, tooltipSize.width, tooltipSize.height); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         else | ||||||
|  |         { | ||||||
|  |             const MyGUI::IntPoint& lastPressed = InputManager::getInstance().getLastPressedPosition(MyGUI::MouseButton::Left); | ||||||
|  | 
 | ||||||
|  |             if (mousePos == lastPressed) // mouseclick makes tooltip disappear
 | ||||||
|  |                 return; | ||||||
|  | 
 | ||||||
|  |             if (mousePos.left == mLastMouseX && mousePos.top == mLastMouseY) | ||||||
|  |             { | ||||||
|  |                 mRemainingDelay -= frameDuration; | ||||||
|             } |             } | ||||||
|             else |             else | ||||||
|                 tooltipSize = tooltip->getSize(); |  | ||||||
| 
 |  | ||||||
|             std::map<std::string, std::string> userStrings = focus->getUserStrings(); |  | ||||||
|             for (std::map<std::string, std::string>::iterator it = userStrings.begin(); |  | ||||||
|                 it != userStrings.end(); ++it) |  | ||||||
|             { |             { | ||||||
|                 if (it->first == "ToolTipType" |                 mRemainingDelay = mDelay; | ||||||
|                     || it->first == "ToolTipLayout") |             } | ||||||
|                     continue; |             mLastMouseX = mousePos.left; | ||||||
|  |             mLastMouseY = mousePos.top; | ||||||
| 
 | 
 | ||||||
|  |             if (mRemainingDelay > 0) | ||||||
|  |                 return; | ||||||
| 
 | 
 | ||||||
|                 size_t underscorePos = it->first.find("_"); |             Widget* focus = InputManager::getInstance().getMouseFocusWidget(); | ||||||
|                 std::string propertyKey = it->first.substr(0, underscorePos); |             if (focus == 0) | ||||||
|                 std::string widgetName = it->first.substr(underscorePos+1, it->first.size()-(underscorePos+1)); |             { | ||||||
| 
 |                 return; | ||||||
|                 MyGUI::Widget* w; |  | ||||||
|                 getWidget(w, widgetName); |  | ||||||
|                 w->setProperty(propertyKey, it->second); |  | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             for (unsigned int i=0; i<tooltip->getChildCount(); ++i) |             IntSize tooltipSize; | ||||||
|  | 
 | ||||||
|  |             // try to go 1 level up until there is a widget that has tooltip
 | ||||||
|  |             // this is necessary because some skin elements are actually separate widgets
 | ||||||
|  |             int i=0; | ||||||
|  |             while (!focus->isUserString("ToolTipType")) | ||||||
|             { |             { | ||||||
|                 MyGUI::Widget* w = tooltip->getChildAt(i); |                 focus = focus->getParent(); | ||||||
| 
 |                 if (!focus) | ||||||
|                 if (w->isUserString("AutoResizeHorizontal")) |                     return; | ||||||
|                 { |                 ++i; | ||||||
|                     MyGUI::TextBox* text = w->castType<MyGUI::TextBox>(); |  | ||||||
|                     tooltipSize.width = std::max(tooltipSize.width, w->getLeft() + text->getTextSize().width + 8); |  | ||||||
|                 } |  | ||||||
|                 else if (!tooltip->isUserString("DontResize")) |  | ||||||
|                     tooltipSize.width = std::max(tooltipSize.width, w->getLeft() + w->getWidth() + 8); |  | ||||||
| 
 |  | ||||||
|                 if (w->isUserString("AutoResizeVertical")) |  | ||||||
|                 { |  | ||||||
|                     MyGUI::TextBox* text = w->castType<MyGUI::TextBox>(); |  | ||||||
|                     int height = text->getTextSize().height; |  | ||||||
|                     if (height > w->getHeight()) |  | ||||||
|                     { |  | ||||||
|                         tooltipSize += MyGUI::IntSize(0, height - w->getHeight()); |  | ||||||
|                     } |  | ||||||
|                     if (height < w->getHeight()) |  | ||||||
|                     { |  | ||||||
|                         tooltipSize -= MyGUI::IntSize(0, w->getHeight() - height); |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
|             } |             } | ||||||
|             tooltip->setCoord(0, 0, tooltipSize.width, tooltipSize.height); |  | ||||||
|         } |  | ||||||
|         else |  | ||||||
|             throw std::runtime_error ("unknown tooltip type"); |  | ||||||
| 
 | 
 | ||||||
|         IntPoint tooltipPosition = InputManager::getInstance().getMousePosition() + IntPoint(0, 24); |             std::string type = focus->getUserString("ToolTipType"); | ||||||
|  |             std::string text = focus->getUserString("ToolTipText"); | ||||||
| 
 | 
 | ||||||
|         // make the tooltip stay completely in the viewport
 |             if (type == "") | ||||||
|         if ((tooltipPosition.left + tooltipSize.width) > viewSize.width) |             { | ||||||
|         { |                 return; | ||||||
|             tooltipPosition.left = viewSize.width - tooltipSize.width; |             } | ||||||
|         } |             else if (type == "ItemPtr") | ||||||
|         if ((tooltipPosition.top + tooltipSize.height) > viewSize.height) |             { | ||||||
|         { |                 mFocusObject = *focus->getUserData<MWWorld::Ptr>(); | ||||||
|             tooltipPosition.top = viewSize.height - tooltipSize.height; |                 tooltipSize = getToolTipViaPtr(false); | ||||||
|         } |             } | ||||||
|  |             else if (type == "Spell") | ||||||
|  |             { | ||||||
|  |                 ToolTipInfo info; | ||||||
|  |                 const ESM::Spell *spell = MWBase::Environment::get().getWorld()->getStore().spells.find(focus->getUserString("Spell")); | ||||||
|  |                 info.caption = spell->name; | ||||||
|  |                 Widgets::SpellEffectList effects; | ||||||
|  |                 std::vector<ESM::ENAMstruct>::const_iterator end = spell->effects.list.end(); | ||||||
|  |                 for (std::vector<ESM::ENAMstruct>::const_iterator it = spell->effects.list.begin(); it != end; ++it) | ||||||
|  |                 { | ||||||
|  |                     Widgets::SpellEffectParams params; | ||||||
|  |                     params.mEffectID = it->effectID; | ||||||
|  |                     params.mSkill = it->skill; | ||||||
|  |                     params.mAttribute = it->attribute; | ||||||
|  |                     params.mDuration = it->duration; | ||||||
|  |                     params.mMagnMin = it->magnMin; | ||||||
|  |                     params.mMagnMax = it->magnMax; | ||||||
|  |                     params.mRange = it->range; | ||||||
|  |                     params.mIsConstant = (spell->data.type == ESM::Spell::ST_Ability); | ||||||
|  |                     effects.push_back(params); | ||||||
|  |                 } | ||||||
|  |                 info.effects = effects; | ||||||
|  |                 tooltipSize = createToolTip(info); | ||||||
|  |             } | ||||||
|  |             else if (type == "Layout") | ||||||
|  |             { | ||||||
|  |                 // tooltip defined in the layout
 | ||||||
|  |                 MyGUI::Widget* tooltip; | ||||||
|  |                 getWidget(tooltip, focus->getUserString("ToolTipLayout")); | ||||||
| 
 | 
 | ||||||
|         setCoord(tooltipPosition.left, tooltipPosition.top, tooltipSize.width, tooltipSize.height); |                 tooltip->setVisible(true); | ||||||
|  |                 if (!tooltip->isUserString("DontResize")) | ||||||
|  |                 { | ||||||
|  |                     tooltip->setCoord(0, 0, 450, 300); // this is the maximum width of the tooltip before it starts word-wrapping
 | ||||||
|  | 
 | ||||||
|  |                     tooltipSize = MyGUI::IntSize(0, tooltip->getSize().height); | ||||||
|  |                 } | ||||||
|  |                 else | ||||||
|  |                     tooltipSize = tooltip->getSize(); | ||||||
|  | 
 | ||||||
|  |                 std::map<std::string, std::string> userStrings = focus->getUserStrings(); | ||||||
|  |                 for (std::map<std::string, std::string>::iterator it = userStrings.begin(); | ||||||
|  |                     it != userStrings.end(); ++it) | ||||||
|  |                 { | ||||||
|  |                     if (it->first == "ToolTipType" | ||||||
|  |                         || it->first == "ToolTipLayout") | ||||||
|  |                         continue; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |                     size_t underscorePos = it->first.find("_"); | ||||||
|  |                     std::string propertyKey = it->first.substr(0, underscorePos); | ||||||
|  |                     std::string widgetName = it->first.substr(underscorePos+1, it->first.size()-(underscorePos+1)); | ||||||
|  | 
 | ||||||
|  |                     MyGUI::Widget* w; | ||||||
|  |                     getWidget(w, widgetName); | ||||||
|  |                     w->setProperty(propertyKey, it->second); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 for (unsigned int i=0; i<tooltip->getChildCount(); ++i) | ||||||
|  |                 { | ||||||
|  |                     MyGUI::Widget* w = tooltip->getChildAt(i); | ||||||
|  | 
 | ||||||
|  |                     if (w->isUserString("AutoResizeHorizontal")) | ||||||
|  |                     { | ||||||
|  |                         MyGUI::TextBox* text = w->castType<MyGUI::TextBox>(); | ||||||
|  |                         tooltipSize.width = std::max(tooltipSize.width, w->getLeft() + text->getTextSize().width + 8); | ||||||
|  |                     } | ||||||
|  |                     else if (!tooltip->isUserString("DontResize")) | ||||||
|  |                         tooltipSize.width = std::max(tooltipSize.width, w->getLeft() + w->getWidth() + 8); | ||||||
|  | 
 | ||||||
|  |                     if (w->isUserString("AutoResizeVertical")) | ||||||
|  |                     { | ||||||
|  |                         MyGUI::TextBox* text = w->castType<MyGUI::TextBox>(); | ||||||
|  |                         int height = text->getTextSize().height; | ||||||
|  |                         if (height > w->getHeight()) | ||||||
|  |                         { | ||||||
|  |                             tooltipSize += MyGUI::IntSize(0, height - w->getHeight()); | ||||||
|  |                         } | ||||||
|  |                         if (height < w->getHeight()) | ||||||
|  |                         { | ||||||
|  |                             tooltipSize -= MyGUI::IntSize(0, w->getHeight() - height); | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |                 tooltip->setCoord(0, 0, tooltipSize.width, tooltipSize.height); | ||||||
|  |             } | ||||||
|  |             else | ||||||
|  |                 throw std::runtime_error ("unknown tooltip type"); | ||||||
|  | 
 | ||||||
|  |             IntPoint tooltipPosition = InputManager::getInstance().getMousePosition() + IntPoint(0, 24); | ||||||
|  | 
 | ||||||
|  |             // make the tooltip stay completely in the viewport
 | ||||||
|  |             if ((tooltipPosition.left + tooltipSize.width) > viewSize.width) | ||||||
|  |             { | ||||||
|  |                 tooltipPosition.left = viewSize.width - tooltipSize.width; | ||||||
|  |             } | ||||||
|  |             if ((tooltipPosition.top + tooltipSize.height) > viewSize.height) | ||||||
|  |             { | ||||||
|  |                 tooltipPosition.top = viewSize.height - tooltipSize.height; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             setCoord(tooltipPosition.left, tooltipPosition.top, tooltipSize.width, tooltipSize.height); | ||||||
|  |         } | ||||||
|     } |     } | ||||||
|     else |     else | ||||||
|     { |     { | ||||||
|  | @ -285,7 +382,7 @@ IntSize ToolTips::createToolTip(const MWGui::ToolTipInfo& info) | ||||||
|     IntSize totalSize = IntSize( std::max(textSize.width, captionSize.width + ((image != "") ? imageCaptionHPadding : 0)), |     IntSize totalSize = IntSize( std::max(textSize.width, captionSize.width + ((image != "") ? imageCaptionHPadding : 0)), | ||||||
|         ((text != "") ? textSize.height + imageCaptionVPadding : 0) + captionHeight ); |         ((text != "") ? textSize.height + imageCaptionVPadding : 0) + captionHeight ); | ||||||
| 
 | 
 | ||||||
|     if (info.effects != 0) |     if (!info.effects.empty()) | ||||||
|     { |     { | ||||||
|         Widget* effectArea = mDynamicToolTipBox->createWidget<Widget>("", |         Widget* effectArea = mDynamicToolTipBox->createWidget<Widget>("", | ||||||
|             IntCoord(0, totalSize.height, 300, 300-totalSize.height), |             IntCoord(0, totalSize.height, 300, 300-totalSize.height), | ||||||
|  | @ -305,7 +402,7 @@ IntSize ToolTips::createToolTip(const MWGui::ToolTipInfo& info) | ||||||
|         effectsWidget->setEffectList(info.effects); |         effectsWidget->setEffectList(info.effects); | ||||||
| 
 | 
 | ||||||
|         std::vector<MyGUI::WidgetPtr> effectItems; |         std::vector<MyGUI::WidgetPtr> effectItems; | ||||||
|         effectsWidget->createEffectWidgets(effectItems, effectArea, coord, true, Widgets::MWEffectList::EF_Potion); |         effectsWidget->createEffectWidgets(effectItems, effectArea, coord, true, Widgets::MWEffectList::EF_NoTarget); | ||||||
|         totalSize.height += coord.top-6; |         totalSize.height += coord.top-6; | ||||||
|         totalSize.width = std::max(totalSize.width, coord.width); |         totalSize.width = std::max(totalSize.width, coord.width); | ||||||
|     } |     } | ||||||
|  | @ -321,7 +418,7 @@ IntSize ToolTips::createToolTip(const MWGui::ToolTipInfo& info) | ||||||
|         Widgets::MWEffectListPtr enchantWidget = enchantArea->createWidget<Widgets::MWEffectList> |         Widgets::MWEffectListPtr enchantWidget = enchantArea->createWidget<Widgets::MWEffectList> | ||||||
|             ("MW_StatName", coord, Align::Default, "ToolTipEnchantWidget"); |             ("MW_StatName", coord, Align::Default, "ToolTipEnchantWidget"); | ||||||
|         enchantWidget->setWindowManager(mWindowManager); |         enchantWidget->setWindowManager(mWindowManager); | ||||||
|         enchantWidget->setEffectList(&enchant->effects); |         enchantWidget->setEffectList(Widgets::MWEffectList::effectListFromESM(&enchant->effects)); | ||||||
| 
 | 
 | ||||||
|         std::vector<MyGUI::WidgetPtr> enchantEffectItems; |         std::vector<MyGUI::WidgetPtr> enchantEffectItems; | ||||||
|         int flag = (enchant->data.type == ESM::Enchantment::ConstantEffect) ? Widgets::MWEffectList::EF_Constant : 0; |         int flag = (enchant->data.type == ESM::Enchantment::ConstantEffect) ? Widgets::MWEffectList::EF_Constant : 0; | ||||||
|  | @ -339,7 +436,6 @@ IntSize ToolTips::createToolTip(const MWGui::ToolTipInfo& info) | ||||||
| 
 | 
 | ||||||
|             TextBox* chargeText = enchantArea->createWidget<TextBox>("SandText", IntCoord(0, 0, 10, 18), Align::Default, "ToolTipEnchantChargeText"); |             TextBox* chargeText = enchantArea->createWidget<TextBox>("SandText", IntCoord(0, 0, 10, 18), Align::Default, "ToolTipEnchantChargeText"); | ||||||
|             chargeText->setCaption(store.gameSettings.search("sCharges")->str); |             chargeText->setCaption(store.gameSettings.search("sCharges")->str); | ||||||
|             chargeText->setProperty("Static", "true"); |  | ||||||
|             const int chargeTextWidth = chargeText->getTextSize().width + 5; |             const int chargeTextWidth = chargeText->getTextSize().width + 5; | ||||||
| 
 | 
 | ||||||
|             const int chargeAndTextWidth = chargeWidth + chargeTextWidth; |             const int chargeAndTextWidth = chargeWidth + chargeTextWidth; | ||||||
|  | @ -440,3 +536,156 @@ void ToolTips::setFocusObjectScreenCoords(float min_x, float min_y, float max_x, | ||||||
|     mFocusToolTipX = (min_x + max_x) / 2; |     mFocusToolTipX = (min_x + max_x) / 2; | ||||||
|     mFocusToolTipY = min_y; |     mFocusToolTipY = min_y; | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | void ToolTips::createSkillToolTip(MyGUI::Widget* widget, int skillId) | ||||||
|  | { | ||||||
|  |     if (skillId == -1) | ||||||
|  |         return; | ||||||
|  | 
 | ||||||
|  |     const std::string &skillNameId = ESMS::Skill::sSkillNameIds[skillId]; | ||||||
|  |     const ESM::Skill* skill = MWBase::Environment::get().getWorld()->getStore().skills.search(skillId); | ||||||
|  |     assert(skill); | ||||||
|  |     const ESM::Attribute* attr = MWBase::Environment::get().getWorld()->getStore().attributes.search(skill->data.attribute); | ||||||
|  |     assert(attr); | ||||||
|  |     std::string icon = "icons\\k\\" + ESM::Skill::sIconNames[skillId]; | ||||||
|  | 
 | ||||||
|  |     widget->setUserString("ToolTipType", "Layout"); | ||||||
|  |     widget->setUserString("ToolTipLayout", "SkillNoProgressToolTip"); | ||||||
|  |     widget->setUserString("Caption_SkillNoProgressName", "#{"+skillNameId+"}"); | ||||||
|  |     widget->setUserString("Caption_SkillNoProgressDescription", skill->description); | ||||||
|  |     widget->setUserString("Caption_SkillNoProgressAttribute", "#{sGoverningAttribute}: #{" + attr->name + "}"); | ||||||
|  |     widget->setUserString("ImageTexture_SkillNoProgressImage", icon); | ||||||
|  |     widget->setUserString("ToolTipLayout", "SkillNoProgressToolTip"); | ||||||
|  |     widget->setUserString("ToolTipLayout", "SkillNoProgressToolTip"); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void ToolTips::createAttributeToolTip(MyGUI::Widget* widget, int attributeId) | ||||||
|  | { | ||||||
|  |     if (attributeId == -1) | ||||||
|  |         return; | ||||||
|  | 
 | ||||||
|  |     const ESM::Attribute* attr = MWBase::Environment::get().getWorld()->getStore().attributes.search(attributeId); | ||||||
|  |     assert(attr); | ||||||
|  |     std::string icon = ESM::Attribute::attributeIcons[attributeId]; | ||||||
|  |     std::string name = ESM::Attribute::gmstAttributeIds[attributeId]; | ||||||
|  |     std::string desc = ESM::Attribute::gmstAttributeDescIds[attributeId]; | ||||||
|  | 
 | ||||||
|  |     widget->setUserString("ToolTipType", "Layout"); | ||||||
|  |     widget->setUserString("ToolTipLayout", "AttributeToolTip"); | ||||||
|  |     widget->setUserString("Caption_AttributeName", "#{"+name+"}"); | ||||||
|  |     widget->setUserString("Caption_AttributeDescription", "#{"+desc+"}"); | ||||||
|  |     widget->setUserString("ImageTexture_AttributeImage", icon); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void ToolTips::createSpecializationToolTip(MyGUI::Widget* widget, const std::string& name, int specId) | ||||||
|  | { | ||||||
|  |     widget->setUserString("Caption_CenteredCaption", name); | ||||||
|  |     std::string specText; | ||||||
|  |     // get all skills of this specialisation
 | ||||||
|  |     std::map<int, ESM::Skill> skills = MWBase::Environment::get().getWorld()->getStore().skills.list; | ||||||
|  |     for (std::map<int, ESM::Skill>::const_iterator it = skills.begin(); | ||||||
|  |         it != skills.end(); ++it) | ||||||
|  |     { | ||||||
|  |         if (it->second.data.specialization == specId) | ||||||
|  |             specText += std::string("\n#{") + ESM::Skill::sSkillNameIds[it->second.index] + "}"; | ||||||
|  |     } | ||||||
|  |     widget->setUserString("Caption_CenteredCaptionText", specText); | ||||||
|  |     widget->setUserString("ToolTipLayout", "TextWithCenteredCaptionToolTip"); | ||||||
|  |     widget->setUserString("ToolTipType", "Layout"); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void ToolTips::createBirthsignToolTip(MyGUI::Widget* widget, const std::string& birthsignId) | ||||||
|  | { | ||||||
|  |     const ESM::BirthSign *sign = MWBase::Environment::get().getWorld()->getStore().birthSigns.find(birthsignId); | ||||||
|  | 
 | ||||||
|  |     widget->setUserString("ToolTipType", "Layout"); | ||||||
|  |     widget->setUserString("ToolTipLayout", "BirthSignToolTip"); | ||||||
|  |     std::string image = sign->texture; | ||||||
|  |     image.replace(image.size()-3, 3, "dds"); | ||||||
|  |     widget->setUserString("ImageTexture_BirthSignImage", "textures\\" + image); | ||||||
|  |     std::string text; | ||||||
|  | 
 | ||||||
|  |     text += sign->name; | ||||||
|  |     text += "\n#BF9959" + sign->description; | ||||||
|  | 
 | ||||||
|  |     std::vector<std::string> abilities, powers, spells; | ||||||
|  | 
 | ||||||
|  |     std::vector<std::string>::const_iterator it = sign->powers.list.begin(); | ||||||
|  |     std::vector<std::string>::const_iterator end = sign->powers.list.end(); | ||||||
|  |     for (; it != end; ++it) | ||||||
|  |     { | ||||||
|  |         const std::string &spellId = *it; | ||||||
|  |         const ESM::Spell *spell = MWBase::Environment::get().getWorld()->getStore().spells.search(spellId); | ||||||
|  |         if (!spell) | ||||||
|  |             continue; // Skip spells which cannot be found
 | ||||||
|  |         ESM::Spell::SpellType type = static_cast<ESM::Spell::SpellType>(spell->data.type); | ||||||
|  |         if (type != ESM::Spell::ST_Spell && type != ESM::Spell::ST_Ability && type != ESM::Spell::ST_Power) | ||||||
|  |             continue; // We only want spell, ability and powers.
 | ||||||
|  | 
 | ||||||
|  |         if (type == ESM::Spell::ST_Ability) | ||||||
|  |             abilities.push_back(spellId); | ||||||
|  |         else if (type == ESM::Spell::ST_Power) | ||||||
|  |             powers.push_back(spellId); | ||||||
|  |         else if (type == ESM::Spell::ST_Spell) | ||||||
|  |             spells.push_back(spellId); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     struct{ const std::vector<std::string> &spells; std::string label; } categories[3] = { | ||||||
|  |         {abilities, "sBirthsignmenu1"}, | ||||||
|  |         {powers,    "sPowers"}, | ||||||
|  |         {spells,    "sBirthsignmenu2"} | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     for (int category = 0; category < 3; ++category) | ||||||
|  |     { | ||||||
|  |         for (std::vector<std::string>::const_iterator it = categories[category].spells.begin(); it != categories[category].spells.end(); ++it) | ||||||
|  |         { | ||||||
|  |             if (it == categories[category].spells.begin()) | ||||||
|  |             { | ||||||
|  |                 text += std::string("\n#DDC79E") + std::string("#{") + categories[category].label + "}"; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             const std::string &spellId = *it; | ||||||
|  | 
 | ||||||
|  |             const ESM::Spell *spell = MWBase::Environment::get().getWorld()->getStore().spells.search(spellId); | ||||||
|  |             text += "\n#BF9959" + spell->name; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     widget->setUserString("Caption_BirthSignText", text); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void ToolTips::createRaceToolTip(MyGUI::Widget* widget, const ESM::Race* playerRace) | ||||||
|  | { | ||||||
|  |     widget->setUserString("Caption_CenteredCaption", playerRace->name); | ||||||
|  |     widget->setUserString("Caption_CenteredCaptionText", playerRace->description); | ||||||
|  |     widget->setUserString("ToolTipType", "Layout"); | ||||||
|  |     widget->setUserString("ToolTipLayout", "TextWithCenteredCaptionToolTip"); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void ToolTips::createClassToolTip(MyGUI::Widget* widget, const ESM::Class& playerClass) | ||||||
|  | { | ||||||
|  |     if (playerClass.name == "") | ||||||
|  |         return; | ||||||
|  | 
 | ||||||
|  |     int spec = playerClass.data.specialization; | ||||||
|  |     std::string specStr; | ||||||
|  |     if (spec == 0) | ||||||
|  |         specStr = "#{sSpecializationCombat}"; | ||||||
|  |     else if (spec == 1) | ||||||
|  |         specStr = "#{sSpecializationMagic}"; | ||||||
|  |     else if (spec == 2) | ||||||
|  |         specStr = "#{sSpecializationStealth}"; | ||||||
|  | 
 | ||||||
|  |     widget->setUserString("Caption_ClassName", playerClass.name); | ||||||
|  |     widget->setUserString("Caption_ClassDescription", playerClass.description); | ||||||
|  |     widget->setUserString("Caption_ClassSpecialisation", "#{sSpecialization}: " + specStr); | ||||||
|  |     widget->setUserString("ToolTipType", "Layout"); | ||||||
|  |     widget->setUserString("ToolTipLayout", "ClassToolTip"); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void ToolTips::setDelay(float delay) | ||||||
|  | { | ||||||
|  |     mDelay = delay; | ||||||
|  |     mRemainingDelay = mDelay; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ -5,6 +5,8 @@ | ||||||
| #include <openengine/gui/layout.hpp> | #include <openengine/gui/layout.hpp> | ||||||
| #include "../mwworld/ptr.hpp" | #include "../mwworld/ptr.hpp" | ||||||
| 
 | 
 | ||||||
|  | #include "widgets.hpp" | ||||||
|  | 
 | ||||||
| namespace MWGui | namespace MWGui | ||||||
| { | { | ||||||
|     class WindowManager; |     class WindowManager; | ||||||
|  | @ -13,11 +15,6 @@ namespace MWGui | ||||||
|     struct ToolTipInfo |     struct ToolTipInfo | ||||||
|     { |     { | ||||||
|     public: |     public: | ||||||
|         ToolTipInfo() : |  | ||||||
|             effects(0) |  | ||||||
|         { |  | ||||||
|         }; |  | ||||||
| 
 |  | ||||||
|         std::string caption; |         std::string caption; | ||||||
|         std::string text; |         std::string text; | ||||||
|         std::string icon; |         std::string icon; | ||||||
|  | @ -26,7 +23,7 @@ namespace MWGui | ||||||
|         std::string enchant; |         std::string enchant; | ||||||
| 
 | 
 | ||||||
|         // effects (for potions, ingredients)
 |         // effects (for potions, ingredients)
 | ||||||
|         const ESM::EffectList* effects; |         Widgets::SpellEffectList effects; | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     class ToolTips : public OEngine::GUI::Layout |     class ToolTips : public OEngine::GUI::Layout | ||||||
|  | @ -44,6 +41,8 @@ namespace MWGui | ||||||
|         void toggleFullHelp(); ///< show extra info in item tooltips (owner, script)
 |         void toggleFullHelp(); ///< show extra info in item tooltips (owner, script)
 | ||||||
|         bool getFullHelp() const; |         bool getFullHelp() const; | ||||||
| 
 | 
 | ||||||
|  |         void setDelay(float delay); | ||||||
|  | 
 | ||||||
|         void setFocusObject(const MWWorld::Ptr& focus); |         void setFocusObject(const MWWorld::Ptr& focus); | ||||||
|         void setFocusObjectScreenCoords(float min_x, float min_y, float max_x, float max_y); |         void setFocusObjectScreenCoords(float min_x, float min_y, float max_x, float max_y); | ||||||
|         ///< set the screen-space position of the tooltip for focused object 
 |         ///< set the screen-space position of the tooltip for focused object 
 | ||||||
|  | @ -60,6 +59,15 @@ namespace MWGui | ||||||
|         static std::string getCountString(const int value); |         static std::string getCountString(const int value); | ||||||
|         ///< @return blank string if count is 1, or else " (value)"
 |         ///< @return blank string if count is 1, or else " (value)"
 | ||||||
| 
 | 
 | ||||||
|  |         // these do not create an actual tooltip, but they fill in the data that is required so the tooltip
 | ||||||
|  |         // system knows what to show in case this widget is hovered
 | ||||||
|  |         static void createSkillToolTip(MyGUI::Widget* widget, int skillId); | ||||||
|  |         static void createAttributeToolTip(MyGUI::Widget* widget, int attributeId); | ||||||
|  |         static void createSpecializationToolTip(MyGUI::Widget* widget, const std::string& name, int specId); | ||||||
|  |         static void createBirthsignToolTip(MyGUI::Widget* widget, const std::string& birthsignId); | ||||||
|  |         static void createRaceToolTip(MyGUI::Widget* widget, const ESM::Race* playerRace); | ||||||
|  |         static void createClassToolTip(MyGUI::Widget* widget, const ESM::Class& playerClass); | ||||||
|  | 
 | ||||||
|     private: |     private: | ||||||
|         MyGUI::Widget* mDynamicToolTipBox; |         MyGUI::Widget* mDynamicToolTipBox; | ||||||
| 
 | 
 | ||||||
|  | @ -78,6 +86,12 @@ namespace MWGui | ||||||
|         float mFocusToolTipX; |         float mFocusToolTipX; | ||||||
|         float mFocusToolTipY; |         float mFocusToolTipY; | ||||||
| 
 | 
 | ||||||
|  |         float mDelay; | ||||||
|  |         float mRemainingDelay; // remaining time until tooltip will show
 | ||||||
|  | 
 | ||||||
|  |         int mLastMouseX; | ||||||
|  |         int mLastMouseY; | ||||||
|  | 
 | ||||||
|         bool mGameMode; |         bool mGameMode; | ||||||
| 
 | 
 | ||||||
|         bool mEnabled; |         bool mEnabled; | ||||||
|  |  | ||||||
|  | @ -104,6 +104,8 @@ namespace MWGui | ||||||
|         ContainerBase::openContainer(actor); |         ContainerBase::openContainer(actor); | ||||||
| 
 | 
 | ||||||
|         updateLabels(); |         updateLabels(); | ||||||
|  | 
 | ||||||
|  |         drawItems(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     void TradeWindow::onFilterChanged(MyGUI::Widget* _sender) |     void TradeWindow::onFilterChanged(MyGUI::Widget* _sender) | ||||||
|  | @ -157,9 +159,9 @@ namespace MWGui | ||||||
| 
 | 
 | ||||||
|         // check if the merchant can afford this
 |         // check if the merchant can afford this
 | ||||||
|         int merchantgold; |         int merchantgold; | ||||||
|         if (mContainer.getTypeName() == typeid(ESM::NPC).name()) |         if (mPtr.getTypeName() == typeid(ESM::NPC).name()) | ||||||
|         { |         { | ||||||
|             ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData>* ref = mContainer.get<ESM::NPC>(); |             ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData>* ref = mPtr.get<ESM::NPC>(); | ||||||
|             if (ref->base->npdt52.gold == -10) |             if (ref->base->npdt52.gold == -10) | ||||||
|                 merchantgold = ref->base->npdt12.gold; |                 merchantgold = ref->base->npdt12.gold; | ||||||
|             else |             else | ||||||
|  | @ -167,7 +169,7 @@ namespace MWGui | ||||||
|         } |         } | ||||||
|         else // ESM::Creature
 |         else // ESM::Creature
 | ||||||
|         { |         { | ||||||
|             ESMS::LiveCellRef<ESM::Creature, MWWorld::RefData>* ref = mContainer.get<ESM::Creature>(); |             ESMS::LiveCellRef<ESM::Creature, MWWorld::RefData>* ref = mPtr.get<ESM::Creature>(); | ||||||
|             merchantgold = ref->base->data.gold; |             merchantgold = ref->base->data.gold; | ||||||
|         } |         } | ||||||
|         if (mCurrentBalance > 0 && merchantgold < mCurrentBalance) |         if (mCurrentBalance > 0 && merchantgold < mCurrentBalance) | ||||||
|  | @ -210,7 +212,7 @@ namespace MWGui | ||||||
|         std::string sound = "Item Gold Up"; |         std::string sound = "Item Gold Up"; | ||||||
|         MWBase::Environment::get().getSoundManager()->playSound (sound, 1.0, 1.0); |         MWBase::Environment::get().getSoundManager()->playSound (sound, 1.0, 1.0); | ||||||
| 
 | 
 | ||||||
|         mWindowManager.setGuiMode(GM_Game); |         mWindowManager.popGuiMode(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     void TradeWindow::onCancelButtonClicked(MyGUI::Widget* _sender) |     void TradeWindow::onCancelButtonClicked(MyGUI::Widget* _sender) | ||||||
|  | @ -218,9 +220,9 @@ namespace MWGui | ||||||
|         // i give you back your stuff!
 |         // i give you back your stuff!
 | ||||||
|         returnBoughtItems(mWindowManager.getInventoryWindow()->getContainerStore()); |         returnBoughtItems(mWindowManager.getInventoryWindow()->getContainerStore()); | ||||||
|         // now gimme back my stuff!
 |         // now gimme back my stuff!
 | ||||||
|         mWindowManager.getInventoryWindow()->returnBoughtItems(MWWorld::Class::get(mContainer).getContainerStore(mContainer)); |         mWindowManager.getInventoryWindow()->returnBoughtItems(MWWorld::Class::get(mPtr).getContainerStore(mPtr)); | ||||||
| 
 | 
 | ||||||
|         mWindowManager.setGuiMode(GM_Game); |         mWindowManager.popGuiMode(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     void TradeWindow::updateLabels() |     void TradeWindow::updateLabels() | ||||||
|  | @ -240,9 +242,9 @@ namespace MWGui | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         int merchantgold; |         int merchantgold; | ||||||
|         if (mContainer.getTypeName() == typeid(ESM::NPC).name()) |         if (mPtr.getTypeName() == typeid(ESM::NPC).name()) | ||||||
|         { |         { | ||||||
|             ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData>* ref = mContainer.get<ESM::NPC>(); |             ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData>* ref = mPtr.get<ESM::NPC>(); | ||||||
|             if (ref->base->npdt52.gold == -10) |             if (ref->base->npdt52.gold == -10) | ||||||
|                 merchantgold = ref->base->npdt12.gold; |                 merchantgold = ref->base->npdt12.gold; | ||||||
|             else |             else | ||||||
|  | @ -250,7 +252,7 @@ namespace MWGui | ||||||
|         } |         } | ||||||
|         else // ESM::Creature
 |         else // ESM::Creature
 | ||||||
|         { |         { | ||||||
|             ESMS::LiveCellRef<ESM::Creature, MWWorld::RefData>* ref = mContainer.get<ESM::Creature>(); |             ESMS::LiveCellRef<ESM::Creature, MWWorld::RefData>* ref = mPtr.get<ESM::Creature>(); | ||||||
|             merchantgold = ref->base->data.gold; |             merchantgold = ref->base->data.gold; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  | @ -262,13 +264,13 @@ namespace MWGui | ||||||
|     { |     { | ||||||
|         std::vector<MWWorld::Ptr> items; |         std::vector<MWWorld::Ptr> items; | ||||||
| 
 | 
 | ||||||
|         if (mContainer.getTypeName() == typeid(ESM::Creature).name()) |         if (mPtr.getTypeName() == typeid(ESM::Creature).name()) | ||||||
|         { |         { | ||||||
|             // creatures don't have equipment slots.
 |             // creatures don't have equipment slots.
 | ||||||
|             return items; |             return items; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         MWWorld::InventoryStore& invStore = MWWorld::Class::get(mContainer).getInventoryStore(mContainer); |         MWWorld::InventoryStore& invStore = MWWorld::Class::get(mPtr).getInventoryStore(mPtr); | ||||||
| 
 | 
 | ||||||
|         for (int slot=0; slot < MWWorld::InventoryStore::Slots; ++slot) |         for (int slot=0; slot < MWWorld::InventoryStore::Slots; ++slot) | ||||||
|         { |         { | ||||||
|  | @ -285,19 +287,21 @@ namespace MWGui | ||||||
|     bool TradeWindow::npcAcceptsItem(MWWorld::Ptr item) |     bool TradeWindow::npcAcceptsItem(MWWorld::Ptr item) | ||||||
|     { |     { | ||||||
|         int services = 0; |         int services = 0; | ||||||
|         if (mContainer.getTypeName() == typeid(ESM::NPC).name()) |         if (mPtr.getTypeName() == typeid(ESM::NPC).name()) | ||||||
|         { |         { | ||||||
|             ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData>* ref = mContainer.get<ESM::NPC>(); |             ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData>* ref = mPtr.get<ESM::NPC>(); | ||||||
|             if (ref->base->hasAI) |             if (ref->base->hasAI) | ||||||
|                 services = ref->base->AI.services; |                 services = ref->base->AI.services; | ||||||
|         } |         } | ||||||
|         else if (mContainer.getTypeName() == typeid(ESM::Creature).name()) |         else if (mPtr.getTypeName() == typeid(ESM::Creature).name()) | ||||||
|         { |         { | ||||||
|             ESMS::LiveCellRef<ESM::Creature, MWWorld::RefData>* ref = mContainer.get<ESM::Creature>(); |             ESMS::LiveCellRef<ESM::Creature, MWWorld::RefData>* ref = mPtr.get<ESM::Creature>(); | ||||||
|             if (ref->base->hasAI) |             if (ref->base->hasAI) | ||||||
|                 services = ref->base->AI.services; |                 services = ref->base->AI.services; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |         /// \todo what about potions, there doesn't seem to be a flag for them??
 | ||||||
|  | 
 | ||||||
|         if      (item.getTypeName() == typeid(ESM::Weapon).name()) |         if      (item.getTypeName() == typeid(ESM::Weapon).name()) | ||||||
|             return services & ESM::NPC::Weapon; |             return services & ESM::NPC::Weapon; | ||||||
|         else if (item.getTypeName() == typeid(ESM::Armor).name()) |         else if (item.getTypeName() == typeid(ESM::Armor).name()) | ||||||
|  | @ -327,7 +331,7 @@ namespace MWGui | ||||||
|     std::vector<MWWorld::Ptr> TradeWindow::itemsToIgnore() |     std::vector<MWWorld::Ptr> TradeWindow::itemsToIgnore() | ||||||
|     { |     { | ||||||
|         std::vector<MWWorld::Ptr> items; |         std::vector<MWWorld::Ptr> items; | ||||||
|         MWWorld::ContainerStore& invStore = MWWorld::Class::get(mContainer).getContainerStore(mContainer); |         MWWorld::ContainerStore& invStore = MWWorld::Class::get(mPtr).getContainerStore(mPtr); | ||||||
| 
 | 
 | ||||||
|         for (MWWorld::ContainerStoreIterator it = invStore.begin(); |         for (MWWorld::ContainerStoreIterator it = invStore.begin(); | ||||||
|                 it != invStore.end(); ++it) |                 it != invStore.end(); ++it) | ||||||
|  | @ -356,4 +360,11 @@ namespace MWGui | ||||||
| 
 | 
 | ||||||
|         updateLabels(); |         updateLabels(); | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     void TradeWindow::onReferenceUnavailable() | ||||||
|  |     { | ||||||
|  |         // remove both Trade and Dialogue (since you always trade with the NPC/creature that you have previously talked to)
 | ||||||
|  |         mWindowManager.removeGuiMode(GM_Barter); | ||||||
|  |         mWindowManager.removeGuiMode(GM_Dialogue); | ||||||
|  |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -69,6 +69,8 @@ namespace MWGui | ||||||
|             virtual std::vector<MWWorld::Ptr> itemsToIgnore(); |             virtual std::vector<MWWorld::Ptr> itemsToIgnore(); | ||||||
| 
 | 
 | ||||||
|             void updateLabels(); |             void updateLabels(); | ||||||
|  | 
 | ||||||
|  |             virtual void onReferenceUnavailable(); | ||||||
|     }; |     }; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -234,8 +234,17 @@ void MWSpell::createEffectWidgets(std::vector<MyGUI::WidgetPtr> &effects, MyGUI: | ||||||
|     { |     { | ||||||
|         effect = creator->createWidget<MWSpellEffect>("MW_EffectImage", coord, MyGUI::Align::Default); |         effect = creator->createWidget<MWSpellEffect>("MW_EffectImage", coord, MyGUI::Align::Default); | ||||||
|         effect->setWindowManager(mWindowManager); |         effect->setWindowManager(mWindowManager); | ||||||
|         effect->setFlags(flags); |         SpellEffectParams params; | ||||||
|         effect->setSpellEffect(*it); |         params.mEffectID = it->effectID; | ||||||
|  |         params.mSkill = it->skill; | ||||||
|  |         params.mAttribute = it->attribute; | ||||||
|  |         params.mDuration = it->duration; | ||||||
|  |         params.mMagnMin = it->magnMin; | ||||||
|  |         params.mMagnMax = it->magnMax; | ||||||
|  |         params.mRange = it->range; | ||||||
|  |         params.mIsConstant = (flags & MWEffectList::EF_Constant); | ||||||
|  |         params.mNoTarget = (flags & MWEffectList::EF_NoTarget); | ||||||
|  |         effect->setSpellEffect(params); | ||||||
|         effects.push_back(effect); |         effects.push_back(effect); | ||||||
|         coord.top += effect->getHeight(); |         coord.top += effect->getHeight(); | ||||||
|         coord.width = std::max(coord.width, effect->getRequestedWidth()); |         coord.width = std::max(coord.width, effect->getRequestedWidth()); | ||||||
|  | @ -274,7 +283,7 @@ MWEffectList::MWEffectList() | ||||||
| { | { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void MWEffectList::setEffectList(const ESM::EffectList* list) | void MWEffectList::setEffectList(const SpellEffectList& list) | ||||||
| { | { | ||||||
|     mEffectList = list; |     mEffectList = list; | ||||||
|     updateWidgets(); |     updateWidgets(); | ||||||
|  | @ -283,25 +292,26 @@ void MWEffectList::setEffectList(const ESM::EffectList* list) | ||||||
| void MWEffectList::createEffectWidgets(std::vector<MyGUI::WidgetPtr> &effects, MyGUI::WidgetPtr creator, MyGUI::IntCoord &coord, bool center, int flags) | void MWEffectList::createEffectWidgets(std::vector<MyGUI::WidgetPtr> &effects, MyGUI::WidgetPtr creator, MyGUI::IntCoord &coord, bool center, int flags) | ||||||
| { | { | ||||||
|     // We don't know the width of all the elements beforehand, so we do it in
 |     // We don't know the width of all the elements beforehand, so we do it in
 | ||||||
|     // 2 steps: first, create all widgets and check their width
 |     // 2 steps: first, create all widgets and check their width....
 | ||||||
|     MWSpellEffectPtr effect = nullptr; |     MWSpellEffectPtr effect = nullptr; | ||||||
|     std::vector<ESM::ENAMstruct>::const_iterator end = mEffectList->list.end(); |  | ||||||
|     int maxwidth = coord.width; |     int maxwidth = coord.width; | ||||||
|     for (std::vector<ESM::ENAMstruct>::const_iterator it = mEffectList->list.begin(); it != end; ++it) | 
 | ||||||
|  |     for (SpellEffectList::iterator it=mEffectList.begin(); | ||||||
|  |         it != mEffectList.end(); ++it) | ||||||
|     { |     { | ||||||
|         effect = creator->createWidget<MWSpellEffect>("MW_EffectImage", coord, MyGUI::Align::Default); |         effect = creator->createWidget<MWSpellEffect>("MW_EffectImage", coord, MyGUI::Align::Default); | ||||||
|         effect->setWindowManager(mWindowManager); |         effect->setWindowManager(mWindowManager); | ||||||
|         effect->setFlags(flags); |         it->mIsConstant = (flags & EF_Constant) || it->mIsConstant; | ||||||
|  |         it->mNoTarget = (flags & EF_NoTarget) || it->mNoTarget; | ||||||
|         effect->setSpellEffect(*it); |         effect->setSpellEffect(*it); | ||||||
|         effects.push_back(effect); |         effects.push_back(effect); | ||||||
| 
 |  | ||||||
|         if (effect->getRequestedWidth() > maxwidth) |         if (effect->getRequestedWidth() > maxwidth) | ||||||
|             maxwidth = effect->getRequestedWidth(); |             maxwidth = effect->getRequestedWidth(); | ||||||
| 
 | 
 | ||||||
|         coord.top += effect->getHeight(); |         coord.top += effect->getHeight(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // then adjust the size for all widgets
 |     // ... then adjust the size for all widgets
 | ||||||
|     for (std::vector<MyGUI::WidgetPtr>::iterator it = effects.begin(); it != effects.end(); ++it) |     for (std::vector<MyGUI::WidgetPtr>::iterator it = effects.begin(); it != effects.end(); ++it) | ||||||
|     { |     { | ||||||
|         effect = static_cast<MWSpellEffectPtr>(*it); |         effect = static_cast<MWSpellEffectPtr>(*it); | ||||||
|  | @ -334,6 +344,25 @@ MWEffectList::~MWEffectList() | ||||||
| { | { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | SpellEffectList MWEffectList::effectListFromESM(const ESM::EffectList* effects) | ||||||
|  | { | ||||||
|  |     SpellEffectList result; | ||||||
|  |     std::vector<ESM::ENAMstruct>::const_iterator end = effects->list.end(); | ||||||
|  |     for (std::vector<ESM::ENAMstruct>::const_iterator it = effects->list.begin(); it != end; ++it) | ||||||
|  |     { | ||||||
|  |         SpellEffectParams params; | ||||||
|  |         params.mEffectID = it->effectID; | ||||||
|  |         params.mSkill = it->skill; | ||||||
|  |         params.mAttribute = it->attribute; | ||||||
|  |         params.mDuration = it->duration; | ||||||
|  |         params.mMagnMin = it->magnMin; | ||||||
|  |         params.mMagnMax = it->magnMax; | ||||||
|  |         params.mRange = it->range; | ||||||
|  |         result.push_back(params); | ||||||
|  |     } | ||||||
|  |     return result; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| /* MWSpellEffect */ | /* MWSpellEffect */ | ||||||
| 
 | 
 | ||||||
| MWSpellEffect::MWSpellEffect() | MWSpellEffect::MWSpellEffect() | ||||||
|  | @ -341,13 +370,12 @@ MWSpellEffect::MWSpellEffect() | ||||||
|     , imageWidget(nullptr) |     , imageWidget(nullptr) | ||||||
|     , textWidget(nullptr) |     , textWidget(nullptr) | ||||||
|     , mRequestedWidth(0) |     , mRequestedWidth(0) | ||||||
|     , mFlags(0) |  | ||||||
| { | { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void MWSpellEffect::setSpellEffect(SpellEffectValue value) | void MWSpellEffect::setSpellEffect(const SpellEffectParams& params) | ||||||
| { | { | ||||||
|     effect = value; |     mEffectParams = params; | ||||||
|     updateWidgets(); |     updateWidgets(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -357,74 +385,71 @@ void MWSpellEffect::updateWidgets() | ||||||
|         return; |         return; | ||||||
| 
 | 
 | ||||||
|     const ESMS::ESMStore &store = mWindowManager->getStore(); |     const ESMS::ESMStore &store = mWindowManager->getStore(); | ||||||
|     const ESM::MagicEffect *magicEffect = store.magicEffects.search(effect.effectID); |     const ESM::MagicEffect *magicEffect = store.magicEffects.search(mEffectParams.mEffectID); | ||||||
|  |     if (!magicEffect) | ||||||
|  |         return; | ||||||
|     if (textWidget) |     if (textWidget) | ||||||
|     { |     { | ||||||
|         if (magicEffect) |         std::string pt =  mWindowManager->getGameSettingString("spoint", ""); | ||||||
|  |         std::string pts =  mWindowManager->getGameSettingString("spoints", ""); | ||||||
|  |         std::string to =  " " + mWindowManager->getGameSettingString("sTo", "") + " "; | ||||||
|  |         std::string sec =  " " + mWindowManager->getGameSettingString("ssecond", ""); | ||||||
|  |         std::string secs =  " " + mWindowManager->getGameSettingString("sseconds", ""); | ||||||
|  | 
 | ||||||
|  |         std::string effectIDStr = effectIDToString(mEffectParams.mEffectID); | ||||||
|  |         std::string spellLine = mWindowManager->getGameSettingString(effectIDStr, ""); | ||||||
|  |         if (effectInvolvesSkill(effectIDStr) && mEffectParams.mSkill >= 0 && mEffectParams.mSkill < ESM::Skill::Length) | ||||||
|         { |         { | ||||||
|             std::string pt =  mWindowManager->getGameSettingString("spoint", ""); |             spellLine += " " + mWindowManager->getGameSettingString(ESM::Skill::sSkillNameIds[mEffectParams.mSkill], ""); | ||||||
|             std::string pts =  mWindowManager->getGameSettingString("spoints", ""); |  | ||||||
|             std::string to =  " " + mWindowManager->getGameSettingString("sTo", "") + " "; |  | ||||||
|             std::string sec =  " " + mWindowManager->getGameSettingString("ssecond", ""); |  | ||||||
|             std::string secs =  " " + mWindowManager->getGameSettingString("sseconds", ""); |  | ||||||
| 
 |  | ||||||
|             std::string effectIDStr = effectIDToString(effect.effectID); |  | ||||||
|             std::string spellLine = mWindowManager->getGameSettingString(effectIDStr, ""); |  | ||||||
|             if (effect.skill >= 0 && effect.skill < ESM::Skill::Length) |  | ||||||
|             { |  | ||||||
|                 spellLine += " " + mWindowManager->getGameSettingString(ESM::Skill::sSkillNameIds[effect.skill], ""); |  | ||||||
|             } |  | ||||||
|             if (effect.attribute >= 0 && effect.attribute < 8) |  | ||||||
|             { |  | ||||||
|                 static const char *attributes[8] = { |  | ||||||
|                     "sAttributeStrength", |  | ||||||
|                     "sAttributeIntelligence", |  | ||||||
|                     "sAttributeWillpower", |  | ||||||
|                     "sAttributeAgility", |  | ||||||
|                     "sAttributeSpeed", |  | ||||||
|                     "sAttributeEndurance", |  | ||||||
|                     "sAttributePersonality", |  | ||||||
|                     "sAttributeLuck" |  | ||||||
|                 }; |  | ||||||
|                 spellLine += " " + mWindowManager->getGameSettingString(attributes[effect.attribute], ""); |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             if ((effect.magnMin >= 0 || effect.magnMax >= 0) && effectHasMagnitude(effectIDStr)) |  | ||||||
|             { |  | ||||||
|                 if (effect.magnMin == effect.magnMax) |  | ||||||
|                     spellLine += " " + boost::lexical_cast<std::string>(effect.magnMin) + " " + ((effect.magnMin == 1) ? pt : pts); |  | ||||||
|                 else |  | ||||||
|                 { |  | ||||||
|                     spellLine += " " + boost::lexical_cast<std::string>(effect.magnMin) + to + boost::lexical_cast<std::string>(effect.magnMax) + " " + pts; |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             // constant effects have no duration and no target
 |  | ||||||
|             if (!(mFlags & MWEffectList::EF_Constant)) |  | ||||||
|             { |  | ||||||
|                 if (effect.duration >= 0 && effectHasDuration(effectIDStr)) |  | ||||||
|                 { |  | ||||||
|                     spellLine += " " + mWindowManager->getGameSettingString("sfor", "") + " " + boost::lexical_cast<std::string>(effect.duration) + ((effect.duration == 1) ? sec : secs); |  | ||||||
|                 } |  | ||||||
| 
 |  | ||||||
|                 // potions have no target
 |  | ||||||
|                 if (!(mFlags & MWEffectList::EF_Potion)) |  | ||||||
|                 { |  | ||||||
|                     std::string on = mWindowManager->getGameSettingString("sonword", ""); |  | ||||||
|                     if (effect.range == ESM::RT_Self) |  | ||||||
|                         spellLine += " " + on + " " + mWindowManager->getGameSettingString("sRangeSelf", ""); |  | ||||||
|                     else if (effect.range == ESM::RT_Touch) |  | ||||||
|                         spellLine += " " + on + " " + mWindowManager->getGameSettingString("sRangeTouch", ""); |  | ||||||
|                     else if (effect.range == ESM::RT_Target) |  | ||||||
|                         spellLine += " " + on + " " + mWindowManager->getGameSettingString("sRangeTarget", ""); |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             static_cast<MyGUI::TextBox*>(textWidget)->setCaption(spellLine); |  | ||||||
|             mRequestedWidth = textWidget->getTextSize().width + 24; |  | ||||||
|         } |         } | ||||||
|         else |         if (effectInvolvesAttribute(effectIDStr) && mEffectParams.mAttribute >= 0 && mEffectParams.mAttribute < 8) | ||||||
|             static_cast<MyGUI::TextBox*>(textWidget)->setCaption(""); |         { | ||||||
|  |             static const char *attributes[8] = { | ||||||
|  |                 "sAttributeStrength", | ||||||
|  |                 "sAttributeIntelligence", | ||||||
|  |                 "sAttributeWillpower", | ||||||
|  |                 "sAttributeAgility", | ||||||
|  |                 "sAttributeSpeed", | ||||||
|  |                 "sAttributeEndurance", | ||||||
|  |                 "sAttributePersonality", | ||||||
|  |                 "sAttributeLuck" | ||||||
|  |             }; | ||||||
|  |             spellLine += " " + mWindowManager->getGameSettingString(attributes[mEffectParams.mAttribute], ""); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         if ((mEffectParams.mMagnMin >= 0 || mEffectParams.mMagnMax >= 0) && effectHasMagnitude(effectIDStr)) | ||||||
|  |         { | ||||||
|  |             if (mEffectParams.mMagnMin == mEffectParams.mMagnMax) | ||||||
|  |                 spellLine += " " + boost::lexical_cast<std::string>(mEffectParams.mMagnMin) + " " + ((mEffectParams.mMagnMin == 1) ? pt : pts); | ||||||
|  |             else | ||||||
|  |             { | ||||||
|  |                 spellLine += " " + boost::lexical_cast<std::string>(mEffectParams.mMagnMin) + to + boost::lexical_cast<std::string>(mEffectParams.mMagnMax) + " " + pts; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         // constant effects have no duration and no target
 | ||||||
|  |         if (!mEffectParams.mIsConstant) | ||||||
|  |         { | ||||||
|  |             if (mEffectParams.mDuration >= 0 && effectHasDuration(effectIDStr)) | ||||||
|  |             { | ||||||
|  |                 spellLine += " " + mWindowManager->getGameSettingString("sfor", "") + " " + boost::lexical_cast<std::string>(mEffectParams.mDuration) + ((mEffectParams.mDuration == 1) ? sec : secs); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             // potions have no target
 | ||||||
|  |             if (!mEffectParams.mNoTarget) | ||||||
|  |             { | ||||||
|  |                 std::string on = mWindowManager->getGameSettingString("sonword", ""); | ||||||
|  |                 if (mEffectParams.mRange == ESM::RT_Self) | ||||||
|  |                     spellLine += " " + on + " " + mWindowManager->getGameSettingString("sRangeSelf", ""); | ||||||
|  |                 else if (mEffectParams.mRange == ESM::RT_Touch) | ||||||
|  |                     spellLine += " " + on + " " + mWindowManager->getGameSettingString("sRangeTouch", ""); | ||||||
|  |                 else if (mEffectParams.mRange == ESM::RT_Target) | ||||||
|  |                     spellLine += " " + on + " " + mWindowManager->getGameSettingString("sRangeTarget", ""); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         static_cast<MyGUI::TextBox*>(textWidget)->setCaption(spellLine); | ||||||
|  |         mRequestedWidth = textWidget->getTextSize().width + 24; | ||||||
|     } |     } | ||||||
|     if (imageWidget) |     if (imageWidget) | ||||||
|     { |     { | ||||||
|  | @ -677,6 +702,24 @@ bool MWSpellEffect::effectHasMagnitude(const std::string& effect) | ||||||
|     return (std::find(effectsWithoutMagnitude.begin(), effectsWithoutMagnitude.end(), effect) == effectsWithoutMagnitude.end()); |     return (std::find(effectsWithoutMagnitude.begin(), effectsWithoutMagnitude.end(), effect) == effectsWithoutMagnitude.end()); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | bool MWSpellEffect::effectInvolvesAttribute (const std::string& effect) | ||||||
|  | { | ||||||
|  |     return (effect == "sEffectRestoreAttribute" | ||||||
|  |         || effect == "sEffectAbsorbAttribute" | ||||||
|  |         || effect == "sEffectDrainAttribute" | ||||||
|  |         || effect == "sEffectFortifyAttribute" | ||||||
|  |         || effect == "sEffectDamageAttribute"); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | bool MWSpellEffect::effectInvolvesSkill (const std::string& effect) | ||||||
|  | { | ||||||
|  |     return (effect == "sEffectRestoreSkill" | ||||||
|  |         || effect == "sEffectAbsorbSkill" | ||||||
|  |         || effect == "sEffectDrainSkill" | ||||||
|  |         || effect == "sEffectFortifySkill" | ||||||
|  |         || effect == "sEffectDamageSkill"); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| MWSpellEffect::~MWSpellEffect() | MWSpellEffect::~MWSpellEffect() | ||||||
| { | { | ||||||
| } | } | ||||||
|  | @ -724,7 +767,7 @@ void MWDynamicStat::setValue(int cur, int max_) | ||||||
|             static_cast<MyGUI::TextBox*>(barTextWidget)->setCaption(""); |             static_cast<MyGUI::TextBox*>(barTextWidget)->setCaption(""); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| void MWDynamicStat::setTitle(const std::string text) | void MWDynamicStat::setTitle(const std::string& text) | ||||||
| { | { | ||||||
|     if (textWidget) |     if (textWidget) | ||||||
|         static_cast<MyGUI::TextBox*>(textWidget)->setCaption(text); |         static_cast<MyGUI::TextBox*>(textWidget)->setCaption(text); | ||||||
|  |  | ||||||
|  | @ -21,8 +21,58 @@ namespace MWGui | ||||||
| 
 | 
 | ||||||
|     namespace Widgets |     namespace Widgets | ||||||
|     { |     { | ||||||
|  |         class MWEffectList; | ||||||
|  | 
 | ||||||
|         void fixTexturePath(std::string &path); |         void fixTexturePath(std::string &path); | ||||||
| 
 | 
 | ||||||
|  |         struct SpellEffectParams | ||||||
|  |         { | ||||||
|  |             SpellEffectParams() | ||||||
|  |                 : mMagnMin(-1) | ||||||
|  |                 , mMagnMax(-1) | ||||||
|  |                 , mRange(-1) | ||||||
|  |                 , mDuration(-1) | ||||||
|  |                 , mSkill(-1) | ||||||
|  |                 , mAttribute(-1) | ||||||
|  |                 , mEffectID(-1) | ||||||
|  |                 , mNoTarget(false) | ||||||
|  |                 , mIsConstant(false) | ||||||
|  |             { | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             bool mNoTarget; // potion effects for example have no target (target is always the player)
 | ||||||
|  |             bool mIsConstant; // constant effect means that duration will not be displayed
 | ||||||
|  | 
 | ||||||
|  |             // value of -1 here means the effect is unknown to the player
 | ||||||
|  |             short mEffectID; | ||||||
|  | 
 | ||||||
|  |             // value of -1 here means there is no skill/attribute
 | ||||||
|  |             signed char mSkill, mAttribute; | ||||||
|  | 
 | ||||||
|  |             // value of -1 here means the value is unavailable
 | ||||||
|  |             int mMagnMin, mMagnMax, mRange, mDuration; | ||||||
|  | 
 | ||||||
|  |             bool operator==(const SpellEffectParams& other) const | ||||||
|  |             { | ||||||
|  |                 if (mEffectID !=  other.mEffectID) | ||||||
|  |                     return false; | ||||||
|  | 
 | ||||||
|  |                 bool involvesAttribute = (mEffectID == 74 // restore attribute
 | ||||||
|  |                                         || mEffectID == 85 // absorb attribute
 | ||||||
|  |                                         || mEffectID == 17 // drain attribute
 | ||||||
|  |                                         || mEffectID == 79 // fortify attribute
 | ||||||
|  |                                         || mEffectID == 22); // damage attribute
 | ||||||
|  |                 bool involvesSkill = (mEffectID == 78 // restore skill
 | ||||||
|  |                                         || mEffectID == 89 // absorb skill
 | ||||||
|  |                                         || mEffectID == 21 // drain skill
 | ||||||
|  |                                         || mEffectID == 83 // fortify skill
 | ||||||
|  |                                         || mEffectID == 26); // damage skill
 | ||||||
|  |                 return ((other.mSkill == mSkill) || !involvesSkill) && ((other.mAttribute == mAttribute) && !involvesAttribute); | ||||||
|  |             } | ||||||
|  |         }; | ||||||
|  | 
 | ||||||
|  |         typedef std::vector<SpellEffectParams> SpellEffectList; | ||||||
|  | 
 | ||||||
|         class MYGUI_EXPORT MWSkill : public Widget |         class MYGUI_EXPORT MWSkill : public Widget | ||||||
|         { |         { | ||||||
|             MYGUI_RTTI_DERIVED( MWSkill ); |             MYGUI_RTTI_DERIVED( MWSkill ); | ||||||
|  | @ -108,6 +158,9 @@ namespace MWGui | ||||||
|         }; |         }; | ||||||
|         typedef MWAttribute* MWAttributePtr; |         typedef MWAttribute* MWAttributePtr; | ||||||
| 
 | 
 | ||||||
|  |         /**
 | ||||||
|  |          * @todo remove this class and use MWEffectList instead | ||||||
|  |          */ | ||||||
|         class MWSpellEffect; |         class MWSpellEffect; | ||||||
|         class MYGUI_EXPORT MWSpell : public Widget |         class MYGUI_EXPORT MWSpell : public Widget | ||||||
|         { |         { | ||||||
|  | @ -155,12 +208,14 @@ namespace MWGui | ||||||
| 
 | 
 | ||||||
|             enum EffectFlags |             enum EffectFlags | ||||||
|             { |             { | ||||||
|                 EF_Potion = 0x01, // potions have no target (target is always the player) 
 |                 EF_NoTarget = 0x01, // potions have no target (target is always the player)
 | ||||||
|                 EF_Constant = 0x02 // constant effect means that duration will not be displayed
 |                 EF_Constant = 0x02 // constant effect means that duration will not be displayed
 | ||||||
|             }; |             }; | ||||||
| 
 | 
 | ||||||
|             void setWindowManager(WindowManager* parWindowManager) { mWindowManager = parWindowManager; } |             void setWindowManager(WindowManager* parWindowManager) { mWindowManager = parWindowManager; } | ||||||
|             void setEffectList(const ESM::EffectList* list); |             void setEffectList(const SpellEffectList& list); | ||||||
|  | 
 | ||||||
|  |             static SpellEffectList effectListFromESM(const ESM::EffectList* effects); | ||||||
| 
 | 
 | ||||||
|             /**
 |             /**
 | ||||||
|              * @param vector to store the created effect widgets |              * @param vector to store the created effect widgets | ||||||
|  | @ -180,7 +235,7 @@ namespace MWGui | ||||||
|             void updateWidgets(); |             void updateWidgets(); | ||||||
| 
 | 
 | ||||||
|             WindowManager* mWindowManager; |             WindowManager* mWindowManager; | ||||||
|             const ESM::EffectList* mEffectList; |             SpellEffectList mEffectList; | ||||||
|         }; |         }; | ||||||
|         typedef MWEffectList* MWEffectListPtr; |         typedef MWEffectList* MWEffectListPtr; | ||||||
| 
 | 
 | ||||||
|  | @ -193,14 +248,13 @@ namespace MWGui | ||||||
|             typedef ESM::ENAMstruct SpellEffectValue; |             typedef ESM::ENAMstruct SpellEffectValue; | ||||||
| 
 | 
 | ||||||
|             void setWindowManager(WindowManager* parWindowManager) { mWindowManager = parWindowManager; } |             void setWindowManager(WindowManager* parWindowManager) { mWindowManager = parWindowManager; } | ||||||
|             void setSpellEffect(SpellEffectValue value); |             void setSpellEffect(const SpellEffectParams& params); | ||||||
|             void setFlags(int flags) { mFlags = flags; } |  | ||||||
| 
 | 
 | ||||||
|             std::string effectIDToString(const short effectID); |             std::string effectIDToString(const short effectID); | ||||||
|             bool effectHasMagnitude (const std::string& effect); |             bool effectHasMagnitude (const std::string& effect); | ||||||
|             bool effectHasDuration (const std::string& effect); |             bool effectHasDuration (const std::string& effect); | ||||||
| 
 |             bool effectInvolvesAttribute (const std::string& effect); | ||||||
|             const SpellEffectValue &getSpellEffect() const { return effect; } |             bool effectInvolvesSkill (const std::string& effect); | ||||||
| 
 | 
 | ||||||
|             int getRequestedWidth() const { return mRequestedWidth; } |             int getRequestedWidth() const { return mRequestedWidth; } | ||||||
| 
 | 
 | ||||||
|  | @ -214,8 +268,7 @@ namespace MWGui | ||||||
|             void updateWidgets(); |             void updateWidgets(); | ||||||
| 
 | 
 | ||||||
|             WindowManager* mWindowManager; |             WindowManager* mWindowManager; | ||||||
|             SpellEffectValue effect; |             SpellEffectParams mEffectParams; | ||||||
|             int mFlags; |  | ||||||
|             MyGUI::ImageBox* imageWidget; |             MyGUI::ImageBox* imageWidget; | ||||||
|             MyGUI::TextBox* textWidget; |             MyGUI::TextBox* textWidget; | ||||||
|             int mRequestedWidth; |             int mRequestedWidth; | ||||||
|  | @ -229,7 +282,7 @@ namespace MWGui | ||||||
|             MWDynamicStat(); |             MWDynamicStat(); | ||||||
| 
 | 
 | ||||||
|             void setValue(int value, int max); |             void setValue(int value, int max); | ||||||
|             void setTitle(const std::string text); |             void setTitle(const std::string& text); | ||||||
| 
 | 
 | ||||||
|             int getValue() const { return value; } |             int getValue() const { return value; } | ||||||
|             int getMax() const { return max; } |             int getMax() const { return max; } | ||||||
|  | @ -247,7 +300,6 @@ namespace MWGui | ||||||
|             MyGUI::TextBox* barTextWidget; |             MyGUI::TextBox* barTextWidget; | ||||||
|         }; |         }; | ||||||
|         typedef MWDynamicStat* MWDynamicStatPtr; |         typedef MWDynamicStat* MWDynamicStatPtr; | ||||||
| 
 |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,6 +1,8 @@ | ||||||
| #include "window_base.hpp" | #include "window_base.hpp" | ||||||
| #include "window_manager.hpp" | #include "window_manager.hpp" | ||||||
| 
 | 
 | ||||||
|  | #include <components/settings/settings.hpp> | ||||||
|  | 
 | ||||||
| using namespace MWGui; | using namespace MWGui; | ||||||
| 
 | 
 | ||||||
| WindowBase::WindowBase(const std::string& parLayout, WindowManager& parWindowManager) | WindowBase::WindowBase(const std::string& parLayout, WindowManager& parWindowManager) | ||||||
|  | @ -13,10 +15,25 @@ void WindowBase::open() | ||||||
| { | { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void WindowBase::setVisible(bool visible) | ||||||
|  | { | ||||||
|  |     bool wasVisible = mMainWidget->getVisible(); | ||||||
|  |     mMainWidget->setVisible(visible); | ||||||
|  | 
 | ||||||
|  |     if (!wasVisible && visible) | ||||||
|  |         open(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void WindowBase::center() | void WindowBase::center() | ||||||
| { | { | ||||||
|     // Centre dialog
 |     // Centre dialog
 | ||||||
|     MyGUI::IntSize gameWindowSize = MyGUI::RenderManager::getInstance().getViewSize(); | 
 | ||||||
|  |     // MyGUI::IntSize gameWindowSize = MyGUI::RenderManager::getInstance().getViewSize();
 | ||||||
|  |     // Note by scrawl: The following works more reliably in the case when the window was _just_
 | ||||||
|  |     // resized and MyGUI RenderManager doesn't know about the new size yet
 | ||||||
|  |     MyGUI::IntSize gameWindowSize = MyGUI::IntSize(Settings::Manager::getInt("resolution x", "Video"), | ||||||
|  |             Settings::Manager::getInt("resolution y", "Video")); | ||||||
|  | 
 | ||||||
|     MyGUI::IntCoord coord = mMainWidget->getCoord(); |     MyGUI::IntCoord coord = mMainWidget->getCoord(); | ||||||
|     coord.left = (gameWindowSize.width - coord.width)/2; |     coord.left = (gameWindowSize.width - coord.width)/2; | ||||||
|     coord.top = (gameWindowSize.height - coord.height)/2; |     coord.top = (gameWindowSize.height - coord.height)/2; | ||||||
|  |  | ||||||
|  | @ -16,6 +16,7 @@ namespace MWGui | ||||||
|         typedef MyGUI::delegates::CMultiDelegate1<WindowBase*> EventHandle_WindowBase; |         typedef MyGUI::delegates::CMultiDelegate1<WindowBase*> EventHandle_WindowBase; | ||||||
| 
 | 
 | ||||||
|         virtual void open(); |         virtual void open(); | ||||||
|  |         virtual void setVisible(bool visible); // calls open() if visible is true and was false before
 | ||||||
|         void center(); |         void center(); | ||||||
| 
 | 
 | ||||||
|         /** Event : Dialog finished, OK button clicked.\n
 |         /** Event : Dialog finished, OK button clicked.\n
 | ||||||
|  |  | ||||||
|  | @ -16,6 +16,10 @@ | ||||||
| #include "mainmenu.hpp" | #include "mainmenu.hpp" | ||||||
| #include "countdialog.hpp" | #include "countdialog.hpp" | ||||||
| #include "tradewindow.hpp" | #include "tradewindow.hpp" | ||||||
|  | #include "settingswindow.hpp" | ||||||
|  | #include "confirmationdialog.hpp" | ||||||
|  | #include "alchemywindow.hpp" | ||||||
|  | #include "spellwindow.hpp" | ||||||
| 
 | 
 | ||||||
| #include "../mwmechanics/mechanicsmanager.hpp" | #include "../mwmechanics/mechanicsmanager.hpp" | ||||||
| #include "../mwinput/inputmanager.hpp" | #include "../mwinput/inputmanager.hpp" | ||||||
|  | @ -35,7 +39,7 @@ | ||||||
| using namespace MWGui; | using namespace MWGui; | ||||||
| 
 | 
 | ||||||
| WindowManager::WindowManager( | WindowManager::WindowManager( | ||||||
|     const Compiler::Extensions& extensions, int fpsLevel, bool newGame, OEngine::Render::OgreRenderer *mOgre, const std::string logpath) |     const Compiler::Extensions& extensions, int fpsLevel, bool newGame, OEngine::Render::OgreRenderer *mOgre, const std::string& logpath) | ||||||
|   : mGuiManager(NULL) |   : mGuiManager(NULL) | ||||||
|   , hud(NULL) |   , hud(NULL) | ||||||
|   , map(NULL) |   , map(NULL) | ||||||
|  | @ -45,11 +49,15 @@ WindowManager::WindowManager( | ||||||
|   , mMessageBoxManager(NULL) |   , mMessageBoxManager(NULL) | ||||||
|   , console(NULL) |   , console(NULL) | ||||||
|   , mJournal(NULL) |   , mJournal(NULL) | ||||||
|   , mDialogueWindow(nullptr) |   , mDialogueWindow(NULL) | ||||||
|   , mBookWindow(NULL) |   , mBookWindow(NULL) | ||||||
|   , mScrollWindow(NULL) |   , mScrollWindow(NULL) | ||||||
|   , mCountDialog(NULL) |   , mCountDialog(NULL) | ||||||
|   , mTradeWindow(NULL) |   , mTradeWindow(NULL) | ||||||
|  |   , mSettingsWindow(NULL) | ||||||
|  |   , mConfirmationDialog(NULL) | ||||||
|  |   , mAlchemyWindow(NULL) | ||||||
|  |   , mSpellWindow(NULL) | ||||||
|   , mCharGen(NULL) |   , mCharGen(NULL) | ||||||
|   , playerClass() |   , playerClass() | ||||||
|   , playerName() |   , playerName() | ||||||
|  | @ -62,9 +70,6 @@ WindowManager::WindowManager( | ||||||
|   , playerMagicka() |   , playerMagicka() | ||||||
|   , playerFatigue() |   , playerFatigue() | ||||||
|   , gui(NULL) |   , gui(NULL) | ||||||
|   , mode(GM_Game) |  | ||||||
|   , nextMode(GM_Game) |  | ||||||
|   , needModeChange(false) |  | ||||||
|   , garbageDialogs() |   , garbageDialogs() | ||||||
|   , shown(GW_ALL) |   , shown(GW_ALL) | ||||||
|   , allowed(newGame ? GW_None : GW_ALL) |   , allowed(newGame ? GW_None : GW_ALL) | ||||||
|  | @ -118,6 +123,10 @@ WindowManager::WindowManager( | ||||||
|     mScrollWindow = new ScrollWindow(*this); |     mScrollWindow = new ScrollWindow(*this); | ||||||
|     mBookWindow = new BookWindow(*this); |     mBookWindow = new BookWindow(*this); | ||||||
|     mCountDialog = new CountDialog(*this); |     mCountDialog = new CountDialog(*this); | ||||||
|  |     mSettingsWindow = new SettingsWindow(*this); | ||||||
|  |     mConfirmationDialog = new ConfirmationDialog(*this); | ||||||
|  |     mAlchemyWindow = new AlchemyWindow(*this); | ||||||
|  |     mSpellWindow = new SpellWindow(*this); | ||||||
| 
 | 
 | ||||||
|     // The HUD is always on
 |     // The HUD is always on
 | ||||||
|     hud->setVisible(true); |     hud->setVisible(true); | ||||||
|  | @ -135,6 +144,9 @@ WindowManager::WindowManager( | ||||||
|         playerSkillValues.insert(std::make_pair(ESM::Skill::skillIds[i], MWMechanics::Stat<float>())); |         playerSkillValues.insert(std::make_pair(ESM::Skill::skillIds[i], MWMechanics::Stat<float>())); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     unsetSelectedSpell(); | ||||||
|  |     unsetSelectedWeapon(); | ||||||
|  | 
 | ||||||
|     // Set up visibility
 |     // Set up visibility
 | ||||||
|     updateVisible(); |     updateVisible(); | ||||||
| } | } | ||||||
|  | @ -158,6 +170,10 @@ WindowManager::~WindowManager() | ||||||
|     delete mBookWindow; |     delete mBookWindow; | ||||||
|     delete mScrollWindow; |     delete mScrollWindow; | ||||||
|     delete mTradeWindow; |     delete mTradeWindow; | ||||||
|  |     delete mSettingsWindow; | ||||||
|  |     delete mConfirmationDialog; | ||||||
|  |     delete mAlchemyWindow; | ||||||
|  |     delete mSpellWindow; | ||||||
| 
 | 
 | ||||||
|     cleanupGarbage(); |     cleanupGarbage(); | ||||||
| } | } | ||||||
|  | @ -178,29 +194,10 @@ void WindowManager::cleanupGarbage() | ||||||
| void WindowManager::update() | void WindowManager::update() | ||||||
| { | { | ||||||
|     cleanupGarbage(); |     cleanupGarbage(); | ||||||
|     if (needModeChange) |  | ||||||
|     { |  | ||||||
|         needModeChange = false; |  | ||||||
|         MWBase::Environment::get().getInputManager()->setGuiMode(nextMode); |  | ||||||
|         nextMode = GM_Game; |  | ||||||
|     } |  | ||||||
|     if (showFPSLevel > 0) |  | ||||||
|     { |  | ||||||
|         hud->setFPS(mFPS); |  | ||||||
|         hud->setTriangleCount(mTriangleCount); |  | ||||||
|         hud->setBatchCount(mBatchCount); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 | 
 | ||||||
| void WindowManager::setNextMode(GuiMode newMode) |     hud->setFPS(mFPS); | ||||||
| { |     hud->setTriangleCount(mTriangleCount); | ||||||
|     nextMode = newMode; |     hud->setBatchCount(mBatchCount); | ||||||
|     needModeChange = true; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void WindowManager::setGuiMode(GuiMode newMode) |  | ||||||
| { |  | ||||||
|     MWBase::Environment::get().getInputManager()->setGuiMode(newMode); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void WindowManager::updateVisible() | void WindowManager::updateVisible() | ||||||
|  | @ -217,22 +214,38 @@ void WindowManager::updateVisible() | ||||||
|     mScrollWindow->setVisible(false); |     mScrollWindow->setVisible(false); | ||||||
|     mBookWindow->setVisible(false); |     mBookWindow->setVisible(false); | ||||||
|     mTradeWindow->setVisible(false); |     mTradeWindow->setVisible(false); | ||||||
|  |     mSettingsWindow->setVisible(false); | ||||||
|  |     mAlchemyWindow->setVisible(false); | ||||||
|  |     mSpellWindow->setVisible(false); | ||||||
| 
 | 
 | ||||||
|     // Mouse is visible whenever we're not in game mode
 |     // Mouse is visible whenever we're not in game mode
 | ||||||
|     MyGUI::PointerManager::getInstance().setVisible(isGuiMode()); |     MyGUI::PointerManager::getInstance().setVisible(isGuiMode()); | ||||||
| 
 | 
 | ||||||
|     if (mode == GM_Game) |     bool gameMode = !isGuiMode(); | ||||||
|  | 
 | ||||||
|  |     if (gameMode) | ||||||
|         mToolTips->enterGameMode(); |         mToolTips->enterGameMode(); | ||||||
|     else |     else | ||||||
|         mToolTips->enterGuiMode(); |         mToolTips->enterGuiMode(); | ||||||
| 
 | 
 | ||||||
|  |     setMinimapVisibility((allowed & GW_Map) && !map->pinned()); | ||||||
|  |     setWeaponVisibility((allowed & GW_Inventory) && !mInventoryWindow->pinned()); | ||||||
|  |     setSpellVisibility((allowed & GW_Magic) && !mSpellWindow->pinned()); | ||||||
|  |     setHMSVisibility((allowed & GW_Stats) && !mStatsWindow->pinned()); | ||||||
|  | 
 | ||||||
|  |     // If in game mode, don't show anything.
 | ||||||
|  |     if (gameMode) | ||||||
|  |         return; | ||||||
|  | 
 | ||||||
|  |     GuiMode mode = mGuiModes.back(); | ||||||
|  | 
 | ||||||
|     switch(mode) { |     switch(mode) { | ||||||
|         case GM_Game: |  | ||||||
|             // If in game mode, don't show anything.
 |  | ||||||
|             break; |  | ||||||
|         case GM_MainMenu: |         case GM_MainMenu: | ||||||
|             menu->setVisible(true); |             menu->setVisible(true); | ||||||
|             break; |             break; | ||||||
|  |         case GM_Settings: | ||||||
|  |             mSettingsWindow->setVisible(true); | ||||||
|  |             break; | ||||||
|         case GM_Console: |         case GM_Console: | ||||||
|             console->enable(); |             console->enable(); | ||||||
|             break; |             break; | ||||||
|  | @ -242,6 +255,9 @@ void WindowManager::updateVisible() | ||||||
|         case GM_Book: |         case GM_Book: | ||||||
|             mBookWindow->setVisible(true); |             mBookWindow->setVisible(true); | ||||||
|             break; |             break; | ||||||
|  |         case GM_Alchemy: | ||||||
|  |             mAlchemyWindow->setVisible(true); | ||||||
|  |             break; | ||||||
|         case GM_Name: |         case GM_Name: | ||||||
|         case GM_Race: |         case GM_Race: | ||||||
|         case GM_Class: |         case GM_Class: | ||||||
|  | @ -261,29 +277,24 @@ void WindowManager::updateVisible() | ||||||
|             int eff = shown & allowed; |             int eff = shown & allowed; | ||||||
| 
 | 
 | ||||||
|             // Show the windows we want
 |             // Show the windows we want
 | ||||||
|             map   -> setVisible( (eff & GW_Map) != 0 ); |             map   -> setVisible(eff & GW_Map); | ||||||
|             mStatsWindow -> setVisible( (eff & GW_Stats) != 0 ); |             mStatsWindow -> setVisible(eff & GW_Stats); | ||||||
|             mInventoryWindow->setVisible(true); |             mInventoryWindow->setVisible(eff & GW_Inventory); | ||||||
|             mInventoryWindow->openInventory(); |             mSpellWindow->setVisible(eff & GW_Magic); | ||||||
|             break; |             break; | ||||||
|         } |         } | ||||||
|         case GM_Container: |         case GM_Container: | ||||||
|             mContainerWindow->setVisible(true); |             mContainerWindow->setVisible(true); | ||||||
|             mInventoryWindow->setVisible(true); |             mInventoryWindow->setVisible(true); | ||||||
|             mInventoryWindow->openInventory(); |  | ||||||
|             break; |             break; | ||||||
|         case GM_Dialogue: |         case GM_Dialogue: | ||||||
|             mDialogueWindow->open(); |             mDialogueWindow->setVisible(true); | ||||||
|             break; |             break; | ||||||
|         case GM_Barter: |         case GM_Barter: | ||||||
|             mInventoryWindow->setVisible(true); |             mInventoryWindow->setVisible(true); | ||||||
|             mInventoryWindow->openInventory(); |  | ||||||
|             mTradeWindow->setVisible(true); |             mTradeWindow->setVisible(true); | ||||||
|             break; |             break; | ||||||
|         case GM_InterMessageBox: |         case GM_InterMessageBox: | ||||||
|             if(!mMessageBoxManager->isInteractiveMessageBox()) { |  | ||||||
|                 setGuiMode(GM_Game); |  | ||||||
|             } |  | ||||||
|             break; |             break; | ||||||
|         case GM_Journal: |         case GM_Journal: | ||||||
|             mJournal->setVisible(true); |             mJournal->setVisible(true); | ||||||
|  | @ -291,9 +302,6 @@ void WindowManager::updateVisible() | ||||||
|             break; |             break; | ||||||
|         default: |         default: | ||||||
|             // Unsupported mode, switch back to game
 |             // Unsupported mode, switch back to game
 | ||||||
|             // Note: The call will eventually end up this method again but
 |  | ||||||
|             // will stop at the check if mode is GM_Game.
 |  | ||||||
|             setGuiMode(GM_Game); |  | ||||||
|             break; |             break; | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | @ -301,6 +309,7 @@ void WindowManager::updateVisible() | ||||||
| void WindowManager::setValue (const std::string& id, const MWMechanics::Stat<int>& value) | void WindowManager::setValue (const std::string& id, const MWMechanics::Stat<int>& value) | ||||||
| { | { | ||||||
|     mStatsWindow->setValue (id, value); |     mStatsWindow->setValue (id, value); | ||||||
|  |     mCharGen->setValue(id, value); | ||||||
| 
 | 
 | ||||||
|     static const char *ids[] = |     static const char *ids[] = | ||||||
|     { |     { | ||||||
|  | @ -331,6 +340,7 @@ void WindowManager::setValue (const std::string& id, const MWMechanics::Stat<int | ||||||
| void WindowManager::setValue(const ESM::Skill::SkillEnum parSkill, const MWMechanics::Stat<float>& value) | void WindowManager::setValue(const ESM::Skill::SkillEnum parSkill, const MWMechanics::Stat<float>& value) | ||||||
| { | { | ||||||
|     mStatsWindow->setValue(parSkill, value); |     mStatsWindow->setValue(parSkill, value); | ||||||
|  |     mCharGen->setValue(parSkill, value); | ||||||
|     playerSkillValues[parSkill] = value; |     playerSkillValues[parSkill] = value; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -338,6 +348,7 @@ void WindowManager::setValue (const std::string& id, const MWMechanics::DynamicS | ||||||
| { | { | ||||||
|     mStatsWindow->setValue (id, value); |     mStatsWindow->setValue (id, value); | ||||||
|     hud->setValue (id, value); |     hud->setValue (id, value); | ||||||
|  |     mCharGen->setValue(id, value); | ||||||
|     if (id == "HBar") |     if (id == "HBar") | ||||||
|     { |     { | ||||||
|         playerHealth = value; |         playerHealth = value; | ||||||
|  | @ -390,6 +401,7 @@ void WindowManager::setPlayerClass (const ESM::Class &class_) | ||||||
| void WindowManager::configureSkills (const SkillList& major, const SkillList& minor) | void WindowManager::configureSkills (const SkillList& major, const SkillList& minor) | ||||||
| { | { | ||||||
|     mStatsWindow->configureSkills (major, minor); |     mStatsWindow->configureSkills (major, minor); | ||||||
|  |     mCharGen->configureSkills(major, minor); | ||||||
|     playerMajorSkills = major; |     playerMajorSkills = major; | ||||||
|     playerMinorSkills = minor; |     playerMinorSkills = minor; | ||||||
| } | } | ||||||
|  | @ -427,7 +439,7 @@ void WindowManager::messageBox (const std::string& message, const std::vector<st | ||||||
|     else |     else | ||||||
|     { |     { | ||||||
|         mMessageBoxManager->createInteractiveMessageBox(message, buttons); |         mMessageBoxManager->createInteractiveMessageBox(message, buttons); | ||||||
|         setGuiMode(GM_InterMessageBox); |         pushGuiMode(GM_InterMessageBox); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -452,7 +464,7 @@ void WindowManager::onDialogueWindowBye() | ||||||
|         //removeDialog(dialogueWindow);
 |         //removeDialog(dialogueWindow);
 | ||||||
|         mDialogueWindow->setVisible(false); |         mDialogueWindow->setVisible(false); | ||||||
|     } |     } | ||||||
|     setGuiMode(GM_Game); |     popGuiMode(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void WindowManager::onFrame (float frameDuration) | void WindowManager::onFrame (float frameDuration) | ||||||
|  | @ -469,6 +481,13 @@ void WindowManager::onFrame (float frameDuration) | ||||||
|     mInventoryWindow->onFrame(); |     mInventoryWindow->onFrame(); | ||||||
| 
 | 
 | ||||||
|     mStatsWindow->onFrame(); |     mStatsWindow->onFrame(); | ||||||
|  | 
 | ||||||
|  |     hud->onFrame(frameDuration); | ||||||
|  | 
 | ||||||
|  |     mDialogueWindow->checkReferenceAvailable(); | ||||||
|  |     mTradeWindow->checkReferenceAvailable(); | ||||||
|  |     mContainerWindow->checkReferenceAvailable(); | ||||||
|  |     console->checkReferenceAvailable(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| const ESMS::ESMStore& WindowManager::getStore() const | const ESMS::ESMStore& WindowManager::getStore() const | ||||||
|  | @ -493,6 +512,7 @@ void WindowManager::changeCell(MWWorld::Ptr::CellStore* cell) | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         map->setCellName( name ); |         map->setCellName( name ); | ||||||
|  |         hud->setCellName( name ); | ||||||
| 
 | 
 | ||||||
|         map->setCellPrefix("Cell"); |         map->setCellPrefix("Cell"); | ||||||
|         hud->setCellPrefix("Cell"); |         hud->setCellPrefix("Cell"); | ||||||
|  | @ -502,6 +522,7 @@ void WindowManager::changeCell(MWWorld::Ptr::CellStore* cell) | ||||||
|     else |     else | ||||||
|     { |     { | ||||||
|         map->setCellName( cell->cell->name ); |         map->setCellName( cell->cell->name ); | ||||||
|  |         hud->setCellName( cell->cell->name ); | ||||||
|         map->setCellPrefix( cell->cell->name ); |         map->setCellPrefix( cell->cell->name ); | ||||||
|         hud->setCellPrefix( cell->cell->name ); |         hud->setCellPrefix( cell->cell->name ); | ||||||
|     } |     } | ||||||
|  | @ -542,14 +563,6 @@ void WindowManager::toggleFogOfWar() | ||||||
|     hud->toggleFogOfWar(); |     hud->toggleFogOfWar(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int WindowManager::toggleFps() |  | ||||||
| { |  | ||||||
|     showFPSLevel = (showFPSLevel+1)%3; |  | ||||||
|     hud->setFpsLevel(showFPSLevel); |  | ||||||
|     Settings::Manager::setInt("fps", "HUD", showFPSLevel); |  | ||||||
|     return showFPSLevel; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void WindowManager::setFocusObject(const MWWorld::Ptr& focus) | void WindowManager::setFocusObject(const MWWorld::Ptr& focus) | ||||||
| { | { | ||||||
|     mToolTips->setFocusObject(focus); |     mToolTips->setFocusObject(focus); | ||||||
|  | @ -572,12 +585,13 @@ bool WindowManager::getFullHelp() const | ||||||
| 
 | 
 | ||||||
| void WindowManager::setWeaponVisibility(bool visible) | void WindowManager::setWeaponVisibility(bool visible) | ||||||
| { | { | ||||||
|     hud->weapBox->setVisible(visible); |     hud->setBottomLeftVisibility(hud->health->getVisible(), visible, hud->spellBox->getVisible()); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void WindowManager::setSpellVisibility(bool visible) | void WindowManager::setSpellVisibility(bool visible) | ||||||
| { | { | ||||||
|     hud->spellBox->setVisible(visible); |     hud->setBottomLeftVisibility(hud->health->getVisible(), hud->weapBox->getVisible(), visible); | ||||||
|  |     hud->setBottomRightVisibility(visible, hud->minimapBox->getVisible()); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void WindowManager::setMouseVisible(bool visible) | void WindowManager::setMouseVisible(bool visible) | ||||||
|  | @ -596,4 +610,125 @@ void WindowManager::onRetrieveTag(const MyGUI::UString& _tag, MyGUI::UString& _r | ||||||
|     const ESM::GameSetting *setting = MWBase::Environment::get().getWorld()->getStore().gameSettings.search(_tag); |     const ESM::GameSetting *setting = MWBase::Environment::get().getWorld()->getStore().gameSettings.search(_tag); | ||||||
|     if (setting && setting->type == ESM::VT_String) |     if (setting && setting->type == ESM::VT_String) | ||||||
|         _result = setting->str; |         _result = setting->str; | ||||||
|  |     else | ||||||
|  |         _result = _tag; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void WindowManager::processChangedSettings(const Settings::CategorySettingVector& changed) | ||||||
|  | { | ||||||
|  |     hud->setFpsLevel(Settings::Manager::getInt("fps", "HUD")); | ||||||
|  |     mToolTips->setDelay(Settings::Manager::getFloat("tooltip delay", "GUI")); | ||||||
|  | 
 | ||||||
|  |     bool changeRes = false; | ||||||
|  |     for (Settings::CategorySettingVector::const_iterator it = changed.begin(); | ||||||
|  |         it != changed.end(); ++it) | ||||||
|  |     { | ||||||
|  |         if (it->first == "Video" &&  ( | ||||||
|  |             it->second == "resolution x" | ||||||
|  |             || it->second == "resolution y")) | ||||||
|  |         { | ||||||
|  |             changeRes = true; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (changeRes) | ||||||
|  |     { | ||||||
|  |         int x = Settings::Manager::getInt("resolution x", "Video"); | ||||||
|  |         int y = Settings::Manager::getInt("resolution y", "Video"); | ||||||
|  |         hud->onResChange(x, y); | ||||||
|  |         console->onResChange(x, y); | ||||||
|  |         mSettingsWindow->center(); | ||||||
|  |         mDragAndDrop->mDragAndDropWidget->setSize(MyGUI::IntSize(x, y)); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void WindowManager::pushGuiMode(GuiMode mode) | ||||||
|  | { | ||||||
|  |     if (mode==GM_Inventory && allowed==GW_None) | ||||||
|  |         return; | ||||||
|  | 
 | ||||||
|  |     mGuiModes.push_back(mode); | ||||||
|  | 
 | ||||||
|  |     bool gameMode = !isGuiMode(); | ||||||
|  |     MWBase::Environment::get().getInputManager()->changeInputMode(!gameMode); | ||||||
|  | 
 | ||||||
|  |     updateVisible(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void WindowManager::popGuiMode() | ||||||
|  | { | ||||||
|  |     if (!mGuiModes.empty()) | ||||||
|  |         mGuiModes.pop_back(); | ||||||
|  | 
 | ||||||
|  |     bool gameMode = !isGuiMode(); | ||||||
|  |     MWBase::Environment::get().getInputManager()->changeInputMode(!gameMode); | ||||||
|  | 
 | ||||||
|  |     updateVisible(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void WindowManager::removeGuiMode(GuiMode mode) | ||||||
|  | { | ||||||
|  |     std::vector<GuiMode>::iterator it = mGuiModes.begin(); | ||||||
|  |     while (it != mGuiModes.end()) | ||||||
|  |     { | ||||||
|  |         if (*it == mode) | ||||||
|  |             it = mGuiModes.erase(it); | ||||||
|  |         else | ||||||
|  |             ++it; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     updateVisible(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void WindowManager::setSelectedSpell(const std::string& spellId, int successChancePercent) | ||||||
|  | { | ||||||
|  |     hud->setSelectedSpell(spellId, successChancePercent); | ||||||
|  |     const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().spells.find(spellId); | ||||||
|  |     mSpellWindow->setTitle(spell->name); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void WindowManager::setSelectedEnchantItem(const MWWorld::Ptr& item, int chargePercent) | ||||||
|  | { | ||||||
|  |     hud->setSelectedEnchantItem(item, chargePercent); | ||||||
|  |     mSpellWindow->setTitle(MWWorld::Class::get(item).getName(item)); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void WindowManager::setSelectedWeapon(const MWWorld::Ptr& item, int durabilityPercent) | ||||||
|  | { | ||||||
|  |     hud->setSelectedWeapon(item, durabilityPercent); | ||||||
|  |     mInventoryWindow->setTitle(MWWorld::Class::get(item).getName(item)); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void WindowManager::unsetSelectedSpell() | ||||||
|  | { | ||||||
|  |     hud->unsetSelectedSpell(); | ||||||
|  |     mSpellWindow->setTitle("#{sNone}"); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void WindowManager::unsetSelectedWeapon() | ||||||
|  | { | ||||||
|  |     hud->unsetSelectedWeapon(); | ||||||
|  |     mInventoryWindow->setTitle("#{sSkillHandtohand}"); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void WindowManager::getMousePosition(int &x, int &y) | ||||||
|  | { | ||||||
|  |     const MyGUI::IntPoint& pos = MyGUI::InputManager::getInstance().getMousePosition(); | ||||||
|  |     x = pos.left; | ||||||
|  |     y = pos.top; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void WindowManager::getMousePosition(float &x, float &y) | ||||||
|  | { | ||||||
|  |     const MyGUI::IntPoint& pos = MyGUI::InputManager::getInstance().getMousePosition(); | ||||||
|  |     x = pos.left; | ||||||
|  |     y = pos.top; | ||||||
|  |     const MyGUI::IntSize& viewSize = MyGUI::RenderManager::getInstance().getViewSize(); | ||||||
|  |     x /= viewSize.width; | ||||||
|  |     y /= viewSize.height; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | bool WindowManager::getWorldMouseOver() | ||||||
|  | { | ||||||
|  |     return hud->getWorldMouseOver(); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -17,6 +17,7 @@ | ||||||
| #include "MyGUI_UString.h" | #include "MyGUI_UString.h" | ||||||
| 
 | 
 | ||||||
| #include <components/esm_store/store.hpp> | #include <components/esm_store/store.hpp> | ||||||
|  | #include <components/settings/settings.hpp> | ||||||
| #include <openengine/ogre/renderer.hpp> | #include <openengine/ogre/renderer.hpp> | ||||||
| #include <openengine/gui/manager.hpp> | #include <openengine/gui/manager.hpp> | ||||||
| 
 | 
 | ||||||
|  | @ -77,6 +78,10 @@ namespace MWGui | ||||||
|   class MessageBoxManager; |   class MessageBoxManager; | ||||||
|   class CountDialog; |   class CountDialog; | ||||||
|   class TradeWindow; |   class TradeWindow; | ||||||
|  |   class SettingsWindow; | ||||||
|  |   class ConfirmationDialog; | ||||||
|  |   class AlchemyWindow; | ||||||
|  |   class SpellWindow; | ||||||
| 
 | 
 | ||||||
|   struct ClassPoint |   struct ClassPoint | ||||||
|   { |   { | ||||||
|  | @ -93,11 +98,9 @@ namespace MWGui | ||||||
|     typedef std::vector<Faction> FactionList; |     typedef std::vector<Faction> FactionList; | ||||||
|     typedef std::vector<int> SkillList; |     typedef std::vector<int> SkillList; | ||||||
| 
 | 
 | ||||||
|     WindowManager(const Compiler::Extensions& extensions, int fpsLevel, bool newGame, OEngine::Render::OgreRenderer *mOgre, const std::string logpath); |     WindowManager(const Compiler::Extensions& extensions, int fpsLevel, bool newGame, OEngine::Render::OgreRenderer *mOgre, const std::string& logpath); | ||||||
|     virtual ~WindowManager(); |     virtual ~WindowManager(); | ||||||
| 
 | 
 | ||||||
|     void setGuiMode(GuiMode newMode); |  | ||||||
| 
 |  | ||||||
|     /**
 |     /**
 | ||||||
|      * Should be called each frame to update windows/gui elements. |      * Should be called each frame to update windows/gui elements. | ||||||
|      * This could mean updating sizes of gui elements or opening |      * This could mean updating sizes of gui elements or opening | ||||||
|  | @ -105,19 +108,24 @@ namespace MWGui | ||||||
|      */ |      */ | ||||||
|     void update(); |     void update(); | ||||||
| 
 | 
 | ||||||
|     void setMode(GuiMode newMode) |     void pushGuiMode(GuiMode mode); | ||||||
|  |     void popGuiMode(); | ||||||
|  |     void removeGuiMode(GuiMode mode); ///< can be anywhere in the stack
 | ||||||
|  | 
 | ||||||
|  |     GuiMode getMode() const | ||||||
|     { |     { | ||||||
|       if (newMode==GM_Inventory && allowed==GW_None) |         if (mGuiModes.empty()) | ||||||
|         return; |             throw std::runtime_error ("getMode() called, but there is no active mode"); | ||||||
| 
 |         return mGuiModes.back(); | ||||||
|       mode = newMode; |  | ||||||
|       updateVisible(); |  | ||||||
|     } |     } | ||||||
|     void setNextMode(GuiMode newMode); |  | ||||||
| 
 | 
 | ||||||
|     GuiMode getMode() const { return mode; } |     bool isGuiMode() const { return !mGuiModes.empty(); } | ||||||
| 
 | 
 | ||||||
|     bool isGuiMode() const { return getMode() != GM_Game; } // Everything that is not game mode is considered "gui mode"
 |     void toggleVisible(GuiWindow wnd) | ||||||
|  |     { | ||||||
|  |         shown = (shown & wnd) ? (GuiWindow) (shown & ~wnd) : (GuiWindow) (shown | wnd); | ||||||
|  |         updateVisible(); | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|     // Disallow all inventory mode windows
 |     // Disallow all inventory mode windows
 | ||||||
|     void disallowAll() |     void disallowAll() | ||||||
|  | @ -133,13 +141,21 @@ namespace MWGui | ||||||
|       updateVisible(); |       updateVisible(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     bool isAllowed(GuiWindow wnd) const | ||||||
|  |     { | ||||||
|  |         return allowed & wnd; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     MWGui::DialogueWindow* getDialogueWindow() {return mDialogueWindow;} |     MWGui::DialogueWindow* getDialogueWindow() {return mDialogueWindow;} | ||||||
|     MWGui::ContainerWindow* getContainerWindow() {return mContainerWindow;} |     MWGui::ContainerWindow* getContainerWindow() {return mContainerWindow;} | ||||||
|     MWGui::InventoryWindow* getInventoryWindow() {return mInventoryWindow;} |     MWGui::InventoryWindow* getInventoryWindow() {return mInventoryWindow;} | ||||||
|     MWGui::BookWindow* getBookWindow() {return mBookWindow;} |     MWGui::BookWindow* getBookWindow() {return mBookWindow;} | ||||||
|     MWGui::ScrollWindow* getScrollWindow() {return mScrollWindow;} |     MWGui::ScrollWindow* getScrollWindow() {return mScrollWindow;} | ||||||
|     MWGui::CountDialog* getCountDialog() {return mCountDialog;} |     MWGui::CountDialog* getCountDialog() {return mCountDialog;} | ||||||
|  |     MWGui::ConfirmationDialog* getConfirmationDialog() {return mConfirmationDialog;} | ||||||
|     MWGui::TradeWindow* getTradeWindow() {return mTradeWindow;} |     MWGui::TradeWindow* getTradeWindow() {return mTradeWindow;} | ||||||
|  |     MWGui::SpellWindow* getSpellWindow() {return mSpellWindow;} | ||||||
|  |     MWGui::Console* getConsole() {return console;} | ||||||
| 
 | 
 | ||||||
|     MyGUI::Gui* getGui() const { return gui; } |     MyGUI::Gui* getGui() const { return gui; } | ||||||
| 
 | 
 | ||||||
|  | @ -173,15 +189,15 @@ namespace MWGui | ||||||
|     void setFocusObjectScreenCoords(float min_x, float min_y, float max_x, float max_y); |     void setFocusObjectScreenCoords(float min_x, float min_y, float max_x, float max_y); | ||||||
| 
 | 
 | ||||||
|     void setMouseVisible(bool visible); |     void setMouseVisible(bool visible); | ||||||
|  |     void getMousePosition(int &x, int &y); | ||||||
|  |     void getMousePosition(float &x, float &y); | ||||||
|     void setDragDrop(bool dragDrop); |     void setDragDrop(bool dragDrop); | ||||||
|  |     bool getWorldMouseOver(); | ||||||
| 
 | 
 | ||||||
|     void toggleFogOfWar(); |     void toggleFogOfWar(); | ||||||
|     void toggleFullHelp(); ///< show extra info in item tooltips (owner, script)
 |     void toggleFullHelp(); ///< show extra info in item tooltips (owner, script)
 | ||||||
|     bool getFullHelp() const; |     bool getFullHelp() const; | ||||||
| 
 | 
 | ||||||
|     int toggleFps(); |  | ||||||
|     ///< toggle fps display @return resulting fps level
 |  | ||||||
| 
 |  | ||||||
|     void setInteriorMapTexture(const int x, const int y); |     void setInteriorMapTexture(const int x, const int y); | ||||||
|     ///< set the index of the map texture that should be used (for interiors)
 |     ///< set the index of the map texture that should be used (for interiors)
 | ||||||
| 
 | 
 | ||||||
|  | @ -192,6 +208,12 @@ namespace MWGui | ||||||
|     void setWeaponVisibility(bool visible); |     void setWeaponVisibility(bool visible); | ||||||
|     void setSpellVisibility(bool visible); |     void setSpellVisibility(bool visible); | ||||||
| 
 | 
 | ||||||
|  |     void setSelectedSpell(const std::string& spellId, int successChancePercent); | ||||||
|  |     void setSelectedEnchantItem(const MWWorld::Ptr& item, int chargePercent); | ||||||
|  |     void setSelectedWeapon(const MWWorld::Ptr& item, int durabilityPercent); | ||||||
|  |     void unsetSelectedSpell(); | ||||||
|  |     void unsetSelectedWeapon(); | ||||||
|  | 
 | ||||||
|     template<typename T> |     template<typename T> | ||||||
|     void removeDialog(T*& dialog); ///< Casts to OEngine::GUI::Layout and calls removeDialog, then resets pointer to nullptr.
 |     void removeDialog(T*& dialog); ///< Casts to OEngine::GUI::Layout and calls removeDialog, then resets pointer to nullptr.
 | ||||||
|     void removeDialog(OEngine::GUI::Layout* dialog); ///< Hides dialog and schedules dialog to be deleted.
 |     void removeDialog(OEngine::GUI::Layout* dialog); ///< Hides dialog and schedules dialog to be deleted.
 | ||||||
|  | @ -201,6 +223,11 @@ namespace MWGui | ||||||
| 
 | 
 | ||||||
|     void onFrame (float frameDuration); |     void onFrame (float frameDuration); | ||||||
| 
 | 
 | ||||||
|  |     std::map<ESM::Skill::SkillEnum, MWMechanics::Stat<float> > getPlayerSkillValues() { return playerSkillValues; } | ||||||
|  |     std::map<ESM::Attribute::AttributeID, MWMechanics::Stat<int> > getPlayerAttributeValues() { return playerAttributes; } | ||||||
|  |     SkillList getPlayerMinorSkills() { return playerMinorSkills; } | ||||||
|  |     SkillList getPlayerMajorSkills() { return playerMajorSkills; } | ||||||
|  | 
 | ||||||
|     /**
 |     /**
 | ||||||
|      * Fetches a GMST string from the store, if there is no setting with the given |      * Fetches a GMST string from the store, if there is no setting with the given | ||||||
|      * ID or it is not a string the default string is returned. |      * ID or it is not a string the default string is returned. | ||||||
|  | @ -212,6 +239,8 @@ namespace MWGui | ||||||
| 
 | 
 | ||||||
|     const ESMS::ESMStore& getStore() const; |     const ESMS::ESMStore& getStore() const; | ||||||
| 
 | 
 | ||||||
|  |     void processChangedSettings(const Settings::CategorySettingVector& changed); | ||||||
|  | 
 | ||||||
|   private: |   private: | ||||||
|     OEngine::GUI::MyGUIManager *mGuiManager; |     OEngine::GUI::MyGUIManager *mGuiManager; | ||||||
|     HUD *hud; |     HUD *hud; | ||||||
|  | @ -230,6 +259,10 @@ namespace MWGui | ||||||
|     BookWindow* mBookWindow; |     BookWindow* mBookWindow; | ||||||
|     CountDialog* mCountDialog; |     CountDialog* mCountDialog; | ||||||
|     TradeWindow* mTradeWindow; |     TradeWindow* mTradeWindow; | ||||||
|  |     SettingsWindow* mSettingsWindow; | ||||||
|  |     ConfirmationDialog* mConfirmationDialog; | ||||||
|  |     AlchemyWindow* mAlchemyWindow; | ||||||
|  |     SpellWindow* mSpellWindow; | ||||||
| 
 | 
 | ||||||
|     CharacterCreation* mCharGen; |     CharacterCreation* mCharGen; | ||||||
| 
 | 
 | ||||||
|  | @ -244,9 +277,7 @@ namespace MWGui | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|     MyGUI::Gui *gui; // Gui
 |     MyGUI::Gui *gui; // Gui
 | ||||||
|     GuiMode mode; // Current gui mode
 |     std::vector<GuiMode> mGuiModes; | ||||||
|     GuiMode nextMode; // Next mode to activate in update()
 |  | ||||||
|     bool needModeChange; //Whether a mode change is needed in update() [will use nextMode]
 |  | ||||||
| 
 | 
 | ||||||
|     std::vector<OEngine::GUI::Layout*> garbageDialogs; |     std::vector<OEngine::GUI::Layout*> garbageDialogs; | ||||||
|     void cleanupGarbage(); |     void cleanupGarbage(); | ||||||
|  | @ -257,9 +288,6 @@ namespace MWGui | ||||||
|        the start of the game, when windows are enabled one by one |        the start of the game, when windows are enabled one by one | ||||||
|        through script commands. You can manipulate this through using |        through script commands. You can manipulate this through using | ||||||
|        allow() and disableAll(). |        allow() and disableAll(). | ||||||
| 
 |  | ||||||
|        The setting should also affect visibility of certain HUD |  | ||||||
|        elements, but this is not done yet. |  | ||||||
|      */ |      */ | ||||||
|     GuiWindow allowed; |     GuiWindow allowed; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -12,6 +12,7 @@ namespace MWGui | ||||||
|     public: |     public: | ||||||
|         WindowPinnableBase(const std::string& parLayout, WindowManager& parWindowManager); |         WindowPinnableBase(const std::string& parLayout, WindowManager& parWindowManager); | ||||||
|         void setVisible(bool b); |         void setVisible(bool b); | ||||||
|  |         bool pinned() { return mPinned; } | ||||||
| 
 | 
 | ||||||
|     private: |     private: | ||||||
|         void onWindowButtonPressed(MyGUI::Window* sender, const std::string& eventName); |         void onWindowButtonPressed(MyGUI::Window* sender, const std::string& eventName); | ||||||
|  |  | ||||||
|  | @ -69,7 +69,7 @@ namespace MWInput | ||||||
|       A_ToggleWeapon, |       A_ToggleWeapon, | ||||||
|       A_ToggleSpell, |       A_ToggleSpell, | ||||||
| 
 | 
 | ||||||
|       A_ToggleFps, // Toggle FPS display (this is temporary)
 |       A_Settings, // Temporary hotkey
 | ||||||
| 
 | 
 | ||||||
|       A_LAST            // Marker for the last item
 |       A_LAST            // Marker for the last item
 | ||||||
|     }; |     }; | ||||||
|  | @ -92,12 +92,12 @@ namespace MWInput | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|    /* InputImpl Methods */ |    /* InputImpl Methods */ | ||||||
| 
 | public: | ||||||
|     void toggleFps() |     void adjustMouseRegion(int width, int height) | ||||||
|     { |     { | ||||||
|         windows.toggleFps(); |         input.adjustMouseClippingSize(width, height); | ||||||
|     } |     } | ||||||
| 
 | private: | ||||||
|     void toggleSpell() |     void toggleSpell() | ||||||
|     { |     { | ||||||
|         if (windows.isGuiMode()) return; |         if (windows.isGuiMode()) return; | ||||||
|  | @ -140,23 +140,32 @@ namespace MWInput | ||||||
|         windows.messageBox ("Screenshot saved", empty); |         windows.messageBox ("Screenshot saved", empty); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     void showSettings() | ||||||
|  |     { | ||||||
|  |         if (mDragDrop) | ||||||
|  |             return; | ||||||
|  | 
 | ||||||
|  |         if (!windows.isGuiMode() || windows.getMode() != MWGui::GM_Settings) | ||||||
|  |             windows.pushGuiMode(MWGui::GM_Settings); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     /* toggleInventory() is called when the user presses the button to toggle the inventory screen. */ |     /* toggleInventory() is called when the user presses the button to toggle the inventory screen. */ | ||||||
|     void toggleInventory() |     void toggleInventory() | ||||||
|     { |     { | ||||||
|       using namespace MWGui; |         using namespace MWGui; | ||||||
| 
 | 
 | ||||||
|       if (mDragDrop) |         if (mDragDrop) | ||||||
|         return; |             return; | ||||||
| 
 | 
 | ||||||
|       GuiMode mode = windows.getMode(); |         bool gameMode = !windows.isGuiMode(); | ||||||
| 
 | 
 | ||||||
|       // Toggle between game mode and inventory mode
 |         // Toggle between game mode and inventory mode
 | ||||||
|       if(mode == GM_Game) |         if(gameMode) | ||||||
|         setGuiMode(GM_Inventory); |             windows.pushGuiMode(GM_Inventory); | ||||||
|       else if(mode == GM_Inventory) |         else if(windows.getMode() == GM_Inventory) | ||||||
|         setGuiMode(GM_Game); |             windows.popGuiMode(); | ||||||
| 
 | 
 | ||||||
|       // .. but don't touch any other mode.
 |         // .. but don't touch any other mode.
 | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // Toggle console
 |     // Toggle console
 | ||||||
|  | @ -167,28 +176,33 @@ namespace MWInput | ||||||
|       if (mDragDrop) |       if (mDragDrop) | ||||||
|         return; |         return; | ||||||
| 
 | 
 | ||||||
|       GuiMode mode = windows.getMode(); |       bool gameMode = !windows.isGuiMode(); | ||||||
| 
 | 
 | ||||||
|       // Switch to console mode no matter what mode we are currently
 |       // Switch to console mode no matter what mode we are currently
 | ||||||
|       // in, except of course if we are already in console mode
 |       // in, except of course if we are already in console mode
 | ||||||
|       if(mode == GM_Console) |       if (!gameMode) | ||||||
|         setGuiMode(GM_Game); |       { | ||||||
|       else setGuiMode(GM_Console); |           if (windows.getMode() == GM_Console) | ||||||
|  |               windows.popGuiMode(); | ||||||
|  |           else | ||||||
|  |               windows.pushGuiMode(GM_Console); | ||||||
|  |       } | ||||||
|  |       else | ||||||
|  |           windows.pushGuiMode(GM_Console); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     void toggleJournal() |     void toggleJournal() | ||||||
|     { |     { | ||||||
|       using namespace MWGui; |         using namespace MWGui; | ||||||
| 
 | 
 | ||||||
|       GuiMode mode = windows.getMode(); |         // Toggle between game mode and journal mode
 | ||||||
|  |         bool gameMode = !windows.isGuiMode(); | ||||||
| 
 | 
 | ||||||
|       // Toggle between game mode and journal mode
 |         if(gameMode) | ||||||
|       if(mode == GM_Game) |             windows.pushGuiMode(GM_Journal); | ||||||
|         setGuiMode(GM_Journal); |         else if(windows.getMode() == GM_Journal) | ||||||
|       else if(mode == GM_Journal) |             windows.popGuiMode(); | ||||||
|         setGuiMode(GM_Game); |         // .. but don't touch any other mode.
 | ||||||
| 
 |  | ||||||
|       // .. but don't touch any other mode.
 |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     void activate() |     void activate() | ||||||
|  | @ -259,8 +273,8 @@ namespace MWInput | ||||||
|                       "Draw Weapon"); |                       "Draw Weapon"); | ||||||
|       disp->funcs.bind(A_ToggleSpell,boost::bind(&InputImpl::toggleSpell,this), |       disp->funcs.bind(A_ToggleSpell,boost::bind(&InputImpl::toggleSpell,this), | ||||||
|                       "Ready hands"); |                       "Ready hands"); | ||||||
|       disp->funcs.bind(A_ToggleFps, boost::bind(&InputImpl::toggleFps, this), |       disp->funcs.bind(A_Settings, boost::bind(&InputImpl::showSettings, this), | ||||||
|                       "Toggle FPS display"); |                       "Show settings window"); | ||||||
|       // Add the exit listener
 |       // Add the exit listener
 | ||||||
|       ogre.getRoot()->addFrameListener(&exit); |       ogre.getRoot()->addFrameListener(&exit); | ||||||
| 
 | 
 | ||||||
|  | @ -282,8 +296,7 @@ namespace MWInput | ||||||
|         lst->add(guiEvents,Event::EV_ALL); |         lst->add(guiEvents,Event::EV_ALL); | ||||||
|       } |       } | ||||||
| 
 | 
 | ||||||
|       // Start out in game mode
 |       changeInputMode(false); | ||||||
|       setGuiMode(MWGui::GM_Game); |  | ||||||
| 
 | 
 | ||||||
|       /**********************************
 |       /**********************************
 | ||||||
|         Key binding section |         Key binding section | ||||||
|  | @ -307,7 +320,7 @@ namespace MWInput | ||||||
|       disp->bind(A_ToggleWalk, KC_C); |       disp->bind(A_ToggleWalk, KC_C); | ||||||
|       disp->bind(A_ToggleWeapon,KC_F); |       disp->bind(A_ToggleWeapon,KC_F); | ||||||
|       disp->bind(A_ToggleSpell,KC_R); |       disp->bind(A_ToggleSpell,KC_R); | ||||||
|       disp->bind(A_ToggleFps, KC_F10); |       disp->bind(A_Settings, KC_F2); | ||||||
| 
 | 
 | ||||||
|       // Key bindings for polled keys
 |       // Key bindings for polled keys
 | ||||||
|       // NOTE: These keys are constantly being polled. Only add keys that must be checked each frame.
 |       // NOTE: These keys are constantly being polled. Only add keys that must be checked each frame.
 | ||||||
|  | @ -348,6 +361,7 @@ namespace MWInput | ||||||
|         windows.update(); |         windows.update(); | ||||||
| 
 | 
 | ||||||
|         // Disable movement in Gui mode
 |         // Disable movement in Gui mode
 | ||||||
|  | 
 | ||||||
|         if (windows.isGuiMode()) return; |         if (windows.isGuiMode()) return; | ||||||
| 
 | 
 | ||||||
|         // Configure player movement according to keyboard input. Actual movement will
 |         // Configure player movement according to keyboard input. Actual movement will
 | ||||||
|  | @ -388,14 +402,10 @@ namespace MWInput | ||||||
| 
 | 
 | ||||||
|     // Switch between gui modes. Besides controlling the Gui windows
 |     // Switch between gui modes. Besides controlling the Gui windows
 | ||||||
|     // this also makes sure input is directed to the right place
 |     // this also makes sure input is directed to the right place
 | ||||||
|     void setGuiMode(MWGui::GuiMode mode) |     void changeInputMode(bool guiMode) | ||||||
|     { |     { | ||||||
|       // Tell the GUI what to show (this also takes care of the mouse
 |  | ||||||
|       // pointer)
 |  | ||||||
|       windows.setMode(mode); |  | ||||||
| 
 |  | ||||||
|       // Are we in GUI mode now?
 |       // Are we in GUI mode now?
 | ||||||
|       if(windows.isGuiMode()) |       if(guiMode) | ||||||
|         { |         { | ||||||
|           // Disable mouse look
 |           // Disable mouse look
 | ||||||
|           mouse->setCamera(NULL); |           mouse->setCamera(NULL); | ||||||
|  | @ -431,11 +441,6 @@ namespace MWInput | ||||||
|     delete impl; |     delete impl; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   void MWInputManager::setGuiMode(MWGui::GuiMode mode) |  | ||||||
|   { |  | ||||||
|       impl->setGuiMode(mode); |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   void MWInputManager::update() |   void MWInputManager::update() | ||||||
|   { |   { | ||||||
|       impl->update(); |       impl->update(); | ||||||
|  | @ -445,4 +450,25 @@ namespace MWInput | ||||||
|   { |   { | ||||||
|       impl->setDragDrop(dragDrop); |       impl->setDragDrop(dragDrop); | ||||||
|   } |   } | ||||||
|  | 
 | ||||||
|  |   void MWInputManager::changeInputMode(bool guiMode) | ||||||
|  |   { | ||||||
|  |       impl->changeInputMode(guiMode); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   void MWInputManager::processChangedSettings(const Settings::CategorySettingVector& changed) | ||||||
|  |   { | ||||||
|  |       bool changeRes = false; | ||||||
|  |       for (Settings::CategorySettingVector::const_iterator it = changed.begin(); | ||||||
|  |         it != changed.end(); ++it) | ||||||
|  |       { | ||||||
|  |           if (it->first == "Video" && ( | ||||||
|  |             it->second == "resolution x" | ||||||
|  |             || it->second == "resolution y")) | ||||||
|  |                 changeRes = true; | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       if (changeRes) | ||||||
|  |           impl->adjustMouseRegion(Settings::Manager::getInt("resolution x", "Video"), Settings::Manager::getInt("resolution y", "Video")); | ||||||
|  |   } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -3,6 +3,8 @@ | ||||||
| 
 | 
 | ||||||
| #include "../mwgui/mode.hpp" | #include "../mwgui/mode.hpp" | ||||||
| 
 | 
 | ||||||
|  | #include <components/settings/settings.hpp> | ||||||
|  | 
 | ||||||
| namespace OEngine | namespace OEngine | ||||||
| { | { | ||||||
|   namespace Render |   namespace Render | ||||||
|  | @ -50,9 +52,11 @@ namespace MWInput | ||||||
| 
 | 
 | ||||||
|     void update(); |     void update(); | ||||||
| 
 | 
 | ||||||
|     void setDragDrop(bool dragDrop); |     void changeInputMode(bool guiMode); | ||||||
| 
 | 
 | ||||||
|     void setGuiMode(MWGui::GuiMode mode); |     void processChangedSettings(const Settings::CategorySettingVector& changed); | ||||||
|  | 
 | ||||||
|  |     void setDragDrop(bool dragDrop); | ||||||
|   }; |   }; | ||||||
| } | } | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  | @ -71,7 +71,10 @@ namespace MWMechanics | ||||||
| 
 | 
 | ||||||
|     void Actors::removeActor (const MWWorld::Ptr& ptr) |     void Actors::removeActor (const MWWorld::Ptr& ptr) | ||||||
|     { |     { | ||||||
|         mActors.erase (ptr); |         std::set<MWWorld::Ptr>::iterator iter = mActors.find (ptr); | ||||||
|  | 
 | ||||||
|  |         if (iter!=mActors.end()) | ||||||
|  |             mActors.erase (iter); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     void Actors::dropActors (const MWWorld::Ptr::CellStore *cellStore) |     void Actors::dropActors (const MWWorld::Ptr::CellStore *cellStore) | ||||||
|  |  | ||||||
|  | @ -32,6 +32,8 @@ namespace MWMechanics | ||||||
| 
 | 
 | ||||||
|             void removeActor (const MWWorld::Ptr& ptr); |             void removeActor (const MWWorld::Ptr& ptr); | ||||||
|             ///< Deregister an actor for stats management
 |             ///< Deregister an actor for stats management
 | ||||||
|  |             ///
 | ||||||
|  |             /// \note Ignored, if \a ptr is not a registered actor.
 | ||||||
| 
 | 
 | ||||||
|             void dropActors (const MWWorld::Ptr::CellStore *cellStore); |             void dropActors (const MWWorld::Ptr::CellStore *cellStore); | ||||||
|             ///< Deregister all actors in the given cell.
 |             ///< Deregister all actors in the given cell.
 | ||||||
|  |  | ||||||
|  | @ -30,6 +30,15 @@ namespace MWMechanics | ||||||
|         for (int i=0; i<27; ++i) |         for (int i=0; i<27; ++i) | ||||||
|             npcStats.mSkill[i].setBase (player->npdt52.skills[i]); |             npcStats.mSkill[i].setBase (player->npdt52.skills[i]); | ||||||
| 
 | 
 | ||||||
|  |         creatureStats.mAttributes[0].setBase (player->npdt52.strength); | ||||||
|  |         creatureStats.mAttributes[1].setBase (player->npdt52.intelligence); | ||||||
|  |         creatureStats.mAttributes[2].setBase (player->npdt52.willpower); | ||||||
|  |         creatureStats.mAttributes[3].setBase (player->npdt52.agility); | ||||||
|  |         creatureStats.mAttributes[4].setBase (player->npdt52.speed); | ||||||
|  |         creatureStats.mAttributes[5].setBase (player->npdt52.endurance); | ||||||
|  |         creatureStats.mAttributes[6].setBase (player->npdt52.personality); | ||||||
|  |         creatureStats.mAttributes[7].setBase (player->npdt52.luck); | ||||||
|  | 
 | ||||||
|         // race
 |         // race
 | ||||||
|         if (mRaceSelected) |         if (mRaceSelected) | ||||||
|         { |         { | ||||||
|  |  | ||||||
|  | @ -28,7 +28,7 @@ namespace MWMechanics | ||||||
| 
 | 
 | ||||||
|     void Spells::add (const std::string& spellId) |     void Spells::add (const std::string& spellId) | ||||||
|     { |     { | ||||||
|         if (std::find (mSpells.begin(), mSpells.end(), spellId)!=mSpells.end()) |         if (std::find (mSpells.begin(), mSpells.end(), spellId)==mSpells.end()) | ||||||
|             mSpells.push_back (spellId); |             mSpells.push_back (spellId); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
							
								
								
									
										99
									
								
								apps/openmw/mwmechanics/spellsuccess.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										99
									
								
								apps/openmw/mwmechanics/spellsuccess.hpp
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,99 @@ | ||||||
|  | #ifndef MWMECHANICS_SPELLSUCCESS_H | ||||||
|  | #define MWMECHANICS_SPELLSUCCESS_H | ||||||
|  | 
 | ||||||
|  | #include "../mwworld/ptr.hpp" | ||||||
|  | #include "../mwworld/world.hpp" | ||||||
|  | #include "../mwbase/environment.hpp" | ||||||
|  | #include "../mwmechanics/creaturestats.hpp" | ||||||
|  | 
 | ||||||
|  | #include "npcstats.hpp" | ||||||
|  | 
 | ||||||
|  | namespace MWMechanics | ||||||
|  | { | ||||||
|  |     inline int spellSchoolToSkill(int school) | ||||||
|  |     { | ||||||
|  |         std::map<int, int> schoolSkillMap; // maps spell school to skill id
 | ||||||
|  |         schoolSkillMap[0] = 11; // alteration
 | ||||||
|  |         schoolSkillMap[1] = 13; // conjuration
 | ||||||
|  |         schoolSkillMap[3] = 12; // illusion
 | ||||||
|  |         schoolSkillMap[2] = 10; // destruction
 | ||||||
|  |         schoolSkillMap[4] = 14; // mysticism
 | ||||||
|  |         schoolSkillMap[5] = 15; // restoration
 | ||||||
|  |         assert(schoolSkillMap.find(school) != schoolSkillMap.end()); | ||||||
|  |         return schoolSkillMap[school]; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     inline int getSpellSchool(const std::string& spellId, const MWWorld::Ptr& actor) | ||||||
|  |     { | ||||||
|  |         const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().spells.find(spellId); | ||||||
|  |         NpcStats& stats = MWWorld::Class::get(actor).getNpcStats(actor); | ||||||
|  | 
 | ||||||
|  |         // determine the spell's school
 | ||||||
|  |         // this is always the school where the player's respective skill is the least advanced
 | ||||||
|  |         // out of all the magic effects' schools
 | ||||||
|  |         const std::vector<ESM::ENAMstruct>& effects = spell->effects.list; | ||||||
|  |         int school = -1; | ||||||
|  |         int skillLevel = -1; | ||||||
|  |         for (std::vector<ESM::ENAMstruct>::const_iterator it = effects.begin(); | ||||||
|  |             it != effects.end(); ++it) | ||||||
|  |         { | ||||||
|  |             const ESM::MagicEffect* effect = MWBase::Environment::get().getWorld()->getStore().magicEffects.find(it->effectID); | ||||||
|  |             int _school = effect->data.school; | ||||||
|  |             int _skillLevel = stats.mSkill[spellSchoolToSkill(_school)].getModified(); | ||||||
|  | 
 | ||||||
|  |             if (school == -1) | ||||||
|  |             { | ||||||
|  |                 school = _school; | ||||||
|  |                 skillLevel = _skillLevel; | ||||||
|  |             } | ||||||
|  |             else if (_skillLevel < skillLevel) | ||||||
|  |             { | ||||||
|  |                 school = _school; | ||||||
|  |                 skillLevel = _skillLevel; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         return school; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     // UESP wiki / Morrowind/Spells:
 | ||||||
|  |     // Chance of success is (Spell's skill * 2 + Willpower / 5 + Luck / 10 - Spell cost - Sound magnitude) * (Current fatigue + Maximum Fatigue * 1.5) / Maximum fatigue * 2
 | ||||||
|  |     /**
 | ||||||
|  |      * @param spellId ID of spell | ||||||
|  |      * @param actor calculate spell success chance for this actor (depends on actor's skills) | ||||||
|  |      * @attention actor has to be an NPC and not a creature! | ||||||
|  |      * @return success chance from 0 to 100 (in percent) | ||||||
|  |      */ | ||||||
|  |     inline float getSpellSuccessChance (const std::string& spellId, const MWWorld::Ptr& actor) | ||||||
|  |     { | ||||||
|  |         const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().spells.find(spellId); | ||||||
|  | 
 | ||||||
|  |         if (spell->data.flags & ESM::Spell::F_Always // spells with this flag always succeed (usually birthsign spells)
 | ||||||
|  |             || spell->data.type == ESM::Spell::ST_Power) // powers always succeed, but can be cast only once per day
 | ||||||
|  |             return 100.0; | ||||||
|  | 
 | ||||||
|  |         NpcStats& stats = MWWorld::Class::get(actor).getNpcStats(actor); | ||||||
|  |         CreatureStats& creatureStats = MWWorld::Class::get(actor).getCreatureStats(actor); | ||||||
|  | 
 | ||||||
|  |         int skillLevel = stats.mSkill[getSpellSchool(spellId, actor)].getModified(); | ||||||
|  | 
 | ||||||
|  |         // Sound magic effect (reduces spell casting chance)
 | ||||||
|  |         int soundMagnitude = creatureStats.mMagicEffects.get (MWMechanics::EffectKey (48)).mMagnitude; | ||||||
|  | 
 | ||||||
|  |         int willpower = creatureStats.mAttributes[ESM::Attribute::Willpower].getModified(); | ||||||
|  |         int luck = creatureStats.mAttributes[ESM::Attribute::Luck].getModified(); | ||||||
|  |         int currentFatigue = creatureStats.mDynamic[2].getCurrent(); | ||||||
|  |         int maxFatigue = creatureStats.mDynamic[2].getModified(); | ||||||
|  |         int spellCost = spell->data.cost; | ||||||
|  | 
 | ||||||
|  |         // There we go, all needed variables are there, lets go
 | ||||||
|  |         float chance = (float(skillLevel * 2) + float(willpower)/5.0 + float(luck)/ 10.0 - spellCost - soundMagnitude) * (float(currentFatigue + maxFatigue * 1.5)) / float(maxFatigue * 2.0); | ||||||
|  | 
 | ||||||
|  |         chance = std::max(0.0f, std::min(100.0f, chance)); // clamp to 0 .. 100
 | ||||||
|  | 
 | ||||||
|  |         return chance; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
|  | @ -26,6 +26,21 @@ void Compositors::setEnabled (const bool enabled) | ||||||
|     mEnabled = enabled; |     mEnabled = enabled; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void Compositors::recreate() | ||||||
|  | { | ||||||
|  |     Ogre::CompositorManager::getSingleton().removeCompositorChain(mViewport); | ||||||
|  | 
 | ||||||
|  |     CompositorMap temp = mCompositors; | ||||||
|  |     mCompositors.clear(); | ||||||
|  | 
 | ||||||
|  |     for (CompositorMap::iterator it=temp.begin(); | ||||||
|  |         it != temp.end(); ++it) | ||||||
|  |     { | ||||||
|  |         addCompositor(it->first, it->second.second); | ||||||
|  |         setCompositorEnabled(it->first, mEnabled && it->second.first); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void Compositors::addCompositor (const std::string& name, const int priority) | void Compositors::addCompositor (const std::string& name, const int priority) | ||||||
| { | { | ||||||
|     int id = 0; |     int id = 0; | ||||||
|  | @ -47,3 +62,10 @@ void Compositors::setCompositorEnabled (const std::string& name, const bool enab | ||||||
|     mCompositors[name].first = enabled; |     mCompositors[name].first = enabled; | ||||||
|     Ogre::CompositorManager::getSingleton().setCompositorEnabled (mViewport, name, enabled && mEnabled); |     Ogre::CompositorManager::getSingleton().setCompositorEnabled (mViewport, name, enabled && mEnabled); | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | void Compositors::removeAll() | ||||||
|  | { | ||||||
|  |     Ogre::CompositorManager::getSingleton().removeCompositorChain(mViewport); | ||||||
|  | 
 | ||||||
|  |     mCompositors.clear(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ -25,6 +25,11 @@ namespace MWRender | ||||||
|          */ |          */ | ||||||
|         void setEnabled (const bool enabled); |         void setEnabled (const bool enabled); | ||||||
| 
 | 
 | ||||||
|  |         void setViewport(Ogre::Viewport* vp) { mViewport = vp; } | ||||||
|  | 
 | ||||||
|  |         /// recreate compositors (call this after viewport size changes)
 | ||||||
|  |         void recreate(); | ||||||
|  | 
 | ||||||
|         bool toggle() { setEnabled(!mEnabled); return mEnabled; } |         bool toggle() { setEnabled(!mEnabled); return mEnabled; } | ||||||
| 
 | 
 | ||||||
|         /**
 |         /**
 | ||||||
|  | @ -39,6 +44,8 @@ namespace MWRender | ||||||
|          */ |          */ | ||||||
|         void addCompositor (const std::string& name, const int priority); |         void addCompositor (const std::string& name, const int priority); | ||||||
| 
 | 
 | ||||||
|  |         void removeAll (); | ||||||
|  | 
 | ||||||
|     protected: |     protected: | ||||||
|         /// maps compositor name to its "enabled" state
 |         /// maps compositor name to its "enabled" state
 | ||||||
|         CompositorMap mCompositors; |         CompositorMap mCompositors; | ||||||
|  |  | ||||||
|  | @ -68,7 +68,7 @@ ManualObject *Debugging::createPathgridLines(const ESM::Pathgrid *pathgrid) | ||||||
|     result->begin(PATHGRID_LINE_MATERIAL, RenderOperation::OT_LINE_LIST); |     result->begin(PATHGRID_LINE_MATERIAL, RenderOperation::OT_LINE_LIST); | ||||||
|     for(ESM::Pathgrid::EdgeList::const_iterator it = pathgrid->edges.begin(); |     for(ESM::Pathgrid::EdgeList::const_iterator it = pathgrid->edges.begin(); | ||||||
|         it != pathgrid->edges.end(); |         it != pathgrid->edges.end(); | ||||||
|         it++) |         ++it) | ||||||
|     { |     { | ||||||
|         const ESM::Pathgrid::Edge &edge = *it; |         const ESM::Pathgrid::Edge &edge = *it; | ||||||
|         const ESM::Pathgrid::Point &p1 = pathgrid->points[edge.v0], &p2 = pathgrid->points[edge.v1]; |         const ESM::Pathgrid::Point &p1 = pathgrid->points[edge.v0], &p2 = pathgrid->points[edge.v1]; | ||||||
|  | @ -197,7 +197,7 @@ void Debugging::togglePathgrid() | ||||||
| 
 | 
 | ||||||
|         // add path grid meshes to already loaded cells
 |         // add path grid meshes to already loaded cells
 | ||||||
|         mPathGridRoot = mMwRoot->createChildSceneNode(); |         mPathGridRoot = mMwRoot->createChildSceneNode(); | ||||||
|         for(CellList::iterator it = mActiveCells.begin(); it != mActiveCells.end(); it++) |         for(CellList::iterator it = mActiveCells.begin(); it != mActiveCells.end(); ++it) | ||||||
|         { |         { | ||||||
|             enableCellPathgrid(*it); |             enableCellPathgrid(*it); | ||||||
|         } |         } | ||||||
|  | @ -205,7 +205,7 @@ void Debugging::togglePathgrid() | ||||||
|     else |     else | ||||||
|     { |     { | ||||||
|         // remove path grid meshes from already loaded cells
 |         // remove path grid meshes from already loaded cells
 | ||||||
|         for(CellList::iterator it = mActiveCells.begin(); it != mActiveCells.end(); it++) |         for(CellList::iterator it = mActiveCells.begin(); it != mActiveCells.end(); ++it) | ||||||
|         { |         { | ||||||
|             disableCellPathgrid(*it); |             disableCellPathgrid(*it); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  | @ -307,50 +307,81 @@ void LocalMap::updatePlayer (const Ogre::Vector3& position, const Ogre::Quaterni | ||||||
| 
 | 
 | ||||||
|     // convert from world coordinates to texture UV coordinates
 |     // convert from world coordinates to texture UV coordinates
 | ||||||
|     float u,v; |     float u,v; | ||||||
|     std::string texName; |     std::string texBaseName; | ||||||
|     if (!mInterior) |     if (!mInterior) | ||||||
|     { |     { | ||||||
|         u = std::abs((pos.x - (sSize*x))/sSize); |         u = std::abs((pos.x - (sSize*x))/sSize); | ||||||
|         v = 1-std::abs((pos.y + (sSize*y))/sSize); |         v = 1-std::abs((pos.y + (sSize*y))/sSize); | ||||||
|         texName = "Cell_"+coordStr(x,y); |         texBaseName = "Cell_"; | ||||||
|     } |     } | ||||||
|     else |     else | ||||||
|     { |     { | ||||||
|         u = (pos.x - min.x - sSize*x)/sSize; |         u = (pos.x - min.x - sSize*x)/sSize; | ||||||
|         v = (pos.y - min.y - sSize*y)/sSize; |         v = (pos.y - min.y - sSize*y)/sSize; | ||||||
| 
 | 
 | ||||||
|         texName = mInteriorName + "_" + coordStr(x,y); |         texBaseName = mInteriorName + "_"; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     MWBase::Environment::get().getWindowManager()->setPlayerPos(u, v); |     MWBase::Environment::get().getWindowManager()->setPlayerPos(u, v); | ||||||
|     MWBase::Environment::get().getWindowManager()->setPlayerDir(playerdirection.x, -playerdirection.z); |     MWBase::Environment::get().getWindowManager()->setPlayerDir(playerdirection.x, -playerdirection.z); | ||||||
| 
 | 
 | ||||||
|     // explore radius (squared)
 |     // explore radius (squared)
 | ||||||
|     const float sqrExploreRadius = 0.01 * sFogOfWarResolution*sFogOfWarResolution; |     const float sqrExploreRadius = (mInterior ? 0.01 : 0.09) * sFogOfWarResolution*sFogOfWarResolution; | ||||||
|  |     const float exploreRadius = (mInterior ? 0.1 : 0.3) * sFogOfWarResolution; // explore radius from 0 to sFogOfWarResolution
 | ||||||
|  |     const float exploreRadiusUV = exploreRadius / sFogOfWarResolution; // explore radius from 0 to 1 (UV space)
 | ||||||
| 
 | 
 | ||||||
|     // get the appropriate fog of war texture
 |     int intExtMult = mInterior ? 1 : -1; // interior and exterior have reversed Y coordinates (interior: top to bottom)
 | ||||||
|     TexturePtr tex = TextureManager::getSingleton().getByName(texName+"_fog"); | 
 | ||||||
|     if (!tex.isNull()) |     // change the affected fog of war textures (in a 3x3 grid around the player)
 | ||||||
|  |     for (int mx = -1; mx<2; ++mx) | ||||||
|     { |     { | ||||||
|         // get its buffer
 |         for (int my = -1; my<2; ++my) | ||||||
|         if (mBuffers.find(texName) == mBuffers.end()) return; |  | ||||||
|         int i=0; |  | ||||||
|         for (int texV = 0; texV<sFogOfWarResolution; ++texV) |  | ||||||
|         { |         { | ||||||
|             for (int texU = 0; texU<sFogOfWarResolution; ++texU) |  | ||||||
|             { |  | ||||||
|                 float sqrDist = Math::Sqr(texU - u*sFogOfWarResolution) + Math::Sqr(texV - v*sFogOfWarResolution); |  | ||||||
|                 uint32 clr = mBuffers[texName][i]; |  | ||||||
|                 uint8 alpha = (clr >> 24); |  | ||||||
|                 alpha = std::min( alpha, (uint8) (std::max(0.f, std::min(1.f, (sqrDist/sqrExploreRadius)))*255) ); |  | ||||||
|                 mBuffers[texName][i] = (uint32) (alpha << 24); |  | ||||||
| 
 | 
 | ||||||
|                 ++i; |             // is this texture affected at all?
 | ||||||
|  |             bool affected = false; | ||||||
|  |             if (mx == 0 && my == 0) // the player is always in the center of the 3x3 grid
 | ||||||
|  |                 affected = true; | ||||||
|  |             else | ||||||
|  |             { | ||||||
|  |                 bool affectsX = (mx > 0)? (u + exploreRadiusUV > 1) : (u - exploreRadiusUV < 0); | ||||||
|  |                 bool affectsY = (my > 0)? (v + exploreRadiusUV > 1) : (v - exploreRadiusUV < 0); | ||||||
|  |                 affected = (affectsX && (my == 0)) || (affectsY && mx == 0) || (affectsX && affectsY); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             if (!affected) | ||||||
|  |                 continue; | ||||||
|  | 
 | ||||||
|  |             std::string texName = texBaseName + coordStr(x+mx,y+my*intExtMult); | ||||||
|  | 
 | ||||||
|  |             TexturePtr tex = TextureManager::getSingleton().getByName(texName+"_fog"); | ||||||
|  |             if (!tex.isNull()) | ||||||
|  |             { | ||||||
|  |                 // get its buffer
 | ||||||
|  |                 if (mBuffers.find(texName) == mBuffers.end()) return; | ||||||
|  |                 int i=0; | ||||||
|  |                 for (int texV = 0; texV<sFogOfWarResolution; ++texV) | ||||||
|  |                 { | ||||||
|  |                     for (int texU = 0; texU<sFogOfWarResolution; ++texU) | ||||||
|  |                     { | ||||||
|  |                         // fix into range of 0 ... sFogOfWarResolution
 | ||||||
|  |                         int _texU = texU * (float(sFogOfWarResolution+1) / float(sFogOfWarResolution)); | ||||||
|  |                         int _texV = texV * (float(sFogOfWarResolution+1) / float(sFogOfWarResolution)); | ||||||
|  | 
 | ||||||
|  |                         float sqrDist = Math::Sqr((_texU + mx*sFogOfWarResolution) - u*sFogOfWarResolution) + Math::Sqr((_texV + my*sFogOfWarResolution) - v*sFogOfWarResolution); | ||||||
|  |                         uint32 clr = mBuffers[texName][i]; | ||||||
|  |                         uint8 alpha = (clr >> 24); | ||||||
|  |                         alpha = std::min( alpha, (uint8) (std::max(0.f, std::min(1.f, (sqrDist/sqrExploreRadius)))*255) ); | ||||||
|  |                         mBuffers[texName][i] = (uint32) (alpha << 24); | ||||||
|  | 
 | ||||||
|  |                         ++i; | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 // copy to the texture
 | ||||||
|  |                 memcpy(tex->getBuffer()->lock(HardwareBuffer::HBL_DISCARD), &mBuffers[texName][0], sFogOfWarResolution*sFogOfWarResolution*4); | ||||||
|  |                 tex->getBuffer()->unlock(); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
| 
 |  | ||||||
|         // copy to the texture
 |  | ||||||
|         memcpy(tex->getBuffer()->lock(HardwareBuffer::HBL_DISCARD), &mBuffers[texName][0], sFogOfWarResolution*sFogOfWarResolution*4); |  | ||||||
|         tex->getBuffer()->unlock(); |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -528,7 +528,7 @@ void NpcAnimation::insertFootPart(int type, const std::string &mesh){ | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
| std::pair<Ogre::Entity*, std::vector<Nif::NiTriShapeCopy>*> NpcAnimation::insertFreePart(const std::string &mesh, const std::string suffix){ | std::pair<Ogre::Entity*, std::vector<Nif::NiTriShapeCopy>*> NpcAnimation::insertFreePart(const std::string &mesh, const std::string& suffix){ | ||||||
| 
 | 
 | ||||||
|     std::string meshNumbered = mesh + getUniqueID(mesh + suffix) + suffix; |     std::string meshNumbered = mesh + getUniqueID(mesh + suffix) + suffix; | ||||||
|     NIFLoader::load(meshNumbered); |     NIFLoader::load(meshNumbered); | ||||||
|  |  | ||||||
|  | @ -84,7 +84,7 @@ private: | ||||||
|      NpcAnimation(const MWWorld::Ptr& ptr, OEngine::Render::OgreRenderer& _rend, MWWorld::InventoryStore& _inv); |      NpcAnimation(const MWWorld::Ptr& ptr, OEngine::Render::OgreRenderer& _rend, MWWorld::InventoryStore& _inv); | ||||||
|      virtual ~NpcAnimation(); |      virtual ~NpcAnimation(); | ||||||
|     Ogre::Entity* insertBoundedPart(const std::string &mesh, std::string bonename); |     Ogre::Entity* insertBoundedPart(const std::string &mesh, std::string bonename); | ||||||
|      std::pair<Ogre::Entity*, std::vector<Nif::NiTriShapeCopy>*> insertFreePart(const std::string &mesh, const std::string suffix); |      std::pair<Ogre::Entity*, std::vector<Nif::NiTriShapeCopy>*> insertFreePart(const std::string &mesh, const std::string& suffix); | ||||||
|      void insertFootPart(int type, const std::string &mesh); |      void insertFootPart(int type, const std::string &mesh); | ||||||
| 	virtual void runAnimation(float timepassed); | 	virtual void runAnimation(float timepassed); | ||||||
| 	void updateParts(); | 	void updateParts(); | ||||||
|  |  | ||||||
|  | @ -39,7 +39,8 @@ struct LightInfo | ||||||
| 
 | 
 | ||||||
|     LightInfo() : |     LightInfo() : | ||||||
|         flickerVariation(0), resetTime(0.5), |         flickerVariation(0), resetTime(0.5), | ||||||
|         flickerSlowVariation(0), time(0), interior(true) |         flickerSlowVariation(0), time(0), interior(true), | ||||||
|  |         type(LT_Normal), radius(1.0) | ||||||
|     { |     { | ||||||
|     } |     } | ||||||
| }; | }; | ||||||
|  | @ -68,7 +69,7 @@ class Objects{ | ||||||
|     ///< Remove all movable objects from \a node.
 |     ///< Remove all movable objects from \a node.
 | ||||||
| 
 | 
 | ||||||
| public: | public: | ||||||
|     Objects(OEngine::Render::OgreRenderer& renderer): mRenderer (renderer) {} |     Objects(OEngine::Render::OgreRenderer& renderer): mRenderer (renderer), mIsStatic(false) {} | ||||||
|     ~Objects(){} |     ~Objects(){} | ||||||
|     void insertBegin (const MWWorld::Ptr& ptr, bool enabled, bool static_); |     void insertBegin (const MWWorld::Ptr& ptr, bool enabled, bool static_); | ||||||
|     void insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh); |     void insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh); | ||||||
|  |  | ||||||
|  | @ -6,4 +6,22 @@ namespace MWRender | ||||||
|     Player::Player (Ogre::Camera *camera, Ogre::SceneNode* node) |     Player::Player (Ogre::Camera *camera, Ogre::SceneNode* node) | ||||||
|     : mCamera (camera), mNode (node) |     : mCamera (camera), mNode (node) | ||||||
|     {} |     {} | ||||||
|  | 
 | ||||||
|  |     void Player::setRot(float x, float y, float z) | ||||||
|  |     { | ||||||
|  |             Ogre::SceneNode *sceneNode = mNode; | ||||||
|  |             Ogre::Node* yawNode = sceneNode->getChildIterator().getNext(); | ||||||
|  |             Ogre::Node* pitchNode = yawNode->getChildIterator().getNext(); | ||||||
|  | 
 | ||||||
|  |             // we are only interested in X and Y rotation
 | ||||||
|  | 
 | ||||||
|  |             // Rotate around X axis
 | ||||||
|  |             Ogre::Quaternion xr(Ogre::Radian(x), Ogre::Vector3::UNIT_X); | ||||||
|  | 
 | ||||||
|  |             // Rotate around Y axis
 | ||||||
|  |             Ogre::Quaternion yr(Ogre::Radian(-z), Ogre::Vector3::UNIT_Y); | ||||||
|  | 
 | ||||||
|  |             pitchNode->setOrientation(xr); | ||||||
|  |             yawNode->setOrientation(yr); | ||||||
|  |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -23,6 +23,9 @@ namespace MWRender | ||||||
| 
 | 
 | ||||||
|                 Ogre::Camera *getCamera() { return mCamera; } |                 Ogre::Camera *getCamera() { return mCamera; } | ||||||
| 
 | 
 | ||||||
|  |                 /// Set where the player is looking at. Uses Morrowind (euler) angles
 | ||||||
|  |                 void setRot(float x, float y, float z); | ||||||
|  | 
 | ||||||
|                 std::string getHandle() const { return mNode->getName(); } |                 std::string getHandle() const { return mNode->getName(); } | ||||||
|                 Ogre::SceneNode* getNode() {return mNode;} |                 Ogre::SceneNode* getNode() {return mNode;} | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|  | @ -11,6 +11,7 @@ | ||||||
| 
 | 
 | ||||||
| #include "../mwworld/world.hpp" // these includes can be removed once the static-hack is gone
 | #include "../mwworld/world.hpp" // these includes can be removed once the static-hack is gone
 | ||||||
| #include "../mwworld/ptr.hpp" | #include "../mwworld/ptr.hpp" | ||||||
|  | #include "../mwworld/player.hpp" | ||||||
| #include "../mwbase/environment.hpp" | #include "../mwbase/environment.hpp" | ||||||
| #include <components/esm/loadstat.hpp> | #include <components/esm/loadstat.hpp> | ||||||
| #include <components/settings/settings.hpp> | #include <components/settings/settings.hpp> | ||||||
|  | @ -21,6 +22,9 @@ | ||||||
| #include "water.hpp" | #include "water.hpp" | ||||||
| #include "compositors.hpp" | #include "compositors.hpp" | ||||||
| 
 | 
 | ||||||
|  | #include "../mwgui/window_manager.hpp" // FIXME
 | ||||||
|  | #include "../mwinput/inputmanager.hpp" // FIXME
 | ||||||
|  | 
 | ||||||
| using namespace MWRender; | using namespace MWRender; | ||||||
| using namespace Ogre; | using namespace Ogre; | ||||||
| 
 | 
 | ||||||
|  | @ -30,6 +34,7 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const | ||||||
|     :mRendering(_rend), mObjects(mRendering), mActors(mRendering), mAmbientMode(0), mSunEnabled(0) |     :mRendering(_rend), mObjects(mRendering), mActors(mRendering), mAmbientMode(0), mSunEnabled(0) | ||||||
| { | { | ||||||
|     mRendering.createScene("PlayerCam", Settings::Manager::getFloat("field of view", "General"), 5); |     mRendering.createScene("PlayerCam", Settings::Manager::getFloat("field of view", "General"), 5); | ||||||
|  |     mRendering.setWindowEventListener(this); | ||||||
| 
 | 
 | ||||||
|     mCompositors = new Compositors(mRendering.getViewport()); |     mCompositors = new Compositors(mRendering.getViewport()); | ||||||
| 
 | 
 | ||||||
|  | @ -62,25 +67,13 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const | ||||||
| 
 | 
 | ||||||
|     // disable unsupported effects
 |     // disable unsupported effects
 | ||||||
|     const RenderSystemCapabilities* caps = Root::getSingleton().getRenderSystem()->getCapabilities(); |     const RenderSystemCapabilities* caps = Root::getSingleton().getRenderSystem()->getCapabilities(); | ||||||
|     if (caps->getNumMultiRenderTargets() < 2 || !Settings::Manager::getBool("shaders", "Objects")) |     if (!waterShaderSupported()) | ||||||
|         Settings::Manager::setBool("shader", "Water", false); |         Settings::Manager::setBool("shader", "Water", false); | ||||||
|     if ( !(caps->isShaderProfileSupported("fp40") || caps->isShaderProfileSupported("ps_4_0")) |     if ( !(caps->isShaderProfileSupported("fp40") || caps->isShaderProfileSupported("ps_4_0")) | ||||||
|         || !Settings::Manager::getBool("shaders", "Objects")) |         || !Settings::Manager::getBool("shaders", "Objects")) | ||||||
|         Settings::Manager::setBool("enabled", "Shadows", false); |         Settings::Manager::setBool("enabled", "Shadows", false); | ||||||
| 
 | 
 | ||||||
|     // note that the order is important here
 |     applyCompositors(); | ||||||
|     if (useMRT()) |  | ||||||
|     { |  | ||||||
|         mCompositors->addCompositor("gbuffer", 0); |  | ||||||
|         mCompositors->setCompositorEnabled("gbuffer", true); |  | ||||||
|         mCompositors->addCompositor("Underwater", 1); |  | ||||||
|         mCompositors->addCompositor("gbufferFinalizer", 2); |  | ||||||
|         mCompositors->setCompositorEnabled("gbufferFinalizer", true); |  | ||||||
|     } |  | ||||||
|     else |  | ||||||
|     { |  | ||||||
|         mCompositors->addCompositor("UnderwaterNoMRT", 0); |  | ||||||
|     } |  | ||||||
| 
 | 
 | ||||||
|     // Turn the entire scene (represented by the 'root' node) -90
 |     // Turn the entire scene (represented by the 'root' node) -90
 | ||||||
|     // degrees around the x axis. This makes Z go upwards, and Y go into
 |     // degrees around the x axis. This makes Z go upwards, and Y go into
 | ||||||
|  | @ -104,7 +97,6 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const | ||||||
| 
 | 
 | ||||||
|     mTerrainManager = new TerrainManager(mRendering.getScene(), this); |     mTerrainManager = new TerrainManager(mRendering.getScene(), this); | ||||||
| 
 | 
 | ||||||
|     //mSkyManager = 0;
 |  | ||||||
|     mSkyManager = new SkyManager(mMwRoot, mRendering.getCamera()); |     mSkyManager = new SkyManager(mMwRoot, mRendering.getCamera()); | ||||||
| 
 | 
 | ||||||
|     mOcclusionQuery = new OcclusionQuery(&mRendering, mSkyManager->getSunNode()); |     mOcclusionQuery = new OcclusionQuery(&mRendering, mSkyManager->getSunNode()); | ||||||
|  | @ -114,17 +106,24 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const | ||||||
| 
 | 
 | ||||||
|     mDebugging = new Debugging(mMwRoot, engine); |     mDebugging = new Debugging(mMwRoot, engine); | ||||||
|     mLocalMap = new MWRender::LocalMap(&mRendering, this); |     mLocalMap = new MWRender::LocalMap(&mRendering, this); | ||||||
|  | 
 | ||||||
|  |     setMenuTransparency(Settings::Manager::getFloat("menu transparency", "GUI")); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| RenderingManager::~RenderingManager () | RenderingManager::~RenderingManager () | ||||||
| { | { | ||||||
|  |     mRendering.removeWindowEventListener(this); | ||||||
|  | 
 | ||||||
|     delete mPlayer; |     delete mPlayer; | ||||||
|     delete mSkyManager; |     delete mSkyManager; | ||||||
|     delete mDebugging; |     delete mDebugging; | ||||||
|  |     delete mShaderHelper; | ||||||
|  |     delete mShadows; | ||||||
|     delete mTerrainManager; |     delete mTerrainManager; | ||||||
|     delete mLocalMap; |     delete mLocalMap; | ||||||
|     delete mOcclusionQuery; |     delete mOcclusionQuery; | ||||||
|     delete mCompositors; |     delete mCompositors; | ||||||
|  |     delete mWater; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| MWRender::SkyManager* RenderingManager::getSkyManager() | MWRender::SkyManager* RenderingManager::getSkyManager() | ||||||
|  | @ -563,4 +562,119 @@ Compositors* RenderingManager::getCompositors() | ||||||
|     return mCompositors; |     return mCompositors; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void RenderingManager::processChangedSettings(const Settings::CategorySettingVector& settings) | ||||||
|  | { | ||||||
|  |     bool changeRes = false; | ||||||
|  |     for (Settings::CategorySettingVector::const_iterator it=settings.begin(); | ||||||
|  |             it != settings.end(); ++it) | ||||||
|  |     { | ||||||
|  |         if (it->second == "menu transparency" && it->first == "GUI") | ||||||
|  |         { | ||||||
|  |             setMenuTransparency(Settings::Manager::getFloat("menu transparency", "GUI")); | ||||||
|  |         } | ||||||
|  |         else if (it->second == "max viewing distance" && it->first == "Viewing distance") | ||||||
|  |         { | ||||||
|  |             if (!MWBase::Environment::get().getWorld()->isCellExterior() && !MWBase::Environment::get().getWorld()->isCellQuasiExterior()) | ||||||
|  |                 configureFog(*MWBase::Environment::get().getWorld()->getPlayer().getPlayer().getCell()); | ||||||
|  |         } | ||||||
|  |         else if (it->first == "Video" && ( | ||||||
|  |                 it->second == "resolution x" | ||||||
|  |                 || it->second == "resolution y" | ||||||
|  |                 || it->second == "fullscreen")) | ||||||
|  |             changeRes = true; | ||||||
|  |         else if (it->second == "field of view" && it->first == "General") | ||||||
|  |             mRendering.setFov(Settings::Manager::getFloat("field of view", "General")); | ||||||
|  |         else if ((it->second == "texture filtering" && it->first == "General") | ||||||
|  |             || (it->second == "anisotropy" && it->first == "General")) | ||||||
|  |         { | ||||||
|  |             TextureFilterOptions tfo; | ||||||
|  |             std::string filter = Settings::Manager::getString("texture filtering", "General"); | ||||||
|  |             if (filter == "anisotropic") tfo = TFO_ANISOTROPIC; | ||||||
|  |             else if (filter == "trilinear") tfo = TFO_TRILINEAR; | ||||||
|  |             else if (filter == "bilinear") tfo = TFO_BILINEAR; | ||||||
|  |             else if (filter == "none") tfo = TFO_NONE; | ||||||
|  | 
 | ||||||
|  |             MaterialManager::getSingleton().setDefaultTextureFiltering(tfo); | ||||||
|  |             MaterialManager::getSingleton().setDefaultAnisotropy( (filter == "anisotropic") ? Settings::Manager::getInt("anisotropy", "General") : 1 ); | ||||||
|  |         } | ||||||
|  |         else if (it->second == "shader" && it->first == "Water") | ||||||
|  |         { | ||||||
|  |             applyCompositors(); | ||||||
|  |             mShaderHelper->applyShaders(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (changeRes) | ||||||
|  |     { | ||||||
|  |         unsigned int x = Settings::Manager::getInt("resolution x", "Video"); | ||||||
|  |         unsigned int y = Settings::Manager::getInt("resolution y", "Video"); | ||||||
|  | 
 | ||||||
|  |         if (x != mRendering.getWindow()->getWidth() || y != mRendering.getWindow()->getHeight()) | ||||||
|  |         { | ||||||
|  |             mRendering.getWindow()->resize(x, y); | ||||||
|  |         } | ||||||
|  |         mRendering.getWindow()->setFullscreen(Settings::Manager::getBool("fullscreen", "Video"), x, y); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (mWater) | ||||||
|  |         mWater->processChangedSettings(settings); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void RenderingManager::setMenuTransparency(float val) | ||||||
|  | { | ||||||
|  |     Ogre::TexturePtr tex = Ogre::TextureManager::getSingleton().getByName("transparent.png"); | ||||||
|  |     std::vector<Ogre::uint32> buffer; | ||||||
|  |     buffer.resize(1); | ||||||
|  |     buffer[0] = (int(255*val) << 24); | ||||||
|  |     memcpy(tex->getBuffer()->lock(Ogre::HardwareBuffer::HBL_DISCARD), &buffer[0], 1*4); | ||||||
|  |     tex->getBuffer()->unlock(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void RenderingManager::windowResized(Ogre::RenderWindow* rw) | ||||||
|  | { | ||||||
|  |     Settings::Manager::setInt("resolution x", "Video", rw->getWidth()); | ||||||
|  |     Settings::Manager::setInt("resolution y", "Video", rw->getHeight()); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     mRendering.adjustViewport(); | ||||||
|  |     mCompositors->recreate(); | ||||||
|  |     mWater->assignTextures(); | ||||||
|  | 
 | ||||||
|  |     const Settings::CategorySettingVector& changed = Settings::Manager::apply(); | ||||||
|  |     MWBase::Environment::get().getInputManager()->processChangedSettings(changed); //FIXME
 | ||||||
|  |     MWBase::Environment::get().getWindowManager()->processChangedSettings(changed); // FIXME
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void RenderingManager::windowClosed(Ogre::RenderWindow* rw) | ||||||
|  | { | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | bool RenderingManager::waterShaderSupported() | ||||||
|  | { | ||||||
|  |     const RenderSystemCapabilities* caps = Root::getSingleton().getRenderSystem()->getCapabilities(); | ||||||
|  |     if (caps->getNumMultiRenderTargets() < 2 || !Settings::Manager::getBool("shaders", "Objects")) | ||||||
|  |         return false; | ||||||
|  |     return true; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void RenderingManager::applyCompositors() | ||||||
|  | { | ||||||
|  |     mCompositors->removeAll(); | ||||||
|  |     if (useMRT()) | ||||||
|  |     { | ||||||
|  |         mCompositors->addCompositor("gbuffer", 0); | ||||||
|  |         mCompositors->setCompositorEnabled("gbuffer", true); | ||||||
|  |         mCompositors->addCompositor("Underwater", 1); | ||||||
|  |         mCompositors->addCompositor("gbufferFinalizer", 2); | ||||||
|  |         mCompositors->setCompositorEnabled("gbufferFinalizer", true); | ||||||
|  |     } | ||||||
|  |     else | ||||||
|  |     { | ||||||
|  |         mCompositors->addCompositor("UnderwaterNoMRT", 0); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (mWater) | ||||||
|  |         mWater->assignTextures(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| } // namespace
 | } // namespace
 | ||||||
|  |  | ||||||
|  | @ -8,11 +8,15 @@ | ||||||
| 
 | 
 | ||||||
| #include "../mwworld/class.hpp" | #include "../mwworld/class.hpp" | ||||||
| 
 | 
 | ||||||
|  | #include <OgreWindowEventUtilities.h> | ||||||
|  | 
 | ||||||
| #include <utility> | #include <utility> | ||||||
| #include <openengine/ogre/renderer.hpp> | #include <openengine/ogre/renderer.hpp> | ||||||
| #include <openengine/ogre/fader.hpp> | #include <openengine/ogre/fader.hpp> | ||||||
| #include <openengine/bullet/physic.hpp> | #include <openengine/bullet/physic.hpp> | ||||||
| 
 | 
 | ||||||
|  | #include <components/settings/settings.hpp> | ||||||
|  | 
 | ||||||
| #include <vector> | #include <vector> | ||||||
| #include <string> | #include <string> | ||||||
| 
 | 
 | ||||||
|  | @ -49,7 +53,7 @@ namespace MWRender | ||||||
|     class Water; |     class Water; | ||||||
|     class Compositors; |     class Compositors; | ||||||
| 
 | 
 | ||||||
| class RenderingManager: private RenderingInterface { | class RenderingManager: private RenderingInterface, public Ogre::WindowEventListener { | ||||||
| 
 | 
 | ||||||
|   private: |   private: | ||||||
| 
 | 
 | ||||||
|  | @ -157,10 +161,24 @@ class RenderingManager: private RenderingInterface { | ||||||
|     ///< transform the specified bounding box (in world coordinates) into screen coordinates.
 |     ///< transform the specified bounding box (in world coordinates) into screen coordinates.
 | ||||||
|     /// @return packed vector4 (min_x, min_y, max_x, max_y)
 |     /// @return packed vector4 (min_x, min_y, max_x, max_y)
 | ||||||
| 
 | 
 | ||||||
|  |     void processChangedSettings(const Settings::CategorySettingVector& settings); | ||||||
|  | 
 | ||||||
|  |     Ogre::Viewport* getViewport() { return mRendering.getViewport(); } | ||||||
|  | 
 | ||||||
|  |     static bool waterShaderSupported(); | ||||||
|  | 
 | ||||||
|  |   protected: | ||||||
|  | 	virtual void windowResized(Ogre::RenderWindow* rw); | ||||||
|  |     virtual void windowClosed(Ogre::RenderWindow* rw); | ||||||
|  | 
 | ||||||
|   private: |   private: | ||||||
| 
 | 
 | ||||||
|     void setAmbientMode(); |     void setAmbientMode(); | ||||||
| 
 | 
 | ||||||
|  |     void setMenuTransparency(float val); | ||||||
|  | 
 | ||||||
|  |     void applyCompositors(); | ||||||
|  | 
 | ||||||
|     bool mSunEnabled; |     bool mSunEnabled; | ||||||
| 
 | 
 | ||||||
|     SkyManager* mSkyManager; |     SkyManager* mSkyManager; | ||||||
|  |  | ||||||
|  | @ -374,7 +374,7 @@ SkyManager::SkyManager (SceneNode* pMwRoot, Camera* pCamera) | ||||||
|     , mSunGlare(NULL) |     , mSunGlare(NULL) | ||||||
|     , mMasser(NULL) |     , mMasser(NULL) | ||||||
|     , mSecunda(NULL) |     , mSecunda(NULL) | ||||||
|     , mViewport(NULL) |     , mCamera(pCamera) | ||||||
|     , mRootNode(NULL) |     , mRootNode(NULL) | ||||||
|     , mSceneMgr(NULL) |     , mSceneMgr(NULL) | ||||||
|     , mAtmosphereDay(NULL) |     , mAtmosphereDay(NULL) | ||||||
|  | @ -399,9 +399,8 @@ SkyManager::SkyManager (SceneNode* pMwRoot, Camera* pCamera) | ||||||
|     , mSecundaEnabled(true) |     , mSecundaEnabled(true) | ||||||
|     , mCreated(false) |     , mCreated(false) | ||||||
| { | { | ||||||
|     mViewport = pCamera->getViewport(); |  | ||||||
|     mSceneMgr = pMwRoot->getCreator(); |     mSceneMgr = pMwRoot->getCreator(); | ||||||
|     mRootNode = pCamera->getParentSceneNode()->createChildSceneNode(); |     mRootNode = mCamera->getParentSceneNode()->createChildSceneNode(); | ||||||
|     mRootNode->pitch(Degree(-90)); // convert MW to ogre coordinates
 |     mRootNode->pitch(Degree(-90)); // convert MW to ogre coordinates
 | ||||||
|     mRootNode->setInheritOrientation(false); |     mRootNode->setInheritOrientation(false); | ||||||
| } | } | ||||||
|  | @ -741,7 +740,7 @@ void SkyManager::update(float duration) | ||||||
|         // on how directly the player is looking at the sun
 |         // on how directly the player is looking at the sun
 | ||||||
|         Vector3 sun = mSunGlare->getPosition(); |         Vector3 sun = mSunGlare->getPosition(); | ||||||
|         sun = Vector3(sun.x, sun.z, -sun.y); |         sun = Vector3(sun.x, sun.z, -sun.y); | ||||||
|         Vector3 cam = mViewport->getCamera()->getRealDirection(); |         Vector3 cam = mCamera->getRealDirection(); | ||||||
|         const Degree angle = sun.angleBetween( cam ); |         const Degree angle = sun.angleBetween( cam ); | ||||||
|         float val = 1- (angle.valueDegrees() / 180.f); |         float val = 1- (angle.valueDegrees() / 180.f); | ||||||
|         val = (val*val*val*val)*2; |         val = (val*val*val*val)*2; | ||||||
|  |  | ||||||
|  | @ -185,7 +185,7 @@ namespace MWRender | ||||||
|         Moon* mMasser; |         Moon* mMasser; | ||||||
|         Moon* mSecunda; |         Moon* mSecunda; | ||||||
| 
 | 
 | ||||||
|         Ogre::Viewport* mViewport; |         Ogre::Camera* mCamera; | ||||||
|         Ogre::SceneNode* mRootNode; |         Ogre::SceneNode* mRootNode; | ||||||
|         Ogre::SceneManager* mSceneMgr; |         Ogre::SceneManager* mSceneMgr; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -22,30 +22,30 @@ namespace MWRender | ||||||
|     TerrainManager::TerrainManager(Ogre::SceneManager* mgr, RenderingManager* rend) : |     TerrainManager::TerrainManager(Ogre::SceneManager* mgr, RenderingManager* rend) : | ||||||
|          mTerrainGroup(TerrainGroup(mgr, Terrain::ALIGN_X_Z, mLandSize, mWorldSize)), mRendering(rend) |          mTerrainGroup(TerrainGroup(mgr, Terrain::ALIGN_X_Z, mLandSize, mWorldSize)), mRendering(rend) | ||||||
|     { |     { | ||||||
| 
 |         mTerrainGlobals = OGRE_NEW TerrainGlobalOptions(); | ||||||
|         TerrainMaterialGeneratorPtr matGen; |         TerrainMaterialGeneratorPtr matGen; | ||||||
|         TerrainMaterialGeneratorB* matGenP = new TerrainMaterialGeneratorB(); |         TerrainMaterialGeneratorB* matGenP = new TerrainMaterialGeneratorB(); | ||||||
|         matGen.bind(matGenP); |         matGen.bind(matGenP); | ||||||
|         mTerrainGlobals.setDefaultMaterialGenerator(matGen); |         mTerrainGlobals->setDefaultMaterialGenerator(matGen); | ||||||
| 
 | 
 | ||||||
|         TerrainMaterialGenerator::Profile* const activeProfile = |         TerrainMaterialGenerator::Profile* const activeProfile = | ||||||
|             mTerrainGlobals.getDefaultMaterialGenerator() |             mTerrainGlobals->getDefaultMaterialGenerator() | ||||||
|                            ->getActiveProfile(); |                            ->getActiveProfile(); | ||||||
|         mActiveProfile = static_cast<TerrainMaterialGeneratorB::SM2Profile*>(activeProfile); |         mActiveProfile = static_cast<TerrainMaterialGeneratorB::SM2Profile*>(activeProfile); | ||||||
| 
 | 
 | ||||||
|         //The pixel error should be as high as possible without it being noticed
 |         //The pixel error should be as high as possible without it being noticed
 | ||||||
|         //as it governs how fast mesh quality decreases.
 |         //as it governs how fast mesh quality decreases.
 | ||||||
|         mTerrainGlobals.setMaxPixelError(8); |         mTerrainGlobals->setMaxPixelError(8); | ||||||
| 
 | 
 | ||||||
|         mTerrainGlobals.setLayerBlendMapSize(32); |         mTerrainGlobals->setLayerBlendMapSize(32); | ||||||
|         mTerrainGlobals.setDefaultGlobalColourMapSize(65); |         mTerrainGlobals->setDefaultGlobalColourMapSize(65); | ||||||
| 
 | 
 | ||||||
|         //10 (default) didn't seem to be quite enough
 |         //10 (default) didn't seem to be quite enough
 | ||||||
|         mTerrainGlobals.setSkirtSize(128); |         mTerrainGlobals->setSkirtSize(128); | ||||||
| 
 | 
 | ||||||
|         //due to the sudden flick between composite and non composite textures,
 |         //due to the sudden flick between composite and non composite textures,
 | ||||||
|         //this seemed the distance where it wasn't too noticeable
 |         //this seemed the distance where it wasn't too noticeable
 | ||||||
|         mTerrainGlobals.setCompositeMapDistance(mWorldSize*2); |         mTerrainGlobals->setCompositeMapDistance(mWorldSize*2); | ||||||
| 
 | 
 | ||||||
|         mActiveProfile->setLightmapEnabled(false); |         mActiveProfile->setLightmapEnabled(false); | ||||||
|         mActiveProfile->setLayerSpecularMappingEnabled(false); |         mActiveProfile->setLayerSpecularMappingEnabled(false); | ||||||
|  | @ -86,20 +86,21 @@ namespace MWRender | ||||||
| 
 | 
 | ||||||
|     TerrainManager::~TerrainManager() |     TerrainManager::~TerrainManager() | ||||||
|     { |     { | ||||||
|  |         OGRE_DELETE mTerrainGlobals; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     //----------------------------------------------------------------------------------------------
 |     //----------------------------------------------------------------------------------------------
 | ||||||
| 
 | 
 | ||||||
|     void TerrainManager::setDiffuse(const ColourValue& diffuse) |     void TerrainManager::setDiffuse(const ColourValue& diffuse) | ||||||
|     { |     { | ||||||
|         mTerrainGlobals.setCompositeMapDiffuse(diffuse); |         mTerrainGlobals->setCompositeMapDiffuse(diffuse); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     //----------------------------------------------------------------------------------------------
 |     //----------------------------------------------------------------------------------------------
 | ||||||
| 
 | 
 | ||||||
|     void TerrainManager::setAmbient(const ColourValue& ambient) |     void TerrainManager::setAmbient(const ColourValue& ambient) | ||||||
|     { |     { | ||||||
|         mTerrainGlobals.setCompositeMapAmbient(ambient); |         mTerrainGlobals->setCompositeMapAmbient(ambient); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     //----------------------------------------------------------------------------------------------
 |     //----------------------------------------------------------------------------------------------
 | ||||||
|  |  | ||||||
|  | @ -33,7 +33,7 @@ namespace MWRender{ | ||||||
|         void cellAdded(MWWorld::Ptr::CellStore* store); |         void cellAdded(MWWorld::Ptr::CellStore* store); | ||||||
|         void cellRemoved(MWWorld::Ptr::CellStore* store); |         void cellRemoved(MWWorld::Ptr::CellStore* store); | ||||||
|     private: |     private: | ||||||
|         Ogre::TerrainGlobalOptions mTerrainGlobals; |         Ogre::TerrainGlobalOptions* mTerrainGlobals; | ||||||
|         Ogre::TerrainGroup mTerrainGroup; |         Ogre::TerrainGroup mTerrainGroup; | ||||||
| 
 | 
 | ||||||
|         RenderingManager* mRendering; |         RenderingManager* mRendering; | ||||||
|  |  | ||||||
|  | @ -167,7 +167,7 @@ namespace Ogre | ||||||
| 			class ShaderHelper : public TerrainAlloc | 			class ShaderHelper : public TerrainAlloc | ||||||
| 			{ | 			{ | ||||||
| 			public: | 			public: | ||||||
| 				ShaderHelper() {} | 				ShaderHelper() : mShadowSamplerStartHi(0), mShadowSamplerStartLo(0) {} | ||||||
| 				virtual ~ShaderHelper() {} | 				virtual ~ShaderHelper() {} | ||||||
| 				virtual HighLevelGpuProgramPtr generateVertexProgram(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt); | 				virtual HighLevelGpuProgramPtr generateVertexProgram(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt); | ||||||
| 				virtual HighLevelGpuProgramPtr generateFragmentProgram(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt); | 				virtual HighLevelGpuProgramPtr generateFragmentProgram(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt); | ||||||
|  |  | ||||||
|  | @ -1,5 +1,5 @@ | ||||||
| #include "water.hpp" | #include "water.hpp" | ||||||
| #include <components/settings/settings.hpp> | 
 | ||||||
| #include "sky.hpp" | #include "sky.hpp" | ||||||
| #include "renderingmanager.hpp" | #include "renderingmanager.hpp" | ||||||
| #include "compositors.hpp" | #include "compositors.hpp" | ||||||
|  | @ -10,7 +10,7 @@ namespace MWRender | ||||||
| { | { | ||||||
| 
 | 
 | ||||||
| Water::Water (Ogre::Camera *camera, RenderingManager* rend, const ESM::Cell* cell) : | Water::Water (Ogre::Camera *camera, RenderingManager* rend, const ESM::Cell* cell) : | ||||||
|     mCamera (camera), mViewport (camera->getViewport()), mSceneManager (camera->getSceneManager()), |     mCamera (camera), mSceneManager (camera->getSceneManager()), | ||||||
|     mIsUnderwater(false), mVisibilityFlags(0), |     mIsUnderwater(false), mVisibilityFlags(0), | ||||||
|     mReflectionTarget(0), mActive(1), mToggled(1), |     mReflectionTarget(0), mActive(1), mToggled(1), | ||||||
|     mReflectionRenderActive(false), mRendering(rend) |     mReflectionRenderActive(false), mRendering(rend) | ||||||
|  | @ -30,13 +30,6 @@ Water::Water (Ogre::Camera *camera, RenderingManager* rend, const ESM::Cell* cel | ||||||
|     mWater->setRenderQueueGroup(RQG_Water); |     mWater->setRenderQueueGroup(RQG_Water); | ||||||
|     mWater->setCastShadows(false); |     mWater->setCastShadows(false); | ||||||
| 
 | 
 | ||||||
|     mVisibilityFlags = RV_Terrain * Settings::Manager::getBool("reflect terrain", "Water") |  | ||||||
|                         + RV_Statics * Settings::Manager::getBool("reflect statics", "Water") |  | ||||||
|                         + RV_StaticsSmall * Settings::Manager::getBool("reflect small statics", "Water") |  | ||||||
|                         + RV_Actors * Settings::Manager::getBool("reflect actors", "Water") |  | ||||||
|                         + RV_Misc * Settings::Manager::getBool("reflect misc", "Water") |  | ||||||
|                         + RV_Sky; |  | ||||||
| 
 |  | ||||||
|     mWaterNode = mSceneManager->getRootSceneNode()->createChildSceneNode(); |     mWaterNode = mSceneManager->getRootSceneNode()->createChildSceneNode(); | ||||||
|     mWaterNode->setPosition(0, mTop, 0); |     mWaterNode->setPosition(0, mTop, 0); | ||||||
| 
 | 
 | ||||||
|  | @ -48,30 +41,9 @@ Water::Water (Ogre::Camera *camera, RenderingManager* rend, const ESM::Cell* cel | ||||||
|     } |     } | ||||||
|     mWaterNode->attachObject(mWater); |     mWaterNode->attachObject(mWater); | ||||||
| 
 | 
 | ||||||
|     // Create rendertarget for reflection
 |     applyRTT(); | ||||||
|     int rttsize = Settings::Manager::getInt("rtt size", "Water"); |     applyVisibilityMask(); | ||||||
| 
 | 
 | ||||||
|     TexturePtr tex; |  | ||||||
|     if (Settings::Manager::getBool("shader", "Water")) |  | ||||||
|     { |  | ||||||
|         tex = TextureManager::getSingleton().createManual("WaterReflection", |  | ||||||
|             ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, TEX_TYPE_2D, rttsize, rttsize, 0, PF_FLOAT16_RGBA, TU_RENDERTARGET); |  | ||||||
| 
 |  | ||||||
|         RenderTarget* rtt = tex->getBuffer()->getRenderTarget(); |  | ||||||
|         Viewport* vp = rtt->addViewport(mReflectionCamera); |  | ||||||
|         vp->setOverlaysEnabled(false); |  | ||||||
|         vp->setBackgroundColour(ColourValue(0.8f, 0.9f, 1.0f)); |  | ||||||
|         vp->setShadowsEnabled(false); |  | ||||||
|         vp->setVisibilityMask( mVisibilityFlags ); |  | ||||||
|         // use fallback techniques without shadows and without mrt (currently not implemented for sky and terrain)
 |  | ||||||
|         //vp->setMaterialScheme("Fallback");
 |  | ||||||
|         rtt->addListener(this); |  | ||||||
|         rtt->setActive(true); |  | ||||||
| 
 |  | ||||||
|         mReflectionTarget = rtt; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     mCompositorName = RenderingManager::useMRT() ? "Underwater" : "UnderwaterNoMRT"; |  | ||||||
| 
 | 
 | ||||||
|     createMaterial(); |     createMaterial(); | ||||||
|     mWater->setMaterial(mMaterial); |     mWater->setMaterial(mMaterial); | ||||||
|  | @ -80,6 +52,8 @@ Water::Water (Ogre::Camera *camera, RenderingManager* rend, const ESM::Cell* cel | ||||||
| 
 | 
 | ||||||
|     mSceneManager->addRenderQueueListener(this); |     mSceneManager->addRenderQueueListener(this); | ||||||
| 
 | 
 | ||||||
|  |     assignTextures(); | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
|     // ----------------------------------------------------------------------------------------------
 |     // ----------------------------------------------------------------------------------------------
 | ||||||
|     // ---------------------------------- reflection debug overlay ----------------------------------
 |     // ---------------------------------- reflection debug overlay ----------------------------------
 | ||||||
|  | @ -140,6 +114,9 @@ Water::~Water() | ||||||
| { | { | ||||||
|     MeshManager::getSingleton().remove("water"); |     MeshManager::getSingleton().remove("water"); | ||||||
| 
 | 
 | ||||||
|  |     if (mReflectionTarget) | ||||||
|  |         mReflectionTexture->getBuffer()->getRenderTarget()->removeListener(this); | ||||||
|  | 
 | ||||||
|     mWaterNode->detachObject(mWater); |     mWaterNode->detachObject(mWater); | ||||||
|     mSceneManager->destroyEntity(mWater); |     mSceneManager->destroyEntity(mWater); | ||||||
|     mSceneManager->destroySceneNode(mWaterNode); |     mSceneManager->destroySceneNode(mWaterNode); | ||||||
|  | @ -249,7 +226,15 @@ void Water::postRenderTargetUpdate(const RenderTargetEvent& evt) | ||||||
| 
 | 
 | ||||||
| void Water::createMaterial() | void Water::createMaterial() | ||||||
| { | { | ||||||
|     mMaterial = MaterialManager::getSingleton().getByName("Water"); |     if (mReflectionTarget == 0) | ||||||
|  |     { | ||||||
|  |         mMaterial = MaterialManager::getSingleton().getByName("Water_Fallback"); | ||||||
|  |     } | ||||||
|  |     else | ||||||
|  |     { | ||||||
|  |         mMaterial = MaterialManager::getSingleton().getByName("Water"); | ||||||
|  |         mMaterial->getTechnique(0)->getPass(0)->getTextureUnitState(0)->setTexture(mReflectionTexture); | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|     // these have to be set in code
 |     // these have to be set in code
 | ||||||
|     std::string textureNames[32]; |     std::string textureNames[32]; | ||||||
|  | @ -257,15 +242,20 @@ void Water::createMaterial() | ||||||
|     { |     { | ||||||
|         textureNames[i] = "textures\\water\\water" + StringConverter::toString(i, 2, '0') + ".dds"; |         textureNames[i] = "textures\\water\\water" + StringConverter::toString(i, 2, '0') + ".dds"; | ||||||
|     } |     } | ||||||
|     mMaterial->getTechnique(1)->getPass(0)->getTextureUnitState(0)->setAnimatedTextureName(textureNames, 32, 2); |     Ogre::Technique* tech; | ||||||
| 
 |  | ||||||
|     // use technique without shaders if reflection is disabled
 |  | ||||||
|     if (mReflectionTarget == 0) |     if (mReflectionTarget == 0) | ||||||
|         mMaterial->removeTechnique(0); |         tech = mMaterial->getTechnique(0); | ||||||
|  |     else | ||||||
|  |         tech = mMaterial->getTechnique(1); | ||||||
| 
 | 
 | ||||||
|  |     tech->getPass(0)->getTextureUnitState(0)->setAnimatedTextureName(textureNames, 32, 2); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void Water::assignTextures() | ||||||
|  | { | ||||||
|     if (Settings::Manager::getBool("shader", "Water")) |     if (Settings::Manager::getBool("shader", "Water")) | ||||||
|     { |     { | ||||||
|         CompositorInstance* compositor = CompositorManager::getSingleton().getCompositorChain(mViewport)->getCompositor("gbuffer"); |         CompositorInstance* compositor = CompositorManager::getSingleton().getCompositorChain(mRendering->getViewport())->getCompositor("gbuffer"); | ||||||
| 
 | 
 | ||||||
|         TexturePtr colorTexture = compositor->getTextureInstance("mrt_output", 0); |         TexturePtr colorTexture = compositor->getTextureInstance("mrt_output", 0); | ||||||
|         TextureUnitState* tus = mMaterial->getTechnique(0)->getPass(0)->getTextureUnitState("refractionMap"); |         TextureUnitState* tus = mMaterial->getTechnique(0)->getPass(0)->getTextureUnitState("refractionMap"); | ||||||
|  | @ -315,4 +305,84 @@ void Water::update() | ||||||
| { | { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void Water::applyRTT() | ||||||
|  | { | ||||||
|  |     if (mReflectionTarget) | ||||||
|  |     { | ||||||
|  |         TextureManager::getSingleton().remove("WaterReflection"); | ||||||
|  |         mReflectionTarget = 0; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     // Create rendertarget for reflection
 | ||||||
|  |     int rttsize = Settings::Manager::getInt("rtt size", "Water"); | ||||||
|  | 
 | ||||||
|  |     if (Settings::Manager::getBool("shader", "Water")) | ||||||
|  |     { | ||||||
|  |         mReflectionTexture = TextureManager::getSingleton().createManual("WaterReflection", | ||||||
|  |             ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, TEX_TYPE_2D, rttsize, rttsize, 0, PF_FLOAT16_RGBA, TU_RENDERTARGET); | ||||||
|  | 
 | ||||||
|  |         RenderTarget* rtt = mReflectionTexture->getBuffer()->getRenderTarget(); | ||||||
|  |         Viewport* vp = rtt->addViewport(mReflectionCamera); | ||||||
|  |         vp->setOverlaysEnabled(false); | ||||||
|  |         vp->setBackgroundColour(ColourValue(0.8f, 0.9f, 1.0f)); | ||||||
|  |         vp->setShadowsEnabled(false); | ||||||
|  |         // use fallback techniques without shadows and without mrt (currently not implemented for sky and terrain)
 | ||||||
|  |         //vp->setMaterialScheme("Fallback");
 | ||||||
|  |         rtt->addListener(this); | ||||||
|  |         rtt->setActive(true); | ||||||
|  | 
 | ||||||
|  |         mReflectionTarget = rtt; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     mCompositorName = RenderingManager::useMRT() ? "Underwater" : "UnderwaterNoMRT"; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void Water::applyVisibilityMask() | ||||||
|  | { | ||||||
|  |     mVisibilityFlags = RV_Terrain * Settings::Manager::getBool("reflect terrain", "Water") | ||||||
|  |                         + RV_Statics * Settings::Manager::getBool("reflect statics", "Water") | ||||||
|  |                         + RV_StaticsSmall * Settings::Manager::getBool("reflect small statics", "Water") | ||||||
|  |                         + RV_Actors * Settings::Manager::getBool("reflect actors", "Water") | ||||||
|  |                         + RV_Misc * Settings::Manager::getBool("reflect misc", "Water") | ||||||
|  |                         + RV_Sky; | ||||||
|  | 
 | ||||||
|  |     if (mReflectionTarget) | ||||||
|  |     { | ||||||
|  |         mReflectionTexture->getBuffer()->getRenderTarget()->getViewport(0)->setVisibilityMask(mVisibilityFlags); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void Water::processChangedSettings(const Settings::CategorySettingVector& settings) | ||||||
|  | { | ||||||
|  |     bool applyRT = false; | ||||||
|  |     bool applyVisMask = false; | ||||||
|  |     for (Settings::CategorySettingVector::const_iterator it=settings.begin(); | ||||||
|  |             it != settings.end(); ++it) | ||||||
|  |     { | ||||||
|  |         if ( it->first == "Water" && ( | ||||||
|  |                it->second == "shader" | ||||||
|  |             || it->second == "rtt size")) | ||||||
|  |             applyRT = true; | ||||||
|  | 
 | ||||||
|  |         if ( it->first == "Water" && ( | ||||||
|  |                it->second == "reflect actors" | ||||||
|  |             || it->second == "reflect terrain" | ||||||
|  |             || it->second == "reflect misc" | ||||||
|  |             || it->second == "reflect small statics" | ||||||
|  |             || it->second == "reflect statics")) | ||||||
|  |             applyVisMask = true; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if(applyRT) | ||||||
|  |     { | ||||||
|  |         applyRTT(); | ||||||
|  |         applyVisibilityMask(); | ||||||
|  |         createMaterial(); | ||||||
|  |         mWater->setMaterial(mMaterial); | ||||||
|  |         assignTextures(); | ||||||
|  |     } | ||||||
|  |     if (applyVisMask) | ||||||
|  |         applyVisibilityMask(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| } // namespace
 | } // namespace
 | ||||||
|  |  | ||||||
|  | @ -3,9 +3,11 @@ | ||||||
| 
 | 
 | ||||||
| #include <Ogre.h> | #include <Ogre.h> | ||||||
| #include <components/esm/loadcell.hpp> | #include <components/esm/loadcell.hpp> | ||||||
|  | #include <components/settings/settings.hpp> | ||||||
| 
 | 
 | ||||||
| #include "renderconst.hpp" | #include "renderconst.hpp" | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
| namespace MWRender { | namespace MWRender { | ||||||
| 
 | 
 | ||||||
|     class SkyManager; |     class SkyManager; | ||||||
|  | @ -17,7 +19,6 @@ namespace MWRender { | ||||||
|         static const int CELL_SIZE = 8192; |         static const int CELL_SIZE = 8192; | ||||||
|         Ogre::Camera *mCamera; |         Ogre::Camera *mCamera; | ||||||
|         Ogre::SceneManager *mSceneManager; |         Ogre::SceneManager *mSceneManager; | ||||||
|         Ogre::Viewport *mViewport; |  | ||||||
| 
 | 
 | ||||||
|         Ogre::Plane mWaterPlane; |         Ogre::Plane mWaterPlane; | ||||||
|         Ogre::SceneNode *mWaterNode; |         Ogre::SceneNode *mWaterNode; | ||||||
|  | @ -39,6 +40,9 @@ namespace MWRender { | ||||||
|         void renderQueueStarted (Ogre::uint8 queueGroupId, const Ogre::String &invocation, bool &skipThisInvocation); |         void renderQueueStarted (Ogre::uint8 queueGroupId, const Ogre::String &invocation, bool &skipThisInvocation); | ||||||
|         void renderQueueEnded (Ogre::uint8 queueGroupId, const Ogre::String &invocation, bool &repeatThisInvocation); |         void renderQueueEnded (Ogre::uint8 queueGroupId, const Ogre::String &invocation, bool &repeatThisInvocation); | ||||||
| 
 | 
 | ||||||
|  |         void applyRTT(); | ||||||
|  |         void applyVisibilityMask(); | ||||||
|  | 
 | ||||||
|         void updateVisible(); |         void updateVisible(); | ||||||
| 
 | 
 | ||||||
|         RenderingManager* mRendering; |         RenderingManager* mRendering; | ||||||
|  | @ -51,6 +55,7 @@ namespace MWRender { | ||||||
| 
 | 
 | ||||||
|         Ogre::Camera* mReflectionCamera; |         Ogre::Camera* mReflectionCamera; | ||||||
| 
 | 
 | ||||||
|  |         Ogre::TexturePtr mReflectionTexture; | ||||||
|         Ogre::RenderTarget* mReflectionTarget; |         Ogre::RenderTarget* mReflectionTarget; | ||||||
| 
 | 
 | ||||||
|         bool mUnderwaterEffect; |         bool mUnderwaterEffect; | ||||||
|  | @ -65,8 +70,12 @@ namespace MWRender { | ||||||
|         void toggle(); |         void toggle(); | ||||||
|         void update(); |         void update(); | ||||||
| 
 | 
 | ||||||
|  |         void assignTextures(); | ||||||
|  | 
 | ||||||
|         void setViewportBackground(const Ogre::ColourValue& bg); |         void setViewportBackground(const Ogre::ColourValue& bg); | ||||||
| 
 | 
 | ||||||
|  |         void processChangedSettings(const Settings::CategorySettingVector& settings); | ||||||
|  | 
 | ||||||
|         void checkUnderwater(float y); |         void checkUnderwater(float y); | ||||||
|         void changeCell(const ESM::Cell* cell); |         void changeCell(const ESM::Cell* cell); | ||||||
|         void setHeight(const float height); |         void setHeight(const float height); | ||||||
|  |  | ||||||
|  | @ -146,4 +146,5 @@ op 0x200014f: ForceGreeting | ||||||
| op 0x2000150: ForceGreeting, explicit reference | op 0x2000150: ForceGreeting, explicit reference | ||||||
| op 0x2000151: ToggleFullHelp | op 0x2000151: ToggleFullHelp | ||||||
| op 0x2000152: Goodbye | op 0x2000152: Goodbye | ||||||
|  | op 0x2000153: DontSaveObject (left unimplemented) | ||||||
| opcodes 0x2000154-0x3ffffff unused | opcodes 0x2000154-0x3ffffff unused | ||||||
|  |  | ||||||
|  | @ -44,7 +44,7 @@ namespace MWScript | ||||||
| 
 | 
 | ||||||
|                 virtual void execute (Interpreter::Runtime& runtime) |                 virtual void execute (Interpreter::Runtime& runtime) | ||||||
|                 { |                 { | ||||||
|                     MWBase::Environment::get().getInputManager()->setGuiMode(mDialogue); |                     MWBase::Environment::get().getWindowManager()->pushGuiMode(mDialogue); | ||||||
|                 } |                 } | ||||||
|         }; |         }; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -194,6 +194,17 @@ namespace MWScript | ||||||
|                 } |                 } | ||||||
|         }; |         }; | ||||||
| 
 | 
 | ||||||
|  |         class OpDontSaveObject : public Interpreter::Opcode0 | ||||||
|  |         { | ||||||
|  |             public: | ||||||
|  | 
 | ||||||
|  |                 virtual void execute (Interpreter::Runtime& runtime) | ||||||
|  |                 { | ||||||
|  |                     // We are ignoring the DontSaveObject statement for now. Probably not worth
 | ||||||
|  |                     /// bothering with. The incompatibility we are creating should be marginal at most.
 | ||||||
|  |                 } | ||||||
|  |         }; | ||||||
|  | 
 | ||||||
|         const int opcodeXBox = 0x200000c; |         const int opcodeXBox = 0x200000c; | ||||||
|         const int opcodeOnActivate = 0x200000d; |         const int opcodeOnActivate = 0x200000d; | ||||||
|         const int opcodeActivate = 0x2000075; |         const int opcodeActivate = 0x2000075; | ||||||
|  | @ -208,6 +219,7 @@ namespace MWScript | ||||||
|         const int opcodeFadeTo = 0x200013e; |         const int opcodeFadeTo = 0x200013e; | ||||||
|         const int opcodeToggleWater = 0x2000144; |         const int opcodeToggleWater = 0x2000144; | ||||||
|         const int opcodeTogglePathgrid = 0x2000146; |         const int opcodeTogglePathgrid = 0x2000146; | ||||||
|  |         const int opcodeDontSaveObject = 0x2000153; | ||||||
| 
 | 
 | ||||||
|         void registerExtensions (Compiler::Extensions& extensions) |         void registerExtensions (Compiler::Extensions& extensions) | ||||||
|         { |         { | ||||||
|  | @ -229,6 +241,7 @@ namespace MWScript | ||||||
|             extensions.registerInstruction ("twa", "", opcodeToggleWater); |             extensions.registerInstruction ("twa", "", opcodeToggleWater); | ||||||
|             extensions.registerInstruction ("togglepathgrid", "", opcodeTogglePathgrid); |             extensions.registerInstruction ("togglepathgrid", "", opcodeTogglePathgrid); | ||||||
|             extensions.registerInstruction ("tpg", "", opcodeTogglePathgrid); |             extensions.registerInstruction ("tpg", "", opcodeTogglePathgrid); | ||||||
|  |             extensions.registerInstruction ("dontsaveobject", "", opcodeDontSaveObject); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         void installOpcodes (Interpreter::Interpreter& interpreter) |         void installOpcodes (Interpreter::Interpreter& interpreter) | ||||||
|  | @ -247,6 +260,7 @@ namespace MWScript | ||||||
|             interpreter.installSegment5 (opcodeFadeTo, new OpFadeTo); |             interpreter.installSegment5 (opcodeFadeTo, new OpFadeTo); | ||||||
|             interpreter.installSegment5 (opcodeTogglePathgrid, new OpTogglePathgrid); |             interpreter.installSegment5 (opcodeTogglePathgrid, new OpTogglePathgrid); | ||||||
|             interpreter.installSegment5 (opcodeToggleWater, new OpToggleWater); |             interpreter.installSegment5 (opcodeToggleWater, new OpToggleWater); | ||||||
|  |             interpreter.installSegment5 (opcodeDontSaveObject, new OpDontSaveObject); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -46,7 +46,7 @@ namespace MWSound | ||||||
|     public: |     public: | ||||||
|         virtual ~Sound_Output() { } |         virtual ~Sound_Output() { } | ||||||
| 
 | 
 | ||||||
|         bool isInitialized() { return mInitialized; } |         bool isInitialized() const { return mInitialized; } | ||||||
| 
 | 
 | ||||||
|         friend class OpenAL_Output; |         friend class OpenAL_Output; | ||||||
|         friend class SoundManager; |         friend class SoundManager; | ||||||
|  |  | ||||||
|  | @ -7,7 +7,6 @@ | ||||||
| #include <OgreRoot.h> | #include <OgreRoot.h> | ||||||
| 
 | 
 | ||||||
| #include <components/esm_store/store.hpp> | #include <components/esm_store/store.hpp> | ||||||
| #include <components/settings/settings.hpp> |  | ||||||
| 
 | 
 | ||||||
| #include "../mwbase/environment.hpp" | #include "../mwbase/environment.hpp" | ||||||
| 
 | 
 | ||||||
|  | @ -53,6 +52,8 @@ namespace MWSound | ||||||
|         , mMasterVolume(1.0f) |         , mMasterVolume(1.0f) | ||||||
|         , mSFXVolume(1.0f) |         , mSFXVolume(1.0f) | ||||||
|         , mMusicVolume(1.0f) |         , mMusicVolume(1.0f) | ||||||
|  |         , mFootstepsVolume(1.0f) | ||||||
|  |         , mVoiceVolume(1.0f) | ||||||
|     { |     { | ||||||
|         if(!useSound) |         if(!useSound) | ||||||
|             return; |             return; | ||||||
|  | @ -63,6 +64,10 @@ namespace MWSound | ||||||
|         mSFXVolume = std::min(std::max(mSFXVolume, 0.0f), 1.0f); |         mSFXVolume = std::min(std::max(mSFXVolume, 0.0f), 1.0f); | ||||||
|         mMusicVolume = Settings::Manager::getFloat("music volume", "Sound"); |         mMusicVolume = Settings::Manager::getFloat("music volume", "Sound"); | ||||||
|         mMusicVolume = std::min(std::max(mMusicVolume, 0.0f), 1.0f); |         mMusicVolume = std::min(std::max(mMusicVolume, 0.0f), 1.0f); | ||||||
|  |         mVoiceVolume = Settings::Manager::getFloat("voice volume", "Sound"); | ||||||
|  |         mVoiceVolume = std::min(std::max(mVoiceVolume, 0.0f), 1.0f); | ||||||
|  |         mFootstepsVolume = Settings::Manager::getFloat("footsteps volume", "Sound"); | ||||||
|  |         mFootstepsVolume = std::min(std::max(mFootstepsVolume, 0.0f), 1.0f); | ||||||
| 
 | 
 | ||||||
|         std::cout << "Sound output: " << SOUND_OUT << std::endl; |         std::cout << "Sound output: " << SOUND_OUT << std::endl; | ||||||
|         std::cout << "Sound decoder: " << SOUND_IN << std::endl; |         std::cout << "Sound decoder: " << SOUND_IN << std::endl; | ||||||
|  | @ -210,7 +215,7 @@ namespace MWSound | ||||||
|         try |         try | ||||||
|         { |         { | ||||||
|             // The range values are not tested
 |             // The range values are not tested
 | ||||||
|             float basevol = mMasterVolume * mSFXVolume; |             float basevol = mMasterVolume * mVoiceVolume; | ||||||
|             std::string filePath = "Sound/"+filename; |             std::string filePath = "Sound/"+filename; | ||||||
|             const ESM::Position &pos = ptr.getCellRef().pos; |             const ESM::Position &pos = ptr.getCellRef().pos; | ||||||
|             const Ogre::Vector3 objpos(pos.pos[0], pos.pos[1], pos.pos[2]); |             const Ogre::Vector3 objpos(pos.pos[0], pos.pos[1], pos.pos[2]); | ||||||
|  | @ -234,7 +239,7 @@ namespace MWSound | ||||||
|             return; |             return; | ||||||
|         try |         try | ||||||
|         { |         { | ||||||
|             float basevol = mMasterVolume * mSFXVolume; |             float basevol = mMasterVolume * mVoiceVolume; | ||||||
|             std::string filePath = "Sound/"+filename; |             std::string filePath = "Sound/"+filename; | ||||||
| 
 | 
 | ||||||
|             SoundPtr sound = mOutput->playSound(filePath, basevol, 1.0f, Play_Normal); |             SoundPtr sound = mOutput->playSound(filePath, basevol, 1.0f, Play_Normal); | ||||||
|  | @ -527,6 +532,39 @@ namespace MWSound | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  |     void SoundManager::processChangedSettings(const Settings::CategorySettingVector& settings) | ||||||
|  |     { | ||||||
|  |         mMasterVolume = Settings::Manager::getFloat("master volume", "Sound"); | ||||||
|  |         mMusicVolume = Settings::Manager::getFloat("music volume", "Sound"); | ||||||
|  |         mSFXVolume = Settings::Manager::getFloat("sfx volume", "Sound"); | ||||||
|  |         mFootstepsVolume = Settings::Manager::getFloat("footsteps volume", "Sound"); | ||||||
|  |         mVoiceVolume = Settings::Manager::getFloat("voice volume", "Sound"); | ||||||
|  | 
 | ||||||
|  |         SoundMap::iterator snditer = mActiveSounds.begin(); | ||||||
|  |         while(snditer != mActiveSounds.end()) | ||||||
|  |         { | ||||||
|  |             if(snditer->second.second != "_say_sound") | ||||||
|  |             { | ||||||
|  |                 float basevol = mMasterVolume * mSFXVolume; | ||||||
|  |                 float min, max; | ||||||
|  |                 lookup(snditer->second.second, basevol, min, max); | ||||||
|  |                 snditer->first->mBaseVolume = basevol; | ||||||
|  |             } | ||||||
|  |             else | ||||||
|  |             { | ||||||
|  |                 float basevol = mMasterVolume * mVoiceVolume; | ||||||
|  |                 snditer->first->mBaseVolume = basevol; | ||||||
|  |             } | ||||||
|  |             snditer->first->update(); | ||||||
|  |             snditer++; | ||||||
|  |         } | ||||||
|  |         if(mMusic) | ||||||
|  |         { | ||||||
|  |             mMusic->mBaseVolume = mMasterVolume * mMusicVolume; | ||||||
|  |             mMusic->update(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     // Default readAll implementation, for decoders that can't do anything
 |     // Default readAll implementation, for decoders that can't do anything
 | ||||||
|     // better
 |     // better
 | ||||||
|     void Sound_Decoder::readAll(std::vector<char> &output) |     void Sound_Decoder::readAll(std::vector<char> &output) | ||||||
|  |  | ||||||
Some files were not shown because too many files have changed in this diff Show more
		Loading…
	
		Reference in a new issue