mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-10-30 02:56:44 +00:00 
			
		
		
		
	Merge branch 'master' of https://github.com/zinnschlag/openmw.git into objectRotationScaling
Conflicts: apps/openmw/mwscript/docs/vmformat.txt
This commit is contained in:
		
						commit
						0012d7eb58
					
				
					 154 changed files with 5661 additions and 1890 deletions
				
			
		|  | @ -15,7 +15,7 @@ include (OpenMWMacros) | |||
| # Version | ||||
| 
 | ||||
| set (OPENMW_VERSION_MAJOR 0) | ||||
| set (OPENMW_VERSION_MINOR 14) | ||||
| set (OPENMW_VERSION_MINOR 15) | ||||
| set (OPENMW_VERSION_RELEASE 0) | ||||
| 
 | ||||
| set (OPENMW_VERSION "${OPENMW_VERSION_MAJOR}.${OPENMW_VERSION_MINOR}.${OPENMW_VERSION_RELEASE}") | ||||
|  |  | |||
|  | @ -1,7 +1,11 @@ | |||
| #include "graphicspage.hpp" | ||||
| 
 | ||||
| #include <QtGui> | ||||
| 
 | ||||
| #include "graphicspage.hpp" | ||||
| #include <boost/lexical_cast.hpp> | ||||
| 
 | ||||
| #include <components/files/configurationmanager.hpp> | ||||
| #include <components/settings/settings.hpp> | ||||
| 
 | ||||
| GraphicsPage::GraphicsPage(Files::ConfigurationManager &cfg, QWidget *parent) | ||||
|     : QWidget(parent) | ||||
|  | @ -17,12 +21,9 @@ GraphicsPage::GraphicsPage(Files::ConfigurationManager &cfg, QWidget *parent) | |||
|     renderSystemLayout->addWidget(rendererLabel, 0, 0, 1, 1); | ||||
|     renderSystemLayout->addWidget(mRendererComboBox, 0, 1, 1, 1); | ||||
| 
 | ||||
|     mRendererStackedWidget = new QStackedWidget(rendererGroup); | ||||
| 
 | ||||
|     QVBoxLayout *rendererGroupLayout = new QVBoxLayout(rendererGroup); | ||||
| 
 | ||||
|     rendererGroupLayout->addLayout(renderSystemLayout); | ||||
|     rendererGroupLayout->addWidget(mRendererStackedWidget); | ||||
| 
 | ||||
|     // Display
 | ||||
|     QGroupBox *displayGroup = new QGroupBox(tr("Display"), this); | ||||
|  | @ -52,107 +53,33 @@ GraphicsPage::GraphicsPage(Files::ConfigurationManager &cfg, QWidget *parent) | |||
| 
 | ||||
| void GraphicsPage::createPages() | ||||
| { | ||||
|     // OpenGL rendering settings
 | ||||
|     QWidget *mOGLRendererPage = new QWidget(); | ||||
|     QWidget *main = new QWidget(); | ||||
|     QGridLayout *grid = new QGridLayout(main); | ||||
| 
 | ||||
|     QLabel *OGLRTTLabel = new QLabel(tr("Preferred RTT Mode:"), mOGLRendererPage); | ||||
|     mOGLRTTComboBox = new QComboBox(mOGLRendererPage); | ||||
|     mVSyncCheckBox = new QCheckBox(tr("Vertical Sync"), main); | ||||
|     grid->addWidget(mVSyncCheckBox, 0, 0, 1, 1); | ||||
| 
 | ||||
|     QLabel *OGLAntiAliasingLabel = new QLabel(tr("Antialiasing:"), mOGLRendererPage); | ||||
|     mOGLAntiAliasingComboBox = new QComboBox(mOGLRendererPage); | ||||
|     mFullScreenCheckBox = new QCheckBox(tr("Full Screen"), main); | ||||
|     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); | ||||
|     grid->addItem(vSpacer1, 4, 0, 1, 1); | ||||
| 
 | ||||
|     OGLRendererLayout->addWidget(OGLRTTLabel, 0, 0, 1, 1); | ||||
|     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); | ||||
|     mDisplayStackedWidget->addWidget(main); | ||||
| } | ||||
| 
 | ||||
| void GraphicsPage::setupConfig() | ||||
| { | ||||
|     QString ogreCfg = mCfgMgr.getOgreConfigPath().string().c_str(); | ||||
|     QFile file(ogreCfg); | ||||
|     mOgreConfig = new QSettings(ogreCfg, QSettings::IniFormat); | ||||
| } | ||||
| 
 | ||||
| void GraphicsPage::setupOgre() | ||||
|  | @ -164,32 +91,12 @@ void GraphicsPage::setupOgre() | |||
|     Ogre::LogManager* logMgr = OGRE_NEW Ogre::LogManager; | ||||
|     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 | ||||
|     { | ||||
|     #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 | ||||
|         mOgre = new Ogre::Root(pluginCfg.toStdString(), file.fileName().toStdString(), "./launcherOgre.log"); | ||||
|         mOgre = new Ogre::Root(pluginCfg.toStdString(), "", "./launcherOgre.log"); | ||||
|     #endif | ||||
|     } | ||||
|     catch(Ogre::Exception &ex) | ||||
|  | @ -228,11 +135,19 @@ void GraphicsPage::setupOgre() | |||
|         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) { | ||||
|         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
 | ||||
|     QString openGLName = mRendererComboBox->itemText(mRendererComboBox->findText(QString("OpenGL"), Qt::MatchStartsWith)); | ||||
|  | @ -255,217 +170,44 @@ void GraphicsPage::setupOgre() | |||
|     } | ||||
| 
 | ||||
|     // Now fill the GUI elements
 | ||||
|     // OpenGL
 | ||||
|     if (mOpenGLRenderSystem) { | ||||
|         mOGLRTTComboBox->addItems(getAvailableOptions(QString("RTT Preferred Mode"), mOpenGLRenderSystem)); | ||||
|         mOGLAntiAliasingComboBox->addItems(getAvailableOptions(QString("FSAA"), mOpenGLRenderSystem)); | ||||
|         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)); | ||||
|     } | ||||
|     mAntiAliasingComboBox->clear(); | ||||
|     mResolutionComboBox->clear(); | ||||
|     mAntiAliasingComboBox->addItems(getAvailableOptions(QString("FSAA"), mSelectedRenderSystem)); | ||||
|     mResolutionComboBox->addItems(getAvailableOptions(QString("Video Mode"), mSelectedRenderSystem)); | ||||
| } | ||||
| 
 | ||||
| void GraphicsPage::readConfig() | ||||
| { | ||||
|     // Read the config file settings
 | ||||
|     if (mOpenGLRenderSystem) { | ||||
|     if (Settings::Manager::getBool("vsync", "Video")) | ||||
|         mVSyncCheckBox->setCheckState(Qt::Checked); | ||||
| 
 | ||||
|         int index = mOGLRTTComboBox->findText(getConfigValue("RTT Preferred Mode", mOpenGLRenderSystem)); | ||||
|         if ( index != -1) { | ||||
|             mOGLRTTComboBox->setCurrentIndex(index); | ||||
|         } | ||||
|     if (Settings::Manager::getBool("fullscreen", "Video")) | ||||
|         mFullScreenCheckBox->setCheckState(Qt::Checked); | ||||
| 
 | ||||
|         index = mOGLAntiAliasingComboBox->findText(getConfigValue("FSAA", mOpenGLRenderSystem)); | ||||
|         if ( index != -1){ | ||||
|             mOGLAntiAliasingComboBox->setCurrentIndex(index); | ||||
|         } | ||||
|     int aaIndex = mAntiAliasingComboBox->findText(QString::fromStdString(Settings::Manager::getString("antialiasing", "Video"))); | ||||
|     if (aaIndex != -1) | ||||
|         mAntiAliasingComboBox->setCurrentIndex(aaIndex); | ||||
| 
 | ||||
|         index = mOGLResolutionComboBox->findText(getConfigValue("Video Mode", mOpenGLRenderSystem)); | ||||
|         if ( index != -1) { | ||||
|             mOGLResolutionComboBox->setCurrentIndex(index); | ||||
|         } | ||||
| 
 | ||||
|         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); | ||||
|         } | ||||
|     } | ||||
|     std::string resolution = boost::lexical_cast<std::string>(Settings::Manager::getInt("resolution x", "Video")) | ||||
|         + " x " + boost::lexical_cast<std::string>(Settings::Manager::getInt("resolution y", "Video")); | ||||
|     int resIndex = mResolutionComboBox->findText(QString::fromStdString(resolution)); | ||||
|     if (resIndex != -1) | ||||
|         mResolutionComboBox->setCurrentIndex(resIndex); | ||||
| } | ||||
| 
 | ||||
| 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) { | ||||
|         // Nvidia Performance HUD
 | ||||
|         if (mD3DNvPerfCheckBox->checkState() == Qt::Checked) { | ||||
|             mDirect3DRenderSystem->setConfigOption("Allow NVPerfHUD", "Yes"); | ||||
|         } else { | ||||
|             mDirect3DRenderSystem->setConfigOption("Allow NVPerfHUD", "No"); | ||||
|         } | ||||
| 
 | ||||
|         // 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; | ||||
|     std::string resolution = mResolutionComboBox->currentText().toStdString(); | ||||
|     // parse resolution x and y from a string like "800 x 600"
 | ||||
|     size_t xPos = resolution.find("x"); | ||||
|     int resX = boost::lexical_cast<int>(resolution.substr(0, xPos-1)); | ||||
|     int resY = boost::lexical_cast<int>(resolution.substr(xPos+2, resolution.size()-(xPos+2))); | ||||
|     Settings::Manager::setInt("resolution x", "Video", resX); | ||||
|     Settings::Manager::setInt("resolution y", "Video", resY); | ||||
| } | ||||
| 
 | ||||
| QStringList GraphicsPage::getAvailableOptions(const QString &key, Ogre::RenderSystem *renderer) | ||||
|  | @ -484,7 +226,12 @@ QStringList GraphicsPage::getAvailableOptions(const QString &key, Ogre::RenderSy | |||
|         { | ||||
| 
 | ||||
|             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) | ||||
| { | ||||
|     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()); | ||||
| 
 | ||||
|     mAntiAliasingComboBox->clear(); | ||||
|     mResolutionComboBox->clear(); | ||||
| 
 | ||||
|     mAntiAliasingComboBox->addItems(getAvailableOptions(QString("FSAA"), mSelectedRenderSystem)); | ||||
|     mResolutionComboBox->addItems(getAvailableOptions(QString("Video Mode"), mSelectedRenderSystem)); | ||||
| } | ||||
|  |  | |||
|  | @ -49,33 +49,15 @@ private: | |||
| 
 | ||||
|     QComboBox *mRendererComboBox; | ||||
| 
 | ||||
|     QStackedWidget *mRendererStackedWidget; | ||||
|     QStackedWidget *mDisplayStackedWidget; | ||||
| 
 | ||||
|     // OpenGL
 | ||||
|     QComboBox *mOGLRTTComboBox; | ||||
|     QComboBox *mOGLAntiAliasingComboBox; | ||||
|     QComboBox *mOGLResolutionComboBox; | ||||
|     QComboBox *mOGLFrequencyComboBox; | ||||
| 
 | ||||
|     QCheckBox *mOGLVSyncCheckBox; | ||||
|     QCheckBox *mOGLFullScreenCheckBox; | ||||
| 
 | ||||
|     // Direct3D
 | ||||
|     QComboBox *mD3DRenderDeviceComboBox; | ||||
|     QComboBox *mD3DAntiAliasingComboBox; | ||||
|     QComboBox *mD3DFloatingPointComboBox; | ||||
|     QComboBox *mD3DResolutionComboBox; | ||||
| 
 | ||||
|     QCheckBox *mD3DNvPerfCheckBox; | ||||
|     QCheckBox *mD3DVSyncCheckBox; | ||||
|     QCheckBox *mD3DFullScreenCheckBox; | ||||
| 
 | ||||
|     QSettings *mOgreConfig; | ||||
|     QComboBox *mAntiAliasingComboBox; | ||||
|     QComboBox *mResolutionComboBox; | ||||
|     QCheckBox *mVSyncCheckBox; | ||||
|     QCheckBox *mFullScreenCheckBox; | ||||
| 
 | ||||
|     Files::ConfigurationManager &mCfgMgr; | ||||
| 
 | ||||
|     QString getConfigValue(const QString &key, Ogre::RenderSystem *renderer); | ||||
|     QStringList getAvailableOptions(const QString &key, Ogre::RenderSystem *renderer); | ||||
| 
 | ||||
|     void createPages(); | ||||
|  |  | |||
|  | @ -7,6 +7,28 @@ | |||
| 
 | ||||
| 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->setObjectName("IconWidget"); | ||||
|     mIconWidget->setViewMode(QListView::IconMode); | ||||
|  | @ -178,6 +200,11 @@ void MainDialog::closeEvent(QCloseEvent *event) | |||
|     // Now write all config files
 | ||||
|     mDataFilesPage->writeConfig(); | ||||
|     mGraphicsPage->writeConfig(); | ||||
| 
 | ||||
|     // Save user settings
 | ||||
|     const std::string settingspath = mCfgMgr.getUserPath().string() + "/settings.cfg"; | ||||
|     mSettings.saveUser(settingspath); | ||||
| 
 | ||||
|     event->accept(); | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -4,6 +4,7 @@ | |||
| #include <QDialog> | ||||
| 
 | ||||
| #include <components/files/configurationmanager.hpp> | ||||
| #include <components/settings/settings.hpp> | ||||
| 
 | ||||
| class QListWidget; | ||||
| class QListWidgetItem; | ||||
|  | @ -41,6 +42,7 @@ private: | |||
|     DataFilesPage *mDataFilesPage; | ||||
| 
 | ||||
|     Files::ConfigurationManager mCfgMgr; | ||||
|     Settings::Manager mSettings; | ||||
| }; | ||||
| 
 | ||||
| #endif | ||||
|  |  | |||
|  | @ -16,6 +16,7 @@ source_group(game FILES ${GAME} ${GAME_HEADER}) | |||
| add_openmw_dir (mwrender | ||||
|     renderingmanager debugging sky player animation npcanimation creatureanimation actors objects | ||||
|     renderinginterface localmap occlusionquery terrain terrainmaterial water shadows shaderhelper | ||||
|     compositors | ||||
|     ) | ||||
| 
 | ||||
| add_openmw_dir (mwinput | ||||
|  | @ -26,7 +27,8 @@ add_openmw_dir (mwgui | |||
|     text_input widgets race class birth review window_manager console dialogue | ||||
|     dialogue_history window_base stats_window messagebox journalwindow charactercreation | ||||
|     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 | ||||
|  | @ -48,7 +50,7 @@ add_openmw_dir (mwworld | |||
|     refdata world physicssystem scene globals class action nullaction actionteleport | ||||
|     containerstore actiontalk actiontake manualref player cellfunctors | ||||
|     cells localscripts customdata weather inventorystore ptr actionopen actionread | ||||
|     actionequip timestamp | ||||
|     actionequip timestamp actionalchemy | ||||
|     ) | ||||
| 
 | ||||
| add_openmw_dir (mwclass | ||||
|  |  | |||
|  | @ -105,7 +105,7 @@ bool OMW::Engine::frameRenderingQueued (const Ogre::FrameEvent& evt) | |||
|                                // frame.
 | ||||
| 
 | ||||
|         // passing of time
 | ||||
|         if (MWBase::Environment::get().getWindowManager()->getMode()==MWGui::GM_Game) | ||||
|         if (!MWBase::Environment::get().getWindowManager()->isGuiMode()) | ||||
|             MWBase::Environment::get().getWorld()->advanceTime ( | ||||
|                 mEnvironment.getFrameDuration()*MWBase::Environment::get().getWorld()->getTimeScaleFactor()/3600); | ||||
| 
 | ||||
|  | @ -116,9 +116,9 @@ bool OMW::Engine::frameRenderingQueued (const Ogre::FrameEvent& evt) | |||
|         // update actors
 | ||||
|         std::vector<std::pair<std::string, Ogre::Vector3> > movement; | ||||
|         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()); | ||||
| 
 | ||||
|         // update world
 | ||||
|  | @ -268,15 +268,6 @@ void OMW::Engine::go() | |||
| 
 | ||||
|     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
 | ||||
|     Settings::Manager settings; | ||||
|     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")) | ||||
|         nifOverrides.loadTransparencyOverrides(mCfgMgr.getGlobalPath().string() + "/transparency-overrides.cfg"); | ||||
| 
 | ||||
|     mOgre->configure(!boost::filesystem::is_regular_file(mCfgMgr.getOgreConfigPath()), | ||||
|         mCfgMgr.getOgreConfigPath().string(), | ||||
|     std::string renderSystem = settings.getString("render system", "Video"); | ||||
|     if (renderSystem == "") | ||||
|     { | ||||
| #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 | ||||
|         renderSystem = "Direct3D9 Rendering Subsystem"; | ||||
| #else | ||||
|         renderSystem = "OpenGL Rendering Subsystem"; | ||||
| #endif | ||||
|     } | ||||
|     mOgre->configure( | ||||
|         mCfgMgr.getLogPath().string(), | ||||
|         mCfgMgr.getPluginsConfigPath().string(), false); | ||||
|         mCfgMgr.getPluginsConfigPath().string(), | ||||
|         renderSystem, | ||||
|         false); | ||||
| 
 | ||||
|     // This has to be added BEFORE MyGUI is initialized, as it needs
 | ||||
|     // to find core.xml here.
 | ||||
|  | @ -325,7 +326,14 @@ void OMW::Engine::go() | |||
|     addZipResource(mResDir / "mygui" / "Obliviontt.zip"); | ||||
| 
 | ||||
|     // 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(); | ||||
| 
 | ||||
|  | @ -413,7 +421,7 @@ void OMW::Engine::go() | |||
| 
 | ||||
| void OMW::Engine::activate() | ||||
| { | ||||
|     if (MWBase::Environment::get().getWindowManager()->getMode()!=MWGui::GM_Game) | ||||
|     if (MWBase::Environment::get().getWindowManager()->isGuiMode()) | ||||
|         return; | ||||
| 
 | ||||
|     std::string handle = MWBase::Environment::get().getWorld()->getFacedHandle(); | ||||
|  |  | |||
|  | @ -9,6 +9,7 @@ | |||
| 
 | ||||
| #include "../mwworld/ptr.hpp" | ||||
| #include "../mwworld/actiontake.hpp" | ||||
| #include "../mwworld/actionalchemy.hpp" | ||||
| #include "../mwworld/world.hpp" | ||||
| 
 | ||||
| #include "../mwrender/objects.hpp" | ||||
|  | @ -140,4 +141,10 @@ namespace MWClass | |||
| 
 | ||||
|         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; | ||||
|             ///< 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 = | ||||
|             ptr.get<ESM::Creature>(); | ||||
| 
 | ||||
| 
 | ||||
|         const std::string &model = ref->base->model; | ||||
|         assert (ref->base != NULL); | ||||
|         if(!model.empty()){ | ||||
|             physics.insertActorPhysics(ptr, "meshes\\" + model); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     void Creature::enable (const MWWorld::Ptr& ptr) const | ||||
|     { | ||||
|         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 | ||||
|     { | ||||
|         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 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; | ||||
|             ///< \return name (the one that is to be presented to the user; not the internal one);
 | ||||
|             /// can return an empty string.
 | ||||
|  |  | |||
|  | @ -135,6 +135,19 @@ namespace MWClass | |||
|             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; | ||||
| 
 | ||||
|         return info; | ||||
|  |  | |||
|  | @ -55,12 +55,6 @@ namespace MWClass | |||
|         if(!model.empty()){ | ||||
|             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()) | ||||
|         { | ||||
|  |  | |||
|  | @ -14,11 +14,6 @@ namespace MWClass | |||
| 
 | ||||
|             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; | ||||
|             ///< \return name (the one that is to be presented to the user; not the internal one);
 | ||||
|             /// can return an empty string.
 | ||||
|  |  | |||
|  | @ -110,44 +110,27 @@ namespace MWClass | |||
| 
 | ||||
|     void Npc::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const | ||||
|     { | ||||
| 
 | ||||
| 
 | ||||
|         renderingInterface.getActors().insertNPC(ptr, getInventoryStore(ptr)); | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     void Npc::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const | ||||
|     { | ||||
| 
 | ||||
| 
 | ||||
|         ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData> *ref = | ||||
|             ptr.get<ESM::NPC>(); | ||||
| 
 | ||||
| 
 | ||||
|         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 smodel = "meshes\\base_anim.nif"; | ||||
|         if(beast) | ||||
|             smodel = "meshes\\base_animkna.nif"; | ||||
|         physics.insertActorPhysics(ptr, smodel); | ||||
| 
 | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     void Npc::enable (const MWWorld::Ptr& ptr) const | ||||
|     { | ||||
|         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 | ||||
|     { | ||||
|         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 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; | ||||
|             ///< \return name (the one that is to be presented to the user; not the internal one);
 | ||||
|             /// 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 += 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()) { | ||||
|             text += MWGui::ToolTips::getMiscString(ref->ref.owner, "Owner"); | ||||
|  |  | |||
|  | @ -635,7 +635,7 @@ namespace MWDialogue | |||
|         actorKnownTopics.clear(); | ||||
| 
 | ||||
|         //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(); | ||||
|         win->startDialogue(actor, MWWorld::Class::get (actor).getName (actor)); | ||||
| 
 | ||||
|  | @ -843,7 +843,7 @@ namespace MWDialogue | |||
| 
 | ||||
|     void DialogueManager::goodbyeSelected() | ||||
|     { | ||||
|         MWBase::Environment::get().getInputManager()->setGuiMode(MWGui::GM_Game); | ||||
|         MWBase::Environment::get().getWindowManager()->popGuiMode(); | ||||
|     } | ||||
| 
 | ||||
|     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 "formatting.hpp" | ||||
| #include <boost/lexical_cast.hpp> | ||||
| 
 | ||||
| #include "../mwbase/environment.hpp" | ||||
| #include "../mwinput/inputmanager.hpp" | ||||
| #include "../mwsound/soundmanager.hpp" | ||||
| #include "../mwworld/actiontake.hpp" | ||||
| 
 | ||||
| #include <boost/lexical_cast.hpp> | ||||
| #include "formatting.hpp" | ||||
| #include "window_manager.hpp" | ||||
| 
 | ||||
| using namespace MWGui; | ||||
| 
 | ||||
|  | @ -91,7 +92,7 @@ void BookWindow::onCloseButtonClicked (MyGUI::Widget* _sender) | |||
|     // 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().getInputManager()->setGuiMode(MWGui::GM_Game); | ||||
|     mWindowManager.popGuiMode(); | ||||
| } | ||||
| 
 | ||||
| void BookWindow::onTakeButtonClicked (MyGUI::Widget* _sender) | ||||
|  | @ -101,7 +102,7 @@ void BookWindow::onTakeButtonClicked (MyGUI::Widget* _sender) | |||
|     MWWorld::ActionTake take(mBook); | ||||
|     take.execute(); | ||||
| 
 | ||||
|     MWBase::Environment::get().getInputManager()->setGuiMode (GM_Game); | ||||
|     mWindowManager.popGuiMode(); | ||||
| } | ||||
| 
 | ||||
| void BookWindow::onNextPageButtonClicked (MyGUI::Widget* _sender) | ||||
|  |  | |||
|  | @ -110,7 +110,6 @@ using namespace MWGui; | |||
| CharacterCreation::CharacterCreation(WindowManager* _wm) | ||||
|     : mNameDialog(0) | ||||
|     , mRaceDialog(0) | ||||
|     , mDialogueWindow(0) | ||||
|     , mClassChoiceDialog(0) | ||||
|     , mGenerateClassQuestionDialog(0) | ||||
|     , mGenerateClassResultDialog(0) | ||||
|  | @ -123,6 +122,56 @@ CharacterCreation::CharacterCreation(WindowManager* _wm) | |||
|     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) | ||||
| { | ||||
|     switch (id) | ||||
|  | @ -209,20 +258,22 @@ void CharacterCreation::spawnDialog(const char id) | |||
|             mReviewDialog->setFatigue(mPlayerFatigue); | ||||
| 
 | ||||
|             { | ||||
|                 std::map<ESM::Attribute::AttributeID, MWMechanics::Stat<int> >::iterator end = mPlayerAttributes.end(); | ||||
|                 for (std::map<ESM::Attribute::AttributeID, MWMechanics::Stat<int> >::iterator it = mPlayerAttributes.begin(); it != end; ++it) | ||||
|                 std::map<ESM::Attribute::AttributeID, MWMechanics::Stat<int> > attributes = mWM->getPlayerAttributeValues(); | ||||
|                 for (std::map<ESM::Attribute::AttributeID, MWMechanics::Stat<int> >::iterator it = attributes.begin(); | ||||
|                     it != attributes.end(); ++it) | ||||
|                 { | ||||
|                     mReviewDialog->setAttribute(it->first, it->second); | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             { | ||||
|                 std::map<ESM::Skill::SkillEnum, MWMechanics::Stat<float> >::iterator end = mPlayerSkillValues.end(); | ||||
|                 for (std::map<ESM::Skill::SkillEnum, MWMechanics::Stat<float> >::iterator it = mPlayerSkillValues.begin(); it != end; ++it) | ||||
|                 std::map<ESM::Skill::SkillEnum, MWMechanics::Stat<float> > skills = mWM->getPlayerSkillValues(); | ||||
|                 for (std::map<ESM::Skill::SkillEnum, MWMechanics::Stat<float> >::iterator it = skills.begin(); | ||||
|                     it != skills.end(); ++it) | ||||
|                 { | ||||
|                     mReviewDialog->setSkillValue(it->first, it->second); | ||||
|                 } | ||||
|                 mReviewDialog->configureSkills(mPlayerMajorSkills, mPlayerMinorSkills); | ||||
|                 mReviewDialog->configureSkills(mWM->getPlayerMajorSkills(), mWM->getPlayerMinorSkills()); | ||||
|             } | ||||
| 
 | ||||
|             mReviewDialog->eventDone += MyGUI::newDelegate(this, &CharacterCreation::onReviewDialogDone); | ||||
|  | @ -253,7 +304,7 @@ void CharacterCreation::onReviewDialogDone(WindowBase* parWindow) | |||
|     if (mReviewDialog) | ||||
|         mWM->removeDialog(mReviewDialog); | ||||
| 
 | ||||
|     mWM->setGuiMode(GM_Game); | ||||
|     mWM->popGuiMode(); | ||||
| } | ||||
| 
 | ||||
| void CharacterCreation::onReviewDialogBack() | ||||
|  | @ -261,7 +312,7 @@ void CharacterCreation::onReviewDialogBack() | |||
|     if (mReviewDialog) | ||||
|         mWM->removeDialog(mReviewDialog); | ||||
| 
 | ||||
|     mWM->setGuiMode(GM_Birth); | ||||
|     mWM->pushGuiMode(GM_Birth); | ||||
| } | ||||
| 
 | ||||
| void CharacterCreation::onReviewActivateDialog(int parDialog) | ||||
|  | @ -270,19 +321,21 @@ void CharacterCreation::onReviewActivateDialog(int parDialog) | |||
|         mWM->removeDialog(mReviewDialog); | ||||
|     mCreationStage = CSE_ReviewNext; | ||||
| 
 | ||||
|     mWM->popGuiMode(); | ||||
| 
 | ||||
|     switch(parDialog) | ||||
|     { | ||||
|         case ReviewDialog::NAME_DIALOG: | ||||
|             mWM->setGuiMode(GM_Name); | ||||
|             mWM->pushGuiMode(GM_Name); | ||||
|             break; | ||||
|         case ReviewDialog::RACE_DIALOG: | ||||
|             mWM->setGuiMode(GM_Race); | ||||
|             mWM->pushGuiMode(GM_Race); | ||||
|             break; | ||||
|         case ReviewDialog::CLASS_DIALOG: | ||||
|             mWM->setGuiMode(GM_Class); | ||||
|             mWM->pushGuiMode(GM_Class); | ||||
|             break; | ||||
|         case ReviewDialog::BIRTHSIGN_DIALOG: | ||||
|             mWM->setGuiMode(GM_Birth); | ||||
|             mWM->pushGuiMode(GM_Birth); | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
|  | @ -304,13 +357,19 @@ void CharacterCreation::onPickClassDialogDone(WindowBase* parWindow) | |||
| 
 | ||||
|     //TODO This bit gets repeated a few times; wrap it in a function
 | ||||
|     if (mCreationStage == CSE_ReviewNext) | ||||
|         mWM->setGuiMode(GM_Review); | ||||
|     { | ||||
|         mWM->popGuiMode(); | ||||
|         mWM->pushGuiMode(GM_Review); | ||||
|     } | ||||
|     else if (mCreationStage >= CSE_ClassChosen) | ||||
|         mWM->setGuiMode(GM_Birth); | ||||
|     { | ||||
|         mWM->popGuiMode(); | ||||
|         mWM->pushGuiMode(GM_Birth); | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         mCreationStage = CSE_ClassChosen; | ||||
|         mWM->setGuiMode(GM_Game); | ||||
|         mWM->popGuiMode(); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | @ -324,7 +383,8 @@ void CharacterCreation::onPickClassDialogBack() | |||
|         mWM->removeDialog(mPickClassDialog); | ||||
|     } | ||||
| 
 | ||||
|     mWM->setGuiMode(GM_Class); | ||||
|     mWM->popGuiMode(); | ||||
|     mWM->pushGuiMode(GM_Class); | ||||
| } | ||||
| 
 | ||||
| void CharacterCreation::onClassChoice(int _index) | ||||
|  | @ -334,19 +394,21 @@ void CharacterCreation::onClassChoice(int _index) | |||
|         mWM->removeDialog(mClassChoiceDialog); | ||||
|     } | ||||
| 
 | ||||
|     mWM->popGuiMode(); | ||||
| 
 | ||||
|     switch(_index) | ||||
|     { | ||||
|         case ClassChoiceDialog::Class_Generate: | ||||
|             mWM->setGuiMode(GM_ClassGenerate); | ||||
|             mWM->pushGuiMode(GM_ClassGenerate); | ||||
|             break; | ||||
|         case ClassChoiceDialog::Class_Pick: | ||||
|             mWM->setGuiMode(GM_ClassPick); | ||||
|             mWM->pushGuiMode(GM_ClassPick); | ||||
|             break; | ||||
|         case ClassChoiceDialog::Class_Create: | ||||
|             mWM->setGuiMode(GM_ClassCreate); | ||||
|             mWM->pushGuiMode(GM_ClassCreate); | ||||
|             break; | ||||
|         case ClassChoiceDialog::Class_Back: | ||||
|             mWM->setGuiMode(GM_Race); | ||||
|             mWM->pushGuiMode(GM_Race); | ||||
|             break; | ||||
| 
 | ||||
|     }; | ||||
|  | @ -363,13 +425,19 @@ void CharacterCreation::onNameDialogDone(WindowBase* parWindow) | |||
|     } | ||||
| 
 | ||||
|     if (mCreationStage == CSE_ReviewNext) | ||||
|         mWM->setGuiMode(GM_Review); | ||||
|     { | ||||
|         mWM->popGuiMode(); | ||||
|         mWM->pushGuiMode(GM_Review); | ||||
|     } | ||||
|     else if (mCreationStage >= CSE_NameChosen) | ||||
|         mWM->setGuiMode(GM_Race); | ||||
|     { | ||||
|         mWM->popGuiMode(); | ||||
|         mWM->pushGuiMode(GM_Race); | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         mCreationStage = CSE_NameChosen; | ||||
|         mWM->setGuiMode(GM_Game); | ||||
|         mWM->popGuiMode(); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | @ -383,7 +451,8 @@ void CharacterCreation::onRaceDialogBack() | |||
|         mWM->removeDialog(mRaceDialog); | ||||
|     } | ||||
| 
 | ||||
|     mWM->setGuiMode(GM_Name); | ||||
|     mWM->popGuiMode(); | ||||
|     mWM->pushGuiMode(GM_Name); | ||||
| } | ||||
| 
 | ||||
| void CharacterCreation::onRaceDialogDone(WindowBase* parWindow) | ||||
|  | @ -398,13 +467,19 @@ void CharacterCreation::onRaceDialogDone(WindowBase* parWindow) | |||
|     } | ||||
| 
 | ||||
|     if (mCreationStage == CSE_ReviewNext) | ||||
|         mWM->setGuiMode(GM_Review); | ||||
|     else if(mCreationStage >= CSE_RaceChosen) | ||||
|         mWM->setGuiMode(GM_Class); | ||||
|     { | ||||
|         mWM->popGuiMode(); | ||||
|         mWM->pushGuiMode(GM_Review); | ||||
|     } | ||||
|     else if (mCreationStage >= CSE_RaceChosen) | ||||
|     { | ||||
|         mWM->popGuiMode(); | ||||
|         mWM->pushGuiMode(GM_Class); | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         mCreationStage = CSE_RaceChosen; | ||||
|         mWM->setGuiMode(GM_Game); | ||||
|         mWM->popGuiMode(); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | @ -419,11 +494,14 @@ void CharacterCreation::onBirthSignDialogDone(WindowBase* parWindow) | |||
|     } | ||||
| 
 | ||||
|     if (mCreationStage >= CSE_BirthSignChosen) | ||||
|         mWM->setGuiMode(GM_Review); | ||||
|     { | ||||
|         mWM->popGuiMode(); | ||||
|         mWM->pushGuiMode(GM_Review); | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         mCreationStage = CSE_BirthSignChosen; | ||||
|         mWM->setGuiMode(GM_Game); | ||||
|         mWM->popGuiMode(); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | @ -435,7 +513,8 @@ void CharacterCreation::onBirthSignDialogBack() | |||
|         mWM->removeDialog(mBirthSignDialog); | ||||
|     } | ||||
| 
 | ||||
|     mWM->setGuiMode(GM_Class); | ||||
|     mWM->popGuiMode(); | ||||
|     mWM->pushGuiMode(GM_Class); | ||||
| } | ||||
| 
 | ||||
| void CharacterCreation::onCreateClassDialogDone(WindowBase* parWindow) | ||||
|  | @ -470,13 +549,19 @@ void CharacterCreation::onCreateClassDialogDone(WindowBase* parWindow) | |||
|     } | ||||
| 
 | ||||
|     if (mCreationStage == CSE_ReviewNext) | ||||
|         mWM->setGuiMode(GM_Review); | ||||
|     { | ||||
|         mWM->popGuiMode(); | ||||
|         mWM->pushGuiMode(GM_Review); | ||||
|     } | ||||
|     else if (mCreationStage >= CSE_ClassChosen) | ||||
|         mWM->setGuiMode(GM_Birth); | ||||
|     { | ||||
|         mWM->popGuiMode(); | ||||
|         mWM->pushGuiMode(GM_Birth); | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         mCreationStage = CSE_ClassChosen; | ||||
|         mWM->setGuiMode(GM_Game); | ||||
|         mWM->popGuiMode(); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | @ -485,7 +570,8 @@ void CharacterCreation::onCreateClassDialogBack() | |||
|     if (mCreateClassDialog) | ||||
|         mWM->removeDialog(mCreateClassDialog); | ||||
| 
 | ||||
|     mWM->setGuiMode(GM_Class); | ||||
|     mWM->popGuiMode(); | ||||
|     mWM->pushGuiMode(GM_Class); | ||||
| } | ||||
| 
 | ||||
| void CharacterCreation::onClassQuestionChosen(int _index) | ||||
|  | @ -496,7 +582,8 @@ void CharacterCreation::onClassQuestionChosen(int _index) | |||
|         mWM->removeDialog(mGenerateClassQuestionDialog); | ||||
|     if (_index < 0 || _index >= 3) | ||||
|     { | ||||
|         mWM->setGuiMode(GM_Class); | ||||
|         mWM->popGuiMode(); | ||||
|         mWM->pushGuiMode(GM_Class); | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|  | @ -581,7 +668,8 @@ void CharacterCreation::showClassQuestionDialog() | |||
| 
 | ||||
|     if (mGenerateClassStep > sGenerateClassSteps.size()) | ||||
|     { | ||||
|         mWM->setGuiMode(GM_Class); | ||||
|         mWM->popGuiMode(); | ||||
|         mWM->pushGuiMode(GM_Class); | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|  | @ -610,7 +698,8 @@ void CharacterCreation::onGenerateClassBack() | |||
|         mWM->removeDialog(mGenerateClassResultDialog); | ||||
|     MWBase::Environment::get().getMechanicsManager()->setPlayerClass(mGenerateClass); | ||||
| 
 | ||||
|     mWM->setGuiMode(GM_Class); | ||||
|     mWM->popGuiMode(); | ||||
|     mWM->pushGuiMode(GM_Class); | ||||
| } | ||||
| 
 | ||||
| void CharacterCreation::onGenerateClassDone(WindowBase* parWindow) | ||||
|  | @ -620,13 +709,19 @@ void CharacterCreation::onGenerateClassDone(WindowBase* parWindow) | |||
|     MWBase::Environment::get().getMechanicsManager()->setPlayerClass(mGenerateClass); | ||||
| 
 | ||||
|     if (mCreationStage == CSE_ReviewNext) | ||||
|         mWM->setGuiMode(GM_Review); | ||||
|     { | ||||
|         mWM->popGuiMode(); | ||||
|         mWM->pushGuiMode(GM_Review); | ||||
|     } | ||||
|     else if (mCreationStage >= CSE_ClassChosen) | ||||
|         mWM->setGuiMode(GM_Birth); | ||||
|     { | ||||
|         mWM->popGuiMode(); | ||||
|         mWM->pushGuiMode(GM_Birth); | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         mCreationStage = CSE_ClassChosen; | ||||
|         mWM->setGuiMode(GM_Game); | ||||
|         mWM->popGuiMode(); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | @ -634,7 +729,6 @@ CharacterCreation::~CharacterCreation() | |||
| { | ||||
|     delete mNameDialog; | ||||
|     delete mRaceDialog; | ||||
|     delete mDialogueWindow; | ||||
|     delete mClassChoiceDialog; | ||||
|     delete mGenerateClassQuestionDialog; | ||||
|     delete mGenerateClassResultDialog; | ||||
|  |  | |||
|  | @ -42,11 +42,15 @@ namespace MWGui | |||
| 
 | ||||
|     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: | ||||
|     //Dialogs
 | ||||
|     TextInputDialog* mNameDialog; | ||||
|     RaceDialog* mRaceDialog; | ||||
|     DialogueWindow* mDialogueWindow; | ||||
|     ClassChoiceDialog* mClassChoiceDialog; | ||||
|     InfoBoxDialog* mGenerateClassQuestionDialog; | ||||
|     GenerateClassResultDialog* mGenerateClassResultDialog; | ||||
|  | @ -62,9 +66,6 @@ namespace MWGui | |||
|     std::string mPlayerRaceId; | ||||
|     std::string mPlayerBirthSignId; | ||||
|     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> mPlayerMagicka; | ||||
|     MWMechanics::DynamicStat<int> mPlayerFatigue; | ||||
|  |  | |||
|  | @ -1,6 +1,4 @@ | |||
| #include "class.hpp" | ||||
| #include "window_manager.hpp" | ||||
| #include "components/esm_store/store.hpp" | ||||
| 
 | ||||
| #include <assert.h> | ||||
| #include <iterator> | ||||
|  | @ -8,6 +6,11 @@ | |||
| #include <boost/algorithm/string.hpp> | ||||
| #include <boost/lexical_cast.hpp> | ||||
| 
 | ||||
| #include <components/esm_store/store.hpp> | ||||
| 
 | ||||
| #include "window_manager.hpp" | ||||
| #include "tooltips.hpp" | ||||
| 
 | ||||
| #undef min | ||||
| #undef max | ||||
| 
 | ||||
|  | @ -79,17 +82,13 @@ PickClassDialog::PickClassDialog(WindowManager& parWindowManager) | |||
|     // Centre dialog
 | ||||
|     center(); | ||||
| 
 | ||||
|     setText("SpecializationT", mWindowManager.getGameSettingString("sChooseClassMenu1", "Specialization")); | ||||
|     getWidget(specializationName, "SpecializationName"); | ||||
| 
 | ||||
|     setText("FavoriteAttributesT", mWindowManager.getGameSettingString("sChooseClassMenu2", "Favorite Attributes:")); | ||||
|     getWidget(favoriteAttribute[0], "FavoriteAttribute0"); | ||||
|     getWidget(favoriteAttribute[1], "FavoriteAttribute1"); | ||||
|     favoriteAttribute[0]->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++) | ||||
|     { | ||||
|         char theIndex = '0'+i; | ||||
|  | @ -231,15 +230,21 @@ void PickClassDialog::updateStats() | |||
|         "sSpecializationMagic", | ||||
|         "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[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) | ||||
|     { | ||||
|         majorSkill[i]->setSkillNumber(klass->data.skills[i][0]); | ||||
|         minorSkill[i]->setSkillNumber(klass->data.skills[i][1]); | ||||
|         minorSkill[i]->setSkillNumber(klass->data.skills[i][0]); | ||||
|         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"); | ||||
|  | @ -387,7 +392,6 @@ CreateClassDialog::CreateClassDialog(WindowManager& parWindowManager) | |||
| 
 | ||||
|     setText("SpecializationT", mWindowManager.getGameSettingString("sChooseClassMenu1", "Specialization")); | ||||
|     getWidget(specializationName, "SpecializationName"); | ||||
|     specializationName->setCaption(mWindowManager.getGameSettingString(ESM::Class::gmstSpecializationIds[ESM::Class::Combat], "")); | ||||
|     specializationName->eventMouseButtonClick += MyGUI::newDelegate(this, &CreateClassDialog::onSpecializationClicked); | ||||
| 
 | ||||
|     setText("FavoriteAttributesT", mWindowManager.getGameSettingString("sChooseClassMenu2", "Favorite Attributes:")); | ||||
|  | @ -451,6 +455,9 @@ CreateClassDialog::CreateClassDialog(WindowManager& parWindowManager) | |||
|     minorSkill[2]->setSkillId(ESM::Skill::Spear); | ||||
|     minorSkill[3]->setSkillId(ESM::Skill::Athletics); | ||||
|     minorSkill[4]->setSkillId(ESM::Skill::Enchant); | ||||
| 
 | ||||
|     setSpecialization(0); | ||||
|     update(); | ||||
| } | ||||
| 
 | ||||
| CreateClassDialog::~CreateClassDialog() | ||||
|  | @ -461,6 +468,18 @@ CreateClassDialog::~CreateClassDialog() | |||
|     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 | ||||
| { | ||||
|     return editName->getOnlyText(); | ||||
|  | @ -499,7 +518,7 @@ std::vector<ESM::Skill::SkillEnum> CreateClassDialog::getMinorSkills() const | |||
|     std::vector<ESM::Skill::SkillEnum> v; | ||||
|     for(int i=0; i < 5; i++) | ||||
|     { | ||||
|         v.push_back(majorSkill[i]->getSkillId()); | ||||
|         v.push_back(minorSkill[i]->getSkillId()); | ||||
|     } | ||||
|     return v; | ||||
| } | ||||
|  | @ -539,14 +558,25 @@ void CreateClassDialog::open() | |||
| void CreateClassDialog::onDialogCancel() | ||||
| { | ||||
|     if (specDialog) | ||||
|         specDialog->setVisible(false); | ||||
|     { | ||||
|         mWindowManager.removeDialog(specDialog); | ||||
|         specDialog = 0; | ||||
|     } | ||||
|     if (attribDialog) | ||||
|         attribDialog->setVisible(false); | ||||
|     { | ||||
|         mWindowManager.removeDialog(attribDialog); | ||||
|         attribDialog = 0; | ||||
|     } | ||||
|     if (skillDialog) | ||||
|         skillDialog->setVisible(false); | ||||
|     { | ||||
|         mWindowManager.removeDialog(skillDialog); | ||||
|         skillDialog = 0; | ||||
|     } | ||||
|     if (descDialog) | ||||
|         descDialog->setVisible(false); | ||||
|     // TODO: Delete dialogs here
 | ||||
|     { | ||||
|         mWindowManager.removeDialog(descDialog); | ||||
|         descDialog = 0; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void CreateClassDialog::onSpecializationClicked(MyGUI::WidgetPtr _sender) | ||||
|  | @ -562,8 +592,23 @@ void CreateClassDialog::onSpecializationClicked(MyGUI::WidgetPtr _sender) | |||
| void CreateClassDialog::onSpecializationSelected() | ||||
| { | ||||
|     specializationId = specDialog->getSpecializationId(); | ||||
|     specializationName->setCaption(mWindowManager.getGameSettingString(ESM::Class::gmstSpecializationIds[specializationId], "")); | ||||
|     specDialog->setVisible(false); | ||||
|     setSpecialization(specializationId); | ||||
| 
 | ||||
|     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) | ||||
|  | @ -592,7 +637,10 @@ void CreateClassDialog::onAttributeSelected() | |||
|             favoriteAttribute0->setAttributeId(favoriteAttribute1->getAttributeId()); | ||||
|     } | ||||
|     attribute->setAttributeId(id); | ||||
|     attribDialog->setVisible(false); | ||||
|     mWindowManager.removeDialog(attribDialog); | ||||
|     attribDialog = 0; | ||||
| 
 | ||||
|     update(); | ||||
| } | ||||
| 
 | ||||
| void CreateClassDialog::onSkillClicked(Widgets::MWSkillPtr _sender) | ||||
|  | @ -625,7 +673,9 @@ void CreateClassDialog::onSkillSelected() | |||
|     } | ||||
| 
 | ||||
|     skill->setSkillId(skillDialog->getSkillId()); | ||||
|     skillDialog->setVisible(false); | ||||
|     mWindowManager.removeDialog(skillDialog); | ||||
|     skillDialog = 0; | ||||
|     update(); | ||||
| } | ||||
| 
 | ||||
| void CreateClassDialog::onDescriptionClicked(MyGUI::Widget* _sender) | ||||
|  | @ -640,6 +690,7 @@ void CreateClassDialog::onDescriptionEntered(WindowBase* parWindow) | |||
| { | ||||
|     description = descDialog->getTextInput(); | ||||
|     mWindowManager.removeDialog(descDialog); | ||||
|     descDialog = 0; | ||||
| } | ||||
| 
 | ||||
| void CreateClassDialog::onOkClicked(MyGUI::Widget* _sender) | ||||
|  | @ -665,20 +716,35 @@ SelectSpecializationDialog::SelectSpecializationDialog(WindowManager& parWindowM | |||
|     getWidget(specialization0, "Specialization0"); | ||||
|     getWidget(specialization1, "Specialization1"); | ||||
|     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); | ||||
|     specialization1->setCaption(mWindowManager.getGameSettingString(ESM::Class::gmstSpecializationIds[ESM::Class::Magic], "")); | ||||
|     specialization1->setCaption(magic); | ||||
|     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); | ||||
|     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; | ||||
|     getWidget(cancelButton, "CancelButton"); | ||||
|     cancelButton->setCaption(mWindowManager.getGameSettingString("sCancel", "")); | ||||
|     cancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SelectSpecializationDialog::onCancelClicked); | ||||
|     int buttonWidth = cancelButton->getTextSize().width + 24; | ||||
|     cancelButton->setCoord(216 - buttonWidth, 90, buttonWidth, 21); | ||||
| 
 | ||||
|     MyGUI::InputManager::getInstance().addWidgetModal(mMainWidget); | ||||
| } | ||||
| 
 | ||||
| SelectSpecializationDialog::~SelectSpecializationDialog() | ||||
| { | ||||
|     MyGUI::InputManager::getInstance().removeWidgetModal(mMainWidget); | ||||
| } | ||||
| 
 | ||||
| // widget controls
 | ||||
|  | @ -721,6 +787,7 @@ SelectAttributeDialog::SelectAttributeDialog(WindowManager& parWindowManager) | |||
|         attribute->setWindowManager(&parWindowManager); | ||||
|         attribute->setAttributeId(ESM::Attribute::attributeIds[i]); | ||||
|         attribute->eventClicked += MyGUI::newDelegate(this, &SelectAttributeDialog::onAttributeClicked); | ||||
|         ToolTips::createAttributeToolTip(attribute, attribute->getAttributeId()); | ||||
|     } | ||||
| 
 | ||||
|     MyGUI::ButtonPtr cancelButton; | ||||
|  | @ -729,6 +796,13 @@ SelectAttributeDialog::SelectAttributeDialog(WindowManager& parWindowManager) | |||
|     cancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SelectAttributeDialog::onCancelClicked); | ||||
|     int buttonWidth = cancelButton->getTextSize().width + 24; | ||||
|     cancelButton->setCoord(186 - buttonWidth, 180, buttonWidth, 21); | ||||
| 
 | ||||
|     MyGUI::InputManager::getInstance().addWidgetModal(mMainWidget); | ||||
| } | ||||
| 
 | ||||
| SelectAttributeDialog::~SelectAttributeDialog() | ||||
| { | ||||
|     MyGUI::InputManager::getInstance().removeWidgetModal(mMainWidget); | ||||
| } | ||||
| 
 | ||||
| // widget controls
 | ||||
|  | @ -810,6 +884,7 @@ SelectSkillDialog::SelectSkillDialog(WindowManager& parWindowManager) | |||
|             skills[spec][i].widget->setWindowManager(&mWindowManager); | ||||
|             skills[spec][i].widget->setSkillId(skills[spec][i].skillId); | ||||
|             skills[spec][i].widget->eventClicked += MyGUI::newDelegate(this, &SelectSkillDialog::onSkillClicked); | ||||
|             ToolTips::createSkillToolTip(skills[spec][i].widget, skills[spec][i].widget->getSkillId()); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  | @ -819,6 +894,13 @@ SelectSkillDialog::SelectSkillDialog(WindowManager& parWindowManager) | |||
|     cancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SelectSkillDialog::onCancelClicked); | ||||
|     int buttonWidth = cancelButton->getTextSize().width + 24; | ||||
|     cancelButton->setCoord(447 - buttonWidth, 218, buttonWidth, 21); | ||||
| 
 | ||||
|     MyGUI::InputManager::getInstance().addWidgetModal(mMainWidget); | ||||
| } | ||||
| 
 | ||||
| SelectSkillDialog::~SelectSkillDialog() | ||||
| { | ||||
|     MyGUI::InputManager::getInstance().removeWidgetModal(mMainWidget); | ||||
| } | ||||
| 
 | ||||
| // widget controls
 | ||||
|  | @ -853,6 +935,13 @@ DescriptionDialog::DescriptionDialog(WindowManager& parWindowManager) | |||
| 
 | ||||
|     // Make sure the edit box has focus
 | ||||
|     MyGUI::InputManager::getInstance().setKeyFocusWidget(textEdit); | ||||
| 
 | ||||
|     MyGUI::InputManager::getInstance().addWidgetModal(mMainWidget); | ||||
| } | ||||
| 
 | ||||
| DescriptionDialog::~DescriptionDialog() | ||||
| { | ||||
|     MyGUI::InputManager::getInstance().removeWidgetModal(mMainWidget); | ||||
| } | ||||
| 
 | ||||
| // widget controls
 | ||||
|  |  | |||
|  | @ -139,6 +139,7 @@ namespace MWGui | |||
|     { | ||||
|     public: | ||||
|         SelectSpecializationDialog(WindowManager& parWindowManager); | ||||
|         ~SelectSpecializationDialog(); | ||||
| 
 | ||||
|         ESM::Class::Specialization getSpecializationId() const { return specializationId; } | ||||
| 
 | ||||
|  | @ -169,6 +170,7 @@ namespace MWGui | |||
|     { | ||||
|     public: | ||||
|         SelectAttributeDialog(WindowManager& parWindowManager); | ||||
|         ~SelectAttributeDialog(); | ||||
| 
 | ||||
|         ESM::Attribute::AttributeID getAttributeId() const { return attributeId; } | ||||
|         Widgets::MWAttributePtr getAffectedWidget() const { return affectedWidget; } | ||||
|  | @ -201,6 +203,7 @@ namespace MWGui | |||
|     { | ||||
|     public: | ||||
|         SelectSkillDialog(WindowManager& parWindowManager); | ||||
|         ~SelectSkillDialog(); | ||||
| 
 | ||||
|         ESM::Skill::SkillEnum getSkillId() const { return skillId; } | ||||
|         Widgets::MWSkillPtr getAffectedWidget() const { return affectedWidget; } | ||||
|  | @ -236,6 +239,7 @@ namespace MWGui | |||
|     { | ||||
|     public: | ||||
|         DescriptionDialog(WindowManager& parWindowManager); | ||||
|         ~DescriptionDialog(); | ||||
| 
 | ||||
|         std::string getTextInput() const { return textEdit ? textEdit->getOnlyText() : ""; } | ||||
|         void setTextInput(const std::string &text) { if (textEdit) textEdit->setOnlyText(text); } | ||||
|  | @ -285,6 +289,10 @@ namespace MWGui | |||
|         void onDescriptionEntered(WindowBase* parWindow); | ||||
|         void onDialogCancel(); | ||||
| 
 | ||||
|         void setSpecialization(int id); | ||||
| 
 | ||||
|         void update(); | ||||
| 
 | ||||
|     private: | ||||
|         MyGUI::EditPtr          editName; | ||||
|         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() | ||||
|     { | ||||
|         setVisible(false); | ||||
|         setSelectedObject(MWWorld::Ptr()); | ||||
|         // Remove keyboard focus from the console input whenever the
 | ||||
|         // console is turned off
 | ||||
|         MyGUI::InputManager::getInstance().setKeyFocusWidget(NULL); | ||||
|  | @ -240,7 +241,7 @@ namespace MWGui | |||
|         { | ||||
|             try | ||||
|             { | ||||
|                 ConsoleInterpreterContext interpreterContext (*this, MWWorld::Ptr()); | ||||
|                 ConsoleInterpreterContext interpreterContext (*this, mPtr); | ||||
|                 Interpreter::Interpreter interpreter; | ||||
|                 MWScript::installOpcodes (interpreter); | ||||
|                 std::vector<Interpreter::Type_Code> code; | ||||
|  | @ -370,4 +371,23 @@ namespace MWGui | |||
|         /* All keywords match with the shortest. Append it to the output string and return it. */ | ||||
|         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}"); | ||||
|     } | ||||
| 
 | ||||
|     void Console::onReferenceUnavailable() | ||||
|     { | ||||
|         setSelectedObject(MWWorld::Ptr()); | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -16,9 +16,11 @@ | |||
| #include "../mwscript/compilercontext.hpp" | ||||
| #include "../mwscript/interpretercontext.hpp" | ||||
| 
 | ||||
| #include "referenceinterface.hpp" | ||||
| 
 | ||||
| namespace MWGui | ||||
| { | ||||
|   class Console : private OEngine::GUI::Layout, private Compiler::ErrorHandler | ||||
|   class Console : private OEngine::GUI::Layout, private Compiler::ErrorHandler, public ReferenceInterface | ||||
|   { | ||||
|     private: | ||||
| 
 | ||||
|  | @ -39,6 +41,16 @@ namespace MWGui | |||
|         /// \note The list may contain duplicates (if a name is a keyword and an identifier at the same
 | ||||
|         /// time).
 | ||||
| 
 | ||||
|     public: | ||||
| 
 | ||||
|         void setSelectedObject(const MWWorld::Ptr& object); | ||||
|         ///< Set the implicit object for script execution
 | ||||
| 
 | ||||
|     protected: | ||||
| 
 | ||||
|         virtual void onReferenceUnavailable(); | ||||
| 
 | ||||
| 
 | ||||
|     public: | ||||
|     MyGUI::EditPtr command; | ||||
|     MyGUI::EditPtr history; | ||||
|  | @ -58,6 +70,8 @@ namespace MWGui | |||
| 
 | ||||
|     void setFont(const std::string &fntName); | ||||
| 
 | ||||
|     void onResChange(int width, int height); | ||||
| 
 | ||||
|     void clearHistory(); | ||||
| 
 | ||||
|     // Print a message to the console. Messages may contain color
 | ||||
|  |  | |||
|  | @ -119,7 +119,7 @@ void ContainerBase::onSelectedItem(MyGUI::Widget* _sender) | |||
|         else | ||||
|             onContainerClicked(mContainerWidget); | ||||
|     } | ||||
|     else | ||||
|     else if (isTrading()) | ||||
|     { | ||||
|         MWWorld::Ptr object = (*_sender->getUserData<MWWorld::Ptr>()); | ||||
|         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) | ||||
|  | @ -260,16 +264,16 @@ void ContainerBase::onContainerClicked(MyGUI::Widget* _sender) | |||
|     if(mDragAndDrop->mIsOnDragAndDrop) //drop item here
 | ||||
|     { | ||||
|         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) | ||||
|         { | ||||
|             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
 | ||||
|             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) | ||||
|                 { | ||||
|                     // 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)
 | ||||
|             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.
 | ||||
|                 object.getRefData().setCount(mDragAndDrop->mDraggedCount); | ||||
|                 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) | ||||
|                 { | ||||
|                     it->getRefData().setCount(0); | ||||
|  | @ -342,8 +346,7 @@ void ContainerBase::setFilter(ContainerBase::Filter filter) | |||
| 
 | ||||
| void ContainerBase::openContainer(MWWorld::Ptr container) | ||||
| { | ||||
|     mContainer = container; | ||||
|     drawItems(); | ||||
|     mPtr = container; | ||||
| } | ||||
| 
 | ||||
| void ContainerBase::drawItems() | ||||
|  | @ -352,7 +355,7 @@ void ContainerBase::drawItems() | |||
|     { | ||||
|         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 y = 0; | ||||
|  | @ -383,6 +386,8 @@ void ContainerBase::drawItems() | |||
|                     + MWWorld::ContainerStore::Type_Lockpick + MWWorld::ContainerStore::Type_Light | ||||
|                     + MWWorld::ContainerStore::Type_Apparatus; | ||||
|     } | ||||
|     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
 | ||||
| 
 | ||||
|  | @ -465,7 +470,7 @@ void ContainerBase::drawItems() | |||
|         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\\"); | ||||
|             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)
 | ||||
|             bool isMagic = (MWWorld::Class::get(*iter).getEnchantment(*iter) != ""); | ||||
|  | @ -514,6 +519,7 @@ void ContainerBase::drawItems() | |||
|             text->setNeedMouseFocus(false); | ||||
|             text->setTextShadow(true); | ||||
|             text->setTextShadowColour(MyGUI::Colour(0,0,0)); | ||||
|             text->setCaption(getCountString(displayCount)); | ||||
| 
 | ||||
|             y += 42; | ||||
|             if (y > maxHeight) | ||||
|  | @ -522,13 +528,14 @@ void ContainerBase::drawItems() | |||
|                 y = 0; | ||||
|             } | ||||
| 
 | ||||
|             text->setCaption(getCountString(displayCount)); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     MyGUI::IntSize size = MyGUI::IntSize(std::max(mItemView->getSize().width, x+42), mItemView->getSize().height); | ||||
|     mItemView->setCanvasSize(size); | ||||
|     mContainerWidget->setSize(size); | ||||
| 
 | ||||
|     notifyContentChanged(); | ||||
| } | ||||
| 
 | ||||
| std::string ContainerBase::getCountString(const int count) | ||||
|  | @ -551,7 +558,7 @@ void ContainerBase::addBarteredItem(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();     | ||||
| 
 | ||||
|  | @ -563,7 +570,7 @@ void ContainerBase::addItem(MWWorld::Ptr item, int count) | |||
| 
 | ||||
| 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) | ||||
|     { | ||||
|  | @ -581,7 +588,7 @@ void ContainerBase::returnBoughtItems(MWWorld::ContainerStore& store) | |||
| 
 | ||||
| MWWorld::ContainerStore& ContainerBase::getContainerStore() | ||||
| { | ||||
|     MWWorld::ContainerStore& store = MWWorld::Class::get(mContainer).getContainerStore(mContainer); | ||||
|     MWWorld::ContainerStore& store = MWWorld::Class::get(mPtr).getContainerStore(mPtr); | ||||
|     return store; | ||||
| } | ||||
| 
 | ||||
|  | @ -630,13 +637,14 @@ void ContainerWindow::open(MWWorld::Ptr container) | |||
| { | ||||
|     openContainer(container); | ||||
|     setTitle(MWWorld::Class::get(container).getName(container)); | ||||
|     drawItems(); | ||||
| } | ||||
| 
 | ||||
| void ContainerWindow::onCloseButtonClicked(MyGUI::Widget* _sender) | ||||
| { | ||||
|     if(mDragAndDrop == NULL || !mDragAndDrop->mIsOnDragAndDrop) | ||||
|     { | ||||
|         MWBase::Environment::get().getWindowManager()->setGuiMode(GM_Game); | ||||
|         MWBase::Environment::get().getWindowManager()->popGuiMode(); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | @ -645,7 +653,7 @@ void ContainerWindow::onTakeAllButtonClicked(MyGUI::Widget* _sender) | |||
|     if(mDragAndDrop == NULL || !mDragAndDrop->mIsOnDragAndDrop) | ||||
|     { | ||||
|         // 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::ContainerStore& playerStore = MWWorld::Class::get(player).getContainerStore(player); | ||||
|  | @ -667,6 +675,11 @@ void ContainerWindow::onTakeAllButtonClicked(MyGUI::Widget* _sender) | |||
| 
 | ||||
|         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 | ||||
| 
 | ||||
| #include <components/esm_store/store.hpp> | ||||
| #include "../mwclass/container.hpp" | ||||
| #include <sstream> | ||||
| #include <set> | ||||
| #include <string> | ||||
| #include <utility> | ||||
| 
 | ||||
| #include "window_base.hpp" | ||||
| #include "referenceinterface.hpp" | ||||
| 
 | ||||
| #include "../mwclass/container.hpp" | ||||
| #include "../mwworld/ptr.hpp" | ||||
| #include "../mwworld/containerstore.hpp" | ||||
| #include <vector> | ||||
| 
 | ||||
| 
 | ||||
| namespace MWWorld | ||||
| { | ||||
|  | @ -43,7 +42,7 @@ namespace MWGui | |||
|         int mDraggedCount; | ||||
|     }; | ||||
| 
 | ||||
|     class ContainerBase | ||||
|     class ContainerBase : public ReferenceInterface | ||||
|     { | ||||
|     public: | ||||
|         ContainerBase(DragAndDrop* dragAndDrop); | ||||
|  | @ -55,7 +54,9 @@ namespace MWGui | |||
|             Filter_Weapon = 0x02, | ||||
|             Filter_Apparel = 0x03, | ||||
|             Filter_Magic = 0x04, | ||||
|             Filter_Misc = 0x05 | ||||
|             Filter_Misc = 0x05, | ||||
| 
 | ||||
|             Filter_Ingredients = 0x06 | ||||
|         }; | ||||
| 
 | ||||
|         enum ItemState | ||||
|  | @ -87,7 +88,6 @@ namespace MWGui | |||
|         MyGUI::Widget* mSelectedItem; | ||||
| 
 | ||||
|         DragAndDrop* mDragAndDrop; | ||||
|         MWWorld::Ptr mContainer; | ||||
| 
 | ||||
|         Filter mFilter; | ||||
| 
 | ||||
|  | @ -116,8 +116,12 @@ namespace MWGui | |||
| 
 | ||||
|         virtual bool isTrading() { return false; } | ||||
| 
 | ||||
|         virtual void onSelectedItemImpl(MWWorld::Ptr item) { ; } | ||||
| 
 | ||||
|         virtual bool ignoreEquippedItems() { return false; } | ||||
|         virtual std::vector<MWWorld::Ptr> itemsToIgnore() { return std::vector<MWWorld::Ptr>(); } | ||||
| 
 | ||||
|         virtual void notifyContentChanged() { ; } | ||||
|     }; | ||||
| 
 | ||||
|     class ContainerWindow : public ContainerBase, public WindowBase | ||||
|  | @ -136,6 +140,8 @@ namespace MWGui | |||
|         void onWindowResize(MyGUI::Window* window); | ||||
|         void onCloseButtonClicked(MyGUI::Widget* _sender); | ||||
|         void onTakeAllButtonClicked(MyGUI::Widget* _sender); | ||||
| 
 | ||||
|         virtual void onReferenceUnavailable(); | ||||
|     }; | ||||
| } | ||||
| #endif // CONTAINER_H
 | ||||
|  |  | |||
|  | @ -17,9 +17,6 @@ namespace MWGui | |||
|         getWidget(mOkButton, "OkButton"); | ||||
|         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); | ||||
|         mOkButton->eventMouseButtonClick += MyGUI::newDelegate(this, &CountDialog::onOkButtonClicked); | ||||
|         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); | ||||
| } | ||||
| 
 | ||||
| void DialogueWindow::open() | ||||
| { | ||||
|     topicsList->clear(); | ||||
|     pTopicsText.clear(); | ||||
|     history->eraseText(0,history->getTextLength()); | ||||
|     updateOptions(); | ||||
|     setVisible(true); | ||||
| } | ||||
| 
 | ||||
| void DialogueWindow::onByeClicked(MyGUI::Widget* _sender) | ||||
| { | ||||
|     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) | ||||
|     { | ||||
|         /// \todo check if the player is allowed to trade with this actor (e.g. faction rank high enough)?
 | ||||
|         mWindowManager.setGuiMode(GM_Barter); | ||||
|         mWindowManager.getTradeWindow()->startTrade(mActor); | ||||
|         mWindowManager.pushGuiMode(GM_Barter); | ||||
|         mWindowManager.getTradeWindow()->startTrade(mPtr); | ||||
|     } | ||||
| 
 | ||||
|     else | ||||
|  | @ -144,9 +135,14 @@ void DialogueWindow::onSelectTopic(std::string topic) | |||
| void DialogueWindow::startDialogue(MWWorld::Ptr actor, std::string npcName) | ||||
| { | ||||
|     mEnabled = true; | ||||
|     mActor = actor; | ||||
|     mPtr = actor; | ||||
|     topicsList->setEnabled(true); | ||||
|     setTitle(npcName); | ||||
| 
 | ||||
|     topicsList->clear(); | ||||
|     pTopicsText.clear(); | ||||
|     history->eraseText(0,history->getTextLength()); | ||||
|     updateOptions(); | ||||
| } | ||||
| 
 | ||||
| void DialogueWindow::setKeywords(std::list<std::string> keyWords) | ||||
|  | @ -264,3 +260,8 @@ void DialogueWindow::goodbye() | |||
|     topicsList->setEnabled(false); | ||||
|     mEnabled = false; | ||||
| } | ||||
| 
 | ||||
| void DialogueWindow::onReferenceUnavailable() | ||||
| { | ||||
|     mWindowManager.removeGuiMode(GM_Dialogue); | ||||
| } | ||||
|  |  | |||
|  | @ -2,6 +2,7 @@ | |||
| #define MWGUI_DIALOGE_H | ||||
| 
 | ||||
| #include "window_base.hpp" | ||||
| #include "referenceinterface.hpp" | ||||
| #include <boost/array.hpp> | ||||
| 
 | ||||
| #include "../mwworld/ptr.hpp" | ||||
|  | @ -25,13 +26,11 @@ namespace MWGui | |||
| { | ||||
|     class DialogueHistory; | ||||
| 
 | ||||
|     class DialogueWindow: public WindowBase | ||||
|     class DialogueWindow: public WindowBase, public ReferenceInterface | ||||
|     { | ||||
|     public: | ||||
|         DialogueWindow(WindowManager& parWindowManager); | ||||
| 
 | ||||
|         void open(); | ||||
| 
 | ||||
|         // Events
 | ||||
|         typedef MyGUI::delegates::CMultiDelegate0 EventHandle_Void; | ||||
| 
 | ||||
|  | @ -60,6 +59,8 @@ namespace MWGui | |||
|         void onMouseWheel(MyGUI::Widget* _sender, int _rel); | ||||
|         void onWindowResize(MyGUI::Window* _sender); | ||||
| 
 | ||||
|         virtual void onReferenceUnavailable(); | ||||
| 
 | ||||
|     private: | ||||
|         void updateOptions(); | ||||
|         /**
 | ||||
|  | @ -72,8 +73,6 @@ namespace MWGui | |||
| 
 | ||||
|         bool mEnabled; | ||||
| 
 | ||||
|         MWWorld::Ptr mActor; // actor being talked to
 | ||||
| 
 | ||||
|         DialogueHistory*     history; | ||||
|         Widgets::MWList*      topicsList; | ||||
|         MyGUI::ProgressPtr pDispositionBar; | ||||
|  |  | |||
|  | @ -12,8 +12,10 @@ | |||
| #include "../mwworld/world.hpp" | ||||
| #include "../mwworld/player.hpp" | ||||
| 
 | ||||
| #include "inventorywindow.hpp" | ||||
| #include "window_manager.hpp" | ||||
| #include "container.hpp" | ||||
| #include "console.hpp" | ||||
| 
 | ||||
| using namespace MWGui; | ||||
| 
 | ||||
|  | @ -41,35 +43,60 @@ HUD::HUD(int width, int height, int fpsLevel, DragAndDrop* dragAndDrop) | |||
|     , effectBoxBaseRight(0) | ||||
|     , minimapBoxBaseRight(0) | ||||
|     , mDragAndDrop(dragAndDrop) | ||||
|     , mCellNameTimer(0.0f) | ||||
|     , mCellNameBox(NULL) | ||||
|     , mMapVisible(true) | ||||
|     , mWeaponVisible(true) | ||||
|     , mSpellVisible(true) | ||||
|     , mWorldMouseOver(false) | ||||
| { | ||||
|     setCoord(0,0, width, height); | ||||
| 
 | ||||
|     // Energy bars
 | ||||
|     getWidget(mHealthFrame, "HealthFrame"); | ||||
|     getWidget(health, "Health"); | ||||
|     getWidget(magicka, "Magicka"); | ||||
|     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
 | ||||
|     getWidget(weapBox, "WeapBox"); | ||||
|     getWidget(weapImage, "WeapImage"); | ||||
|     getWidget(weapStatus, "WeapStatus"); | ||||
|     weapBoxBaseLeft = weapBox->getLeft(); | ||||
|     weapBox->eventMouseButtonClick += MyGUI::newDelegate(this, &HUD::onWeaponClicked); | ||||
| 
 | ||||
|     getWidget(spellBox, "SpellBox"); | ||||
|     getWidget(spellImage, "SpellImage"); | ||||
|     getWidget(spellStatus, "SpellStatus"); | ||||
|     spellBoxBaseLeft = spellBox->getLeft(); | ||||
|     spellBox->eventMouseButtonClick += MyGUI::newDelegate(this, &HUD::onMagicClicked); | ||||
| 
 | ||||
|     getWidget(effectBox, "EffectBox"); | ||||
|     getWidget(effect1, "Effect1"); | ||||
|     effectBoxBaseRight = effectBox->getRight(); | ||||
|     effectBoxBaseRight = viewSize.width - effectBox->getRight(); | ||||
|     effectBox->eventMouseButtonClick += MyGUI::newDelegate(this, &HUD::onMagicClicked); | ||||
| 
 | ||||
|     getWidget(minimapBox, "MiniMapBox"); | ||||
|     minimapBoxBaseRight = minimapBox->getRight(); | ||||
|     minimapBoxBaseRight = viewSize.width - minimapBox->getRight(); | ||||
|     minimapBox->eventMouseButtonClick += MyGUI::newDelegate(this, &HUD::onMapClicked); | ||||
|     getWidget(minimap, "MiniMap"); | ||||
|     getWidget(compass, "Compass"); | ||||
| 
 | ||||
|     getWidget(mCellNameBox, "CellName"); | ||||
|     getWidget(mWeaponSpellBox, "WeaponSpellName"); | ||||
| 
 | ||||
|     getWidget(crosshair, "Crosshair"); | ||||
| 
 | ||||
|     setFpsLevel(fpsLevel); | ||||
|  | @ -77,15 +104,9 @@ HUD::HUD(int width, int height, int fpsLevel, DragAndDrop* dragAndDrop) | |||
|     getWidget(trianglecounter, "TriangleCounter"); | ||||
|     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"); | ||||
| 
 | ||||
|     LocalMapBase::init(minimap, this); | ||||
|     LocalMapBase::init(minimap, compass, this); | ||||
| 
 | ||||
|     mMainWidget->eventMouseButtonClick += MyGUI::newDelegate(this, &HUD::onWorldClicked); | ||||
|     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) | ||||
| { | ||||
|     fpscounter = 0; | ||||
| 
 | ||||
|     MyGUI::Widget* fps; | ||||
|     getWidget(fps, "FPSBoxAdv"); | ||||
|     fps->setVisible(false); | ||||
|  | @ -116,6 +139,7 @@ void HUD::setFpsLevel(int level) | |||
| 
 | ||||
| void HUD::setFPS(float fps) | ||||
| { | ||||
|     if (fpscounter) | ||||
|         fpscounter->setCaption(boost::lexical_cast<std::string>((int)fps)); | ||||
| } | ||||
| 
 | ||||
|  | @ -129,28 +153,6 @@ void HUD::setBatchCount(size_t 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) | ||||
| { | ||||
|     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) | ||||
| { | ||||
|     int weapDx = 0, spellDx = 0; | ||||
|  | @ -228,7 +201,12 @@ void HUD::setBottomLeftVisibility(bool hmsVisible, bool weapVisible, bool spellV | |||
|         spellDx = weapDx = weapBoxBaseLeft - hmsBaseLeft; | ||||
| 
 | ||||
|     if (!weapVisible) | ||||
|         spellDx -= spellBoxBaseLeft - weapBoxBaseLeft; | ||||
|         spellDx += spellBoxBaseLeft - weapBoxBaseLeft; | ||||
| 
 | ||||
|     mWeaponVisible = weapVisible; | ||||
|     mSpellVisible = spellVisible; | ||||
|     if (!mWeaponVisible && !mSpellVisible) | ||||
|         mWeaponSpellBox->setVisible(false); | ||||
| 
 | ||||
|     health->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) | ||||
| { | ||||
|     const MyGUI::IntSize& viewSize = MyGUI::RenderManager::getInstance().getViewSize(); | ||||
| 
 | ||||
|     // effect box can have variable width -> variable left coordinate
 | ||||
|     int effectsDx = 0; | ||||
|     if (!minimapBoxVisible) | ||||
|         effectsDx = minimapBoxBaseRight - effectBoxBaseRight; | ||||
|         effectsDx = (viewSize.width - minimapBoxBaseRight) - (viewSize.width - effectBoxBaseRight); | ||||
| 
 | ||||
|     mMapVisible = 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); | ||||
| } | ||||
| 
 | ||||
|  | @ -286,6 +267,33 @@ void HUD::onWorldClicked(MyGUI::Widget* _sender) | |||
|         mDragAndDrop->mDraggedWidget = 0; | ||||
| 
 | ||||
|         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) | ||||
|     { | ||||
|         mWorldMouseOver = false; | ||||
| 
 | ||||
|         MyGUI::IntSize viewSize = MyGUI::RenderManager::getInstance().getViewSize(); | ||||
|         MyGUI::IntPoint cursorPosition = MyGUI::InputManager::getInstance().getMousePosition(); | ||||
|         float mouseX = cursorPosition.left / float(viewSize.width); | ||||
|  | @ -312,11 +322,195 @@ void HUD::onWorldMouseOver(MyGUI::Widget* _sender, int x, int y) | |||
|     else | ||||
|     { | ||||
|         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) | ||||
| { | ||||
|     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 "../mwmechanics/stat.hpp" | ||||
| #include "../mwworld/ptr.hpp" | ||||
| 
 | ||||
| namespace MWGui | ||||
| { | ||||
|  | @ -12,22 +13,30 @@ namespace MWGui | |||
|     { | ||||
|     public: | ||||
|         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 setValue (const std::string& id, const MWMechanics::DynamicStat<int>& value); | ||||
|         void setFPS(float fps); | ||||
|         void setTriangleCount(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 setBottomRightVisibility(bool effectBoxVisible, bool minimapVisible); | ||||
|         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::Widget* mHealthFrame; | ||||
|         MyGUI::Widget *weapBox, *spellBox; | ||||
|         MyGUI::ImageBox *weapImage, *spellImage; | ||||
|         MyGUI::ProgressPtr weapStatus, spellStatus; | ||||
|  | @ -36,6 +45,8 @@ namespace MWGui | |||
|         MyGUI::ScrollView* minimap; | ||||
|         MyGUI::ImageBox* compass; | ||||
|         MyGUI::ImageBox* crosshair; | ||||
|         MyGUI::TextBox* mCellNameBox; | ||||
|         MyGUI::TextBox* mWeaponSpellBox; | ||||
| 
 | ||||
|         MyGUI::WidgetPtr fpsbox; | ||||
|         MyGUI::TextBox* fpscounter; | ||||
|  | @ -50,8 +61,25 @@ namespace MWGui | |||
| 
 | ||||
|         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 onWorldMouseOver(MyGUI::Widget* _sender, int x, int y); | ||||
|         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 "../mwbase/environment.hpp" | ||||
| #include "../mwworld/manualref.hpp" | ||||
| #include "../mwworld/actiontake.hpp" | ||||
| #include "../mwsound/soundmanager.hpp" | ||||
| 
 | ||||
| #include "window_manager.hpp" | ||||
| #include "widgets.hpp" | ||||
| #include "bookwindow.hpp" | ||||
| #include "scrollwindow.hpp" | ||||
| #include "spellwindow.hpp" | ||||
| 
 | ||||
| namespace | ||||
| { | ||||
|  | @ -91,13 +94,13 @@ namespace MWGui | |||
| 
 | ||||
|         mFilterAll->setStateSelected(true); | ||||
| 
 | ||||
|         setCoord(0, 342, 600, 258); | ||||
|         setCoord(0, 342, 498, 258); | ||||
| 
 | ||||
|         MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); | ||||
|         openContainer(player); | ||||
|     } | ||||
| 
 | ||||
|     void InventoryWindow::openInventory() | ||||
|     void InventoryWindow::open() | ||||
|     { | ||||
|         updateEncumbranceBar(); | ||||
| 
 | ||||
|  | @ -155,7 +158,7 @@ namespace MWGui | |||
|             if (mDragAndDrop->mDraggedFrom != this) | ||||
|             { | ||||
|                 // 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(); | ||||
| 
 | ||||
|                 int origCount = ptr.getRefData().getCount(); | ||||
|  | @ -187,12 +190,21 @@ namespace MWGui | |||
|             mWindowManager.setDragDrop(false); | ||||
| 
 | ||||
|             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() | ||||
|     { | ||||
|         MWWorld::InventoryStore& invStore = MWWorld::Class::get(mContainer).getInventoryStore(mContainer); | ||||
|         MWWorld::InventoryStore& invStore = MWWorld::Class::get(mPtr).getInventoryStore(mPtr); | ||||
| 
 | ||||
|         std::vector<MWWorld::Ptr> items; | ||||
| 
 | ||||
|  | @ -210,7 +222,7 @@ namespace MWGui | |||
| 
 | ||||
|     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) | ||||
|         { | ||||
|  | @ -244,7 +256,7 @@ namespace MWGui | |||
| 
 | ||||
|     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(); | ||||
|                 it != invStore.end(); ++it) | ||||
|  | @ -259,4 +271,72 @@ namespace MWGui | |||
|     { | ||||
|         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::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(); | ||||
|         MWWorld::ActionTake action(object); | ||||
|         action.execute(); | ||||
|         mDragAndDrop->mIsOnDragAndDrop = true; | ||||
|         mDragAndDrop->mDraggedCount = count; | ||||
| 
 | ||||
|         std::string path = std::string("icons\\"); | ||||
|         path += MWWorld::Class::get(object).getInventoryIcon(object); | ||||
|         MyGUI::ImageBox* baseWidget = mContainerWidget->createWidget<ImageBox>("ImageBox", MyGUI::IntCoord(0, 0, 42, 42), MyGUI::Align::Default); | ||||
|         baseWidget->detachFromWidget(); | ||||
|         baseWidget->attachToWidget(mDragAndDrop->mDragAndDropWidget); | ||||
|         baseWidget->setUserData(object); | ||||
|         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: | ||||
|             InventoryWindow(WindowManager& parWindowManager,DragAndDrop* dragAndDrop); | ||||
| 
 | ||||
|             void openInventory(); | ||||
|             virtual void open(); | ||||
| 
 | ||||
|             /// start trading, disables item drag&drop
 | ||||
|             void startTrade(); | ||||
| 
 | ||||
|             void onFrame(); | ||||
| 
 | ||||
|             void pickUpObject (MWWorld::Ptr object); | ||||
| 
 | ||||
|             int getPlayerGold(); | ||||
| 
 | ||||
|         protected: | ||||
|  | @ -48,6 +50,10 @@ namespace MWGui | |||
|             virtual bool isInventory() { return true; } | ||||
|             virtual std::vector<MWWorld::Ptr> getEquippedItems(); | ||||
|             virtual void _unequipItem(MWWorld::Ptr item); | ||||
| 
 | ||||
|             virtual void onReferenceUnavailable() { ; } | ||||
| 
 | ||||
|             virtual void notifyContentChanged(); | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -11,6 +11,7 @@ LocalMapBase::LocalMapBase() | |||
|     , mInterior(false) | ||||
|     , mFogOfWar(true) | ||||
|     , mLocalMap(NULL) | ||||
|     , mMapDragAndDrop(false) | ||||
|     , mPrefix() | ||||
|     , mChanged(true) | ||||
|     , mLayout(NULL) | ||||
|  | @ -18,13 +19,41 @@ LocalMapBase::LocalMapBase() | |||
|     , mLastPositionY(0.0f) | ||||
|     , mLastDirectionX(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; | ||||
|     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) | ||||
|  | @ -47,10 +76,10 @@ void LocalMapBase::applyFogOfWar() | |||
|         { | ||||
|             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>(mCurX + (mx-1)) + "_" | ||||
|                     + boost::lexical_cast<std::string>(mCurY + (mInterior ? (my-1) : -1*(my-1))); | ||||
|             MyGUI::ImageBox* fog; | ||||
|             mLayout->getWidget(fog, name+"_fog"); | ||||
|             MyGUI::ImageBox* fog = mFogWidgets[my + 3*mx]; | ||||
|             fog->setImageTexture(mFogOfWar ? | ||||
|                 ((MyGUI::RenderManager::getInstance().getTexture(image+"_fog") != 0) ? image+"_fog" | ||||
|                 : "black.png" ) | ||||
|  | @ -66,14 +95,13 @@ void LocalMapBase::setActiveCell(const int x, const int y, bool interior) | |||
|     { | ||||
|         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)) + "_" | ||||
|                     + boost::lexical_cast<std::string>(y + (interior ? (my-1) : -1*(my-1))); | ||||
| 
 | ||||
|             MyGUI::ImageBox* box; | ||||
|             mLayout->getWidget(box, name); | ||||
|             std::string name = "Map_" + boost::lexical_cast<std::string>(mx) + "_" | ||||
|                     + boost::lexical_cast<std::string>(my); | ||||
| 
 | ||||
|             MyGUI::ImageBox* box = mMapWidgets[my + 3*mx]; | ||||
| 
 | ||||
|             if (MyGUI::RenderManager::getInstance().getTexture(image) != 0) | ||||
|                 box->setImageTexture(image); | ||||
|  | @ -86,6 +114,42 @@ void LocalMapBase::setActiveCell(const int x, const int y, bool interior) | |||
|     mCurY = y; | ||||
|     mChanged = false; | ||||
|     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"); | ||||
|     mButton->eventMouseButtonClick += MyGUI::newDelegate(this, &MapWindow::onWorldButtonClicked); | ||||
|     mButton->setCaption(mWindowManager.getGameSettingString("sWorld", "")); | ||||
|     mButton->setCaptionWithReplacing("#{sWorld}"); | ||||
|     int width = mButton->getTextSize().width + 24; | ||||
|     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->eventMouseButtonPressed += MyGUI::newDelegate(this, &MapWindow::onDragStart); | ||||
| 
 | ||||
|     LocalMapBase::init(mLocalMap, this); | ||||
|     LocalMapBase::init(mLocalMap, mPlayerArrow, this); | ||||
| } | ||||
| 
 | ||||
| void MapWindow::setCellName(const std::string& cellName) | ||||
|  | @ -119,33 +183,6 @@ void MapWindow::setCellName(const std::string& 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) | ||||
| { | ||||
|     if (_id!=MyGUI::MouseButton::Left) return; | ||||
|  | @ -172,8 +209,8 @@ void MapWindow::onWorldButtonClicked(MyGUI::Widget* _sender) | |||
|     mGlobalMap->setVisible(mGlobal); | ||||
|     mLocalMap->setVisible(!mGlobal); | ||||
| 
 | ||||
|     mButton->setCaption( mGlobal ? mWindowManager.getGameSettingString("sWorld", "") : | ||||
|             mWindowManager.getGameSettingString("sLocal", "")); | ||||
|     mButton->setCaptionWithReplacing( mGlobal ? "#{sLocal}" : | ||||
|             "#{sWorld}"); | ||||
|     int width = mButton->getTextSize().width + 24; | ||||
|     mButton->setCoord(mMainWidget->getSize().width - width - 22, mMainWidget->getSize().height - 64, width, 22); | ||||
| } | ||||
|  |  | |||
|  | @ -9,10 +9,12 @@ namespace MWGui | |||
|     { | ||||
|     public: | ||||
|         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 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(); | ||||
| 
 | ||||
|  | @ -20,14 +22,20 @@ namespace MWGui | |||
|         int mCurX, mCurY; | ||||
|         bool mInterior; | ||||
|         MyGUI::ScrollView* mLocalMap; | ||||
|         MyGUI::ImageBox* mCompass; | ||||
|         std::string mPrefix; | ||||
|         bool mChanged; | ||||
|         bool mFogOfWar; | ||||
| 
 | ||||
|         std::vector<MyGUI::ImageBox*> mMapWidgets; | ||||
|         std::vector<MyGUI::ImageBox*> mFogWidgets; | ||||
| 
 | ||||
|         void applyFogOfWar(); | ||||
| 
 | ||||
|         OEngine::GUI::Layout* mLayout; | ||||
| 
 | ||||
|         bool mMapDragAndDrop; | ||||
| 
 | ||||
|         float mLastPositionX; | ||||
|         float mLastPositionY; | ||||
|         float mLastDirectionX; | ||||
|  | @ -40,8 +48,6 @@ namespace MWGui | |||
|         MapWindow(WindowManager& parWindowManager); | ||||
|         virtual ~MapWindow(){} | ||||
| 
 | ||||
|         void setPlayerPos(const float x, const float y); | ||||
|         void setPlayerDir(const float x, const float y); | ||||
|         void setCellName(const std::string& cellName); | ||||
|    | ||||
|     private: | ||||
|  |  | |||
|  | @ -58,7 +58,7 @@ void MessageBoxManager::onFrame (float frameDuration) | |||
|     if(mInterMessageBoxe != NULL && mInterMessageBoxe->mMarkedToDelete) { | ||||
|         delete mInterMessageBoxe; | ||||
|         mInterMessageBoxe = NULL; | ||||
|         mWindowManager->setNextMode(GM_Game); | ||||
|         mWindowManager->popGuiMode(); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | @ -161,7 +161,7 @@ MessageBox::MessageBox(MessageBoxManager& parMessageBoxManager, const std::strin | |||
|     getWidget(mMessageWidget, "message"); | ||||
| 
 | ||||
|     mMessageWidget->setOverflowToTheLeft(true); | ||||
|     mMessageWidget->addText(cMessage); | ||||
|     mMessageWidget->setCaptionWithReplacing(cMessage); | ||||
| 
 | ||||
|     MyGUI::IntSize size; | ||||
|     size.width = mFixedWidth; | ||||
|  |  | |||
|  | @ -5,7 +5,7 @@ namespace MWGui | |||
| { | ||||
|   enum GuiMode | ||||
|     { | ||||
|       GM_Game,          // Game mode, only HUD
 | ||||
|       GM_Settings,      // Settings window
 | ||||
|       GM_Inventory,     // Inventory mode
 | ||||
|       GM_Container, | ||||
|       GM_MainMenu,      // Main menu mode
 | ||||
|  | @ -15,6 +15,7 @@ namespace MWGui | |||
| 
 | ||||
|       GM_Scroll,        // Read scroll
 | ||||
|       GM_Book,          // Read book
 | ||||
|       GM_Alchemy,       // Make potions
 | ||||
| 
 | ||||
|       GM_Dialogue,      // NPC interaction
 | ||||
|       GM_Barter, | ||||
|  |  | |||
|  | @ -1,7 +1,4 @@ | |||
| #include "race.hpp" | ||||
| #include "window_manager.hpp" | ||||
| #include "widgets.hpp" | ||||
| #include "components/esm_store/store.hpp" | ||||
| 
 | ||||
| #include <assert.h> | ||||
| #include <iostream> | ||||
|  | @ -10,6 +7,12 @@ | |||
| #include <boost/algorithm/string.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 Widgets; | ||||
| 
 | ||||
|  | @ -51,7 +54,7 @@ RaceDialog::RaceDialog(WindowManager& parWindowManager) | |||
|     prevButton->eventMouseButtonClick += MyGUI::newDelegate(this, &RaceDialog::onSelectPreviousFace); | ||||
|     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(nextButton, "NextHairButton"); | ||||
|     prevButton->eventMouseButtonClick += MyGUI::newDelegate(this, &RaceDialog::onSelectPreviousHair); | ||||
|  | @ -255,6 +258,8 @@ void RaceDialog::updateSkills() | |||
|         skillWidget->setWindowManager(&mWindowManager); | ||||
|         skillWidget->setSkillNumber(skillId); | ||||
|         skillWidget->setSkillValue(MWSkill::SkillValue(race->data.bonus[i].bonus)); | ||||
|         ToolTips::createSkillToolTip(skillWidget, skillId); | ||||
| 
 | ||||
| 
 | ||||
|         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->setWindowManager(&mWindowManager); | ||||
|         spellPowerWidget->setSpellId(spellpower); | ||||
|         spellPowerWidget->setUserString("ToolTipType", "Spell"); | ||||
|         spellPowerWidget->setUserString("Spell", spellpower); | ||||
| 
 | ||||
|         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 "window_manager.hpp" | ||||
| #include "widgets.hpp" | ||||
| #include "components/esm_store/store.hpp" | ||||
| 
 | ||||
| #include <cmath> | ||||
| 
 | ||||
| #include <boost/algorithm/string.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 max | ||||
|  | @ -74,7 +77,7 @@ ReviewDialog::ReviewDialog(WindowManager& parWindowManager) | |||
|     getWidget(skillAreaWidget, "Skills"); | ||||
|     getWidget(skillClientWidget, "SkillClient"); | ||||
|     getWidget(skillScrollerWidget, "SkillScroller"); | ||||
| 
 | ||||
|     skillClientWidget->eventMouseWheel += MyGUI::newDelegate(this, &ReviewDialog::onMouseWheel); | ||||
|     skillScrollerWidget->eventScrollChangePosition += MyGUI::newDelegate(this, &ReviewDialog::onScrollChangePosition); | ||||
|     updateScroller(); | ||||
| 
 | ||||
|  | @ -137,13 +140,17 @@ void ReviewDialog::setRace(const std::string &raceId_) | |||
|     raceId = raceId_; | ||||
|     const ESM::Race *race = mWindowManager.getStore().races.search(raceId); | ||||
|     if (race) | ||||
|     { | ||||
|         ToolTips::createRaceToolTip(raceWidget, race); | ||||
|         raceWidget->setCaption(race->name); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void ReviewDialog::setClass(const ESM::Class& class_) | ||||
| { | ||||
|     klass = class_; | ||||
|     classWidget->setCaption(klass.name); | ||||
|     ToolTips::createClassToolTip(classWidget, klass); | ||||
| } | ||||
| 
 | ||||
| void ReviewDialog::setBirthSign(const std::string& signId) | ||||
|  | @ -151,22 +158,31 @@ void ReviewDialog::setBirthSign(const std::string& signId) | |||
|     birthSignId = signId; | ||||
|     const ESM::BirthSign *sign = mWindowManager.getStore().birthSigns.search(birthSignId); | ||||
|     if (sign) | ||||
|     { | ||||
|         birthSignWidget->setCaption(sign->name); | ||||
|         ToolTips::createBirthsignToolTip(birthSignWidget, birthSignId); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void ReviewDialog::setHealth(const MWMechanics::DynamicStat<int>& value) | ||||
| { | ||||
|     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) | ||||
| { | ||||
|     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) | ||||
| { | ||||
|     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) | ||||
|  | @ -195,6 +211,7 @@ void ReviewDialog::setSkillValue(ESM::Skill::SkillEnum skillId, const MWMechanic | |||
|         widget->setCaption(text); | ||||
|         widget->_setWidgetState(state); | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| 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()) | ||||
|             miscSkills.push_back(skill); | ||||
|     } | ||||
| 
 | ||||
|     updateSkillArea(); | ||||
| } | ||||
| 
 | ||||
| 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); | ||||
|     separator->eventMouseWheel += MyGUI::newDelegate(this, &ReviewDialog::onMouseWheel); | ||||
| 
 | ||||
|     skillWidgets.push_back(separator); | ||||
| 
 | ||||
|     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) | ||||
| { | ||||
|     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); | ||||
|     skillWidgets.push_back(groupWidget); | ||||
| 
 | ||||
|  | @ -242,10 +264,12 @@ MyGUI::TextBox* ReviewDialog::addValueItem(const std::string text, const std::st | |||
| 
 | ||||
|     skillNameWidget = skillClientWidget->createWidget<MyGUI::TextBox>("SandText", coord1, MyGUI::Align::Default); | ||||
|     skillNameWidget->setCaption(text); | ||||
|     skillNameWidget->eventMouseWheel += MyGUI::newDelegate(this, &ReviewDialog::onMouseWheel); | ||||
| 
 | ||||
|     skillValueWidget = skillClientWidget->createWidget<MyGUI::TextBox>("SandTextRight", coord2, MyGUI::Align::Top | MyGUI::Align::Right); | ||||
|     skillValueWidget->setCaption(value); | ||||
|     skillValueWidget->_setWidgetState(state); | ||||
|     skillValueWidget->eventMouseWheel += MyGUI::newDelegate(this, &ReviewDialog::onMouseWheel); | ||||
| 
 | ||||
|     skillWidgets.push_back(skillNameWidget); | ||||
|     skillWidgets.push_back(skillValueWidget); | ||||
|  | @ -262,6 +286,7 @@ void ReviewDialog::addItem(const std::string text, MyGUI::IntCoord &coord1, MyGU | |||
| 
 | ||||
|     skillNameWidget = skillClientWidget->createWidget<MyGUI::TextBox>("SandText", coord1 + MyGUI::IntSize(coord2.width, 0), MyGUI::Align::Default); | ||||
|     skillNameWidget->setCaption(text); | ||||
|     skillNameWidget->eventMouseWheel += MyGUI::newDelegate(this, &ReviewDialog::onMouseWheel); | ||||
| 
 | ||||
|     skillWidgets.push_back(skillNameWidget); | ||||
| 
 | ||||
|  | @ -297,6 +322,12 @@ void ReviewDialog::addSkills(const SkillList &skills, const std::string &titleId | |||
|         else if (modified < base) | ||||
|             state = "decreased"; | ||||
|         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; | ||||
|     } | ||||
| } | ||||
|  | @ -330,6 +361,8 @@ void ReviewDialog::updateScroller() | |||
| { | ||||
|     skillScrollerWidget->setScrollRange(std::max(clientHeight - skillClientWidget->getHeight(), 0)); | ||||
|     skillScrollerWidget->setScrollPage(std::max(skillClientWidget->getHeight() - lineHeight, 0)); | ||||
|     if (clientHeight != 0) | ||||
|         skillScrollerWidget->setTrackSize( (skillAreaWidget->getHeight() / float(clientHeight)) * skillScrollerWidget->getLineSize() ); | ||||
| } | ||||
| 
 | ||||
| // widget controls
 | ||||
|  | @ -363,3 +396,15 @@ void ReviewDialog::onBirthSignClicked(MyGUI::Widget* _sender) | |||
| { | ||||
|     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,6 +68,8 @@ namespace MWGui | |||
|         void onClassClicked(MyGUI::Widget* _sender); | ||||
|         void onBirthSignClicked(MyGUI::Widget* _sender); | ||||
| 
 | ||||
|         void onMouseWheel(MyGUI::Widget* _sender, int _rel); | ||||
| 
 | ||||
|     private: | ||||
|         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); | ||||
|  |  | |||
|  | @ -1,12 +1,13 @@ | |||
| #include "scrollwindow.hpp" | ||||
| 
 | ||||
| #include "formatting.hpp" | ||||
| 
 | ||||
| #include "../mwbase/environment.hpp" | ||||
| #include "../mwinput/inputmanager.hpp" | ||||
| #include "../mwworld/actiontake.hpp" | ||||
| #include "../mwsound/soundmanager.hpp" | ||||
| 
 | ||||
| #include "formatting.hpp" | ||||
| #include "window_manager.hpp" | ||||
| 
 | ||||
| using namespace MWGui; | ||||
| 
 | ||||
| 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().getInputManager()->setGuiMode (GM_Game); | ||||
|     mWindowManager.popGuiMode(); | ||||
| } | ||||
| 
 | ||||
| void ScrollWindow::onTakeButtonClicked (MyGUI::Widget* _sender) | ||||
|  | @ -65,5 +66,5 @@ void ScrollWindow::onTakeButtonClicked (MyGUI::Widget* _sender) | |||
|     MWWorld::ActionTake take(mScroll); | ||||
|     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 const float sFovMin = 30; | ||||
|             static const float sFovMax = 140; | ||||
|             static const float sViewDistMin = 2000; | ||||
|             static const float 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 "window_manager.hpp" | ||||
| #include "tooltips.hpp" | ||||
| 
 | ||||
| 
 | ||||
| using namespace MWGui; | ||||
|  | @ -77,8 +78,6 @@ StatsWindow::StatsWindow (WindowManager& parWindowManager) | |||
| 
 | ||||
|     MyGUI::WindowPtr t = static_cast<MyGUI::WindowPtr>(mMainWidget); | ||||
|     t->eventWindowChangeCoord += MyGUI::newDelegate(this, &StatsWindow::onWindowResize); | ||||
| 
 | ||||
|     setupToolTips(); | ||||
| } | ||||
| 
 | ||||
| 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()) | ||||
|             miscSkills.push_back(skill); | ||||
|     } | ||||
| 
 | ||||
|     updateSkillArea(); | ||||
| } | ||||
| 
 | ||||
| void StatsWindow::onFrame () | ||||
|  | @ -376,6 +377,7 @@ void StatsWindow::addSkills(const SkillList &skills, const std::string &titleId, | |||
|         const MWMechanics::Stat<float> &stat = skillValues.find(skillId)->second; | ||||
|         float base = stat.getBase(); | ||||
|         float modified = stat.getModified(); | ||||
|         int progressPercent = (modified - float(static_cast<int>(modified))) * 100; | ||||
| 
 | ||||
|         const ESM::Skill* skill = mWindowManager.getStore().skills.search(skillId); | ||||
|         assert(skill); | ||||
|  | @ -401,8 +403,9 @@ void StatsWindow::addSkills(const SkillList &skills, const std::string &titleId, | |||
|             skillWidgets[skillWidgets.size()-1-i]->setUserString("Caption_SkillDescription", skill->description); | ||||
|             skillWidgets[skillWidgets.size()-1-i]->setUserString("Caption_SkillAttribute", "#{sGoverningAttribute}: #{" + attr->name + "}"); | ||||
|             skillWidgets[skillWidgets.size()-1-i]->setUserString("ImageTexture_SkillImage", icon); | ||||
|             skillWidgets[skillWidgets.size()-1-i]->setUserString("Caption_SkillProgressText", "0/100"); | ||||
|             skillWidgets[skillWidgets.size()-1-i]->setUserString("Caption_SkillProgressText", boost::lexical_cast<std::string>(progressPercent)+"/100"); | ||||
|             skillWidgets[skillWidgets.size()-1-i]->setUserString("Range_SkillProgress", "100"); | ||||
|             skillWidgets[skillWidgets.size()-1-i]->setUserString("RangePosition_SkillProgress", boost::lexical_cast<std::string>(progressPercent)); | ||||
|         } | ||||
| 
 | ||||
|         skillWidgetMap[skillId] = widget; | ||||
|  | @ -442,32 +445,17 @@ void StatsWindow::updateSkillArea() | |||
|     const ESM::Race* playerRace =  store.races.find (MWBase::Environment::get().getWorld()->getPlayer().getRace()); | ||||
|     MyGUI::Widget* raceWidget; | ||||
|     getWidget(raceWidget, "RaceText"); | ||||
|     raceWidget->setUserString("Caption_CenteredCaption", playerRace->name); | ||||
|     raceWidget->setUserString("Caption_CenteredCaptionText", playerRace->description); | ||||
|     ToolTips::createRaceToolTip(raceWidget, playerRace); | ||||
|     getWidget(raceWidget, "Race_str"); | ||||
|     raceWidget->setUserString("Caption_CenteredCaption", playerRace->name); | ||||
|     raceWidget->setUserString("Caption_CenteredCaptionText", playerRace->description); | ||||
|     ToolTips::createRaceToolTip(raceWidget, playerRace); | ||||
| 
 | ||||
|     // class tooltip
 | ||||
|     MyGUI::Widget* classWidget; | ||||
|     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"); | ||||
|     classWidget->setUserString("Caption_ClassName", playerClass.name); | ||||
|     classWidget->setUserString("Caption_ClassDescription", playerClass.description); | ||||
|     classWidget->setUserString("Caption_ClassSpecialisation", "#{sSpecialization}: " + specStr); | ||||
|     ToolTips::createClassToolTip(classWidget, playerClass); | ||||
|     getWidget(classWidget, "Class_str"); | ||||
|     classWidget->setUserString("Caption_ClassName", playerClass.name); | ||||
|     classWidget->setUserString("Caption_ClassDescription", playerClass.description); | ||||
|     classWidget->setUserString("Caption_ClassSpecialisation", "#{sSpecialization}: " + specStr); | ||||
|     ToolTips::createClassToolTip(classWidget, playerClass); | ||||
| 
 | ||||
|     if (!mFactions.empty()) | ||||
|     { | ||||
|  | @ -534,61 +522,8 @@ void StatsWindow::updateSkillArea() | |||
|         addGroup(mWindowManager.getGameSettingString("sBirthSign", "Sign"), coord1, coord2); | ||||
|         const ESM::BirthSign *sign = store.birthSigns.find(birthSignId); | ||||
|         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; | ||||
|         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); | ||||
|         ToolTips::createBirthsignToolTip(w, birthSignId); | ||||
|     } | ||||
| 
 | ||||
|     // Add a line separator if there are items above
 | ||||
|  | @ -631,116 +566,3 @@ void StatsWindow::onPinToggled() | |||
| { | ||||
|     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"); | ||||
| } | ||||
|  |  | |||
|  | @ -50,8 +50,6 @@ namespace MWGui | |||
|             MyGUI::Widget* addItem(const std::string text, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2); | ||||
|             void updateScroller(); | ||||
| 
 | ||||
|             void setupToolTips(); | ||||
| 
 | ||||
|             void setFactions (const FactionList& factions); | ||||
|             void setBirthSign (const std::string &signId); | ||||
| 
 | ||||
|  |  | |||
|  | @ -8,6 +8,8 @@ | |||
| 
 | ||||
| #include <boost/lexical_cast.hpp> | ||||
| 
 | ||||
| #include <components/settings/settings.hpp> | ||||
| 
 | ||||
| using namespace MWGui; | ||||
| using namespace MyGUI; | ||||
| 
 | ||||
|  | @ -19,6 +21,10 @@ ToolTips::ToolTips(WindowManager* windowManager) : | |||
|     , mEnabled(true) | ||||
|     , mFocusToolTipX(0.0) | ||||
|     , mFocusToolTipY(0.0) | ||||
|     , mDelay(0.0) | ||||
|     , mRemainingDelay(0.0) | ||||
|     , mLastMouseX(0) | ||||
|     , mLastMouseY(0) | ||||
| { | ||||
|     getWidget(mDynamicToolTipBox, "DynamicToolTipBox"); | ||||
| 
 | ||||
|  | @ -28,6 +34,9 @@ ToolTips::ToolTips(WindowManager* windowManager) : | |||
|     // even if the mouse is over the tooltip
 | ||||
|     mDynamicToolTipBox->setNeedMouseFocus(false); | ||||
|     mMainWidget->setNeedMouseFocus(false); | ||||
| 
 | ||||
|     mDelay = Settings::Manager::getFloat("tooltip delay", "GUI"); | ||||
|     mRemainingDelay = mDelay; | ||||
| } | ||||
| 
 | ||||
| void ToolTips::setEnabled(bool enabled) | ||||
|  | @ -37,10 +46,10 @@ void ToolTips::setEnabled(bool enabled) | |||
| 
 | ||||
| void ToolTips::onFrame(float frameDuration) | ||||
| { | ||||
|     MyGUI::Gui::getInstance().destroyWidget(mDynamicToolTipBox); | ||||
|     mDynamicToolTipBox = mMainWidget->createWidget<Widget>("HUD_Box", | ||||
|         IntCoord(0, 0, mMainWidget->getCoord().width, mMainWidget->getCoord().height), | ||||
|         Align::Stretch, "DynamicToolTipBox"); | ||||
|     while (mDynamicToolTipBox->getChildCount()) | ||||
|     { | ||||
|         MyGUI::Gui::getInstance().destroyWidget(mDynamicToolTipBox->getChildAt(0)); | ||||
|     } | ||||
| 
 | ||||
|     // start by hiding everything
 | ||||
|     for (unsigned int i=0; i < mMainWidget->getChildCount(); ++i) | ||||
|  | @ -57,6 +66,60 @@ void ToolTips::onFrame(float frameDuration) | |||
| 
 | ||||
|     if (!mGameMode) | ||||
|     { | ||||
|         const MyGUI::IntPoint& mousePos = InputManager::getInstance().getMousePosition(); | ||||
| 
 | ||||
|         if (mWindowManager->getWorldMouseOver() && ((mWindowManager->getMode() == GM_Console) | ||||
|             || (mWindowManager->getMode() == GM_Container) | ||||
|             || (mWindowManager->getMode() == GM_Inventory))) | ||||
|         { | ||||
|             std::string handle = MWBase::Environment::get().getWorld()->getFacedHandle(); | ||||
|             try | ||||
|             { | ||||
|                 mFocusObject = MWBase::Environment::get().getWorld()->getPtrViaHandle(handle); | ||||
|             } | ||||
|             catch (std::exception& e) | ||||
|             { | ||||
|                 return; | ||||
|             } | ||||
| 
 | ||||
|             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 | ||||
|             { | ||||
|                 mRemainingDelay = mDelay; | ||||
|             } | ||||
|             mLastMouseX = mousePos.left; | ||||
|             mLastMouseY = mousePos.top; | ||||
| 
 | ||||
|             if (mRemainingDelay > 0) | ||||
|                 return; | ||||
| 
 | ||||
|             Widget* focus = InputManager::getInstance().getMouseFocusWidget(); | ||||
|             if (focus == 0) | ||||
|             { | ||||
|  | @ -65,6 +128,17 @@ void ToolTips::onFrame(float frameDuration) | |||
| 
 | ||||
|             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")) | ||||
|             { | ||||
|                 focus = focus->getParent(); | ||||
|                 if (!focus) | ||||
|                     return; | ||||
|                 ++i; | ||||
|             } | ||||
| 
 | ||||
|             std::string type = focus->getUserString("ToolTipType"); | ||||
|             std::string text = focus->getUserString("ToolTipText"); | ||||
| 
 | ||||
|  | @ -78,6 +152,29 @@ void ToolTips::onFrame(float frameDuration) | |||
|                 mFocusObject = *focus->getUserData<MWWorld::Ptr>(); | ||||
|                 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
 | ||||
|  | @ -157,6 +254,7 @@ void ToolTips::onFrame(float frameDuration) | |||
| 
 | ||||
|             setCoord(tooltipPosition.left, tooltipPosition.top, tooltipSize.width, tooltipSize.height); | ||||
|         } | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         if (!mFocusObject.isEmpty()) | ||||
|  | @ -285,7 +383,7 @@ IntSize ToolTips::createToolTip(const MWGui::ToolTipInfo& info) | |||
|     IntSize totalSize = IntSize( std::max(textSize.width, captionSize.width + ((image != "") ? imageCaptionHPadding : 0)), | ||||
|         ((text != "") ? textSize.height + imageCaptionVPadding : 0) + captionHeight ); | ||||
| 
 | ||||
|     if (info.effects != 0) | ||||
|     if (!info.effects.empty()) | ||||
|     { | ||||
|         Widget* effectArea = mDynamicToolTipBox->createWidget<Widget>("", | ||||
|             IntCoord(0, totalSize.height, 300, 300-totalSize.height), | ||||
|  | @ -305,7 +403,7 @@ IntSize ToolTips::createToolTip(const MWGui::ToolTipInfo& info) | |||
|         effectsWidget->setEffectList(info.effects); | ||||
| 
 | ||||
|         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.width = std::max(totalSize.width, coord.width); | ||||
|     } | ||||
|  | @ -321,7 +419,7 @@ IntSize ToolTips::createToolTip(const MWGui::ToolTipInfo& info) | |||
|         Widgets::MWEffectListPtr enchantWidget = enchantArea->createWidget<Widgets::MWEffectList> | ||||
|             ("MW_StatName", coord, Align::Default, "ToolTipEnchantWidget"); | ||||
|         enchantWidget->setWindowManager(mWindowManager); | ||||
|         enchantWidget->setEffectList(&enchant->effects); | ||||
|         enchantWidget->setEffectList(Widgets::MWEffectList::effectListFromESM(&enchant->effects)); | ||||
| 
 | ||||
|         std::vector<MyGUI::WidgetPtr> enchantEffectItems; | ||||
|         int flag = (enchant->data.type == ESM::Enchantment::ConstantEffect) ? Widgets::MWEffectList::EF_Constant : 0; | ||||
|  | @ -339,7 +437,6 @@ IntSize ToolTips::createToolTip(const MWGui::ToolTipInfo& info) | |||
| 
 | ||||
|             TextBox* chargeText = enchantArea->createWidget<TextBox>("SandText", IntCoord(0, 0, 10, 18), Align::Default, "ToolTipEnchantChargeText"); | ||||
|             chargeText->setCaption(store.gameSettings.search("sCharges")->str); | ||||
|             chargeText->setProperty("Static", "true"); | ||||
|             const int chargeTextWidth = chargeText->getTextSize().width + 5; | ||||
| 
 | ||||
|             const int chargeAndTextWidth = chargeWidth + chargeTextWidth; | ||||
|  | @ -440,3 +537,156 @@ void ToolTips::setFocusObjectScreenCoords(float min_x, float min_y, float max_x, | |||
|     mFocusToolTipX = (min_x + max_x) / 2; | ||||
|     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 "../mwworld/ptr.hpp" | ||||
| 
 | ||||
| #include "widgets.hpp" | ||||
| 
 | ||||
| namespace MWGui | ||||
| { | ||||
|     class WindowManager; | ||||
|  | @ -13,11 +15,6 @@ namespace MWGui | |||
|     struct ToolTipInfo | ||||
|     { | ||||
|     public: | ||||
|         ToolTipInfo() : | ||||
|             effects(0) | ||||
|         { | ||||
|         }; | ||||
| 
 | ||||
|         std::string caption; | ||||
|         std::string text; | ||||
|         std::string icon; | ||||
|  | @ -26,7 +23,7 @@ namespace MWGui | |||
|         std::string enchant; | ||||
| 
 | ||||
|         // effects (for potions, ingredients)
 | ||||
|         const ESM::EffectList* effects; | ||||
|         Widgets::SpellEffectList effects; | ||||
|     }; | ||||
| 
 | ||||
|     class ToolTips : public OEngine::GUI::Layout | ||||
|  | @ -44,6 +41,8 @@ namespace MWGui | |||
|         void toggleFullHelp(); ///< show extra info in item tooltips (owner, script)
 | ||||
|         bool getFullHelp() const; | ||||
| 
 | ||||
|         void setDelay(float delay); | ||||
| 
 | ||||
|         void setFocusObject(const MWWorld::Ptr& focus); | ||||
|         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 
 | ||||
|  | @ -60,6 +59,15 @@ namespace MWGui | |||
|         static std::string getCountString(const int 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: | ||||
|         MyGUI::Widget* mDynamicToolTipBox; | ||||
| 
 | ||||
|  | @ -78,6 +86,12 @@ namespace MWGui | |||
|         float mFocusToolTipX; | ||||
|         float mFocusToolTipY; | ||||
| 
 | ||||
|         float mDelay; | ||||
|         float mRemainingDelay; // remaining time until tooltip will show
 | ||||
| 
 | ||||
|         int mLastMouseX; | ||||
|         int mLastMouseY; | ||||
| 
 | ||||
|         bool mGameMode; | ||||
| 
 | ||||
|         bool mEnabled; | ||||
|  |  | |||
|  | @ -104,6 +104,8 @@ namespace MWGui | |||
|         ContainerBase::openContainer(actor); | ||||
| 
 | ||||
|         updateLabels(); | ||||
| 
 | ||||
|         drawItems(); | ||||
|     } | ||||
| 
 | ||||
|     void TradeWindow::onFilterChanged(MyGUI::Widget* _sender) | ||||
|  | @ -157,9 +159,9 @@ namespace MWGui | |||
| 
 | ||||
|         // check if the merchant can afford this
 | ||||
|         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) | ||||
|                 merchantgold = ref->base->npdt12.gold; | ||||
|             else | ||||
|  | @ -167,7 +169,7 @@ namespace MWGui | |||
|         } | ||||
|         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; | ||||
|         } | ||||
|         if (mCurrentBalance > 0 && merchantgold < mCurrentBalance) | ||||
|  | @ -210,7 +212,7 @@ namespace MWGui | |||
|         std::string sound = "Item Gold Up"; | ||||
|         MWBase::Environment::get().getSoundManager()->playSound (sound, 1.0, 1.0); | ||||
| 
 | ||||
|         mWindowManager.setGuiMode(GM_Game); | ||||
|         mWindowManager.popGuiMode(); | ||||
|     } | ||||
| 
 | ||||
|     void TradeWindow::onCancelButtonClicked(MyGUI::Widget* _sender) | ||||
|  | @ -218,9 +220,9 @@ namespace MWGui | |||
|         // i give you back your stuff!
 | ||||
|         returnBoughtItems(mWindowManager.getInventoryWindow()->getContainerStore()); | ||||
|         // 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() | ||||
|  | @ -240,9 +242,9 @@ namespace MWGui | |||
|         } | ||||
| 
 | ||||
|         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) | ||||
|                 merchantgold = ref->base->npdt12.gold; | ||||
|             else | ||||
|  | @ -250,7 +252,7 @@ namespace MWGui | |||
|         } | ||||
|         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; | ||||
|         } | ||||
| 
 | ||||
|  | @ -262,13 +264,13 @@ namespace MWGui | |||
|     { | ||||
|         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.
 | ||||
|             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) | ||||
|         { | ||||
|  | @ -285,19 +287,21 @@ namespace MWGui | |||
|     bool TradeWindow::npcAcceptsItem(MWWorld::Ptr item) | ||||
|     { | ||||
|         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) | ||||
|                 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) | ||||
|                 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()) | ||||
|             return services & ESM::NPC::Weapon; | ||||
|         else if (item.getTypeName() == typeid(ESM::Armor).name()) | ||||
|  | @ -327,7 +331,7 @@ namespace MWGui | |||
|     std::vector<MWWorld::Ptr> TradeWindow::itemsToIgnore() | ||||
|     { | ||||
|         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(); | ||||
|                 it != invStore.end(); ++it) | ||||
|  | @ -356,4 +360,11 @@ namespace MWGui | |||
| 
 | ||||
|         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(); | ||||
| 
 | ||||
|             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->setWindowManager(mWindowManager); | ||||
|         effect->setFlags(flags); | ||||
|         effect->setSpellEffect(*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; | ||||
|         params.mIsConstant = (flags & MWEffectList::EF_Constant); | ||||
|         params.mNoTarget = (flags & MWEffectList::EF_NoTarget); | ||||
|         effect->setSpellEffect(params); | ||||
|         effects.push_back(effect); | ||||
|         coord.top += effect->getHeight(); | ||||
|         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; | ||||
|     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) | ||||
| { | ||||
|     // 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; | ||||
|     std::vector<ESM::ENAMstruct>::const_iterator end = mEffectList->list.end(); | ||||
|     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->setWindowManager(mWindowManager); | ||||
|         effect->setFlags(flags); | ||||
|         it->mIsConstant = (flags & EF_Constant) || it->mIsConstant; | ||||
|         it->mNoTarget = (flags & EF_NoTarget) || it->mNoTarget; | ||||
|         effect->setSpellEffect(*it); | ||||
|         effects.push_back(effect); | ||||
| 
 | ||||
|         if (effect->getRequestedWidth() > maxwidth) | ||||
|             maxwidth = effect->getRequestedWidth(); | ||||
| 
 | ||||
|         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) | ||||
|     { | ||||
|         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() | ||||
|  | @ -341,13 +370,12 @@ MWSpellEffect::MWSpellEffect() | |||
|     , imageWidget(nullptr) | ||||
|     , textWidget(nullptr) | ||||
|     , mRequestedWidth(0) | ||||
|     , mFlags(0) | ||||
| { | ||||
| } | ||||
| 
 | ||||
| void MWSpellEffect::setSpellEffect(SpellEffectValue value) | ||||
| void MWSpellEffect::setSpellEffect(const SpellEffectParams& params) | ||||
| { | ||||
|     effect = value; | ||||
|     mEffectParams = params; | ||||
|     updateWidgets(); | ||||
| } | ||||
| 
 | ||||
|  | @ -357,10 +385,10 @@ void MWSpellEffect::updateWidgets() | |||
|         return; | ||||
| 
 | ||||
|     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 (magicEffect) | ||||
|     { | ||||
|         std::string pt =  mWindowManager->getGameSettingString("spoint", ""); | ||||
|         std::string pts =  mWindowManager->getGameSettingString("spoints", ""); | ||||
|  | @ -368,13 +396,13 @@ void MWSpellEffect::updateWidgets() | |||
|         std::string sec =  " " + mWindowManager->getGameSettingString("ssecond", ""); | ||||
|         std::string secs =  " " + mWindowManager->getGameSettingString("sseconds", ""); | ||||
| 
 | ||||
|             std::string effectIDStr = effectIDToString(effect.effectID); | ||||
|         std::string effectIDStr = effectIDToString(mEffectParams.mEffectID); | ||||
|         std::string spellLine = mWindowManager->getGameSettingString(effectIDStr, ""); | ||||
|             if (effect.skill >= 0 && effect.skill < ESM::Skill::Length) | ||||
|         if (effectInvolvesSkill(effectIDStr) && mEffectParams.mSkill >= 0 && mEffectParams.mSkill < ESM::Skill::Length) | ||||
|         { | ||||
|                 spellLine += " " + mWindowManager->getGameSettingString(ESM::Skill::sSkillNameIds[effect.skill], ""); | ||||
|             spellLine += " " + mWindowManager->getGameSettingString(ESM::Skill::sSkillNameIds[mEffectParams.mSkill], ""); | ||||
|         } | ||||
|             if (effect.attribute >= 0 && effect.attribute < 8) | ||||
|         if (effectInvolvesAttribute(effectIDStr) && mEffectParams.mAttribute >= 0 && mEffectParams.mAttribute < 8) | ||||
|         { | ||||
|             static const char *attributes[8] = { | ||||
|                 "sAttributeStrength", | ||||
|  | @ -386,36 +414,36 @@ void MWSpellEffect::updateWidgets() | |||
|                 "sAttributePersonality", | ||||
|                 "sAttributeLuck" | ||||
|             }; | ||||
|                 spellLine += " " + mWindowManager->getGameSettingString(attributes[effect.attribute], ""); | ||||
|             spellLine += " " + mWindowManager->getGameSettingString(attributes[mEffectParams.mAttribute], ""); | ||||
|         } | ||||
| 
 | ||||
|             if ((effect.magnMin >= 0 || effect.magnMax >= 0) && effectHasMagnitude(effectIDStr)) | ||||
|         if ((mEffectParams.mMagnMin >= 0 || mEffectParams.mMagnMax >= 0) && effectHasMagnitude(effectIDStr)) | ||||
|         { | ||||
|                 if (effect.magnMin == effect.magnMax) | ||||
|                     spellLine += " " + boost::lexical_cast<std::string>(effect.magnMin) + " " + ((effect.magnMin == 1) ? pt : pts); | ||||
|             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>(effect.magnMin) + to + boost::lexical_cast<std::string>(effect.magnMax) + " " + pts; | ||||
|                 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 (!(mFlags & MWEffectList::EF_Constant)) | ||||
|         if (!mEffectParams.mIsConstant) | ||||
|         { | ||||
|                 if (effect.duration >= 0 && effectHasDuration(effectIDStr)) | ||||
|             if (mEffectParams.mDuration >= 0 && effectHasDuration(effectIDStr)) | ||||
|             { | ||||
|                     spellLine += " " + mWindowManager->getGameSettingString("sfor", "") + " " + boost::lexical_cast<std::string>(effect.duration) + ((effect.duration == 1) ? sec : secs); | ||||
|                 spellLine += " " + mWindowManager->getGameSettingString("sfor", "") + " " + boost::lexical_cast<std::string>(mEffectParams.mDuration) + ((mEffectParams.mDuration == 1) ? sec : secs); | ||||
|             } | ||||
| 
 | ||||
|             // potions have no target
 | ||||
|                 if (!(mFlags & MWEffectList::EF_Potion)) | ||||
|             if (!mEffectParams.mNoTarget) | ||||
|             { | ||||
|                 std::string on = mWindowManager->getGameSettingString("sonword", ""); | ||||
|                     if (effect.range == ESM::RT_Self) | ||||
|                 if (mEffectParams.mRange == ESM::RT_Self) | ||||
|                     spellLine += " " + on + " " + mWindowManager->getGameSettingString("sRangeSelf", ""); | ||||
|                     else if (effect.range == ESM::RT_Touch) | ||||
|                 else if (mEffectParams.mRange == ESM::RT_Touch) | ||||
|                     spellLine += " " + on + " " + mWindowManager->getGameSettingString("sRangeTouch", ""); | ||||
|                     else if (effect.range == ESM::RT_Target) | ||||
|                 else if (mEffectParams.mRange == ESM::RT_Target) | ||||
|                     spellLine += " " + on + " " + mWindowManager->getGameSettingString("sRangeTarget", ""); | ||||
|             } | ||||
|         } | ||||
|  | @ -423,9 +451,6 @@ void MWSpellEffect::updateWidgets() | |||
|         static_cast<MyGUI::TextBox*>(textWidget)->setCaption(spellLine); | ||||
|         mRequestedWidth = textWidget->getTextSize().width + 24; | ||||
|     } | ||||
|         else | ||||
|             static_cast<MyGUI::TextBox*>(textWidget)->setCaption(""); | ||||
|     } | ||||
|     if (imageWidget) | ||||
|     { | ||||
|         std::string path = std::string("icons\\") + magicEffect->icon; | ||||
|  | @ -677,6 +702,24 @@ bool MWSpellEffect::effectHasMagnitude(const std::string& effect) | |||
|     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() | ||||
| { | ||||
| } | ||||
|  |  | |||
|  | @ -21,8 +21,47 @@ namespace MWGui | |||
| 
 | ||||
|     namespace Widgets | ||||
|     { | ||||
|         class MWEffectList; | ||||
| 
 | ||||
|         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 | ||||
|             { | ||||
|                 return (other.mEffectID == mEffectID | ||||
|                         && other.mSkill == mSkill | ||||
|                         && other.mAttribute == mAttribute); | ||||
|             } | ||||
|         }; | ||||
| 
 | ||||
|         typedef std::vector<SpellEffectParams> SpellEffectList; | ||||
| 
 | ||||
|         class MYGUI_EXPORT MWSkill : public Widget | ||||
|         { | ||||
|             MYGUI_RTTI_DERIVED( MWSkill ); | ||||
|  | @ -108,6 +147,9 @@ namespace MWGui | |||
|         }; | ||||
|         typedef MWAttribute* MWAttributePtr; | ||||
| 
 | ||||
|         /**
 | ||||
|          * @todo remove this class and use MWEffectList instead | ||||
|          */ | ||||
|         class MWSpellEffect; | ||||
|         class MYGUI_EXPORT MWSpell : public Widget | ||||
|         { | ||||
|  | @ -155,12 +197,14 @@ namespace MWGui | |||
| 
 | ||||
|             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
 | ||||
|             }; | ||||
| 
 | ||||
|             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 | ||||
|  | @ -180,7 +224,7 @@ namespace MWGui | |||
|             void updateWidgets(); | ||||
| 
 | ||||
|             WindowManager* mWindowManager; | ||||
|             const ESM::EffectList* mEffectList; | ||||
|             SpellEffectList mEffectList; | ||||
|         }; | ||||
|         typedef MWEffectList* MWEffectListPtr; | ||||
| 
 | ||||
|  | @ -193,14 +237,13 @@ namespace MWGui | |||
|             typedef ESM::ENAMstruct SpellEffectValue; | ||||
| 
 | ||||
|             void setWindowManager(WindowManager* parWindowManager) { mWindowManager = parWindowManager; } | ||||
|             void setSpellEffect(SpellEffectValue value); | ||||
|             void setFlags(int flags) { mFlags = flags; } | ||||
|             void setSpellEffect(const SpellEffectParams& params); | ||||
| 
 | ||||
|             std::string effectIDToString(const short effectID); | ||||
|             bool effectHasMagnitude (const std::string& effect); | ||||
|             bool effectHasDuration (const std::string& effect); | ||||
| 
 | ||||
|             const SpellEffectValue &getSpellEffect() const { return effect; } | ||||
|             bool effectInvolvesAttribute (const std::string& effect); | ||||
|             bool effectInvolvesSkill (const std::string& effect); | ||||
| 
 | ||||
|             int getRequestedWidth() const { return mRequestedWidth; } | ||||
| 
 | ||||
|  | @ -214,8 +257,7 @@ namespace MWGui | |||
|             void updateWidgets(); | ||||
| 
 | ||||
|             WindowManager* mWindowManager; | ||||
|             SpellEffectValue effect; | ||||
|             int mFlags; | ||||
|             SpellEffectParams mEffectParams; | ||||
|             MyGUI::ImageBox* imageWidget; | ||||
|             MyGUI::TextBox* textWidget; | ||||
|             int mRequestedWidth; | ||||
|  | @ -247,7 +289,6 @@ namespace MWGui | |||
|             MyGUI::TextBox* barTextWidget; | ||||
|         }; | ||||
|         typedef MWDynamicStat* MWDynamicStatPtr; | ||||
| 
 | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,6 +1,8 @@ | |||
| #include "window_base.hpp" | ||||
| #include "window_manager.hpp" | ||||
| 
 | ||||
| #include <components/settings/settings.hpp> | ||||
| 
 | ||||
| using namespace MWGui; | ||||
| 
 | ||||
| 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() | ||||
| { | ||||
|     // 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(); | ||||
|     coord.left = (gameWindowSize.width - coord.width)/2; | ||||
|     coord.top = (gameWindowSize.height - coord.height)/2; | ||||
|  |  | |||
|  | @ -16,6 +16,7 @@ namespace MWGui | |||
|         typedef MyGUI::delegates::CMultiDelegate1<WindowBase*> EventHandle_WindowBase; | ||||
| 
 | ||||
|         virtual void open(); | ||||
|         virtual void setVisible(bool visible); // calls open() if visible is true and was false before
 | ||||
|         void center(); | ||||
| 
 | ||||
|         /** Event : Dialog finished, OK button clicked.\n
 | ||||
|  |  | |||
|  | @ -16,6 +16,10 @@ | |||
| #include "mainmenu.hpp" | ||||
| #include "countdialog.hpp" | ||||
| #include "tradewindow.hpp" | ||||
| #include "settingswindow.hpp" | ||||
| #include "confirmationdialog.hpp" | ||||
| #include "alchemywindow.hpp" | ||||
| #include "spellwindow.hpp" | ||||
| 
 | ||||
| #include "../mwmechanics/mechanicsmanager.hpp" | ||||
| #include "../mwinput/inputmanager.hpp" | ||||
|  | @ -45,11 +49,15 @@ WindowManager::WindowManager( | |||
|   , mMessageBoxManager(NULL) | ||||
|   , console(NULL) | ||||
|   , mJournal(NULL) | ||||
|   , mDialogueWindow(nullptr) | ||||
|   , mDialogueWindow(NULL) | ||||
|   , mBookWindow(NULL) | ||||
|   , mScrollWindow(NULL) | ||||
|   , mCountDialog(NULL) | ||||
|   , mTradeWindow(NULL) | ||||
|   , mSettingsWindow(NULL) | ||||
|   , mConfirmationDialog(NULL) | ||||
|   , mAlchemyWindow(NULL) | ||||
|   , mSpellWindow(NULL) | ||||
|   , mCharGen(NULL) | ||||
|   , playerClass() | ||||
|   , playerName() | ||||
|  | @ -62,9 +70,6 @@ WindowManager::WindowManager( | |||
|   , playerMagicka() | ||||
|   , playerFatigue() | ||||
|   , gui(NULL) | ||||
|   , mode(GM_Game) | ||||
|   , nextMode(GM_Game) | ||||
|   , needModeChange(false) | ||||
|   , garbageDialogs() | ||||
|   , shown(GW_ALL) | ||||
|   , allowed(newGame ? GW_None : GW_ALL) | ||||
|  | @ -118,6 +123,10 @@ WindowManager::WindowManager( | |||
|     mScrollWindow = new ScrollWindow(*this); | ||||
|     mBookWindow = new BookWindow(*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
 | ||||
|     hud->setVisible(true); | ||||
|  | @ -135,6 +144,9 @@ WindowManager::WindowManager( | |||
|         playerSkillValues.insert(std::make_pair(ESM::Skill::skillIds[i], MWMechanics::Stat<float>())); | ||||
|     } | ||||
| 
 | ||||
|     unsetSelectedSpell(); | ||||
|     unsetSelectedWeapon(); | ||||
| 
 | ||||
|     // Set up visibility
 | ||||
|     updateVisible(); | ||||
| } | ||||
|  | @ -158,6 +170,10 @@ WindowManager::~WindowManager() | |||
|     delete mBookWindow; | ||||
|     delete mScrollWindow; | ||||
|     delete mTradeWindow; | ||||
|     delete mSettingsWindow; | ||||
|     delete mConfirmationDialog; | ||||
|     delete mAlchemyWindow; | ||||
|     delete mSpellWindow; | ||||
| 
 | ||||
|     cleanupGarbage(); | ||||
| } | ||||
|  | @ -178,29 +194,10 @@ void WindowManager::cleanupGarbage() | |||
| void WindowManager::update() | ||||
| { | ||||
|     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) | ||||
| { | ||||
|     nextMode = newMode; | ||||
|     needModeChange = true; | ||||
| } | ||||
| 
 | ||||
| void WindowManager::setGuiMode(GuiMode newMode) | ||||
| { | ||||
|     MWBase::Environment::get().getInputManager()->setGuiMode(newMode); | ||||
| } | ||||
| 
 | ||||
| void WindowManager::updateVisible() | ||||
|  | @ -217,22 +214,38 @@ void WindowManager::updateVisible() | |||
|     mScrollWindow->setVisible(false); | ||||
|     mBookWindow->setVisible(false); | ||||
|     mTradeWindow->setVisible(false); | ||||
|     mSettingsWindow->setVisible(false); | ||||
|     mAlchemyWindow->setVisible(false); | ||||
|     mSpellWindow->setVisible(false); | ||||
| 
 | ||||
|     // Mouse is visible whenever we're not in game mode
 | ||||
|     MyGUI::PointerManager::getInstance().setVisible(isGuiMode()); | ||||
| 
 | ||||
|     if (mode == GM_Game) | ||||
|     bool gameMode = !isGuiMode(); | ||||
| 
 | ||||
|     if (gameMode) | ||||
|         mToolTips->enterGameMode(); | ||||
|     else | ||||
|         mToolTips->enterGuiMode(); | ||||
| 
 | ||||
|     switch(mode) { | ||||
|         case GM_Game: | ||||
|     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.
 | ||||
|             break; | ||||
|     if (gameMode) | ||||
|         return; | ||||
| 
 | ||||
|     GuiMode mode = mGuiModes.back(); | ||||
| 
 | ||||
|     switch(mode) { | ||||
|         case GM_MainMenu: | ||||
|             menu->setVisible(true); | ||||
|             break; | ||||
|         case GM_Settings: | ||||
|             mSettingsWindow->setVisible(true); | ||||
|             break; | ||||
|         case GM_Console: | ||||
|             console->enable(); | ||||
|             break; | ||||
|  | @ -242,6 +255,9 @@ void WindowManager::updateVisible() | |||
|         case GM_Book: | ||||
|             mBookWindow->setVisible(true); | ||||
|             break; | ||||
|         case GM_Alchemy: | ||||
|             mAlchemyWindow->setVisible(true); | ||||
|             break; | ||||
|         case GM_Name: | ||||
|         case GM_Race: | ||||
|         case GM_Class: | ||||
|  | @ -261,29 +277,24 @@ void WindowManager::updateVisible() | |||
|             int eff = shown & allowed; | ||||
| 
 | ||||
|             // Show the windows we want
 | ||||
|             map   -> setVisible( (eff & GW_Map) != 0 ); | ||||
|             mStatsWindow -> setVisible( (eff & GW_Stats) != 0 ); | ||||
|             mInventoryWindow->setVisible(true); | ||||
|             mInventoryWindow->openInventory(); | ||||
|             map   -> setVisible(eff & GW_Map); | ||||
|             mStatsWindow -> setVisible(eff & GW_Stats); | ||||
|             mInventoryWindow->setVisible(eff & GW_Inventory); | ||||
|             mSpellWindow->setVisible(eff & GW_Magic); | ||||
|             break; | ||||
|         } | ||||
|         case GM_Container: | ||||
|             mContainerWindow->setVisible(true); | ||||
|             mInventoryWindow->setVisible(true); | ||||
|             mInventoryWindow->openInventory(); | ||||
|             break; | ||||
|         case GM_Dialogue: | ||||
|             mDialogueWindow->open(); | ||||
|             mDialogueWindow->setVisible(true); | ||||
|             break; | ||||
|         case GM_Barter: | ||||
|             mInventoryWindow->setVisible(true); | ||||
|             mInventoryWindow->openInventory(); | ||||
|             mTradeWindow->setVisible(true); | ||||
|             break; | ||||
|         case GM_InterMessageBox: | ||||
|             if(!mMessageBoxManager->isInteractiveMessageBox()) { | ||||
|                 setGuiMode(GM_Game); | ||||
|             } | ||||
|             break; | ||||
|         case GM_Journal: | ||||
|             mJournal->setVisible(true); | ||||
|  | @ -291,9 +302,6 @@ void WindowManager::updateVisible() | |||
|             break; | ||||
|         default: | ||||
|             // 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; | ||||
|     } | ||||
| } | ||||
|  | @ -301,6 +309,7 @@ void WindowManager::updateVisible() | |||
| void WindowManager::setValue (const std::string& id, const MWMechanics::Stat<int>& value) | ||||
| { | ||||
|     mStatsWindow->setValue (id, value); | ||||
|     mCharGen->setValue(id, value); | ||||
| 
 | ||||
|     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) | ||||
| { | ||||
|     mStatsWindow->setValue(parSkill, value); | ||||
|     mCharGen->setValue(parSkill, value); | ||||
|     playerSkillValues[parSkill] = value; | ||||
| } | ||||
| 
 | ||||
|  | @ -338,6 +348,7 @@ void WindowManager::setValue (const std::string& id, const MWMechanics::DynamicS | |||
| { | ||||
|     mStatsWindow->setValue (id, value); | ||||
|     hud->setValue (id, value); | ||||
|     mCharGen->setValue(id, value); | ||||
|     if (id == "HBar") | ||||
|     { | ||||
|         playerHealth = value; | ||||
|  | @ -390,6 +401,7 @@ void WindowManager::setPlayerClass (const ESM::Class &class_) | |||
| void WindowManager::configureSkills (const SkillList& major, const SkillList& minor) | ||||
| { | ||||
|     mStatsWindow->configureSkills (major, minor); | ||||
|     mCharGen->configureSkills(major, minor); | ||||
|     playerMajorSkills = major; | ||||
|     playerMinorSkills = minor; | ||||
| } | ||||
|  | @ -427,7 +439,7 @@ void WindowManager::messageBox (const std::string& message, const std::vector<st | |||
|     else | ||||
|     { | ||||
|         mMessageBoxManager->createInteractiveMessageBox(message, buttons); | ||||
|         setGuiMode(GM_InterMessageBox); | ||||
|         pushGuiMode(GM_InterMessageBox); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | @ -452,7 +464,7 @@ void WindowManager::onDialogueWindowBye() | |||
|         //removeDialog(dialogueWindow);
 | ||||
|         mDialogueWindow->setVisible(false); | ||||
|     } | ||||
|     setGuiMode(GM_Game); | ||||
|     popGuiMode(); | ||||
| } | ||||
| 
 | ||||
| void WindowManager::onFrame (float frameDuration) | ||||
|  | @ -469,6 +481,13 @@ void WindowManager::onFrame (float frameDuration) | |||
|     mInventoryWindow->onFrame(); | ||||
| 
 | ||||
|     mStatsWindow->onFrame(); | ||||
| 
 | ||||
|     hud->onFrame(frameDuration); | ||||
| 
 | ||||
|     mDialogueWindow->checkReferenceAvailable(); | ||||
|     mTradeWindow->checkReferenceAvailable(); | ||||
|     mContainerWindow->checkReferenceAvailable(); | ||||
|     console->checkReferenceAvailable(); | ||||
| } | ||||
| 
 | ||||
| const ESMS::ESMStore& WindowManager::getStore() const | ||||
|  | @ -493,6 +512,7 @@ void WindowManager::changeCell(MWWorld::Ptr::CellStore* cell) | |||
|         } | ||||
| 
 | ||||
|         map->setCellName( name ); | ||||
|         hud->setCellName( name ); | ||||
| 
 | ||||
|         map->setCellPrefix("Cell"); | ||||
|         hud->setCellPrefix("Cell"); | ||||
|  | @ -502,6 +522,7 @@ void WindowManager::changeCell(MWWorld::Ptr::CellStore* cell) | |||
|     else | ||||
|     { | ||||
|         map->setCellName( cell->cell->name ); | ||||
|         hud->setCellName( cell->cell->name ); | ||||
|         map->setCellPrefix( cell->cell->name ); | ||||
|         hud->setCellPrefix( cell->cell->name ); | ||||
|     } | ||||
|  | @ -542,14 +563,6 @@ void WindowManager::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) | ||||
| { | ||||
|     mToolTips->setFocusObject(focus); | ||||
|  | @ -572,12 +585,13 @@ bool WindowManager::getFullHelp() const | |||
| 
 | ||||
| void WindowManager::setWeaponVisibility(bool visible) | ||||
| { | ||||
|     hud->weapBox->setVisible(visible); | ||||
|     hud->setBottomLeftVisibility(hud->health->getVisible(), visible, hud->spellBox->getVisible()); | ||||
| } | ||||
| 
 | ||||
| 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) | ||||
|  | @ -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); | ||||
|     if (setting && setting->type == ESM::VT_String) | ||||
|         _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.size()) | ||||
|         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 <components/esm_store/store.hpp> | ||||
| #include <components/settings/settings.hpp> | ||||
| #include <openengine/ogre/renderer.hpp> | ||||
| #include <openengine/gui/manager.hpp> | ||||
| 
 | ||||
|  | @ -77,6 +78,10 @@ namespace MWGui | |||
|   class MessageBoxManager; | ||||
|   class CountDialog; | ||||
|   class TradeWindow; | ||||
|   class SettingsWindow; | ||||
|   class ConfirmationDialog; | ||||
|   class AlchemyWindow; | ||||
|   class SpellWindow; | ||||
| 
 | ||||
|   struct ClassPoint | ||||
|   { | ||||
|  | @ -96,8 +101,6 @@ namespace MWGui | |||
|     WindowManager(const Compiler::Extensions& extensions, int fpsLevel, bool newGame, OEngine::Render::OgreRenderer *mOgre, const std::string logpath); | ||||
|     virtual ~WindowManager(); | ||||
| 
 | ||||
|     void setGuiMode(GuiMode newMode); | ||||
| 
 | ||||
|     /**
 | ||||
|      * Should be called each frame to update windows/gui elements. | ||||
|      * This could mean updating sizes of gui elements or opening | ||||
|  | @ -105,19 +108,24 @@ namespace MWGui | |||
|      */ | ||||
|     void update(); | ||||
| 
 | ||||
|     void setMode(GuiMode newMode) | ||||
|     { | ||||
|       if (newMode==GM_Inventory && allowed==GW_None) | ||||
|         return; | ||||
|     void pushGuiMode(GuiMode mode); | ||||
|     void popGuiMode(); | ||||
|     void removeGuiMode(GuiMode mode); ///< can be anywhere in the stack
 | ||||
| 
 | ||||
|       mode = newMode; | ||||
|     GuiMode getMode() const | ||||
|     { | ||||
|         if (mGuiModes.empty()) | ||||
|             throw std::runtime_error ("getMode() called, but there is no active mode"); | ||||
|         return mGuiModes.back(); | ||||
|     } | ||||
| 
 | ||||
|     bool isGuiMode() const { return !mGuiModes.empty(); } | ||||
| 
 | ||||
|     void toggleVisible(GuiWindow wnd) | ||||
|     { | ||||
|         shown = (shown & wnd) ? (GuiWindow) (shown & ~wnd) : (GuiWindow) (shown | wnd); | ||||
|         updateVisible(); | ||||
|     } | ||||
|     void setNextMode(GuiMode newMode); | ||||
| 
 | ||||
|     GuiMode getMode() const { return mode; } | ||||
| 
 | ||||
|     bool isGuiMode() const { return getMode() != GM_Game; } // Everything that is not game mode is considered "gui mode"
 | ||||
| 
 | ||||
|     // Disallow all inventory mode windows
 | ||||
|     void disallowAll() | ||||
|  | @ -133,13 +141,21 @@ namespace MWGui | |||
|       updateVisible(); | ||||
|     } | ||||
| 
 | ||||
|     bool isAllowed(GuiWindow wnd) | ||||
|     { | ||||
|         return allowed & wnd; | ||||
|     } | ||||
| 
 | ||||
|     MWGui::DialogueWindow* getDialogueWindow() {return mDialogueWindow;} | ||||
|     MWGui::ContainerWindow* getContainerWindow() {return mContainerWindow;} | ||||
|     MWGui::InventoryWindow* getInventoryWindow() {return mInventoryWindow;} | ||||
|     MWGui::BookWindow* getBookWindow() {return mBookWindow;} | ||||
|     MWGui::ScrollWindow* getScrollWindow() {return mScrollWindow;} | ||||
|     MWGui::CountDialog* getCountDialog() {return mCountDialog;} | ||||
|     MWGui::ConfirmationDialog* getConfirmationDialog() {return mConfirmationDialog;} | ||||
|     MWGui::TradeWindow* getTradeWindow() {return mTradeWindow;} | ||||
|     MWGui::SpellWindow* getSpellWindow() {return mSpellWindow;} | ||||
|     MWGui::Console* getConsole() {return console;} | ||||
| 
 | ||||
|     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 setMouseVisible(bool visible); | ||||
|     void getMousePosition(int &x, int &y); | ||||
|     void getMousePosition(float &x, float &y); | ||||
|     void setDragDrop(bool dragDrop); | ||||
|     bool getWorldMouseOver(); | ||||
| 
 | ||||
|     void toggleFogOfWar(); | ||||
|     void toggleFullHelp(); ///< show extra info in item tooltips (owner, script)
 | ||||
|     bool getFullHelp() const; | ||||
| 
 | ||||
|     int toggleFps(); | ||||
|     ///< toggle fps display @return resulting fps level
 | ||||
| 
 | ||||
|     void setInteriorMapTexture(const int x, const int y); | ||||
|     ///< set the index of the map texture that should be used (for interiors)
 | ||||
| 
 | ||||
|  | @ -192,6 +208,12 @@ namespace MWGui | |||
|     void setWeaponVisibility(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> | ||||
|     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.
 | ||||
|  | @ -201,6 +223,11 @@ namespace MWGui | |||
| 
 | ||||
|     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 | ||||
|      * ID or it is not a string the default string is returned. | ||||
|  | @ -212,6 +239,8 @@ namespace MWGui | |||
| 
 | ||||
|     const ESMS::ESMStore& getStore() const; | ||||
| 
 | ||||
|     void processChangedSettings(const Settings::CategorySettingVector& changed); | ||||
| 
 | ||||
|   private: | ||||
|     OEngine::GUI::MyGUIManager *mGuiManager; | ||||
|     HUD *hud; | ||||
|  | @ -230,6 +259,10 @@ namespace MWGui | |||
|     BookWindow* mBookWindow; | ||||
|     CountDialog* mCountDialog; | ||||
|     TradeWindow* mTradeWindow; | ||||
|     SettingsWindow* mSettingsWindow; | ||||
|     ConfirmationDialog* mConfirmationDialog; | ||||
|     AlchemyWindow* mAlchemyWindow; | ||||
|     SpellWindow* mSpellWindow; | ||||
| 
 | ||||
|     CharacterCreation* mCharGen; | ||||
| 
 | ||||
|  | @ -244,9 +277,7 @@ namespace MWGui | |||
| 
 | ||||
| 
 | ||||
|     MyGUI::Gui *gui; // Gui
 | ||||
|     GuiMode mode; // Current gui mode
 | ||||
|     GuiMode nextMode; // Next mode to activate in update()
 | ||||
|     bool needModeChange; //Whether a mode change is needed in update() [will use nextMode]
 | ||||
|     std::vector<GuiMode> mGuiModes; | ||||
| 
 | ||||
|     std::vector<OEngine::GUI::Layout*> garbageDialogs; | ||||
|     void cleanupGarbage(); | ||||
|  | @ -257,9 +288,6 @@ namespace MWGui | |||
|        the start of the game, when windows are enabled one by one | ||||
|        through script commands. You can manipulate this through using | ||||
|        allow() and disableAll(). | ||||
| 
 | ||||
|        The setting should also affect visibility of certain HUD | ||||
|        elements, but this is not done yet. | ||||
|      */ | ||||
|     GuiWindow allowed; | ||||
| 
 | ||||
|  |  | |||
|  | @ -12,6 +12,7 @@ namespace MWGui | |||
|     public: | ||||
|         WindowPinnableBase(const std::string& parLayout, WindowManager& parWindowManager); | ||||
|         void setVisible(bool b); | ||||
|         bool pinned() { return mPinned; } | ||||
| 
 | ||||
|     private: | ||||
|         void onWindowButtonPressed(MyGUI::Window* sender, const std::string& eventName); | ||||
|  |  | |||
|  | @ -69,7 +69,7 @@ namespace MWInput | |||
|       A_ToggleWeapon, | ||||
|       A_ToggleSpell, | ||||
| 
 | ||||
|       A_ToggleFps, // Toggle FPS display (this is temporary)
 | ||||
|       A_Settings, // Temporary hotkey
 | ||||
| 
 | ||||
|       A_LAST            // Marker for the last item
 | ||||
|     }; | ||||
|  | @ -92,12 +92,12 @@ namespace MWInput | |||
| 
 | ||||
| 
 | ||||
|    /* InputImpl Methods */ | ||||
| 
 | ||||
|     void toggleFps() | ||||
| public: | ||||
|     void adjustMouseRegion(int width, int height) | ||||
|     { | ||||
|         windows.toggleFps(); | ||||
|         input.adjustMouseClippingSize(width, height); | ||||
|     } | ||||
| 
 | ||||
| private: | ||||
|     void toggleSpell() | ||||
|     { | ||||
|         if (windows.isGuiMode()) return; | ||||
|  | @ -140,6 +140,15 @@ namespace MWInput | |||
|         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. */ | ||||
|     void toggleInventory() | ||||
|     { | ||||
|  | @ -148,13 +157,13 @@ namespace MWInput | |||
|         if (mDragDrop) | ||||
|             return; | ||||
| 
 | ||||
|       GuiMode mode = windows.getMode(); | ||||
|         bool gameMode = !windows.isGuiMode(); | ||||
| 
 | ||||
|         // Toggle between game mode and inventory mode
 | ||||
|       if(mode == GM_Game) | ||||
|         setGuiMode(GM_Inventory); | ||||
|       else if(mode == GM_Inventory) | ||||
|         setGuiMode(GM_Game); | ||||
|         if(gameMode) | ||||
|             windows.pushGuiMode(GM_Inventory); | ||||
|         else if(windows.getMode() == GM_Inventory) | ||||
|             windows.popGuiMode(); | ||||
| 
 | ||||
|         // .. but don't touch any other mode.
 | ||||
|     } | ||||
|  | @ -167,27 +176,32 @@ namespace MWInput | |||
|       if (mDragDrop) | ||||
|         return; | ||||
| 
 | ||||
|       GuiMode mode = windows.getMode(); | ||||
|       bool gameMode = !windows.isGuiMode(); | ||||
| 
 | ||||
|       // Switch to console mode no matter what mode we are currently
 | ||||
|       // in, except of course if we are already in console mode
 | ||||
|       if(mode == GM_Console) | ||||
|         setGuiMode(GM_Game); | ||||
|       else setGuiMode(GM_Console); | ||||
|       if (!gameMode) | ||||
|       { | ||||
|           if (windows.getMode() == GM_Console) | ||||
|               windows.popGuiMode(); | ||||
|           else | ||||
|               windows.pushGuiMode(GM_Console); | ||||
|       } | ||||
|       else | ||||
|           windows.pushGuiMode(GM_Console); | ||||
|     } | ||||
| 
 | ||||
|     void toggleJournal() | ||||
|     { | ||||
|         using namespace MWGui; | ||||
| 
 | ||||
|       GuiMode mode = windows.getMode(); | ||||
| 
 | ||||
|         // Toggle between game mode and journal mode
 | ||||
|       if(mode == GM_Game) | ||||
|         setGuiMode(GM_Journal); | ||||
|       else if(mode == GM_Journal) | ||||
|         setGuiMode(GM_Game); | ||||
|         bool gameMode = !windows.isGuiMode(); | ||||
| 
 | ||||
|         if(gameMode) | ||||
|             windows.pushGuiMode(GM_Journal); | ||||
|         else if(windows.getMode() == GM_Journal) | ||||
|             windows.popGuiMode(); | ||||
|         // .. but don't touch any other mode.
 | ||||
|     } | ||||
| 
 | ||||
|  | @ -259,8 +273,8 @@ namespace MWInput | |||
|                       "Draw Weapon"); | ||||
|       disp->funcs.bind(A_ToggleSpell,boost::bind(&InputImpl::toggleSpell,this), | ||||
|                       "Ready hands"); | ||||
|       disp->funcs.bind(A_ToggleFps, boost::bind(&InputImpl::toggleFps, this), | ||||
|                       "Toggle FPS display"); | ||||
|       disp->funcs.bind(A_Settings, boost::bind(&InputImpl::showSettings, this), | ||||
|                       "Show settings window"); | ||||
|       // Add the exit listener
 | ||||
|       ogre.getRoot()->addFrameListener(&exit); | ||||
| 
 | ||||
|  | @ -282,8 +296,7 @@ namespace MWInput | |||
|         lst->add(guiEvents,Event::EV_ALL); | ||||
|       } | ||||
| 
 | ||||
|       // Start out in game mode
 | ||||
|       setGuiMode(MWGui::GM_Game); | ||||
|       changeInputMode(false); | ||||
| 
 | ||||
|       /**********************************
 | ||||
|         Key binding section | ||||
|  | @ -307,7 +320,7 @@ namespace MWInput | |||
|       disp->bind(A_ToggleWalk, KC_C); | ||||
|       disp->bind(A_ToggleWeapon,KC_F); | ||||
|       disp->bind(A_ToggleSpell,KC_R); | ||||
|       disp->bind(A_ToggleFps, KC_F10); | ||||
|       disp->bind(A_Settings, KC_F2); | ||||
| 
 | ||||
|       // Key bindings for polled keys
 | ||||
|       // NOTE: These keys are constantly being polled. Only add keys that must be checked each frame.
 | ||||
|  | @ -348,6 +361,7 @@ namespace MWInput | |||
|         windows.update(); | ||||
| 
 | ||||
|         // Disable movement in Gui mode
 | ||||
| 
 | ||||
|         if (windows.isGuiMode()) return; | ||||
| 
 | ||||
|         // 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
 | ||||
|     // 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?
 | ||||
|       if(windows.isGuiMode()) | ||||
|       if(guiMode) | ||||
|         { | ||||
|           // Disable mouse look
 | ||||
|           mouse->setCamera(NULL); | ||||
|  | @ -431,11 +441,6 @@ namespace MWInput | |||
|     delete impl; | ||||
|   } | ||||
| 
 | ||||
|   void MWInputManager::setGuiMode(MWGui::GuiMode mode) | ||||
|   { | ||||
|       impl->setGuiMode(mode); | ||||
|   } | ||||
| 
 | ||||
|   void MWInputManager::update() | ||||
|   { | ||||
|       impl->update(); | ||||
|  | @ -445,4 +450,25 @@ namespace MWInput | |||
|   { | ||||
|       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 <components/settings/settings.hpp> | ||||
| 
 | ||||
| namespace OEngine | ||||
| { | ||||
|   namespace Render | ||||
|  | @ -50,9 +52,11 @@ namespace MWInput | |||
| 
 | ||||
|     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 | ||||
|  |  | |||
|  | @ -71,7 +71,10 @@ namespace MWMechanics | |||
| 
 | ||||
|     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) | ||||
|  |  | |||
|  | @ -32,6 +32,8 @@ namespace MWMechanics | |||
| 
 | ||||
|             void removeActor (const MWWorld::Ptr& ptr); | ||||
|             ///< Deregister an actor for stats management
 | ||||
|             ///
 | ||||
|             /// \note Ignored, if \a ptr is not a registered actor.
 | ||||
| 
 | ||||
|             void dropActors (const MWWorld::Ptr::CellStore *cellStore); | ||||
|             ///< Deregister all actors in the given cell.
 | ||||
|  |  | |||
|  | @ -30,6 +30,15 @@ namespace MWMechanics | |||
|         for (int i=0; i<27; ++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
 | ||||
|         if (mRaceSelected) | ||||
|         { | ||||
|  |  | |||
|  | @ -28,7 +28,7 @@ namespace MWMechanics | |||
| 
 | ||||
|     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); | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										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 | ||||
							
								
								
									
										71
									
								
								apps/openmw/mwrender/compositors.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								apps/openmw/mwrender/compositors.cpp
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,71 @@ | |||
| #include "compositors.hpp" | ||||
| 
 | ||||
| #include <OgreViewport.h> | ||||
| #include <OgreCompositorManager.h> | ||||
| 
 | ||||
| using namespace MWRender; | ||||
| 
 | ||||
| Compositors::Compositors(Ogre::Viewport* vp) : | ||||
|       mViewport(vp) | ||||
|     , mEnabled(true) | ||||
| { | ||||
| } | ||||
| 
 | ||||
| Compositors::~Compositors() | ||||
| { | ||||
|     Ogre::CompositorManager::getSingleton().removeCompositorChain(mViewport); | ||||
| } | ||||
| 
 | ||||
| void Compositors::setEnabled (const bool enabled) | ||||
| { | ||||
|     for (CompositorMap::iterator it=mCompositors.begin(); | ||||
|         it != mCompositors.end(); ++it) | ||||
|     { | ||||
|         Ogre::CompositorManager::getSingleton().setCompositorEnabled(mViewport, it->first, enabled && it->second.first); | ||||
|     } | ||||
|     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) | ||||
| { | ||||
|     int id = 0; | ||||
| 
 | ||||
|     for (CompositorMap::iterator it=mCompositors.begin(); | ||||
|         it != mCompositors.end(); ++it) | ||||
|     { | ||||
|         if (it->second.second > priority) | ||||
|             break; | ||||
|         ++id; | ||||
|     } | ||||
|     Ogre::CompositorManager::getSingleton().addCompositor (mViewport, name, id); | ||||
| 
 | ||||
|     mCompositors[name] = std::make_pair(false, priority); | ||||
| } | ||||
| 
 | ||||
| void Compositors::setCompositorEnabled (const std::string& name, const bool enabled) | ||||
| { | ||||
|     mCompositors[name].first = enabled; | ||||
|     Ogre::CompositorManager::getSingleton().setCompositorEnabled (mViewport, name, enabled && mEnabled); | ||||
| } | ||||
| 
 | ||||
| void Compositors::removeAll() | ||||
| { | ||||
|     Ogre::CompositorManager::getSingleton().removeCompositorChain(mViewport); | ||||
| 
 | ||||
|     mCompositors.clear(); | ||||
| } | ||||
							
								
								
									
										60
									
								
								apps/openmw/mwrender/compositors.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								apps/openmw/mwrender/compositors.hpp
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,60 @@ | |||
| #ifndef GAME_MWRENDER_COMPOSITORS_H | ||||
| #define GAME_MWRENDER_COMPOSITORS_H | ||||
| 
 | ||||
| #include <map> | ||||
| #include <string> | ||||
| 
 | ||||
| namespace Ogre | ||||
| { | ||||
|     class Viewport; | ||||
| } | ||||
| 
 | ||||
| namespace MWRender | ||||
| { | ||||
|     typedef std::map < std::string, std::pair<bool, int> > CompositorMap; | ||||
| 
 | ||||
|     /// \brief Manages a set of compositors for one viewport
 | ||||
|     class Compositors | ||||
|     { | ||||
|     public: | ||||
|         Compositors(Ogre::Viewport* vp); | ||||
|         virtual ~Compositors(); | ||||
| 
 | ||||
|         /**
 | ||||
|          *  enable or disable all compositors globally | ||||
|          */ | ||||
|         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; } | ||||
| 
 | ||||
|         /**
 | ||||
|          * enable or disable a specific compositor | ||||
|          * @note enable has no effect if all compositors are globally disabled | ||||
|          */ | ||||
|         void setCompositorEnabled (const std::string& name, const bool enabled); | ||||
| 
 | ||||
|         /**
 | ||||
|          * @param name of compositor | ||||
|          * @param priority, lower number will be first in the chain | ||||
|          */ | ||||
|         void addCompositor (const std::string& name, const int priority); | ||||
| 
 | ||||
|         void removeAll (); | ||||
| 
 | ||||
|     protected: | ||||
|         /// maps compositor name to its "enabled" state
 | ||||
|         CompositorMap mCompositors; | ||||
| 
 | ||||
|         bool mEnabled; | ||||
| 
 | ||||
|         Ogre::Viewport* mViewport; | ||||
|     }; | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| #endif | ||||
|  | @ -307,28 +307,53 @@ void LocalMap::updatePlayer (const Ogre::Vector3& position, const Ogre::Quaterni | |||
| 
 | ||||
|     // convert from world coordinates to texture UV coordinates
 | ||||
|     float u,v; | ||||
|     std::string texName; | ||||
|     std::string texBaseName; | ||||
|     if (!mInterior) | ||||
|     { | ||||
|         u = std::abs((pos.x - (sSize*x))/sSize); | ||||
|         v = 1-std::abs((pos.y + (sSize*y))/sSize); | ||||
|         texName = "Cell_"+coordStr(x,y); | ||||
|         texBaseName = "Cell_"; | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         u = (pos.x - min.x - sSize*x)/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()->setPlayerDir(playerdirection.x, -playerdirection.z); | ||||
| 
 | ||||
|     // 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)
 | ||||
| 
 | ||||
|     int intExtMult = mInterior ? 1 : -1; // interior and exterior have reversed Y coordinates (interior: top to bottom)
 | ||||
| 
 | ||||
|     // change the affected fog of war textures (in a 3x3 grid around the player)
 | ||||
|     for (int mx = -1; mx<2; ++mx) | ||||
|     { | ||||
|         for (int my = -1; my<2; ++my) | ||||
|         { | ||||
| 
 | ||||
|             // 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); | ||||
| 
 | ||||
|     // get the appropriate fog of war texture
 | ||||
|             TexturePtr tex = TextureManager::getSingleton().getByName(texName+"_fog"); | ||||
|             if (!tex.isNull()) | ||||
|             { | ||||
|  | @ -339,7 +364,11 @@ void LocalMap::updatePlayer (const Ogre::Vector3& position, const Ogre::Quaterni | |||
|                 { | ||||
|                     for (int texU = 0; texU<sFogOfWarResolution; ++texU) | ||||
|                     { | ||||
|                 float sqrDist = Math::Sqr(texU - u*sFogOfWarResolution) + Math::Sqr(texV - v*sFogOfWarResolution); | ||||
|                         // 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) ); | ||||
|  | @ -353,4 +382,6 @@ void LocalMap::updatePlayer (const Ogre::Vector3& position, const Ogre::Quaterni | |||
|                 memcpy(tex->getBuffer()->lock(HardwareBuffer::HBL_DISCARD), &mBuffers[texName][0], sFogOfWarResolution*sFogOfWarResolution*4); | ||||
|                 tex->getBuffer()->unlock(); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -6,4 +6,22 @@ namespace MWRender | |||
|     Player::Player (Ogre::Camera *camera, Ogre::SceneNode* 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; } | ||||
| 
 | ||||
|                 /// 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(); } | ||||
|                 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/ptr.hpp" | ||||
| #include "../mwworld/player.hpp" | ||||
| #include "../mwbase/environment.hpp" | ||||
| #include <components/esm/loadstat.hpp> | ||||
| #include <components/settings/settings.hpp> | ||||
|  | @ -19,6 +20,10 @@ | |||
| #include "shaderhelper.hpp" | ||||
| #include "localmap.hpp" | ||||
| #include "water.hpp" | ||||
| #include "compositors.hpp" | ||||
| 
 | ||||
| #include "../mwgui/window_manager.hpp" // FIXME
 | ||||
| #include "../mwinput/inputmanager.hpp" // FIXME
 | ||||
| 
 | ||||
| using namespace MWRender; | ||||
| using namespace Ogre; | ||||
|  | @ -29,6 +34,9 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const | |||
|     :mRendering(_rend), mObjects(mRendering), mActors(mRendering), mAmbientMode(0), mSunEnabled(0) | ||||
| { | ||||
|     mRendering.createScene("PlayerCam", Settings::Manager::getFloat("field of view", "General"), 5); | ||||
|     mRendering.setWindowEventListener(this); | ||||
| 
 | ||||
|     mCompositors = new Compositors(mRendering.getViewport()); | ||||
| 
 | ||||
|     mWater = 0; | ||||
| 
 | ||||
|  | @ -59,25 +67,13 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const | |||
| 
 | ||||
|     // disable unsupported effects
 | ||||
|     const RenderSystemCapabilities* caps = Root::getSingleton().getRenderSystem()->getCapabilities(); | ||||
|     if (caps->getNumMultiRenderTargets() < 2 || !Settings::Manager::getBool("shaders", "Objects")) | ||||
|     if (!waterShaderSupported()) | ||||
|         Settings::Manager::setBool("shader", "Water", false); | ||||
|     if ( !(caps->isShaderProfileSupported("fp40") || caps->isShaderProfileSupported("ps_4_0")) | ||||
|         || !Settings::Manager::getBool("shaders", "Objects")) | ||||
|         Settings::Manager::setBool("enabled", "Shadows", false); | ||||
| 
 | ||||
|     // note that the order is important here
 | ||||
|     if (useMRT()) | ||||
|     { | ||||
|         CompositorManager::getSingleton().addCompositor(mRendering.getViewport(), "gbuffer"); | ||||
|         CompositorManager::getSingleton().setCompositorEnabled(mRendering.getViewport(), "gbuffer", true); | ||||
|         CompositorManager::getSingleton().addCompositor(mRendering.getViewport(), "Underwater"); | ||||
|         CompositorManager::getSingleton().addCompositor(mRendering.getViewport(), "gbufferFinalizer"); | ||||
|         CompositorManager::getSingleton().setCompositorEnabled(mRendering.getViewport(), "gbufferFinalizer", true); | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         CompositorManager::getSingleton().addCompositor(mRendering.getViewport(), "UnderwaterNoMRT"); | ||||
|     } | ||||
|     applyCompositors(); | ||||
| 
 | ||||
|     // Turn the entire scene (represented by the 'root' node) -90
 | ||||
|     // degrees around the x axis. This makes Z go upwards, and Y go into
 | ||||
|  | @ -111,6 +107,8 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const | |||
| 
 | ||||
|     mDebugging = new Debugging(mMwRoot, engine); | ||||
|     mLocalMap = new MWRender::LocalMap(&mRendering, this); | ||||
| 
 | ||||
|     setMenuTransparency(Settings::Manager::getFloat("menu transparency", "GUI")); | ||||
| } | ||||
| 
 | ||||
| RenderingManager::~RenderingManager () | ||||
|  | @ -121,6 +119,7 @@ RenderingManager::~RenderingManager () | |||
|     delete mTerrainManager; | ||||
|     delete mLocalMap; | ||||
|     delete mOcclusionQuery; | ||||
|     delete mCompositors; | ||||
| } | ||||
| 
 | ||||
| MWRender::SkyManager* RenderingManager::getSkyManager() | ||||
|  | @ -235,7 +234,7 @@ void RenderingManager::waterAdded (MWWorld::Ptr::CellStore *store){ | |||
|             && !MWBase::Environment::get().getWorld()->getStore().lands.search(store->cell->data.gridX,store->cell->data.gridY) )) // always use water, if the cell does not have land.
 | ||||
|     { | ||||
|         if(mWater == 0) | ||||
|             mWater = new MWRender::Water(mRendering.getCamera(), mSkyManager, store->cell); | ||||
|             mWater = new MWRender::Water(mRendering.getCamera(), this, store->cell); | ||||
|         else | ||||
|             mWater->changeCell(store->cell); | ||||
|         mWater->setActive(true); | ||||
|  | @ -295,35 +294,29 @@ void RenderingManager::skySetMoonColour (bool red){ | |||
| 
 | ||||
| bool RenderingManager::toggleRenderMode(int mode) | ||||
| { | ||||
|     if (mode != MWWorld::World::Render_Wireframe) | ||||
|     if (mode == MWWorld::World::Render_CollisionDebug || mode == MWWorld::World::Render_Pathgrid) | ||||
|         return mDebugging->toggleRenderMode(mode); | ||||
|     else // if (mode == MWWorld::World::Render_Wireframe)
 | ||||
|     else if (mode == MWWorld::World::Render_Wireframe) | ||||
|     { | ||||
|         if (mRendering.getCamera()->getPolygonMode() == PM_SOLID) | ||||
|         { | ||||
|             // disable compositors
 | ||||
|             if (useMRT()) | ||||
|             { | ||||
|                 CompositorManager::getSingleton().setCompositorEnabled(mRendering.getViewport(), "gbuffer", false); | ||||
|                 CompositorManager::getSingleton().setCompositorEnabled(mRendering.getViewport(), "gbufferFinalizer", false); | ||||
|             } | ||||
|             mCompositors->setEnabled(false); | ||||
| 
 | ||||
|             mRendering.getCamera()->setPolygonMode(PM_WIREFRAME); | ||||
|             return true; | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             // re-enable compositors
 | ||||
|             if (useMRT()) | ||||
|             { | ||||
|                 CompositorManager::getSingleton().setCompositorEnabled(mRendering.getViewport(), "gbuffer", true); | ||||
|                 CompositorManager::getSingleton().setCompositorEnabled(mRendering.getViewport(), "gbufferFinalizer", true); | ||||
|             } | ||||
|             mCompositors->setEnabled(true); | ||||
| 
 | ||||
|             mRendering.getCamera()->setPolygonMode(PM_SOLID); | ||||
|             return false; | ||||
|         } | ||||
|     } | ||||
|     else //if (mode == MWWorld::World::Render_Compositors)
 | ||||
|     { | ||||
|         return mCompositors->toggle(); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void RenderingManager::configureFog(ESMS::CellStore<MWWorld::RefData> &mCell) | ||||
|  | @ -560,4 +553,124 @@ Ogre::Vector4 RenderingManager::boundingBoxToScreen(Ogre::AxisAlignedBox bounds) | |||
|     return Vector4(min_x, min_y, max_x, max_y); | ||||
| } | ||||
| 
 | ||||
| Compositors* RenderingManager::getCompositors() | ||||
| { | ||||
|     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
 | ||||
|  |  | |||
|  | @ -8,11 +8,15 @@ | |||
| 
 | ||||
| #include "../mwworld/class.hpp" | ||||
| 
 | ||||
| #include <OgreWindowEventUtilities.h> | ||||
| 
 | ||||
| #include <utility> | ||||
| #include <openengine/ogre/renderer.hpp> | ||||
| #include <openengine/ogre/fader.hpp> | ||||
| #include <openengine/bullet/physic.hpp> | ||||
| 
 | ||||
| #include <components/settings/settings.hpp> | ||||
| 
 | ||||
| #include <vector> | ||||
| #include <string> | ||||
| 
 | ||||
|  | @ -47,8 +51,9 @@ namespace MWRender | |||
|     class ShaderHelper; | ||||
|     class LocalMap; | ||||
|     class Water; | ||||
|     class Compositors; | ||||
| 
 | ||||
| class RenderingManager: private RenderingInterface { | ||||
| class RenderingManager: private RenderingInterface, public Ogre::WindowEventListener { | ||||
| 
 | ||||
|   private: | ||||
| 
 | ||||
|  | @ -67,6 +72,7 @@ class RenderingManager: private RenderingInterface { | |||
|                                             /// to internal details of the rendering system anymore
 | ||||
| 
 | ||||
|     SkyManager* getSkyManager(); | ||||
|     Compositors* getCompositors(); | ||||
| 
 | ||||
|     void toggleLight(); | ||||
|     bool toggleRenderMode(int mode); | ||||
|  | @ -155,10 +161,24 @@ class RenderingManager: private RenderingInterface { | |||
|     ///< transform the specified bounding box (in world coordinates) into screen coordinates.
 | ||||
|     /// @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: | ||||
| 
 | ||||
|     void setAmbientMode(); | ||||
| 
 | ||||
|     void setMenuTransparency(float val); | ||||
| 
 | ||||
|     void applyCompositors(); | ||||
| 
 | ||||
|     bool mSunEnabled; | ||||
| 
 | ||||
|     SkyManager* mSkyManager; | ||||
|  | @ -196,6 +216,8 @@ class RenderingManager: private RenderingInterface { | |||
|     MWRender::Shadows* mShadows; | ||||
| 
 | ||||
|     MWRender::ShaderHelper* mShaderHelper; | ||||
| 
 | ||||
|     MWRender::Compositors* mCompositors; | ||||
| }; | ||||
| 
 | ||||
| } | ||||
|  |  | |||
|  | @ -258,7 +258,7 @@ void ShaderHelper::createShader(const bool mrt, const bool shadows, const bool s | |||
|         outStream << | ||||
|         "   float3 lightingFinal = lightColour.xyz * diffuse.xyz + ambient.xyz * lightAmbient.xyz + emissive.xyz; \n" | ||||
|         "   float fogValue = saturate((iDepth - fogParams.y) * fogParams.w); \n" | ||||
|         "   oColor.xyz = lerp(lightingFinal * tex.xyz * vertexColour.xyz, fogColour.xyz, fogValue); \n" | ||||
|         "   oColor.xyz = saturate(lerp(lightingFinal * tex.xyz * vertexColour.xyz, fogColour.xyz, fogValue)); \n" // saturate output to prevent negative output colors - TODO: replace this once there is HDR-rendering
 | ||||
|         "   oColor.a = tex.a * diffuse.a * vertexColour.a; \n"; | ||||
| 
 | ||||
|         if (mrt) outStream << | ||||
|  |  | |||
|  | @ -113,6 +113,7 @@ void BillboardObject::init(const String& textureName, | |||
|     p->setSelfIllumination(1.0,1.0,1.0); | ||||
|     p->setDiffuse(0.0,0.0,0.0,1.0); | ||||
|     p->setAmbient(0.0,0.0,0.0); | ||||
|     p->setPolygonModeOverrideable(false); | ||||
|     p->createTextureUnitState(textureName); | ||||
|     mBBSet->setMaterialName("BillboardMaterial"+StringConverter::toString(bodyCount)); | ||||
| 
 | ||||
|  | @ -373,7 +374,7 @@ SkyManager::SkyManager (SceneNode* pMwRoot, Camera* pCamera) | |||
|     , mSunGlare(NULL) | ||||
|     , mMasser(NULL) | ||||
|     , mSecunda(NULL) | ||||
|     , mViewport(NULL) | ||||
|     , mCamera(pCamera) | ||||
|     , mRootNode(NULL) | ||||
|     , mSceneMgr(NULL) | ||||
|     , mAtmosphereDay(NULL) | ||||
|  | @ -398,9 +399,8 @@ SkyManager::SkyManager (SceneNode* pMwRoot, Camera* pCamera) | |||
|     , mSecundaEnabled(true) | ||||
|     , mCreated(false) | ||||
| { | ||||
|     mViewport = pCamera->getViewport(); | ||||
|     mSceneMgr = pMwRoot->getCreator(); | ||||
|     mRootNode = pCamera->getParentSceneNode()->createChildSceneNode(); | ||||
|     mRootNode = mCamera->getParentSceneNode()->createChildSceneNode(); | ||||
|     mRootNode->pitch(Degree(-90)); // convert MW to ogre coordinates
 | ||||
|     mRootNode->setInheritOrientation(false); | ||||
| } | ||||
|  | @ -520,6 +520,7 @@ void SkyManager::create() | |||
|         mp->getTechnique(0)->getPass(0)->setSceneBlending(SBT_TRANSPARENT_ALPHA); | ||||
|         mp->getTechnique(0)->getPass(0)->setVertexProgram(stars_vp->getName()); | ||||
|         mp->getTechnique(0)->getPass(0)->setFragmentProgram(stars_fp->getName()); | ||||
|         mp->getTechnique(0)->getPass(0)->setPolygonModeOverrideable(false); | ||||
|         mStarsMaterials[i] = mp; | ||||
|     } | ||||
| 
 | ||||
|  | @ -535,6 +536,7 @@ void SkyManager::create() | |||
|     mAtmosphereDay = mRootNode->createChildSceneNode(); | ||||
|     mAtmosphereDay->attachObject(atmosphere_ent); | ||||
|     mAtmosphereMaterial = atmosphere_ent->getSubEntity(0)->getMaterial(); | ||||
|     mAtmosphereMaterial->getTechnique(0)->getPass(0)->setPolygonModeOverrideable(false); | ||||
| 
 | ||||
|     // Atmosphere shader
 | ||||
|     HighLevelGpuProgramPtr vshader = mgr.createProgram("Atmosphere_VP", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, | ||||
|  | @ -598,6 +600,7 @@ void SkyManager::create() | |||
|     SceneNode* clouds_node = mRootNode->createChildSceneNode(); | ||||
|     clouds_node->attachObject(clouds_ent); | ||||
|     mCloudMaterial = clouds_ent->getSubEntity(0)->getMaterial(); | ||||
|     mCloudMaterial->getTechnique(0)->getPass(0)->setPolygonModeOverrideable(false); | ||||
|     clouds_ent->setCastShadows(false); | ||||
| 
 | ||||
|     // Clouds vertex shader
 | ||||
|  | @ -737,7 +740,7 @@ void SkyManager::update(float duration) | |||
|         // on how directly the player is looking at the sun
 | ||||
|         Vector3 sun = mSunGlare->getPosition(); | ||||
|         sun = Vector3(sun.x, sun.z, -sun.y); | ||||
|         Vector3 cam = mViewport->getCamera()->getRealDirection(); | ||||
|         Vector3 cam = mCamera->getRealDirection(); | ||||
|         const Degree angle = sun.angleBetween( cam ); | ||||
|         float val = 1- (angle.valueDegrees() / 180.f); | ||||
|         val = (val*val*val*val)*2; | ||||
|  |  | |||
|  | @ -185,7 +185,7 @@ namespace MWRender | |||
|         Moon* mMasser; | ||||
|         Moon* mSecunda; | ||||
| 
 | ||||
|         Ogre::Viewport* mViewport; | ||||
|         Ogre::Camera* mCamera; | ||||
|         Ogre::SceneNode* mRootNode; | ||||
|         Ogre::SceneManager* mSceneMgr; | ||||
| 
 | ||||
|  |  | |||
|  | @ -22,30 +22,30 @@ namespace MWRender | |||
|     TerrainManager::TerrainManager(Ogre::SceneManager* mgr, RenderingManager* rend) : | ||||
|          mTerrainGroup(TerrainGroup(mgr, Terrain::ALIGN_X_Z, mLandSize, mWorldSize)), mRendering(rend) | ||||
|     { | ||||
| 
 | ||||
|         mTerrainGlobals = OGRE_NEW TerrainGlobalOptions(); | ||||
|         TerrainMaterialGeneratorPtr matGen; | ||||
|         TerrainMaterialGeneratorB* matGenP = new TerrainMaterialGeneratorB(); | ||||
|         matGen.bind(matGenP); | ||||
|         mTerrainGlobals.setDefaultMaterialGenerator(matGen); | ||||
|         mTerrainGlobals->setDefaultMaterialGenerator(matGen); | ||||
| 
 | ||||
|         TerrainMaterialGenerator::Profile* const activeProfile = | ||||
|             mTerrainGlobals.getDefaultMaterialGenerator() | ||||
|             mTerrainGlobals->getDefaultMaterialGenerator() | ||||
|                            ->getActiveProfile(); | ||||
|         mActiveProfile = static_cast<TerrainMaterialGeneratorB::SM2Profile*>(activeProfile); | ||||
| 
 | ||||
|         //The pixel error should be as high as possible without it being noticed
 | ||||
|         //as it governs how fast mesh quality decreases.
 | ||||
|         mTerrainGlobals.setMaxPixelError(8); | ||||
|         mTerrainGlobals->setMaxPixelError(8); | ||||
| 
 | ||||
|         mTerrainGlobals.setLayerBlendMapSize(32); | ||||
|         mTerrainGlobals.setDefaultGlobalColourMapSize(65); | ||||
|         mTerrainGlobals->setLayerBlendMapSize(32); | ||||
|         mTerrainGlobals->setDefaultGlobalColourMapSize(65); | ||||
| 
 | ||||
|         //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,
 | ||||
|         //this seemed the distance where it wasn't too noticeable
 | ||||
|         mTerrainGlobals.setCompositeMapDistance(mWorldSize*2); | ||||
|         mTerrainGlobals->setCompositeMapDistance(mWorldSize*2); | ||||
| 
 | ||||
|         mActiveProfile->setLightmapEnabled(false); | ||||
|         mActiveProfile->setLayerSpecularMappingEnabled(false); | ||||
|  | @ -86,20 +86,21 @@ namespace MWRender | |||
| 
 | ||||
|     TerrainManager::~TerrainManager() | ||||
|     { | ||||
|         OGRE_DELETE mTerrainGlobals; | ||||
|     } | ||||
| 
 | ||||
|     //----------------------------------------------------------------------------------------------
 | ||||
| 
 | ||||
|     void TerrainManager::setDiffuse(const ColourValue& diffuse) | ||||
|     { | ||||
|         mTerrainGlobals.setCompositeMapDiffuse(diffuse); | ||||
|         mTerrainGlobals->setCompositeMapDiffuse(diffuse); | ||||
|     } | ||||
| 
 | ||||
|     //----------------------------------------------------------------------------------------------
 | ||||
| 
 | ||||
|     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 cellRemoved(MWWorld::Ptr::CellStore* store); | ||||
|     private: | ||||
|         Ogre::TerrainGlobalOptions mTerrainGlobals; | ||||
|         Ogre::TerrainGlobalOptions* mTerrainGlobals; | ||||
|         Ogre::TerrainGroup mTerrainGroup; | ||||
| 
 | ||||
|         RenderingManager* mRendering; | ||||
|  |  | |||
|  | @ -1,25 +1,21 @@ | |||
| #include "water.hpp" | ||||
| #include <components/settings/settings.hpp> | ||||
| 
 | ||||
| #include "sky.hpp" | ||||
| #include "renderingmanager.hpp" | ||||
| #include "compositors.hpp" | ||||
| 
 | ||||
| using namespace Ogre; | ||||
| 
 | ||||
| namespace MWRender | ||||
| { | ||||
| 
 | ||||
| Water::Water (Ogre::Camera *camera, SkyManager* sky, const ESM::Cell* cell) : | ||||
|     mCamera (camera), mViewport (camera->getViewport()), mSceneManager (camera->getSceneManager()), | ||||
| Water::Water (Ogre::Camera *camera, RenderingManager* rend, const ESM::Cell* cell) : | ||||
|     mCamera (camera), mSceneManager (camera->getSceneManager()), | ||||
|     mIsUnderwater(false), mVisibilityFlags(0), | ||||
|     mReflectionTarget(0), mActive(1), mToggled(1), | ||||
|     mReflectionRenderActive(false) | ||||
|     mReflectionRenderActive(false), mRendering(rend) | ||||
| { | ||||
|     mSky = sky; | ||||
| 
 | ||||
|     try | ||||
|     { | ||||
|         CompositorManager::getSingleton().setCompositorEnabled(mViewport, "Water", false); | ||||
|     } catch(...) {} | ||||
|     mSky = rend->getSkyManager(); | ||||
| 
 | ||||
|     mTop = cell->water; | ||||
| 
 | ||||
|  | @ -34,13 +30,6 @@ Water::Water (Ogre::Camera *camera, SkyManager* sky, const ESM::Cell* cell) : | |||
|     mWater->setRenderQueueGroup(RQG_Water); | ||||
|     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->setPosition(0, mTop, 0); | ||||
| 
 | ||||
|  | @ -52,30 +41,9 @@ Water::Water (Ogre::Camera *camera, SkyManager* sky, const ESM::Cell* cell) : | |||
|     } | ||||
|     mWaterNode->attachObject(mWater); | ||||
| 
 | ||||
|     // Create rendertarget for reflection
 | ||||
|     int rttsize = Settings::Manager::getInt("rtt size", "Water"); | ||||
|     applyRTT(); | ||||
|     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(); | ||||
|     mWater->setMaterial(mMaterial); | ||||
|  | @ -84,6 +52,8 @@ Water::Water (Ogre::Camera *camera, SkyManager* sky, const ESM::Cell* cell) : | |||
| 
 | ||||
|     mSceneManager->addRenderQueueListener(this); | ||||
| 
 | ||||
|     assignTextures(); | ||||
| 
 | ||||
| 
 | ||||
|     // ----------------------------------------------------------------------------------------------
 | ||||
|     // ---------------------------------- reflection debug overlay ----------------------------------
 | ||||
|  | @ -147,8 +117,6 @@ Water::~Water() | |||
|     mWaterNode->detachObject(mWater); | ||||
|     mSceneManager->destroyEntity(mWater); | ||||
|     mSceneManager->destroySceneNode(mWaterNode); | ||||
| 
 | ||||
|     CompositorManager::getSingleton().removeCompositorChain(mViewport); | ||||
| } | ||||
| 
 | ||||
| void Water::changeCell(const ESM::Cell* cell) | ||||
|  | @ -178,13 +146,13 @@ void Water::checkUnderwater(float y) | |||
| { | ||||
|     if (!mActive) | ||||
|     { | ||||
|         CompositorManager::getSingleton().setCompositorEnabled(mViewport, mCompositorName, false); | ||||
|         mRendering->getCompositors()->setCompositorEnabled(mCompositorName, false); | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     if ((mIsUnderwater && y > mTop) || !mWater->isVisible() || mCamera->getPolygonMode() != Ogre::PM_SOLID) | ||||
|     { | ||||
|         CompositorManager::getSingleton().setCompositorEnabled(mViewport, mCompositorName, false); | ||||
|         mRendering->getCompositors()->setCompositorEnabled(mCompositorName, false); | ||||
| 
 | ||||
|         // tell the shader we are not underwater
 | ||||
|         Ogre::Pass* pass = mMaterial->getTechnique(0)->getPass(0); | ||||
|  | @ -199,7 +167,7 @@ void Water::checkUnderwater(float y) | |||
|     if (!mIsUnderwater && y < mTop && mWater->isVisible() && mCamera->getPolygonMode() == Ogre::PM_SOLID) | ||||
|     { | ||||
|         if (mUnderwaterEffect) | ||||
|             CompositorManager::getSingleton().setCompositorEnabled(mViewport, mCompositorName, true); | ||||
|             mRendering->getCompositors()->setCompositorEnabled(mCompositorName, true); | ||||
| 
 | ||||
|         // tell the shader we are underwater
 | ||||
|         Ogre::Pass* pass = mMaterial->getTechnique(0)->getPass(0); | ||||
|  | @ -255,7 +223,15 @@ void Water::postRenderTargetUpdate(const RenderTargetEvent& evt) | |||
| 
 | ||||
| void Water::createMaterial() | ||||
| { | ||||
|     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
 | ||||
|     std::string textureNames[32]; | ||||
|  | @ -263,15 +239,20 @@ void Water::createMaterial() | |||
|     { | ||||
|         textureNames[i] = "textures\\water\\water" + StringConverter::toString(i, 2, '0') + ".dds"; | ||||
|     } | ||||
|     mMaterial->getTechnique(1)->getPass(0)->getTextureUnitState(0)->setAnimatedTextureName(textureNames, 32, 2); | ||||
| 
 | ||||
|     // use technique without shaders if reflection is disabled
 | ||||
|     Ogre::Technique* tech; | ||||
|     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")) | ||||
|     { | ||||
|         CompositorInstance* compositor = CompositorManager::getSingleton().getCompositorChain(mViewport)->getCompositor("gbuffer"); | ||||
|         CompositorInstance* compositor = CompositorManager::getSingleton().getCompositorChain(mRendering->getViewport())->getCompositor("gbuffer"); | ||||
| 
 | ||||
|         TexturePtr colorTexture = compositor->getTextureInstance("mrt_output", 0); | ||||
|         TextureUnitState* tus = mMaterial->getTechnique(0)->getPass(0)->getTextureUnitState("refractionMap"); | ||||
|  | @ -321,4 +302,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
 | ||||
|  |  | |||
|  | @ -3,12 +3,15 @@ | |||
| 
 | ||||
| #include <Ogre.h> | ||||
| #include <components/esm/loadcell.hpp> | ||||
| #include <components/settings/settings.hpp> | ||||
| 
 | ||||
| #include "renderconst.hpp" | ||||
| 
 | ||||
| 
 | ||||
| namespace MWRender { | ||||
| 
 | ||||
|     class SkyManager; | ||||
|     class RenderingManager; | ||||
| 
 | ||||
|     /// Water rendering 	
 | ||||
|     class Water : public Ogre::RenderTargetListener, public Ogre::RenderQueueListener | ||||
|  | @ -16,7 +19,6 @@ namespace MWRender { | |||
|         static const int CELL_SIZE = 8192; | ||||
|         Ogre::Camera *mCamera; | ||||
|         Ogre::SceneManager *mSceneManager; | ||||
|         Ogre::Viewport *mViewport; | ||||
| 
 | ||||
|         Ogre::Plane mWaterPlane; | ||||
|         Ogre::SceneNode *mWaterNode; | ||||
|  | @ -38,8 +40,12 @@ namespace MWRender { | |||
|         void renderQueueStarted (Ogre::uint8 queueGroupId, const Ogre::String &invocation, bool &skipThisInvocation); | ||||
|         void renderQueueEnded (Ogre::uint8 queueGroupId, const Ogre::String &invocation, bool &repeatThisInvocation); | ||||
| 
 | ||||
|         void applyRTT(); | ||||
|         void applyVisibilityMask(); | ||||
| 
 | ||||
|         void updateVisible(); | ||||
| 
 | ||||
|         RenderingManager* mRendering; | ||||
|         SkyManager* mSky; | ||||
| 
 | ||||
|         std::string mCompositorName; | ||||
|  | @ -49,13 +55,14 @@ namespace MWRender { | |||
| 
 | ||||
|         Ogre::Camera* mReflectionCamera; | ||||
| 
 | ||||
|         Ogre::TexturePtr mReflectionTexture; | ||||
|         Ogre::RenderTarget* mReflectionTarget; | ||||
| 
 | ||||
|         bool mUnderwaterEffect; | ||||
|         int mVisibilityFlags; | ||||
| 
 | ||||
|     public: | ||||
|         Water (Ogre::Camera *camera, SkyManager* sky, const ESM::Cell* cell); | ||||
|         Water (Ogre::Camera *camera, RenderingManager* rend, const ESM::Cell* cell); | ||||
|         ~Water(); | ||||
| 
 | ||||
|         void setActive(bool active); | ||||
|  | @ -63,8 +70,12 @@ namespace MWRender { | |||
|         void toggle(); | ||||
|         void update(); | ||||
| 
 | ||||
|         void assignTextures(); | ||||
| 
 | ||||
|         void setViewportBackground(const Ogre::ColourValue& bg); | ||||
| 
 | ||||
|         void processChangedSettings(const Settings::CategorySettingVector& settings); | ||||
| 
 | ||||
|         void checkUnderwater(float y); | ||||
|         void changeCell(const ESM::Cell* cell); | ||||
|         void setHeight(const float height); | ||||
|  |  | |||
|  | @ -44,7 +44,7 @@ namespace MWScript | |||
| 
 | ||||
|                 virtual void execute (Interpreter::Runtime& runtime) | ||||
|                 { | ||||
|                     MWBase::Environment::get().getInputManager()->setGuiMode(mDialogue); | ||||
|                     MWBase::Environment::get().getWindowManager()->pushGuiMode(mDialogue); | ||||
|                 } | ||||
|         }; | ||||
| 
 | ||||
|  |  | |||
|  | @ -7,7 +7,6 @@ | |||
| #include <OgreRoot.h> | ||||
| 
 | ||||
| #include <components/esm_store/store.hpp> | ||||
| #include <components/settings/settings.hpp> | ||||
| 
 | ||||
| #include "../mwbase/environment.hpp" | ||||
| 
 | ||||
|  | @ -53,6 +52,8 @@ namespace MWSound | |||
|         , mMasterVolume(1.0f) | ||||
|         , mSFXVolume(1.0f) | ||||
|         , mMusicVolume(1.0f) | ||||
|         , mFootstepsVolume(1.0f) | ||||
|         , mVoiceVolume(1.0f) | ||||
|     { | ||||
|         if(!useSound) | ||||
|             return; | ||||
|  | @ -63,6 +64,10 @@ namespace MWSound | |||
|         mSFXVolume = std::min(std::max(mSFXVolume, 0.0f), 1.0f); | ||||
|         mMusicVolume = Settings::Manager::getFloat("music volume", "Sound"); | ||||
|         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 decoder: " << SOUND_IN << std::endl; | ||||
|  | @ -210,7 +215,7 @@ namespace MWSound | |||
|         try | ||||
|         { | ||||
|             // The range values are not tested
 | ||||
|             float basevol = mMasterVolume * mSFXVolume; | ||||
|             float basevol = mMasterVolume * mVoiceVolume; | ||||
|             std::string filePath = "Sound/"+filename; | ||||
|             const ESM::Position &pos = ptr.getCellRef().pos; | ||||
|             const Ogre::Vector3 objpos(pos.pos[0], pos.pos[1], pos.pos[2]); | ||||
|  | @ -234,7 +239,7 @@ namespace MWSound | |||
|             return; | ||||
|         try | ||||
|         { | ||||
|             float basevol = mMasterVolume * mSFXVolume; | ||||
|             float basevol = mMasterVolume * mVoiceVolume; | ||||
|             std::string filePath = "Sound/"+filename; | ||||
| 
 | ||||
|             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
 | ||||
|     // better
 | ||||
|     void Sound_Decoder::readAll(std::vector<char> &output) | ||||
|  |  | |||
|  | @ -7,6 +7,8 @@ | |||
| 
 | ||||
| #include <OgreResourceGroupManager.h> | ||||
| 
 | ||||
| #include <components/settings/settings.hpp> | ||||
| 
 | ||||
| #include "../mwworld/ptr.hpp" | ||||
| 
 | ||||
| 
 | ||||
|  | @ -52,6 +54,10 @@ namespace MWSound | |||
|         float mMasterVolume; | ||||
|         float mSFXVolume; | ||||
|         float mMusicVolume; | ||||
|         float mVoiceVolume; | ||||
| 
 | ||||
|         // not implemented
 | ||||
|         float mFootstepsVolume; | ||||
| 
 | ||||
|         boost::shared_ptr<Sound> mMusic; | ||||
|         std::string mCurrentPlaylist; | ||||
|  | @ -78,6 +84,8 @@ namespace MWSound | |||
|         SoundManager(bool useSound); | ||||
|         ~SoundManager(); | ||||
| 
 | ||||
|         void processChangedSettings(const Settings::CategorySettingVector& settings); | ||||
| 
 | ||||
|         void stopMusic(); | ||||
|         ///< Stops music if it's playing
 | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										13
									
								
								apps/openmw/mwworld/actionalchemy.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								apps/openmw/mwworld/actionalchemy.cpp
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,13 @@ | |||
| #include "actionalchemy.hpp" | ||||
| 
 | ||||
| #include "../mwbase/environment.hpp" | ||||
| #include "../mwgui/window_manager.hpp" | ||||
| 
 | ||||
| namespace MWWorld | ||||
| { | ||||
|     void ActionAlchemy::execute() | ||||
|     { | ||||
|         MWBase::Environment::get().getWindowManager()->popGuiMode(); | ||||
|         MWBase::Environment::get().getWindowManager()->pushGuiMode(MWGui::GM_Alchemy); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										15
									
								
								apps/openmw/mwworld/actionalchemy.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								apps/openmw/mwworld/actionalchemy.hpp
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,15 @@ | |||
| #ifndef GAME_MWWORLD_ACTIONALCHEMY_H | ||||
| #define GAME_MWWORLD_ACTIONALCHEMY_H | ||||
| 
 | ||||
| #include "action.hpp" | ||||
| 
 | ||||
| namespace MWWorld | ||||
| { | ||||
|     class ActionAlchemy : public Action | ||||
|     { | ||||
|         public: | ||||
|             virtual void execute (); | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
| #endif | ||||
|  | @ -16,7 +16,10 @@ namespace MWWorld | |||
| 
 | ||||
|     void ActionOpen::execute () | ||||
|     { | ||||
|         MWBase::Environment::get().getWindowManager()->setGuiMode(MWGui::GM_Container); | ||||
|         if (!MWBase::Environment::get().getWindowManager()->isAllowed(MWGui::GW_Inventory)) | ||||
|             return; | ||||
| 
 | ||||
|         MWBase::Environment::get().getWindowManager()->pushGuiMode(MWGui::GM_Container); | ||||
|         MWBase::Environment::get().getWindowManager()->getContainerWindow()->open(mContainer); | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -18,12 +18,12 @@ namespace MWWorld | |||
| 
 | ||||
|         if (ref->base->data.isScroll) | ||||
|         { | ||||
|             MWBase::Environment::get().getWindowManager()->setGuiMode(MWGui::GM_Scroll); | ||||
|             MWBase::Environment::get().getWindowManager()->pushGuiMode(MWGui::GM_Scroll); | ||||
|             MWBase::Environment::get().getWindowManager()->getScrollWindow()->open(mObject); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             MWBase::Environment::get().getWindowManager()->setGuiMode(MWGui::GM_Book); | ||||
|             MWBase::Environment::get().getWindowManager()->pushGuiMode(MWGui::GM_Book); | ||||
|             MWBase::Environment::get().getWindowManager()->getBookWindow()->open(mObject); | ||||
|         } | ||||
|     } | ||||
|  |  | |||
|  | @ -2,6 +2,7 @@ | |||
| #include "actiontake.hpp" | ||||
| 
 | ||||
| #include "../mwbase/environment.hpp" | ||||
| #include "../mwgui/window_manager.hpp" | ||||
| 
 | ||||
| #include "class.hpp" | ||||
| #include "world.hpp" | ||||
|  | @ -13,6 +14,9 @@ namespace MWWorld | |||
| 
 | ||||
|     void ActionTake::execute() | ||||
|     { | ||||
|         if (!MWBase::Environment::get().getWindowManager()->isAllowed(MWGui::GW_Inventory)) | ||||
|             return; | ||||
| 
 | ||||
|         // insert into player's inventory
 | ||||
|         MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPtr ("player", true); | ||||
| 
 | ||||
|  |  | |||
|  | @ -2,7 +2,7 @@ | |||
| #include "actiontalk.hpp" | ||||
| 
 | ||||
| #include "../mwbase/environment.hpp" | ||||
| 
 | ||||
| #include "../mwgui/window_manager.hpp" | ||||
| #include "../mwdialogue/dialoguemanager.hpp" | ||||
| 
 | ||||
| namespace MWWorld | ||||
|  |  | |||
|  | @ -78,8 +78,6 @@ MWWorld::Ptr::CellStore *MWWorld::Cells::getExterior (int x, int y) | |||
|     std::map<std::pair<int, int>, Ptr::CellStore>::iterator result = | ||||
|         mExteriors.find (std::make_pair (x, y)); | ||||
| 
 | ||||
|     bool fill = false; | ||||
| 
 | ||||
|     if (result==mExteriors.end()) | ||||
|     { | ||||
|         const ESM::Cell *cell = mStore.cells.searchExt (x, y); | ||||
|  | @ -100,15 +98,13 @@ MWWorld::Ptr::CellStore *MWWorld::Cells::getExterior (int x, int y) | |||
| 
 | ||||
|         result = mExteriors.insert (std::make_pair ( | ||||
|             std::make_pair (x, y), Ptr::CellStore (cell))).first; | ||||
| 
 | ||||
|         fill = true; | ||||
|     } | ||||
| 
 | ||||
|     if (result->second.mState!=Ptr::CellStore::State_Loaded) | ||||
|     { | ||||
|         result->second.load (mStore, mReader); | ||||
| 
 | ||||
|     if (fill) | ||||
|         fillContainers (result->second); | ||||
|     } | ||||
| 
 | ||||
|     return &result->second; | ||||
| } | ||||
|  | @ -117,22 +113,18 @@ MWWorld::Ptr::CellStore *MWWorld::Cells::getInterior (const std::string& name) | |||
| { | ||||
|     std::map<std::string, Ptr::CellStore>::iterator result = mInteriors.find (name); | ||||
| 
 | ||||
|     bool fill = false; | ||||
| 
 | ||||
|     if (result==mInteriors.end()) | ||||
|     { | ||||
|         const ESM::Cell *cell = mStore.cells.findInt (name); | ||||
| 
 | ||||
|         result = mInteriors.insert (std::make_pair (name, Ptr::CellStore (cell))).first; | ||||
| 
 | ||||
|         fill = true; | ||||
|     } | ||||
| 
 | ||||
|     if (result->second.mState!=Ptr::CellStore::State_Loaded) | ||||
|     { | ||||
|         result->second.load (mStore, mReader); | ||||
| 
 | ||||
|     if (fill) | ||||
|         fillContainers (result->second); | ||||
|     } | ||||
| 
 | ||||
|     return &result->second; | ||||
| } | ||||
|  |  | |||
|  | @ -32,16 +32,6 @@ namespace MWWorld | |||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     void Class::enable (const Ptr& ptr) const | ||||
|     { | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     void Class::disable (const Ptr& ptr) const | ||||
|     { | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     MWMechanics::CreatureStats& Class::getCreatureStats (const Ptr& ptr) const | ||||
|     { | ||||
|         throw std::runtime_error ("class does not have creature stats"); | ||||
|  |  | |||
|  | @ -68,16 +68,6 @@ namespace MWWorld | |||
|             virtual void insertObject(const Ptr& ptr, MWWorld::PhysicsSystem& physics) const; | ||||
|             ///< Add reference into a cell for rendering (default implementation: don't render anything).
 | ||||
| 
 | ||||
|             virtual void enable (const Ptr& ptr) const; | ||||
|             ///< Enable reference; only does the non-rendering part (default implementation: ignore)
 | ||||
|             /// \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 void disable (const Ptr& ptr) const; | ||||
|             ///< Enable reference; only does the non-rendering part (default implementation: ignore)
 | ||||
|             /// \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 Ptr& ptr) const = 0; | ||||
|             ///< \return name (the one that is to be presented to the user; not the internal one);
 | ||||
|             /// can return an empty string.
 | ||||
|  |  | |||
|  | @ -61,6 +61,7 @@ bool MWWorld::ContainerStore::stacks(const Ptr& ptr1, const Ptr& ptr2) | |||
|     /// \todo add current weapon/armor health, remaining lockpick/repair uses, current enchantment charge here as soon as they are implemented
 | ||||
|     if (  ptr1.mCellRef->refID == ptr2.mCellRef->refID | ||||
|         && MWWorld::Class::get(ptr1).getScript(ptr1) == "" // item with a script never stacks
 | ||||
|         && MWWorld::Class::get(ptr1).getEnchantment(ptr1) == "" // item with enchantment never stacks (we could revisit this later, but for now it makes selecting items in the spell window much easier)
 | ||||
|         && ptr1.mCellRef->owner == ptr2.mCellRef->owner | ||||
|         && ptr1.mCellRef->soul == ptr2.mCellRef->soul | ||||
|         && ptr1.mCellRef->charge == ptr2.mCellRef->charge) | ||||
|  |  | |||
|  | @ -39,15 +39,18 @@ void MWWorld::InventoryStore::initSlots (TSlots& slots) | |||
| } | ||||
| 
 | ||||
| MWWorld::InventoryStore::InventoryStore() : mMagicEffectsUpToDate (false) | ||||
|  , mSelectedEnchantItem(end()) | ||||
| { | ||||
|     initSlots (mSlots); | ||||
| } | ||||
| 
 | ||||
| MWWorld::InventoryStore::InventoryStore (const InventoryStore& store) | ||||
| : ContainerStore (store) | ||||
|  , mSelectedEnchantItem(end()) | ||||
| { | ||||
|     mMagicEffects = store.mMagicEffects; | ||||
|     mMagicEffectsUpToDate = store.mMagicEffectsUpToDate; | ||||
|     mSelectedEnchantItem = store.mSelectedEnchantItem; | ||||
|     copySlots (store); | ||||
| } | ||||
| 
 | ||||
|  | @ -260,3 +263,13 @@ bool MWWorld::InventoryStore::stacks(const Ptr& ptr1, const Ptr& ptr2) | |||
| 
 | ||||
|     return true; | ||||
| } | ||||
| 
 | ||||
| void MWWorld::InventoryStore::setSelectedEnchantItem(const ContainerStoreIterator& iterator) | ||||
| { | ||||
|     mSelectedEnchantItem = iterator; | ||||
| } | ||||
| 
 | ||||
| MWWorld::ContainerStoreIterator MWWorld::InventoryStore::getSelectedEnchantItem() | ||||
| { | ||||
|     return mSelectedEnchantItem; | ||||
| } | ||||
|  |  | |||
Some files were not shown because too many files have changed in this diff Show more
		Loading…
	
		Reference in a new issue